nvmath-python 0.9.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. nvmath/__init__.pxd +0 -0
  2. nvmath/__init__.py +45 -0
  3. nvmath/_internal/__init__.py +0 -0
  4. nvmath/_internal/attribute_ifc_factory.py +330 -0
  5. nvmath/_internal/layout.py +70 -0
  6. nvmath/_internal/templates.py +383 -0
  7. nvmath/_utils.py +150 -0
  8. nvmath/bindings/__init__.py +51 -0
  9. nvmath/bindings/_internal/__init__.pxd +0 -0
  10. nvmath/bindings/_internal/__init__.py +0 -0
  11. nvmath/bindings/_internal/cublas.cp314-win_amd64.pyd +0 -0
  12. nvmath/bindings/_internal/cublas.pxd +530 -0
  13. nvmath/bindings/_internal/cublasLt.cp314-win_amd64.pyd +0 -0
  14. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  15. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  16. nvmath/bindings/_internal/cudss.cp314-win_amd64.pyd +0 -0
  17. nvmath/bindings/_internal/cudss.pxd +47 -0
  18. nvmath/bindings/_internal/cufft.cp314-win_amd64.pyd +0 -0
  19. nvmath/bindings/_internal/cufft.pxd +70 -0
  20. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  21. nvmath/bindings/_internal/curand.cp314-win_amd64.pyd +0 -0
  22. nvmath/bindings/_internal/curand.pxd +42 -0
  23. nvmath/bindings/_internal/cusolver.cp314-win_amd64.pyd +0 -0
  24. nvmath/bindings/_internal/cusolver.pxd +15 -0
  25. nvmath/bindings/_internal/cusolverDn.cp314-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  27. nvmath/bindings/_internal/cusparse.cp314-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusparse.pxd +277 -0
  29. nvmath/bindings/_internal/cusparseLt.cp314-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  31. nvmath/bindings/_internal/cutensor.cp314-win_amd64.pyd +0 -0
  32. nvmath/bindings/_internal/cutensor.pxd +58 -0
  33. nvmath/bindings/_internal/mathdx.cp314-win_amd64.pyd +0 -0
  34. nvmath/bindings/_internal/mathdx.pxd +116 -0
  35. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  36. nvmath/bindings/_internal/utils.cp314-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/utils.pxd +179 -0
  38. nvmath/bindings/_internal/utils.pyi +10 -0
  39. nvmath/bindings/cublas.cp314-win_amd64.pyd +0 -0
  40. nvmath/bindings/cublas.pxd +558 -0
  41. nvmath/bindings/cublas.pyi +746 -0
  42. nvmath/bindings/cublasLt.cp314-win_amd64.pyd +0 -0
  43. nvmath/bindings/cublasLt.pxd +109 -0
  44. nvmath/bindings/cublasLt.pyi +1337 -0
  45. nvmath/bindings/cublasMp.pxd +85 -0
  46. nvmath/bindings/cublasMp.pyi +219 -0
  47. nvmath/bindings/cudss.cp314-win_amd64.pyd +0 -0
  48. nvmath/bindings/cudss.pxd +86 -0
  49. nvmath/bindings/cudss.pyi +282 -0
  50. nvmath/bindings/cufft.cp314-win_amd64.pyd +0 -0
  51. nvmath/bindings/cufft.pxd +118 -0
  52. nvmath/bindings/cufft.pyi +241 -0
  53. nvmath/bindings/cufftMp.pxd +124 -0
  54. nvmath/bindings/cufftMp.pyi +260 -0
  55. nvmath/bindings/curand.cp314-win_amd64.pyd +0 -0
  56. nvmath/bindings/curand.pxd +71 -0
  57. nvmath/bindings/curand.pyi +159 -0
  58. nvmath/bindings/cusolver.cp314-win_amd64.pyd +0 -0
  59. nvmath/bindings/cusolver.pxd +62 -0
  60. nvmath/bindings/cusolver.pyi +242 -0
  61. nvmath/bindings/cusolverDn.cp314-win_amd64.pyd +0 -0
  62. nvmath/bindings/cusolverDn.pxd +430 -0
  63. nvmath/bindings/cusolverDn.pyi +416 -0
  64. nvmath/bindings/cusparse.cp314-win_amd64.pyd +0 -0
  65. nvmath/bindings/cusparse.pxd +338 -0
  66. nvmath/bindings/cusparse.pyi +659 -0
  67. nvmath/bindings/cusparseLt.cp314-win_amd64.pyd +0 -0
  68. nvmath/bindings/cusparseLt.pxd +99 -0
  69. nvmath/bindings/cusparseLt.pyi +198 -0
  70. nvmath/bindings/cutensor.cp314-win_amd64.pyd +0 -0
  71. nvmath/bindings/cutensor.pxd +98 -0
  72. nvmath/bindings/cutensor.pyi +294 -0
  73. nvmath/bindings/cycublas.cp314-win_amd64.pyd +0 -0
  74. nvmath/bindings/cycublas.pxd +684 -0
  75. nvmath/bindings/cycublasLt.cp314-win_amd64.pyd +0 -0
  76. nvmath/bindings/cycublasLt.pxd +1055 -0
  77. nvmath/bindings/cycublasMp.pxd +183 -0
  78. nvmath/bindings/cycudss.cp314-win_amd64.pyd +0 -0
  79. nvmath/bindings/cycudss.pxd +224 -0
  80. nvmath/bindings/cycufft.cp314-win_amd64.pyd +0 -0
  81. nvmath/bindings/cycufft.pxd +326 -0
  82. nvmath/bindings/cycufftMp.pxd +334 -0
  83. nvmath/bindings/cycurand.cp314-win_amd64.pyd +0 -0
  84. nvmath/bindings/cycurand.pxd +146 -0
  85. nvmath/bindings/cycusolver.cp314-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycusolver.pxd +154 -0
  87. nvmath/bindings/cycusolverDn.cp314-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycusolverDn.pxd +446 -0
  89. nvmath/bindings/cycusparse.cp314-win_amd64.pyd +0 -0
  90. nvmath/bindings/cycusparse.pxd +470 -0
  91. nvmath/bindings/cycusparseLt.cp314-win_amd64.pyd +0 -0
  92. nvmath/bindings/cycusparseLt.pxd +150 -0
  93. nvmath/bindings/cycutensor.cp314-win_amd64.pyd +0 -0
  94. nvmath/bindings/cycutensor.pxd +192 -0
  95. nvmath/bindings/cymathdx.cp314-win_amd64.pyd +0 -0
  96. nvmath/bindings/cymathdx.pxd +552 -0
  97. nvmath/bindings/cynvshmem.pxd +126 -0
  98. nvmath/bindings/mathdx.cp314-win_amd64.pyd +0 -0
  99. nvmath/bindings/mathdx.pxd +182 -0
  100. nvmath/bindings/mathdx.pyi +1244 -0
  101. nvmath/bindings/nvpl/__init__.pxd +0 -0
  102. nvmath/bindings/nvpl/__init__.py +13 -0
  103. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  104. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  105. nvmath/bindings/nvpl/_internal/blas.cp314-win_amd64.pyd +0 -0
  106. nvmath/bindings/nvpl/_internal/blas.pxd +125 -0
  107. nvmath/bindings/nvpl/_internal/fft.cp314-win_amd64.pyd +0 -0
  108. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  109. nvmath/bindings/nvpl/blas.cp314-win_amd64.pyd +0 -0
  110. nvmath/bindings/nvpl/blas.pxd +85 -0
  111. nvmath/bindings/nvpl/blas.pyi +122 -0
  112. nvmath/bindings/nvpl/cyblas.cp314-win_amd64.pyd +0 -0
  113. nvmath/bindings/nvpl/cyblas.pxd +166 -0
  114. nvmath/bindings/nvpl/cyfft.cp314-win_amd64.pyd +0 -0
  115. nvmath/bindings/nvpl/cyfft.pxd +92 -0
  116. nvmath/bindings/nvpl/fft.cp314-win_amd64.pyd +0 -0
  117. nvmath/bindings/nvpl/fft.pxd +100 -0
  118. nvmath/bindings/nvpl/fft.pyi +100 -0
  119. nvmath/bindings/nvshmem.pxd +54 -0
  120. nvmath/bindings/nvshmem.pyi +179 -0
  121. nvmath/device/__init__.py +21 -0
  122. nvmath/device/_deprecated.py +33 -0
  123. nvmath/device/common.py +313 -0
  124. nvmath/device/common_backend.py +131 -0
  125. nvmath/device/common_cuda.py +201 -0
  126. nvmath/device/common_numba.py +310 -0
  127. nvmath/device/common_opaque_tensor.py +201 -0
  128. nvmath/device/cublasdx.py +1805 -0
  129. nvmath/device/cublasdx_backend.py +807 -0
  130. nvmath/device/cublasdx_numba.py +1612 -0
  131. nvmath/device/cufftdx.py +510 -0
  132. nvmath/device/cufftdx_backend.py +196 -0
  133. nvmath/device/cufftdx_numba.py +196 -0
  134. nvmath/device/curand_kernel.py +9147 -0
  135. nvmath/device/cusolverdx.py +2690 -0
  136. nvmath/device/cusolverdx_backend.py +440 -0
  137. nvmath/device/cusolverdx_numba.py +1624 -0
  138. nvmath/device/llvm_array.py +29 -0
  139. nvmath/device/random.py +445 -0
  140. nvmath/device/random_helpers.py +23 -0
  141. nvmath/device/random_states.py +187 -0
  142. nvmath/device/types.py +147 -0
  143. nvmath/device/vector_types_numba.py +203 -0
  144. nvmath/distributed/__init__.py +205 -0
  145. nvmath/distributed/_internal/__init__.py +0 -0
  146. nvmath/distributed/_internal/nvshmem.py +302 -0
  147. nvmath/distributed/_internal/tensor_ifc.py +67 -0
  148. nvmath/distributed/_internal/tensor_ifc_cupy.py +62 -0
  149. nvmath/distributed/_internal/tensor_ifc_host_device.py +165 -0
  150. nvmath/distributed/_internal/tensor_ifc_numpy.py +41 -0
  151. nvmath/distributed/_internal/tensor_ifc_torch.py +141 -0
  152. nvmath/distributed/_internal/tensor_wrapper.py +78 -0
  153. nvmath/distributed/_utils.py +167 -0
  154. nvmath/distributed/distribution.py +770 -0
  155. nvmath/distributed/fft/__init__.py +7 -0
  156. nvmath/distributed/fft/_configuration.py +79 -0
  157. nvmath/distributed/fft/fft.py +2801 -0
  158. nvmath/distributed/linalg/__init__.py +12 -0
  159. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  160. nvmath/distributed/linalg/_internal/epilog_protocol.py +496 -0
  161. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  162. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  163. nvmath/distributed/linalg/advanced/_configuration.py +166 -0
  164. nvmath/distributed/linalg/advanced/matmulmod.py +2908 -0
  165. nvmath/distributed/process_group.py +408 -0
  166. nvmath/distributed/reshape/__init__.py +6 -0
  167. nvmath/distributed/reshape/_configuration.py +39 -0
  168. nvmath/distributed/reshape/reshape.py +1256 -0
  169. nvmath/fft/__init__.py +7 -0
  170. nvmath/fft/_configuration.py +208 -0
  171. nvmath/fft/_exec_utils.py +109 -0
  172. nvmath/fft/_helpers.py +237 -0
  173. nvmath/fft/fft.py +2903 -0
  174. nvmath/internal/__init__.pxd +3 -0
  175. nvmath/internal/__init__.py +10 -0
  176. nvmath/internal/_bindings.cp314-win_amd64.pyd +0 -0
  177. nvmath/internal/_bindings.pxd +12 -0
  178. nvmath/internal/_device_utils.py +54 -0
  179. nvmath/internal/enum_utils.py +142 -0
  180. nvmath/internal/formatters.py +87 -0
  181. nvmath/internal/mem_limit.py +51 -0
  182. nvmath/internal/memory.cp314-win_amd64.pyd +0 -0
  183. nvmath/internal/memory.pxd +10 -0
  184. nvmath/internal/memory.pyi +46 -0
  185. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  186. nvmath/internal/ndbuffer/__init__.py +7 -0
  187. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  188. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  189. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  190. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  191. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +240 -0
  192. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  193. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  194. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  195. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  196. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  197. nvmath/internal/ndbuffer/copy_kernel.cp314-win_amd64.pyd +0 -0
  198. nvmath/internal/ndbuffer/copy_kernel.pxd +9 -0
  199. nvmath/internal/ndbuffer/copy_kernel.pyi +9 -0
  200. nvmath/internal/ndbuffer/data_layout.cp314-win_amd64.pyd +0 -0
  201. nvmath/internal/ndbuffer/data_layout.pxd +72 -0
  202. nvmath/internal/ndbuffer/data_layout.pyi +23 -0
  203. nvmath/internal/ndbuffer/jit.cp314-win_amd64.pyd +0 -0
  204. nvmath/internal/ndbuffer/jit.pxd +7 -0
  205. nvmath/internal/ndbuffer/jit.pyi +6 -0
  206. nvmath/internal/ndbuffer/ndbuffer.cp314-win_amd64.pyd +0 -0
  207. nvmath/internal/ndbuffer/ndbuffer.pxd +36 -0
  208. nvmath/internal/ndbuffer/ndbuffer.pyi +41 -0
  209. nvmath/internal/ndbuffer/package_utils.cp314-win_amd64.pyd +0 -0
  210. nvmath/internal/ndbuffer/package_utils.pxd +11 -0
  211. nvmath/internal/ndbuffer/package_utils.pyi +12 -0
  212. nvmath/internal/package_ifc.py +147 -0
  213. nvmath/internal/package_ifc_cuda.py +49 -0
  214. nvmath/internal/package_ifc_cupy.py +49 -0
  215. nvmath/internal/package_ifc_torch.py +31 -0
  216. nvmath/internal/package_wrapper.py +14 -0
  217. nvmath/internal/tensor_ifc.py +194 -0
  218. nvmath/internal/tensor_ifc_cupy.py +241 -0
  219. nvmath/internal/tensor_ifc_ndbuffer.py +153 -0
  220. nvmath/internal/tensor_ifc_numpy.py +183 -0
  221. nvmath/internal/tensor_ifc_torch.py +176 -0
  222. nvmath/internal/tensor_wrapper.py +157 -0
  223. nvmath/internal/typemaps.py +162 -0
  224. nvmath/internal/utils.py +771 -0
  225. nvmath/linalg/__init__.py +46 -0
  226. nvmath/linalg/_internal/__init__.py +3 -0
  227. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  228. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  229. nvmath/linalg/_internal/batch.py +217 -0
  230. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  231. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  232. nvmath/linalg/_internal/layout.py +624 -0
  233. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  234. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  235. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  236. nvmath/linalg/_internal/typemaps.py +144 -0
  237. nvmath/linalg/_internal/utils.py +134 -0
  238. nvmath/linalg/advanced/__init__.py +8 -0
  239. nvmath/linalg/advanced/_algorithmmod.py +149 -0
  240. nvmath/linalg/advanced/_configuration.py +349 -0
  241. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  242. nvmath/linalg/advanced/helpers/matmul.py +1348 -0
  243. nvmath/linalg/advanced/matmulmod.py +3937 -0
  244. nvmath/linalg/generic/__init__.py +43 -0
  245. nvmath/linalg/generic/_configuration/__init__.py +37 -0
  246. nvmath/linalg/generic/_configuration/layout.py +263 -0
  247. nvmath/linalg/generic/_configuration/match.py +609 -0
  248. nvmath/linalg/generic/_configuration/qualifiers.py +494 -0
  249. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  250. nvmath/linalg/generic/_dtype.py +15 -0
  251. nvmath/linalg/generic/matmulmod.py +1060 -0
  252. nvmath/memory.py +282 -0
  253. nvmath/sparse/__init__.py +38 -0
  254. nvmath/sparse/_internal/__init__.py +21 -0
  255. nvmath/sparse/_internal/common_utils.py +144 -0
  256. nvmath/sparse/_internal/cudss_config_ifc.py +741 -0
  257. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  258. nvmath/sparse/_internal/cudss_utils.py +445 -0
  259. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  260. nvmath/sparse/_internal/sparse_bsc_ifc.py +300 -0
  261. nvmath/sparse/_internal/sparse_bsr_ifc.py +303 -0
  262. nvmath/sparse/_internal/sparse_coo_ifc.py +254 -0
  263. nvmath/sparse/_internal/sparse_csc_ifc.py +266 -0
  264. nvmath/sparse/_internal/sparse_csr_ifc.py +266 -0
  265. nvmath/sparse/_internal/sparse_dia_ifc.py +239 -0
  266. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  267. nvmath/sparse/_internal/sparse_tensor_ifc.py +121 -0
  268. nvmath/sparse/_internal/sparse_ust_ifc.py +146 -0
  269. nvmath/sparse/_internal/utils.py +56 -0
  270. nvmath/sparse/advanced/__init__.py +7 -0
  271. nvmath/sparse/advanced/_configuration.py +230 -0
  272. nvmath/sparse/advanced/direct_solver.py +1884 -0
  273. nvmath/sparse/generic/__init__.py +7 -0
  274. nvmath/sparse/generic/_configuration.py +129 -0
  275. nvmath/sparse/generic/_helpers.py +137 -0
  276. nvmath/sparse/generic/_thunks.py +21 -0
  277. nvmath/sparse/generic/matmulmod.py +2426 -0
  278. nvmath/sparse/ust/__init__.py +7 -0
  279. nvmath/sparse/ust/_converters.py +378 -0
  280. nvmath/sparse/ust/_drawer.py +552 -0
  281. nvmath/sparse/ust/_emitter.py +553 -0
  282. nvmath/sparse/ust/_jit.py +212 -0
  283. nvmath/sparse/ust/_kernel.py +346 -0
  284. nvmath/sparse/ust/_semiring.py +71 -0
  285. nvmath/sparse/ust/_utils.py +102 -0
  286. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  287. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  288. nvmath/sparse/ust/semiring_ops.py +71 -0
  289. nvmath/sparse/ust/tensor.py +1027 -0
  290. nvmath/sparse/ust/tensor_drawer.py +552 -0
  291. nvmath/sparse/ust/tensor_emitter.py +558 -0
  292. nvmath/sparse/ust/tensor_format.py +935 -0
  293. nvmath/sparse/ust/tensor_jit.py +212 -0
  294. nvmath/sparse/ust/tensor_kernel.py +348 -0
  295. nvmath/sparse/ust/tensor_utils.py +380 -0
  296. nvmath/tensor/__init__.py +6 -0
  297. nvmath/tensor/_configuration.py +95 -0
  298. nvmath/tensor/_internal/__init__.py +3 -0
  299. nvmath/tensor/_internal/cutensor_config_ifc.py +247 -0
  300. nvmath/tensor/_internal/cutensor_utils.py +162 -0
  301. nvmath/tensor/_internal/data.py +43 -0
  302. nvmath/tensor/_internal/einsum_parser.py +444 -0
  303. nvmath/tensor/_internal/typemaps.py +96 -0
  304. nvmath/tensor/contract.py +1861 -0
  305. nvmath_python-0.9.0.dist-info/METADATA +127 -0
  306. nvmath_python-0.9.0.dist-info/RECORD +309 -0
  307. nvmath_python-0.9.0.dist-info/WHEEL +5 -0
  308. nvmath_python-0.9.0.dist-info/licenses/LICENSE +177 -0
  309. nvmath_python-0.9.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,445 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from collections.abc import Sequence
