nvmath-python 1.0.0__cp314-cp314t-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 (332) 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 +130 -0
  7. nvmath/_internal/threadsafe.py +106 -0
  8. nvmath/_internal/utils.py +43 -0
  9. nvmath/_internal/workspace.py +490 -0
  10. nvmath/_utils.py +147 -0
  11. nvmath/bindings/__init__.py +60 -0
  12. nvmath/bindings/_internal/__init__.pxd +0 -0
  13. nvmath/bindings/_internal/__init__.py +0 -0
  14. nvmath/bindings/_internal/common_types.pxd +31 -0
  15. nvmath/bindings/_internal/cublas.cp314t-win_amd64.pyd +0 -0
  16. nvmath/bindings/_internal/cublas.pxd +530 -0
  17. nvmath/bindings/_internal/cublasLt.cp314t-win_amd64.pyd +0 -0
  18. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  19. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  20. nvmath/bindings/_internal/cudss.cp314t-win_amd64.pyd +0 -0
  21. nvmath/bindings/_internal/cudss.pxd +54 -0
  22. nvmath/bindings/_internal/cufft.cp314t-win_amd64.pyd +0 -0
  23. nvmath/bindings/_internal/cufft.pxd +70 -0
  24. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  25. nvmath/bindings/_internal/curand.cp314t-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/curand.pxd +42 -0
  27. nvmath/bindings/_internal/cusolver.cp314t-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusolver.pxd +15 -0
  29. nvmath/bindings/_internal/cusolverDn.cp314t-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  31. nvmath/bindings/_internal/cusolverMp.pxd +71 -0
  32. nvmath/bindings/_internal/cusolverSp.cp314t-win_amd64.pyd +0 -0
  33. nvmath/bindings/_internal/cusolverSp.pxd +75 -0
  34. nvmath/bindings/_internal/cusparse.cp314t-win_amd64.pyd +0 -0
  35. nvmath/bindings/_internal/cusparse.pxd +471 -0
  36. nvmath/bindings/_internal/cusparseLt.cp314t-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  38. nvmath/bindings/_internal/cutensor.cp314t-win_amd64.pyd +0 -0
  39. nvmath/bindings/_internal/cutensor.pxd +58 -0
  40. nvmath/bindings/_internal/mathdx.cp314t-win_amd64.pyd +0 -0
  41. nvmath/bindings/_internal/mathdx.pxd +116 -0
  42. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  43. nvmath/bindings/_internal/utils.cp314t-win_amd64.pyd +0 -0
  44. nvmath/bindings/_internal/utils.pxd +174 -0
  45. nvmath/bindings/_internal/utils.pyi +10 -0
  46. nvmath/bindings/cublas.cp314t-win_amd64.pyd +0 -0
  47. nvmath/bindings/cublas.pxd +558 -0
  48. nvmath/bindings/cublas.pyi +812 -0
  49. nvmath/bindings/cublasLt.cp314t-win_amd64.pyd +0 -0
  50. nvmath/bindings/cublasLt.pxd +109 -0
  51. nvmath/bindings/cublasLt.pyi +1461 -0
  52. nvmath/bindings/cublasMp.pxd +85 -0
  53. nvmath/bindings/cublasMp.pyi +267 -0
  54. nvmath/bindings/cudss.cp314t-win_amd64.pyd +0 -0
  55. nvmath/bindings/cudss.pxd +98 -0
  56. nvmath/bindings/cudss.pyi +443 -0
  57. nvmath/bindings/cufft.cp314t-win_amd64.pyd +0 -0
  58. nvmath/bindings/cufft.pxd +118 -0
  59. nvmath/bindings/cufft.pyi +301 -0
  60. nvmath/bindings/cufftMp.pxd +124 -0
  61. nvmath/bindings/cufftMp.pyi +326 -0
  62. nvmath/bindings/curand.cp314t-win_amd64.pyd +0 -0
  63. nvmath/bindings/curand.pxd +71 -0
  64. nvmath/bindings/curand.pyi +189 -0
  65. nvmath/bindings/cusolver.cp314t-win_amd64.pyd +0 -0
  66. nvmath/bindings/cusolver.pxd +62 -0
  67. nvmath/bindings/cusolver.pyi +320 -0
  68. nvmath/bindings/cusolverDn.cp314t-win_amd64.pyd +0 -0
  69. nvmath/bindings/cusolverDn.pxd +430 -0
  70. nvmath/bindings/cusolverDn.pyi +422 -0
  71. nvmath/bindings/cusolverMp.pxd +98 -0
  72. nvmath/bindings/cusolverMp.pyi +114 -0
  73. nvmath/bindings/cusolverSp.cp314t-win_amd64.pyd +0 -0
  74. nvmath/bindings/cusolverSp.pxd +95 -0
  75. nvmath/bindings/cusolverSp.pyi +70 -0
  76. nvmath/bindings/cusparse.cp314t-win_amd64.pyd +0 -0
  77. nvmath/bindings/cusparse.pxd +546 -0
  78. nvmath/bindings/cusparse.pyi +1017 -0
  79. nvmath/bindings/cusparseLt.cp314t-win_amd64.pyd +0 -0
  80. nvmath/bindings/cusparseLt.pxd +99 -0
  81. nvmath/bindings/cusparseLt.pyi +252 -0
  82. nvmath/bindings/cutensor.cp314t-win_amd64.pyd +0 -0
  83. nvmath/bindings/cutensor.pxd +98 -0
  84. nvmath/bindings/cutensor.pyi +324 -0
  85. nvmath/bindings/cycublas.cp314t-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycublas.pxd +664 -0
  87. nvmath/bindings/cycublasLt.cp314t-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycublasLt.pxd +1045 -0
  89. nvmath/bindings/cycublasMp.pxd +171 -0
  90. nvmath/bindings/cycudss.cp314t-win_amd64.pyd +0 -0
  91. nvmath/bindings/cycudss.pxd +277 -0
  92. nvmath/bindings/cycufft.cp314t-win_amd64.pyd +0 -0
  93. nvmath/bindings/cycufft.pxd +333 -0
  94. nvmath/bindings/cycufftMp.pxd +342 -0
  95. nvmath/bindings/cycurand.cp314t-win_amd64.pyd +0 -0
  96. nvmath/bindings/cycurand.pxd +141 -0
  97. nvmath/bindings/cycusolver.cp314t-win_amd64.pyd +0 -0
  98. nvmath/bindings/cycusolver.pxd +137 -0
  99. nvmath/bindings/cycusolverDn.cp314t-win_amd64.pyd +0 -0
  100. nvmath/bindings/cycusolverDn.pxd +443 -0
  101. nvmath/bindings/cycusolverMp.pxd +107 -0
  102. nvmath/bindings/cycusolverSp.cp314t-win_amd64.pyd +0 -0
  103. nvmath/bindings/cycusolverSp.pxd +93 -0
  104. nvmath/bindings/cycusparse.cp314t-win_amd64.pyd +0 -0
  105. nvmath/bindings/cycusparse.pxd +679 -0
  106. nvmath/bindings/cycusparseLt.cp314t-win_amd64.pyd +0 -0
  107. nvmath/bindings/cycusparseLt.pxd +135 -0
  108. nvmath/bindings/cycutensor.cp314t-win_amd64.pyd +0 -0
  109. nvmath/bindings/cycutensor.pxd +189 -0
  110. nvmath/bindings/cymathdx.cp314t-win_amd64.pyd +0 -0
  111. nvmath/bindings/cymathdx.pxd +552 -0
  112. nvmath/bindings/cynvshmem.pxd +118 -0
  113. nvmath/bindings/mathdx.cp314t-win_amd64.pyd +0 -0
  114. nvmath/bindings/mathdx.pxd +182 -0
  115. nvmath/bindings/mathdx.pyi +1562 -0
  116. nvmath/bindings/nvpl/__init__.pxd +0 -0
  117. nvmath/bindings/nvpl/__init__.py +13 -0
  118. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  119. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  120. nvmath/bindings/nvpl/_internal/blas.cp314t-win_amd64.pyd +0 -0
  121. nvmath/bindings/nvpl/_internal/blas.pxd +237 -0
  122. nvmath/bindings/nvpl/_internal/fft.cp314t-win_amd64.pyd +0 -0
  123. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  124. nvmath/bindings/nvpl/blas.cp314t-win_amd64.pyd +0 -0
  125. nvmath/bindings/nvpl/blas.pxd +131 -0
  126. nvmath/bindings/nvpl/blas.pyi +168 -0
  127. nvmath/bindings/nvpl/cyblas.cp314t-win_amd64.pyd +0 -0
  128. nvmath/bindings/nvpl/cyblas.pxd +280 -0
  129. nvmath/bindings/nvpl/cyfft.cp314t-win_amd64.pyd +0 -0
  130. nvmath/bindings/nvpl/cyfft.pxd +93 -0
  131. nvmath/bindings/nvpl/fft.cp314t-win_amd64.pyd +0 -0
  132. nvmath/bindings/nvpl/fft.pxd +100 -0
  133. nvmath/bindings/nvpl/fft.pyi +168 -0
  134. nvmath/bindings/nvshmem.pxd +54 -0
  135. nvmath/bindings/nvshmem.pyi +191 -0
  136. nvmath/device/__init__.py +38 -0
  137. nvmath/device/_deprecated.py +33 -0
  138. nvmath/device/common.py +315 -0
  139. nvmath/device/common_backend.py +131 -0
  140. nvmath/device/common_cuda.py +201 -0
  141. nvmath/device/common_numba.py +300 -0
  142. nvmath/device/common_numba_cuda_mlir.py +202 -0
  143. nvmath/device/common_opaque_tensor.py +201 -0
  144. nvmath/device/cublasdx.py +1606 -0
  145. nvmath/device/cublasdx_backend.py +860 -0
  146. nvmath/device/cublasdx_numba.py +1534 -0
  147. nvmath/device/cublasdx_numba_cuda_mlir.py +208 -0
  148. nvmath/device/cufftdx.py +373 -0
  149. nvmath/device/cufftdx_backend.py +220 -0
  150. nvmath/device/cufftdx_numba.py +140 -0
  151. nvmath/device/cufftdx_numba_cuda_mlir.py +79 -0
  152. nvmath/device/curand_kernel.py +9147 -0
  153. nvmath/device/cusolverdx.py +2708 -0
  154. nvmath/device/cusolverdx_backend.py +440 -0
  155. nvmath/device/cusolverdx_numba.py +567 -0
  156. nvmath/device/cusolverdx_numba_cuda_mlir.py +604 -0
  157. nvmath/device/cusolverdx_overload_backend.py +1029 -0
  158. nvmath/device/llvm_array.py +29 -0
  159. nvmath/device/random.py +441 -0
  160. nvmath/device/random_helpers.py +23 -0
  161. nvmath/device/random_states.py +187 -0
  162. nvmath/device/types.py +138 -0
  163. nvmath/device/vector_types_numba.py +259 -0
  164. nvmath/distributed/__init__.py +200 -0
  165. nvmath/distributed/_internal/__init__.py +0 -0
  166. nvmath/distributed/_internal/nccl.py +86 -0
  167. nvmath/distributed/_internal/nvshmem.py +307 -0
  168. nvmath/distributed/_internal/symmetric_memory.py +35 -0
  169. nvmath/distributed/_internal/tensor_ifc.py +70 -0
  170. nvmath/distributed/_internal/tensor_ifc_cupy.py +68 -0
  171. nvmath/distributed/_internal/tensor_ifc_host_device.py +172 -0
  172. nvmath/distributed/_internal/tensor_ifc_numpy.py +46 -0
  173. nvmath/distributed/_internal/tensor_ifc_torch.py +162 -0
  174. nvmath/distributed/_internal/tensor_wrapper.py +81 -0
  175. nvmath/distributed/_utils.py +167 -0
  176. nvmath/distributed/distribution/__init__.py +30 -0
  177. nvmath/distributed/distribution/_configuration.py +39 -0
  178. nvmath/distributed/distribution/distributions.py +1024 -0
  179. nvmath/distributed/distribution/redistribute.py +1284 -0
  180. nvmath/distributed/fft/__init__.py +7 -0
  181. nvmath/distributed/fft/_configuration.py +82 -0
  182. nvmath/distributed/fft/fft.py +2742 -0
  183. nvmath/distributed/linalg/__init__.py +22 -0
  184. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  185. nvmath/distributed/linalg/_internal/epilog_protocol.py +586 -0
  186. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  187. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  188. nvmath/distributed/linalg/advanced/_configuration.py +171 -0
  189. nvmath/distributed/linalg/advanced/matmulmod.py +3573 -0
  190. nvmath/distributed/linalg/generic/__init__.py +8 -0
  191. nvmath/distributed/linalg/generic/_caching.py +66 -0
  192. nvmath/distributed/linalg/generic/_configuration.py +61 -0
  193. nvmath/distributed/linalg/generic/_factorization.py +172 -0
  194. nvmath/distributed/linalg/generic/_initialization.py +966 -0
  195. nvmath/distributed/linalg/generic/_problem_spec.py +511 -0
  196. nvmath/distributed/linalg/generic/solvermod.py +1368 -0
  197. nvmath/distributed/process_group.py +408 -0
  198. nvmath/fft/__init__.py +7 -0
  199. nvmath/fft/_configuration.py +189 -0
  200. nvmath/fft/_exec_utils.py +82 -0
  201. nvmath/fft/_helpers.py +237 -0
  202. nvmath/fft/fft.py +3122 -0
  203. nvmath/internal/__init__.pxd +3 -0
  204. nvmath/internal/__init__.py +10 -0
  205. nvmath/internal/_bindings.cp314t-win_amd64.pyd +0 -0
  206. nvmath/internal/_bindings.pxd +18 -0
  207. nvmath/internal/_device_utils.py +45 -0
  208. nvmath/internal/_layout/__init__.pxd +3 -0
  209. nvmath/internal/_layout/__init__.py +7 -0
  210. nvmath/internal/_layout/_layout.cp314t-win_amd64.pyd +0 -0
  211. nvmath/internal/_layout/_layout.pxd +1303 -0
  212. nvmath/internal/_layout/_layout.pyi +1145 -0
  213. nvmath/internal/enum_utils.py +142 -0
  214. nvmath/internal/formatters.py +87 -0
  215. nvmath/internal/mem_limit.py +51 -0
  216. nvmath/internal/memory.cp314t-win_amd64.pyd +0 -0
  217. nvmath/internal/memory.pxd +13 -0
  218. nvmath/internal/memory.pyi +50 -0
  219. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  220. nvmath/internal/ndbuffer/__init__.py +9 -0
  221. nvmath/internal/ndbuffer/_copy_kernel.cp314t-win_amd64.pyd +0 -0
  222. nvmath/internal/ndbuffer/_copy_kernel.pxd +10 -0
  223. nvmath/internal/ndbuffer/_jit.cp314t-win_amd64.pyd +0 -0
  224. nvmath/internal/ndbuffer/_jit.pxd +7 -0
  225. nvmath/internal/ndbuffer/_ndbuffer.cp314t-win_amd64.pyd +0 -0
  226. nvmath/internal/ndbuffer/_ndbuffer.pxd +40 -0
  227. nvmath/internal/ndbuffer/_ndbuffer.pyi +463 -0
  228. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  229. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  230. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  231. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  232. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +242 -0
  233. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  234. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  235. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  236. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  237. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  238. nvmath/internal/package_ifc.py +168 -0
  239. nvmath/internal/package_ifc_cuda.py +57 -0
  240. nvmath/internal/package_ifc_cupy.py +67 -0
  241. nvmath/internal/package_ifc_torch.py +69 -0
  242. nvmath/internal/package_wrapper.py +14 -0
  243. nvmath/internal/tensor_ifc.py +179 -0
  244. nvmath/internal/tensor_ifc_cupy.py +234 -0
  245. nvmath/internal/tensor_ifc_ndbuffer.py +147 -0
  246. nvmath/internal/tensor_ifc_numpy.py +184 -0
  247. nvmath/internal/tensor_ifc_torch.py +178 -0
  248. nvmath/internal/tensor_wrapper.py +160 -0
  249. nvmath/internal/typemaps.py +113 -0
  250. nvmath/internal/utils.py +805 -0
  251. nvmath/linalg/__init__.py +56 -0
  252. nvmath/linalg/_internal/__init__.py +3 -0
  253. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  254. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  255. nvmath/linalg/_internal/batch.py +234 -0
  256. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  257. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  258. nvmath/linalg/_internal/layout.py +624 -0
  259. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  260. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  261. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  262. nvmath/linalg/_internal/solver_utils.py +432 -0
  263. nvmath/linalg/_internal/typemaps.py +144 -0
  264. nvmath/linalg/_internal/utils.py +157 -0
  265. nvmath/linalg/advanced/__init__.py +8 -0
  266. nvmath/linalg/advanced/_algorithmmod.py +170 -0
  267. nvmath/linalg/advanced/_configuration.py +351 -0
  268. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  269. nvmath/linalg/advanced/helpers/matmul.py +1316 -0
  270. nvmath/linalg/advanced/matmulmod.py +3734 -0
  271. nvmath/linalg/generic/__init__.py +53 -0
  272. nvmath/linalg/generic/_configuration/__init__.py +39 -0
  273. nvmath/linalg/generic/_configuration/layout.py +263 -0
  274. nvmath/linalg/generic/_configuration/match.py +734 -0
  275. nvmath/linalg/generic/_configuration/qualifiers.py +493 -0
  276. nvmath/linalg/generic/_configuration/solver_configuration.py +59 -0
  277. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  278. nvmath/linalg/generic/_dtype.py +15 -0
  279. nvmath/linalg/generic/matmulmod.py +2094 -0
  280. nvmath/linalg/generic/solvermod.py +1301 -0
  281. nvmath/memory.py +279 -0
  282. nvmath/sparse/__init__.py +38 -0
  283. nvmath/sparse/_internal/__init__.py +21 -0
  284. nvmath/sparse/_internal/common_utils.py +147 -0
  285. nvmath/sparse/_internal/cudss_config_ifc.py +702 -0
  286. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  287. nvmath/sparse/_internal/cudss_utils.py +506 -0
  288. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  289. nvmath/sparse/_internal/sparse_bsc_ifc.py +303 -0
  290. nvmath/sparse/_internal/sparse_bsr_ifc.py +305 -0
  291. nvmath/sparse/_internal/sparse_coo_ifc.py +256 -0
  292. nvmath/sparse/_internal/sparse_csc_ifc.py +268 -0
  293. nvmath/sparse/_internal/sparse_csr_ifc.py +288 -0
  294. nvmath/sparse/_internal/sparse_dia_ifc.py +242 -0
  295. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  296. nvmath/sparse/_internal/sparse_tensor_ifc.py +133 -0
  297. nvmath/sparse/_internal/sparse_ust_ifc.py +141 -0
  298. nvmath/sparse/_internal/utils.py +56 -0
  299. nvmath/sparse/advanced/__init__.py +7 -0
  300. nvmath/sparse/advanced/_configuration.py +227 -0
  301. nvmath/sparse/advanced/direct_solver.py +2069 -0
  302. nvmath/sparse/generic/__init__.py +7 -0
  303. nvmath/sparse/generic/_configuration.py +129 -0
  304. nvmath/sparse/generic/_helpers.py +137 -0
  305. nvmath/sparse/generic/_thunks.py +21 -0
  306. nvmath/sparse/generic/matmulmod.py +2353 -0
  307. nvmath/sparse/ust/__init__.py +7 -0
  308. nvmath/sparse/ust/_converters.py +422 -0
  309. nvmath/sparse/ust/_cpp.py +28 -0
  310. nvmath/sparse/ust/_drawer.py +565 -0
  311. nvmath/sparse/ust/_emitter.py +1033 -0
  312. nvmath/sparse/ust/_jit.py +188 -0
  313. nvmath/sparse/ust/_kernel.py +282 -0
  314. nvmath/sparse/ust/_utils.py +149 -0
  315. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  316. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  317. nvmath/sparse/ust/tensor.py +1016 -0
  318. nvmath/sparse/ust/tensor_format.py +957 -0
  319. nvmath/tensor/__init__.py +6 -0
  320. nvmath/tensor/_configuration.py +120 -0
  321. nvmath/tensor/_internal/__init__.py +3 -0
  322. nvmath/tensor/_internal/cutensor_config_ifc.py +279 -0
  323. nvmath/tensor/_internal/cutensor_utils.py +230 -0
  324. nvmath/tensor/_internal/data.py +43 -0
  325. nvmath/tensor/_internal/einsum_parser.py +444 -0
  326. nvmath/tensor/_internal/typemaps.py +96 -0
  327. nvmath/tensor/contract.py +1900 -0
  328. nvmath_python-1.0.0.dist-info/METADATA +134 -0
  329. nvmath_python-1.0.0.dist-info/RECORD +332 -0
  330. nvmath_python-1.0.0.dist-info/WHEEL +5 -0
  331. nvmath_python-1.0.0.dist-info/licenses/LICENSE +177 -0
  332. nvmath_python-1.0.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,268 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use CSC tensors from different libraries.
