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/memory.py ADDED
@@ -0,0 +1,282 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """Interface for pluggable memory handlers."""
6
+
7
+ __all__ = ["BaseCUDAMemoryManager", "MemoryPointer"]
8
+
9
+ import logging
10
+ import weakref
11
+ from abc import abstractmethod
12
+ from collections.abc import Callable
13
+ from typing import Protocol, runtime_checkable
14
+
15
+ try:
16
+ from cuda.core import Stream
17
+ except ImportError:
18
+ from cuda.core.experimental import Stream
19
+
20
+ from nvmath.internal import utils
21
+ from nvmath.internal.memory import allocate_from_mr, get_device_memory_resource
22
+ from nvmath.internal.package_ifc_cuda import CUDAPackage
23
+
24
+
25
+ class MemoryPointer:
26
+ """
27
+ An RAII class for a device memory buffer.
28
+
29
+ Args:
30
+ device_ptr: The address of the device memory buffer.
31
+ size: The size of the memory buffer in bytes.
32
+ finalizer: A nullary callable that will be called when the buffer is to be freed.
33
+
34
+ .. seealso:: :class:`numba.cuda.MemoryPointer`
35
+ """
36
+
37
+ def __init__(self, device_ptr: int, size: int, finalizer: None | Callable[[], None]):
38
+ self.device_ptr = device_ptr
39
+ self.size = size
40
+ self._finalizer: weakref.finalize | None
41
+ if finalizer is not None:
42
+ self._finalizer = weakref.finalize(self, finalizer)
43
+ else:
44
+ self._finalizer = None
45
+
46
+ def free(self):
47
+ """
48
+ "Frees" the memory buffer by calling the finalizer.
49
+ """
50
+ if self._finalizer is None:
51
+ return
52
+
53
+ if not self._finalizer.alive:
54
+ raise RuntimeError("The buffer has already been freed.")
55
+ self._finalizer()
56
+
57
+
58
+ class _UnmanagedMemoryPointer:
59
+ """
60
+ An alternative to :class:`MemoryPointer` to wrap objects that already implements
61
+ its own RAII semantics.
62
+
63
+ Args:
64
+ device_ptr: The address of the device memory buffer.
65
+ size: The size of the memory buffer in bytes.
66
+ owner: An object that owns the memory buffer and releases the allocation
67
+ on object deletion.
68
+
69
+ .. seealso:: :class:`MemoryPointer`
70
+ """
71
+
72
+ __slots__ = ("device_ptr", "size", "_owner")
73
+
74
+ def __init__(self, device_ptr: int, size: int, owner: object):
75
+ self.device_ptr = device_ptr
76
+ self.size = size
77
+ self._owner = owner
78
+
79
+ def free(self):
80
+ """
81
+ "Frees" by removing the reference to the owner.
82
+ """
83
+ self._owner = None
84
+
85
+
86
+ @runtime_checkable
87
+ class BaseCUDAMemoryManager(Protocol):
88
+ """
89
+ Protocol for memory manager plugins.
90
+
91
+ .. seealso:: :class:`numba.cuda.BaseCUDAMemoryManager`
92
+ """
93
+
94
+ @abstractmethod
95
+ def __init__(self, device_id: int, logger: logging.Logger):
96
+ raise NotImplementedError
97
+
98
+ @abstractmethod
99
+ def memalloc(self, size: int) -> MemoryPointer:
100
+ """
101
+ Allocate device memory synchronously or on the current stream.
102
+
103
+ Args:
104
+ size: The size of the memory buffer in bytes.
105
+
106
+ Returns:
107
+ An object that owns the allocated memory and is responsible for releasing it (to
108
+ the OS or a pool). The object must have an attribute named ``device_ptr``,
109
+ ``device_pointer``, or ``ptr`` specifying the pointer to the allocated memory
110
+ buffer. See :class:`MemoryPointer` for an example interface.
111
+
112
+ Note:
113
+ Objects of type :class:`numba.cuda.MemoryPointer` as well as
114
+ :class:`cupy.cuda.MemoryPointer` meet the requirements listed above for the
115
+ device memory pointer object.
116
+ """
117
+ raise NotImplementedError
118
+
119
+
120
+ @runtime_checkable
121
+ class BaseCUDAMemoryManagerAsync(Protocol):
122
+ """
123
+ Protocol for async memory manager plugins.
124
+
125
+ .. seealso:: :class:`BaseCUDAMemoryManager`
126
+ """
127
+
128
+ @abstractmethod
129
+ def __init__(self, device_id: int, logger: logging.Logger):
130
+ raise NotImplementedError
131
+
132
+ @abstractmethod
133
+ def memalloc_async(self, size: int, stream: Stream) -> MemoryPointer:
134
+ """
135
+ Allocate device memory asynchronously on the provided stream.
136
+
137
+ Args:
138
+ size: The size of the memory buffer in bytes.
139
+ stream: A cuda.core.Stream object on which the allocation will be performed.
140
+
141
+ Returns:
142
+ An object that owns the allocated memory and is responsible for releasing it (to
143
+ the OS or a pool). The object must have an attribute named ``device_ptr``,
144
+ ``device_pointer``, or ``ptr`` specifying the pointer to the allocated memory
145
+ buffer. See :class:`MemoryPointer` for an example interface.
146
+
147
+ Note:
148
+ Objects of type :class:`numba.cuda.MemoryPointer` as well as
149
+ :class:`cupy.cuda.MemoryPointer` meet the requirements listed above for the
150
+ device memory pointer object.
151
+ """
152
+ raise NotImplementedError
153
+
154
+
155
+ class _RawCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
156
+ """
157
+ Raw device memory allocator.
158
+
159
+ Args:
160
+ device_id: The ID (int) of the device on which memory is to be allocated.
161
+ logger (logging.Logger): Python Logger object.
162
+ """
163
+
164
+ def __init__(self, device_id: int, logger: logging.Logger):
165
+ """
166
+ __init__(device_id)
167
+ """
168
+ self.device_id = device_id
169
+ self.logger = logger
170
+ self._pool = get_device_memory_resource(device_id)
171
+
172
+ def memalloc_async(self, size: int, stream: Stream) -> MemoryPointer:
173
+ buffer = allocate_from_mr(self._pool, size, stream, self.device_id, self.logger)
174
+ device_ptr = int(buffer.handle)
175
+
176
+ return _UnmanagedMemoryPointer(device_ptr, size, buffer) # type: ignore[return-value]
177
+
178
+
179
+ _MEMORY_MANAGER: dict[str, type[BaseCUDAMemoryManager] | type[BaseCUDAMemoryManagerAsync]] = {
180
+ "_raw": _RawCUDAMemoryManager,
181
+ "cuda": _RawCUDAMemoryManager,
182
+ }
183
+
184
+
185
+ def lazy_load_cupy():
186
+ global _MEMORY_MANAGER
187
+ import cupy as cp
188
+
189
+ from nvmath.internal.package_ifc_cupy import CupyPackage
190
+
191
+ class _CupyCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
192
+ """
193
+ CuPy device memory allocator.
194
+
195
+ Args:
196
+ device_id: The ID (int) of the device on which memory is to be allocated.
197
+ logger (logging.Logger): Python Logger object.
198
+ """
199
+
200
+ def __init__(self, device_id: int, logger: logging.Logger):
201
+ """
202
+ __init__(device_id)
203
+ """
204
+ self.device_id = device_id
205
+ self.logger = logger
206
+
207
+ def memalloc_async(self, size: int, stream) -> MemoryPointer:
208
+ stream_ctx = CupyPackage.to_stream_context(
209
+ CupyPackage.create_external_stream(self.device_id, CUDAPackage.to_stream_pointer(stream))
210
+ )
211
+ with utils.device_ctx(self.device_id), stream_ctx:
212
+ cp_mem_ptr = cp.cuda.alloc(size)
213
+ device_ptr = cp_mem_ptr.ptr
214
+
215
+ self.logger.debug(
216
+ "_CupyCUDAMemoryManager (allocate memory): size = %d, ptr = %d, device_id = %d, stream = %s",
217
+ size,
218
+ device_ptr,
219
+ self.device_id,
220
+ stream,
221
+ )
222
+
223
+ def finalizer():
224
+ # The cupy MemoryPointer object is RAII, so we keep a reference to it
225
+ # until we don't need it anymore.
226
+ nonlocal cp_mem_ptr, device_ptr
227
+ self.logger.debug("_CupyCUDAMemoryManager (release memory): ptr = %d", device_ptr)
228
+ del cp_mem_ptr
229
+
230
+ return MemoryPointer(device_ptr, size, finalizer=finalizer)
231
+
232
+ _MEMORY_MANAGER["cupy"] = _CupyCUDAMemoryManager
233
+
234
+
235
+ def lazy_load_torch():
236
+ global _MEMORY_MANAGER
237
+
238
+ from torch.cuda import caching_allocator_alloc, caching_allocator_delete
239
+
240
+ from nvmath.internal.package_ifc_torch import TorchPackage
241
+
242
+ class _TorchCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
243
+ """
244
+ Torch caching memory allocator.
245
+
246
+ Args:
247
+ device_id: The ID (int) of the device on which memory is to be allocated.
248
+ logger (logging.Logger): Python Logger object.
249
+ """
250
+
251
+ def __init__(self, device_id: int, logger: logging.Logger):
252
+ """
253
+ __init__(device_id)
254
+ """
255
+ self.device_id = device_id
256
+ self.logger = logger
257
+
258
+ def memalloc_async(self, size: int, stream: Stream) -> MemoryPointer:
259
+ torch_stream = TorchPackage.create_external_stream(self.device_id, CUDAPackage.to_stream_pointer(stream))
260
+ device_ptr = caching_allocator_alloc(size, device=self.device_id, stream=torch_stream)
261
+
262
+ self.logger.debug(
263
+ "_TorchCUDAMemoryManager (allocate memory): size = %d, ptr = %d, device_id = %d, stream = %s",
264
+ size,
265
+ device_ptr,
266
+ self.device_id,
267
+ stream,
268
+ )
269
+
270
+ def finalizer():
271
+ nonlocal device_ptr, stream
272
+ self.logger.debug(
273
+ "_TorchCUDAMemoryManager (release memory): ptr = %d, device_id = %d, stream = %s",
274
+ device_ptr,
275
+ self.device_id,
276
+ stream,
277
+ )
278
+ caching_allocator_delete(device_ptr)
279
+
280
+ return MemoryPointer(device_ptr, size, finalizer=finalizer)
281
+
282
+ _MEMORY_MANAGER["torch"] = _TorchCUDAMemoryManager
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from . import advanced, ust # noqa: E402
6
+ from .generic import ComputeType, ExecutionCUDA, Matmul, MatmulOptions, matmul
7
+ from .generic import (
8
+ compile_add as compile_matmul_add,
9
+ )
10
+ from .generic import (
11
+ compile_atomic_add as compile_matmul_atomic_add,
12
+ )
13
+ from .generic import (
14
+ compile_epilog as compile_matmul_epilog,
15
+ )
16
+ from .generic import (
17
+ compile_mul as compile_matmul_mul,
18
+ )
19
+ from .generic import (
20
+ compile_prolog as compile_matmul_prolog,
21
+ )
22
+ from .generic import matrix_qualifiers_dtype as matmul_matrix_qualifiers_dtype
23
+
24
+ __all__ = [
25
+ "advanced",
26
+ "ust",
27
+ "ExecutionCUDA",
28
+ "MatmulOptions",
29
+ "matmul_matrix_qualifiers_dtype",
30
+ "compile_matmul_prolog",
31
+ "compile_matmul_epilog",
32
+ "compile_matmul_add",
33
+ "compile_matmul_atomic_add",
34
+ "compile_matmul_mul",
35
+ "Matmul",
36
+ "matmul",
37
+ "ComputeType",
38
+ ]
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from . import common_utils as common_utils
6
+ from . import cudss_config_ifc as cudss_config_ifc
7
+ from . import cudss_data_ifc as cudss_data_ifc
8
+ from . import cudss_utils as cudss_utils
9
+ from . import sparse_csr_ifc as sparse_csr_ifc
10
+ from . import sparse_format_helpers as sparse_format_helpers
11
+ from . import sparse_tensor_ifc as sparse_tensor_ifc
12
+
13
+ __all__ = [
14
+ "common_utils",
15
+ "cudss_config_ifc",
16
+ "cudss_data_ifc",
17
+ "cudss_utils",
18
+ "sparse_csr_ifc",
19
+ "sparse_format_helpers",
20
+ "sparse_tensor_ifc",
21
+ ]
@@ -0,0 +1,144 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ A collection of sparse utilities.
7
+ """
8
+
9
+ import importlib
10
+ from collections.abc import Sequence
11
+
12
+ from nvmath.internal.utils import infer_object_package
13
+ from nvmath.sparse._internal.sparse_format_helpers import PACKAGE_HELPER_MAP
14
+
15
+ RECOGNIZED_NAMED_FORMATS = {"BSR", "BSC", "CSR", "CSC", "COO", "DIA"}
16
+
17
+
18
+ def check_supported_package(native_operands):
19
+ """
20
+ Check if the operands belong to one of the supported packages.
21
+ """
22
+ package = {infer_object_package(o) for o in native_operands}
23
+ if len(package) != 1:
24
+ raise ValueError(f"The sparse operands do not belong to the same package: {package}.")
25
+
26
+ package = package.pop()
27
+ if package not in PACKAGE_HELPER_MAP:
28
+ raise TypeError(f"The sparse operand package {package} is not supported.")
29
+
30
+ return package
31
+
32
+
33
+ def wrap_sparse_operand(native_operand):
34
+ """
35
+ Wrap one "native" sparse operand so that package-agnostic API can be used.
36
+ """
37
+
38
+ package = infer_object_package(native_operand)
39
+ helper = PACKAGE_HELPER_MAP[package]
40
+ sparse_format = helper.sparse_format_name(native_operand)
41
+
42
+ # The sparse format should be a recognized named format or an UST.
43
+ if sparse_format not in RECOGNIZED_NAMED_FORMATS:
44
+ if package == "nvmath":
45
+ from nvmath.sparse._internal.sparse_ust_ifc import USTensorHolder
46
+
47
+ return USTensorHolder(native_operand)
48
+
49
+ raise TypeError(f"The sparse format {sparse_format} is not currently supported.")
50
+
51
+ # Recognized named format.
52
+ attr_name_map = getattr(helper, f"{sparse_format.lower()}_attribute_names")()
53
+
54
+ module_name = f"nvmath.sparse._internal.sparse_{sparse_format.lower()}_ifc"
55
+ module = importlib.import_module(module_name)
56
+ SparseHolder = getattr(module, f"{sparse_format}TensorHolder")
57
+
58
+ return SparseHolder.create_from_tensor(native_operand, attr_name_map=attr_name_map)
59
+
60
+
61
+ def wrap_sparse_operands(native_operands):
62
+ """
63
+ Wrap each "native" sparse operand so that package-agnostic API can be used.
64
+ """
65
+
66
+ if not isinstance(native_operands, Sequence):
67
+ return wrap_sparse_operand(native_operands)
68
+
69
+ package = check_supported_package(native_operands)
70
+ helper = PACKAGE_HELPER_MAP[package]
71
+
72
+ sparse_format = {helper.sparse_format_name(o) for o in native_operands}
73
+ if len(sparse_format) != 1:
74
+ raise ValueError(f"The sparse operands do not have the same sparse format: {sparse_format}")
75
+ sparse_format = sparse_format.pop()
76
+
77
+ # The sparse format should be a recognized named format or an UST.
78
+ if sparse_format not in RECOGNIZED_NAMED_FORMATS:
79
+ if package == "nvmath":
80
+ from nvmath.sparse._internal.sparse_ust_ifc import USTensor
81
+
82
+ return [USTensor(o) for o in native_operands]
83
+
84
+ raise TypeError(f"The sparse format {sparse_format} is not currently supported.")
85
+
86
+ attr_name_map = getattr(helper, f"{sparse_format.lower()}_attribute_names")()
87
+
88
+ module_name = f"nvmath.sparse._internal.sparse_{sparse_format.lower()}_ifc"
89
+ module = importlib.import_module(module_name)
90
+ SparseHolder = getattr(module, f"{sparse_format}TensorHolder")
91
+
92
+ return [SparseHolder.create_from_tensor(o, attr_name_map=attr_name_map) for o in native_operands]
93
+
94
+
95
+ # TODO: Unify all the get_attribute functions in internal.utils
96
+ # as get(operands, attribute, attribute_desc).
97
+ def get_operands_index_type(operands):
98
+ """
99
+ Return the index type name of the tensors.
100
+ """
101
+ index_type = operands[0].index_type
102
+ if not all(operand.index_type == index_type for operand in operands):
103
+ index_types = {operand.index_type for operand in operands}
104
+ raise ValueError(f"All operands must have the same index type. The index types found = {index_types}.")
105
+ return index_type
106
+
107
+
108
+ def sparse_or_dense(operand):
109
+ """
110
+ Determine if the operand is sparse or dense.
111
+ """
112
+
113
+ dense_tensor_modules = {"cupy", "numpy", "torch"}
114
+ sparse_tensor_modules = set(PACKAGE_HELPER_MAP.keys())
115
+
116
+ module = infer_object_package(operand)
117
+
118
+ if module == "torch":
119
+ import torch
120
+
121
+ if not torch.is_tensor(operand):
122
+ raise TypeError(f"The operand '{operand}' is not a tensor object.")
123
+
124
+ if operand.layout == torch.strided:
125
+ return "dense"
126
+
127
+ return "sparse"
128
+
129
+ # TODO: use the level spec instead of format name to infer if dense.
130
+ if module == "nvmath":
131
+ name = operand.tensor_format.name
132
+ if name == "Scalar" or "Dense" in name:
133
+ return "dense"
134
+ return "sparse"
135
+
136
+ # We'll check if the object is a tensor later, we'll assume here that it is
137
+ # solely based on the package.
138
+ if module in sparse_tensor_modules:
139
+ return "sparse"
140
+
141
+ if module in dense_tensor_modules:
142
+ return "dense"
143
+
144
+ raise TypeError(f"The package '{module}' is not supported.")