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,604 @@
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_cuda_mlir import cuda
9
+ from numba_cuda_mlir.compiler import declare_device
10
+ from numba_cuda_mlir.extending import lowering_registry, overload_attribute, overload_method, typing_registry
11
+ from numba_cuda_mlir.lowering_utilities.type_conversions import to_numba_type
12
+ from numba_cuda_mlir.numba_cuda import types
13
+ from numba_cuda_mlir.numba_cuda.cudadrv.linkable_code import LTOIR, Fatbin
14
+
15
+ from nvmath.device.common_cuda import get_default_code_type
16
+ from nvmath.device.cusolverdx import Solver, compile_solver_execute
17
+ from nvmath.device.cusolverdx_backend import get_universal_fatbin
18
+
19
+ from .common_numba_cuda_mlir import (
20
+ HostDescriptorBase,
21
+ get_array_pointer,
22
+ int_to_uint32_ptr,
23
+ passthrough,
24
+ register_dummy_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(HostDescriptorBase):
45
+ def __init__(self, solver: Solver) -> None:
46
+ super().__init__(solver, _SOLVER_DEFINITION_ARGS, "Solver")
47
+
48
+
49
+ register_dummy_type(SolverNumbaType, Solver, _SOLVER_DEFINITION_ARGS + _SOLVER_PROPS)
50
+
51
+
52
+ # ==========================
53
+ # Overloads: Type conversions
54
+ # ==========================
55
+
56
+
57
+ def _numba_solver_value_type_ptr(solver_type: SolverNumbaType) -> types.Type:
58
+ return types.CPointer(to_numba_type(solver_type.host_descriptor.value_type))
59
+
60
+
61
+ def _numba_solver_precision_type_ptr(solver_type: SolverNumbaType) -> types.Type:
62
+ return types.CPointer(to_numba_type(solver_type.host_descriptor.precision))
63
+
64
+
65
+ def _numba_solver_integer_value(solver_type: SolverNumbaType) -> types.Type:
66
+ return types.Integer
67
+
68
+
69
+ def _numba_solver_int32_ptr(solver_type: SolverNumbaType) -> types.Type:
70
+ return types.CPointer(types.int32)
71
+
72
+
73
+ _TO_IR_TYPE_MAP = {
74
+ _ArgType.value_type_ptr: _numba_solver_value_type_ptr,
75
+ _ArgType.precision_type_ptr: _numba_solver_precision_type_ptr,
76
+ _ArgType.integer_value: _numba_solver_integer_value,
77
+ _ArgType.int32_ptr: _numba_solver_int32_ptr,
78
+ }
79
+
80
+
81
+ def _convert_to_ir_type(arg_type: _ArgType, solver_type: SolverNumbaType) -> types.Type:
82
+ factory = _TO_IR_TYPE_MAP[arg_type]
83
+ return factory(solver_type)
84
+
85
+
86
+ # ==========================
87
+ # Overloads: Method Dispatch Implementation
88
+ # ==========================
89
+
90
+
91
+ def _validate_arg_type(user_type: types.Type, expected_type: types.Type) -> bool:
92
+ if expected_type == types.Integer:
93
+ return isinstance(user_type, types.Integer)
94
+
95
+ assert isinstance(expected_type, types.CPointer)
96
+ dtype, _ = expected_type.key
97
+
98
+ return isinstance(user_type, types.Array) and user_type.dtype == dtype
99
+
100
+
101
+ def _get_libmathdx_type(expected_type: types.Type) -> types.Type:
102
+ if expected_type == types.Integer:
103
+ return types.CPointer(types.uint32)
104
+ return expected_type
105
+
106
+
107
+ def _get_error_message_type(numba_type: types.Type) -> types.Type | str:
108
+ """Converts a type to its user-friendly representation for error messages."""
109
+ if numba_type == types.Integer:
110
+ return numba_type.__name__
111
+ return numba_type
112
+
113
+
114
+ def _check_all_none(args: list[types.Type]) -> bool:
115
+ """Checks if all elements are None"""
116
+ return all(unwanted_arg in {None, types.Omitted(None), types.none} for unwanted_arg in args)
117
+
118
+
119
+ def _validate_arg_types(solver_type: SolverNumbaType, arg_types: list[_Arg], args_fit: list[types.Type]) -> bool:
120
+ """Validates whether provided arguments match the expected types for a signature."""
121
+ return all(
122
+ _validate_arg_type(arg, _convert_to_ir_type(arg_spec.arg_type, solver_type))
123
+ for arg_spec, arg in zip(arg_types, args_fit, strict=True)
124
+ )
125
+
126
+
127
+ def _find_overload(args: list[types.Type], solver_type: SolverNumbaType) -> _Signature | None:
128
+ """
129
+ Iterates through all available signatures for the solver's function and finds
130
+ the first one where:
131
+ 1. The number of arguments matches (no extra arguments provided)
132
+ 2. All argument types are valid for the signature
133
+ """
134
+
135
+ signatures = _get_function_signatures(solver_type.host_descriptor.function)
136
+ assert signatures is not None
137
+
138
+ for sig in signatures:
139
+ expected_args_num = len(sig.args)
140
+
141
+ args_fit = args[:expected_args_num]
142
+ if not _check_all_none(args[expected_args_num:]):
143
+ continue
144
+
145
+ if not _validate_arg_types(solver_type, sig.args, args_fit):
146
+ continue
147
+
148
+ return sig
149
+
150
+ return None
151
+
152
+
153
+ def _compile_device_function(solver_type: SolverNumbaType, signature: _Signature) -> Callable:
154
+ code, symbol = compile_solver_execute(
155
+ solver_type.host_descriptor,
156
+ code_type=get_default_code_type(),
157
+ execution_api=signature.api,
158
+ )
159
+
160
+ fatbin = Fatbin(get_universal_fatbin().data)
161
+
162
+ numba_args = [_get_libmathdx_type(_convert_to_ir_type(arg_spec.arg_type, solver_type)) for arg_spec in signature.args]
163
+ sig = types.void(*numba_args)
164
+
165
+ return declare_device(symbol, sig, link=[LTOIR(code.data), fatbin], abi="c")
166
+
167
+
168
+ def _format_signature(solver_type: SolverNumbaType, sig: _Signature) -> str:
169
+ arg_list = ", ".join(
170
+ f"{arg_spec.name}: {_get_error_message_type(_convert_to_ir_type(arg_spec.arg_type, solver_type))}"
171
+ for arg_spec in sig.args
172
+ )
173
+ return f"({arg_list}) -> None"
174
+
175
+
176
+ def _raise_overload_resolution_error(solver_type: SolverNumbaType, args: list[types.Type]) -> NoReturn:
177
+ """Raises a detailed TypeError when no matching function signature is found."""
178
+ signatures = _get_function_signatures(solver_type.host_descriptor.function)
179
+ assert signatures is not None
180
+
181
+ available_sigs = ", ".join(_format_signature(solver_type, sig) for sig in signatures)
182
+ provided_args = [
183
+ types.CPointer(arg.dtype) if isinstance(arg, types.Array) else arg
184
+ for arg in args
185
+ if arg not in {None, types.Omitted(None), types.none}
186
+ ]
187
+ provided_sig = types.void(*provided_args)
188
+
189
+ raise TypeError(
190
+ 'Failed to find matching overload of "SOLVER.execute()" function.'
191
+ f" Provided signature: {provided_sig}, but only these are available: {available_sigs}"
192
+ )
193
+
194
+
195
+ @overload_method(SolverNumbaType, "execute", strict=False, inline="always", typing_registry=typing_registry)
196
+ def _overload_execute(solver_type: SolverNumbaType, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
197
+ if not isinstance(solver_type, SolverNumbaType):
198
+ return
199
+
200
+ args = [arg0, arg1, arg2, arg3, arg4, arg5]
201
+ overload = _find_overload(args, solver_type)
202
+
203
+ if overload is None:
204
+ _raise_overload_resolution_error(solver_type, args)
205
+
206
+ device_func = _compile_device_function(solver_type, overload)
207
+
208
+ def prepare_arg_intrinsic(arg):
209
+ if isinstance(arg, types.Integer):
210
+ return int_to_uint32_ptr
211
+ elif isinstance(arg, types.Array):
212
+ return get_array_pointer
213
+ else:
214
+ return passthrough
215
+
216
+ intrinsic0 = prepare_arg_intrinsic(arg0)
217
+ intrinsic1 = prepare_arg_intrinsic(arg1)
218
+ intrinsic2 = prepare_arg_intrinsic(arg2)
219
+ intrinsic3 = prepare_arg_intrinsic(arg3)
220
+ intrinsic4 = prepare_arg_intrinsic(arg4)
221
+ intrinsic5 = prepare_arg_intrinsic(arg5)
222
+
223
+ num_args = len(overload.args)
224
+
225
+ # TODO: no lowering for tuple slicing
226
+ if num_args == 2:
227
+
228
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
229
+ device_func(intrinsic0(arg0), intrinsic1(arg1))
230
+
231
+ elif num_args == 3:
232
+
233
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
234
+ device_func(intrinsic0(arg0), intrinsic1(arg1), intrinsic2(arg2))
235
+
236
+ elif num_args == 4:
237
+
238
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
239
+ device_func(intrinsic0(arg0), intrinsic1(arg1), intrinsic2(arg2), intrinsic3(arg3))
240
+
241
+ elif num_args == 5:
242
+
243
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
244
+ device_func(
245
+ intrinsic0(arg0),
246
+ intrinsic1(arg1),
247
+ intrinsic2(arg2),
248
+ intrinsic3(arg3),
249
+ intrinsic4(arg4),
250
+ )
251
+
252
+ elif num_args == 6:
253
+
254
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
255
+ device_func(
256
+ intrinsic0(arg0),
257
+ intrinsic1(arg1),
258
+ intrinsic2(arg2),
259
+ intrinsic3(arg3),
260
+ intrinsic4(arg4),
261
+ intrinsic5(arg5),
262
+ )
263
+
264
+ else:
265
+ raise AssertionError(f"unsupported cusolverdx execute arity: num_args={num_args}")
266
+
267
+ return execute_impl
268
+
269
+
270
+ # ==========================
271
+ # User API helpers
272
+ # ==========================
273
+
274
+
275
+ @cuda.jit(device=True, forceinline=True)
276
+ def _calculate_strides(shape: tuple[int, int], ld: int, is_col_major: bool) -> tuple[int, int, int]:
277
+ if is_col_major:
278
+ return (ld * shape[1], 1, ld)
279
+ return (ld * shape[0], ld, 1)
280
+
281
+
282
+ def _validate_ld_type(ld, name):
283
+ if ld not in {None, types.Omitted(None), types.none} and not isinstance(ld, types.Integer):
284
+ raise RuntimeError(f"{name} must be an Integer!")
285
+
286
+
287
+ def _ensure_no_positional_arguments(arg0, function):
288
+ if arg0 not in {None, types.Omitted(None), types.none}:
289
+ raise RuntimeError(f"Function {function} does not accept positional arguments")
290
+
291
+
292
+ # ==========================
293
+ # Stride and size device-method impls
294
+ # ==========================
295
+
296
+
297
+ class _MethodImpls(NamedTuple):
298
+ plain: Callable
299
+ with_ld: Callable
300
+ ld_kwarg_name: str
301
+
302
+
303
+ # TODO(numba-cuda-mlir) extremely long compilation times when using string comparison
304
+
305
+
306
+ def _a_strides_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
307
+ return _calculate_strides(
308
+ (solver.a_shape[1], solver.a_shape[2]),
309
+ solver.lda,
310
+ solver._a_is_col_major,
311
+ )
312
+
313
+
314
+ def _a_strides_impl_with_lda(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
315
+ return _calculate_strides(
316
+ (solver.a_shape[1], solver.a_shape[2]),
317
+ lda,
318
+ solver._a_is_col_major,
319
+ )
320
+
321
+
322
+ def _b_strides_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
323
+ return _calculate_strides(
324
+ (solver.b_shape[1], solver.b_shape[2]),
325
+ solver.ldb,
326
+ solver._b_is_col_major,
327
+ )
328
+
329
+
330
+ def _b_strides_impl_with_ldb(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,
334
+ solver._b_is_col_major,
335
+ )
336
+
337
+
338
+ def _c_strides_impl_plain(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
+ solver.ldb,
342
+ solver._b_is_col_major,
343
+ )
344
+
345
+
346
+ def _c_strides_impl_with_ldc(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
347
+ return _calculate_strides(
348
+ (solver.c_shape[1], solver.c_shape[2]),
349
+ ldc,
350
+ solver._b_is_col_major,
351
+ )
352
+
353
+
354
+ def _bx_strides_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
355
+ return _calculate_strides(
356
+ (max(solver.m, solver.n), solver.k),
357
+ solver.ldb,
358
+ solver._b_is_col_major,
359
+ )
360
+
361
+
362
+ def _bx_strides_impl_with_ldb(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
363
+ return _calculate_strides(
364
+ (max(solver.m, solver.n), solver.k),
365
+ ldb,
366
+ solver._b_is_col_major,
367
+ )
368
+
369
+
370
+ def _a_size_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
371
+ return solver.a_strides()[0] * solver.a_shape[0]
372
+
373
+
374
+ def _a_size_impl_with_lda(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
375
+ return solver.a_strides(lda=lda)[0] * solver.a_shape[0]
376
+
377
+
378
+ def _b_size_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
379
+ return solver.b_strides()[0] * solver.b_shape[0]
380
+
381
+
382
+ def _b_size_impl_with_ldb(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
383
+ return solver.b_strides(ldb=ldb)[0] * solver.b_shape[0]
384
+
385
+
386
+ def _c_size_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
387
+ return solver.c_strides()[0] * solver.c_shape[0]
388
+
389
+
390
+ def _c_size_impl_with_ldc(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
391
+ return solver.c_strides(ldc=ldc)[0] * solver.c_shape[0]
392
+
393
+
394
+ def _bx_size_impl_plain(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
395
+ return solver.bx_strides()[0] * solver.batches_per_block
396
+
397
+
398
+ def _bx_size_impl_with_ldb(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
399
+ return solver.bx_strides(ldb=ldb)[0] * solver.batches_per_block
400
+
401
+
402
+ # ==========================
403
+ # Execute() call-shape builders
404
+ # ==========================
405
+
406
+
407
+ def _impl_a0_a1(solver: Solver) -> Callable:
408
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
409
+ solver.execute(arg0, arg1)
410
+
411
+ return impl
412
+
413
+
414
+ def _impl_a0_a1_a2(solver: Solver) -> Callable:
415
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
416
+ solver.execute(arg0, arg1, arg2)
417
+
418
+ return impl
419
+
420
+
421
+ def _impl_a0_lda_a1(solver: Solver) -> Callable:
422
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
423
+ solver.execute(arg0, lda, arg1)
424
+
425
+ return impl
426
+
427
+
428
+ def _impl_a0_lda_a1_ldb(solver: Solver) -> Callable:
429
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
430
+ solver.execute(arg0, lda, arg1, ldb)
431
+
432
+ return impl
433
+
434
+
435
+ def _impl_a0_lda_a1_a2(solver: Solver) -> Callable:
436
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
437
+ solver.execute(arg0, lda, arg1, arg2)
438
+
439
+ return impl
440
+
441
+
442
+ def _impl_a0_lda_a1_a2_ldb(solver: Solver) -> Callable:
443
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
444
+ solver.execute(arg0, lda, arg1, arg2, ldb)
445
+
446
+ return impl
447
+
448
+
449
+ def _impl_a0_lda_a1_a2_ldc(solver: Solver) -> Callable:
450
+ def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
451
+ solver.execute(arg0, lda, arg1, arg2, ldc)
452
+
453
+ return impl
454
+
455
+
456
+ class _CallShape(NamedTuple):
457
+ plain: Callable # impl builder for the no-leading-dims path
458
+ lds: Callable # impl builder for the runtime-leading-dims path
459
+ requires_square: bool = False # solve operations: solver is None when the matrix isn't square
460
+
461
+
462
+ # ==========================
463
+ # Mappings
464
+ # ==========================
465
+
466
+ _DEVICE_METHODS_IMPL = {
467
+ _UserApiDeviceMethod.a_strides: _MethodImpls(plain=_a_strides_impl_plain,
468
+ with_ld=_a_strides_impl_with_lda, ld_kwarg_name="lda"),
469
+ _UserApiDeviceMethod.b_strides: _MethodImpls(plain=_b_strides_impl_plain,
470
+ with_ld=_b_strides_impl_with_ldb, ld_kwarg_name="ldb"),
471
+ _UserApiDeviceMethod.c_strides: _MethodImpls(plain=_c_strides_impl_plain,
472
+ with_ld=_c_strides_impl_with_ldc, ld_kwarg_name="ldc"),
473
+ _UserApiDeviceMethod.bx_strides: _MethodImpls(plain=_bx_strides_impl_plain,
474
+ with_ld=_bx_strides_impl_with_ldb, ld_kwarg_name="ldb"),
475
+ _UserApiDeviceMethod.a_size: _MethodImpls(plain=_a_size_impl_plain,
476
+ with_ld=_a_size_impl_with_lda, ld_kwarg_name="lda"),
477
+ _UserApiDeviceMethod.b_size: _MethodImpls(plain=_b_size_impl_plain,
478
+ with_ld=_b_size_impl_with_ldb, ld_kwarg_name="ldb"),
479
+ _UserApiDeviceMethod.c_size: _MethodImpls(plain=_c_size_impl_plain,
480
+ with_ld=_c_size_impl_with_ldc, ld_kwarg_name="ldc"),
481
+ _UserApiDeviceMethod.bx_size: _MethodImpls(plain=_bx_size_impl_plain,
482
+ with_ld=_bx_size_impl_with_ldb, ld_kwarg_name="ldb"),
483
+ } # fmt: skip
484
+ assert set(_DEVICE_METHODS_IMPL) == set(_UserApiDeviceMethod)
485
+
486
+ _CALL_SHAPES = {
487
+ _UserApiDispatchFactory.factorize_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1),
488
+ _UserApiDispatchFactory.solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb,
489
+ requires_square=True),
490
+ _UserApiDispatchFactory.triangular_solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb),
491
+ _UserApiDispatchFactory.factorize_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2),
492
+ _UserApiDispatchFactory.solve_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb,
493
+ requires_square=True),
494
+ _UserApiDispatchFactory.orthogonal_multiply_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldc),
495
+ _UserApiDispatchFactory.least_squares_solve_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb),
496
+ } # fmt: skip
497
+ assert set(_CALL_SHAPES) == set(_UserApiDispatchFactory)
498
+
499
+
500
+ # ==========================
501
+ # Dispatch overload registration
502
+ # ==========================
503
+
504
+
505
+ def _create_solver_dispatch_overload(numba_type, method, solver_attr, call_shape: _CallShape, expected_lds):
506
+ @overload_method(numba_type, method, strict=False, inline="always", typing_registry=typing_registry)
507
+ def overload_user_api_method(
508
+ user_api, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None
509
+ ):
510
+ assert isinstance(user_api, numba_type)
511
+
512
+ def expected_ensure_provided(ld, name, expected):
513
+ if expected == name and ld is None:
514
+ raise RuntimeError(f"{name} must be provided to use runtime leading dimensions")
515
+
516
+ _validate_ld_type(lda, "lda")
517
+ _validate_ld_type(ldb, "ldb")
518
+ _validate_ld_type(ldc, "ldc")
519
+
520
+ use_lds = (
521
+ lda not in {None, types.Omitted(None), types.none}
522
+ or ldb not in {None, types.Omitted(None), types.none}
523
+ or ldc not in {None, types.Omitted(None), types.none}
524
+ )
525
+ if use_lds:
526
+ for expected_ld in expected_lds:
527
+ expected_ensure_provided(lda, "lda", expected_ld)
528
+ expected_ensure_provided(ldb, "ldb", expected_ld)
529
+ expected_ensure_provided(ldc, "ldc", expected_ld)
530
+
531
+ solver = getattr(user_api.host_descriptor, solver_attr)
532
+ if call_shape.requires_square:
533
+ if solver is None:
534
+ raise RuntimeError(
535
+ "Device function: solve is not available with this configuration: "
536
+ "Operation is permitted only for square matrices"
537
+ )
538
+ assert solver.m == solver.n
539
+ else:
540
+ assert solver is not None
541
+ return (call_shape.lds if use_lds else call_shape.plain)(solver)
542
+
543
+ return overload_user_api_method
544
+
545
+
546
+ def _create_device_method_overload(numba_type, method: _UserApiDeviceMethod):
547
+ impls = _DEVICE_METHODS_IMPL[method]
548
+
549
+ @overload_method(numba_type, method.value, strict=False, inline="always", typing_registry=typing_registry)
550
+ def overload_user_api_method(user_api, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
551
+ assert isinstance(user_api, numba_type)
552
+
553
+ _ensure_no_positional_arguments(arg0, method.value)
554
+ _validate_ld_type(lda, "lda")
555
+ _validate_ld_type(ldb, "ldb")
556
+ _validate_ld_type(ldc, "ldc")
557
+
558
+ ld_value = {"lda": lda, "ldb": ldb, "ldc": ldc}[impls.ld_kwarg_name]
559
+ use_ld = ld_value not in {None, types.Omitted(None), types.none}
560
+
561
+ return impls.with_ld if use_ld else impls.plain
562
+
563
+ return overload_user_api_method
564
+
565
+
566
+ # TODO(numba-cuda-mlir) extremely long compilation times when using string comparison
567
+ def _overload_is_col_major(numba_type, attribute: str, arrangement_attr: str) -> None:
568
+ @overload_attribute(
569
+ numba_type, attribute, inline="always", typing_registry=typing_registry, lowering_registry=lowering_registry
570
+ )
571
+ def ol_is_col_major(user_api):
572
+ is_col_major = getattr(user_api.host_descriptor, arrangement_attr) == "col_major"
573
+ return lambda user_api: is_col_major
574
+
575
+
576
+ def _register_user_api_dispatch(user_api_spec: _UserApiSpec):
577
+ class UserApiNumbaType(HostDescriptorBase):
578
+ def __init__(self, solver) -> None:
579
+ super().__init__(solver, user_api_spec.definition_args, user_api_spec.user_api_class.__name__)
580
+
581
+ register_dummy_type(
582
+ UserApiNumbaType,
583
+ user_api_spec.user_api_class,
584
+ user_api_spec.definition_args + user_api_spec.helpers_prop,
585
+ )
586
+
587
+ _overload_is_col_major(UserApiNumbaType, "_a_is_col_major", "a_arrangement")
588
+ _overload_is_col_major(UserApiNumbaType, "_b_is_col_major", "b_arrangement")
589
+
590
+ for solver_dispath_method in user_api_spec.solver_dispath_methods:
591
+ _create_solver_dispatch_overload(
592
+ UserApiNumbaType,
593
+ solver_dispath_method.method,
594
+ solver_dispath_method.solver_attr,
595
+ _CALL_SHAPES[solver_dispath_method.factory],
596
+ solver_dispath_method.expected_lds,
597
+ )
598
+
599
+ for device_method in user_api_spec.device_methods:
600
+ _create_device_method_overload(UserApiNumbaType, device_method)
601
+
602
+
603
+ for user_api_spec in _USER_API_DISPATCH_SPECS:
604
+ _register_user_api_dispatch(user_api_spec)