nvmath-python 0.9.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. nvmath/__init__.pxd +0 -0
  2. nvmath/__init__.py +45 -0
  3. nvmath/_internal/__init__.py +0 -0
  4. nvmath/_internal/attribute_ifc_factory.py +330 -0
  5. nvmath/_internal/layout.py +70 -0
  6. nvmath/_internal/templates.py +383 -0
  7. nvmath/_utils.py +150 -0
  8. nvmath/bindings/__init__.py +51 -0
  9. nvmath/bindings/_internal/__init__.pxd +0 -0
  10. nvmath/bindings/_internal/__init__.py +0 -0
  11. nvmath/bindings/_internal/cublas.cp314-win_amd64.pyd +0 -0
  12. nvmath/bindings/_internal/cublas.pxd +530 -0
  13. nvmath/bindings/_internal/cublasLt.cp314-win_amd64.pyd +0 -0
  14. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  15. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  16. nvmath/bindings/_internal/cudss.cp314-win_amd64.pyd +0 -0
  17. nvmath/bindings/_internal/cudss.pxd +47 -0
  18. nvmath/bindings/_internal/cufft.cp314-win_amd64.pyd +0 -0
  19. nvmath/bindings/_internal/cufft.pxd +70 -0
  20. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  21. nvmath/bindings/_internal/curand.cp314-win_amd64.pyd +0 -0
  22. nvmath/bindings/_internal/curand.pxd +42 -0
  23. nvmath/bindings/_internal/cusolver.cp314-win_amd64.pyd +0 -0
  24. nvmath/bindings/_internal/cusolver.pxd +15 -0
  25. nvmath/bindings/_internal/cusolverDn.cp314-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  27. nvmath/bindings/_internal/cusparse.cp314-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusparse.pxd +277 -0
  29. nvmath/bindings/_internal/cusparseLt.cp314-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  31. nvmath/bindings/_internal/cutensor.cp314-win_amd64.pyd +0 -0
  32. nvmath/bindings/_internal/cutensor.pxd +58 -0
  33. nvmath/bindings/_internal/mathdx.cp314-win_amd64.pyd +0 -0
  34. nvmath/bindings/_internal/mathdx.pxd +116 -0
  35. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  36. nvmath/bindings/_internal/utils.cp314-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/utils.pxd +179 -0
  38. nvmath/bindings/_internal/utils.pyi +10 -0
  39. nvmath/bindings/cublas.cp314-win_amd64.pyd +0 -0
  40. nvmath/bindings/cublas.pxd +558 -0
  41. nvmath/bindings/cublas.pyi +746 -0
  42. nvmath/bindings/cublasLt.cp314-win_amd64.pyd +0 -0
  43. nvmath/bindings/cublasLt.pxd +109 -0
  44. nvmath/bindings/cublasLt.pyi +1337 -0
  45. nvmath/bindings/cublasMp.pxd +85 -0
  46. nvmath/bindings/cublasMp.pyi +219 -0
  47. nvmath/bindings/cudss.cp314-win_amd64.pyd +0 -0
  48. nvmath/bindings/cudss.pxd +86 -0
  49. nvmath/bindings/cudss.pyi +282 -0
  50. nvmath/bindings/cufft.cp314-win_amd64.pyd +0 -0
  51. nvmath/bindings/cufft.pxd +118 -0
  52. nvmath/bindings/cufft.pyi +241 -0
  53. nvmath/bindings/cufftMp.pxd +124 -0
  54. nvmath/bindings/cufftMp.pyi +260 -0
  55. nvmath/bindings/curand.cp314-win_amd64.pyd +0 -0
  56. nvmath/bindings/curand.pxd +71 -0
  57. nvmath/bindings/curand.pyi +159 -0
  58. nvmath/bindings/cusolver.cp314-win_amd64.pyd +0 -0
  59. nvmath/bindings/cusolver.pxd +62 -0
  60. nvmath/bindings/cusolver.pyi +242 -0
  61. nvmath/bindings/cusolverDn.cp314-win_amd64.pyd +0 -0
  62. nvmath/bindings/cusolverDn.pxd +430 -0
  63. nvmath/bindings/cusolverDn.pyi +416 -0
  64. nvmath/bindings/cusparse.cp314-win_amd64.pyd +0 -0
  65. nvmath/bindings/cusparse.pxd +338 -0
  66. nvmath/bindings/cusparse.pyi +659 -0
  67. nvmath/bindings/cusparseLt.cp314-win_amd64.pyd +0 -0
  68. nvmath/bindings/cusparseLt.pxd +99 -0
  69. nvmath/bindings/cusparseLt.pyi +198 -0
  70. nvmath/bindings/cutensor.cp314-win_amd64.pyd +0 -0
  71. nvmath/bindings/cutensor.pxd +98 -0
  72. nvmath/bindings/cutensor.pyi +294 -0
  73. nvmath/bindings/cycublas.cp314-win_amd64.pyd +0 -0
  74. nvmath/bindings/cycublas.pxd +684 -0
  75. nvmath/bindings/cycublasLt.cp314-win_amd64.pyd +0 -0
  76. nvmath/bindings/cycublasLt.pxd +1055 -0
  77. nvmath/bindings/cycublasMp.pxd +183 -0
  78. nvmath/bindings/cycudss.cp314-win_amd64.pyd +0 -0
  79. nvmath/bindings/cycudss.pxd +224 -0
  80. nvmath/bindings/cycufft.cp314-win_amd64.pyd +0 -0
  81. nvmath/bindings/cycufft.pxd +326 -0
  82. nvmath/bindings/cycufftMp.pxd +334 -0
  83. nvmath/bindings/cycurand.cp314-win_amd64.pyd +0 -0
  84. nvmath/bindings/cycurand.pxd +146 -0
  85. nvmath/bindings/cycusolver.cp314-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycusolver.pxd +154 -0
  87. nvmath/bindings/cycusolverDn.cp314-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycusolverDn.pxd +446 -0
  89. nvmath/bindings/cycusparse.cp314-win_amd64.pyd +0 -0
  90. nvmath/bindings/cycusparse.pxd +470 -0
  91. nvmath/bindings/cycusparseLt.cp314-win_amd64.pyd +0 -0
  92. nvmath/bindings/cycusparseLt.pxd +150 -0
  93. nvmath/bindings/cycutensor.cp314-win_amd64.pyd +0 -0
  94. nvmath/bindings/cycutensor.pxd +192 -0
  95. nvmath/bindings/cymathdx.cp314-win_amd64.pyd +0 -0
  96. nvmath/bindings/cymathdx.pxd +552 -0
  97. nvmath/bindings/cynvshmem.pxd +126 -0
  98. nvmath/bindings/mathdx.cp314-win_amd64.pyd +0 -0
  99. nvmath/bindings/mathdx.pxd +182 -0
  100. nvmath/bindings/mathdx.pyi +1244 -0
  101. nvmath/bindings/nvpl/__init__.pxd +0 -0
  102. nvmath/bindings/nvpl/__init__.py +13 -0
  103. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  104. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  105. nvmath/bindings/nvpl/_internal/blas.cp314-win_amd64.pyd +0 -0
  106. nvmath/bindings/nvpl/_internal/blas.pxd +125 -0
  107. nvmath/bindings/nvpl/_internal/fft.cp314-win_amd64.pyd +0 -0
  108. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  109. nvmath/bindings/nvpl/blas.cp314-win_amd64.pyd +0 -0
  110. nvmath/bindings/nvpl/blas.pxd +85 -0
  111. nvmath/bindings/nvpl/blas.pyi +122 -0
  112. nvmath/bindings/nvpl/cyblas.cp314-win_amd64.pyd +0 -0
  113. nvmath/bindings/nvpl/cyblas.pxd +166 -0
  114. nvmath/bindings/nvpl/cyfft.cp314-win_amd64.pyd +0 -0
  115. nvmath/bindings/nvpl/cyfft.pxd +92 -0
  116. nvmath/bindings/nvpl/fft.cp314-win_amd64.pyd +0 -0
  117. nvmath/bindings/nvpl/fft.pxd +100 -0
  118. nvmath/bindings/nvpl/fft.pyi +100 -0
  119. nvmath/bindings/nvshmem.pxd +54 -0
  120. nvmath/bindings/nvshmem.pyi +179 -0
  121. nvmath/device/__init__.py +21 -0
  122. nvmath/device/_deprecated.py +33 -0
  123. nvmath/device/common.py +313 -0
  124. nvmath/device/common_backend.py +131 -0
  125. nvmath/device/common_cuda.py +201 -0
  126. nvmath/device/common_numba.py +310 -0
  127. nvmath/device/common_opaque_tensor.py +201 -0
  128. nvmath/device/cublasdx.py +1805 -0
  129. nvmath/device/cublasdx_backend.py +807 -0
  130. nvmath/device/cublasdx_numba.py +1612 -0
  131. nvmath/device/cufftdx.py +510 -0
  132. nvmath/device/cufftdx_backend.py +196 -0
  133. nvmath/device/cufftdx_numba.py +196 -0
  134. nvmath/device/curand_kernel.py +9147 -0
  135. nvmath/device/cusolverdx.py +2690 -0
  136. nvmath/device/cusolverdx_backend.py +440 -0
  137. nvmath/device/cusolverdx_numba.py +1624 -0
  138. nvmath/device/llvm_array.py +29 -0
  139. nvmath/device/random.py +445 -0
  140. nvmath/device/random_helpers.py +23 -0
  141. nvmath/device/random_states.py +187 -0
  142. nvmath/device/types.py +147 -0
  143. nvmath/device/vector_types_numba.py +203 -0
  144. nvmath/distributed/__init__.py +205 -0
  145. nvmath/distributed/_internal/__init__.py +0 -0
  146. nvmath/distributed/_internal/nvshmem.py +302 -0
  147. nvmath/distributed/_internal/tensor_ifc.py +67 -0
  148. nvmath/distributed/_internal/tensor_ifc_cupy.py +62 -0
  149. nvmath/distributed/_internal/tensor_ifc_host_device.py +165 -0
  150. nvmath/distributed/_internal/tensor_ifc_numpy.py +41 -0
  151. nvmath/distributed/_internal/tensor_ifc_torch.py +141 -0
  152. nvmath/distributed/_internal/tensor_wrapper.py +78 -0
  153. nvmath/distributed/_utils.py +167 -0
  154. nvmath/distributed/distribution.py +770 -0
  155. nvmath/distributed/fft/__init__.py +7 -0
  156. nvmath/distributed/fft/_configuration.py +79 -0
  157. nvmath/distributed/fft/fft.py +2801 -0
  158. nvmath/distributed/linalg/__init__.py +12 -0
  159. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  160. nvmath/distributed/linalg/_internal/epilog_protocol.py +496 -0
  161. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  162. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  163. nvmath/distributed/linalg/advanced/_configuration.py +166 -0
  164. nvmath/distributed/linalg/advanced/matmulmod.py +2908 -0
  165. nvmath/distributed/process_group.py +408 -0
  166. nvmath/distributed/reshape/__init__.py +6 -0
  167. nvmath/distributed/reshape/_configuration.py +39 -0
  168. nvmath/distributed/reshape/reshape.py +1256 -0
  169. nvmath/fft/__init__.py +7 -0
  170. nvmath/fft/_configuration.py +208 -0
  171. nvmath/fft/_exec_utils.py +109 -0
  172. nvmath/fft/_helpers.py +237 -0
  173. nvmath/fft/fft.py +2903 -0
  174. nvmath/internal/__init__.pxd +3 -0
  175. nvmath/internal/__init__.py +10 -0
  176. nvmath/internal/_bindings.cp314-win_amd64.pyd +0 -0
  177. nvmath/internal/_bindings.pxd +12 -0
  178. nvmath/internal/_device_utils.py +54 -0
  179. nvmath/internal/enum_utils.py +142 -0
  180. nvmath/internal/formatters.py +87 -0
  181. nvmath/internal/mem_limit.py +51 -0
  182. nvmath/internal/memory.cp314-win_amd64.pyd +0 -0
  183. nvmath/internal/memory.pxd +10 -0
  184. nvmath/internal/memory.pyi +46 -0
  185. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  186. nvmath/internal/ndbuffer/__init__.py +7 -0
  187. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  188. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  189. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  190. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  191. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +240 -0
  192. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  193. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  194. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  195. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  196. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  197. nvmath/internal/ndbuffer/copy_kernel.cp314-win_amd64.pyd +0 -0
  198. nvmath/internal/ndbuffer/copy_kernel.pxd +9 -0
  199. nvmath/internal/ndbuffer/copy_kernel.pyi +9 -0
  200. nvmath/internal/ndbuffer/data_layout.cp314-win_amd64.pyd +0 -0
  201. nvmath/internal/ndbuffer/data_layout.pxd +72 -0
  202. nvmath/internal/ndbuffer/data_layout.pyi +23 -0
  203. nvmath/internal/ndbuffer/jit.cp314-win_amd64.pyd +0 -0
  204. nvmath/internal/ndbuffer/jit.pxd +7 -0
  205. nvmath/internal/ndbuffer/jit.pyi +6 -0
  206. nvmath/internal/ndbuffer/ndbuffer.cp314-win_amd64.pyd +0 -0
  207. nvmath/internal/ndbuffer/ndbuffer.pxd +36 -0
  208. nvmath/internal/ndbuffer/ndbuffer.pyi +41 -0
  209. nvmath/internal/ndbuffer/package_utils.cp314-win_amd64.pyd +0 -0
  210. nvmath/internal/ndbuffer/package_utils.pxd +11 -0
  211. nvmath/internal/ndbuffer/package_utils.pyi +12 -0
  212. nvmath/internal/package_ifc.py +147 -0
  213. nvmath/internal/package_ifc_cuda.py +49 -0
  214. nvmath/internal/package_ifc_cupy.py +49 -0
  215. nvmath/internal/package_ifc_torch.py +31 -0
  216. nvmath/internal/package_wrapper.py +14 -0
  217. nvmath/internal/tensor_ifc.py +194 -0
  218. nvmath/internal/tensor_ifc_cupy.py +241 -0
  219. nvmath/internal/tensor_ifc_ndbuffer.py +153 -0
  220. nvmath/internal/tensor_ifc_numpy.py +183 -0
  221. nvmath/internal/tensor_ifc_torch.py +176 -0
  222. nvmath/internal/tensor_wrapper.py +157 -0
  223. nvmath/internal/typemaps.py +162 -0
  224. nvmath/internal/utils.py +771 -0
  225. nvmath/linalg/__init__.py +46 -0
  226. nvmath/linalg/_internal/__init__.py +3 -0
  227. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  228. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  229. nvmath/linalg/_internal/batch.py +217 -0
  230. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  231. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  232. nvmath/linalg/_internal/layout.py +624 -0
  233. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  234. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  235. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  236. nvmath/linalg/_internal/typemaps.py +144 -0
  237. nvmath/linalg/_internal/utils.py +134 -0
  238. nvmath/linalg/advanced/__init__.py +8 -0
  239. nvmath/linalg/advanced/_algorithmmod.py +149 -0
  240. nvmath/linalg/advanced/_configuration.py +349 -0
  241. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  242. nvmath/linalg/advanced/helpers/matmul.py +1348 -0
  243. nvmath/linalg/advanced/matmulmod.py +3937 -0
  244. nvmath/linalg/generic/__init__.py +43 -0
  245. nvmath/linalg/generic/_configuration/__init__.py +37 -0
  246. nvmath/linalg/generic/_configuration/layout.py +263 -0
  247. nvmath/linalg/generic/_configuration/match.py +609 -0
  248. nvmath/linalg/generic/_configuration/qualifiers.py +494 -0
  249. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  250. nvmath/linalg/generic/_dtype.py +15 -0
  251. nvmath/linalg/generic/matmulmod.py +1060 -0
  252. nvmath/memory.py +282 -0
  253. nvmath/sparse/__init__.py +38 -0
  254. nvmath/sparse/_internal/__init__.py +21 -0
  255. nvmath/sparse/_internal/common_utils.py +144 -0
  256. nvmath/sparse/_internal/cudss_config_ifc.py +741 -0
  257. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  258. nvmath/sparse/_internal/cudss_utils.py +445 -0
  259. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  260. nvmath/sparse/_internal/sparse_bsc_ifc.py +300 -0
  261. nvmath/sparse/_internal/sparse_bsr_ifc.py +303 -0
  262. nvmath/sparse/_internal/sparse_coo_ifc.py +254 -0
  263. nvmath/sparse/_internal/sparse_csc_ifc.py +266 -0
  264. nvmath/sparse/_internal/sparse_csr_ifc.py +266 -0
  265. nvmath/sparse/_internal/sparse_dia_ifc.py +239 -0
  266. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  267. nvmath/sparse/_internal/sparse_tensor_ifc.py +121 -0
  268. nvmath/sparse/_internal/sparse_ust_ifc.py +146 -0
  269. nvmath/sparse/_internal/utils.py +56 -0
  270. nvmath/sparse/advanced/__init__.py +7 -0
  271. nvmath/sparse/advanced/_configuration.py +230 -0
  272. nvmath/sparse/advanced/direct_solver.py +1884 -0
  273. nvmath/sparse/generic/__init__.py +7 -0
  274. nvmath/sparse/generic/_configuration.py +129 -0
  275. nvmath/sparse/generic/_helpers.py +137 -0
  276. nvmath/sparse/generic/_thunks.py +21 -0
  277. nvmath/sparse/generic/matmulmod.py +2426 -0
  278. nvmath/sparse/ust/__init__.py +7 -0
  279. nvmath/sparse/ust/_converters.py +378 -0
  280. nvmath/sparse/ust/_drawer.py +552 -0
  281. nvmath/sparse/ust/_emitter.py +553 -0
  282. nvmath/sparse/ust/_jit.py +212 -0
  283. nvmath/sparse/ust/_kernel.py +346 -0
  284. nvmath/sparse/ust/_semiring.py +71 -0
  285. nvmath/sparse/ust/_utils.py +102 -0
  286. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  287. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  288. nvmath/sparse/ust/semiring_ops.py +71 -0
  289. nvmath/sparse/ust/tensor.py +1027 -0
  290. nvmath/sparse/ust/tensor_drawer.py +552 -0
  291. nvmath/sparse/ust/tensor_emitter.py +558 -0
  292. nvmath/sparse/ust/tensor_format.py +935 -0
  293. nvmath/sparse/ust/tensor_jit.py +212 -0
  294. nvmath/sparse/ust/tensor_kernel.py +348 -0
  295. nvmath/sparse/ust/tensor_utils.py +380 -0
  296. nvmath/tensor/__init__.py +6 -0
  297. nvmath/tensor/_configuration.py +95 -0
  298. nvmath/tensor/_internal/__init__.py +3 -0
  299. nvmath/tensor/_internal/cutensor_config_ifc.py +247 -0
  300. nvmath/tensor/_internal/cutensor_utils.py +162 -0
  301. nvmath/tensor/_internal/data.py +43 -0
  302. nvmath/tensor/_internal/einsum_parser.py +444 -0
  303. nvmath/tensor/_internal/typemaps.py +96 -0
  304. nvmath/tensor/contract.py +1861 -0
  305. nvmath_python-0.9.0.dist-info/METADATA +127 -0
  306. nvmath_python-0.9.0.dist-info/RECORD +309 -0
  307. nvmath_python-0.9.0.dist-info/WHEEL +5 -0
  308. nvmath_python-0.9.0.dist-info/licenses/LICENSE +177 -0
  309. nvmath_python-0.9.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,510 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = ["fft", "FFT", "compile_fft_execute"]
