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,567 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from collections.abc import Callable
6
+ from typing import NamedTuple, NoReturn
7
+
8
+ from numba import cuda
9
+ from numba.core import typing
10
+ from numba.extending import intrinsic, overload_method, types
11
+
12
+ from nvmath.device import (
13
+ Solver,
14
+ compile_solver_execute,
15
+ )
16
+ from nvmath.device.common_cuda import get_default_code_type
17
+ from nvmath.device.cusolverdx_backend import get_universal_fatbin
18
+
19
+ from .common_numba import (
20
+ NUMBA_FE_TYPES_TO_NUMBA_IR,
21
+ declare_cabi_device,
22
+ get_array_ptr,
23
+ get_uint32_value_ptr,
24
+ register_dummy_numba_type,
25
+ )
26
+ from .cusolverdx_overload_backend import (
27
+ _SOLVER_DEFINITION_ARGS,
28
+ _SOLVER_PROPS,
29
+ _USER_API_DISPATCH_SPECS,
30
+ _Arg,
31
+ _ArgType,
32
+ _get_function_signatures,
33
+ _Signature,
34
+ _UserApiDeviceMethod,
35
+ _UserApiDispatchFactory,
36
+ _UserApiSpec,
37
+ )
38
+
39
+ # ==========================
40
+ # Numba type
41
+ # ==========================
42
+
43
+
44
+ class SolverNumbaType(types.Type):
45
+ def __init__(self, solver: Solver) -> None:
46
+ self._solver = solver
47
+
48
+ attributes = [f"{attr}={getattr(solver, attr)}" for attr in _SOLVER_DEFINITION_ARGS if getattr(solver, attr)]
49
+ attributes.sort()
50
+ attr_str = ", ".join(attributes)
51
+
52
+ super().__init__(name=f"Solver({attr_str})")
53
+
54
+ @property
55
+ def solver(self) -> Solver:
56
+ return self._solver
57
+
58
+
59
+ register_dummy_numba_type(
60
+ SolverNumbaType,
61
+ Solver,
62
+ "solver",
63
+ _SOLVER_DEFINITION_ARGS + _SOLVER_PROPS,
64
+ )
65
+
66
+
67
+ # ==========================
68
+ # Intrinsics
69
+ # ==========================
70
+
71
+
72
+ @intrinsic
73
+ def _link_fatbin(typingctx: typing.Context):
74
+ sig = types.void()
75
+
76
+ fatbin = get_universal_fatbin()
77
+
78
+ def codegen(context, builder, sig, args):
79
+ context.active_code_library.add_linking_file(fatbin)
80
+
81
+ return sig, codegen
82
+
83
+
84
+ @intrinsic
85
+ def _do_nothing(typingctx: typing.Context, value: types.Type):
86
+ sig = value(value)
87
+
88
+ def codegen(context, builder, sig, args):
89
+ return args[0]
90
+
91
+ return sig, codegen
92
+
93
+
94
+ # ==========================
95
+ # Overloads: Type conversions
96
+ # ==========================
97
+
98
+
99
+ def _numba_solver_value_type_ptr(solver_type: SolverNumbaType) -> types.Type:
100
+ return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.value_type])
101
+
102
+
103
+ def _numba_solver_precision_type_ptr(solver_type: SolverNumbaType) -> types.Type:
104
+ return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.precision])
105
+
106
+
107
+ def _numba_solver_integer_value(solver_type: SolverNumbaType) -> types.Type:
108
+ return types.Integer
109
+
110
+
111
+ def _numba_solver_int32_ptr(solver_type: SolverNumbaType) -> types.Type:
112
+ return types.CPointer(types.int32)
113
+
114
+
115
+ def _convert_to_ir_type(arg_type: _ArgType, solver_type: SolverNumbaType) -> types.Type:
116
+ TO_IR_TYPE_MAP = {
117
+ _ArgType.value_type_ptr: _numba_solver_value_type_ptr,
118
+ _ArgType.precision_type_ptr: _numba_solver_precision_type_ptr,
119
+ _ArgType.integer_value: _numba_solver_integer_value,
120
+ _ArgType.int32_ptr: _numba_solver_int32_ptr,
121
+ }
122
+
123
+ factory = TO_IR_TYPE_MAP[arg_type]
124
+ return factory(solver_type)
125
+
126
+
127
+ # ==========================
128
+ # Overloads: Method Dispatch Implementation
129
+ # ==========================
130
+
131
+
132
+ def _validate_arg_type(user_type: types.Type, expected_type: types.Type) -> bool:
133
+ if expected_type == types.Integer:
134
+ return isinstance(user_type, types.Integer)
135
+
136
+ assert isinstance(expected_type, types.CPointer)
137
+ dtype, _ = expected_type.key
138
+
139
+ return isinstance(user_type, types.Array) and user_type.dtype == dtype
140
+
141
+
142
+ def _get_libmathdx_type(expected_type: types.Type) -> types.Type:
143
+ if expected_type == types.Integer:
144
+ return types.CPointer(types.uint32)
145
+ return expected_type
146
+
147
+
148
+ def _get_error_message_type(numba_type: types.Type) -> types.Type | str:
149
+ """
150
+ Converts a type to its user-friendly representation for error messages.
151
+ """
152
+ if numba_type == types.Integer:
153
+ return numba_type.__name__
154
+ return numba_type
155
+
156
+
157
+ def _check_all_none(args: list[types.Type]) -> bool:
158
+ """Checks if all elements are None"""
159
+ return all(unwanted_arg in {None, types.Omitted(None), types.none} for unwanted_arg in args)
160
+
161
+
162
+ def _validate_arg_types(solver_type: SolverNumbaType, arg_types: list[_Arg], args_fit: list[types.Type]) -> bool:
163
+ """Validates whether provided arguments match the expected types for a signature."""
164
+ return all(
165
+ _validate_arg_type(arg, _convert_to_ir_type(arg_spec.arg_type, solver_type))
166
+ for arg_spec, arg in zip(arg_types, args_fit, strict=True)
167
+ )
168
+
169
+
170
+ def _find_overload(args: list[types.Type], solver_type: SolverNumbaType) -> _Signature | None:
171
+ """
172
+ Iterates through all available signatures for the solver's function and finds
173
+ the first one where:
174
+ 1. The number of arguments matches (no extra arguments provided)
175
+ 2. All argument types are valid for the signature
176
+ """
177
+
178
+ signatures = _get_function_signatures(solver_type.solver.function)
179
+ assert signatures is not None
180
+
181
+ for sig in signatures:
182
+ expected_args_num = len(sig.args)
183
+
184
+ args_fit = args[:expected_args_num]
185
+ if not _check_all_none(args[expected_args_num:]):
186
+ continue
187
+
188
+ if not _validate_arg_types(solver_type, sig.args, args_fit):
189
+ continue
190
+
191
+ return sig
192
+
193
+ return None
194
+
195
+
196
+ def _compile_device_function(solver_type: SolverNumbaType, signature: _Signature) -> Callable:
197
+ """
198
+ Compile cusolverdx execute device function and wrap it into numba device function.
199
+ """
200
+
201
+ # Call libmathdx to jit the function
202
+ code, symbol = compile_solver_execute(
203
+ solver_type.solver,
204
+ code_type=get_default_code_type(),
205
+ execution_api=signature.api,
206
+ )
207
+ lto = cuda.LTOIR(code.data)
208
+
209
+ numba_args = [_get_libmathdx_type(_convert_to_ir_type(arg_spec.arg_type, solver_type)) for arg_spec in signature.args]
210
+ sig = types.void(*numba_args)
211
+
212
+ # Convert to cabi from numba abi
213
+ return declare_cabi_device(symbol, sig, link=lto)
214
+
215
+
216
+ def _format_signature(solver_type: SolverNumbaType, sig: _Signature) -> str:
217
+ arg_list = ", ".join(
218
+ f"{arg_spec.name}: {_get_error_message_type(_convert_to_ir_type(arg_spec.arg_type, solver_type))}"
219
+ for arg_spec in sig.args
220
+ )
221
+ return f"({arg_list}) -> None"
222
+
223
+
224
+ def _raise_overload_resolution_error(solver_type: SolverNumbaType, args: list[types.Type]) -> NoReturn:
225
+ """
226
+ Raises a detailed TypeError when no matching function signature is found.
227
+
228
+ Constructs an informative error message showing:
229
+ - The signature that was provided by the user
230
+ - All available signatures for the solver function
231
+ """
232
+ signatures = _get_function_signatures(solver_type.solver.function)
233
+ assert signatures is not None
234
+
235
+ available_sigs = ", ".join(_format_signature(solver_type, sig) for sig in signatures)
236
+ provided_args = [
237
+ types.CPointer(arg.dtype) if isinstance(arg, types.Array) else arg
238
+ for arg in args
239
+ if arg not in {None, types.Omitted(None), types.none}
240
+ ]
241
+ provided_sig = types.void(*provided_args)
242
+
243
+ raise TypeError(
244
+ 'Failed to find matching overload of "SOLVER.execute()" function.'
245
+ f" Provided signature: {provided_sig}, but only these are available: {available_sigs}"
246
+ )
247
+
248
+
249
+ @overload_method(SolverNumbaType, "execute", target="cuda", jit_options={"forceinline": True}, strict=False)
250
+ def _overload_execute(solver_type: SolverNumbaType, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
251
+ """Numba overload for Solver.execute(), resolves signature and compiles function."""
252
+ assert isinstance(solver_type, SolverNumbaType)
253
+
254
+ # Find matching signature for the provided arguments
255
+ args = [arg0, arg1, arg2, arg3, arg4, arg5]
256
+ overload = _find_overload(args, solver_type)
257
+
258
+ if overload is None:
259
+ _raise_overload_resolution_error(solver_type, args)
260
+
261
+ # Compile the device function for the matched signature
262
+ device_func = _compile_device_function(solver_type, overload)
263
+
264
+ # Generate the implementation wrapper
265
+ def prepare_arg_intrinsic(arg):
266
+ if isinstance(arg, types.Integer):
267
+ return get_uint32_value_ptr
268
+ elif isinstance(arg, types.Array):
269
+ return get_array_ptr
270
+ else:
271
+ return _do_nothing
272
+
273
+ intrinsic0 = prepare_arg_intrinsic(arg0)
274
+ intrinsic1 = prepare_arg_intrinsic(arg1)
275
+ intrinsic2 = prepare_arg_intrinsic(arg2)
276
+ intrinsic3 = prepare_arg_intrinsic(arg3)
277
+ intrinsic4 = prepare_arg_intrinsic(arg4)
278
+ intrinsic5 = prepare_arg_intrinsic(arg5)
279
+
280
+ num_args = len(overload.args)
281
+
282
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
283
+ _link_fatbin()
284
+ converted_args = (
285
+ intrinsic0(arg0),
286
+ intrinsic1(arg1),
287
+ intrinsic2(arg2),
288
+ intrinsic3(arg3),
289
+ intrinsic4(arg4),
290
+ intrinsic5(arg5),
291
+ )
292
+ device_func(*converted_args[:num_args])
293
+
294
+ return execute_impl
295
+
296
+
297
+ # ==========================
298
+ # User API helpers
299
+ # =========================
300
+
301
+
302
+ @cuda.jit(device=True, forceinline=True)
303
+ def _calculate_strides(shape: tuple[int, int], ld: int, is_col_major: bool) -> tuple[int, int, int]:
304
+ return (ld * shape[1], 1, ld) if is_col_major else (ld * shape[0], ld, 1)
305
+
306
+
307
+ def _validate_ld_type(ld, name):
308
+ if ld not in {None, types.Omitted(None), types.none} and not isinstance(ld, types.Integer):
309
+ raise RuntimeError(f"{name} must be an Integer!")
310
+
311
+
312
+ def _ensure_no_positional_arguments(arg0, function):
313
+ if arg0 not in {None, types.Omitted(None), types.none}:
314
+ raise RuntimeError(f"Function {function} does not accept positional arguments")
315
+
316
+
317
+ # ==========================
318
+ # Stride and size device-method impls
319
+ # ==========================
320
+
321
+
322
+ def _a_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
323
+ return _calculate_strides(
324
+ (solver.a_shape[1], solver.a_shape[2]),
325
+ lda if lda is not None else solver.lda,
326
+ solver.a_arrangement == "col_major",
327
+ )
328
+
329
+
330
+ def _b_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
331
+ return _calculate_strides(
332
+ (solver.b_shape[1], solver.b_shape[2]),
333
+ ldb if ldb is not None else solver.ldb,
334
+ solver.b_arrangement == "col_major",
335
+ )
336
+
337
+
338
+ def _c_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
339
+ return _calculate_strides(
340
+ (solver.c_shape[1], solver.c_shape[2]),
341
+ ldc if ldc is not None else solver.ldb,
342
+ solver.b_arrangement == "col_major",
343
+ )
344
+
345
+
346
+ def _bx_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
347
+ return _calculate_strides(
348
+ (max(solver.m, solver.n), solver.k),
349
+ ldb if ldb is not None else solver.ldb,
350
+ solver.b_arrangement == "col_major",
351
+ )
352
+
353
+
354
+ def _a_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
355
+ return solver.a_strides(lda=lda)[0] * solver.a_shape[0]
356
+
357
+
358
+ def _b_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
359
+ return solver.b_strides(ldb=ldb)[0] * solver.b_shape[0]
360
+
361
+
362
+ def _c_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
363
+ return solver.c_strides(ldc=ldc)[0] * solver.c_shape[0]
364
+
365
+
366
+ def _bx_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
367
+ return solver.bx_strides(ldb=ldb)[0] * solver.batches_per_block
368
+
369
+
370
+ # ==========================
371
+ # Execute() call-shape builders
372
+ # ==========================
373
+
374
+
375
+ def _impl_a0_a1(solver: Solver) -> Callable:
376
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
377
+ solver.execute(arg0, arg1)
378
+
379
+ return impl
380
+
381
+
382
+ def _impl_a0_a1_a2(solver: Solver) -> Callable:
383
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
384
+ solver.execute(arg0, arg1, arg2)
385
+
386
+ return impl
387
+
388
+
389
+ def _impl_a0_lda_a1(solver: Solver) -> Callable:
390
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
391
+ solver.execute(arg0, lda, arg1)
392
+
393
+ return impl
394
+
395
+
396
+ def _impl_a0_lda_a1_ldb(solver: Solver) -> Callable:
397
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
398
+ solver.execute(arg0, lda, arg1, ldb)
399
+
400
+ return impl
401
+
402
+
403
+ def _impl_a0_lda_a1_a2(solver: Solver) -> Callable:
404
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
405
+ solver.execute(arg0, lda, arg1, arg2)
406
+
407
+ return impl
408
+
409
+
410
+ def _impl_a0_lda_a1_a2_ldb(solver: Solver) -> Callable:
411
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
412
+ solver.execute(arg0, lda, arg1, arg2, ldb)
413
+
414
+ return impl
415
+
416
+
417
+ def _impl_a0_lda_a1_a2_ldc(solver: Solver) -> Callable:
418
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
419
+ solver.execute(arg0, lda, arg1, arg2, ldc)
420
+
421
+ return impl
422
+
423
+
424
+ class _CallShape(NamedTuple):
425
+ plain: Callable # impl builder for the no-leading-dims path
426
+ lds: Callable # impl builder for the runtime-leading-dims path
427
+ requires_square: bool = False # solve operations: solver is None when the matrix isn't square
428
+
429
+
430
+ # ==========================
431
+ # Mappings
432
+ # ==========================
433
+
434
+ _DEVICE_METHODS_IMPL = {
435
+ _UserApiDeviceMethod.a_strides: _a_strides_impl,
436
+ _UserApiDeviceMethod.b_strides: _b_strides_impl,
437
+ _UserApiDeviceMethod.c_strides: _c_strides_impl,
438
+ _UserApiDeviceMethod.bx_strides: _bx_strides_impl,
439
+ _UserApiDeviceMethod.a_size: _a_size_impl,
440
+ _UserApiDeviceMethod.b_size: _b_size_impl,
441
+ _UserApiDeviceMethod.c_size: _c_size_impl,
442
+ _UserApiDeviceMethod.bx_size: _bx_size_impl,
443
+ } # fmt: skip
444
+ assert set(_DEVICE_METHODS_IMPL) == set(_UserApiDeviceMethod)
445
+
446
+ _CALL_SHAPES = {
447
+ _UserApiDispatchFactory.factorize_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1),
448
+ _UserApiDispatchFactory.solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb,
449
+ requires_square=True),
450
+ _UserApiDispatchFactory.triangular_solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb),
451
+ _UserApiDispatchFactory.factorize_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2),
452
+ _UserApiDispatchFactory.solve_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb,
453
+ requires_square=True),
454
+ _UserApiDispatchFactory.orthogonal_multiply_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldc),
455
+ _UserApiDispatchFactory.least_squares_solve_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb),
456
+ } # fmt: skip
457
+ assert set(_CALL_SHAPES) == set(_UserApiDispatchFactory)
458
+
459
+
460
+ # ==========================
461
+ # Dispatch Methods Factories
462
+ # ==========================
463
+
464
+
465
+ def _create_solver_dispatch_overload(numba_type, method, solver_attr, call_shape: _CallShape, expected_lds):
466
+ @overload_method(numba_type, method, target="cuda", jit_options={"forceinline": True}, strict=False)
467
+ def overload_user_api_method(
468
+ user_api, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None
469
+ ):
470
+ assert isinstance(user_api, numba_type)
471
+
472
+ def expected_ensure_provided(ld, name, expected):
473
+ if expected == name and ld is None:
474
+ raise RuntimeError(f"{name} must be provided to use runtime leading dimensions")
475
+
476
+ _validate_ld_type(lda, "lda")
477
+ _validate_ld_type(ldb, "ldb")
478
+ _validate_ld_type(ldc, "ldc")
479
+
480
+ use_lds = (
481
+ lda not in {None, types.Omitted(None), types.none}
482
+ or ldb not in {None, types.Omitted(None), types.none}
483
+ or ldc not in {None, types.Omitted(None), types.none}
484
+ )
485
+ if use_lds:
486
+ for expected_ld in expected_lds:
487
+ expected_ensure_provided(lda, "lda", expected_ld)
488
+ expected_ensure_provided(ldb, "ldb", expected_ld)
489
+ expected_ensure_provided(ldc, "ldc", expected_ld)
490
+
491
+ solver = getattr(user_api.solver, solver_attr)
492
+ if call_shape.requires_square:
493
+ if solver is None:
494
+ raise RuntimeError(
495
+ "Device function: solve is not available with this configuration: "
496
+ "Operation is permitted only for square matrices"
497
+ )
498
+ assert solver.m == solver.n
499
+ else:
500
+ assert solver is not None
501
+ return (call_shape.lds if use_lds else call_shape.plain)(solver)
502
+
503
+ return overload_user_api_method
504
+
505
+
506
+ def _create_device_method_overload(numba_type, method: _UserApiDeviceMethod):
507
+ impl = _DEVICE_METHODS_IMPL[method]
508
+
509
+ @overload_method(numba_type, method.value, target="cuda", jit_options={"forceinline": True}, strict=False)
510
+ def overload_user_api_method(user_api, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
511
+ assert isinstance(user_api, numba_type)
512
+
513
+ _ensure_no_positional_arguments(arg0, method.value)
514
+ _validate_ld_type(lda, "lda")
515
+ _validate_ld_type(ldb, "ldb")
516
+ _validate_ld_type(ldc, "ldc")
517
+
518
+ return impl
519
+
520
+ return overload_user_api_method
521
+
522
+
523
+ def _register_user_api_dispatch(user_api_spec: _UserApiSpec):
524
+ """
525
+ Registers new numba type for a user API class and overloads the device methods.
526
+
527
+ Assumes the API object has hidden fields containing Solver objects.
528
+ Uses device_methods_attrs (which maps method names to solver fields)
529
+ to forward execution to the execute() method of the corresponding solver.
530
+ """
531
+
532
+ class UserApiNumbaType(types.Type):
533
+ def __init__(self, solver) -> None:
534
+ self._solver = solver
535
+
536
+ attributes = [f"{attr}={getattr(solver, attr)}" for attr in user_api_spec.definition_args if getattr(solver, attr)]
537
+ attributes.sort()
538
+ attr_str = ", ".join(attributes)
539
+
540
+ super().__init__(name=f"{user_api_spec.user_api_class.__name__}({attr_str})")
541
+
542
+ @property
543
+ def solver(self):
544
+ return self._solver
545
+
546
+ register_dummy_numba_type(
547
+ UserApiNumbaType,
548
+ user_api_spec.user_api_class,
549
+ "solver",
550
+ user_api_spec.definition_args + user_api_spec.helpers_prop,
551
+ )
552
+
553
+ for solver_dispath_method in user_api_spec.solver_dispath_methods:
554
+ _create_solver_dispatch_overload(
555
+ UserApiNumbaType,
556
+ solver_dispath_method.method,
557
+ solver_dispath_method.solver_attr,
558
+ _CALL_SHAPES[solver_dispath_method.factory],
559
+ solver_dispath_method.expected_lds,
560
+ )
561
+
562
+ for device_method in user_api_spec.device_methods:
563
+ _create_device_method_overload(UserApiNumbaType, device_method)
564
+
565
+
566
+ for user_api_spec in _USER_API_DISPATCH_SPECS:
567
+ _register_user_api_dispatch(user_api_spec)