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,183 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use Numpy ndarray objects.
7
+ """
8
+
9
+ __all__ = ["NumpyTensor", "CudaTensor"]
10
+
11
+ from collections.abc import Sequence
12
+
13
+ import numpy
14
+ import numpy.typing as npt
15
+
16
+ from nvmath.internal.tensor_ifc_ndbuffer import NDBufferTensor
17
+
18
+ from . import utils
19
+ from .ndbuffer import ndbuffer, package_utils
20
+ from .package_ifc import StreamHolder
21
+ from .tensor_ifc import TensorHolder
22
+
23
+
24
+ class CudaTensor(NDBufferTensor):
25
+ """
26
+ Wraps ndbuffer with data residing on the GPU.
27
+ It serves as a CUDA counterpart for NumpyTensor.
28
+ """
29
+
30
+ name = "cuda"
31
+ host_tensor_class: type["NumpyTensor"] # set once NumpyTensor is defined
32
+
33
+ def __init__(self, tensor):
34
+ super().__init__(tensor)
35
+
36
+ @classmethod
37
+ def create_from_host(cls, tensor: TensorHolder, device_id: int, stream_holder: StreamHolder):
38
+ with utils.device_ctx(device_id):
39
+ src_ndbuffer = tensor.asndbuffer()
40
+ dst_ndbuffer = ndbuffer.empty_like(src_ndbuffer, device_id=device_id, stream=stream_holder)
41
+ ndbuffer.copy_into(dst_ndbuffer, src_ndbuffer, stream_holder)
42
+ return cls(dst_ndbuffer)
43
+
44
+ def to(self, device_id, stream_holder):
45
+ if device_id == "cpu":
46
+ with utils.device_ctx(self.device_id):
47
+ dst = self.host_tensor_class.create_host_from(self, stream_holder)
48
+ return dst
49
+ elif device_id == self.device_id:
50
+ return self
51
+ elif isinstance(device_id, int):
52
+ raise ValueError(f"Unsupported copy between different devices {self.device_id} and {device_id}.")
53
+ else:
54
+ raise ValueError(f"The device must be specified as an integer or 'cpu', not '{device_id}'.")
55
+
56
+
57
+ class NumpyTensor(TensorHolder[npt.NDArray]):
58
+ """
59
+ TensorHolder for numpy ndarrays.
60
+ """
61
+
62
+ name = "numpy"
63
+ module = numpy
64
+ name_to_dtype = TensorHolder.create_name_dtype_map(
65
+ conversion_function=lambda name: numpy.dtype(name), exception_type=TypeError
66
+ )
67
+
68
+ device_tensor_class = CudaTensor
69
+
70
+ def __init__(self, tensor):
71
+ super().__init__(tensor)
72
+
73
+ @property
74
+ def data_ptr(self):
75
+ return self.tensor.ctypes.data
76
+
77
+ @property
78
+ def device(self):
79
+ return "cpu"
80
+
81
+ @property
82
+ def device_id(self):
83
+ return "cpu"
84
+
85
+ @property
86
+ def dtype(self):
87
+ """Name of the data type"""
88
+ return self.tensor.dtype.name
89
+
90
+ @property
91
+ def itemsize(self):
92
+ return self.tensor.itemsize
93
+
94
+ @classmethod
95
+ def empty(cls, shape, device_id="cpu", *, dtype="float32", strides=None, **context):
96
+ """
97
+ Create an empty tensor of the specified shape and data type.
98
+ """
99
+ assert device_id == "cpu", "Internal Error: Numpy tensors must be allocated with device_id='cpu'"
100
+ dtype = NumpyTensor.name_to_dtype[dtype]
101
+ # when strides is not None, it should be of unit counts not bytes
102
+ return cls(
103
+ cls.module.ndarray(shape, dtype=dtype, strides=(tuple(s * dtype.itemsize for s in strides) if strides else None))
104
+ )
105
+
106
+ @classmethod
107
+ def create_host_from(cls, tensor: TensorHolder, stream_holder: StreamHolder):
108
+ src_nd = tensor.asndbuffer()
109
+ wrapped_np = package_utils.empty_numpy_like(src_nd)
110
+ ndbuffer.copy_into(wrapped_np, src_nd, stream_holder)
111
+ return cls(wrapped_np.data)
112
+
113
+ @property
114
+ def shape(self):
115
+ return tuple(self.tensor.shape)
116
+
117
+ @property
118
+ def size(self):
119
+ return self.tensor.size
120
+
121
+ @property
122
+ def strides(self):
123
+ return tuple(stride_in_bytes // self.tensor.itemsize for stride_in_bytes in self.tensor.strides)
124
+
125
+ def asndbuffer(self):
126
+ return package_utils.wrap_numpy_array(self.tensor)
127
+
128
+ def to(self, device_id, stream_holder):
129
+ if device_id == "cpu":
130
+ return self
131
+ elif isinstance(device_id, int):
132
+ dst = self.device_tensor_class.create_from_host(self, device_id, stream_holder)
133
+ return dst
134
+ else:
135
+ raise ValueError(f"The device must be specified as an integer or 'cpu', not '{device_id}'.")
136
+
137
+ def copy_(self, src, stream_holder):
138
+ match src.name:
139
+ case "numpy":
140
+ numpy.copyto(self.tensor, src.tensor)
141
+ case _:
142
+ with utils.device_ctx(src.device_id):
143
+ ndbuffer.copy_into(self.asndbuffer(), src._broadcast_to(self.shape).asndbuffer(), stream_holder)
144
+
145
+ def istensor(self):
146
+ """
147
+ Check if the object is ndarray-like.
148
+ """
149
+ return isinstance(self.tensor, numpy.ndarray)
150
+
151
+ def reshape(self, shape: Sequence[int], *, copy: bool | None = None):
152
+ if int(numpy.__version__.split(".")[0]) < 2:
153
+ return self.__class__(numpy.reshape(self.tensor, shape))
154
+ else:
155
+ return self.__class__(numpy.reshape(self.tensor, shape, copy=copy))
156
+
157
+ def memory_buffer(self):
158
+ """Creates a view of the memory buffer as a 1D tensor."""
159
+ t = self.tensor
160
+ # TODO: ensure tensor is dense for now, and later support linear
161
+ # memory with constant stride.
162
+ v = NumpyTensor(t.ravel(order="K"))
163
+ assert v.data_ptr == self.data_ptr, "Internal error."
164
+ return v
165
+
166
+ def memory_buffer_to_tensor(self, shape, strides):
167
+ """
168
+ Creates a N-D tensor view of the memory buffer according to the specified
169
+ shape and strides.
170
+ """
171
+ assert len(self.shape) == 1, "Internal error."
172
+ t = self.tensor
173
+ strides = [s * self.itemsize for s in strides]
174
+ v = NumpyTensor(numpy.lib.stride_tricks.as_strided(t, shape=shape, strides=strides))
175
+ assert v.data_ptr == self.data_ptr, "Internal error."
176
+ return v
177
+
178
+ def _broadcast_to(self, shape):
179
+ reshaped_tensor = numpy.broadcast_to(self.tensor, shape)
180
+ return self.__class__(reshaped_tensor)
181
+
182
+
183
+ CudaTensor.host_tensor_class = NumpyTensor
@@ -0,0 +1,176 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use Torch tensor objects.
7
+ """
8
+
9
+ __all__ = ["TorchTensor"]
10
+
11
+ import contextlib
12
+ from collections.abc import Sequence
13
+
14
+ import torch
15
+
16
+ from .package_ifc import StreamHolder
17
+ from .tensor_ifc import TensorHolder
18
+
19
+
20
+ class TorchTensor(TensorHolder[torch.Tensor]):
21
+ """
22
+ TensorHolder for Torch Tensors.
23
+ """
24
+
25
+ name = "torch"
26
+ module = torch
27
+ name_to_dtype = TensorHolder.create_name_dtype_map(
28
+ conversion_function=lambda name: getattr(torch, name), exception_type=AttributeError
29
+ )
30
+
31
+ def __init__(self, tensor):
32
+ super().__init__(tensor)
33
+
34
+ @property
35
+ def data_ptr(self):
36
+ return self.tensor.data_ptr()
37
+
38
+ @property
39
+ def device(self):
40
+ return str(self.tensor.device).split(":")[0]
41
+
42
+ @property
43
+ def device_id(self):
44
+ index = self.tensor.device.index
45
+ return "cpu" if index is None else index
46
+
47
+ @property
48
+ def dtype(self):
49
+ """Name of the data type"""
50
+ return str(self.tensor.dtype).split(".")[-1]
51
+
52
+ @property
53
+ def itemsize(self):
54
+ return self.tensor.itemsize
55
+
56
+ @property
57
+ def shape(self):
58
+ return tuple(self.tensor.shape)
59
+
60
+ @property
61
+ def size(self):
62
+ return self.tensor.nelement()
63
+
64
+ @property
65
+ def strides(self):
66
+ return self.tensor.stride()
67
+
68
+ @classmethod
69
+ def empty(
70
+ cls, shape, device_id="cpu", *, dtype="float32", strides=None, stream_holder: StreamHolder | None = None, **context
71
+ ):
72
+ """
73
+ Create an empty tensor of the specified shape and data type on the specified device
74
+ (None, 'cpu', or device id).
75
+
76
+ Note, that the strides, if specified, should correspond to a dense
77
+ (possibly permuted) tensor and MUST NOT overlap.
78
+ Otherwise, the behaviour is not defined.
79
+ """
80
+ dtype = TorchTensor.name_to_dtype[dtype]
81
+ stream_ctx = contextlib.nullcontext() if stream_holder is None else stream_holder.ctx
82
+ with stream_ctx:
83
+ if strides:
84
+ # note: torch strides is not scaled by bytes
85
+ tensor = torch.empty_strided(shape, strides, dtype=dtype, device=device_id)
86
+ else:
87
+ tensor = torch.empty(shape, dtype=dtype, device=device_id)
88
+
89
+ return cls(tensor)
90
+
91
+ def asndbuffer(self):
92
+ raise RuntimeError("Converting torch tensor to ndbuffer is not supported")
93
+
94
+ def to(self, device_id, stream_holder):
95
+ if not (device_id == "cpu" or isinstance(device_id, int)):
96
+ raise ValueError(f"The device must be specified as an integer or 'cpu', not '{device_id}'.")
97
+
98
+ # For h2d the data on the CPU is available and we block on `to()`, so a stream
99
+ # is not needed. It is currently ignored if provided.
100
+
101
+ # For d2h and d2d, we require a stream to ensure that the source data is ready
102
+ # before the copy operation is launched.
103
+ if self.device_id != "cpu" and stream_holder is None:
104
+ raise AssertionError("Internal error: a stream holder should be provided for d2h or d2d copies.")
105
+
106
+ # Always block for h2d and d2h copies to ensure that the copied data is ready
107
+ # for consumption when `to()` return.
108
+
109
+ # For d2d, the `torch.to()` operation is launched on the source device on the
110
+ # specified stream, so this stream must be on the source device. Their
111
+ # implementation ensures correct ordering between the current streams on the
112
+ # source and target devices.
113
+
114
+ blocking = self.device_id == "cpu" or device_id == "cpu"
115
+
116
+ stream_ctx = contextlib.nullcontext() if stream_holder is None else stream_holder.ctx
117
+ with stream_ctx:
118
+ tensor_device = self.tensor.to(device=device_id, non_blocking=not blocking)
119
+
120
+ return TorchTensor(tensor_device)
121
+
122
+ def copy_(self, src, stream_holder):
123
+ """
124
+ Inplace copy of src (copy the data from src into self).
125
+ """
126
+
127
+ # For d2h and d2d, we require a stream to ensure that the source data is ready
128
+ # before the copy operation is launched.
129
+ if src.device_id != "cpu" and stream_holder is None:
130
+ raise AssertionError("Internal error: a stream holder should be provided for d2h or d2d copies.")
131
+
132
+ stream_ctx = contextlib.nullcontext() if stream_holder is None else stream_holder.ctx
133
+ with stream_ctx:
134
+ self.tensor.copy_(src.tensor)
135
+
136
+ def istensor(self):
137
+ """
138
+ Check if the object is ndarray-like.
139
+ """
140
+ return isinstance(self.tensor, torch.Tensor)
141
+
142
+ def reshape(self, shape: Sequence[int], *, copy: bool | None = None):
143
+ if copy:
144
+ raise NotImplementedError("reshape with copy=True not implemented")
145
+ if copy is False:
146
+ return self.__class__(self.tensor.view(shape))
147
+ return self.__class__(self.tensor.reshape(shape))
148
+
149
+ def memory_buffer(self):
150
+ """Creates a view of the memory buffer as a 1D tensor."""
151
+ storage = self.tensor.untyped_storage()
152
+ size = self.size
153
+ v = self.tensor.view(self.shape)
154
+ # TODO: ensure tensor is dense for now, and later support linear
155
+ # memory with constant stride.
156
+ v.set_(storage, self.tensor.storage_offset(), (size,), (1,))
157
+ return TorchTensor(v)
158
+
159
+ def memory_buffer_to_tensor(self, shape, strides):
160
+ """
161
+ Creates a N-D tensor view of the memory buffer according to the specified
162
+ shape and strides.
163
+ """
164
+ assert len(self.shape) == 1, "Internal error."
165
+ storage = self.tensor.untyped_storage()
166
+ t = self.tensor.view(self.shape)
167
+ t.set_(storage, self.tensor.storage_offset(), shape, strides)
168
+ return TorchTensor(t)
169
+
170
+ def _broadcast_to(self, shape):
171
+ reshaped_tensor = torch.broadcast_to(self.tensor, shape)
172
+ return self.__class__(reshaped_tensor)
173
+
174
+ @property
175
+ def is_conjugate(self) -> bool:
176
+ return self.tensor.is_conj()
@@ -0,0 +1,157 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Entry point to using tensors from different libraries seamlessly.
7
+ """
8
+
9
+ __all__ = ["infer_tensor_package", "wrap_operand", "wrap_operands", "to", "copy_", "TensorHolder", "AnyTensor"]
10
+
11
+ import warnings
12
+ from collections.abc import Sequence
13
+
14
+ import numpy as np
15
+
16
+ from . import formatters
17
+ from .tensor_ifc import AnyTensor, Tensor, TensorHolder
18
+ from .tensor_ifc_numpy import CudaTensor, NumpyTensor
19
+
20
+ _TENSOR_TYPES: dict[str, type[TensorHolder]] = {"numpy": NumpyTensor, "cuda": CudaTensor}
21
+
22
+ _SUPPORTED_PACKAGES = tuple(_TENSOR_TYPES.keys())
23
+
24
+
25
+ def infer_tensor_package(tensor):
26
+ """
27
+ Infer the package that defines this tensor.
28
+ """
29
+ if issubclass(tensor.__class__, np.ndarray):
30
+ return "numpy"
31
+ module = tensor.__class__.__module__
32
+ package = module.split(".")[0]
33
+ maybe_register_package(package)
34
+ return package
35
+
36
+
37
+ def maybe_register_package(package):
38
+ global _SUPPORTED_PACKAGES
39
+ if package not in _SUPPORTED_PACKAGES:
40
+ global _TENSOR_TYPES
41
+ from .. import memory
42
+ from . import package_wrapper
43
+
44
+ if package == "torch":
45
+ from .package_ifc_torch import TorchPackage
46
+ from .tensor_ifc_torch import TorchTensor
47
+
48
+ _TENSOR_TYPES[package] = TorchTensor
49
+ package_wrapper.PACKAGE[package] = TorchPackage
50
+ memory.lazy_load_torch()
51
+ elif package == "cupy":
52
+ from .package_ifc_cupy import CupyPackage
53
+ from .tensor_ifc_cupy import CupyTensor, HostTensor
54
+
55
+ _TENSOR_TYPES[package] = CupyTensor
56
+ _TENSOR_TYPES["cupy_host"] = HostTensor
57
+ package_wrapper.PACKAGE[package] = CupyPackage
58
+ package_wrapper.PACKAGE["cupy_host"] = CupyPackage
59
+ memory.lazy_load_cupy()
60
+ else:
61
+ message = f"""{package} not supported yet. Currently must be one of ['numpy', 'cupy', 'torch']"""
62
+ raise ValueError(message)
63
+ _SUPPORTED_PACKAGES = tuple(_TENSOR_TYPES.keys())
64
+
65
+
66
+ def wrap_operand(native_operand: Tensor) -> TensorHolder[Tensor]:
67
+ """
68
+ Wrap one "native" operand so that package-agnostic API can be used.
69
+ """
70
+ if isinstance(native_operand, TensorHolder):
71
+ msg = (
72
+ "wrap_operand() is being called unnecessarily because the input is already a TensorHolder. "
73
+ "Only public facing APIs should call wrap_operand(). "
74
+ "Internal APIs should assume the operands are TensorHolder already."
75
+ "Trying to wrap a TensorHolder will become an error in the future."
76
+ )
77
+ warnings.warn(msg, DeprecationWarning)
78
+ return native_operand
79
+ wrapped_operand = _TENSOR_TYPES[infer_tensor_package(native_operand)](native_operand)
80
+ return wrapped_operand
81
+
82
+
83
+ def check_valid_package(native_operands):
84
+ """
85
+ Check if the operands belong to one of the supported packages.
86
+ """
87
+ operands_pkg = [infer_tensor_package(o) for o in native_operands]
88
+ checks = [p in _SUPPORTED_PACKAGES for p in operands_pkg]
89
+ if not all(checks):
90
+ unknown = [f"{location}: {operands_pkg[location]}" for location, predicate in enumerate(checks) if predicate is False]
91
+ unknown = formatters.array2string(unknown)
92
+ message = f"""The operands should be ndarray-like objects from one of {_SUPPORTED_PACKAGES} packages.
93
+ The unsupported operands as a sequence of "position: package" is: \n{unknown}"""
94
+ raise ValueError(message)
95
+
96
+ return operands_pkg
97
+
98
+
99
+ def check_valid_operand_type(wrapped_operands):
100
+ """
101
+ Check if the wrapped operands are ndarray-like.
102
+ """
103
+ istensor = [o.istensor() for o in wrapped_operands]
104
+ if not all(istensor):
105
+ unknown = [
106
+ f"{location}: {type(wrapped_operands[location].tensor)}"
107
+ for location, predicate in enumerate(istensor)
108
+ if predicate is False
109
+ ]
110
+ unknown = formatters.array2string(unknown)
111
+ message = f"""The operands should be ndarray-like objects from one of {_SUPPORTED_PACKAGES} packages.
112
+ The unsupported operands as a sequence of "position: type" is: \n{unknown}"""
113
+ raise ValueError(message)
114
+
115
+
116
+ def _wrapper_helper(operand: Tensor | TensorHolder, index: int, packages: list[str]) -> TensorHolder[Tensor]:
117
+ if isinstance(operand, TensorHolder):
118
+ msg = (
119
+ "wrap_operands() is being called unnecessarily because at least one input is already a TensorHolder. "
120
+ "Only public facing APIs should call wrap_operands(). "
121
+ "Internal APIs should assume the operands are TensorHolder already."
122
+ "Trying to wrap a TensorHolder will become an error in the future."
123
+ )
124
+ warnings.warn(msg, DeprecationWarning)
125
+ return operand
126
+ return _TENSOR_TYPES[packages[index]](operand)
127
+
128
+
129
+ def wrap_operands(native_operands: Sequence[Tensor]) -> Sequence[TensorHolder[Tensor]]:
130
+ """
131
+ Wrap the "native" operands so that package-agnostic API can be used.
132
+ """
133
+
134
+ operands_pkg = check_valid_package(native_operands)
135
+
136
+ wrapped_operands = tuple(_wrapper_helper(o, i, operands_pkg) for i, o in enumerate(native_operands))
137
+
138
+ check_valid_operand_type(wrapped_operands)
139
+
140
+ return wrapped_operands
141
+
142
+
143
+ def to(operands: Sequence[TensorHolder], device_id, stream_holder) -> Sequence[TensorHolder]:
144
+ """
145
+ Copy the wrapped operands to the specified device_id (None or int) and return the
146
+ wrapped operands on the device.
147
+ """
148
+ assert isinstance(operands, Sequence) and isinstance(operands[0], TensorHolder)
149
+ return tuple(o.to(device_id, stream_holder) for o in operands)
150
+
151
+
152
+ def copy_(src: Sequence[TensorHolder], dest: Sequence[TensorHolder], stream_holder):
153
+ """
154
+ Copy the wrapped operands in src to the corresponding wrapped operands in dest.
155
+ """
156
+ for s, d in zip(src, dest, strict=True):
157
+ d.copy_(s, stream_holder=stream_holder)
@@ -0,0 +1,162 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Functions to link type names with CUDA data and compute types.
7
+ """
8
+
9
+ __all__ = ["COMPUTE_TYPE_TO_NAME", "DATA_TYPE_TO_NAME", "NAME_TO_DATA_TYPE", "NAME_TO_COMPUTE_TYPE", "NAME_TO_DATA_WIDTH"]
10
+
11
+ import re
12
+ from enum import IntEnum
13
+
14
+
15
+ class ComputeType(IntEnum):
16
+ """An enumeration of CUDA compute types."""
17
+
18
+ COMPUTE_DEFAULT = 0
19
+ COMPUTE_16F = 1 << 0
20
+ COMPUTE_32F = 1 << 2
21
+ COMPUTE_64F = 1 << 4
22
+ COMPUTE_8U = 1 << 6
23
+ COMPUTE_8I = 1 << 8
24
+ COMPUTE_32U = 1 << 7
25
+ COMPUTE_32I = 1 << 9
26
+ COMPUTE_16BF = 1 << 10
27
+ COMPUTE_TF32 = 1 << 12
28
+
29
+
30
+ class cudaDataType(IntEnum):
31
+ """An enumeration of `cudaDataType_t`."""
32
+
33
+ CUDA_R_16F = 2
34
+ CUDA_C_16F = 6
35
+ CUDA_R_16BF = 14
36
+ CUDA_C_16BF = 15
37
+ CUDA_R_32F = 0
38
+ CUDA_C_32F = 4
39
+ CUDA_R_64F = 1
40
+ CUDA_C_64F = 5
41
+ CUDA_R_4I = 16
42
+ CUDA_C_4I = 17
43
+ CUDA_R_4U = 18
44
+ CUDA_C_4U = 19
45
+ CUDA_R_8I = 3
46
+ CUDA_C_8I = 7
47
+ CUDA_R_8U = 8
48
+ CUDA_C_8U = 9
49
+ CUDA_R_16I = 20
50
+ CUDA_C_16I = 21
51
+ CUDA_R_16U = 22
52
+ CUDA_C_16U = 23
53
+ CUDA_R_32I = 10
54
+ CUDA_C_32I = 11
55
+ CUDA_R_32U = 12
56
+ CUDA_C_32U = 13
57
+ CUDA_R_64I = 24
58
+ CUDA_C_64I = 25
59
+ CUDA_R_64U = 26
60
+ CUDA_C_64U = 27
61
+ CUDA_R_8F_E4M3 = 28
62
+ CUDA_R_8F_E5M2 = 29
63
+ CUDA_R_4F_E2M1 = 33 # supported on SM 10.0+
64
+
65
+
66
+ def create_cuda_data_type_map(cuda_data_type_enum_class):
67
+ """
68
+ Map the data type name to the corresponding CUDA data type.
69
+ """
70
+ cuda_data_type_pattern = re.compile(r"CUDA_(?P<cr>C|R)_(?P<width>\d+)(?P<type>F|I|U|BF)_?(?P<kind>(E\dM\d)?)")
71
+
72
+ type_code_map = {"i": "int", "u": "uint", "f": "float", "bf": "bfloat"}
73
+ # A map from (width, exponent kind) to qualifiers (finite, unsigned zero, ...) for data
74
+ # types.
75
+ type_qualifier_map = {
76
+ (8, "e4m3"): "fn",
77
+ # FP4: finite-only, packed 2 per byte, see for example:
78
+ # - https://github.com/pytorch/pytorch/issues/146414
79
+ # - https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf
80
+ (4, "e2m1"): "fn_x2",
81
+ }
82
+
83
+ complex_types = {"float": "complex", "bfloat": "bcomplex"}
84
+
85
+ cuda_data_type_map = {}
86
+ data_type_width_map = {}
87
+ for d in cuda_data_type_enum_class:
88
+ m = cuda_data_type_pattern.match(d.name)
89
+
90
+ is_complex = m.group("cr").lower() == "c"
91
+ type_code = type_code_map[m.group("type").lower()]
92
+
93
+ # We'll generalize this if and when we support Gaussian integers.
94
+ if is_complex and type_code not in complex_types:
95
+ continue
96
+
97
+ width = int(m.group("width"))
98
+ if is_complex:
99
+ width *= 2
100
+ type_code = complex_types[type_code]
101
+
102
+ name = type_code + str(width)
103
+
104
+ # Handle narrow type kinds.
105
+ if width <= 8:
106
+ kind = m.group("kind").lower()
107
+ # Handle type qualifiers for narrow types.
108
+ kind += type_qualifier_map.get((width, kind), "")
109
+ if kind:
110
+ name += "_" + kind
111
+
112
+ cuda_data_type_map[name] = d
113
+ data_type_width_map[name] = width
114
+
115
+ return cuda_data_type_map, data_type_width_map
116
+
117
+
118
+ def create_cuda_compute_type_map(cuda_compute_type_enum_class):
119
+ """
120
+ Map the data type name to the corresponding CUDA compute type.
121
+ """
122
+ cuda_compute_type_pattern = re.compile(r"COMPUTE_(?:(?P<width>\d+)(?P<type>F|I|U|BF)|(?P<tf32>TF32))")
123
+
124
+ type_code_map = {"i": "int", "u": "uint", "f": "float", "bf": "bfloat"}
125
+
126
+ cuda_compute_type_map = {}
127
+ for c in cuda_compute_type_enum_class:
128
+ if c.name == "COMPUTE_DEFAULT":
129
+ continue
130
+
131
+ m = cuda_compute_type_pattern.match(c.name)
132
+
133
+ if not m:
134
+ raise ValueError("Internal error - unexpected enum entry")
135
+
136
+ if m.group("tf32"):
137
+ continue
138
+
139
+ name = type_code_map[m.group("type").lower()] + m.group("width")
140
+ cuda_compute_type_map[name] = c
141
+
142
+ # Treat complex types as special case.
143
+ cuda_compute_type_map["bcomplex32"] = cuda_compute_type_enum_class.COMPUTE_16BF
144
+ cuda_compute_type_map["complex32"] = cuda_compute_type_enum_class.COMPUTE_16F
145
+ cuda_compute_type_map["complex64"] = cuda_compute_type_enum_class.COMPUTE_32F
146
+ cuda_compute_type_map["complex128"] = cuda_compute_type_enum_class.COMPUTE_64F
147
+
148
+ return cuda_compute_type_map
149
+
150
+
151
+ NAME_TO_DATA_TYPE, NAME_TO_DATA_WIDTH = create_cuda_data_type_map(cudaDataType)
152
+ NAME_TO_ITEM_SIZE = {k: v // 8 for k, v in NAME_TO_DATA_WIDTH.items() if v % 8 == 0}
153
+ DATA_TYPE_TO_NAME = {v: k for k, v in NAME_TO_DATA_TYPE.items()}
154
+ NAME_TO_COMPUTE_TYPE = create_cuda_compute_type_map(ComputeType)
155
+ COMPUTE_TYPE_TO_NAME = {v: k for k, v in NAME_TO_COMPUTE_TYPE.items()}
156
+
157
+
158
+ FFTW_SUPPORTED_SINGLE = (cudaDataType.CUDA_R_32F, cudaDataType.CUDA_C_32F)
159
+ FFTW_SUPPORTED_DOUBLE = (cudaDataType.CUDA_R_64F, cudaDataType.CUDA_C_64F)
160
+ FFTW_SUPPORTED_FLOAT = (cudaDataType.CUDA_R_32F, cudaDataType.CUDA_R_64F)
161
+ FFTW_SUPPORTED_COMPLEX = (cudaDataType.CUDA_C_32F, cudaDataType.CUDA_C_64F)
162
+ FFTW_SUPPORTED_TYPES = sorted(FFTW_SUPPORTED_SINGLE + FFTW_SUPPORTED_DOUBLE)