6
+
7
+ import numpy as np
8
+
9
+ from nvmath.bindings import cudss
10
+ from nvmath.internal.tensor_wrapper import wrap_operand
11
+
12
+ COMPATIBLE_LHS_RHS_PACKAGES = {("scipy", "numpy"), ("cupyx", "cupy"), ("torch", "torch")}
13
+
14
+
15
+ # TODO: Add debug log messages.
16
+ def wrap_dense_tensors(tensor_type, native_operands):
17
+ # Unchecked faster version of tensor_wrapper.wrap_operands().
18
+ return tuple(tensor_type(o) for o in native_operands)
19
+
20
+
21
+ def wrap_sparse_tensors(tensor_type, attr_name_map, native_operands):
22
+ # A more direct version of nvmath.sparse._internal.common_utils.wrap_sparse_operands().
23
+ return tuple(tensor_type.create_from_tensor(o, attr_name_map=attr_name_map) for o in native_operands)
24
+
25
+
26
+ def create_cudss_dense_matrix(cuda_value_type, rhs):
27
+ # The rhs should be a wrapped (TensorHolder object) matrix or vector in a memory space
28
+ # consistent with the execution mode.
29
+ shape = rhs.shape
30
+ assert len(shape) <= 2, "Internal error."
31
+
32
+ m = shape[0]
33
+ n = shape[1] if len(shape) == 2 else 1
34
+
35
+ # Only column-major is supported.
36
+ ld = m
37
+
38
+ rhs_ptr = cudss.matrix_create_dn(m, n, ld, rhs.data_ptr, cuda_value_type, cudss.Layout.COL_MAJOR)
39
+ return [], [], rhs_ptr
40
+
41
+
42
+ def create_cudss_dense_explicit_batch(cuda_index_type, cuda_value_type, index_type, rhs, stream_holder):
43
+ # The rhs should be a sequence of wrapped (TensorHolder object) matrix or vector in a
44
+ # memory space consistent with the execution mode.
45
+ assert isinstance(rhs, Sequence), "Internal error."
46
+
47
+ batch_count = len(rhs)
48
+
49
+ m = wrap_operand(np.array([r.shape[0] for r in rhs], dtype=index_type))
50
+ n = wrap_operand(np.array([r.shape[1] if len(r.shape) == 2 else 1 for r in rhs], dtype=index_type))
51
+
52
+ # Take device ID of the first matrix, since it's the same for all.
53
+ device_id = rhs[0].device_id
54
+
55
+ # The pointers must be a device array. We'll first create it on the host, wrap and
56
+ # copy it to the device.
57
+ p = wrap_operand(np.array([r.data_ptr for r in rhs], dtype=np.uint64))
58
+ p = p.to(device_id=device_id, stream_holder=stream_holder)
59
+
60
+ # LD is the same as M, since only column-major is supported.
61
+ rhs_ptr = cudss.matrix_create_batch_dn(
62
+ batch_count, m.data_ptr, n.data_ptr, m.data_ptr, p.data_ptr, cuda_index_type, cuda_value_type, cudss.Layout.COL_MAJOR
63
+ )
64
+
65
+ return [m, n], [p], rhs_ptr
66
+
67
+
68
+ def create_cudss_dense_implicit_batch(cuda_index_type, cuda_value_type, index_type, batch_indices, rhs, stream_holder):
69
+ # The rhs should be a wrapped (TensorHolder object) NDarray 3D or greater dimension.
70
+ assert len(rhs.shape) > 2, "Internal error."
71
+
72
+ # Create a sequence of samples in the batch.
73
+ # Explicitly unpack indices to avoid tensor[*b, ...] (support 3.10).
74
+ unpacked_indices = [tuple(b) + (...,) for b in batch_indices]
75
+ rhs_sequence = [rhs.tensor[u] for u in unpacked_indices]
76
+
77
+ # Wrap the samples using the lightweight interface, since we've already checked.
78
+ rhs_sequence = wrap_dense_tensors(rhs.__class__, rhs_sequence)
79
+
80
+ return create_cudss_dense_explicit_batch(cuda_index_type, cuda_value_type, index_type, rhs_sequence, stream_holder)
81
+
82
+
83
+ def create_cudss_dense_wrapper(cuda_index_type, cuda_value_type, index_type, batch_indices, rhs, stream_holder):
84
+ # A convenience function to forward to the right implementation.
85
+
86
+ if isinstance(rhs, Sequence):
87
+ return create_cudss_dense_explicit_batch(cuda_index_type, cuda_value_type, index_type, rhs, stream_holder)
88
+
89
+ if len(rhs.shape) > 2:
90
+ return create_cudss_dense_implicit_batch(
91
+ cuda_index_type, cuda_value_type, index_type, batch_indices, rhs, stream_holder
92
+ )
93
+
94
+ return create_cudss_dense_matrix(cuda_value_type, rhs)
95
+
96
+
97
+ def update_cudss_dense_matrix_ptr(rhs_ptr, new_rhs):
98
+ # The new rhs should be a wrapped (TensorHolder object) matrix or vector in a memory
99
+ # space consistent with the execution mode.
100
+ # rhs_ptr is a cuDSS matrix ptr.
101
+ assert len(new_rhs.shape) <= 2, "Internal error."
102
+ cudss.matrix_set_values(rhs_ptr, new_rhs.data_ptr)
103
+
104
+ return []
105
+
106
+
107
+ def update_cudss_dense_explicit_batch_ptr(rhs_ptr, new_rhs, stream_holder, existing_ptrs):
108
+ # The new rhs should be a sequence of wrapped (TensorHolder object) matrix or vector
109
+ # in a memory space consistent with the execution mode.
110
+ assert isinstance(new_rhs, Sequence), "Internal error."
111
+
112
+ # Build host array of data pointers for each batch element and copy into the
113
+ # existing device buffer.
114
+ host_p = wrap_operand(np.array([r.data_ptr for r in new_rhs], dtype=np.uint64))
115
+ existing_ptrs[0].copy_(host_p, stream_holder=stream_holder)
116
+
117
+
118
+ def update_cudss_dense_implicit_batch_ptr(rhs_ptr, batch_indices, new_rhs, stream_holder, existing_ptrs):
119
+ # The new rhs should be a wrapped (TensorHolder object) NDarray 3D or greater dimension.
120
+ assert len(new_rhs.shape) > 2, "Internal error."
121
+
122
+ # Create a sequence of samples in the batch.
123
+ # Explicitly unpack indices to avoid tensor[*b, ...] (support 3.10).
124
+ unpacked_indices = [tuple(b) + (...,) for b in batch_indices]
125
+ rhs_sequence = [new_rhs.tensor[u] for u in unpacked_indices]
126
+
127
+ # Wrap the samples using the lightweight interface, since we've already checked.
128
+ rhs_sequence = wrap_dense_tensors(new_rhs.__class__, rhs_sequence)
129
+
130
+ update_cudss_dense_explicit_batch_ptr(rhs_ptr, rhs_sequence, stream_holder, existing_ptrs)
131
+
132
+
133
+ def update_cudss_dense_ptr_wrapper(*, existing_ptrs, rhs_ptr, batch_indices=None, new_rhs=None, stream_holder=None):
134
+ # A convenience function to forward to the right update implementation.
135
+ # For batched cases, existing_ptrs must be the list originally returned by the
136
+ # corresponding create function; pointer values are copied into the existing
137
+ # device buffers in place. For non-batched cases existing_ptrs is unused.
138
+ assert new_rhs is not None, "Internal error."
139
+
140
+ if isinstance(new_rhs, Sequence):
141
+ assert stream_holder is not None and existing_ptrs, "Internal error."
142
+ update_cudss_dense_explicit_batch_ptr(rhs_ptr, new_rhs, stream_holder, existing_ptrs)
143
+ return
144
+
145
+ if len(new_rhs.shape) > 2:
146
+ assert batch_indices is not None and stream_holder is not None and existing_ptrs, "Internal error."
147
+ update_cudss_dense_implicit_batch_ptr(rhs_ptr, batch_indices, new_rhs, stream_holder, existing_ptrs)
148
+ return
149
+
150
+ update_cudss_dense_matrix_ptr(rhs_ptr, new_rhs)
151
+
152
+
153
+ def create_cudss_csr_matrix(cuda_index_type, cuda_value_type, matrix_type, matrix_view_type, lhs):
154
+ # The lhs should be a wrapped (CSRTensorHolder object) matrix in a memory space
155
+ # consistent with the execution mode.
156
+ assert lhs.format_name == "CSR", "Internal error."
157
+
158
+ shape = lhs.shape
159
+ assert len(shape) == 2, "Internal error."
160
+
161
+ m, n = shape
162
+ nnz = lhs.values.size
163
+
164
+ lhs_ptr = cudss.matrix_create_csr(
165
+ m,
166
+ n,
167
+ nnz,
168
+ lhs.crow_indices.data_ptr,
169
+ 0,
170
+ lhs.col_indices.data_ptr,
171
+ lhs.values.data_ptr,
172
+ cuda_index_type,
173
+ cuda_value_type,
174
+ matrix_type,
175
+ matrix_view_type,
176
+ cudss.IndexBase.ZERO,
177
+ )
178
+ return [], [], lhs_ptr
179
+
180
+
181
+ def create_cudss_csr_explicit_batch(
182
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, lhs, stream_holder
183
+ ):
184
+ # The lhs should be a sequence of wrapped (CSRTensorHolder object) matrix in a memory
185
+ # space consistent with the execution mode.
186
+ assert isinstance(lhs, Sequence), "Internal error."
187
+
188
+ batch_count = len(lhs)
189
+
190
+ m = wrap_operand(np.array([o.shape[0] for o in lhs], dtype=index_type))
191
+ n = wrap_operand(np.array([o.shape[1] for o in lhs], dtype=index_type))
192
+ nnz = wrap_operand(np.array([o.values.size for o in lhs], dtype=index_type))
193
+
194
+ # Take device ID of the first operator, since it's the same for all.
195
+ device_id = lhs[0].device_id
196
+
197
+ # The pointer arrays must be on device. We'll first create it on the host, wrap and
198
+ # copy it to the device.
199
+ crow_indices = wrap_operand(np.array([o.crow_indices.data_ptr for o in lhs], dtype=np.uint64))
200
+ crow_indices = crow_indices.to(device_id=device_id, stream_holder=stream_holder)
201
+
202
+ col_indices = wrap_operand(np.array([o.col_indices.data_ptr for o in lhs], dtype=np.uint64))
203
+ col_indices = col_indices.to(device_id=device_id, stream_holder=stream_holder)
204
+
205
+ values = wrap_operand(np.array([o.values.data_ptr for o in lhs], dtype=np.uint64))
206
+ values = values.to(device_id=device_id, stream_holder=stream_holder)
207
+
208
+ lhs_ptr = cudss.matrix_create_batch_csr(
209
+ batch_count,
210
+ m.data_ptr,
211
+ n.data_ptr,
212
+ nnz.data_ptr,
213
+ crow_indices.data_ptr,
214
+ 0,
215
+ col_indices.data_ptr,
216
+ values.data_ptr,
217
+ cuda_index_type,
218
+ cuda_value_type,
219
+ matrix_type,
220
+ matrix_view_type,
221
+ cudss.IndexBase.ZERO,
222
+ )
223
+ return [m, n, nnz], [crow_indices, col_indices, values], lhs_ptr
224
+
225
+
226
+ def create_cudss_csr_implicit_batch(
227
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, batch_indices, lhs, stream_holder
228
+ ):
229
+ # The lhs should be a wrapped CSRTensorHolder object in a memory space consistent with
230
+ # the execution mode.
231
+ assert lhs.num_dimensions > 2, "Internal error."
232
+
233
+ # We can't use an elegant implementation like for the dense implicit batch, where we
234
+ # index the samples in the tensor to form an explicit sequence and forward to the dense
235
+ # explicit batch implementation. This is because we can't rely on having the native
236
+ # LHS tensor after copying across memory spaces.
237
+
238
+ # For this function, we assume that the batch_indices are consistent with the
239
+ # specified lhs.
240
+ batch_count = len(batch_indices)
241
+
242
+ # The shape is constant for each sample.
243
+ shape = lhs.shape[-2], lhs.shape[-1]
244
+ m = wrap_operand(np.full(batch_count, shape[0], dtype=index_type))
245
+ n = wrap_operand(np.full(batch_count, shape[1], dtype=index_type))
246
+
247
+ # Explicitly unpack indices to avoid tensor[*b, ...] (support 3.10).
248
+ unpacked_indices = [tuple(b) + (...,) for b in batch_indices]
249
+
250
+ # Create a sequence of wrapped samples in the batch for each of the constituent dense
251
+ # arrays.
252
+ crow_indices_sequence = [lhs.crow_indices.__class__(lhs.crow_indices.tensor[u]) for u in unpacked_indices]
253
+ col_indices_sequence = [lhs.col_indices.__class__(lhs.col_indices.tensor[u]) for u in unpacked_indices]
254
+ values_sequence = [lhs.values.__class__(lhs.values.tensor[u]) for u in unpacked_indices]
255
+
256
+ # The pointer arrays must be on device. We'll first create it on the host, wrap and
257
+ # copy it to the device.
258
+ crow_indices = wrap_operand(np.array([o.data_ptr for o in crow_indices_sequence], dtype=np.uint64))
259
+ crow_indices = crow_indices.to(device_id=lhs.device_id, stream_holder=stream_holder)
260
+
261
+ col_indices = wrap_operand(np.array([o.data_ptr for o in col_indices_sequence], dtype=np.uint64))
262
+ col_indices = col_indices.to(device_id=lhs.device_id, stream_holder=stream_holder)
263
+
264
+ values = wrap_operand(np.array([o.data_ptr for o in values_sequence], dtype=np.uint64))
265
+ values = values.to(device_id=lhs.device_id, stream_holder=stream_holder)
266
+
267
+ # The nnz should be the same for each sample, but we'll iterate anyway.
268
+ nnz = wrap_operand(np.array([o.size for o in values_sequence], dtype=index_type))
269
+
270
+ lhs_ptr = cudss.matrix_create_batch_csr(
271
+ batch_count,
272
+ m.data_ptr,
273
+ n.data_ptr,
274
+ nnz.data_ptr,
275
+ crow_indices.data_ptr,
276
+ 0,
277
+ col_indices.data_ptr,
278
+ values.data_ptr,
279
+ cuda_index_type,
280
+ cuda_value_type,
281
+ matrix_type,
282
+ matrix_view_type,
283
+ cudss.IndexBase.ZERO,
284
+ )
285
+ return [m, n, nnz], [crow_indices, col_indices, values], lhs_ptr
286
+
287
+
288
+ def create_cudss_batchedcsr_implicit_batch(
289
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, batch_indices, lhs, stream_holder
290
+ ):
291
+ # The lhs should be a wrapped CSRTensorHolder object containing an 3D BatchedCSR UST.
292
+ assert lhs.num_dimensions == 3, "Internal error."
293
+
294
+ # For this function, we assume that the batch_indices are consistent with the
295
+ # specified lhs.
296
+ batch_count = len(batch_indices)
297
+ assert batch_count == lhs.shape[0], "Internal error."
298
+
299
+ # The shape is constant for each sample.
300
+ shape = lhs.shape[-2], lhs.shape[-1]
301
+ m = wrap_operand(np.full(batch_count, shape[0], dtype=index_type))
302
+ n = wrap_operand(np.full(batch_count, shape[1], dtype=index_type))
303
+
304
+ # Create a sequence of wrapped samples in the batch for each of the constituent dense
305
+ # arrays.
306
+ crow_indices_sequence = []
307
+ col_indices_sequence = []
308
+ values_sequence = []
309
+ for b in range(batch_count):
310
+ s = shape[0]
311
+ # Take a copy, since we are offsetting crow_indices to start at 0.
312
+ crow_b = lhs.crow_indices.tensor[b * s : (b + 1) * s + 1].copy()
313
+ crow_indices_sequence.append(lhs.crow_indices.__class__(crow_b))
314
+ col_b = lhs.col_indices.tensor[crow_b[0] : crow_b[-1]]
315
+ col_indices_sequence.append(lhs.col_indices.__class__(col_b))
316
+ values_b = lhs.values.tensor[crow_b[0] : crow_b[-1]]
317
+ values_sequence.append(lhs.values.__class__(values_b))
318
+ # Offset the crow_indices after col_indices and values are sliced.
319
+ crow_b -= crow_b[0]
320
+
321
+ # The pointer arrays must be on device. We'll first create it on the host, wrap and
322
+ # copy it to the device.
323
+ crow_indices = wrap_operand(np.array([o.data_ptr for o in crow_indices_sequence], dtype=np.uint64))
324
+ crow_indices = crow_indices.to(device_id=lhs.device_id, stream_holder=stream_holder)
325
+
326
+ col_indices = wrap_operand(np.array([o.data_ptr for o in col_indices_sequence], dtype=np.uint64))
327
+ col_indices = col_indices.to(device_id=lhs.device_id, stream_holder=stream_holder)
328
+
329
+ values = wrap_operand(np.array([o.data_ptr for o in values_sequence], dtype=np.uint64))
330
+ values = values.to(device_id=lhs.device_id, stream_holder=stream_holder)
331
+
332
+ # The nnz can vary for each sample in UST BatchedCSR, it is important to iterate.
333
+ nnz = wrap_operand(np.array([o.size for o in values_sequence], dtype=index_type))
334
+
335
+ lhs_ptr = cudss.matrix_create_batch_csr(
336
+ batch_count,
337
+ m.data_ptr,
338
+ n.data_ptr,
339
+ nnz.data_ptr,
340
+ crow_indices.data_ptr,
341
+ 0,
342
+ col_indices.data_ptr,
343
+ values.data_ptr,
344
+ cuda_index_type,
345
+ cuda_value_type,
346
+ matrix_type,
347
+ matrix_view_type,
348
+ cudss.IndexBase.ZERO,
349
+ )
350
+ # Since we have taken a copy to offset crow_indices, we need to hold on to it.
351
+ references = [m, n, nnz, crow_indices_sequence, col_indices_sequence, values_sequence, crow_indices, col_indices, values]
352
+ return references, lhs_ptr
353
+
354
+
355
+ def create_cudss_csr_wrapper(
356
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, batch_indices, lhs, stream_holder
357
+ ):
358
+ if isinstance(lhs, Sequence):
359
+ return create_cudss_csr_explicit_batch(
360
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, lhs, stream_holder
361
+ )
362
+
363
+ if len(lhs.shape) > 2:
364
+ return create_cudss_csr_implicit_batch(
365
+ cuda_index_type, cuda_value_type, index_type, matrix_type, matrix_view_type, batch_indices, lhs, stream_holder
366
+ )
367
+
368
+ return create_cudss_csr_matrix(cuda_index_type, cuda_value_type, matrix_type, matrix_view_type, lhs)
369
+
370
+
371
+ def update_cudss_csr_matrix_ptr(lhs_ptr, new_lhs):
372
+ # The new lhs should be a wrapped (CSRTensorHolder object) matrix in a memory space
373
+ # consistent with the execution mode.
374
+ # lhs_ptr is a cuDSS CSR matrix ptr.
375
+ assert len(new_lhs.shape) == 2, "Internal error."
376
+ cudss.matrix_set_csr_pointers(
377
+ lhs_ptr, new_lhs.crow_indices.data_ptr, 0, new_lhs.col_indices.data_ptr, new_lhs.values.data_ptr
378
+ )
379
+ return []
380
+
381
+
382
+ def update_cudss_csr_explicit_batch_ptr(lhs_ptr, new_lhs, stream_holder, existing_ptrs):
383
+ # The new lhs should be a sequence of wrapped (CSRTensorHolder object) matrix in a
384
+ # memory space consistent with the execution mode.
385
+ assert isinstance(new_lhs, Sequence), "Internal error."
386
+
387
+ # Build host arrays of pointers for each batch element and copy into the
388
+ # existing device buffers.
389
+ host_crow = wrap_operand(np.array([o.crow_indices.data_ptr for o in new_lhs], dtype=np.uint64))
390
+ host_col = wrap_operand(np.array([o.col_indices.data_ptr for o in new_lhs], dtype=np.uint64))
391
+ host_val = wrap_operand(np.array([o.values.data_ptr for o in new_lhs], dtype=np.uint64))
392
+
393
+ existing_ptrs[0].copy_(host_crow, stream_holder=stream_holder)
394
+ existing_ptrs[1].copy_(host_col, stream_holder=stream_holder)
395
+ existing_ptrs[2].copy_(host_val, stream_holder=stream_holder)
396
+
397
+
398
+ def update_cudss_csr_implicit_batch_ptr(lhs_ptr, batch_indices, new_lhs, stream_holder, existing_ptrs):
399
+ # The new lhs should be a wrapped (CSRTensorHolder object) tensor 3D or greater
400
+ # dimension in a memory space consistent with the execution mode.
401
+ assert new_lhs.num_dimensions > 2, "Internal error."
402
+
403
+ # We can't use an elegant implementation like for the dense implicit batch, where we
404
+ # index the samples in the tensor to form an explicit sequence and forward to the dense
405
+ # explicit batch implementation. This is because we can't rely on having the native
406
+ # LHS tensor after copying across memory spaces.
407
+
408
+ # Explicitly unpack indices to avoid tensor[*b, ...] (support 3.10).
409
+ unpacked_indices = [tuple(b) + (...,) for b in batch_indices]
410
+
411
+ # Create a sequence of wrapped samples in the batch for each of the constituent dense
412
+ # arrays.
413
+ crow_indices_sequence = [new_lhs.crow_indices.__class__(new_lhs.crow_indices.tensor[u]) for u in unpacked_indices]
414
+ col_indices_sequence = [new_lhs.col_indices.__class__(new_lhs.col_indices.tensor[u]) for u in unpacked_indices]
415
+ values_sequence = [new_lhs.values.__class__(new_lhs.values.tensor[u]) for u in unpacked_indices]
416
+
417
+ # Build host arrays of pointers for each batch element
418
+ # and copy into the existing device buffers.
419
+ host_crow = wrap_operand(np.array([o.data_ptr for o in crow_indices_sequence], dtype=np.uint64))
420
+ host_col = wrap_operand(np.array([o.data_ptr for o in col_indices_sequence], dtype=np.uint64))
421
+ host_val = wrap_operand(np.array([o.data_ptr for o in values_sequence], dtype=np.uint64))
422
+
423
+ existing_ptrs[0].copy_(host_crow, stream_holder=stream_holder)
424
+ existing_ptrs[1].copy_(host_col, stream_holder=stream_holder)
425
+ existing_ptrs[2].copy_(host_val, stream_holder=stream_holder)
426
+
427
+
428
+ def update_cudss_csr_ptr_wrapper(*, existing_ptrs, lhs_ptr, batch_indices=None, new_lhs=None, stream_holder=None):
429
+ # A convenience function to forward to the right update implementation.
430
+ # For batched cases, existing_ptrs must be the list originally returned by the
431
+ # corresponding create function; pointer values are copied into the existing
432
+ # device buffers in place. For non-batched cases existing_ptrs is unused.
433
+ assert new_lhs is not None, "Internal error."
434
+
435
+ if isinstance(new_lhs, Sequence):
436
+ assert stream_holder is not None and existing_ptrs, "Internal error."
437
+ update_cudss_csr_explicit_batch_ptr(lhs_ptr, new_lhs, stream_holder, existing_ptrs)
438
+ return
439
+
440
+ if len(new_lhs.shape) > 2:
441
+ assert batch_indices is not None and stream_holder is not None and existing_ptrs, "Internal error."
442
+ update_cudss_csr_implicit_batch_ptr(lhs_ptr, batch_indices, new_lhs, stream_holder, existing_ptrs)
443
+ return
444
+
445
+ update_cudss_csr_matrix_ptr(lhs_ptr, new_lhs)