nvmath-python 0.9.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (309) hide show
  1. nvmath/__init__.pxd +0 -0
  2. nvmath/__init__.py +45 -0
  3. nvmath/_internal/__init__.py +0 -0
  4. nvmath/_internal/attribute_ifc_factory.py +330 -0
  5. nvmath/_internal/layout.py +70 -0
  6. nvmath/_internal/templates.py +383 -0
  7. nvmath/_utils.py +150 -0
  8. nvmath/bindings/__init__.py +51 -0
  9. nvmath/bindings/_internal/__init__.pxd +0 -0
  10. nvmath/bindings/_internal/__init__.py +0 -0
  11. nvmath/bindings/_internal/cublas.cp314-win_amd64.pyd +0 -0
  12. nvmath/bindings/_internal/cublas.pxd +530 -0
  13. nvmath/bindings/_internal/cublasLt.cp314-win_amd64.pyd +0 -0
  14. nvmath/bindings/_internal/cublasLt.pxd +59 -0
  15. nvmath/bindings/_internal/cublasMp.pxd +52 -0
  16. nvmath/bindings/_internal/cudss.cp314-win_amd64.pyd +0 -0
  17. nvmath/bindings/_internal/cudss.pxd +47 -0
  18. nvmath/bindings/_internal/cufft.cp314-win_amd64.pyd +0 -0
  19. nvmath/bindings/_internal/cufft.pxd +70 -0
  20. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  21. nvmath/bindings/_internal/curand.cp314-win_amd64.pyd +0 -0
  22. nvmath/bindings/_internal/curand.pxd +42 -0
  23. nvmath/bindings/_internal/cusolver.cp314-win_amd64.pyd +0 -0
  24. nvmath/bindings/_internal/cusolver.pxd +15 -0
  25. nvmath/bindings/_internal/cusolverDn.cp314-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/cusolverDn.pxd +406 -0
  27. nvmath/bindings/_internal/cusparse.cp314-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/cusparse.pxd +277 -0
  29. nvmath/bindings/_internal/cusparseLt.cp314-win_amd64.pyd +0 -0
  30. nvmath/bindings/_internal/cusparseLt.pxd +48 -0
  31. nvmath/bindings/_internal/cutensor.cp314-win_amd64.pyd +0 -0
  32. nvmath/bindings/_internal/cutensor.pxd +58 -0
  33. nvmath/bindings/_internal/mathdx.cp314-win_amd64.pyd +0 -0
  34. nvmath/bindings/_internal/mathdx.pxd +116 -0
  35. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  36. nvmath/bindings/_internal/utils.cp314-win_amd64.pyd +0 -0
  37. nvmath/bindings/_internal/utils.pxd +179 -0
  38. nvmath/bindings/_internal/utils.pyi +10 -0
  39. nvmath/bindings/cublas.cp314-win_amd64.pyd +0 -0
  40. nvmath/bindings/cublas.pxd +558 -0
  41. nvmath/bindings/cublas.pyi +746 -0
  42. nvmath/bindings/cublasLt.cp314-win_amd64.pyd +0 -0
  43. nvmath/bindings/cublasLt.pxd +109 -0
  44. nvmath/bindings/cublasLt.pyi +1337 -0
  45. nvmath/bindings/cublasMp.pxd +85 -0
  46. nvmath/bindings/cublasMp.pyi +219 -0
  47. nvmath/bindings/cudss.cp314-win_amd64.pyd +0 -0
  48. nvmath/bindings/cudss.pxd +86 -0
  49. nvmath/bindings/cudss.pyi +282 -0
  50. nvmath/bindings/cufft.cp314-win_amd64.pyd +0 -0
  51. nvmath/bindings/cufft.pxd +118 -0
  52. nvmath/bindings/cufft.pyi +241 -0
  53. nvmath/bindings/cufftMp.pxd +124 -0
  54. nvmath/bindings/cufftMp.pyi +260 -0
  55. nvmath/bindings/curand.cp314-win_amd64.pyd +0 -0
  56. nvmath/bindings/curand.pxd +71 -0
  57. nvmath/bindings/curand.pyi +159 -0
  58. nvmath/bindings/cusolver.cp314-win_amd64.pyd +0 -0
  59. nvmath/bindings/cusolver.pxd +62 -0
  60. nvmath/bindings/cusolver.pyi +242 -0
  61. nvmath/bindings/cusolverDn.cp314-win_amd64.pyd +0 -0
  62. nvmath/bindings/cusolverDn.pxd +430 -0
  63. nvmath/bindings/cusolverDn.pyi +416 -0
  64. nvmath/bindings/cusparse.cp314-win_amd64.pyd +0 -0
  65. nvmath/bindings/cusparse.pxd +338 -0
  66. nvmath/bindings/cusparse.pyi +659 -0
  67. nvmath/bindings/cusparseLt.cp314-win_amd64.pyd +0 -0
  68. nvmath/bindings/cusparseLt.pxd +99 -0
  69. nvmath/bindings/cusparseLt.pyi +198 -0
  70. nvmath/bindings/cutensor.cp314-win_amd64.pyd +0 -0
  71. nvmath/bindings/cutensor.pxd +98 -0
  72. nvmath/bindings/cutensor.pyi +294 -0
  73. nvmath/bindings/cycublas.cp314-win_amd64.pyd +0 -0
  74. nvmath/bindings/cycublas.pxd +684 -0
  75. nvmath/bindings/cycublasLt.cp314-win_amd64.pyd +0 -0
  76. nvmath/bindings/cycublasLt.pxd +1055 -0
  77. nvmath/bindings/cycublasMp.pxd +183 -0
  78. nvmath/bindings/cycudss.cp314-win_amd64.pyd +0 -0
  79. nvmath/bindings/cycudss.pxd +224 -0
  80. nvmath/bindings/cycufft.cp314-win_amd64.pyd +0 -0
  81. nvmath/bindings/cycufft.pxd +326 -0
  82. nvmath/bindings/cycufftMp.pxd +334 -0
  83. nvmath/bindings/cycurand.cp314-win_amd64.pyd +0 -0
  84. nvmath/bindings/cycurand.pxd +146 -0
  85. nvmath/bindings/cycusolver.cp314-win_amd64.pyd +0 -0
  86. nvmath/bindings/cycusolver.pxd +154 -0
  87. nvmath/bindings/cycusolverDn.cp314-win_amd64.pyd +0 -0
  88. nvmath/bindings/cycusolverDn.pxd +446 -0
  89. nvmath/bindings/cycusparse.cp314-win_amd64.pyd +0 -0
  90. nvmath/bindings/cycusparse.pxd +470 -0
  91. nvmath/bindings/cycusparseLt.cp314-win_amd64.pyd +0 -0
  92. nvmath/bindings/cycusparseLt.pxd +150 -0
  93. nvmath/bindings/cycutensor.cp314-win_amd64.pyd +0 -0
  94. nvmath/bindings/cycutensor.pxd +192 -0
  95. nvmath/bindings/cymathdx.cp314-win_amd64.pyd +0 -0
  96. nvmath/bindings/cymathdx.pxd +552 -0
  97. nvmath/bindings/cynvshmem.pxd +126 -0
  98. nvmath/bindings/mathdx.cp314-win_amd64.pyd +0 -0
  99. nvmath/bindings/mathdx.pxd +182 -0
  100. nvmath/bindings/mathdx.pyi +1244 -0
  101. nvmath/bindings/nvpl/__init__.pxd +0 -0
  102. nvmath/bindings/nvpl/__init__.py +13 -0
  103. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  104. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  105. nvmath/bindings/nvpl/_internal/blas.cp314-win_amd64.pyd +0 -0
  106. nvmath/bindings/nvpl/_internal/blas.pxd +125 -0
  107. nvmath/bindings/nvpl/_internal/fft.cp314-win_amd64.pyd +0 -0
  108. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  109. nvmath/bindings/nvpl/blas.cp314-win_amd64.pyd +0 -0
  110. nvmath/bindings/nvpl/blas.pxd +85 -0
  111. nvmath/bindings/nvpl/blas.pyi +122 -0
  112. nvmath/bindings/nvpl/cyblas.cp314-win_amd64.pyd +0 -0
  113. nvmath/bindings/nvpl/cyblas.pxd +166 -0
  114. nvmath/bindings/nvpl/cyfft.cp314-win_amd64.pyd +0 -0
  115. nvmath/bindings/nvpl/cyfft.pxd +92 -0
  116. nvmath/bindings/nvpl/fft.cp314-win_amd64.pyd +0 -0
  117. nvmath/bindings/nvpl/fft.pxd +100 -0
  118. nvmath/bindings/nvpl/fft.pyi +100 -0
  119. nvmath/bindings/nvshmem.pxd +54 -0
  120. nvmath/bindings/nvshmem.pyi +179 -0
  121. nvmath/device/__init__.py +21 -0
  122. nvmath/device/_deprecated.py +33 -0
  123. nvmath/device/common.py +313 -0
  124. nvmath/device/common_backend.py +131 -0
  125. nvmath/device/common_cuda.py +201 -0
  126. nvmath/device/common_numba.py +310 -0
  127. nvmath/device/common_opaque_tensor.py +201 -0
  128. nvmath/device/cublasdx.py +1805 -0
  129. nvmath/device/cublasdx_backend.py +807 -0
  130. nvmath/device/cublasdx_numba.py +1612 -0
  131. nvmath/device/cufftdx.py +510 -0
  132. nvmath/device/cufftdx_backend.py +196 -0
  133. nvmath/device/cufftdx_numba.py +196 -0
  134. nvmath/device/curand_kernel.py +9147 -0
  135. nvmath/device/cusolverdx.py +2690 -0
  136. nvmath/device/cusolverdx_backend.py +440 -0
  137. nvmath/device/cusolverdx_numba.py +1624 -0
  138. nvmath/device/llvm_array.py +29 -0
  139. nvmath/device/random.py +445 -0
  140. nvmath/device/random_helpers.py +23 -0
  141. nvmath/device/random_states.py +187 -0
  142. nvmath/device/types.py +147 -0
  143. nvmath/device/vector_types_numba.py +203 -0
  144. nvmath/distributed/__init__.py +205 -0
  145. nvmath/distributed/_internal/__init__.py +0 -0
  146. nvmath/distributed/_internal/nvshmem.py +302 -0
  147. nvmath/distributed/_internal/tensor_ifc.py +67 -0
  148. nvmath/distributed/_internal/tensor_ifc_cupy.py +62 -0
  149. nvmath/distributed/_internal/tensor_ifc_host_device.py +165 -0
  150. nvmath/distributed/_internal/tensor_ifc_numpy.py +41 -0
  151. nvmath/distributed/_internal/tensor_ifc_torch.py +141 -0
  152. nvmath/distributed/_internal/tensor_wrapper.py +78 -0
  153. nvmath/distributed/_utils.py +167 -0
  154. nvmath/distributed/distribution.py +770 -0
  155. nvmath/distributed/fft/__init__.py +7 -0
  156. nvmath/distributed/fft/_configuration.py +79 -0
  157. nvmath/distributed/fft/fft.py +2801 -0
  158. nvmath/distributed/linalg/__init__.py +12 -0
  159. nvmath/distributed/linalg/_internal/__init__.py +3 -0
  160. nvmath/distributed/linalg/_internal/epilog_protocol.py +496 -0
  161. nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
  162. nvmath/distributed/linalg/advanced/__init__.py +8 -0
  163. nvmath/distributed/linalg/advanced/_configuration.py +166 -0
  164. nvmath/distributed/linalg/advanced/matmulmod.py +2908 -0
  165. nvmath/distributed/process_group.py +408 -0
  166. nvmath/distributed/reshape/__init__.py +6 -0
  167. nvmath/distributed/reshape/_configuration.py +39 -0
  168. nvmath/distributed/reshape/reshape.py +1256 -0
  169. nvmath/fft/__init__.py +7 -0
  170. nvmath/fft/_configuration.py +208 -0
  171. nvmath/fft/_exec_utils.py +109 -0
  172. nvmath/fft/_helpers.py +237 -0
  173. nvmath/fft/fft.py +2903 -0
  174. nvmath/internal/__init__.pxd +3 -0
  175. nvmath/internal/__init__.py +10 -0
  176. nvmath/internal/_bindings.cp314-win_amd64.pyd +0 -0
  177. nvmath/internal/_bindings.pxd +12 -0
  178. nvmath/internal/_device_utils.py +54 -0
  179. nvmath/internal/enum_utils.py +142 -0
  180. nvmath/internal/formatters.py +87 -0
  181. nvmath/internal/mem_limit.py +51 -0
  182. nvmath/internal/memory.cp314-win_amd64.pyd +0 -0
  183. nvmath/internal/memory.pxd +10 -0
  184. nvmath/internal/memory.pyi +46 -0
  185. nvmath/internal/ndbuffer/__init__.pxd +3 -0
  186. nvmath/internal/ndbuffer/__init__.py +7 -0
  187. nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
  188. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
  189. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
  190. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
  191. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +240 -0
  192. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
  193. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
  194. nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
  195. nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
  196. nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
  197. nvmath/internal/ndbuffer/copy_kernel.cp314-win_amd64.pyd +0 -0
  198. nvmath/internal/ndbuffer/copy_kernel.pxd +9 -0
  199. nvmath/internal/ndbuffer/copy_kernel.pyi +9 -0
  200. nvmath/internal/ndbuffer/data_layout.cp314-win_amd64.pyd +0 -0
  201. nvmath/internal/ndbuffer/data_layout.pxd +72 -0
  202. nvmath/internal/ndbuffer/data_layout.pyi +23 -0
  203. nvmath/internal/ndbuffer/jit.cp314-win_amd64.pyd +0 -0
  204. nvmath/internal/ndbuffer/jit.pxd +7 -0
  205. nvmath/internal/ndbuffer/jit.pyi +6 -0
  206. nvmath/internal/ndbuffer/ndbuffer.cp314-win_amd64.pyd +0 -0
  207. nvmath/internal/ndbuffer/ndbuffer.pxd +36 -0
  208. nvmath/internal/ndbuffer/ndbuffer.pyi +41 -0
  209. nvmath/internal/ndbuffer/package_utils.cp314-win_amd64.pyd +0 -0
  210. nvmath/internal/ndbuffer/package_utils.pxd +11 -0
  211. nvmath/internal/ndbuffer/package_utils.pyi +12 -0
  212. nvmath/internal/package_ifc.py +147 -0
  213. nvmath/internal/package_ifc_cuda.py +49 -0
  214. nvmath/internal/package_ifc_cupy.py +49 -0
  215. nvmath/internal/package_ifc_torch.py +31 -0
  216. nvmath/internal/package_wrapper.py +14 -0
  217. nvmath/internal/tensor_ifc.py +194 -0
  218. nvmath/internal/tensor_ifc_cupy.py +241 -0
  219. nvmath/internal/tensor_ifc_ndbuffer.py +153 -0
  220. nvmath/internal/tensor_ifc_numpy.py +183 -0
  221. nvmath/internal/tensor_ifc_torch.py +176 -0
  222. nvmath/internal/tensor_wrapper.py +157 -0
  223. nvmath/internal/typemaps.py +162 -0
  224. nvmath/internal/utils.py +771 -0
  225. nvmath/linalg/__init__.py +46 -0
  226. nvmath/linalg/_internal/__init__.py +3 -0
  227. nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
  228. nvmath/linalg/_internal/algo_config_ifc.py +43 -0
  229. nvmath/linalg/_internal/batch.py +217 -0
  230. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  231. nvmath/linalg/_internal/epilog_protocol.py +766 -0
  232. nvmath/linalg/_internal/layout.py +624 -0
  233. nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
  234. nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
  235. nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
  236. nvmath/linalg/_internal/typemaps.py +144 -0
  237. nvmath/linalg/_internal/utils.py +134 -0
  238. nvmath/linalg/advanced/__init__.py +8 -0
  239. nvmath/linalg/advanced/_algorithmmod.py +149 -0
  240. nvmath/linalg/advanced/_configuration.py +349 -0
  241. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  242. nvmath/linalg/advanced/helpers/matmul.py +1348 -0
  243. nvmath/linalg/advanced/matmulmod.py +3937 -0
  244. nvmath/linalg/generic/__init__.py +43 -0
  245. nvmath/linalg/generic/_configuration/__init__.py +37 -0
  246. nvmath/linalg/generic/_configuration/layout.py +263 -0
  247. nvmath/linalg/generic/_configuration/match.py +609 -0
  248. nvmath/linalg/generic/_configuration/qualifiers.py +494 -0
  249. nvmath/linalg/generic/_configuration/wrap.py +217 -0
  250. nvmath/linalg/generic/_dtype.py +15 -0
  251. nvmath/linalg/generic/matmulmod.py +1060 -0
  252. nvmath/memory.py +282 -0
  253. nvmath/sparse/__init__.py +38 -0
  254. nvmath/sparse/_internal/__init__.py +21 -0
  255. nvmath/sparse/_internal/common_utils.py +144 -0
  256. nvmath/sparse/_internal/cudss_config_ifc.py +741 -0
  257. nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
  258. nvmath/sparse/_internal/cudss_utils.py +445 -0
  259. nvmath/sparse/_internal/cusparse_utils.py +382 -0
  260. nvmath/sparse/_internal/sparse_bsc_ifc.py +300 -0
  261. nvmath/sparse/_internal/sparse_bsr_ifc.py +303 -0
  262. nvmath/sparse/_internal/sparse_coo_ifc.py +254 -0
  263. nvmath/sparse/_internal/sparse_csc_ifc.py +266 -0
  264. nvmath/sparse/_internal/sparse_csr_ifc.py +266 -0
  265. nvmath/sparse/_internal/sparse_dia_ifc.py +239 -0
  266. nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
  267. nvmath/sparse/_internal/sparse_tensor_ifc.py +121 -0
  268. nvmath/sparse/_internal/sparse_ust_ifc.py +146 -0
  269. nvmath/sparse/_internal/utils.py +56 -0
  270. nvmath/sparse/advanced/__init__.py +7 -0
  271. nvmath/sparse/advanced/_configuration.py +230 -0
  272. nvmath/sparse/advanced/direct_solver.py +1884 -0
  273. nvmath/sparse/generic/__init__.py +7 -0
  274. nvmath/sparse/generic/_configuration.py +129 -0
  275. nvmath/sparse/generic/_helpers.py +137 -0
  276. nvmath/sparse/generic/_thunks.py +21 -0
  277. nvmath/sparse/generic/matmulmod.py +2426 -0
  278. nvmath/sparse/ust/__init__.py +7 -0
  279. nvmath/sparse/ust/_converters.py +378 -0
  280. nvmath/sparse/ust/_drawer.py +552 -0
  281. nvmath/sparse/ust/_emitter.py +553 -0
  282. nvmath/sparse/ust/_jit.py +212 -0
  283. nvmath/sparse/ust/_kernel.py +346 -0
  284. nvmath/sparse/ust/_semiring.py +71 -0
  285. nvmath/sparse/ust/_utils.py +102 -0
  286. nvmath/sparse/ust/interfaces/__init__.py +0 -0
  287. nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
  288. nvmath/sparse/ust/semiring_ops.py +71 -0
  289. nvmath/sparse/ust/tensor.py +1027 -0
  290. nvmath/sparse/ust/tensor_drawer.py +552 -0
  291. nvmath/sparse/ust/tensor_emitter.py +558 -0
  292. nvmath/sparse/ust/tensor_format.py +935 -0
  293. nvmath/sparse/ust/tensor_jit.py +212 -0
  294. nvmath/sparse/ust/tensor_kernel.py +348 -0
  295. nvmath/sparse/ust/tensor_utils.py +380 -0
  296. nvmath/tensor/__init__.py +6 -0
  297. nvmath/tensor/_configuration.py +95 -0
  298. nvmath/tensor/_internal/__init__.py +3 -0
  299. nvmath/tensor/_internal/cutensor_config_ifc.py +247 -0
  300. nvmath/tensor/_internal/cutensor_utils.py +162 -0
  301. nvmath/tensor/_internal/data.py +43 -0
  302. nvmath/tensor/_internal/einsum_parser.py +444 -0
  303. nvmath/tensor/_internal/typemaps.py +96 -0
  304. nvmath/tensor/contract.py +1861 -0
  305. nvmath_python-0.9.0.dist-info/METADATA +127 -0
  306. nvmath_python-0.9.0.dist-info/RECORD +309 -0
  307. nvmath_python-0.9.0.dist-info/WHEEL +5 -0
  308. nvmath_python-0.9.0.dist-info/licenses/LICENSE +177 -0
  309. nvmath_python-0.9.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,1624 @@
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 Literal, 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
+ CholeskySolver,
14
+ LeastSquaresSolver,
15
+ LQFactorize,
16
+ LQMultiply,
17
+ LUPivotSolver,
18
+ LUSolver,
19
+ QRFactorize,
20
+ QRMultiply,
21
+ Solver,
22
+ TriangularSolver,
23
+ compile_solver_execute,
24
+ )
25
+ from nvmath.device.common_cuda import get_default_code_type
26
+ from nvmath.device.cusolverdx_backend import _ENABLE_CUSOLVERDX_0_3, get_universal_fatbin
27
+
28
+ from .common_numba import (
29
+ NUMBA_FE_TYPES_TO_NUMBA_IR,
30
+ declare_cabi_device,
31
+ get_array_ptr,
32
+ get_uint32_value_ptr,
33
+ register_dummy_numba_type,
34
+ )
35
+
36
+ # ==========================
37
+ # Data: Solver Configuration
38
+ # ==========================
39
+
40
+ _SOLVER_DEFINITION_ARGS = [
41
+ "function",
42
+ "size",
43
+ "precision",
44
+ "execution",
45
+ "sm",
46
+ "arrangement",
47
+ "transpose_mode",
48
+ "side",
49
+ "diag",
50
+ "fill_mode",
51
+ "batches_per_block",
52
+ "data_type",
53
+ "leading_dimensions",
54
+ "block_dim",
55
+ ]
56
+
57
+ _SOLVER_PROPS = [
58
+ "value_type",
59
+ "m",
60
+ "n",
61
+ "k",
62
+ "a_arrangement",
63
+ "b_arrangement",
64
+ "lda",
65
+ "ldb",
66
+ "info_type",
67
+ "ipiv_type",
68
+ "tau_type",
69
+ "block_size",
70
+ ]
71
+
72
+ if _ENABLE_CUSOLVERDX_0_3:
73
+ _SOLVER_PROPS.append("workspace_size")
74
+ _SOLVER_DEFINITION_ARGS.append("job")
75
+
76
+ # ==========================
77
+ # Numba type
78
+ # ==========================
79
+
80
+
81
+ class SolverNumbaType(types.Type):
82
+ def __init__(self, solver: Solver) -> None:
83
+ self._solver = solver
84
+
85
+ attributes = [f"{attr}={getattr(solver, attr)}" for attr in _SOLVER_DEFINITION_ARGS if getattr(solver, attr)]
86
+ attributes.sort()
87
+ attr_str = ", ".join(attributes)
88
+
89
+ super().__init__(name=f"Solver({attr_str})")
90
+
91
+ @property
92
+ def solver(self) -> Solver:
93
+ return self._solver
94
+
95
+
96
+ register_dummy_numba_type(
97
+ SolverNumbaType,
98
+ Solver,
99
+ "solver",
100
+ _SOLVER_DEFINITION_ARGS + _SOLVER_PROPS,
101
+ )
102
+
103
+ # ==========================
104
+ # Dispatch Data Structures
105
+ # ==========================
106
+
107
+
108
+ class _Arg(NamedTuple):
109
+ arg_type: Callable[[SolverNumbaType], types.Type]
110
+ name: str
111
+
112
+
113
+ class _Signature(NamedTuple):
114
+ api: Literal["compiled_leading_dim"] | Literal["runtime_leading_dim"] # libmathdx API variant
115
+ args: list[_Arg] # List of expected arguments for the function
116
+
117
+
118
+ class _FunctionSignatures(NamedTuple):
119
+ function: str
120
+ signatures: list[_Signature]
121
+
122
+
123
+ def _numba_solver_value_type_ptr(solver_type: SolverNumbaType) -> types.Type:
124
+ return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.value_type])
125
+
126
+
127
+ def _numba_solver_precision_type_ptr(solver_type: SolverNumbaType) -> types.Type:
128
+ return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.precision])
129
+
130
+
131
+ def _numba_solver_integer_value(solver_type: SolverNumbaType) -> types.Type:
132
+ return types.Integer
133
+
134
+
135
+ def _numba_solver_int32_ptr(solver_type: SolverNumbaType) -> types.Type:
136
+ return types.CPointer(types.int32)
137
+
138
+
139
+ def _validate_arg_type(user_type: types.Type, expected_type: types.Type) -> bool:
140
+ if expected_type == types.Integer:
141
+ return isinstance(user_type, types.Integer)
142
+
143
+ assert isinstance(expected_type, types.CPointer)
144
+ dtype, _ = expected_type.key
145
+
146
+ return isinstance(user_type, types.Array) and user_type.dtype == dtype
147
+
148
+
149
+ def _get_libmathdx_type(expected_type: types.Type) -> types.Type:
150
+ if expected_type == types.Integer:
151
+ return types.CPointer(types.uint32)
152
+ return expected_type
153
+
154
+
155
+ def _get_error_message_type(numba_type: types.Type) -> types.Type | str:
156
+ """
157
+ Converts a type to its user-friendly representation for error messages.
158
+ """
159
+ if numba_type == types.Integer:
160
+ return numba_type.__name__
161
+ return numba_type
162
+
163
+
164
+ # ==========================
165
+ # Dispatch Data: Function Signatures Registry
166
+ # ==========================
167
+
168
+ """
169
+ _DISPATCH_DATA contains the dispatch information for different solver functions.
170
+ """
171
+ _DISPATCH_DATA = [
172
+ _FunctionSignatures(
173
+ function="potrs",
174
+ signatures=[
175
+ _Signature(
176
+ api="compiled_leading_dim",
177
+ args=[
178
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
179
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
180
+ ],
181
+ ),
182
+ _Signature(
183
+ api="runtime_leading_dim",
184
+ args=[
185
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
186
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
187
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
188
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
189
+ ],
190
+ ),
191
+ ],
192
+ ),
193
+ _FunctionSignatures(
194
+ function="getrs_no_pivot",
195
+ signatures=[
196
+ _Signature(
197
+ api="compiled_leading_dim",
198
+ args=[
199
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
200
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
201
+ ],
202
+ ),
203
+ _Signature(
204
+ api="runtime_leading_dim",
205
+ args=[
206
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
207
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
208
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
209
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
210
+ ],
211
+ ),
212
+ ],
213
+ ),
214
+ _FunctionSignatures(
215
+ function="gels",
216
+ signatures=[
217
+ _Signature(
218
+ api="compiled_leading_dim",
219
+ args=[
220
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
221
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
222
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
223
+ ],
224
+ ),
225
+ _Signature(
226
+ api="runtime_leading_dim",
227
+ args=[
228
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
229
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
230
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
231
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
232
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
233
+ ],
234
+ ),
235
+ ],
236
+ ),
237
+ _FunctionSignatures(
238
+ function="trsm",
239
+ signatures=[
240
+ _Signature(
241
+ api="compiled_leading_dim",
242
+ args=[
243
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
244
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
245
+ ],
246
+ ),
247
+ _Signature(
248
+ api="runtime_leading_dim",
249
+ args=[
250
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
251
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
252
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
253
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
254
+ ],
255
+ ),
256
+ ],
257
+ ),
258
+ _FunctionSignatures(
259
+ function="geqrf",
260
+ signatures=[
261
+ _Signature(
262
+ api="compiled_leading_dim",
263
+ args=[
264
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
265
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
266
+ ],
267
+ ),
268
+ _Signature(
269
+ api="runtime_leading_dim",
270
+ args=[
271
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
272
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
273
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
274
+ ],
275
+ ),
276
+ ],
277
+ ),
278
+ _FunctionSignatures(
279
+ function="gelqf",
280
+ signatures=[
281
+ _Signature(
282
+ api="compiled_leading_dim",
283
+ args=[
284
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
285
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
286
+ ],
287
+ ),
288
+ _Signature(
289
+ api="runtime_leading_dim",
290
+ args=[
291
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
292
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
293
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
294
+ ],
295
+ ),
296
+ ],
297
+ ),
298
+ _FunctionSignatures(
299
+ function="unmqr",
300
+ signatures=[
301
+ _Signature(
302
+ api="compiled_leading_dim",
303
+ args=[
304
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
305
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
306
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="c"),
307
+ ],
308
+ ),
309
+ _Signature(
310
+ api="runtime_leading_dim",
311
+ args=[
312
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
313
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
314
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
315
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="c"),
316
+ _Arg(arg_type=_numba_solver_integer_value, name="ldc"),
317
+ ],
318
+ ),
319
+ ],
320
+ ),
321
+ _FunctionSignatures(
322
+ function="unmlq",
323
+ signatures=[
324
+ _Signature(
325
+ api="compiled_leading_dim",
326
+ args=[
327
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
328
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
329
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="c"),
330
+ ],
331
+ ),
332
+ _Signature(
333
+ api="runtime_leading_dim",
334
+ args=[
335
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
336
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
337
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
338
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="c"),
339
+ _Arg(arg_type=_numba_solver_integer_value, name="ldc"),
340
+ ],
341
+ ),
342
+ ],
343
+ ),
344
+ _FunctionSignatures(
345
+ function="potrf",
346
+ signatures=[
347
+ _Signature(
348
+ api="compiled_leading_dim",
349
+ args=[
350
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
351
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
352
+ ],
353
+ ),
354
+ _Signature(
355
+ api="runtime_leading_dim",
356
+ args=[
357
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
358
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
359
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
360
+ ],
361
+ ),
362
+ ],
363
+ ),
364
+ _FunctionSignatures(
365
+ function="getrf_no_pivot",
366
+ signatures=[
367
+ _Signature(
368
+ api="compiled_leading_dim",
369
+ args=[
370
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
371
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
372
+ ],
373
+ ),
374
+ _Signature(
375
+ api="runtime_leading_dim",
376
+ args=[
377
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
378
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
379
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
380
+ ],
381
+ ),
382
+ ],
383
+ ),
384
+ _FunctionSignatures(
385
+ function="getrf_partial_pivot",
386
+ signatures=[
387
+ _Signature(
388
+ api="compiled_leading_dim",
389
+ args=[
390
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
391
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
392
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
393
+ ],
394
+ ),
395
+ _Signature(
396
+ api="runtime_leading_dim",
397
+ args=[
398
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
399
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
400
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
401
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
402
+ ],
403
+ ),
404
+ ],
405
+ ),
406
+ _FunctionSignatures(
407
+ function="getrs_partial_pivot",
408
+ signatures=[
409
+ _Signature(
410
+ api="compiled_leading_dim",
411
+ args=[
412
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
413
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
414
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
415
+ ],
416
+ ),
417
+ _Signature(
418
+ api="runtime_leading_dim",
419
+ args=[
420
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
421
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
422
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
423
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
424
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
425
+ ],
426
+ ),
427
+ ],
428
+ ),
429
+ _FunctionSignatures(
430
+ function="posv",
431
+ signatures=[
432
+ _Signature(
433
+ api="compiled_leading_dim",
434
+ args=[
435
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
436
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
437
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
438
+ ],
439
+ ),
440
+ _Signature(
441
+ api="runtime_leading_dim",
442
+ args=[
443
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
444
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
445
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
446
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
447
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
448
+ ],
449
+ ),
450
+ ],
451
+ ),
452
+ _FunctionSignatures(
453
+ function="gesv_no_pivot",
454
+ signatures=[
455
+ _Signature(
456
+ api="compiled_leading_dim",
457
+ args=[
458
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
459
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
460
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
461
+ ],
462
+ ),
463
+ _Signature(
464
+ api="runtime_leading_dim",
465
+ args=[
466
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
467
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
468
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
469
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
470
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
471
+ ],
472
+ ),
473
+ ],
474
+ ),
475
+ _FunctionSignatures(
476
+ function="gesv_partial_pivot",
477
+ signatures=[
478
+ _Signature(
479
+ api="compiled_leading_dim",
480
+ args=[
481
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
482
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
483
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
484
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
485
+ ],
486
+ ),
487
+ _Signature(
488
+ api="runtime_leading_dim",
489
+ args=[
490
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
491
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
492
+ _Arg(arg_type=_numba_solver_int32_ptr, name="ipiv"),
493
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
494
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
495
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
496
+ ],
497
+ ),
498
+ ],
499
+ ),
500
+ ]
501
+
502
+ _DISPATCH_DATA_CUSOLVERDX_0_3 = [
503
+ _FunctionSignatures(
504
+ function="gtsv_no_pivot",
505
+ signatures=[
506
+ _Signature(
507
+ api="compiled_leading_dim",
508
+ args=[
509
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="dl"),
510
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="d"),
511
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="du"),
512
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
513
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
514
+ ],
515
+ ),
516
+ _Signature(
517
+ api="runtime_leading_dim",
518
+ args=[
519
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="dl"),
520
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="d"),
521
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="du"),
522
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="b"),
523
+ _Arg(arg_type=_numba_solver_integer_value, name="ldb"),
524
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
525
+ ],
526
+ ),
527
+ ],
528
+ ),
529
+ _FunctionSignatures(
530
+ function="htev",
531
+ signatures=[
532
+ _Signature(
533
+ api="compiled_leading_dim",
534
+ args=[
535
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="d"),
536
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="e"),
537
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
538
+ ],
539
+ ),
540
+ _Signature(
541
+ api="compiled_leading_dim",
542
+ args=[
543
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="d"),
544
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="e"),
545
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="V"),
546
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
547
+ ],
548
+ ),
549
+ _Signature(
550
+ api="runtime_leading_dim",
551
+ args=[
552
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="d"),
553
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="e"),
554
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="V"),
555
+ _Arg(arg_type=_numba_solver_integer_value, name="ldv"),
556
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
557
+ ],
558
+ ),
559
+ ],
560
+ ),
561
+ _FunctionSignatures(
562
+ function="heev",
563
+ signatures=[
564
+ _Signature(
565
+ api="compiled_leading_dim",
566
+ args=[
567
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
568
+ _Arg(arg_type=_numba_solver_precision_type_ptr, name="lambda"),
569
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="workspace"),
570
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
571
+ ],
572
+ ),
573
+ _Signature(
574
+ api="runtime_leading_dim",
575
+ args=[
576
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
577
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
578
+ _Arg(arg_type=_numba_solver_precision_type_ptr, name="lambda"),
579
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="workspace"),
580
+ _Arg(arg_type=_numba_solver_int32_ptr, name="info"),
581
+ ],
582
+ ),
583
+ ],
584
+ ),
585
+ _FunctionSignatures(
586
+ function="ungqr",
587
+ signatures=[
588
+ _Signature(
589
+ api="compiled_leading_dim",
590
+ args=[
591
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
592
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
593
+ ],
594
+ ),
595
+ _Signature(
596
+ api="runtime_leading_dim",
597
+ args=[
598
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
599
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
600
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
601
+ ],
602
+ ),
603
+ ],
604
+ ),
605
+ _FunctionSignatures(
606
+ function="unglq",
607
+ signatures=[
608
+ _Signature(
609
+ api="compiled_leading_dim",
610
+ args=[
611
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
612
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
613
+ ],
614
+ ),
615
+ _Signature(
616
+ api="runtime_leading_dim",
617
+ args=[
618
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="a"),
619
+ _Arg(arg_type=_numba_solver_integer_value, name="lda"),
620
+ _Arg(arg_type=_numba_solver_value_type_ptr, name="tau"),
621
+ ],
622
+ ),
623
+ ],
624
+ ),
625
+ ]
626
+
627
+ if _ENABLE_CUSOLVERDX_0_3:
628
+ _DISPATCH_DATA += _DISPATCH_DATA_CUSOLVERDX_0_3
629
+
630
+ # ==========================
631
+ # Intrinsics
632
+ # ==========================
633
+
634
+
635
+ @intrinsic
636
+ def _link_fatbin(typingctx: typing.Context):
637
+ sig = types.void()
638
+
639
+ fatbin = get_universal_fatbin()
640
+
641
+ def codegen(context, builder, sig, args):
642
+ context.active_code_library.add_linking_file(fatbin)
643
+
644
+ return sig, codegen
645
+
646
+
647
+ @intrinsic
648
+ def _do_nothing(typingctx: typing.Context, value: types.Type):
649
+ sig = value(value)
650
+
651
+ def codegen(context, builder, sig, args):
652
+ return args[0]
653
+
654
+ return sig, codegen
655
+
656
+
657
+ # ==========================
658
+ # Overloads: Method Dispatch Implementation
659
+ # ==========================
660
+
661
+
662
+ def _get_function_signatures(function: str) -> list[_Signature] | None:
663
+ """Looks up and returns the list of available signatures for a given function."""
664
+ for func_signature in _DISPATCH_DATA:
665
+ if func_signature.function == function:
666
+ return func_signature.signatures
667
+
668
+ return None
669
+
670
+
671
+ def _check_all_none(args: list[types.Type]) -> bool:
672
+ """Checks if all elements are None"""
673
+ return all(unwanted_arg in {None, types.Omitted(None), types.none} for unwanted_arg in args)
674
+
675
+
676
+ def _validate_arg_types(solver_type: SolverNumbaType, arg_types: list[_Arg], args_fit: list[types.Type]) -> bool:
677
+ """Validates whether provided arguments match the expected types for a signature."""
678
+ return all(
679
+ _validate_arg_type(arg, arg_spec.arg_type(solver_type)) for arg_spec, arg in zip(arg_types, args_fit, strict=True)
680
+ )
681
+
682
+
683
+ def _find_overload(args: list[types.Type], solver_type: SolverNumbaType) -> _Signature | None:
684
+ """
685
+ Iterates through all available signatures for the solver's function and finds
686
+ the first one where:
687
+ 1. The number of arguments matches (no extra arguments provided)
688
+ 2. All argument types are valid for the signature
689
+ """
690
+
691
+ signatures = _get_function_signatures(solver_type.solver.function)
692
+ assert signatures is not None
693
+
694
+ for sig in signatures:
695
+ expected_args_num = len(sig.args)
696
+
697
+ args_fit = args[:expected_args_num]
698
+ if not _check_all_none(args[expected_args_num:]):
699
+ continue
700
+
701
+ if not _validate_arg_types(solver_type, sig.args, args_fit):
702
+ continue
703
+
704
+ return sig
705
+
706
+ return None
707
+
708
+
709
+ def _compile_device_function(solver_type: SolverNumbaType, signature: _Signature) -> Callable:
710
+ """
711
+ Compile cusolverdx execute device function and wrap it into numba device function.
712
+ """
713
+
714
+ # Call libmathdx to jit the function
715
+ code, symbol = compile_solver_execute(
716
+ solver_type.solver,
717
+ code_type=get_default_code_type(),
718
+ execution_api=signature.api,
719
+ )
720
+ lto = cuda.LTOIR(code.data)
721
+
722
+ numba_args = [_get_libmathdx_type(arg_spec.arg_type(solver_type)) for arg_spec in signature.args]
723
+ sig = types.void(*numba_args)
724
+
725
+ # Convert to cabi from numba abi
726
+ return declare_cabi_device(symbol, sig, link=lto)
727
+
728
+
729
+ def _format_signature(solver_type: SolverNumbaType, sig: _Signature) -> str:
730
+ arg_list = ", ".join(f"{arg_spec.name}: {_get_error_message_type(arg_spec.arg_type(solver_type))}" for arg_spec in sig.args)
731
+ return f"({arg_list}) -> None"
732
+
733
+
734
+ def _raise_overload_resolution_error(solver_type: SolverNumbaType, args: list[types.Type]) -> NoReturn:
735
+ """
736
+ Raises a detailed TypeError when no matching function signature is found.
737
+
738
+ Constructs an informative error message showing:
739
+ - The signature that was provided by the user
740
+ - All available signatures for the solver function
741
+ """
742
+ signatures = _get_function_signatures(solver_type.solver.function)
743
+ assert signatures is not None
744
+
745
+ available_sigs = ", ".join(_format_signature(solver_type, sig) for sig in signatures)
746
+ provided_args = [
747
+ types.CPointer(arg.dtype) if isinstance(arg, types.Array) else arg
748
+ for arg in args
749
+ if arg not in {None, types.Omitted(None), types.none}
750
+ ]
751
+ provided_sig = types.void(*provided_args)
752
+
753
+ raise TypeError(
754
+ 'Failed to find matching overload of "SOLVER.execute()" function.'
755
+ f" Provided signature: {provided_sig}, but only these are available: {available_sigs}"
756
+ )
757
+
758
+
759
+ @overload_method(SolverNumbaType, "execute", target="cuda", jit_options={"forceinline": True}, strict=False)
760
+ def _overload_execute(solver_type: SolverNumbaType, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
761
+ """Numba overload for Solver.execute(), resolves signature and compiles function."""
762
+ assert isinstance(solver_type, SolverNumbaType)
763
+
764
+ # Find matching signature for the provided arguments
765
+ args = [arg0, arg1, arg2, arg3, arg4, arg5]
766
+ overload = _find_overload(args, solver_type)
767
+
768
+ if overload is None:
769
+ _raise_overload_resolution_error(solver_type, args)
770
+
771
+ # Compile the device function for the matched signature
772
+ device_func = _compile_device_function(solver_type, overload)
773
+
774
+ # Generate the implementation wrapper
775
+ def prepare_arg_intrinsic(arg):
776
+ if isinstance(arg, types.Integer):
777
+ return get_uint32_value_ptr
778
+ elif isinstance(arg, types.Array):
779
+ return get_array_ptr
780
+ else:
781
+ return _do_nothing
782
+
783
+ intrinsic0 = prepare_arg_intrinsic(arg0)
784
+ intrinsic1 = prepare_arg_intrinsic(arg1)
785
+ intrinsic2 = prepare_arg_intrinsic(arg2)
786
+ intrinsic3 = prepare_arg_intrinsic(arg3)
787
+ intrinsic4 = prepare_arg_intrinsic(arg4)
788
+ intrinsic5 = prepare_arg_intrinsic(arg5)
789
+
790
+ num_args = len(overload.args)
791
+
792
+ def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
793
+ _link_fatbin()
794
+ converted_args = (
795
+ intrinsic0(arg0),
796
+ intrinsic1(arg1),
797
+ intrinsic2(arg2),
798
+ intrinsic3(arg3),
799
+ intrinsic4(arg4),
800
+ intrinsic5(arg5),
801
+ )
802
+ device_func(*converted_args[:num_args])
803
+
804
+ return execute_impl
805
+
806
+
807
+ # ==========================
808
+ # User API dispatch
809
+ # =========================
810
+
811
+
812
+ @cuda.jit(device=True, forceinline=True)
813
+ def _calculate_strides(shape: tuple[int, int], ld: int, is_col_major: bool) -> tuple[int, int, int]:
814
+ return (ld * shape[1], 1, ld) if is_col_major else (ld * shape[0], ld, 1)
815
+
816
+
817
+ class _UserApiSolverDispatch(NamedTuple):
818
+ method: str # name of the method to overload
819
+ solver_attr: str # name of the solver attribute to forward execution to
820
+ factory: Callable # factory function to create the overload
821
+ expected_lds: list[Literal["lda", "ldb", "ldc"]] # list of expected leading dimensions
822
+
823
+
824
+ class _UserApiDeviceMethod(NamedTuple):
825
+ method: str # name of the method to overload
826
+ factory: Callable # factory function to create the overload
827
+
828
+
829
+ def _validate_ld_type(ld, name):
830
+ if ld not in {None, types.Omitted(None), types.none} and not isinstance(ld, types.Integer):
831
+ raise RuntimeError(f"{name} must be an Integer!")
832
+
833
+
834
+ def _create_solver_dispatch_overload(numba_type, method, solver_attr, factory, expected_lds):
835
+ @overload_method(numba_type, method, target="cuda", jit_options={"forceinline": True}, strict=False)
836
+ def overload_user_api_method(
837
+ user_api, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None
838
+ ):
839
+ assert isinstance(user_api, numba_type)
840
+
841
+ def expected_ensure_provided(ld, name, expected):
842
+ if expected == name and ld is None:
843
+ raise RuntimeError(f"{name} must be provided to use runtime leading dimensions")
844
+
845
+ _validate_ld_type(lda, "lda")
846
+ _validate_ld_type(ldb, "ldb")
847
+ _validate_ld_type(ldc, "ldc")
848
+
849
+ use_lds = (
850
+ lda not in {None, types.Omitted(None), types.none}
851
+ or ldb not in {None, types.Omitted(None), types.none}
852
+ or ldc not in {None, types.Omitted(None), types.none}
853
+ )
854
+ if use_lds:
855
+ for expected_ld in expected_lds:
856
+ expected_ensure_provided(lda, "lda", expected_ld)
857
+ expected_ensure_provided(ldb, "ldb", expected_ld)
858
+ expected_ensure_provided(ldc, "ldc", expected_ld)
859
+
860
+ solver = getattr(user_api.solver, solver_attr)
861
+ return factory(solver, use_lds)
862
+
863
+ return overload_user_api_method
864
+
865
+
866
+ def _create_device_method_overload(numba_type, method, factory):
867
+ @overload_method(numba_type, method, target="cuda", jit_options={"forceinline": True}, strict=False)
868
+ def overload_user_api_method(user_api, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
869
+ assert isinstance(user_api, numba_type)
870
+
871
+ _validate_ld_type(lda, "lda")
872
+ _validate_ld_type(ldb, "ldb")
873
+ _validate_ld_type(ldc, "ldc")
874
+
875
+ return factory(user_api, arg0, arg1, arg2, lda, ldb, ldc)
876
+
877
+ return overload_user_api_method
878
+
879
+
880
+ def _ensure_no_positional_arguments(arg0, function):
881
+ if arg0 not in {None, types.Omitted(None), types.none}:
882
+ raise RuntimeError(f"Function {function} does not accept positional arguments")
883
+
884
+
885
+ def _register_user_api_dispatch(
886
+ user_api_class: type,
887
+ definition_args: list[str],
888
+ helpers_prop: list[str],
889
+ solver_dispath_methods: list[_UserApiSolverDispatch],
890
+ device_methods: list[_UserApiDeviceMethod],
891
+ ):
892
+ """
893
+ Registers new numba type for a user API class and overloads the device methods.
894
+
895
+ Assumes the API object has hidden fields containing Solver objects.
896
+ Uses device_methods_attrs (which maps method names to solver fields)
897
+ to forward execution to the execute() method of the corresponding solver.
898
+ """
899
+
900
+ class UserApiNumbaType(types.Type):
901
+ def __init__(self, solver) -> None:
902
+ self._solver = solver
903
+
904
+ attributes = [f"{attr}={getattr(solver, attr)}" for attr in definition_args if getattr(solver, attr)]
905
+ attributes.sort()
906
+ attr_str = ", ".join(attributes)
907
+
908
+ super().__init__(name=f"{user_api_class.__name__}({attr_str})")
909
+
910
+ @property
911
+ def solver(self):
912
+ return self._solver
913
+
914
+ register_dummy_numba_type(UserApiNumbaType, user_api_class, "solver", definition_args + helpers_prop)
915
+
916
+ for solver_dispath_method in solver_dispath_methods:
917
+ _create_solver_dispatch_overload(
918
+ UserApiNumbaType,
919
+ solver_dispath_method.method,
920
+ solver_dispath_method.solver_attr,
921
+ solver_dispath_method.factory,
922
+ solver_dispath_method.expected_lds,
923
+ )
924
+
925
+ for device_method in device_methods:
926
+ _create_device_method_overload(UserApiNumbaType, device_method.method, device_method.factory)
927
+
928
+
929
+ # ==========================
930
+ # Stride factories
931
+ # ==========================
932
+
933
+
934
+ def _a_strides_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
935
+ _ensure_no_positional_arguments(arg0, "a_strides")
936
+
937
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
938
+ return _calculate_strides(
939
+ (solver.a_shape[1], solver.a_shape[2]), lda if lda is not None else solver.lda, solver.a_arrangement == "col_major"
940
+ )
941
+
942
+ return impl
943
+
944
+
945
+ _A_STRIDES_DEVICE_METHOD = _UserApiDeviceMethod(
946
+ method="a_strides",
947
+ factory=_a_strides_factory,
948
+ )
949
+
950
+
951
+ def _b_strides_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
952
+ _ensure_no_positional_arguments(arg0, "b_strides")
953
+
954
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
955
+ return _calculate_strides(
956
+ (solver.b_shape[1], solver.b_shape[2]), ldb if ldb is not None else solver.ldb, solver.b_arrangement == "col_major"
957
+ )
958
+
959
+ return impl
960
+
961
+
962
+ _B_STRIDES_DEVICE_METHOD = _UserApiDeviceMethod(
963
+ method="b_strides",
964
+ factory=_b_strides_factory,
965
+ )
966
+
967
+
968
+ def _c_strides_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
969
+ _ensure_no_positional_arguments(arg0, "c_strides")
970
+
971
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
972
+ return _calculate_strides(
973
+ (solver.c_shape[1], solver.c_shape[2]), ldc if ldc is not None else solver.ldb, solver.b_arrangement == "col_major"
974
+ )
975
+
976
+ return impl
977
+
978
+
979
+ _C_STRIDES_DEVICE_METHOD = _UserApiDeviceMethod(
980
+ method="c_strides",
981
+ factory=_c_strides_factory,
982
+ )
983
+
984
+
985
+ def _bx_strides_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
986
+ _ensure_no_positional_arguments(arg0, "bx_strides")
987
+
988
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
989
+ return _calculate_strides(
990
+ (max(solver.m, solver.n), solver.k), ldb if ldb is not None else solver.ldb, solver.b_arrangement == "col_major"
991
+ )
992
+
993
+ return impl
994
+
995
+
996
+ _BX_STRIDES_DEVICE_METHOD = _UserApiDeviceMethod(
997
+ method="bx_strides",
998
+ factory=_bx_strides_factory,
999
+ )
1000
+
1001
+
1002
+ # ==========================
1003
+ # Size (element count) factories
1004
+ # ==========================
1005
+
1006
+
1007
+ def _bx_size_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
1008
+ _ensure_no_positional_arguments(arg0, "bx_size")
1009
+
1010
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
1011
+ return solver.bx_strides(ldb=ldb)[0] * solver.batches_per_block
1012
+
1013
+ return impl
1014
+
1015
+
1016
+ _BX_SIZE_DEVICE_METHOD = _UserApiDeviceMethod(
1017
+ method="bx_size",
1018
+ factory=_bx_size_factory,
1019
+ )
1020
+
1021
+
1022
+ def _a_size_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
1023
+ _ensure_no_positional_arguments(arg0, "a_size")
1024
+
1025
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
1026
+ return solver.a_strides(lda=lda)[0] * solver.a_shape[0]
1027
+
1028
+ return impl
1029
+
1030
+
1031
+ _A_SIZE_DEVICE_METHOD = _UserApiDeviceMethod(
1032
+ method="a_size",
1033
+ factory=_a_size_factory,
1034
+ )
1035
+
1036
+
1037
+ def _b_size_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
1038
+ _ensure_no_positional_arguments(arg0, "b_size")
1039
+
1040
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
1041
+ return solver.b_strides(ldb=ldb)[0] * solver.b_shape[0]
1042
+
1043
+ return impl
1044
+
1045
+
1046
+ _B_SIZE_DEVICE_METHOD = _UserApiDeviceMethod(
1047
+ method="b_size",
1048
+ factory=_b_size_factory,
1049
+ )
1050
+
1051
+
1052
+ def _c_size_factory(user_api, arg0, arg1, arg2, lda, ldb, ldc) -> Callable:
1053
+ _ensure_no_positional_arguments(arg0, "c_size")
1054
+
1055
+ def impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
1056
+ return solver.c_strides(ldc=ldc)[0] * solver.c_shape[0]
1057
+
1058
+ return impl
1059
+
1060
+
1061
+ _C_SIZE_DEVICE_METHOD = _UserApiDeviceMethod(
1062
+ method="c_size",
1063
+ factory=_c_size_factory,
1064
+ )
1065
+
1066
+
1067
+ # ==========================
1068
+ # Cholesky Solver dispatch
1069
+ # ==========================
1070
+
1071
+
1072
+ def _factorize_factory(solver: Solver | None, use_lds: bool) -> Callable:
1073
+ assert solver is not None
1074
+
1075
+ if use_lds:
1076
+
1077
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1078
+ solver.execute(arg0, lda, arg1)
1079
+
1080
+ return user_api_method_lds_impl
1081
+
1082
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1083
+ solver.execute(arg0, arg1)
1084
+
1085
+ return user_api_method_impl
1086
+
1087
+
1088
+ def _solve_factory(solver: Solver | None, use_lds: bool) -> Callable:
1089
+ if solver is None:
1090
+ raise RuntimeError(
1091
+ "Device function: solve is not available with this configuration: Operation is permitted only for square matrices"
1092
+ )
1093
+ assert solver.m == solver.n
1094
+
1095
+ if use_lds:
1096
+
1097
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1098
+ solver.execute(arg0, lda, arg1, ldb)
1099
+
1100
+ return user_api_method_lds_impl
1101
+
1102
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1103
+ solver.execute(arg0, arg1)
1104
+
1105
+ return user_api_method_impl
1106
+
1107
+
1108
+ _CHOLESKY_SOLVER_DEFINITION_ARGS = [
1109
+ "size",
1110
+ "precision",
1111
+ "execution",
1112
+ "sm",
1113
+ "arrangement",
1114
+ "fill_mode",
1115
+ "batches_per_block",
1116
+ "data_type",
1117
+ "leading_dimensions",
1118
+ "block_dim",
1119
+ ]
1120
+
1121
+ _CHOLESKY_SOLVER_PROPS = [
1122
+ "value_type",
1123
+ "m",
1124
+ "n",
1125
+ "k",
1126
+ "a_arrangement",
1127
+ "b_arrangement",
1128
+ "lda",
1129
+ "ldb",
1130
+ "block_size",
1131
+ "info_type",
1132
+ "info_shape",
1133
+ "info_strides",
1134
+ "a_shape",
1135
+ "b_shape",
1136
+ ]
1137
+
1138
+ _CHOLESKY_SOLVER_DISPATCH_METHODS = [
1139
+ _UserApiSolverDispatch(
1140
+ method="factorize",
1141
+ solver_attr="_factorize",
1142
+ factory=_factorize_factory,
1143
+ expected_lds=["lda"],
1144
+ ),
1145
+ _UserApiSolverDispatch(
1146
+ method="solve",
1147
+ solver_attr="_solve",
1148
+ factory=_solve_factory,
1149
+ expected_lds=["lda", "ldb"],
1150
+ ),
1151
+ ]
1152
+
1153
+ _register_user_api_dispatch(
1154
+ CholeskySolver,
1155
+ _CHOLESKY_SOLVER_DEFINITION_ARGS,
1156
+ _CHOLESKY_SOLVER_PROPS,
1157
+ _CHOLESKY_SOLVER_DISPATCH_METHODS,
1158
+ [
1159
+ _A_STRIDES_DEVICE_METHOD,
1160
+ _B_STRIDES_DEVICE_METHOD,
1161
+ _A_SIZE_DEVICE_METHOD,
1162
+ _B_SIZE_DEVICE_METHOD,
1163
+ ],
1164
+ )
1165
+
1166
+ # ==========================
1167
+ # LU Solver dispatch
1168
+ # ==========================
1169
+
1170
+ _LU_SOLVER_DEFINITION_ARGS = [
1171
+ "size",
1172
+ "precision",
1173
+ "execution",
1174
+ "sm",
1175
+ "arrangement",
1176
+ "transpose_mode",
1177
+ "batches_per_block",
1178
+ "data_type",
1179
+ "leading_dimensions",
1180
+ "block_dim",
1181
+ ]
1182
+
1183
+ _LU_SOLVER_PROPS = [
1184
+ "value_type",
1185
+ "m",
1186
+ "n",
1187
+ "k",
1188
+ "a_arrangement",
1189
+ "b_arrangement",
1190
+ "lda",
1191
+ "ldb",
1192
+ "block_size",
1193
+ "info_type",
1194
+ "info_shape",
1195
+ "info_strides",
1196
+ "a_shape",
1197
+ "b_shape",
1198
+ ]
1199
+
1200
+ _LU_SOLVER_DISPATCH_METHODS = [
1201
+ _UserApiSolverDispatch(
1202
+ method="factorize",
1203
+ solver_attr="_factorize",
1204
+ factory=_factorize_factory,
1205
+ expected_lds=["lda"],
1206
+ ),
1207
+ _UserApiSolverDispatch(
1208
+ method="solve",
1209
+ solver_attr="_solve",
1210
+ factory=_solve_factory,
1211
+ expected_lds=["lda", "ldb"],
1212
+ ),
1213
+ ]
1214
+
1215
+ _register_user_api_dispatch(
1216
+ LUSolver,
1217
+ _LU_SOLVER_DEFINITION_ARGS,
1218
+ _LU_SOLVER_PROPS,
1219
+ _LU_SOLVER_DISPATCH_METHODS,
1220
+ [
1221
+ _A_STRIDES_DEVICE_METHOD,
1222
+ _B_STRIDES_DEVICE_METHOD,
1223
+ _A_SIZE_DEVICE_METHOD,
1224
+ _B_SIZE_DEVICE_METHOD,
1225
+ ],
1226
+ )
1227
+
1228
+ # ==========================
1229
+ # Triangular Solver dispatch
1230
+ # ==========================
1231
+
1232
+
1233
+ def _triangular_solve_factory(solver: Solver | None, use_lds: bool) -> Callable:
1234
+ assert solver is not None
1235
+
1236
+ if use_lds:
1237
+
1238
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1239
+ solver.execute(arg0, lda, arg1, ldb)
1240
+
1241
+ return user_api_method_lds_impl
1242
+
1243
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1244
+ solver.execute(arg0, arg1)
1245
+
1246
+ return user_api_method_impl
1247
+
1248
+
1249
+ _TRIANGULAR_SOLVER_DEFINITION_ARGS = [
1250
+ "size",
1251
+ "precision",
1252
+ "execution",
1253
+ "sm",
1254
+ "side",
1255
+ "fill_mode",
1256
+ "diag",
1257
+ "transpose_mode",
1258
+ "arrangement",
1259
+ "batches_per_block",
1260
+ "data_type",
1261
+ "leading_dimensions",
1262
+ ]
1263
+
1264
+ _TRIANGULAR_SOLVER_PROPS = [
1265
+ "block_dim",
1266
+ "value_type",
1267
+ "m",
1268
+ "n",
1269
+ "k",
1270
+ "a_arrangement",
1271
+ "b_arrangement",
1272
+ "lda",
1273
+ "ldb",
1274
+ "block_size",
1275
+ "a_shape",
1276
+ "b_shape",
1277
+ ]
1278
+
1279
+ _TRIANGULAR_SOLVER_DISPATCH_METHODS = [
1280
+ _UserApiSolverDispatch(
1281
+ method="solve",
1282
+ solver_attr="_solve",
1283
+ factory=_triangular_solve_factory,
1284
+ expected_lds=["lda", "ldb"],
1285
+ ),
1286
+ ]
1287
+
1288
+ _register_user_api_dispatch(
1289
+ TriangularSolver,
1290
+ _TRIANGULAR_SOLVER_DEFINITION_ARGS,
1291
+ _TRIANGULAR_SOLVER_PROPS,
1292
+ _TRIANGULAR_SOLVER_DISPATCH_METHODS,
1293
+ [
1294
+ _A_STRIDES_DEVICE_METHOD,
1295
+ _B_STRIDES_DEVICE_METHOD,
1296
+ _A_SIZE_DEVICE_METHOD,
1297
+ _B_SIZE_DEVICE_METHOD,
1298
+ ],
1299
+ )
1300
+
1301
+ # ==========================
1302
+ # LU Pivot Solver dispatch
1303
+ # ==========================
1304
+
1305
+
1306
+ def _factorize_pivot_factory(solver: Solver | None, use_lds: bool) -> Callable:
1307
+ assert solver is not None
1308
+
1309
+ if use_lds:
1310
+
1311
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1312
+ solver.execute(arg0, lda, arg1, arg2)
1313
+
1314
+ return user_api_method_lds_impl
1315
+
1316
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1317
+ solver.execute(arg0, arg1, arg2)
1318
+
1319
+ return user_api_method_impl
1320
+
1321
+
1322
+ def _solve_pivot_factory(solver: Solver | None, use_lds: bool) -> Callable:
1323
+ if solver is None:
1324
+ raise RuntimeError(
1325
+ "Device function: solve is not available with this configuration: Operation is permitted only for square matrices"
1326
+ )
1327
+ assert solver.m == solver.n
1328
+
1329
+ if use_lds:
1330
+
1331
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1332
+ solver.execute(arg0, lda, arg1, arg2, ldb)
1333
+
1334
+ return user_api_method_lds_impl
1335
+
1336
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1337
+ solver.execute(arg0, arg1, arg2)
1338
+
1339
+ return user_api_method_impl
1340
+
1341
+
1342
+ _LU_PIVOT_SOLVER_DEFINITION_ARGS = [
1343
+ "size",
1344
+ "precision",
1345
+ "execution",
1346
+ "sm",
1347
+ "arrangement",
1348
+ "transpose_mode",
1349
+ "batches_per_block",
1350
+ "data_type",
1351
+ "leading_dimensions",
1352
+ "block_dim",
1353
+ ]
1354
+
1355
+ _LU_PIVOT_SOLVER_PROPS = [
1356
+ "block_size",
1357
+ "value_type",
1358
+ "m",
1359
+ "n",
1360
+ "k",
1361
+ "a_arrangement",
1362
+ "b_arrangement",
1363
+ "lda",
1364
+ "ldb",
1365
+ "info_type",
1366
+ "info_shape",
1367
+ "info_strides",
1368
+ "ipiv_type",
1369
+ "ipiv_size",
1370
+ "ipiv_shape",
1371
+ "ipiv_strides",
1372
+ "a_shape",
1373
+ "b_shape",
1374
+ ]
1375
+
1376
+ _LU_PIVOT_SOLVER_DISPATCH_METHODS = [
1377
+ _UserApiSolverDispatch(
1378
+ method="factorize",
1379
+ solver_attr="_factorize",
1380
+ factory=_factorize_pivot_factory,
1381
+ expected_lds=["lda"],
1382
+ ),
1383
+ _UserApiSolverDispatch(
1384
+ method="solve",
1385
+ solver_attr="_solve",
1386
+ factory=_solve_pivot_factory,
1387
+ expected_lds=["lda", "ldb"],
1388
+ ),
1389
+ ]
1390
+
1391
+ _register_user_api_dispatch(
1392
+ LUPivotSolver,
1393
+ _LU_PIVOT_SOLVER_DEFINITION_ARGS,
1394
+ _LU_PIVOT_SOLVER_PROPS,
1395
+ _LU_PIVOT_SOLVER_DISPATCH_METHODS,
1396
+ [
1397
+ _A_STRIDES_DEVICE_METHOD,
1398
+ _B_STRIDES_DEVICE_METHOD,
1399
+ _A_SIZE_DEVICE_METHOD,
1400
+ _B_SIZE_DEVICE_METHOD,
1401
+ ],
1402
+ )
1403
+
1404
+ # ==========================
1405
+ # QRFactors dispatch
1406
+ # ==========================
1407
+
1408
+ _QR_FACTORS_DEFINITION_ARGS = [
1409
+ "size",
1410
+ "precision",
1411
+ "execution",
1412
+ "sm",
1413
+ "batches_per_block",
1414
+ "data_type",
1415
+ "block_dim",
1416
+ "a_arrangement",
1417
+ "lda",
1418
+ ]
1419
+
1420
+ _QR_FACTORS_PROPS = [
1421
+ "value_type",
1422
+ "m",
1423
+ "n",
1424
+ "block_size",
1425
+ "tau_type",
1426
+ "tau_size",
1427
+ "tau_shape",
1428
+ "tau_strides",
1429
+ "a_shape",
1430
+ ]
1431
+
1432
+ _QR_FACTORS_DISPATCH_METHODS = [
1433
+ _UserApiSolverDispatch(
1434
+ method="factorize",
1435
+ solver_attr="_factorize",
1436
+ factory=_factorize_factory,
1437
+ expected_lds=["lda"],
1438
+ ),
1439
+ ]
1440
+
1441
+ _register_user_api_dispatch(
1442
+ QRFactorize,
1443
+ _QR_FACTORS_DEFINITION_ARGS,
1444
+ _QR_FACTORS_PROPS,
1445
+ _QR_FACTORS_DISPATCH_METHODS,
1446
+ [
1447
+ _A_STRIDES_DEVICE_METHOD,
1448
+ _A_SIZE_DEVICE_METHOD,
1449
+ ],
1450
+ )
1451
+
1452
+ _register_user_api_dispatch(
1453
+ LQFactorize,
1454
+ _QR_FACTORS_DEFINITION_ARGS,
1455
+ _QR_FACTORS_PROPS,
1456
+ _QR_FACTORS_DISPATCH_METHODS,
1457
+ [
1458
+ _A_STRIDES_DEVICE_METHOD,
1459
+ _A_SIZE_DEVICE_METHOD,
1460
+ ],
1461
+ )
1462
+
1463
+ # ==========================
1464
+ # Orthogonal Multiply dispatch
1465
+ # ==========================
1466
+
1467
+
1468
+ def _orthogonal_multiply_factory(solver: Solver | None, use_lds: bool) -> Callable:
1469
+ assert solver is not None
1470
+
1471
+ if use_lds:
1472
+
1473
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1474
+ solver.execute(arg0, lda, arg1, arg2, ldc)
1475
+
1476
+ return user_api_method_lds_impl
1477
+
1478
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1479
+ solver.execute(arg0, arg1, arg2)
1480
+
1481
+ return user_api_method_impl
1482
+
1483
+
1484
+ _ORTHOGONAL_MULTIPLY_DEFINITION_ARGS = [
1485
+ "size",
1486
+ "precision",
1487
+ "execution",
1488
+ "sm",
1489
+ "arrangement",
1490
+ "batches_per_block",
1491
+ "data_type",
1492
+ "leading_dimensions",
1493
+ "block_dim",
1494
+ "transpose_mode",
1495
+ "side",
1496
+ ]
1497
+
1498
+ _ORTHOGONAL_MULTIPLY_PROPS = [
1499
+ "value_type",
1500
+ "m",
1501
+ "n",
1502
+ "k",
1503
+ "a_arrangement",
1504
+ "b_arrangement",
1505
+ "lda",
1506
+ "ldb",
1507
+ "block_size",
1508
+ "tau_type",
1509
+ "tau_size",
1510
+ "tau_shape",
1511
+ "tau_strides",
1512
+ "a_shape",
1513
+ "c_shape",
1514
+ ]
1515
+
1516
+ _QR_MULTIPLY_DISPATCH_METHODS = [
1517
+ _UserApiSolverDispatch(
1518
+ method="multiply",
1519
+ solver_attr="_multiply",
1520
+ factory=_orthogonal_multiply_factory,
1521
+ expected_lds=["lda", "ldc"],
1522
+ ),
1523
+ ]
1524
+
1525
+ _register_user_api_dispatch(
1526
+ QRMultiply,
1527
+ _ORTHOGONAL_MULTIPLY_DEFINITION_ARGS,
1528
+ _ORTHOGONAL_MULTIPLY_PROPS,
1529
+ _QR_MULTIPLY_DISPATCH_METHODS,
1530
+ [
1531
+ _A_STRIDES_DEVICE_METHOD,
1532
+ _C_STRIDES_DEVICE_METHOD,
1533
+ _A_SIZE_DEVICE_METHOD,
1534
+ _C_SIZE_DEVICE_METHOD,
1535
+ ],
1536
+ )
1537
+
1538
+ _register_user_api_dispatch(
1539
+ LQMultiply,
1540
+ _ORTHOGONAL_MULTIPLY_DEFINITION_ARGS,
1541
+ _ORTHOGONAL_MULTIPLY_PROPS,
1542
+ _QR_MULTIPLY_DISPATCH_METHODS,
1543
+ [
1544
+ _A_STRIDES_DEVICE_METHOD,
1545
+ _C_STRIDES_DEVICE_METHOD,
1546
+ _A_SIZE_DEVICE_METHOD,
1547
+ _C_SIZE_DEVICE_METHOD,
1548
+ ],
1549
+ )
1550
+
1551
+ # ==========================
1552
+ # Least Squares Solver dispatch
1553
+ # ==========================
1554
+
1555
+
1556
+ def _least_squares_solve_factory(solver: Solver | None, use_lds: bool) -> Callable:
1557
+ assert solver is not None
1558
+
1559
+ if use_lds:
1560
+
1561
+ def user_api_method_lds_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1562
+ solver.execute(arg0, lda, arg1, arg2, ldb)
1563
+
1564
+ return user_api_method_lds_impl
1565
+
1566
+ def user_api_method_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
1567
+ solver.execute(arg0, arg1, arg2)
1568
+
1569
+ return user_api_method_impl
1570
+
1571
+
1572
+ _LEAST_SQUARES_SOLVER_DEFINITION_ARGS = [
1573
+ "size",
1574
+ "precision",
1575
+ "execution",
1576
+ "sm",
1577
+ "arrangement",
1578
+ "transpose_mode",
1579
+ "batches_per_block",
1580
+ "data_type",
1581
+ "leading_dimensions",
1582
+ "block_dim",
1583
+ ]
1584
+
1585
+ _LEAST_SQUARES_SOLVER_PROPS = [
1586
+ "value_type",
1587
+ "m",
1588
+ "n",
1589
+ "k",
1590
+ "a_arrangement",
1591
+ "b_arrangement",
1592
+ "lda",
1593
+ "ldb",
1594
+ "block_size",
1595
+ "tau_type",
1596
+ "tau_size",
1597
+ "tau_shape",
1598
+ "tau_strides",
1599
+ "a_shape",
1600
+ "b_shape",
1601
+ "x_shape",
1602
+ ]
1603
+
1604
+ _LEAST_SQUARES_SOLVER_DISPATCH_METHODS = [
1605
+ _UserApiSolverDispatch(
1606
+ method="solve",
1607
+ solver_attr="_solve",
1608
+ factory=_least_squares_solve_factory,
1609
+ expected_lds=["lda", "ldb"],
1610
+ ),
1611
+ ]
1612
+
1613
+ _register_user_api_dispatch(
1614
+ LeastSquaresSolver,
1615
+ _LEAST_SQUARES_SOLVER_DEFINITION_ARGS,
1616
+ _LEAST_SQUARES_SOLVER_PROPS,
1617
+ _LEAST_SQUARES_SOLVER_DISPATCH_METHODS,
1618
+ [
1619
+ _A_STRIDES_DEVICE_METHOD,
1620
+ _BX_STRIDES_DEVICE_METHOD,
1621
+ _A_SIZE_DEVICE_METHOD,
1622
+ _BX_SIZE_DEVICE_METHOD,
1623
+ ],
1624
+ )