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,26 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface class to encapsulate low-level calls to get and set matrix layout attributes.
7
+ """
8
+
9
+ __all__ = ["MatrixLayoutInterface"]
10
+
11
+ from nvmath._internal.attribute_ifc_factory import make_cublas_attribute_interface
12
+ from nvmath.bindings import cublasLt as cublaslt
13
+
14
+ # Create a class, MatrixLayoutInterface, such that each enum member in
15
+ # MatrixLayoutAttribute is exposed as a lowercase property (getter + setter).
16
+ # For example, if the class instance is stored as ``layout_ifc``,
17
+ # then the enum member ``ROWS`` becomes the property
18
+ # ``layout_ifc.rows``.
19
+ MatrixLayoutInterface = make_cublas_attribute_interface(
20
+ class_module=__name__,
21
+ class_name="MatrixLayoutInterface",
22
+ attribute_enum=cublaslt.MatrixLayoutAttribute,
23
+ get_attribute_dtype_fn=cublaslt.get_matrix_layout_attribute_dtype,
24
+ get_attribute_fn=cublaslt.matrix_layout_get_attribute,
25
+ set_attribute_fn=cublaslt.matrix_layout_set_attribute,
26
+ )
@@ -0,0 +1,432 @@
1
+ # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = (
6
+ "BatchInfo",
7
+ "compute_f_strides",
8
+ "LHSLayout",
9
+ "RHSLayout",
10
+ "get_lhs_layout",
11
+ "get_rhs_layout",
12
+ "wrap_solver_operands",
13
+ "wrap_check_solver_lhs",
14
+ "wrap_check_solver_rhs",
15
+ "parse_solver_operands",
16
+ "copy_operands",
17
+ "SolverBackend",
18
+ )
19
+
20
+ import enum
21
+ import math
22
+ from collections.abc import Sequence
23
+ from dataclasses import dataclass
24
+ from typing import Literal, TypeAlias, TypeGuard, cast
25
+
26
+ import numpy as np
27
+
28
+ from nvmath.internal import tensor_wrapper, utils
29
+ from nvmath.internal.package_ifc import StreamHolder
30
+ from nvmath.internal.tensor_ifc import Tensor, TensorHolder
31
+
32
+ SUPPORTED_DTYPE_NAMES = {"float32", "float64", "complex64", "complex128"}
33
+ WrappedOperand: TypeAlias = TensorHolder | Sequence[TensorHolder]
34
+
35
+
36
+ class SolverBackend(enum.IntEnum):
37
+ CUSOLVER = 0
38
+ CUBLAS = 1
39
+
40
+
41
+ def compute_f_strides(shape: tuple[int, ...]) -> tuple[int, ...]:
42
+ """Column-major (Fortran / LAPACK) strides: first axis is stride 1."""
43
+ strides = [1] * len(shape)
44
+ stride = 1
45
+ for i in range(len(shape)):
46
+ strides[i] = stride
47
+ stride *= shape[i]
48
+ return tuple(strides)
49
+
50
+
51
+ @dataclass(frozen=True, slots=True)
52
+ class LHSLayout:
53
+ # cuSOLVER/cuBLAS interpret matrix operands as column-major. An F-order LHS
54
+ # can be used as-is with op=N. A C-order LHS has the same memory layout as
55
+ # the column-major representation of A.T, so solve uses op=T to recover A @ x = b.
56
+ order: Literal["F", "C"]
57
+ lda: int
58
+
59
+
60
+ @dataclass(frozen=True, slots=True)
61
+ class RHSLayout:
62
+ ldb: int
63
+
64
+
65
+ @dataclass(frozen=True, slots=True, kw_only=True)
66
+ class BatchInfo:
67
+ explicitly_batched: bool
68
+ implicitly_batched: bool
69
+ batch_shape: tuple[int, ...] | None
70
+ batch_count: int
71
+
72
+ def __post_init__(self):
73
+ if self.explicitly_batched:
74
+ if self.implicitly_batched:
75
+ raise ValueError("The operand cannot be both explicitly and implicitly batched.")
76
+ if self.batch_shape is not None:
77
+ raise ValueError("The explicitly batched operand cannot have a batch shape.")
78
+ elif self.implicitly_batched:
79
+ if self.batch_shape is None:
80
+ raise ValueError("The implicitly batched operand must have a batch shape.")
81
+ else:
82
+ if self.batch_shape is not None:
83
+ raise ValueError("The non-batched operand cannot have a batch shape.")
84
+ if self.batch_count != 1:
85
+ raise ValueError("The non-batched operand must have a batch count of 1.")
86
+
87
+ def __str__(self) -> str:
88
+ if not self.explicitly_batched and not self.implicitly_batched:
89
+ return "non-batched"
90
+ if self.explicitly_batched:
91
+ return f"explicit batching (batch_count={self.batch_count})"
92
+ return f"implicit batching (batch_shape={self.batch_shape}, batch_count={self.batch_count})"
93
+
94
+
95
+ def _is_operand_sequence(operand: WrappedOperand) -> TypeGuard[Sequence[TensorHolder]]:
96
+ return isinstance(operand, Sequence)
97
+
98
+
99
+ def get_lhs_layout(lhs: WrappedOperand, check_inplace_compatible_strides: bool = True) -> LHSLayout:
100
+ if _is_operand_sequence(lhs):
101
+ unique_strides = {tuple(operand.strides) for operand in lhs}
102
+ if check_inplace_compatible_strides and len(unique_strides) != 1:
103
+ raise ValueError(
104
+ f"When inplace_a is True, the strides of the LHS must be the same for all batches, but got {unique_strides}."
105
+ )
106
+ strides = unique_strides.pop()
107
+ else:
108
+ lhs = cast(TensorHolder, lhs)
109
+ strides = tuple(lhs.strides)
110
+
111
+ # Store the leading dimension for the column-major view seen by GETRF/GETRS.
112
+ if strides[-2] == 1:
113
+ return LHSLayout("F", strides[-1])
114
+ if strides[-1] == 1:
115
+ return LHSLayout("C", strides[-2])
116
+
117
+ if check_inplace_compatible_strides:
118
+ raise ValueError(
119
+ f"When inplace_a is True, the LHS must have either column-major or row-major layout, but got strides {strides}."
120
+ )
121
+ raise AssertionError(f"Internal error: unable to determine LHS layout from strides {strides}.")
122
+
123
+
124
+ def get_rhs_layout(rhs: WrappedOperand, nrhs: int, check_inplace_compatible_strides: bool = True) -> RHSLayout:
125
+ if _is_operand_sequence(rhs):
126
+ unique_strides = {tuple(operand.strides) for operand in rhs}
127
+ if check_inplace_compatible_strides and len(unique_strides) != 1:
128
+ raise ValueError(
129
+ f"When inplace_b is True, the strides of the RHS must be the same for all batches, but got {unique_strides}."
130
+ )
131
+ strides = unique_strides.pop()
132
+ shape = tuple(rhs[0].shape)
133
+ else:
134
+ rhs = cast(TensorHolder, rhs)
135
+ strides = tuple(rhs.strides)
136
+ shape = tuple(rhs.shape)
137
+
138
+ if len(strides) == 1:
139
+ if check_inplace_compatible_strides and strides[-1] != 1:
140
+ raise ValueError(f"When inplace_b is True, vector RHS operands must have unit stride, but got strides {strides}.")
141
+ return RHSLayout(shape[-1])
142
+
143
+ if check_inplace_compatible_strides and strides[-2] != 1:
144
+ raise ValueError(
145
+ f"When inplace_b is True, matrix RHS operands must have column-major layout, but got strides {strides}."
146
+ )
147
+
148
+ return RHSLayout(strides[-1] if nrhs > 1 else shape[-2])
149
+
150
+
151
+ def check_inplace_lhs_storage(lhs: WrappedOperand, batch_info: BatchInfo) -> None:
152
+ if batch_info.explicitly_batched:
153
+ lhs = cast(Sequence[TensorHolder], lhs)
154
+ # Full non-overlap validation is hard for arbitrary views, so
155
+ # cheaply guard the most obvious dangerous explicit-batch case:
156
+ # repeated views of the same matrix.
157
+ data_ptrs = {o.data_ptr for o in lhs}
158
+ if len(data_ptrs) != batch_info.batch_count:
159
+ raise ValueError(
160
+ f"When inplace_a is True, each batch in LHS must not share overlapping memory, "
161
+ f"but only got {len(data_ptrs)} unique data pointers for {batch_info.batch_count} batches."
162
+ )
163
+ return
164
+
165
+ lhs_holder = cast(TensorHolder, lhs)
166
+ if batch_info.implicitly_batched and 0 in lhs_holder.strides[:-2]:
167
+ # Full non-overlap validation is hard for arbitrary strided views,
168
+ # so cheaply guard the most obvious dangerous implicit-batch case:
169
+ # broadcasted batches (for example torch.expand) with zero batch
170
+ # strides, where multiple batch items share one matrix.
171
+ raise ValueError(
172
+ f"When inplace_a is True, each batch in LHS must not share overlapping memory, "
173
+ f"but found the implicitly batched LHS with strides {lhs_holder.strides}."
174
+ )
175
+
176
+
177
+ def check_inplace_rhs_storage(rhs: WrappedOperand, batch_info: BatchInfo) -> None:
178
+ if batch_info.explicitly_batched:
179
+ rhs = cast(Sequence[TensorHolder], rhs)
180
+ # Full non-overlap validation is hard for arbitrary views, so
181
+ # cheaply guard the most obvious dangerous explicit-batch case:
182
+ # repeated views of the same RHS operand.
183
+ data_ptrs = {o.data_ptr for o in rhs}
184
+ if len(data_ptrs) != batch_info.batch_count:
185
+ raise ValueError(
186
+ f"When inplace_b is True, each batch in RHS must not share overlapping memory, "
187
+ f"but only got {len(data_ptrs)} unique data pointers for {batch_info.batch_count} batches."
188
+ )
189
+ return
190
+
191
+ rhs_holder = cast(TensorHolder, rhs)
192
+ if batch_info.implicitly_batched and 0 in rhs_holder.strides[:-2]:
193
+ # Full non-overlap validation is hard for arbitrary strided views,
194
+ # so cheaply guard the most obvious dangerous implicit-batch case:
195
+ # broadcasted batches (for example torch.expand) with zero batch
196
+ # strides, where multiple batch items share one RHS operand.
197
+ raise ValueError(
198
+ f"When inplace_b is True, each batch in RHS must not share overlapping memory, "
199
+ f"but found the implicitly batched RHS with strides {rhs_holder.strides}."
200
+ )
201
+
202
+
203
+ def get_single_or_sequence_attr(obj, attribute_name: str, check_consistency: bool = False):
204
+ if isinstance(obj, Sequence):
205
+ result = obj[0].__getattribute__(attribute_name)
206
+ if check_consistency:
207
+ for i, o in enumerate(obj, start=1):
208
+ if get_single_or_sequence_attr(o, attribute_name) != result:
209
+ raise ValueError(
210
+ f"The {attribute_name} of the {i}th object ({o}) in the sequence "
211
+ f"({obj}) is different from the first object ({obj[0]})."
212
+ )
213
+ return result
214
+ else:
215
+ return obj.__getattribute__(attribute_name)
216
+
217
+
218
+ def wrap_solver_operands(operands: Tensor | Sequence[Tensor], check_consistency: bool = True):
219
+ explicitly_batched = isinstance(operands, Sequence)
220
+ if isinstance(operands, Sequence):
221
+ results = tensor_wrapper.wrap_operands(operands) # type: ignore
222
+ if check_consistency:
223
+ # Check the consistency of the operands
224
+ utils.get_operands_dtype(results)
225
+ utils.get_operands_device_id(results)
226
+ shapes = [o.shape for o in results]
227
+ for i, shape in enumerate(shapes, start=1):
228
+ if shape != shapes[0]:
229
+ raise ValueError(
230
+ f"The shape of the {i}th operand ({shape}) is not the same as the first operand ({shapes[0]})."
231
+ )
232
+ else:
233
+ results = tensor_wrapper.wrap_operand(operands) # type: ignore
234
+ return results, explicitly_batched
235
+
236
+
237
+ def wrap_check_solver_lhs(a: Tensor | Sequence[Tensor], check_inplace_a_layout: bool = False):
238
+ lhs, explicitly_batched = wrap_solver_operands(a, check_consistency=True)
239
+ implicitly_batched = False
240
+ lhs_layout = None
241
+ if explicitly_batched:
242
+ # shape consistency is checked in wrap_solver_operands
243
+ shape = lhs[0].shape
244
+ batch_count = len(lhs)
245
+ n0, n1 = shape
246
+ if n0 != n1:
247
+ raise ValueError(f"For explicitly batched LHS, the shape of each batch must be square, but got {shape}.")
248
+ n = n0
249
+ batch_shape = None
250
+ else:
251
+ shape = lhs.shape
252
+ ndim = len(shape)
253
+ if ndim == 2:
254
+ batch_shape = None
255
+ n0, n1 = shape
256
+ batch_count = 1
257
+ else:
258
+ implicitly_batched = True
259
+ *batch_shape, n0, n1 = shape
260
+ batch_shape = tuple(batch_shape)
261
+ batch_count = math.prod(batch_shape)
262
+ if n0 != n1:
263
+ raise ValueError(f"The last two dimensions of the LHS must be the same, but got {n0} and {n1}.")
264
+ n = n0
265
+
266
+ batch_info = BatchInfo(
267
+ explicitly_batched=explicitly_batched,
268
+ implicitly_batched=implicitly_batched,
269
+ batch_shape=batch_shape,
270
+ batch_count=batch_count,
271
+ )
272
+ if check_inplace_a_layout:
273
+ check_inplace_lhs_storage(lhs, batch_info)
274
+ # CPU inputs are copied to internal GPU buffers, so their layout does not
275
+ # need to satisfy in-place solver requirements.
276
+ if get_single_or_sequence_attr(lhs, "device") == "cuda":
277
+ lhs_layout = get_lhs_layout(lhs)
278
+
279
+ return lhs, batch_info, n, lhs_layout
280
+
281
+
282
+ def wrap_check_solver_rhs(b: Tensor | Sequence[Tensor], check_inplace_b_layout: bool = False):
283
+ rhs, explicitly_batched = wrap_solver_operands(b, check_consistency=True)
284
+ implicitly_batched = False
285
+ rhs_layout = None
286
+ if explicitly_batched:
287
+ # shape consistency is checked in wrap_solver_operands
288
+ shape = rhs[0].shape
289
+ batch_count = len(rhs)
290
+ ndim = len(shape)
291
+ if ndim == 1:
292
+ n, nrhs = shape[0], 1
293
+ elif ndim == 2:
294
+ n, nrhs = shape
295
+ else:
296
+ raise ValueError(f"For explicitly batched RHS, the shape of each batch must be 1D or 2D, but got {ndim}D.")
297
+ batch_shape = None
298
+ else:
299
+ shape = rhs.shape
300
+ ndim = len(shape)
301
+ if ndim >= 3:
302
+ implicitly_batched = True
303
+ *batch_shape, n, nrhs = shape
304
+ batch_shape = tuple(batch_shape)
305
+ batch_count = math.prod(batch_shape)
306
+ else:
307
+ batch_shape = None
308
+ batch_count = 1
309
+ if ndim == 1:
310
+ n, nrhs = shape[0], 1
311
+ else:
312
+ n, nrhs = shape
313
+
314
+ batch_info = BatchInfo(
315
+ explicitly_batched=explicitly_batched,
316
+ implicitly_batched=implicitly_batched,
317
+ batch_shape=batch_shape,
318
+ batch_count=batch_count,
319
+ )
320
+ if check_inplace_b_layout:
321
+ check_inplace_rhs_storage(rhs, batch_info)
322
+ # CPU inputs are copied to internal GPU buffers, so their layout does not
323
+ # need to satisfy in-place solver requirements.
324
+ if get_single_or_sequence_attr(rhs, "device") == "cuda":
325
+ rhs_layout = get_rhs_layout(rhs, nrhs)
326
+
327
+ return rhs, batch_info, n, nrhs, rhs_layout
328
+
329
+
330
+ def parse_solver_operands(
331
+ a: Tensor | Sequence[Tensor],
332
+ b: Tensor | Sequence[Tensor],
333
+ check_inplace_a_layout: bool = False,
334
+ check_inplace_b_layout: bool = False,
335
+ ):
336
+ lhs, lhs_batch_info, n_lhs, lhs_layout = wrap_check_solver_lhs(a, check_inplace_a_layout=check_inplace_a_layout)
337
+ rhs, rhs_batch_info, n_rhs, nrhs, rhs_layout = wrap_check_solver_rhs(b, check_inplace_b_layout=check_inplace_b_layout)
338
+ if lhs_batch_info.batch_count != rhs_batch_info.batch_count:
339
+ raise ValueError(
340
+ f"The number of batches in the LHS and RHS must be the same, but "
341
+ f"got {lhs_batch_info.batch_count} for the LHS and {rhs_batch_info.batch_count} for the RHS."
342
+ )
343
+ if (
344
+ lhs_batch_info.batch_shape is not None
345
+ and rhs_batch_info.batch_shape is not None
346
+ and lhs_batch_info.batch_shape != rhs_batch_info.batch_shape
347
+ ):
348
+ raise ValueError(
349
+ f"For implicitly batched LHS & RHS, the batch shapes must be the same, but "
350
+ f"got {lhs_batch_info.batch_shape} for the LHS and {rhs_batch_info.batch_shape} for the RHS."
351
+ )
352
+ if n_lhs != n_rhs:
353
+ raise ValueError(f"The number of columns in the LHS ({n_lhs}) and RHS ({n_rhs}) must be the same.")
354
+
355
+ # Consistency within LHS or RHS has been checked in wrap_check_solver_lhs/rhs
356
+ # Here we only need to check the consistency between LHS and RHS.
357
+ package_lhs = get_single_or_sequence_attr(lhs, "name")
358
+ device_id_lhs = get_single_or_sequence_attr(lhs, "device_id")
359
+ dtype_name_lhs = get_single_or_sequence_attr(lhs, "dtype")
360
+
361
+ # We have managed to wrap the operands so we can skip checking the package consistency
362
+ package_rhs = get_single_or_sequence_attr(rhs, "name")
363
+ device_id_rhs = get_single_or_sequence_attr(rhs, "device_id")
364
+ dtype_name_rhs = get_single_or_sequence_attr(rhs, "dtype")
365
+
366
+ if package_lhs != package_rhs:
367
+ raise ValueError(f"The package for the LHS ({package_lhs}) and RHS ({package_rhs}) must be the same.")
368
+ if device_id_lhs != device_id_rhs:
369
+ raise ValueError(f"The device id for the LHS ({device_id_lhs}) and RHS ({device_id_rhs}) must be the same.")
370
+ if dtype_name_lhs != dtype_name_rhs:
371
+ raise ValueError(f"The dtype for the LHS ({dtype_name_lhs}) and RHS ({dtype_name_rhs}) must be the same.")
372
+
373
+ return (
374
+ lhs,
375
+ lhs_batch_info,
376
+ rhs,
377
+ rhs_batch_info,
378
+ n_lhs,
379
+ nrhs,
380
+ package_lhs,
381
+ device_id_lhs,
382
+ dtype_name_lhs,
383
+ lhs_layout,
384
+ rhs_layout,
385
+ )
386
+
387
+
388
+ def copy_operands(
389
+ dst: WrappedOperand,
390
+ src: WrappedOperand,
391
+ stream_holder: StreamHolder,
392
+ ):
393
+ if _is_operand_sequence(dst):
394
+ if not _is_operand_sequence(src):
395
+ raise AssertionError("The source must be a sequence if the destination is a sequence.")
396
+ for d, s in zip(dst, src, strict=True):
397
+ d.copy_(s, stream_holder=stream_holder)
398
+ else:
399
+ if _is_operand_sequence(src):
400
+ raise AssertionError("The source must be a single operand if the destination is a single operand.")
401
+ dst = cast(TensorHolder, dst)
402
+ src = cast(TensorHolder, src)
403
+ dst.copy_(src, stream_holder=stream_holder)
404
+
405
+
406
+ def get_operands_ptr_array(
407
+ wrapped_operands: WrappedOperand,
408
+ batch_indices: tuple[tuple[int, ...], ...] | None = None,
409
+ ) -> TensorHolder:
410
+ if _is_operand_sequence(wrapped_operands):
411
+ device_ptrs = [o.data_ptr for o in wrapped_operands]
412
+ else:
413
+ wrapped_operands = cast(TensorHolder, wrapped_operands)
414
+ assert batch_indices is not None, "Internal Error."
415
+ starting_ptr = wrapped_operands.data_ptr
416
+ offsets = wrapped_operands.strides[: len(batch_indices[0])] # type: ignore
417
+ device_ptrs = []
418
+ for index in batch_indices:
419
+ device_ptrs.append(
420
+ starting_ptr + wrapped_operands.itemsize * sum(o * i for o, i in zip(offsets, index, strict=True))
421
+ )
422
+ return tensor_wrapper.wrap_operand(np.array(device_ptrs, dtype=np.uint64))
423
+
424
+
425
+ def update_operands_ptr_array(
426
+ ptr_operand: TensorHolder,
427
+ wrapped_operands: WrappedOperand,
428
+ stream_holder: StreamHolder,
429
+ batch_indices: tuple[tuple[int, ...], ...] | None = None,
430
+ ):
431
+ device_ptrs = get_operands_ptr_array(wrapped_operands, batch_indices)
432
+ ptr_operand.copy_(device_ptrs, stream_holder=stream_holder)
@@ -0,0 +1,144 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Functions to link type names with CUBLAS compute types.
7
+ """
8
+
9
+ __all__ = [
10
+ "NAMES_TO_DEFAULT_SCALE_TYPE",
11
+ "NAMES_TO_DEFAULT_COMPUTE_TYPE",
12
+ "SUPPORTED_TYPES",
13
+ "COMPUTE_TYPE_TO_DEFAULT_SCALE_TYPE",
14
+ "SCALE_TYPE_TO_DEFAULT_COMPUTE_TYPE",
15
+ ]
16
+
17
+ from nvmath.bindings import cublas # type: ignore
18
+ from nvmath.internal.typemaps import cudaDataType
19
+
20
+
21
+ def create_default_scale_type_map():
22
+ """
23
+ Map the data type name to the corresponding CUDA data type that's appropriate for
24
+ default scale.
25
+ """
26
+
27
+ dt = cudaDataType
28
+
29
+ scale_type_map = {}
30
+ # FP4 scale types (https://docs.nvidia.com/cuda/cublas/index.html#id105)
31
+ scale_type_map["float4_e2m1fn_x2", "float4_e2m1fn_x2"] = dt.CUDA_R_32F
32
+ # FP8 scale types
33
+ scale_type_map["float8_e4m3fn", "float8_e5m2"] = dt.CUDA_R_32F
34
+ scale_type_map["float8_e5m2", "float8_e4m3fn"] = dt.CUDA_R_32F
35
+ scale_type_map["float8_e4m3fn", "float8_e4m3fn"] = dt.CUDA_R_32F
36
+ scale_type_map["bfloat16", "bfloat16"] = dt.CUDA_R_32F
37
+ scale_type_map["float16", "float16"] = dt.CUDA_R_32F
38
+ scale_type_map["float32", "float32"] = dt.CUDA_R_32F
39
+ scale_type_map["float64", "float64"] = dt.CUDA_R_64F
40
+ scale_type_map["complex32", "complex32"] = dt.CUDA_C_32F
41
+ scale_type_map["complex64", "complex64"] = dt.CUDA_C_32F
42
+ scale_type_map["complex128", "complex128"] = dt.CUDA_C_64F
43
+
44
+ return scale_type_map
45
+
46
+
47
+ def create_compute_type_to_scale_type_map(is_complex):
48
+ """
49
+ Map the compute type to the corresponding CUDA data type that's appropriate for
50
+ default scale.
51
+ """
52
+
53
+ dt = cudaDataType
54
+ ct = cublas.ComputeType
55
+
56
+ scale_type_map = {}
57
+ scale_type_map[ct.COMPUTE_16F] = dt.CUDA_R_16F
58
+ scale_type_map[ct.COMPUTE_16F_PEDANTIC] = dt.CUDA_R_16F
59
+
60
+ f32 = dt.CUDA_C_32F if is_complex else dt.CUDA_R_32F
61
+ f64 = dt.CUDA_C_64F if is_complex else dt.CUDA_R_64F
62
+
63
+ scale_type_map[ct.COMPUTE_32F] = f32
64
+ scale_type_map[ct.COMPUTE_32F_PEDANTIC] = f32
65
+ scale_type_map[ct.COMPUTE_32F_FAST_16F] = f32
66
+ scale_type_map[ct.COMPUTE_32F_FAST_16BF] = f32
67
+ scale_type_map[ct.COMPUTE_32F_FAST_TF32] = f32
68
+ scale_type_map[ct.COMPUTE_32F_EMULATED_16BFX9] = f32
69
+ scale_type_map[ct.COMPUTE_64F] = f64
70
+ scale_type_map[ct.COMPUTE_64F_PEDANTIC] = f64
71
+ scale_type_map[ct.COMPUTE_64F_EMULATED_FIXEDPOINT] = f64
72
+
73
+ return scale_type_map
74
+
75
+
76
+ def create_scale_type_to_compute_type_map():
77
+ """
78
+ Map the scale type to the corresponding compute type that's an appropriate default.
79
+ """
80
+
81
+ dt = cudaDataType
82
+ ct = cublas.ComputeType
83
+
84
+ compute_type_map = {}
85
+ compute_type_map[dt.CUDA_R_16F] = ct.COMPUTE_16F
86
+ compute_type_map[dt.CUDA_R_16BF] = ct.COMPUTE_32F
87
+ compute_type_map[dt.CUDA_R_32F] = ct.COMPUTE_32F
88
+ compute_type_map[dt.CUDA_C_32F] = ct.COMPUTE_32F
89
+ compute_type_map[dt.CUDA_R_64F] = ct.COMPUTE_64F
90
+ compute_type_map[dt.CUDA_C_64F] = ct.COMPUTE_64F
91
+ return compute_type_map
92
+
93
+
94
+ def create_compute_type_map():
95
+ """
96
+ Map the data type name to the corresponding CUDA data type that's appropriate for
97
+ default compute type.
98
+ """
99
+
100
+ ct = cublas.ComputeType
101
+
102
+ compute_type_map = {}
103
+ # FP4 compute types (https://docs.nvidia.com/cuda/cublas/index.html#id105)
104
+ compute_type_map["float4_e2m1fn_x2", "float4_e2m1fn_x2"] = ct.COMPUTE_32F
105
+ # FP8 compute types
106
+ compute_type_map["float8_e4m3fn", "float8_e5m2"] = ct.COMPUTE_32F
107
+ compute_type_map["float8_e5m2", "float8_e4m3fn"] = ct.COMPUTE_32F
108
+ compute_type_map["float8_e4m3fn", "float8_e4m3fn"] = ct.COMPUTE_32F
109
+ compute_type_map["bfloat16", "bfloat16"] = ct.COMPUTE_32F
110
+ compute_type_map["float16", "float16"] = ct.COMPUTE_32F
111
+ compute_type_map["float32", "float32"] = ct.COMPUTE_32F
112
+ compute_type_map["float64", "float64"] = ct.COMPUTE_64F
113
+ compute_type_map["complex32", "complex32"] = ct.COMPUTE_32F
114
+ compute_type_map["complex64", "complex64"] = ct.COMPUTE_32F
115
+ compute_type_map["complex128", "complex128"] = ct.COMPUTE_64F
116
+
117
+ return compute_type_map
118
+
119
+
120
+ CUBLAS_COMPUTE_TYPE_TO_NAME = {
121
+ cublas.ComputeType.COMPUTE_32F: ("float32", "complex64"),
122
+ cublas.ComputeType.COMPUTE_64F: ("float64", "complex128"),
123
+ }
124
+
125
+ NAMES_TO_DEFAULT_SCALE_TYPE = create_default_scale_type_map()
126
+ NAMES_TO_DEFAULT_COMPUTE_TYPE = create_compute_type_map()
127
+ COMPUTE_TYPE_TO_DEFAULT_SCALE_TYPE = {
128
+ "real": create_compute_type_to_scale_type_map(is_complex=False),
129
+ "complex": create_compute_type_to_scale_type_map(is_complex=True),
130
+ }
131
+ SCALE_TYPE_TO_DEFAULT_COMPUTE_TYPE = create_scale_type_to_compute_type_map()
132
+
133
+ SUPPORTED_TYPES = [
134
+ "float4_e2m1fn_x2", # FP4 (supported on SM 10.0+)
135
+ "float8_e4m3fn",
136
+ "float8_e5m2",
137
+ "bfloat16",
138
+ "float16",
139
+ "float32",
140
+ "float64",
141
+ "complex32",
142
+ "complex64",
143
+ "complex128",
144
+ ]