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
nvmath/device/types.py ADDED
@@ -0,0 +1,147 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = [
6
+ "Complex",
7
+ "Vector",
8
+ "complex32",
9
+ "complex64",
10
+ "complex128",
11
+ "half2",
12
+ "half4",
13
+ "np_float16x2",
14
+ "np_float16x4",
15
+ "REAL_NP_TYPES",
16
+ "INT_NP_TYPES",
17
+ ]
18
+
19
+ import warnings
20
+
21
+ import numpy as np
22
+
23
+ from ._deprecated import deprecated
24
+
25
+ np_float16x2 = np.dtype([("x", np.float16), ("y", np.float16)], align=True)
26
+ np_float16x4 = np.dtype([("x", np.float16), ("y", np.float16), ("z", np.float16), ("w", np.float16)], align=True)
27
+
28
+ REAL_NP_TYPES: list = [np.float16, np.float32, np.float64]
29
+ INT_NP_TYPES: list = [np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32, np.uint64]
30
+
31
+ _alignment_warning_msg = (
32
+ "You are using the host counterpart of a dtype that is under-aligned "
33
+ "compared to what the device function expects. In most cases this will "
34
+ "work, since device memory is typically allocated with at least 256-byte "
35
+ "alignment. For details, please review the alignment guidelines at "
36
+ "https://nvidia.com/docs/nvmath/alignment"
37
+ )
38
+
39
+
40
+ class Complex:
41
+ """
42
+ Complex type that can be used to represent complex numbers both
43
+ on host and device side. Numpy does not provide a built-in complex type with
44
+ 16-bit real and imaginary parts, so we define our own dtype for that case.
45
+ For 32-bit and 64-bit complex numbers, we can use the built-in numpy dtypes.
46
+ However on device side we expect those types to be aligned to the full size
47
+ of the complex type, so the array defined on host and device side will have
48
+ different type and alignment. :py:const:`np_float16x2`,
49
+ :py:const:`numpy.dtype(numpy.complex64)` and
50
+ :py:const:`numpy.dtype(numpy.complex128)` are the host side dtypes and
51
+ :py:const:`float16x2_type`, :py:const:`float32x2_type` and
52
+ :py:const:`float64x2_type` are the device side types.
53
+ """
54
+
55
+ def __init__(self, real_dtype):
56
+ self._real_dtype = real_dtype
57
+
58
+ @property
59
+ def real_dtype(self):
60
+ return self._real_dtype
61
+
62
+ @property
63
+ def dtype(self):
64
+ warnings.warn(_alignment_warning_msg, UserWarning, stacklevel=2)
65
+ if self._real_dtype == np.float16:
66
+ return np_float16x2
67
+ elif self._real_dtype == np.float32:
68
+ return np.dtype(np.complex64)
69
+ assert self._real_dtype == np.float64
70
+ return np.dtype(np.complex128)
71
+
72
+ @property
73
+ def _numba_type(self):
74
+ from .vector_types_numba import float16x2_type, float32x2_type, float64x2_type
75
+
76
+ if self.real_dtype == np.float16:
77
+ return float16x2_type
78
+ if self.real_dtype == np.float32:
79
+ return float32x2_type
80
+ assert self.real_dtype == np.float64
81
+ return float64x2_type
82
+
83
+ @property
84
+ @deprecated("This is a numba fallback behavior and will be removed in future releases, please use numba types directly")
85
+ def make(self):
86
+ return self._numba_type.make
87
+
88
+
89
+ complex32 = Complex(np.float16)
90
+ complex64 = Complex(np.float32)
91
+ complex128 = Complex(np.float64)
92
+
93
+
94
+ class Vector:
95
+ """
96
+ Vector type that can be used to represent vector numbers both
97
+ on host and device side. Host side representation uses numpy structured
98
+ dtypes to represent the vector components, while device side representation
99
+ uses custom numba types. This difference is necessary because device
100
+ functions expect alignment of the vector types to be the same as the size of
101
+ the vector, which is not the case for numpy structured dtypes.
102
+ :py:const:`np_float16x2` and :py:const:`np_float16x4` are the host side
103
+ dtypes and :py:const:`float16x2_type` and :py:const:`float16x4_type` are the
104
+ device side types.
105
+ """
106
+
107
+ def __init__(self, real_dtype, size):
108
+ if size not in (2, 4):
109
+ raise ValueError(f"Unsupported vector size {size}, only 2 and 4 are supported")
110
+ if real_dtype != np.float16:
111
+ raise ValueError(f"Unsupported vector real dtype {real_dtype}, only float16 is supported")
112
+ self._real_dtype = real_dtype
113
+ self._size = size
114
+
115
+ @property
116
+ def real_dtype(self):
117
+ return self._real_dtype
118
+
119
+ @property
120
+ def size(self):
121
+ return self._size
122
+
123
+ @property
124
+ def dtype(self):
125
+ warnings.warn(_alignment_warning_msg, UserWarning, stacklevel=2)
126
+ if self._size == 2:
127
+ return np_float16x2
128
+ assert self._size == 4
129
+ return np_float16x4
130
+
131
+ @property
132
+ def _numba_type(self):
133
+ from .vector_types_numba import float16x2_type, float16x4_type
134
+
135
+ if self._size == 2:
136
+ return float16x2_type
137
+ assert self._size == 4
138
+ return float16x4_type
139
+
140
+ @property
141
+ @deprecated("This is a numba fallback behavior and will be removed in future releases, please use numba types directly")
142
+ def make(self):
143
+ return self._numba_type.make
144
+
145
+
146
+ half2 = Vector(np.float16, 2)
147
+ half4 = Vector(np.float16, 4)
@@ -0,0 +1,203 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = [
6
+ "float16x2",
7
+ "float16x4",
8
+ "float32x2",
9
+ "float64x2",
10
+ "float16x2_type",
11
+ "float16x4_type",
12
+ "float32x2_type",
13
+ "float64x2_type",
14
+ ]
15
+
16
+ import typing
17
+
18
+ from llvmlite import ir
19
+ from numba.core import types
20
+ from numba.core.typeconv import Conversion
21
+ from numba.core.typing.templates import AttributeTemplate
22
+ from numba.cuda.cudadecl import registry as cuda_registry
23
+ from numba.cuda.cudaimpl import lower_attr as cuda_lower_attr
24
+ from numba.cuda.extending import as_numba_type, lower_builtin, lower_cast, overload, register_model, type_callable
25
+ from numba.extending import models
26
+
27
+
28
+ def make_vector(
29
+ float_bitwidth: int, numba_float_type: types.scalars.Float, llvm_float_type, vector_length: typing.Literal[2, 4]
30
+ ):
31
+ assert vector_length == 2 or vector_length == 4
32
+ vector_bitwidth = vector_length * float_bitwidth
33
+
34
+ # User visible types and functions
35
+ class vector:
36
+ def __init__(self, *args):
37
+ pass
38
+
39
+ def create(input):
40
+ pass
41
+
42
+ # FE types
43
+ class vectorType(types.Number):
44
+ def __init__(self):
45
+ super().__init__(name=f"vector({numba_float_type.name}x{vector_length})")
46
+ self.dtype = numba_float_type
47
+ self.count = vector_length
48
+ self.bitwidth = vector_bitwidth
49
+ self.make = vector
50
+
51
+ def can_convert_from(self, typingctx, other):
52
+ if vector_length == 2 and isinstance(other, types.Complex):
53
+ if other.bitwidth == vector_bitwidth:
54
+ return Conversion.exact
55
+ elif other.bitwidth < vector_bitwidth:
56
+ return Conversion.safe
57
+ elif other.bitwidth > vector_bitwidth:
58
+ return Conversion.unsafe
59
+
60
+ def can_convert_to(self, typingctx, other):
61
+ if vector_length == 2 and isinstance(other, types.Complex):
62
+ if other.bitwidth == vector_bitwidth:
63
+ return Conversion.exact
64
+ elif other.bitwidth < vector_bitwidth:
65
+ return Conversion.unsafe
66
+ elif other.bitwidth > vector_bitwidth:
67
+ return Conversion.safe
68
+
69
+ def __name__(self):
70
+ return f"vector({numba_float_type.name}x{vector_length})"
71
+
72
+ vector_type = vectorType()
73
+
74
+ types.number_domain = types.number_domain | frozenset([vector_type])
75
+
76
+ # Type inference (Python --> FE type)
77
+ as_numba_type.register(vector, vector_type)
78
+
79
+ # How to build a vectorType from individual elements
80
+ @type_callable(vector)
81
+ def type(context):
82
+ def typer(x, y=None, z=None, w=None):
83
+ if (
84
+ (vector_length == 2 and isinstance(x, types.Complex) and y is None and z is None and w is None)
85
+ or (vector_length == 2 and all(isinstance(v, types.Float) for v in [x, y]) and z is None and w is None)
86
+ or (vector_length == 4 and all(isinstance(v, types.Float) for v in [x, y, z, w]))
87
+ ):
88
+ return vector_type
89
+
90
+ return typer
91
+
92
+ # How to represent vectorType in Memory?
93
+ @register_model(vectorType)
94
+ class vectorTypeModel(models.PrimitiveModel):
95
+ def __init__(self, dmm, fe_type):
96
+ be_type = ir.IntType(vector_bitwidth)
97
+ super().__init__(dmm, fe_type, be_type)
98
+
99
+ # How to build a vectorType from individual float values?
100
+ @lower_builtin(vector, *(vector_length * [types.Float])) # FIXME
101
+ def vector_ctor(context, builder, sig, args):
102
+ typ = sig.return_type
103
+ args = list(args)
104
+ assert len(args) == vector_length
105
+ for i in range(vector_length):
106
+ args[i] = context.cast(builder, args[i], sig.args[i], numba_float_type)
107
+
108
+ vt = ir.VectorType(llvm_float_type, vector_length)
109
+ val = ir.Constant(vt, ir.Undefined)
110
+
111
+ for i in range(vector_length):
112
+ val = builder.insert_element(val, args[i], context.get_constant(types.int32, i))
113
+
114
+ return builder.bitcast(val, context.get_value_type(typ))
115
+
116
+ # How to access .x, .y, .z, .w
117
+ @cuda_registry.register_attr
118
+ class complex_attrs(AttributeTemplate):
119
+ key = vectorType
120
+
121
+ def resolve_x(self, mod):
122
+ return numba_float_type
123
+
124
+ def resolve_y(self, mod):
125
+ return numba_float_type
126
+
127
+ def resolve_z(self, mod):
128
+ return numba_float_type
129
+
130
+ def resolve_w(self, mod):
131
+ return numba_float_type
132
+
133
+ def complex_get(context, builder, typ, val, i):
134
+ vt = ir.VectorType(llvm_float_type, vector_length)
135
+ vec = builder.bitcast(val, vt)
136
+ index = context.get_constant(types.int32, i)
137
+ return builder.extract_element(vec, index)
138
+
139
+ # This cannot be done with a loop
140
+ @cuda_lower_attr(vectorType, "x")
141
+ def complex_get_x(context, builder, typ, val):
142
+ return complex_get(context, builder, typ, val, 0)
143
+
144
+ @cuda_lower_attr(vectorType, "y")
145
+ def complex_get_y(context, builder, typ, val):
146
+ return complex_get(context, builder, typ, val, 1)
147
+
148
+ if vector_length == 4:
149
+
150
+ @cuda_lower_attr(vectorType, "z")
151
+ def complex_get_z(context, builder, typ, val):
152
+ return complex_get(context, builder, typ, val, 2)
153
+
154
+ @cuda_lower_attr(vectorType, "w")
155
+ def complex_get_w(context, builder, typ, val):
156
+ return complex_get(context, builder, typ, val, 3)
157
+
158
+ # Conversions from types.Complex
159
+ if vector_length == 2:
160
+
161
+ @overload(create)
162
+ def make_complex(cplx):
163
+ if isinstance(cplx, types.Complex):
164
+
165
+ def impl(cplx):
166
+ return vector(cplx.real, cplx.imag)
167
+
168
+ return impl
169
+
170
+ @lower_cast(types.Complex, vector_type)
171
+ def np_complex_to_complex(context, builder, fromty, toty, val):
172
+ src = context.make_complex(builder, fromty, value=val)
173
+ src_float_ty = fromty.underlying_float
174
+ ctor_sig = toty(src_float_ty, src_float_ty)
175
+ ctor_args = (src.real, src.imag)
176
+ return vector_ctor(context, builder, ctor_sig, ctor_args)
177
+
178
+ @lower_cast(vector_type, types.Complex)
179
+ def complex_to_np_complex(context, builder, fromty, toty, val):
180
+ dst_float_ty = toty.underlying_float
181
+ x = complex_get(context, builder, fromty, val, 0)
182
+ y = complex_get(context, builder, fromty, val, 1)
183
+ x = context.cast(builder, x, numba_float_type, dst_float_ty)
184
+ y = context.cast(builder, y, numba_float_type, dst_float_ty)
185
+ vt = context.get_value_type(toty)
186
+ val = ir.Constant(vt, ir.Undefined)
187
+ val = builder.insert_value(val, x, [0])
188
+ val = builder.insert_value(val, y, [1])
189
+ return val
190
+
191
+ vector.__name__ = f"float{float_bitwidth}x{vector_length}"
192
+ vector.__doc__ = f"""
193
+ float{float_bitwidth}x{vector_length}({"x, y" if vector_length == 2 else "x, y, z, w"})
194
+
195
+ Create a Numba compliant vector object for float{float_bitwidth} with vector length {vector_length}.
196
+ """
197
+ return vector, vector_type
198
+
199
+
200
+ float16x2, float16x2_type = make_vector(16, types.float16, ir.IntType(16), 2)
201
+ float16x4, float16x4_type = make_vector(16, types.float16, ir.IntType(16), 4)
202
+ float32x2, float32x2_type = make_vector(32, types.float32, ir.FloatType(), 2)
203
+ float64x2, float64x2_type = make_vector(64, types.float64, ir.DoubleType(), 2)
@@ -0,0 +1,205 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from __future__ import annotations
6
+
7
+ import sys
8
+
9
+ if sys.platform != "linux":
10
+ raise ImportError("nvmath.distributed is only supported on Linux.")
11
+
12
+ import atexit
13
+ from collections.abc import Sequence
14
+ from dataclasses import dataclass
15
+ from threading import Lock
16
+ from typing import TYPE_CHECKING, Any, Literal
17
+
18
+ import numpy as np
19
+
20
+ try:
21
+ from cuda.core import Device
22
+ except ImportError:
23
+ from cuda.core.experimental import Device
24
+
25
+ if TYPE_CHECKING:
26
+ import mpi4py
27
+
28
+ from nvmath.distributed import fft, linalg, reshape # noqa: E402
29
+ from nvmath.internal.utils import device_ctx
30
+
31
+ from . import distribution
32
+ from ._internal import nvshmem
33
+ from ._utils import allocate_symmetric_memory, free_symmetric_memory
34
+ from .process_group import MPIProcessGroup, ProcessGroup, TorchProcessGroup
35
+
36
+ __all__ = [
37
+ "initialize",
38
+ "finalize",
39
+ "get_context",
40
+ "ProcessGroup",
41
+ "MPIProcessGroup",
42
+ "TorchProcessGroup",
43
+ "allocate_symmetric_memory",
44
+ "free_symmetric_memory",
45
+ "distribution",
46
+ "fft",
47
+ "linalg",
48
+ "reshape",
49
+ ]
50
+
51
+ _initialize_mutex = Lock()
52
+ _atexit_registered = False
53
+ _ctx = None
54
+
55
+
56
+ @dataclass(frozen=True)
57
+ class DistributedContext:
58
+ """
59
+ Context of initialized ``nvmath.distributed`` runtime.
60
+
61
+ Attributes:
62
+ device_id: CUDA device ID associated with the distributed runtime
63
+ on this process.
64
+
65
+ process_group: ``nvmath.distributed`` participating processes.
66
+
67
+ nvshmem_available: True if NVSHMEM backend was selected at initialization.
68
+
69
+ nccl_comm: nccl4py communicator if NCCL backend was selected at
70
+ initialization, None otherwise.
71
+ """
72
+
73
+ device_id: int
74
+ process_group: ProcessGroup
75
+ nvshmem_available: bool
76
+ nccl_comm: Any | None
77
+
78
+
79
+ def initialize(
80
+ device_id: int,
81
+ process_group: ProcessGroup | mpi4py.MPI.Comm,
82
+ backends: Sequence[Literal["nvshmem", "nccl"]],
83
+ ) -> None:
84
+ """Initialize ``nvmath.distributed`` runtime. This is required before any distributed
85
+ operations can be performed. **Note that this is a collective operation and must be
86
+ called by all processes.**
87
+
88
+ If the runtime is already initialized this function will raise an error. If you need
89
+ to reinitialize the runtime (for example with different backends) you have to finalize
90
+ it first.
91
+
92
+ Note: NCCL doesn't allow assigning more than one process to the same GPU.
93
+
94
+ Args:
95
+ device_id: CUDA device ID to associate with the ``nvmath.distributed`` runtime
96
+ on this process.
97
+
98
+ process_group: ProcessGroup (or mpi4py communicator) specifying the participating
99
+ processes. This is used for setup and not for communication during compute.
100
+
101
+ backends: Communication backends to use in distributed computations. Valid values
102
+ are "nvshmem" and "nccl". Note that specific libraries (cuFFTMp, cuBLASMp, ...)
103
+ have specific required backends.
104
+ """
105
+ if not isinstance(device_id, int):
106
+ raise TypeError(
107
+ "The device ID used to initialize the nvmath.distributed module "
108
+ f"must be an integer. The provided device ID is {device_id}."
109
+ )
110
+
111
+ valid_backends = ("nvshmem", "nccl")
112
+ for backend in backends:
113
+ if backend not in valid_backends:
114
+ raise ValueError(f"backend must be one of {valid_backends}, got {backend}")
115
+
116
+ if len(backends) == 0:
117
+ raise ValueError(f"Need to specify at least one of {valid_backends} communication backends")
118
+
119
+ if process_group is None:
120
+ raise ValueError("process_group cannot be None")
121
+
122
+ with _initialize_mutex:
123
+ global _atexit_registered, _ctx
124
+
125
+ if _ctx is not None:
126
+ raise RuntimeError("nvmath.distributed has already been initialized")
127
+
128
+ if not _atexit_registered:
129
+ atexit.register(finalize)
130
+ _atexit_registered = True
131
+
132
+ if not isinstance(process_group, ProcessGroup):
133
+ valid_process_group = False
134
+ if "mpi4py" in sys.modules:
135
+ import mpi4py.MPI
136
+
137
+ if isinstance(process_group, mpi4py.MPI.Comm):
138
+ process_group = MPIProcessGroup(process_group)
139
+ valid_process_group = True
140
+ if not valid_process_group:
141
+ raise TypeError(
142
+ f"Unrecognized process group type ({process_group}). "
143
+ "Need nvmath.distributed.ProcessGroup or mpi4py communicator."
144
+ )
145
+
146
+ assert isinstance(process_group, ProcessGroup) # for type-checker
147
+ rank = process_group.rank
148
+ nranks = process_group.nranks
149
+
150
+ # Set the device for NVSHMEM and NCCL initialization, but also need to make sure
151
+ # that a CUDA context has been created. We can't rely on `device_ctx` to do it
152
+ # since it's not guaranteed to make a runtime API call.
153
+ old_device = Device()
154
+ device = Device(device_id)
155
+ device.set_current()
156
+
157
+ try:
158
+ nvshmem_available = False
159
+ if "nvshmem" in backends:
160
+ nvshmem.initialize(device_id, process_group)
161
+ nvshmem_available = True
162
+
163
+ nccl_comm = None
164
+ if "nccl" in backends:
165
+ # Don't want to import this at the global scope yet because
166
+ # `import nccl.core` imports cupy and torch (with nccl4py 0.1.1)
167
+ import nccl.core as nccl # type: ignore
168
+
169
+ # Create NCCL communicator.
170
+ unique_id = nccl.get_unique_id()
171
+ process_group.broadcast_buffer(unique_id.as_ndarray.view(np.int8), root=0)
172
+ nccl_comm = nccl.Communicator.init(nranks=nranks, rank=rank, unique_id=unique_id)
173
+
174
+ _ctx = DistributedContext(
175
+ device_id=device_id, process_group=process_group, nvshmem_available=nvshmem_available, nccl_comm=nccl_comm
176
+ )
177
+ finally:
178
+ old_device.set_current()
179
+
180
+
181
+ def finalize() -> None:
182
+ """Finalize ``nvmath.distributed`` runtime (this is called automatically at exit
183
+ if the runtime is initialized). **Note that this is a collective operation and
184
+ must be called by all processes.**"""
185
+ global _ctx
186
+ with _initialize_mutex:
187
+ if _ctx is None:
188
+ return
189
+
190
+ linalg.advanced.matmulmod._grid_cache.clear()
191
+
192
+ if _ctx.nccl_comm is not None:
193
+ with device_ctx(_ctx.device_id):
194
+ _ctx.nccl_comm.finalize()
195
+ _ctx.nccl_comm.destroy()
196
+
197
+ if _ctx.nvshmem_available:
198
+ nvshmem.finalize(_ctx.device_id)
199
+
200
+ _ctx = None
201
+
202
+
203
+ def get_context() -> DistributedContext | None:
204
+ """Return the distributed runtime's context or None if not initialized."""
205
+ return _ctx
File without changes