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,8 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from ._configuration import DirectSolverOptions
6
+ from .solvermod import DirectSolver, InvalidDirectSolverState, direct_solver
7
+
8
+ __all__ = ["DirectSolver", "DirectSolverOptions", "InvalidDirectSolverState", "direct_solver"]
@@ -0,0 +1,66 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Cache for cuSOLVERMp lifecycle resources.
7
+
8
+ ``_HANDLES`` -- cuSOLVERMp library handles, keyed on ``device_id`` -- is
9
+ subject to the "one process per device" cuSOLVERMp model (single host thread
10
+ per device, so no locking or thread-local state is needed). The handle lazily
11
+ splits NCCL sub-communicators off the parent communicator on the first
12
+ ``cusolverMpGetrf`` / ``cusolverMpGetrs`` and caches them for its lifetime.
13
+ That one-time split is expensive, so reusing the handle amortizes the cost.
14
+
15
+ Cleanup is driven by ``nvmath.distributed.finalize()``, not by ``atexit``.
16
+ ``finalize()`` calls :func:`clear_handles` before tearing down the
17
+ ``nvmath.distributed`` runtime's NCCL communicator: :func:`clear_handles`
18
+ destroys each cuSOLVERMp handle, which in turn destroys the NCCL
19
+ sub-communicators that cuSOLVERMp split off from the runtime's parent
20
+ communicator. Those sub-communicators must be destroyed while the parent is
21
+ still alive, so this has to happen before ``finalize()`` tears the parent down.
22
+ """
23
+
24
+ __all__ = ["clear_handles", "get_handle"]
25
+
26
+ from nvmath.bindings import cusolverMp # type: ignore[attr-defined]
27
+ from nvmath.internal import utils
28
+
29
+ _HANDLES: dict[int, int] = {}
30
+
31
+
32
+ def get_handle(device_id: int, stream_ptr: int) -> int:
33
+ """
34
+ Return the cached cuSOLVERMp handle for ``device_id``, creating and
35
+ caching one if necessary.
36
+
37
+ ``stream_ptr`` is used only on first creation per device; subsequent
38
+ calls return the cached handle unchanged.
39
+
40
+ **This is not a collective call.** ``cusolverMpCreate`` only allocates
41
+ local resources (CUDA streams/events, child cuBLAS/cuSOLVERDn handles,
42
+ scratch buffers, an empty communicator cache); it never touches the NCCL
43
+ communicator, so ranks may create their handles independently.
44
+ """
45
+ handle = _HANDLES.get(device_id)
46
+ if handle is None:
47
+ with utils.device_ctx(device_id):
48
+ handle = cusolverMp.create(device_id, stream_ptr)
49
+ _HANDLES[device_id] = handle
50
+ return handle
51
+
52
+
53
+ def clear_handles() -> None:
54
+ """Destroy and forget all cached handles.
55
+
56
+ **This is a collective call.** ``cusolverMpDestroy`` tears down the NCCL
57
+ sub-communicators the handle split off and any cached cuBLASMp grids,
58
+ both of which are collective over the runtime communicator.
59
+ All ranks must therefore call this in lockstep, and it must happen
60
+ while that parent communicator is still alive, i.e.
61
+ before ``nvmath.distributed.finalize()`` tears it down.
62
+ """
63
+ for device_id, handle in _HANDLES.items():
64
+ with utils.device_ctx(device_id):
65
+ cusolverMp.destroy(handle)
66
+ _HANDLES.clear()
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = ["DirectSolverOptions"]
6
+
7
+ import dataclasses
8
+ import logging
9
+ from logging import Logger
10
+ from typing import Literal
11
+
12
+
13
+ @dataclasses.dataclass(frozen=True, slots=True, kw_only=True)
14
+ class DirectSolverOptions:
15
+ """A data class for providing options to
16
+ :func:`~nvmath.distributed.linalg.direct_solver` and
17
+ :class:`~nvmath.distributed.linalg.DirectSolver`.
18
+
19
+ Attributes:
20
+ logger: Python Logger object. The root logger will be used if a
21
+ logger object is not provided.
22
+
23
+ blocking: A flag specifying the behavior of the stream-ordered functions and
24
+ methods. When ``blocking`` is ``True``, the stream-ordered methods do not
25
+ return until the operation is complete. When ``blocking`` is ``"auto"``, the
26
+ methods may execute asynchronously when the inputs are on the GPU, depending
27
+ on the problem specification and runtime conditions. The stream-ordered methods
28
+ always block when the operands are on the CPU to ensure that the user doesn't
29
+ inadvertently use the result before it becomes available. The default is
30
+ ``"auto"``.
31
+
32
+ inplace_a: Whether the LU factorization overwrites the input left-hand side
33
+ matrix ``a`` with the LU factors. The default is ``True``.
34
+
35
+ .. experimental:: attribute
36
+
37
+ inplace_b: Whether the solve overwrites the input right-hand side ``b``
38
+ with the solution ``x``. The default is ``True``.
39
+
40
+ .. experimental:: attribute
41
+
42
+ handle: If ``None`` (the default), the required cuSOLVERMp library handle will be
43
+ created automatically for the computation. If users wish to manage the library
44
+ handle themselves, they may provide a cuSOLVERMp handle. The presence of a
45
+ handle must be consistent across processes: either every process provides its
46
+ own handle, or none do.
47
+
48
+ .. seealso::
49
+ :func:`~nvmath.distributed.linalg.direct_solver`,
50
+ :class:`~nvmath.distributed.linalg.DirectSolver`.
51
+ """
52
+
53
+ logger: Logger = dataclasses.field(default_factory=logging.getLogger)
54
+ blocking: Literal[True, "auto"] = "auto"
55
+ inplace_a: bool = True
56
+ inplace_b: bool = True
57
+ handle: int | None = None
58
+
59
+ def __post_init__(self):
60
+ if self.blocking not in (True, "auto"):
61
+ raise ValueError("The value specified for blocking must be either True or 'auto'.")
@@ -0,0 +1,172 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Persistent device state (pivot vector + info words) and the cross-rank
7
+ info reducer used by :meth:`DirectSolver.factorize`.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import TYPE_CHECKING, Final
13
+
14
+ import cuda.bindings.runtime as cbr
15
+ import numpy as np
16
+
17
+ from nvmath.internal.tensor_ifc_ndbuffer import NDBufferTensor
18
+ from nvmath.internal.tensor_ifc_numpy import NumpyTensor
19
+
20
+ if TYPE_CHECKING:
21
+ from cuda.core import Event
22
+
23
+ from nvmath.internal.package_ifc import StreamHolder
24
+
25
+
26
+ class _FactorizationState:
27
+ """Pivot vector and post-call info codes for cuSOLVERMp getrf/getrs."""
28
+
29
+ # info dtype, as documented by the cusolverMp getrf / getrs.
30
+ # Annotated as Final[str] so static checkers flag any reassignment.
31
+ _INFO_DTYPE: Final[str] = "int32"
32
+
33
+ __slots__ = (
34
+ "_alloc_stream",
35
+ "_info_getrf_d",
36
+ "_info_getrf_h",
37
+ "_info_getrs_d",
38
+ "_ipiv",
39
+ )
40
+
41
+ def __init__(
42
+ self,
43
+ *,
44
+ local_cols_a: int,
45
+ device_id: int,
46
+ stream_holder: StreamHolder,
47
+ ) -> None:
48
+ # Stream the device buffers are allocated on, used in free().
49
+ self._alloc_stream = stream_holder.obj
50
+
51
+ # ``ipiv`` is pure cuSOLVERMp scratch: getrf writes the pivot
52
+ # indices, getrs reads them, we never inspect the contents.
53
+ # ipiv has extent N (one entry per column of A, one per pivot step).
54
+ # Each entry's value is still a global row index (the row swapped
55
+ # to the leading position at that step). The dtype is int64.
56
+ # max(.., 1) is used for ranks that own zero columns.
57
+ #
58
+ self._ipiv = NDBufferTensor.empty(
59
+ (max(local_cols_a, 1),),
60
+ device_id=device_id,
61
+ dtype="int64",
62
+ stream_holder=stream_holder,
63
+ )
64
+
65
+ # ``_info_getrs_d`` is kept as a write-only target: cuSOLVERMp's
66
+ # getrs requires a non-NULL pointer for the info argument, but
67
+ # we never read the value back -- getrs has no info>0 case and
68
+ # info<0 would indicate an internal binding bug we cannot
69
+ # productively surface here.
70
+ self._info_getrs_d = NDBufferTensor.empty(
71
+ (1,),
72
+ device_id=device_id,
73
+ dtype=self._INFO_DTYPE,
74
+ stream_holder=stream_holder,
75
+ )
76
+
77
+ # Three-element buffer: element 0 holds the getrf info word and feeds
78
+ # the cross-rank info check, elements 1 and 2 receive its MAX and MIN
79
+ # reductions; see sync_and_check_factorize_info.
80
+ self._info_getrf_h = NumpyTensor.empty((3,), dtype=self._INFO_DTYPE)
81
+ self._info_getrf_d = self._info_getrf_h.to(device_id, stream_holder)
82
+
83
+ @property
84
+ def ipiv_device_ptr(self) -> int:
85
+ return self._ipiv.data_ptr
86
+
87
+ @property
88
+ def info_getrf_device_ptr(self) -> int:
89
+ # getrf's single int32 info word goes in element 0 of the shared buffer.
90
+ return self._info_getrf_d.data_ptr
91
+
92
+ @property
93
+ def info_getrs_device_ptr(self) -> int:
94
+ return self._info_getrs_d.data_ptr
95
+
96
+ def reset_info_getrs_device(self, stream_holder) -> None:
97
+ """Stream-ordered zero of ``_info_getrs_d``."""
98
+ (status,) = cbr.cudaMemsetAsync(self._info_getrs_d.data_ptr, 0, np.dtype(self._INFO_DTYPE).itemsize, stream_holder.ptr)
99
+ if status != cbr.cudaError_t.cudaSuccess:
100
+ raise RuntimeError(f"cudaMemsetAsync on info_getrs_d failed with status {status!r}")
101
+
102
+ def sync_and_check_factorize_info(self, stream_holder, *, nccl_comm) -> None:
103
+ """Sync the factorize stream, reduce the per-rank getrf ``info`` word
104
+ across ranks, and raise on failure.
105
+
106
+ getrf writes ``info`` on each rank (0 = success, >0 = singular
107
+ leading-minor order, <0 = illegal argument). Raises ``RuntimeError`` if
108
+ any rank is singular, or ``AssertionError`` if any rank reports an
109
+ illegal argument (a solver-internal bug). See the inline comments for
110
+ the MIN/MAX reduction and the raise ordering.
111
+ """
112
+ assert nccl_comm is not None # should have been enforced at solver init
113
+ multi_rank = nccl_comm.nranks > 1
114
+ info_ptr = self._info_getrf_d.data_ptr # getrf wrote the local info word here (element 0)
115
+ if multi_rank:
116
+ # Reduce the local info word (element 0) across ranks with both MIN
117
+ # and MAX: MAX alone would miss negatives (``max(-3, 0) == 0``) and
118
+ # MIN alone would miss positives, and we must catch both. The two
119
+ # allreduces are grouped into a single NCCL launch; NCCL gives no
120
+ # ordering between operations in a group, so we have MAX/MIN write
121
+ # distinct outputs. The group is enqueued on the factorize
122
+ # stream so it orders after getrf.
123
+ # nccl is imported lazily here because importing nccl.core eagerly
124
+ # imports the torch and cupy packages (its interop submodules run
125
+ # ``import torch`` / ``import cupy`` at load time), which we can avoid
126
+ # unless we actually need it.
127
+ from nccl.bindings import nccl as nccl_bindings # type: ignore
128
+ from nccl.core.typing import INT32, MAX, MIN # type: ignore
129
+
130
+ vmax_ptr = info_ptr + self._info_getrf_d.itemsize # element 1
131
+ vmin_ptr = info_ptr + 2 * self._info_getrf_d.itemsize # element 2
132
+ nccl_bindings.group_start()
133
+ nccl_bindings.all_reduce(info_ptr, vmax_ptr, 1, int(INT32), int(MAX), nccl_comm.ptr, stream_holder.ptr)
134
+ nccl_bindings.all_reduce(info_ptr, vmin_ptr, 1, int(INT32), int(MIN), nccl_comm.ptr, stream_holder.ptr)
135
+ nccl_bindings.group_end()
136
+
137
+ # copy_ is blocking here.
138
+ self._info_getrf_h.copy_(self._info_getrf_d, stream_holder)
139
+ # Element 0 holds the local info word (used directly when single-rank);
140
+ # for the multi-rank, element 1 holds max(info) and element 2 holds min(info).
141
+ if multi_rank:
142
+ vmax = self._info_getrf_h.tensor[1]
143
+ vmin = self._info_getrf_h.tensor[2]
144
+ else:
145
+ vmax = vmin = self._info_getrf_h.tensor[0]
146
+
147
+ # Raise based on the allreduced values so every rank raises together.
148
+ # Negative info means an illegal argument: getrf's args are
149
+ # solver-internal, so it's our bug. Check it before the singular case
150
+ # so an internal bug still surfaces when another rank also flags a
151
+ # singular minor, and via AssertionError to survive `python -O`.
152
+ if vmin < 0:
153
+ raise AssertionError(
154
+ f"Internal error: cuSOLVERMp getrf reported an illegal argument at position {-vmin} (info={vmin})."
155
+ )
156
+ if vmax > 0:
157
+ raise RuntimeError(f"DirectSolver factorization failed: matrix is singular (leading minor of order {vmax}).")
158
+
159
+ def free(self, last_compute_event: Event | None = None) -> None:
160
+ """Release the pivot vector and the host/device info buffers.
161
+
162
+ Device buffers free stream-ordered on their allocation stream when
163
+ dropped; waiting that stream on ``last_compute_event`` first orders
164
+ the free after any in-flight getrf/getrs (mirrors
165
+ :meth:`Workspace.release`).
166
+ """
167
+ if last_compute_event is not None and self._alloc_stream is not None:
168
+ self._alloc_stream.wait(last_compute_event)
169
+ self._info_getrf_h = None
170
+ self._ipiv = None
171
+ self._info_getrf_d = None
172
+ self._info_getrs_d = None