6
+ import warnings
7
+ from functools import cached_property
8
+ from typing import Any
9
+
10
+ from nvmath.bindings import mathdx
11
+ from nvmath.internal.utils import docstring_decorator
12
+
13
+ from ._deprecated import deprecated
14
+ from .common import (
15
+ SHARED_DEVICE_DOCSTRINGS,
16
+ check_code_type,
17
+ parse_code_type,
18
+ parse_sm,
19
+ )
20
+ from .common_backend import MATHDX_TYPES_TO_NP, get_isa_version, get_lto
21
+ from .common_cuda import (
22
+ Code,
23
+ Dim3,
24
+ )
25
+ from .cufftdx_backend import (
26
+ generate_code,
27
+ generate_FFT,
28
+ get_data_type_trait,
29
+ get_int_trait,
30
+ get_int_traits,
31
+ get_knobs,
32
+ get_str_trait,
33
+ validate,
34
+ validate_execute_api,
35
+ )
36
+
37
+ CUFFTDX_DATABASE = None
38
+
39
+ FFTDX_DOCSTRING = SHARED_DEVICE_DOCSTRINGS.copy()
40
+ FFTDX_DOCSTRING.update(
41
+ {
42
+ "size": """\
43
+ The size of the FFT to calculate.""".replace("\n", " "),
44
+ #
45
+ "fft_type": """\
46
+ A string specifying the type of FFT operation, can be ``'c2c'``, ``'c2r'`` or ``'r2c'``.""".replace("\n", " "),
47
+ #
48
+ "direction": """\
49
+ A string specifying the direction of FFT, can be ``'forward'`` or ``'inverse'``. If not provided, will be ``'forward'``
50
+ if real-to-complex FFT is specified and ``'inverse'`` if complex-to-real FFT is specified.""".replace("\n", " "),
51
+ #
52
+ "ffts_per_block": """\
53
+ The number of FFTs calculated per CUDA block, optional. The default is 1. Alternatively, if provided as ``'suggested'``
54
+ will be set to a suggested value""".replace("\n", " "),
55
+ #
56
+ "elements_per_thread": """\
57
+ The number of elements per thread, optional. The default is 1. Alternatively, if provided as ``'suggested'``, will be
58
+ set to a suggested value. """.replace("\n", " "),
59
+ #
60
+ "real_fft_options": """\
61
+ A dictionary specifying the options for real FFT operation, optional.""".replace("\n", " "),
62
+ "execute_api": """\
63
+ A string specifying the signature of the function that handles problems with input in register or in shared memory buffers.
64
+ Could be ``'shared_memory'`` or ``'register_memory'``.""".replace("\n", " "),
65
+ }
66
+ )
67
+
68
+ _workspace_deprecation_warning = lambda: warnings.warn(
69
+ "Using workspaces is deprecated and will be removed in future release.", DeprecationWarning
70
+ )
71
+
72
+
73
+ @docstring_decorator(FFTDX_DOCSTRING, skip_missing=False)
74
+ class FFT:
75
+ """
76
+ A class that encapsulates a partial FFT device function. A partial device function can
77
+ be queried for available or optimal values for some knobs (such as `ffts_per_block`
78
+ or `elements_per_thread`). It does not contain a compiled, ready-to-use,
79
+ device function until finalized using :meth:`create`.
80
+
81
+ .. versionchanged:: 0.7.0
82
+ `FFT` has replaced `FFTOptions` and `FFTOptionsComplete`.
83
+
84
+ Args:
85
+ size (int): {size}
86
+
87
+ precision (str): {precision}
88
+
89
+ fft_type (str): {fft_type}
90
+
91
+ sm (ComputeCapability): {sm}
92
+
93
+ execution (str): {execution}
94
+
95
+ direction (str): {direction}
96
+
97
+ ffts_per_block (int): {ffts_per_block}
98
+
99
+ elements_per_thread (int): {elements_per_thread}
100
+
101
+ real_fft_options (dict): {real_fft_options} User may specify the following options
102
+ in the dictionary:
103
+
104
+ - ``'complex_layout'``, currently supports ``'natural'``, ``'packed'``, and
105
+ ``'full'``.
106
+ - ``'real_mode'``, currently supports ``'normal'`` and ``'folded``.
107
+
108
+ .. seealso::
109
+ The attributes of this class provide a 1:1 mapping with the CUDA C++ cuFFTDx APIs.
110
+ For further details, please refer to :cufftdx_doc:`cuFFTDx documentation
111
+ <index.html>`.
112
+ """
113
+
114
+ def __init__(
115
+ self,
116
+ size,
117
+ precision,
118
+ fft_type,
119
+ execution,
120
+ *,
121
+ sm=None,
122
+ direction=None,
123
+ ffts_per_block=None,
124
+ elements_per_thread=None,
125
+ real_fft_options=None,
126
+ ):
127
+ sm = parse_sm(sm)
128
+
129
+ #
130
+ # Check that the knobs are, individually, valid
131
+ #
132
+
133
+ validate(
134
+ size=size,
135
+ precision=precision,
136
+ fft_type=fft_type,
137
+ sm=sm,
138
+ execution=execution,
139
+ direction=direction,
140
+ ffts_per_block=ffts_per_block,
141
+ elements_per_thread=elements_per_thread,
142
+ real_fft_options=real_fft_options,
143
+ )
144
+
145
+ if direction is None and fft_type == "r2c":
146
+ direction = "forward"
147
+ elif direction is None and fft_type == "c2r":
148
+ direction = "inverse"
149
+
150
+ #
151
+ # Traits set by input
152
+ #
153
+
154
+ self._precision = precision
155
+ self._fft_type = fft_type
156
+ self._direction = direction
157
+ self._size = size
158
+ self._execution = execution
159
+ self._ffts_per_block = ffts_per_block
160
+ self._elements_per_thread = elements_per_thread
161
+ self._real_fft_options = real_fft_options
162
+ self._sm = sm
163
+
164
+ #
165
+ # Update suggested traits
166
+ #
167
+
168
+ if elements_per_thread == "suggested":
169
+ self._elements_per_thread = self._suggested_elements_per_thread
170
+
171
+ if ffts_per_block == "suggested":
172
+ self._ffts_per_block = self._suggested_ffts_per_block
173
+
174
+ @cached_property
175
+ def _traits(self):
176
+ return _FFTTraits(self)
177
+
178
+ @property
179
+ def elements_per_thread(self):
180
+ if self._elements_per_thread is None:
181
+ return self._traits.elements_per_thread
182
+ return self._elements_per_thread
183
+
184
+ @property
185
+ def precision(self):
186
+ return self._precision
187
+
188
+ @property
189
+ def ffts_per_block(self):
190
+ if self._ffts_per_block is None:
191
+ return self._traits.ffts_per_block
192
+ return self._ffts_per_block
193
+
194
+ @property
195
+ def fft_type(self):
196
+ return self._fft_type
197
+
198
+ @property
199
+ def direction(self):
200
+ return self._direction
201
+
202
+ @property
203
+ def size(self):
204
+ return self._size
205
+
206
+ @property
207
+ def execution(self):
208
+ return self._execution
209
+
210
+ @property
211
+ def real_fft_options(self):
212
+ return self._real_fft_options
213
+
214
+ @property
215
+ def sm(self):
216
+ return self._sm
217
+
218
+ #
219
+ # Extensions
220
+ #
221
+
222
+ def valid(self, *knobs):
223
+ if not (set(knobs) <= {"ffts_per_block", "elements_per_thread"}):
224
+ raise ValueError(f"Unsupported knob. Only valid knobs are ffts_per_block and elements_per_thread but got {knobs}")
225
+
226
+ return self._get_knobs(*knobs)
227
+
228
+ @deprecated("definition is deprecated and may be removed in future versions")
229
+ def definition(self):
230
+ """
231
+ .. deprecated:: 0.7.0
232
+ """
233
+ dd = {
234
+ "size": self.size,
235
+ "precision": self.precision,
236
+ "fft_type": self.fft_type,
237
+ "sm": self.sm,
238
+ "execution": self.execution,
239
+ "direction": self.direction,
240
+ "ffts_per_block": self.ffts_per_block,
241
+ "elements_per_thread": self.elements_per_thread,
242
+ "real_fft_options": self.real_fft_options,
243
+ }
244
+ return dd
245
+
246
+ @deprecated("create is deprecated and may be removed in future versions. Use `functools.partial` instead")
247
+ def create(self, **kwargs):
248
+ """
249
+ Creates a copy of the instance with provided arguments updated.
250
+
251
+ .. deprecated:: 0.7.0
252
+ Please use :py:func:`functools.partial` instead.
253
+ """
254
+ code_type = kwargs.pop("code_type", None)
255
+ if code_type is not None:
256
+ DeprecationWarning("code_type is deprecated and will be removed in future releases. It is no longer needed.")
257
+ compiler = kwargs.pop("compiler", None)
258
+ if compiler is not None:
259
+ DeprecationWarning("compiler is deprecated and will be removed in future releases. It is no longer needed.")
260
+ dd = self.definition()
261
+ dd.update(**kwargs)
262
+ return FFT(**dd)
263
+
264
+ @property
265
+ def value_type(self):
266
+ return self._traits.value_type
267
+
268
+ @property
269
+ def input_type(self):
270
+ return self._traits.input_type
271
+
272
+ @property
273
+ def output_type(self):
274
+ return self._traits.output_type
275
+
276
+ @property
277
+ def storage_size(self):
278
+ return self._traits.storage_size
279
+
280
+ @property
281
+ def shared_memory_size(self):
282
+ return self._traits.shared_memory_size
283
+
284
+ @property
285
+ def stride(self):
286
+ return self._traits.stride
287
+
288
+ @property
289
+ def block_dim(self):
290
+ return self._traits.block_dim
291
+
292
+ @property
293
+ def requires_workspace(self):
294
+ _workspace_deprecation_warning()
295
+ return False
296
+
297
+ @property
298
+ def workspace_size(self):
299
+ return self._traits.workspace_size
300
+
301
+ @property
302
+ def implicit_type_batching(self):
303
+ return self._traits.implicit_type_batching
304
+
305
+ @property
306
+ def extensions(self):
307
+ raise NotImplementedError("Extensions not supported yet")
308
+
309
+ def execute(*args):
310
+ raise RuntimeError("execute is a device function and can not be called on host.")
311
+
312
+ @deprecated("Calling MM(...) directly is deprecated, please use MM.execute(...) method instead.")
313
+ def __call__(self, *args):
314
+ raise RuntimeError("__call__ is a device function and can not be called on host.")
315
+
316
+ @property
317
+ @deprecated("files is deprecated and is no longer required and will be removed in future releases.")
318
+ def files(self) -> list:
319
+ return []
320
+
321
+ #
322
+ # Private implementations
323
+ #
324
+
325
+ def _suggested(self, what):
326
+ # Generate full PTX
327
+ h = generate_FFT(
328
+ size=self._size,
329
+ precision=self._precision,
330
+ fft_type=self._fft_type,
331
+ direction=self._direction,
332
+ ffts_per_block=(None if self._ffts_per_block == "suggested" else self._ffts_per_block),
333
+ elements_per_thread=(None if self._elements_per_thread == "suggested" else self._elements_per_thread),
334
+ real_fft_options=frozenset(self._real_fft_options.items()) if self._real_fft_options else None,
335
+ sm=self._sm,
336
+ execution=self._execution,
337
+ )
338
+
339
+ if what == "elements_per_thread":
340
+ return get_int_trait(h.descriptor, mathdx.CufftdxTraitType.ELEMENTS_PER_THREAD)
341
+
342
+ if what == "suggested_ffts_per_block":
343
+ return get_int_trait(h.descriptor, mathdx.CufftdxTraitType.SUGGESTED_FFTS_PER_BLOCK)
344
+
345
+ raise Exception(f"Unknown suggested option '{what}'")
346
+
347
+ @cached_property
348
+ def _suggested_ffts_per_block(self):
349
+ return self._suggested("suggested_ffts_per_block")
350
+
351
+ @cached_property
352
+ def _suggested_elements_per_thread(self):
353
+ return self._suggested("elements_per_thread")
354
+
355
+ def _get_knobs(self, *knobs):
356
+ if not (set(knobs) <= {"ffts_per_block", "elements_per_thread"}):
357
+ raise ValueError(f"Unsupported knob. Only valid knobs are ffts_per_block and elements_per_thread but got {knobs}")
358
+
359
+ h = generate_FFT(
360
+ size=self._size,
361
+ precision=self._precision,
362
+ fft_type=self._fft_type,
363
+ direction=self._direction,
364
+ ffts_per_block=self._ffts_per_block,
365
+ elements_per_thread=self._elements_per_thread,
366
+ real_fft_options=frozenset(self._real_fft_options.items()) if self._real_fft_options else None,
367
+ sm=self._sm,
368
+ execution=self._execution,
369
+ )
370
+
371
+ return get_knobs(h.descriptor, knobs)
372
+
373
+
374
+ class _FFTTraits:
375
+ def __init__(self, FFT: FFT):
376
+ h = generate_FFT(
377
+ size=FFT._size,
378
+ precision=FFT._precision,
379
+ fft_type=FFT._fft_type,
380
+ direction=FFT._direction,
381
+ sm=FFT._sm,
382
+ execution=FFT._execution,
383
+ ffts_per_block=FFT._ffts_per_block if FFT._execution == "Block" else None,
384
+ elements_per_thread=FFT._elements_per_thread if FFT._execution == "Block" else None,
385
+ real_fft_options=frozenset(FFT._real_fft_options.items()) if FFT._real_fft_options else None,
386
+ ).descriptor
387
+
388
+ self.value_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.VALUE_TYPE)]
389
+ self.input_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.INPUT_TYPE)]
390
+ self.output_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.OUTPUT_TYPE)]
391
+
392
+ self.storage_size = get_int_trait(h, mathdx.CufftdxTraitType.STORAGE_SIZE)
393
+ self.stride = get_int_trait(h, mathdx.CufftdxTraitType.STRIDE)
394
+ self.elements_per_thread = get_int_trait(h, mathdx.CufftdxTraitType.ELEMENTS_PER_THREAD)
395
+ self.implicit_type_batching = get_int_trait(h, mathdx.CufftdxTraitType.IMPLICIT_TYPE_BATCHING)
396
+
397
+ self.workspace_size = 0
398
+ if FFT.execution == "Block":
399
+ self.block_dim: Dim3 | None = Dim3(*get_int_traits(h, mathdx.CufftdxTraitType.BLOCK_DIM, 3))
400
+ self.shared_memory_size: int | None = get_int_trait(h, mathdx.CufftdxTraitType.SHARED_MEMORY_SIZE)
401
+ self.ffts_per_block: int | None = get_int_trait(h, mathdx.CufftdxTraitType.FFTS_PER_BLOCK)
402
+ else:
403
+ self.block_dim = None
404
+ self.shared_memory_size = None
405
+ self.ffts_per_block = None
406
+
407
+
408
+ def compile_fft_execute(
409
+ fft: FFT,
410
+ code_type: Any,
411
+ execute_api: str | None = None,
412
+ ) -> tuple[Code, str]:
413
+ code_type = parse_code_type(code_type)
414
+ check_code_type(code_type, "cuFFTDx")
415
+ validate_execute_api(fft.execution, execute_api)
416
+
417
+ h = generate_FFT(
418
+ size=fft._size,
419
+ precision=fft._precision,
420
+ fft_type=fft._fft_type,
421
+ direction=fft._direction,
422
+ sm=fft._sm,
423
+ execution=fft._execution,
424
+ ffts_per_block=fft._ffts_per_block if fft._execution == "Block" else None,
425
+ elements_per_thread=fft._elements_per_thread if fft._execution == "Block" else None,
426
+ real_fft_options=frozenset(fft._real_fft_options.items()) if fft._real_fft_options else None,
427
+ execute_api=execute_api,
428
+ ).descriptor
429
+
430
+ code = generate_code(h, code_type.cc)
431
+
432
+ # Compile
433
+ lto_fn = get_lto(code.descriptor)
434
+ isa_version = get_isa_version(code.descriptor)
435
+
436
+ symbol = get_str_trait(h, mathdx.CufftdxTraitType.SYMBOL_NAME)
437
+
438
+ return Code(code_type, isa_version, lto_fn), symbol
439
+
440
+
441
+ @docstring_decorator(FFTDX_DOCSTRING, skip_missing=False)
442
+ def fft(*, compiler=None, code_type=None, execute_api=None, **kwargs):
443
+ """
444
+ Create an :class:`FFT` object that encapsulates a compiled and ready-to-use FFT
445
+ device function.
446
+
447
+ .. deprecated:: 0.7.0
448
+
449
+ Args:
450
+ size (int): {size}
451
+
452
+ precision (str): {precision}
453
+
454
+ fft_type (str): {fft_type}
455
+
456
+ sm (ComputeCapability): {sm}
457
+
458
+ execution (str): {execution}
459
+
460
+ direction (str): {direction}
461
+
462
+ ffts_per_block (int): {ffts_per_block}
463
+
464
+ elements_per_thread (int): {elements_per_thread}
465
+
466
+ real_fft_options (dict): {real_fft_options} User may specify the following options
467
+ in the dictionary:
468
+
469
+ - ``'complex_layout'``, currently supports ``'natural'``, ``'packed'``, and
470
+ ``'full'``.
471
+ - ``'real_mode'``, currently supports ``'normal'`` and ``'folded'``.
472
+
473
+ compiler: {compiler}
474
+
475
+ .. versionchanged:: 0.7.0
476
+ compiler is no longer needed and does not take effect. Use
477
+ :py:func:`nvmath.device.compile_fft_execute` to get device
478
+ function code.
479
+
480
+ code_type (CodeType): {code_type}
481
+
482
+ .. versionchanged:: 0.7.0
483
+ code_type should be used by
484
+ :py:func:`nvmath.device.compile_fft_execute` and no longer
485
+ needed for numba-cuda usage.
486
+
487
+ execute_api (str): {execute_api}
488
+
489
+ .. versionchanged:: 0.7.0
490
+ execute_api should be used by
491
+ :py:func:`nvmath.device.compile_fft_execute` and no longer
492
+ needed for numba-cuda usage.
493
+
494
+ .. seealso::
495
+ The attributes of :class:`FFT` provide a 1:1 mapping with the CUDA C++
496
+ cuFFTDx APIs. For further details, please refer to
497
+ :cufftdx_doc:`cuFFTDx documentation <index.html>`.
498
+
499
+ Examples:
500
+ Examples can be found in the `nvmath/examples/device
501
+ <https://github.com/NVIDIA/nvmath-python/tree/main/examples/device>`_ directory.
502
+ """
503
+ DeprecationWarning("fft is deprecated and will be removed in future releases. Please use FFT class directly.")
504
+ if code_type is not None:
505
+ DeprecationWarning("code_type is deprecated and will be removed in future releases. It is no longer needed.")
506
+ if compiler is not None:
507
+ DeprecationWarning("compiler is deprecated and will be removed in future releases. It is no longer needed.")
508
+ if execute_api is not None:
509
+ DeprecationWarning("execute_api is deprecated and will be removed in future releases. It is no longer needed.")
510
+ return FFT(**kwargs)
@@ -0,0 +1,196 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from collections.abc import Sequence
6
+ from functools import lru_cache
7
+ from typing import Protocol
8
+
9
+ import numpy
10
+
11
+ from nvmath.bindings import mathdx
12
+ from nvmath.device.common_backend import DescriptorWrapper
13
+ from nvmath.device.common_cuda import ComputeCapability
14
+
15
+ from .common import check_contains, check_in, check_not_in, check_sm
16
+ from .common_backend import (
17
+ EXECUTION_STR_TO_MATHDX,
18
+ NP_TYPES_TO_MATHDX_PRECISION,
19
+ NVARG_GEN_OPT_LTO,
20
+ build_get_int_traits,
21
+ build_get_str_trait,
22
+ set_code_target_sm,
23
+ )
24
+ from .types import REAL_NP_TYPES
25
+
26
+ _FFT_TYPE_TO_MATHDX = {t.name.lower(): t for t in mathdx.CufftdxType}
27
+
28
+ _FFT_DIRECTION_TO_MATHDX = {d.name.lower(): d for d in mathdx.CufftdxDirection}
29
+
30
+ _FFT_COMPLEX_LAYOUT_TO_MATHDX = {cl.name.lower(): cl for cl in mathdx.CufftdxComplexLayout}
31
+
32
+ _FFT_REAL_MODE_TO_MATHDX = {m.name.lower(): m for m in mathdx.CufftdxRealMode}
33
+
34
+ _FFT_API_STR_TO_MATHDX = {
35
+ "register_memory": mathdx.CufftdxApi.LMEM,
36
+ "shared_memory": mathdx.CufftdxApi.SMEM,
37
+ }
38
+
39
+ _FFT_KNOB_TYPE_TO_MATHDX = {t.name.lower(): t for t in mathdx.CufftdxKnobType}
40
+
41
+
42
+ class CallableGetIntTraits(Protocol):
43
+ def __call__(self, handle: int, trait_type: mathdx.CufftdxTraitType, size: int) -> tuple: ...
44
+
45
+
46
+ class CallableGetStrTrait(Protocol):
47
+ def __call__(self, handle: int, trait_type: mathdx.CufftdxTraitType) -> str: ...
48
+
49
+
50
+ get_int_traits: CallableGetIntTraits = build_get_int_traits(mathdx.cufftdx_get_trait_int64s)
51
+
52
+ get_str_trait: CallableGetStrTrait = build_get_str_trait(mathdx.cufftdx_get_trait_str_size, mathdx.cufftdx_get_trait_str)
53
+
54
+
55
+ def get_int_trait(handle: int, trait_type: mathdx.CufftdxTraitType) -> int:
56
+ return int(mathdx.cufftdx_get_trait_int64(handle, trait_type))
57
+
58
+
59
+ def get_data_type_trait(handle: int, trait_type: mathdx.CufftdxTraitType) -> mathdx.CommondxValueType:
60
+ return mathdx.CommondxValueType(mathdx.cufftdx_get_trait_commondx_data_type(handle, trait_type))
61
+
62
+
63
+ def validate(
64
+ size,
65
+ precision,
66
+ fft_type,
67
+ execution,
68
+ direction,
69
+ ffts_per_block,
70
+ elements_per_thread,
71
+ real_fft_options,
72
+ sm,
73
+ ):
74
+ if size <= 0:
75
+ raise ValueError(f"size must be > 0. Got {size}")
76
+ check_in("precision", precision, REAL_NP_TYPES)
77
+ check_in("fft_type", fft_type, ["c2c", "c2r", "r2c"])
78
+ check_in("execution", execution, ["Block", "Thread"])
79
+ if direction is not None:
80
+ check_in("direction", direction, ["forward", "inverse"])
81
+ if ffts_per_block in (None, "suggested"):
82
+ pass
83
+ else:
84
+ if ffts_per_block <= 0:
85
+ raise ValueError(
86
+ f"ffts_per_block must be None, 'suggested' or a positive integer ; got ffts_per_block = {ffts_per_block}"
87
+ )
88
+ if elements_per_thread in (None, "suggested"):
89
+ pass
90
+ else:
91
+ if elements_per_thread <= 0:
92
+ raise ValueError(
93
+ f"elements_per_thread must be None, 'suggested' or a positive integer ; "
94
+ f"got elements_per_thread = {elements_per_thread}"
95
+ )
96
+ if real_fft_options is None:
97
+ pass
98
+ else:
99
+ check_contains(real_fft_options, "complex_layout")
100
+ check_contains(real_fft_options, "real_mode")
101
+ check_in("real_fft_options['complex_layout']", real_fft_options["complex_layout"], ["natural", "packed", "full"])
102
+ check_in("real_fft_options['real_mode']", real_fft_options["real_mode"], ["normal", "folded"])
103
+ check_sm(sm, "sm")
104
+
105
+
106
+ def validate_execute_api(execution: str, execute_api: str | None):
107
+ """
108
+ Validate the execute_api argument.
109
+ """
110
+ if execution == "Block":
111
+ check_in("execute_api", execute_api, list(_FFT_API_STR_TO_MATHDX.keys()) + [None])
112
+ else:
113
+ if execute_api is not None:
114
+ raise ValueError(f"api may be set only for block execution ; got execution = {execution}")
115
+
116
+
117
+ @lru_cache
118
+ def generate_FFT(
119
+ size,
120
+ precision,
121
+ fft_type,
122
+ direction,
123
+ sm,
124
+ execution,
125
+ ffts_per_block,
126
+ elements_per_thread,
127
+ real_fft_options,
128
+ execute_api=None,
129
+ ):
130
+ check_not_in("ffts_per_block", ffts_per_block, ["suggested"])
131
+ check_not_in("elements_per_thread", elements_per_thread, ["suggested"])
132
+
133
+ h = mathdx.cufftdx_create_descriptor()
134
+
135
+ # TODO: remove after migrating to libmathdx 0.2.4+
136
+ if execute_api is None:
137
+ execute_api = "register_memory"
138
+
139
+ if execute_api is not None:
140
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.API, _FFT_API_STR_TO_MATHDX[execute_api])
141
+
142
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.SM, sm.major * 100 + sm.minor * 10)
143
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.SIZE, size)
144
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.PRECISION, NP_TYPES_TO_MATHDX_PRECISION[precision])
145
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.TYPE, _FFT_TYPE_TO_MATHDX[fft_type])
146
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.DIRECTION, _FFT_DIRECTION_TO_MATHDX[direction])
147
+
148
+ if real_fft_options:
149
+ real_fft_options = dict(real_fft_options)
150
+ ll = real_fft_options["complex_layout"]
151
+ mm = real_fft_options["real_mode"]
152
+ mathdx.cufftdx_set_operator_int64s(
153
+ h, mathdx.CufftdxOperatorType.REAL_FFT_OPTIONS, 2, [_FFT_COMPLEX_LAYOUT_TO_MATHDX[ll], _FFT_REAL_MODE_TO_MATHDX[mm]]
154
+ )
155
+
156
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.EXECUTION, EXECUTION_STR_TO_MATHDX[execution])
157
+
158
+ if ffts_per_block:
159
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.FFTS_PER_BLOCK, ffts_per_block)
160
+
161
+ if elements_per_thread:
162
+ mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.ELEMENTS_PER_THREAD, elements_per_thread)
163
+
164
+ return DescriptorWrapper(h, mathdx.cufftdx_destroy_descriptor)
165
+
166
+
167
+ @lru_cache
168
+ def generate_code(handle, version: ComputeCapability):
169
+ code = mathdx.commondx_create_code()
170
+
171
+ set_code_target_sm(code, version)
172
+ mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVRTC_ARGS, NVARG_GEN_OPT_LTO)
173
+ mathdx.cufftdx_finalize_code(code, handle)
174
+
175
+ return DescriptorWrapper(code, mathdx.commondx_destroy_code)
176
+
177
+
178
+ @lru_cache
179
+ def get_knobs(handle, knobs: Sequence[str]):
180
+ knobs_dx: list[mathdx.CufftdxKnobType] = [_FFT_KNOB_TYPE_TO_MATHDX[k] for k in knobs]
181
+ knobs_size = mathdx.cufftdx_get_knob_int64size(handle, len(knobs), knobs_dx)
182
+
183
+ knobs_result_dx = numpy.empty(knobs_size, dtype=numpy.int64)
184
+ mathdx.cufftdx_get_knob_int64s(
185
+ handle,
186
+ len(knobs),
187
+ knobs_dx,
188
+ knobs_size,
189
+ knobs_result_dx.ctypes.data,
190
+ )
191
+
192
+ knobs_result = [
193
+ tuple(int(knobs_result_dx[j]) for j in range(i, i + len(knobs))) for i in range(0, len(knobs_result_dx), len(knobs))
194
+ ]
195
+
196
+ return knobs_result