functional.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. r""" Functional interface (quantized)."""
  2. from typing import List, Optional
  3. import warnings
  4. import torch
  5. from torch import Tensor
  6. from torch.nn.modules.utils import _pair, _triple
  7. from torch.jit.annotations import BroadcastingList2
  8. from .modules.utils import _pair_from_first
  9. # Although some of the functions and docstrings are mirrored from the torch.nn,
  10. # we want to have them here for future changes.
  11. __all__ = [
  12. "avg_pool2d",
  13. "avg_pool3d",
  14. "adaptive_avg_pool2d",
  15. "adaptive_avg_pool3d",
  16. "conv1d",
  17. "conv2d",
  18. "conv3d",
  19. "interpolate",
  20. "linear",
  21. "max_pool1d",
  22. "max_pool2d",
  23. "celu",
  24. "leaky_relu",
  25. "hardtanh",
  26. "hardswish",
  27. "threshold",
  28. "elu",
  29. "hardsigmoid",
  30. "clamp",
  31. "upsample",
  32. "upsample_bilinear",
  33. "upsample_nearest",
  34. ]
  35. def avg_pool2d(input, kernel_size, stride=None, padding=0, ceil_mode=False,
  36. count_include_pad=True, divisor_override=None):
  37. r"""
  38. Applies 2D average-pooling operation in :math:`kH \times kW` regions by step size
  39. :math:`sH \times sW` steps. The number of output features is equal to the number of
  40. input planes.
  41. .. note:: The input quantization parameters propagate to the output.
  42. See :class:`~torch.ao.nn.quantized.AvgPool2d` for details and output shape.
  43. Args:
  44. input: quantized input tensor :math:`(\text{minibatch} , \text{in\_channels} , iH , iW)`
  45. kernel_size: size of the pooling region. Can be a single number or a
  46. tuple `(kH, kW)`
  47. stride: stride of the pooling operation. Can be a single number or a
  48. tuple `(sH, sW)`. Default: :attr:`kernel_size`
  49. padding: implicit zero paddings on both sides of the input. Can be a
  50. single number or a tuple `(padH, padW)`. Default: 0
  51. ceil_mode: when True, will use `ceil` instead of `floor` in the formula
  52. to compute the output shape. Default: ``False``
  53. count_include_pad: when True, will include the zero-padding in the
  54. averaging calculation. Default: ``True``
  55. divisor_override: if specified, it will be used as divisor, otherwise
  56. size of the pooling region will be used. Default: None
  57. """
  58. if not input.is_quantized:
  59. raise ValueError("Input to 'quantized.avg_pool2d' must be quantized!")
  60. return torch.nn.functional.avg_pool2d(input, kernel_size, stride, padding,
  61. ceil_mode, count_include_pad,
  62. divisor_override)
  63. def avg_pool3d(input, kernel_size, stride=None, padding=0, ceil_mode=False,
  64. count_include_pad=True, divisor_override=None):
  65. r"""
  66. Applies 3D average-pooling operation in :math:`kD \ times kH \times kW` regions by step size
  67. :math:`sD \times sH \times sW` steps. The number of output features is equal to the number of
  68. input planes.
  69. .. note:: The input quantization parameters propagate to the output.
  70. Args:
  71. input: quantized input tensor :math:`(\text{minibatch} , \text{in\_channels} , iH , iW)`
  72. kernel_size: size of the pooling region. Can be a single number or a
  73. tuple `(kD, kH, kW)`
  74. stride: stride of the pooling operation. Can be a single number or a
  75. tuple `(sD, sH, sW)`. Default: :attr:`kernel_size`
  76. padding: implicit zero paddings on both sides of the input. Can be a
  77. single number or a tuple `(padD, padH, padW)`. Default: 0
  78. ceil_mode: when True, will use `ceil` instead of `floor` in the formula
  79. to compute the output shape. Default: ``False``
  80. count_include_pad: when True, will include the zero-padding in the
  81. averaging calculation. Default: ``True``
  82. divisor_override: if specified, it will be used as divisor, otherwise
  83. size of the pooling region will be used. Default: None
  84. """
  85. if not input.is_quantized:
  86. raise ValueError("Input to 'quantized.avg_pool3d' must be quantized!")
  87. return torch.nn.functional.avg_pool3d(input, kernel_size, stride, padding,
  88. ceil_mode, count_include_pad,
  89. divisor_override)
  90. def adaptive_avg_pool2d(input: Tensor, output_size: BroadcastingList2[int]) -> Tensor:
  91. r"""
  92. Applies a 2D adaptive average pooling over a quantized input signal composed
  93. of several quantized input planes.
  94. .. note:: The input quantization parameters propagate to the output.
  95. See :class:`~torch.ao.nn.quantized.AdaptiveAvgPool2d` for details and output shape.
  96. Args:
  97. output_size: the target output size (single integer or
  98. double-integer tuple)
  99. """
  100. if not input.is_quantized:
  101. raise ValueError("Input to 'quantized.functional.adaptive_avg_pool2d' must be quantized!")
  102. return torch.nn.functional.adaptive_avg_pool2d(input, output_size)
  103. def adaptive_avg_pool3d(input: Tensor, output_size: BroadcastingList2[int]) -> Tensor:
  104. r"""
  105. Applies a 3D adaptive average pooling over a quantized input signal composed
  106. of several quantized input planes.
  107. .. note:: The input quantization parameters propagate to the output.
  108. See :class:`~torch.ao.nn.quantized.AdaptiveAvgPool3d` for details and output shape.
  109. Args:
  110. output_size: the target output size (single integer or
  111. double-integer tuple)
  112. """
  113. if not input.is_quantized:
  114. raise ValueError(
  115. "Input to 'quantized.functional.adaptive_avg_pool3d' must be quantized!")
  116. return torch.nn.functional.adaptive_avg_pool3d(input, output_size)
  117. def conv1d(input, weight, bias,
  118. stride=1, padding=0, dilation=1, groups=1,
  119. padding_mode='zeros',
  120. scale=1.0, zero_point=0,
  121. dtype=torch.quint8):
  122. r"""
  123. Applies a 1D convolution over a quantized 1D input composed of several input
  124. planes.
  125. See :class:`~torch.ao.nn.quantized.Conv1d` for details and output shape.
  126. Args:
  127. input: quantized input tensor of shape :math:`(\text{minibatch} , \text{in\_channels} , iW)`
  128. weight: quantized filters of shape :math:`(\text{out\_channels} , \frac{\text{in\_channels}}{\text{groups}} , iW)`
  129. bias: **non-quantized** bias tensor of shape :math:`(\text{out\_channels})`. The tensor type must be `torch.float`.
  130. stride: the stride of the convolving kernel. Can be a single number or a
  131. tuple `(sW,)`. Default: 1
  132. padding: implicit paddings on both sides of the input. Can be a
  133. single number or a tuple `(padW,)`. Default: 0
  134. dilation: the spacing between kernel elements. Can be a single number or
  135. a tuple `(dW,)`. Default: 1
  136. groups: split input into groups, :math:`\text{in\_channels}` should be divisible by the
  137. number of groups. Default: 1
  138. padding_mode: the padding mode to use. Only "zeros" is supported for quantized convolution at the moment. Default: "zeros"
  139. scale: quantization scale for the output. Default: 1.0
  140. zero_point: quantization zero_point for the output. Default: 0
  141. dtype: quantization data type to use. Default: ``torch.quint8``
  142. Examples::
  143. >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE)
  144. >>> from torch.ao.nn.quantized import functional as qF
  145. >>> filters = torch.randn(33, 16, 3, dtype=torch.float)
  146. >>> inputs = torch.randn(20, 16, 50, dtype=torch.float)
  147. >>> bias = torch.randn(33, dtype=torch.float)
  148. >>>
  149. >>> scale, zero_point = 1.0, 0
  150. >>> dtype_inputs = torch.quint8
  151. >>> dtype_filters = torch.qint8
  152. >>>
  153. >>> q_filters = torch.quantize_per_tensor(filters, scale, zero_point, dtype_filters)
  154. >>> q_inputs = torch.quantize_per_tensor(inputs, scale, zero_point, dtype_inputs)
  155. >>> qF.conv1d(q_inputs, q_filters, bias, padding=1, scale=scale, zero_point=zero_point)
  156. """ # noqa: E501
  157. if padding_mode != 'zeros':
  158. raise NotImplementedError("Only zero-padding is supported!")
  159. if input.dtype != torch.quint8:
  160. raise NotImplementedError("Only torch.quint8 is supported for activation tensor!")
  161. if weight.dtype != torch.qint8:
  162. raise NotImplementedError("Only torch.qint8 is supported for weight tensor!")
  163. if input.ndim != 3:
  164. raise ValueError("Input shape must be `(N, C, L)`!")
  165. stride = _pair_from_first(stride)
  166. padding = _pair_from_first(padding)
  167. dilation = _pair_from_first(dilation)
  168. packed_params = torch.ops.quantized.conv1d_prepack(
  169. weight, bias, stride, padding, dilation, groups)
  170. return torch.ops.quantized.conv1d(input, packed_params, scale, zero_point)
  171. def conv2d(input, weight, bias,
  172. stride=1, padding=0, dilation=1, groups=1,
  173. padding_mode='zeros',
  174. scale=1.0, zero_point=0,
  175. dtype=torch.quint8):
  176. r"""
  177. Applies a 2D convolution over a quantized 2D input composed of several input
  178. planes.
  179. See :class:`~torch.ao.nn.quantized.Conv2d` for details and output shape.
  180. Args:
  181. input: quantized input tensor of shape :math:`(\text{minibatch} , \text{in\_channels} , iH , iW)`
  182. weight: quantized filters of shape :math:`(\text{out\_channels} , \frac{\text{in\_channels}}{\text{groups}} , kH , kW)`
  183. bias: **non-quantized** bias tensor of shape :math:`(\text{out\_channels})`. The tensor type must be `torch.float`.
  184. stride: the stride of the convolving kernel. Can be a single number or a
  185. tuple `(sH, sW)`. Default: 1
  186. padding: implicit paddings on both sides of the input. Can be a
  187. single number or a tuple `(padH, padW)`. Default: 0
  188. dilation: the spacing between kernel elements. Can be a single number or
  189. a tuple `(dH, dW)`. Default: 1
  190. groups: split input into groups, :math:`\text{in\_channels}` should be divisible by the
  191. number of groups. Default: 1
  192. padding_mode: the padding mode to use. Only "zeros" is supported for quantized convolution at the moment. Default: "zeros"
  193. scale: quantization scale for the output. Default: 1.0
  194. zero_point: quantization zero_point for the output. Default: 0
  195. dtype: quantization data type to use. Default: ``torch.quint8``
  196. Examples::
  197. >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE)
  198. >>> from torch.ao.nn.quantized import functional as qF
  199. >>> filters = torch.randn(8, 4, 3, 3, dtype=torch.float)
  200. >>> inputs = torch.randn(1, 4, 5, 5, dtype=torch.float)
  201. >>> bias = torch.randn(8, dtype=torch.float)
  202. >>>
  203. >>> scale, zero_point = 1.0, 0
  204. >>> dtype_inputs = torch.quint8
  205. >>> dtype_filters = torch.qint8
  206. >>>
  207. >>> q_filters = torch.quantize_per_tensor(filters, scale, zero_point, dtype_filters)
  208. >>> q_inputs = torch.quantize_per_tensor(inputs, scale, zero_point, dtype_inputs)
  209. >>> qF.conv2d(q_inputs, q_filters, bias, padding=1, scale=scale, zero_point=zero_point)
  210. """ # noqa: E501
  211. if padding_mode != 'zeros':
  212. raise NotImplementedError("Only zero-padding is supported!")
  213. if input.dtype != torch.quint8:
  214. raise NotImplementedError("Only torch.quint8 is supported for activation tensor!")
  215. if weight.dtype != torch.qint8:
  216. raise NotImplementedError("Only torch.qint8 is supported for weight tensor!")
  217. if input.ndim != 4:
  218. raise ValueError("Input shape must be `(N, C, H, W)`!")
  219. stride = _pair(stride)
  220. padding = _pair(padding)
  221. dilation = _pair(dilation)
  222. packed_params = torch.ops.quantized.conv2d_prepack(
  223. weight, bias, stride, padding, dilation, groups)
  224. return torch.ops.quantized.conv2d(input, packed_params, scale, zero_point)
  225. def conv3d(input, weight, bias, stride=1, padding=0, dilation=1, groups=1,
  226. padding_mode='zeros', scale=1.0, zero_point=0, dtype=torch.quint8):
  227. r"""
  228. Applies a 3D convolution over a quantized 3D input composed of several input
  229. planes.
  230. See :class:`~torch.ao.nn.quantized.Conv3d` for details and output shape.
  231. Args:
  232. input: quantized input tensor of shape
  233. :math:`(\text{minibatch} , \text{in\_channels} , iD , iH , iW)`
  234. weight: quantized filters of shape
  235. :math:`(\text{out\_channels} , \frac{\text{in\_channels}}{\text{groups}} , kD , kH , kW)`
  236. bias: **non-quantized** bias tensor of shape
  237. :math:`(\text{out\_channels})`. The tensor type must be `torch.float`.
  238. stride: the stride of the convolving kernel. Can be a single number or a
  239. tuple `(sD, sH, sW)`. Default: 1
  240. padding: implicit paddings on both sides of the input. Can be a
  241. single number or a tuple `(padD, padH, padW)`. Default: 0
  242. dilation: the spacing between kernel elements. Can be a single number or
  243. a tuple `(dD, dH, dW)`. Default: 1
  244. groups: split input into groups, :math:`\text{in\_channels}` should be
  245. divisible by the number of groups. Default: 1
  246. padding_mode: the padding mode to use. Only "zeros" is supported for
  247. quantized convolution at the moment. Default: "zeros"
  248. scale: quantization scale for the output. Default: 1.0
  249. zero_point: quantization zero_point for the output. Default: 0
  250. dtype: quantization data type to use. Default: ``torch.quint8``
  251. Examples::
  252. >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_QENGINE)
  253. >>> from torch.ao.nn.quantized import functional as qF
  254. >>> filters = torch.randn(8, 4, 3, 3, 3, dtype=torch.float)
  255. >>> inputs = torch.randn(1, 4, 5, 5, 5, dtype=torch.float)
  256. >>> bias = torch.randn(8, dtype=torch.float)
  257. >>>
  258. >>> scale, zero_point = 1.0, 0
  259. >>> dtype_inputs = torch.quint8
  260. >>> dtype_filters = torch.qint8
  261. >>>
  262. >>> q_filters = torch.quantize_per_tensor(filters, scale, zero_point, dtype_filters)
  263. >>> q_inputs = torch.quantize_per_tensor(inputs, scale, zero_point, dtype_inputs)
  264. >>> qF.conv3d(q_inputs, q_filters, bias, padding=1, scale=scale, zero_point=zero_point)
  265. """ # noqa: E501
  266. if padding_mode != 'zeros':
  267. raise NotImplementedError("Only zero-padding is supported!")
  268. if input.dtype != torch.quint8:
  269. raise NotImplementedError("Only torch.quint8 is supported for activation tensor!")
  270. if weight.dtype != torch.qint8:
  271. raise NotImplementedError("Only torch.qint8 is supported for weight tensor!")
  272. if input.ndim != 5:
  273. raise ValueError("Input shape must be `(N, C, D, H, W)`!")
  274. stride = _triple(stride)
  275. padding = _triple(padding)
  276. dilation = _triple(dilation)
  277. packed_params = torch.ops.quantized.conv3d_prepack(
  278. weight, bias, stride, padding, dilation, groups)
  279. return torch.ops.quantized.conv3d(input, packed_params, scale, zero_point)
  280. def interpolate(input, size=None, scale_factor=None, mode='nearest', align_corners=None):
  281. r"""Down/up samples the input to either the given :attr:`size` or the given
  282. :attr:`scale_factor`
  283. See :func:`torch.nn.functional.interpolate` for implementation details.
  284. The input dimensions are interpreted in the form:
  285. `mini-batch x channels x [optional depth] x [optional height] x width`.
  286. .. note:: The input quantization parameters propagate to the output.
  287. .. note:: Only 2D/3D input is supported for quantized inputs
  288. .. note:: Only the following modes are supported for the quantized inputs:
  289. - `bilinear`
  290. - `nearest`
  291. Args:
  292. input (Tensor): the input tensor
  293. size (int or Tuple[int] or Tuple[int, int] or Tuple[int, int, int]):
  294. output spatial size.
  295. scale_factor (float or Tuple[float]): multiplier for spatial size. Has to match input size if it is a tuple.
  296. mode (str): algorithm used for upsampling:
  297. ``'nearest'`` | ``'bilinear'``
  298. align_corners (bool, optional): Geometrically, we consider the pixels of the
  299. input and output as squares rather than points.
  300. If set to ``True``, the input and output tensors are aligned by the
  301. center points of their corner pixels, preserving the values at the corner pixels.
  302. If set to ``False``, the input and output tensors are aligned by the corner
  303. points of their corner pixels, and the interpolation uses edge value padding
  304. for out-of-boundary values, making this operation *independent* of input size
  305. when :attr:`scale_factor` is kept the same. This only has an effect when :attr:`mode`
  306. is ``'bilinear'``.
  307. Default: ``False``
  308. """
  309. if not input.is_quantized:
  310. raise ValueError("Input to 'quantized.interpolate' must be quantized!")
  311. return torch.nn.functional.interpolate(input, size, scale_factor, mode,
  312. align_corners)
  313. def linear(
  314. input: Tensor, weight: Tensor, bias: Optional[Tensor] = None,
  315. scale: Optional[float] = None, zero_point: Optional[int] = None
  316. ) -> Tensor:
  317. r"""
  318. Applies a linear transformation to the incoming quantized data:
  319. :math:`y = xA^T + b`.
  320. See :class:`~torch.ao.nn.quantized.Linear`
  321. .. note::
  322. Current implementation packs weights on every call, which has penalty on performance.
  323. If you want to avoid the overhead, use :class:`~torch.ao.nn.quantized.Linear`.
  324. Args:
  325. input (Tensor): Quantized input of type `torch.quint8`
  326. weight (Tensor): Quantized weight of type `torch.qint8`
  327. bias (Tensor): None or fp32 bias of type `torch.float`
  328. scale (double): output scale. If None, derived from the input scale
  329. zero_point (long): output zero point. If None, derived from the input zero_point
  330. Shape:
  331. - Input: :math:`(N, *, in\_features)` where `*` means any number of
  332. additional dimensions
  333. - Weight: :math:`(out\_features, in\_features)`
  334. - Bias: :math:`(out\_features)`
  335. - Output: :math:`(N, *, out\_features)`
  336. """
  337. if scale is None:
  338. scale = input.q_scale()
  339. if zero_point is None:
  340. zero_point = input.q_zero_point()
  341. _packed_params = torch.ops.quantized.linear_prepack(weight, bias)
  342. return torch.ops.quantized.linear(input, _packed_params, scale, zero_point)
  343. def max_pool1d(input, kernel_size, stride=None, padding=0, dilation=1,
  344. ceil_mode=False, return_indices=False):
  345. r"""Applies a 1D max pooling over a quantized input signal composed of
  346. several quantized input planes.
  347. .. note:: The input quantization parameters are propagated to the output.
  348. See :class:`~torch.ao.nn.quantized.MaxPool1d` for details.
  349. """
  350. if return_indices:
  351. raise NotImplementedError("return_indices is not yet implemented!")
  352. if stride is None:
  353. stride = torch.jit.annotate(List[int], [])
  354. return torch.nn.functional.max_pool1d(input, kernel_size, stride, padding,
  355. dilation, ceil_mode=ceil_mode, return_indices=return_indices)
  356. def max_pool2d(input, kernel_size, stride=None, padding=0, dilation=1,
  357. ceil_mode=False, return_indices=False):
  358. r"""Applies a 2D max pooling over a quantized input signal composed of
  359. several quantized input planes.
  360. .. note:: The input quantization parameters are propagated to the output.
  361. See :class:`~torch.ao.nn.quantized.MaxPool2d` for details.
  362. """
  363. if return_indices:
  364. raise NotImplementedError("return_indices is not yet implemented!")
  365. if stride is None:
  366. stride = torch.jit.annotate(List[int], [])
  367. return torch.nn.functional.max_pool2d(input, kernel_size, stride, padding,
  368. dilation, ceil_mode=ceil_mode, return_indices=return_indices)
  369. def celu(input: Tensor, scale: float, zero_point: int, alpha: float = 1.) -> Tensor:
  370. r"""celu(input, scale, zero_point, alpha=1.) -> Tensor
  371. Applies the quantized CELU function element-wise.
  372. .. math::
  373. \text{CELU}(x) = \max(0,x) + \min(0, \alpha * (\exp(x / \alpha) - 1))
  374. Args:
  375. input: quantized input
  376. alpha: the :math:`\alpha` value for the CELU formulation. Default: 1.0
  377. """
  378. if not input.is_quantized:
  379. raise ValueError("Input to 'quantized.celu' must be quantized!")
  380. return torch.ops.quantized.celu(input, scale, zero_point, alpha)
  381. def leaky_relu(input: Tensor, negative_slope: float = 0.01, inplace: bool = False,
  382. scale: Optional[float] = None, zero_point: Optional[int] = None):
  383. r"""
  384. Quantized version of the.
  385. leaky_relu(input, negative_slope=0.01, inplace=False, scale, zero_point) -> Tensor
  386. Applies element-wise,
  387. :math:`\text{LeakyReLU}(x) = \max(0, x) + \text{negative\_slope} * \min(0, x)`
  388. Args:
  389. input: Quantized input
  390. negative_slope: The slope of the negative input
  391. inplace: Inplace modification of the input tensor
  392. scale, zero_point: Scale and zero point of the output tensor.
  393. See :class:`~torch.nn.LeakyReLU` for more details.
  394. """
  395. if scale is not None and zero_point is not None:
  396. assert not inplace, "Cannot rescale with `inplace`"
  397. output = torch._empty_affine_quantized(
  398. input.shape, scale=scale, zero_point=int(zero_point), dtype=input.dtype)
  399. torch._C._nn.leaky_relu(input, negative_slope, out=output)
  400. return output
  401. if inplace:
  402. result = torch._C._nn.leaky_relu_(input, negative_slope)
  403. else:
  404. result = torch._C._nn.leaky_relu(input, negative_slope)
  405. return result
  406. def hardtanh(input: Tensor, min_val: float = -1., max_val: float = 1., inplace: bool = False) -> Tensor:
  407. r"""This is the quantized version of :func:`~torch.nn.functional.hardtanh`.
  408. """
  409. if not input.is_quantized:
  410. raise ValueError("Input to 'quantized.hardtanh' must be quantized!")
  411. if inplace:
  412. return torch._C._nn.hardtanh_(input, min_val, max_val)
  413. return torch._C._nn.hardtanh(input, min_val, max_val)
  414. def hardswish(input: Tensor, scale: float, zero_point: int) -> Tensor:
  415. r"""This is the quantized version of :func:`~torch.nn.functional.hardswish`.
  416. Args:
  417. input: quantized input
  418. scale: quantization scale of the output tensor
  419. zero_point: quantization zero point of the output tensor
  420. """
  421. if not input.is_quantized:
  422. raise ValueError("Input to 'quantized.hardswish' must be quantized!")
  423. return torch._ops.ops.quantized.hardswish(input, scale, zero_point)
  424. def threshold(input: Tensor, threshold: float, value: float) -> Tensor:
  425. r"""Applies the quantized version of the threshold function element-wise:
  426. .. math::
  427. x = \begin{cases}
  428. x & \text{if~} x > \text{threshold} \\
  429. \text{value} & \text{otherwise}
  430. \end{cases}
  431. See :class:`~torch.nn.Threshold` for more details.
  432. """
  433. if not input.is_quantized:
  434. raise ValueError("Input to 'quantized.threshold' must be quantized!")
  435. if threshold is None:
  436. raise ValueError("Input to 'threshold' must be specified!")
  437. if value is None:
  438. raise ValueError("Input to 'value' must be specified!")
  439. return torch._ops.ops.quantized.threshold(input, threshold, value)
  440. def elu(input: Tensor, scale: float, zero_point: int, alpha: float = 1.) -> Tensor:
  441. r"""This is the quantized version of :func:`~torch.nn.functional.elu`.
  442. Args:
  443. input: quantized input
  444. scale: quantization scale of the output tensor
  445. zero_point: quantization zero point of the output tensor
  446. alpha: the alpha constant
  447. """
  448. if not input.is_quantized:
  449. raise ValueError("Input to 'quantized.elu' must be quantized!")
  450. return torch.ops.quantized.elu(input, scale, zero_point, alpha)
  451. def hardsigmoid(input: Tensor, inplace: bool = False) -> Tensor:
  452. r"""This is the quantized version of :func:`~torch.nn.functional.hardsigmoid`.
  453. """
  454. if not input.is_quantized:
  455. raise ValueError("Input to 'quantized.hardsigmoid' must be quantized!")
  456. if inplace:
  457. return torch._C._nn.hardsigmoid_(input) # type: ignore[attr-defined]
  458. return torch._C._nn.hardsigmoid(input)
  459. def clamp(input: Tensor, min_: float, max_: float) -> Tensor:
  460. r"""float(input, min\_, max\_) -> Tensor
  461. Applies the clamp function element-wise.
  462. See :class:`~torch.ao.nn.quantized.clamp` for more details.
  463. Args:
  464. input: quantized input
  465. min_: minimum value for clamping
  466. max_: maximum value for clamping
  467. """
  468. if not input.is_quantized:
  469. raise ValueError("Input to 'quantized.clamp' must be quantized!")
  470. return torch.clamp(input, min_, max_)
  471. def upsample(input, size=None, scale_factor=None, mode='nearest', align_corners=None):
  472. r"""Upsamples the input to either the given :attr:`size` or the given
  473. :attr:`scale_factor`
  474. .. warning::
  475. This function is deprecated in favor of
  476. :func:`torch.ao.nn.quantized.functional.interpolate`.
  477. This is equivalent with ``nn.quantized.functional.interpolate(...)``.
  478. See :func:`torch.nn.functional.interpolate` for implementation details.
  479. The input dimensions are interpreted in the form:
  480. `mini-batch x channels x [optional depth] x [optional height] x width`.
  481. .. note:: The input quantization parameters propagate to the output.
  482. .. note:: Only 2D input is supported for quantized inputs
  483. .. note:: Only the following modes are supported for the quantized inputs:
  484. - `bilinear`
  485. - `nearest`
  486. Args:
  487. input (Tensor): quantized input tensor
  488. size (int or Tuple[int] or Tuple[int, int] or Tuple[int, int, int]):
  489. output spatial size.
  490. scale_factor (float or Tuple[float]): multiplier for spatial size. Has to be an integer.
  491. mode (str): algorithm used for upsampling:
  492. ``'nearest'`` | ``'bilinear'``
  493. align_corners (bool, optional): Geometrically, we consider the pixels of the
  494. input and output as squares rather than points.
  495. If set to ``True``, the input and output tensors are aligned by the
  496. center points of their corner pixels, preserving the values at the corner pixels.
  497. If set to ``False``, the input and output tensors are aligned by the corner
  498. points of their corner pixels, and the interpolation uses edge value padding
  499. for out-of-boundary values, making this operation *independent* of input size
  500. when :attr:`scale_factor` is kept the same. This only has an effect when :attr:`mode`
  501. is ``'bilinear'``.
  502. Default: ``False``
  503. .. warning::
  504. With ``align_corners = True``, the linearly interpolating modes
  505. (`bilinear`) don't proportionally align the
  506. output and input pixels, and thus the output values can depend on the
  507. input size. This was the default behavior for these modes up to version
  508. 0.3.1. Since then, the default behavior is ``align_corners = False``.
  509. See :class:`~torch.nn.Upsample` for concrete examples on how this
  510. affects the outputs.
  511. """
  512. warnings.warn("nn.quantized.functional.upsample is deprecated. Use nn.quantized.functional.interpolate instead.")
  513. return interpolate(input, size, scale_factor, mode, align_corners)
  514. def upsample_bilinear(input, size=None, scale_factor=None):
  515. r"""Upsamples the input, using bilinear upsampling.
  516. .. warning::
  517. This function is deprecated in favor of
  518. :func:`torch.ao.nn.quantized.functional.interpolate`.
  519. This is equivalent with
  520. ``nn.quantized.functional.interpolate(..., mode='bilinear', align_corners=True)``.
  521. .. note:: The input quantization parameters propagate to the output.
  522. .. note:: Only 2D inputs are supported
  523. Args:
  524. input (Tensor): quantized input
  525. size (int or Tuple[int, int]): output spatial size.
  526. scale_factor (int or Tuple[int, int]): multiplier for spatial size
  527. """
  528. # DeprecationWarning is ignored by default
  529. warnings.warn("nn.quantized.functional.upsample_bilinear is deprecated. Use nn.quantized.functional.interpolate instead.")
  530. return interpolate(input, size, scale_factor, mode='bilinear', align_corners=True)
  531. def upsample_nearest(input, size=None, scale_factor=None):
  532. r"""Upsamples the input, using nearest neighbours' pixel values.
  533. .. warning::
  534. This function is deprecated in favor of
  535. :func:`torch.ao.nn.quantized.functional.interpolate`.
  536. This is equivalent with ``nn.quantized.functional.interpolate(..., mode='nearest')``.
  537. .. note:: The input quantization parameters propagate to the output.
  538. .. note:: Only 2D inputs are supported
  539. Args:
  540. input (Tensor): quantized input
  541. size (int or Tuple[int, int] or Tuple[int, int, int]): output spatial
  542. size.
  543. scale_factor (int): multiplier for spatial size. Has to be an integer.
  544. """
  545. # DeprecationWarning is ignored by default
  546. warnings.warn("nn.quantized.functional.upsample_nearest is deprecated. Use nn.quantized.functional.interpolate instead.")
  547. return interpolate(input, size, scale_factor, mode='nearest')