7
+ """
8
+
9
+ from __future__ import annotations # allows typehint of class methods to return the self class
10
+
11
+ __all__ = ["CSCTensorHolder"]
12
+
13
+ from typing import Literal, TypeVar
14
+
15
+ from nvmath._internal.layout import check_monotonic_strides, is_contiguous_and_dense
16
+ from nvmath.internal import tensor_wrapper
17
+ from nvmath.internal.package_ifc import StreamHolder
18
+ from nvmath.internal.tensor_ifc import TensorHolder
19
+ from nvmath.internal.utils import infer_object_package
20
+
21
+ from .sparse_tensor_ifc import SparseTensorHolder
22
+
23
+ """
24
+ A generic type for the third-party CSCTensor which a CSCTensorHolder implementation wraps
25
+ around.
26
+ """
27
+ CSCTensor = TypeVar("CSCTensor")
28
+
29
+
30
+ class CSCTensorHolder(SparseTensorHolder):
31
+ """
32
+ A simple wrapper type for CSC sparse tensors to make the API package-agnostic. The
33
+ naming convention is sparse format name with the suffix "TensorHolder", which convention
34
+ is used in the sparse format helper.
35
+
36
+ Since the implementation is in terms of our dense tensor abstraction, package-specific
37
+ implementation is not needed.
38
+ """
39
+
40
+ _format_name: str = "CSC"
41
+
42
+ def __init__(self, ccol_indices, row_indices, values, *, attr_name_map=None, shape=None, tensor=None):
43
+ # tensor is the native tensor.
44
+ self.tensor = tensor
45
+
46
+ # attr_name_map is the canonical attribute name to package attribute name map.
47
+ # It is set when constructing from a tensor, otherwise it is None.
48
+ self._attr_name_map = attr_name_map
49
+
50
+ assert (shape is not None) ^ (tensor is not None), "Internal error."
51
+
52
+ if shape is not None:
53
+ self._shape = shape
54
+ else:
55
+ self._shape = tuple(tensor.shape)
56
+
57
+ # Wrap constituent dense tensors, if required.
58
+ if not isinstance(ccol_indices, TensorHolder):
59
+ ccol_indices = tensor_wrapper.wrap_operand(ccol_indices)
60
+
61
+ if not isinstance(row_indices, TensorHolder):
62
+ row_indices = tensor_wrapper.wrap_operand(row_indices)
63
+
64
+ if not isinstance(values, TensorHolder):
65
+ values = tensor_wrapper.wrap_operand(values)
66
+
67
+ # The wrapped constituent dense tensors.
68
+ self._ccol_indices = ccol_indices
69
+ self._row_indices = row_indices
70
+ self._values = values
71
+
72
+ # Ensure constituent dense tensors are all on the same device.
73
+ device_ids = {d.device_id for d in (self._ccol_indices, self._row_indices, self._values)}
74
+ message = f"Internal error: the arrays defining the sparse format aren't on the same device {device_ids}."
75
+ assert len(device_ids) == 1, message
76
+ self._device_id = device_ids.pop()
77
+
78
+ self._device = self._values.device
79
+
80
+ # Capture the native tensor package for use in reset_unchecked().
81
+ self.tensor_package = infer_object_package(self.tensor)
82
+
83
+ # The tensor holder type for the dense constituent tensors (take from values, since
84
+ # all constituent tensors have the same type).
85
+ self._dense_tensorholder_type = values.__class__
86
+
87
+ @classmethod
88
+ def create_from_tensor(cls, tensor, *, attr_name_map=None):
89
+ assert attr_name_map is not None, "Internal error."
90
+
91
+ # tensor is the native tensor.
92
+ # For UST, the buffers will be CuPy ndarrays.
93
+ ccol_indices = attr_name_map["ccol_indices"](tensor)
94
+ row_indices = attr_name_map["row_indices"](tensor)
95
+ values = attr_name_map["values"](tensor)
96
+ return CSCTensorHolder(ccol_indices, row_indices, values, attr_name_map=attr_name_map, tensor=tensor)
97
+
98
+ @property
99
+ def attr_name_map(self):
100
+ return self._attr_name_map
101
+
102
+ @property
103
+ def device(self):
104
+ return self._device
105
+
106
+ @property
107
+ def device_id(self):
108
+ return self._device_id
109
+
110
+ @property
111
+ def dtype(self):
112
+ return self._values.dtype
113
+
114
+ @property
115
+ def index_type(self):
116
+ return self._ccol_indices.dtype
117
+
118
+ @property
119
+ def format_name(self) -> str:
120
+ return CSCTensorHolder._format_name
121
+
122
+ @property
123
+ def num_dimensions(self):
124
+ return len(self._shape)
125
+
126
+ @property
127
+ def shape(self):
128
+ return self._shape
129
+
130
+ @property
131
+ def ccol_indices(self) -> TensorHolder:
132
+ """The TensorHolder object wrapping the ccol_indices array."""
133
+ return self._ccol_indices
134
+
135
+ @property
136
+ def row_indices(self) -> TensorHolder:
137
+ """The TensorHolder object wrapping the row_indices array."""
138
+ return self._row_indices
139
+
140
+ @property
141
+ def values(self) -> TensorHolder:
142
+ """The TensorHolder object wrapping the values array."""
143
+ return self._values
144
+
145
+ def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
146
+ """Copy the CSCTensor representation to a different device.
147
+
148
+ No copy is performed if the CSCTensor is already on the requested device.
149
+ """
150
+ if self.tensor_package == "nvmath":
151
+ return super().to(device_id=device_id, stream_holder=stream_holder)
152
+
153
+ target_ccol_indices = self.ccol_indices.to(device_id=device_id, stream_holder=stream_holder)
154
+ target_row_indices = self.row_indices.to(device_id=device_id, stream_holder=stream_holder)
155
+ target_values = self.values.to(device_id=device_id, stream_holder=stream_holder)
156
+
157
+ return CSCTensorHolder(
158
+ target_ccol_indices, target_row_indices, target_values, attr_name_map=self.attr_name_map, shape=self.shape
159
+ )
160
+
161
+ def copy_(self, src, stream_holder: StreamHolder | None) -> None:
162
+ """Overwrite self.tensor (in-place) with a copy of src (CSCTensor)."""
163
+
164
+ self.ccol_indices.copy_(src=src.ccol_indices, stream_holder=stream_holder)
165
+ self.row_indices.copy_(src=src.row_indices, stream_holder=stream_holder)
166
+ self.values.copy_(src=src.values, stream_holder=stream_holder)
167
+
168
+ def to_ust(self, *, stream):
169
+ from nvmath.sparse.ust.tensor import Tensor
170
+ from nvmath.sparse.ust.tensor_format import NamedFormats
171
+
172
+ wrapped = self
173
+ tensor = wrapped.tensor
174
+ if not (wrapped.attr_name_map["is_coalesced"](tensor) and wrapped.attr_name_map["has_sorted_indices"](tensor)):
175
+ raise ValueError(
176
+ "The CSC tensor is not coalesced (metadata sorted with duplicates removed). \
177
+ To coalesce, use the operation provided by your sparse tensor library: `coalesce()`, `sum_duplicates()`, ..."
178
+ )
179
+
180
+ if not (
181
+ is_contiguous_and_dense(wrapped.ccol_indices.shape, wrapped.ccol_indices.strides)
182
+ and is_contiguous_and_dense(wrapped.row_indices.shape, wrapped.row_indices.strides)
183
+ and is_contiguous_and_dense(wrapped.values.shape, wrapped.values.strides)
184
+ ):
185
+ raise ValueError(
186
+ "The sparse tensor representation (ccol_indices(), row_indices(), and values() tensors) must be \
187
+ dense and contiguous."
188
+ )
189
+
190
+ values = wrapped.values.memory_buffer() # Typed memory viewed as a 1-D tensor.
191
+
192
+ num_dim = self.num_dimensions
193
+ num_sparse_dim = self.attr_name_map["num_sparse_dim"](tensor)
194
+ num_dense_dim = self.attr_name_map["num_dense_dim"](tensor)
195
+ num_batch_dim = num_dim - num_sparse_dim - num_dense_dim
196
+ tensor_format = NamedFormats.CSCd(num_batch_dim, num_dense_dim)
197
+
198
+ # Check if the batch axes are in C-order for all component dense arrays.
199
+ if not (
200
+ check_monotonic_strides(wrapped.ccol_indices.strides[:num_batch_dim], reverse=True)
201
+ and check_monotonic_strides(wrapped.row_indices.strides[:num_batch_dim], reverse=True)
202
+ and check_monotonic_strides(wrapped.values.strides[:num_batch_dim], reverse=True)
203
+ ):
204
+ raise ValueError(
205
+ "The batch dimensions in the sparse tensor representation (ccol_indices(), row_indices(), \
206
+ and values() tensors) must use the C-layout."
207
+ )
208
+
209
+ # Create the UST.
210
+ ust = Tensor(tensor.shape, tensor_format=tensor_format, index_type=wrapped.index_type, dtype=wrapped.dtype)
211
+
212
+ ust._pos[num_batch_dim + 1] = wrapped.ccol_indices
213
+ ust._crd[num_batch_dim + 1] = wrapped.row_indices
214
+ ust._val = values
215
+
216
+ return ust
217
+
218
+ def to_package(self):
219
+ """
220
+ This will create a sparse tensor for the original package from which this
221
+ interface was created.
222
+ """
223
+ create_csc = self.attr_name_map["sparse_format_helper"].create_csc
224
+ return create_csc(self.shape, self.ccol_indices, self.row_indices, self.values)
225
+
226
+ def release(self):
227
+ """
228
+ This method will release the wrapped tensor and any format-specific data
229
+ by setting them to None.
230
+ """
231
+ # The tensor reference.
232
+ self.tensor = None
233
+
234
+ # Format-specific data.
235
+ self._ccol_indices = None
236
+ self._row_indices = None
237
+ self._values = None
238
+
239
+ def reset_unchecked(self, tensor):
240
+ """
241
+ This method will reset the wrapped tensor to the specified one, and update
242
+ any format-specific data accordingly. It assumes that all attributes
243
+ like the device, shape, etc are consistent between the existing and new tensor.
244
+
245
+ Args:
246
+ tensor: The native tensor to wrap.
247
+ """
248
+ # Update the tensor reference.
249
+ self.tensor = tensor
250
+
251
+ # Format-specific data.
252
+
253
+ if self.tensor_package == "nvmath":
254
+ # The data arrays are already wrapped.
255
+ self._ccol_indices = self._attr_name_map["ccol_indices"](tensor)
256
+ self._row_indices = self._attr_name_map["row_indices"](tensor)
257
+ self._values = self._attr_name_map["values"](tensor)
258
+ else:
259
+ wrapper = self._dense_tensorholder_type
260
+
261
+ ccol_indices = self._attr_name_map["ccol_indices"](tensor)
262
+ self._ccol_indices = wrapper(ccol_indices)
263
+
264
+ row_indices = self._attr_name_map["row_indices"](tensor)
265
+ self._row_indices = wrapper(row_indices)
266
+
267
+ values = self._attr_name_map["values"](tensor)
268
+ self._values = wrapper(values)
@@ -0,0 +1,288 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use CSR tensors from different libraries.
7
+ """
8
+
9
+ from __future__ import annotations # allows typehint of class methods to return the self class
10
+
11
+ __all__ = ["CSRTensorHolder"]
12
+
13
+ from typing import Literal, TypeVar
14
+
15
+ from nvmath._internal.layout import check_monotonic_strides, is_contiguous_and_dense
16
+ from nvmath.internal import tensor_wrapper
17
+ from nvmath.internal.package_ifc import StreamHolder
18
+ from nvmath.internal.tensor_ifc import TensorHolder
19
+ from nvmath.internal.utils import infer_object_package
20
+
21
+ from .sparse_tensor_ifc import SparseTensorHolder
22
+
23
+ """
24
+ A generic type for the third-party CSRTensor which a CSRTensorHolder implementation wraps
25
+ around.
26
+ """
27
+ CSRTensor = TypeVar("CSRTensor")
28
+
29
+
30
+ class CSRTensorHolder(SparseTensorHolder):
31
+ """
32
+ A simple wrapper type for CSR sparse tensors to make the API package-agnostic. The
33
+ naming convention is sparse format name with the suffix "TensorHolder", which convention
34
+ is used in the sparse format helper.
35
+
36
+ Since the implementation is in terms of our dense tensor abstraction, package-specific
37
+ implementation is not needed.
38
+ """
39
+
40
+ _format_name: str = "CSR"
41
+
42
+ def __init__(self, crow_indices, col_indices, values, *, attr_name_map=None, shape=None, tensor=None):
43
+ # tensor is the native tensor.
44
+ self.tensor = tensor
45
+
46
+ # attr_name_map is the canonical attribute name to package attribute name map.
47
+ # It is set when constructing from a tensor, otherwise it is None.
48
+ self._attr_name_map = attr_name_map
49
+
50
+ assert (shape is not None) ^ (tensor is not None), "Internal error."
51
+
52
+ if shape is not None:
53
+ self._shape = shape
54
+ else:
55
+ self._shape = tuple(tensor.shape)
56
+
57
+ # Wrap constituent dense tensors, if required.
58
+ if not isinstance(crow_indices, TensorHolder):
59
+ crow_indices = tensor_wrapper.wrap_operand(crow_indices)
60
+
61
+ if not isinstance(col_indices, TensorHolder):
62
+ col_indices = tensor_wrapper.wrap_operand(col_indices)
63
+
64
+ if not isinstance(values, TensorHolder):
65
+ values = tensor_wrapper.wrap_operand(values)
66
+
67
+ # The wrapped constituent dense tensors.
68
+ self._crow_indices = crow_indices
69
+ self._col_indices = col_indices
70
+ self._values = values
71
+
72
+ # Ensure constituent dense tensors are all on the same device.
73
+ device_ids = {d.device_id for d in (self._crow_indices, self._col_indices, self._values)}
74
+ message = f"Internal error: the arrays defining the sparse format aren't on the same device {device_ids}."
75
+ assert len(device_ids) == 1, message
76
+ self._device_id = device_ids.pop()
77
+
78
+ self._device = self._values.device
79
+
80
+ # Capture the native tensor package for use in reset_unchecked().
81
+ self.tensor_package = infer_object_package(self.tensor)
82
+
83
+ # The tensor holder type for the dense constituent tensors (take from values, since
84
+ # all constituent tensors have the same type).
85
+ self._dense_tensorholder_type = values.__class__
86
+
87
+ @classmethod
88
+ def create_from_tensor(cls, tensor, *, attr_name_map=None):
89
+ assert attr_name_map is not None, "Internal error."
90
+
91
+ # tensor is the native tensor.
92
+ # For UST, the buffers will be CuPy ndarrays.
93
+ crow_indices = attr_name_map["crow_indices"](tensor)
94
+ col_indices = attr_name_map["col_indices"](tensor)
95
+ values = attr_name_map["values"](tensor)
96
+ return CSRTensorHolder(crow_indices, col_indices, values, attr_name_map=attr_name_map, tensor=tensor)
97
+
98
+ @property
99
+ def attr_name_map(self):
100
+ return self._attr_name_map
101
+
102
+ @property
103
+ def device(self):
104
+ return self._device
105
+
106
+ @property
107
+ def device_id(self):
108
+ return self._device_id
109
+
110
+ @property
111
+ def dtype(self):
112
+ return self._values.dtype
113
+
114
+ @property
115
+ def index_type(self):
116
+ return self._crow_indices.dtype
117
+
118
+ @property
119
+ def format_name(self) -> str:
120
+ return CSRTensorHolder._format_name
121
+
122
+ @property
123
+ def num_dimensions(self):
124
+ return len(self._shape)
125
+
126
+ @property
127
+ def shape(self):
128
+ return self._shape
129
+
130
+ @property
131
+ def crow_indices(self) -> TensorHolder:
132
+ """The TensorHolder object wrapping the crow_indices array."""
133
+ return self._crow_indices
134
+
135
+ @property
136
+ def col_indices(self) -> TensorHolder:
137
+ """The TensorHolder object wrapping the col_indices array."""
138
+ return self._col_indices
139
+
140
+ @property
141
+ def values(self) -> TensorHolder:
142
+ """The TensorHolder object wrapping the values array."""
143
+ return self._values
144
+
145
+ def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
146
+ """Copy the CSRTensor representation to a different device.
147
+
148
+ No copy is performed if the CSRTensor is already on the requested device.
149
+ """
150
+
151
+ if self.tensor_package == "nvmath":
152
+ return super().to(device_id=device_id, stream_holder=stream_holder)
153
+
154
+ target_crow_indices = self.crow_indices.to(device_id=device_id, stream_holder=stream_holder)
155
+ target_col_indices = self.col_indices.to(device_id=device_id, stream_holder=stream_holder)
156
+ target_values = self.values.to(device_id=device_id, stream_holder=stream_holder)
157
+
158
+ return CSRTensorHolder(
159
+ target_crow_indices, target_col_indices, target_values, attr_name_map=self.attr_name_map, shape=self.shape
160
+ )
161
+
162
+ def copy_(self, src, stream_holder: StreamHolder | None) -> None:
163
+ """Overwrite self.tensor (in-place) with a copy of src (CSRTensor)."""
164
+
165
+ self.crow_indices.copy_(src=src.crow_indices, stream_holder=stream_holder)
166
+ self.col_indices.copy_(src=src.col_indices, stream_holder=stream_holder)
167
+ self.values.copy_(src=src.values, stream_holder=stream_holder)
168
+
169
+ def to_ust(self, *, stream):
170
+ from nvmath.sparse.ust.tensor import Tensor
171
+ from nvmath.sparse.ust.tensor_format import NamedFormats
172
+
173
+ wrapped = self
174
+ tensor = wrapped.tensor
175
+ if not (wrapped.attr_name_map["is_coalesced"](tensor) and wrapped.attr_name_map["has_sorted_indices"](tensor)):
176
+ raise ValueError(
177
+ "The CSR tensor is not coalesced (metadata sorted with duplicates removed). \
178
+ To coalesce, use the operation provided by your sparse tensor library: `coalesce()`, `sum_duplicates()`, ..."
179
+ )
180
+
181
+ if not (
182
+ is_contiguous_and_dense(wrapped.crow_indices.shape, wrapped.crow_indices.strides)
183
+ and is_contiguous_and_dense(wrapped.col_indices.shape, wrapped.col_indices.strides)
184
+ and is_contiguous_and_dense(wrapped.values.shape, wrapped.values.strides)
185
+ ):
186
+ raise ValueError(
187
+ "The sparse tensor representation (crow_indices(), col_indices(), and values() tensors) must be \
188
+ dense and contiguous."
189
+ )
190
+
191
+ values = wrapped.values.memory_buffer() # Typed memory viewed as a 1-D tensor.
192
+
193
+ num_dim = self.num_dimensions
194
+ num_sparse_dim = self.attr_name_map["num_sparse_dim"](tensor)
195
+ num_dense_dim = self.attr_name_map["num_dense_dim"](tensor)
196
+ num_batch_dim = num_dim - num_sparse_dim - num_dense_dim
197
+ tensor_format = NamedFormats.CSRd(num_batch_dim, num_dense_dim)
198
+
199
+ # Check if the batch axes are in C-order for all component dense arrays.
200
+ if not (
201
+ check_monotonic_strides(wrapped.crow_indices.strides[:num_batch_dim], reverse=True)
202
+ and check_monotonic_strides(wrapped.col_indices.strides[:num_batch_dim], reverse=True)
203
+ and check_monotonic_strides(wrapped.values.strides[:num_batch_dim], reverse=True)
204
+ ):
205
+ raise ValueError(
206
+ "The batch dimensions in the sparse tensor representation (crow_indices(), col_indices(), \
207
+ and values() tensors) must use the C-layout."
208
+ )
209
+
210
+ # Create the UST.
211
+ ust = Tensor(tensor.shape, tensor_format=tensor_format, index_type=wrapped.index_type, dtype=wrapped.dtype)
212
+
213
+ ust._pos[num_batch_dim + 1] = wrapped.crow_indices
214
+ ust._crd[num_batch_dim + 1] = wrapped.col_indices
215
+ ust._val = values
216
+
217
+ return ust
218
+
219
+ def to_package(self):
220
+ """
221
+ This will create a sparse tensor for the original package from which this
222
+ interface was created.
223
+ """
224
+ create_csr = self.attr_name_map["sparse_format_helper"].create_csr
225
+ return create_csr(self.shape, self.crow_indices, self.col_indices, self.values)
226
+
227
+ def release(self):
228
+ """
229
+ This method will release the wrapped tensor and any format-specific data
230
+ by setting them to None.
231
+ """
232
+ # The tensor reference.
233
+ self.tensor = None
234
+
235
+ # Format-specific data.
236
+ self._crow_indices = None
237
+ self._col_indices = None
238
+ self._values = None
239
+
240
+ def reset_unchecked(self, tensor):
241
+ """
242
+ This method will reset the wrapped tensor to the specified one, and update
243
+ any format-specific data accordingly. It assumes that all attributes
244
+ like the device, shape, etc are consistent between the existing and new tensor.
245
+
246
+ Args:
247
+ tensor: The native tensor to wrap.
248
+ """
249
+ # Update the tensor reference.
250
+ self.tensor = tensor
251
+
252
+ # Format-specific data.
253
+
254
+ if self.tensor_package == "nvmath":
255
+ # The data arrays are already wrapped.
256
+ self._crow_indices = self._attr_name_map["crow_indices"](tensor)
257
+ self._col_indices = self._attr_name_map["col_indices"](tensor)
258
+ self._values = self._attr_name_map["values"](tensor)
259
+ else:
260
+ wrapper = self._dense_tensorholder_type
261
+
262
+ crow_indices = self._attr_name_map["crow_indices"](tensor)
263
+ self._crow_indices = wrapper(crow_indices)
264
+
265
+ col_indices = self._attr_name_map["col_indices"](tensor)
266
+ self._col_indices = wrapper(col_indices)
267
+
268
+ values = self._attr_name_map["values"](tensor)
269
+ self._values = wrapper(values)
270
+
271
+ def release_keeping_shell(self):
272
+ """Release the wrapped tensor and constituent data by setting them to None."""
273
+ self.tensor = None
274
+ self._crow_indices.tensor = None
275
+ self._col_indices.tensor = None
276
+ self._values.tensor = None
277
+
278
+ def reset_unchecked_keeping_shell(self, tensor):
279
+ """Reset the wrapped tensor and update constituent data accordingly.
280
+
281
+ Assumes that the new tensor has the same shape, device, dtype, and
282
+ index type as the original.
283
+ """
284
+ self.tensor = tensor
285
+ attr_map = self._attr_name_map
286
+ self._crow_indices.tensor = attr_map["crow_indices"](tensor)
287
+ self._col_indices.tensor = attr_map["col_indices"](tensor)
288
+ self._values.tensor = attr_map["values"](tensor)