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,157 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Utilities.
7
+ """
8
+
9
+ __all__ = [
10
+ "axis_order_in_memory",
11
+ "calculate_strides",
12
+ "check_batch_tileable",
13
+ "get_handle",
14
+ "pointer_aligned_to",
15
+ ]
16
+
17
+ import typing
18
+
19
+ from nvmath._internal import threadsafe
20
+ from nvmath.bindings import cublas
21
+ from nvmath.bindings import cublasLt as cublaslt
22
+ from nvmath.internal import utils
23
+ from nvmath.internal._layout import StridedLayout
24
+
25
+
26
+ def create_cublas_handle(device_id: int) -> int:
27
+ """
28
+ Currently for internal use only.
29
+ """
30
+ with utils.device_ctx(device_id):
31
+ return cublas.create()
32
+
33
+
34
+ def create_cublaslt_handle(device_id: int) -> int:
35
+ """
36
+ Currently for internal use only.
37
+ """
38
+ with utils.device_ctx(device_id):
39
+ return cublaslt.create()
40
+
41
+
42
+ # One per-thread cache per binding. Keying by `device_id` alone (rather than a
43
+ # shared `(binding, device_id)` dict) keeps the two bindings' handles in
44
+ # separate caches, which avoids any chance of a binding-string typo aliasing
45
+ # the wrong handle. cuBLAS handles must not be shared across threads
46
+ # (https://docs.nvidia.com/cuda/cublas/#thread-safety); cuBLASLt handles could
47
+ # be shared, but per-thread caching is a safe superset and keeps both paths
48
+ # uniform.
49
+ _CUBLAS_CACHE = threadsafe.HandleCache[int](
50
+ create=create_cublas_handle,
51
+ destroy=cublas.destroy,
52
+ )
53
+ _CUBLASLT_CACHE = threadsafe.HandleCache[int](
54
+ create=create_cublaslt_handle,
55
+ destroy=cublaslt.destroy,
56
+ )
57
+
58
+
59
+ def get_handle(device_id: int, binding="cublaslt") -> int:
60
+ """
61
+ Retrieve the cuBLAS[lt] library handle for the specified device. If one doesn't exist,
62
+ create, cache, and return the handle.
63
+
64
+ Handles are cached per thread in a separate cache per binding, so a single
65
+ thread can hold distinct handles for ``"cublas"`` and ``"cublaslt"`` on the
66
+ same device. Cached handles are released automatically when the owning
67
+ thread exits.
68
+ """
69
+ if binding == "cublas":
70
+ cache = _CUBLAS_CACHE
71
+ elif binding == "cublaslt":
72
+ cache = _CUBLASLT_CACHE
73
+ else:
74
+ raise ValueError(f"{binding} is not a valid library name.")
75
+ return cache.get(device_id)
76
+
77
+
78
+ def pointer_aligned_to(address):
79
+ """
80
+ Return the number of bytes the address is aligned to.
81
+ """
82
+ return address & ~(address - 1)
83
+
84
+
85
+ def axis_order_in_memory(strides):
86
+ """
87
+ Compute the order in which the axes appear in memory.
88
+ """
89
+ if len(strides) == 0:
90
+ return ()
91
+
92
+ _, axis_order = zip(*sorted(zip(strides, range(len(strides)), strict=True)), strict=True)
93
+
94
+ return axis_order
95
+
96
+
97
+ def calculate_strides(shape: typing.Sequence[int], axis_order: typing.Sequence[int], min_stride: int = 1):
98
+ """
99
+ Calculate the strides for the provided shape and axis order.
100
+ """
101
+ assert len(axis_order) == len(shape), f"axis_order length ({len(axis_order)}) must equal shape length ({len(shape)})"
102
+ assert len(set(axis_order)) == len(axis_order), f"axis_order must not contain duplicates: {axis_order}"
103
+ assert set(axis_order) == set(range(len(shape))), f"axis_order must be permutation of range({len(shape)}): {axis_order}"
104
+
105
+ strides: list[None | int] = [None] * len(shape)
106
+
107
+ stride = min_stride
108
+ for axis in axis_order:
109
+ strides[axis] = stride
110
+ stride *= shape[axis]
111
+
112
+ return strides
113
+
114
+
115
+ def check_batch_tileable(batch_shape, batch_strides):
116
+ """
117
+ Whether the batch layout can be expressed the way cuBLAS strided-batched
118
+ expects: a single ``batch_count`` and a single stride ``S`` per operand,
119
+ so that tile ``k`` lives at ``base + k * S`` for ``k = 0, ..., N - 1``.
120
+
121
+ Two scenarios -- and only these two -- satisfy that form:
122
+
123
+ (a) Regular grid of distinct tiles (``S > 0``): tiles sit at evenly
124
+ spaced offsets along *some* axis order, with the gap between
125
+ consecutive tiles allowed to be larger than the tile itself (i.e.
126
+ padded/gapped batches are fine).
127
+
128
+ (b) Replicated tile (``S == 0``): every batch index lands on the same
129
+ tile, i.e. *every* non-singleton batch dim has stride 0. Typical
130
+ source: ``torch.expand`` (or equivalent) applied so that the
131
+ operand has no real batch axis -- e.g. ``A.unsqueeze(0).expand(N,
132
+ M, K)``.
133
+
134
+ A broadcast on *some* batch axis combined with a real (stride > 0)
135
+ batch axis of size > 1 does **not** qualify for (b) -- it isn't
136
+ tileable in the form above and is rejected. E.g.
137
+ ``X.unsqueeze(0).expand(N1, P, M, K)`` with both ``N1 > 1`` *and*
138
+ ``P > 1`` has batch strides ``(0, M*K)`` and is not tileable.
139
+ """
140
+ # Empty / all-size-1 batch: degenerate intersection of (a) and (b),
141
+ # trivially tileable.
142
+ if all(n == 1 for n in batch_shape):
143
+ return True
144
+
145
+ layout = StridedLayout(batch_shape, batch_strides, itemsize=1)
146
+
147
+ # Scenario (a): tiles on a regular grid in some axis order.
148
+ # `"K"` lets the grid be in any order (C, F, or a permutation), and
149
+ # `allow_leading_dim_stride=True` lets the smallest stride exceed 1.
150
+ if layout.is_dense("K", allow_leading_dim_stride=True):
151
+ return True
152
+
153
+ # Scenario (b): pure broadcast. Flatten collapses to a single 1-D dim
154
+ # with stride 0 iff every non-size-1 batch stride is 0; mixed
155
+ # broadcast + non-broadcast dims don't collapse and get rejected.
156
+ flat = layout.flattened()
157
+ return flat.ndim == 1 and flat.strides[0] == 0
@@ -0,0 +1,8 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from . import helpers as helpers # noqa: F403
6
+ from ._algorithmmod import * # noqa: F403
7
+ from ._configuration import * # noqa: F403
8
+ from .matmulmod import * # noqa: F403
@@ -0,0 +1,170 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ An interface class to query algorithm capabilities and configure it.
7
+ """
8
+
9
+ __all__ = ["Algorithm"]
10
+
11
+ import dataclasses
12
+
13
+ import numpy as np
14
+ import numpy.typing as npt
15
+
16
+ from nvmath.bindings.cublasLt import MatmulHeuristicResult, matmul_heuristic_result_dtype
17
+ from nvmath.linalg._internal.algo_cap_ifc import AlgoCapInterface
18
+ from nvmath.linalg._internal.algo_config_ifc import AlgoConfigInterface
19
+ from nvmath.linalg._internal.enum_to_tuples import (
20
+ CLUSTER_SHAPE_TO_ENUM,
21
+ ENUM_TO_CLUSTER_SHAPE,
22
+ ENUM_TO_MATMUL_STAGE,
23
+ ENUM_TO_MATMUL_TILE,
24
+ MATMUL_STAGE_TO_ENUM,
25
+ MATMUL_TILE_TO_ENUM,
26
+ )
27
+ from nvmath.linalg.advanced._configuration import AlgorithmCapabilities
28
+
29
+
30
+ class Algorithm:
31
+ """
32
+ An interface class to query algorithm capabilities and configure the algorithm.
33
+
34
+ Note that objects of this type should not be constructed directly by the user.
35
+ """
36
+
37
+ def __init__(self, algorithm: MatmulHeuristicResult) -> None:
38
+ assert isinstance(algorithm, MatmulHeuristicResult), "Internal error."
39
+ self.algorithm = algorithm
40
+ self.cap_ifc = AlgoCapInterface(algorithm)
41
+ self.config_ifc = AlgoConfigInterface(algorithm)
42
+
43
+ @property
44
+ def capabilities(self):
45
+ """
46
+ Return the capabilities of this algorithm as a
47
+ :class:`nvmath.linalg.advanced.AlgorithmCapabilities` dataclass.
48
+ """
49
+ names = [field.name for field in dataclasses.fields(AlgorithmCapabilities)]
50
+ _capabilities = {}
51
+ for name in names:
52
+ # Not all capabilities in the enum are supported in all CTK versions.
53
+ try:
54
+ _capabilities[name] = getattr(self.cap_ifc, name)
55
+ except:
56
+ pass
57
+ return AlgorithmCapabilities(**_capabilities)
58
+
59
+ @property
60
+ def algorithm_id(self) -> int:
61
+ "The ID of the algorithm (integer)."
62
+ return self.config_ifc.id
63
+
64
+ @property
65
+ def tile(self) -> tuple[int | str, ...] | str:
66
+ """A tuple representing the tile (see MatmulAlgoConfigAttribute.TILE_ID).
67
+ The value provided must be one of the `tile_ids` in the algorithm capabilities."""
68
+ return ENUM_TO_MATMUL_TILE[self.config_ifc.tile_id]
69
+
70
+ @tile.setter
71
+ def tile(self, tile: tuple[int | str, ...] | str) -> None:
72
+ self.config_ifc.tile_id = MATMUL_TILE_TO_ENUM[tile]
73
+
74
+ @property
75
+ def stages(self) -> tuple[int | str, ...] | str:
76
+ """A tuple representing the stages (see MatmulAlgoConfigAttribute.STAGES_ID).
77
+ The value provided must be one of the `stages_ids` in the algorithm capabilities."""
78
+ return ENUM_TO_MATMUL_STAGE[self.config_ifc.stages_id]
79
+
80
+ @stages.setter
81
+ def stages(self, stages: tuple[int | str, ...] | str) -> None:
82
+ self.config_ifc.stages_id = MATMUL_STAGE_TO_ENUM[stages]
83
+
84
+ @property
85
+ def split_k(self) -> int:
86
+ """The number of split-k steps (see MatmulAlgoConfigAttribute.SPLITK_NUM).
87
+
88
+ This can be set only if `splitk_support` is 1 in the algorithm capabilities."""
89
+ return self.config_ifc.splitk_num
90
+
91
+ @split_k.setter
92
+ def split_k(self, number: int) -> None:
93
+ self.config_ifc.splitk_num = number
94
+
95
+ @property
96
+ def reduction_scheme(self) -> int:
97
+ """The reduction scheme used (see MatmulAlgoConfigAttribute.REDUCTION_SCHEME).
98
+
99
+ The value provided must be consistent with the `reduction_scheme_mask` in the
100
+ algorithm capabilities."""
101
+ return self.config_ifc.reduction_scheme
102
+
103
+ @reduction_scheme.setter
104
+ def reduction_scheme(self, scheme_id: int) -> None:
105
+ self.config_ifc.reduction_scheme = scheme_id
106
+
107
+ @property
108
+ def cta_swizzling(self) -> bool:
109
+ """A flag indicating CTA swizzling (see MatmulAlgoConfigAttribute.CTA_SWIZZLING).
110
+
111
+ This can be set only if `cta_swizzling` is 1 in the algorithm capabilities."""
112
+ return self.config_ifc.cta_swizzling
113
+
114
+ @cta_swizzling.setter
115
+ def cta_swizzling(self, flag: bool) -> None:
116
+ self.config_ifc.cta_swizzling = flag
117
+
118
+ @property
119
+ def custom_option(self) -> int:
120
+ """A value indicating the custom option (see
121
+ MatmulAlgoConfigAttribute.CUSTOM_OPTION).
122
+
123
+ The value provided must be less than `custom_option_max` in the algorithm
124
+ capabilities."""
125
+ return self.config_ifc.custom_option
126
+
127
+ @custom_option.setter
128
+ def custom_option(self, value: int) -> None:
129
+ self.config_ifc.custom_option = value
130
+
131
+ @property
132
+ def inner_shape(self) -> int:
133
+ """A value indicating the inner shape (see
134
+ MatmulAlgoConfigAttribute.INNER_SHAPE_ID)."""
135
+ return self.config_ifc.inner_shape_id
136
+
137
+ @inner_shape.setter
138
+ def inner_shape(self, shape: int) -> None:
139
+ self.config_ifc.inner_shape_id = shape
140
+
141
+ @property
142
+ def cluster_shape(self) -> tuple[int | str, ...] | str:
143
+ """A tuple representing the cluster shape (see
144
+ MatmulAlgoConfigAttribute.CLUSTER_SHAPE_ID).
145
+
146
+ The value provided must be one of the `cluster_shape_ids` in the algorithm
147
+ capabilities."""
148
+ return ENUM_TO_CLUSTER_SHAPE[self.config_ifc.cluster_shape_id]
149
+
150
+ @cluster_shape.setter
151
+ def cluster_shape(self, shape: tuple[int | str, ...] | str) -> None:
152
+ self.config_ifc.cluster_shape_id = CLUSTER_SHAPE_TO_ENUM[shape]
153
+
154
+ def as_numpy(self) -> npt.NDArray:
155
+ """Return a copy of this `Algorithm` as a NumPy array.
156
+
157
+ Converts the `Algorithm` to a NumPy array of type `matmul_heuristic_result_dtype`
158
+ which may then be saved to disk using ``np.save(..., allow_pickle=False)``.
159
+ """
160
+ return np.frombuffer(buffer=bytes(memoryview(self.algorithm)), dtype=matmul_heuristic_result_dtype) # type: ignore
161
+
162
+ @classmethod
163
+ def from_numpy(cls, array: npt.NDArray) -> "Algorithm":
164
+ """Create an `Algorithm` from a NumPy array.
165
+
166
+ Creates an `Algorithm` by copying a NumPy array of type
167
+ `matmul_heuristic_result_dtype`. The array must be of size 1, and may have been
168
+ loaded from disk using ``np.load(..., allow_pickle=False)``.
169
+ """
170
+ return Algorithm(MatmulHeuristicResult.from_data(np.copy(array)))
@@ -0,0 +1,351 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = [
6
+ "MatmulEpilog",
7
+ "MatmulInnerShape",
8
+ "MatmulNumericalImplFlags",
9
+ "MatmulOptions",
10
+ "MatmulEpilogPreferences",
11
+ "MatmulPlanPreferences",
12
+ "MatmulQuantizationScales",
13
+ "MatmulReductionScheme",
14
+ "matrix_qualifiers_dtype",
15
+ ]
16
+
17
+ import dataclasses
18
+ from enum import IntEnum
19
+ from logging import Logger
20
+ from typing import Literal
21
+
22
+ import numpy as _np
23
+
24
+ from nvmath._utils import CudaDataType
25
+ from nvmath.bindings import cublas # type: ignore
26
+ from nvmath.bindings import cublasLt as cublaslt # type: ignore
27
+ from nvmath.internal import enum_utils
28
+ from nvmath.internal.mem_limit import check_memory_str
29
+ from nvmath.internal.tensor_ifc import AnyTensor
30
+ from nvmath.internal.utils import check_or_create_options
31
+ from nvmath.memory import BaseCUDAMemoryManager, BaseCUDAMemoryManagerAsync
32
+
33
+ MatmulEpilog = cublaslt.Epilogue
34
+ MatmulInnerShape = cublaslt.MatmulInnerShape
35
+ MatmulReductionScheme = cublaslt.ReductionScheme
36
+
37
+
38
+ @dataclasses.dataclass
39
+ class MatmulOptions:
40
+ """A data class for providing options to the :class:`Matmul` object and the wrapper
41
+ function :func:`matmul`.
42
+
43
+ Attributes:
44
+ inplace: Whether the matrix multiplication is performed in-place (operand C is
45
+ overwritten); ``inplace=True`` implies that operand C cannot be broadcast (in
46
+ the batch as well as the N-dimension) since it must be large enough to
47
+ hold the result of the computation. The default is ``inplace=False``.
48
+
49
+ .. experimental:: attribute
50
+
51
+ compute_type (nvmath.linalg.ComputeType): CUDA compute type. A suitable compute type
52
+ will be selected if not specified.
53
+
54
+ scale_type (nvmath.CudaDataType): CUDA data type. A suitable data type consistent
55
+ with the compute type will be selected if not specified.
56
+
57
+ result_type (nvmath.CudaDataType): CUDA data type. A requested datatype of the
58
+ result. If not specified, this type will be determined based on the input types.
59
+ Non-default result types are only supported for narrow-precision (FP8 and lower)
60
+ operations.
61
+
62
+ result_amax (bool): If set, the absolute maximum (amax) of the result will be
63
+ returned in the auxiliary output tensor. Only supported for narrow-precision
64
+ (FP8 and lower) operations.
65
+
66
+ block_scaling (bool): If set, block scaling (MXFP8) will be used instead of
67
+ tensor-wide scaling for FP8 operations. If the result is a narrow-precision
68
+ (FP8 and lower) data type, scales used for result quantization will be returned
69
+ in the auxiliary output tensor as ``"d_out_scale"`` in UE8M0 format. For more
70
+ information on UE8M0 format, see the documentation of
71
+ :class:`~nvmath.linalg.advanced.MatmulQuantizationScales`.
72
+ This option is only supported for narrow-precision (FP8 and lower) operations.
73
+
74
+ sm_count_target (int) : The number of SMs to use for execution. The default is 0,
75
+ corresponding to all available SMs.
76
+
77
+ fast_accumulation (bool) : Enable or disable FP8 fast accumulation mode. The default
78
+ is False (disabled).
79
+
80
+ device_id: CUDA device ordinal (only used if the operand resides on the CPU). The
81
+ default value is 0.
82
+
83
+ handle: Linear algebra library handle. A handle will be created if one is not
84
+ provided.
85
+
86
+ logger (logging.Logger): Python Logger object. The root logger will be used if a
87
+ logger object is not provided.
88
+
89
+ memory_limit: Maximum memory available to the MM operation. It can be specified as a
90
+ value (with optional suffix like K[iB], M[iB], G[iB]) or as a percentage. The
91
+ default is 80% of the device memory.
92
+
93
+ blocking: A flag specifying the behavior of the execution functions and methods,
94
+ such as :func:`matmul` and :meth:`Matmul.execute`. When ``blocking`` is `True`,
95
+ the execution methods do not return until the operation is complete. When
96
+ ``blocking`` is ``"auto"``, the methods return immediately when the inputs are
97
+ on the GPU. The execution methods always block when the operands are on the CPU
98
+ to ensure that the user doesn't inadvertently use the result before it becomes
99
+ available. The default is ``"auto"``.
100
+
101
+ allocator: An object that supports the :class:`BaseCUDAMemoryManager` protocol, used
102
+ to draw device memory. If an allocator is not provided, a memory allocator from
103
+ the library package will be used (:func:`torch.cuda.caching_allocator_alloc` for
104
+ PyTorch operands, :func:`cupy.cuda.alloc` otherwise).
105
+
106
+ .. seealso::
107
+ :class:`Matmul`, :func:`matmul`
108
+ """
109
+
110
+ inplace: bool = False
111
+ compute_type: int | None = None
112
+ scale_type: int | None = None
113
+ result_type: int | None = None
114
+ result_amax: bool = False
115
+ block_scaling: bool = False
116
+ sm_count_target: int | None = 0
117
+ fast_accumulation: bool | None = False
118
+ device_id: int = 0
119
+ handle: int | None = None
120
+ logger: Logger | None = None
121
+ memory_limit: int | str | None = r"80%"
122
+ blocking: Literal[True, "auto"] = "auto"
123
+ allocator: BaseCUDAMemoryManager | None = None
124
+
125
+ def __post_init__(self):
126
+ # Defer computing the memory limit till we know the device the network is on.
127
+
128
+ if self.compute_type is not None:
129
+ self.compute_type = cublas.ComputeType(self.compute_type)
130
+
131
+ if self.scale_type is not None:
132
+ self.scale_type = CudaDataType(self.scale_type)
133
+
134
+ if self.sm_count_target is None:
135
+ self.sm_count_target = MatmulOptions.sm_count_target
136
+
137
+ if self.fast_accumulation is None:
138
+ self.fast_accumulation = MatmulOptions.fast_accumulation
139
+
140
+ if self.device_id is None:
141
+ self.device_id = 0
142
+
143
+ if self.memory_limit is None:
144
+ self.memory_limit = MatmulOptions.memory_limit
145
+
146
+ check_memory_str(self.memory_limit, "memory limit")
147
+
148
+ if self.blocking not in (True, "auto"):
149
+ raise ValueError("The value specified for blocking must be either True or 'auto'.")
150
+
151
+ if self.allocator is not None and not isinstance(self.allocator, BaseCUDAMemoryManager | BaseCUDAMemoryManagerAsync):
152
+ raise TypeError("The allocator must be an object of type that fulfills the BaseCUDAMemoryManager protocol.")
153
+
154
+
155
+ matrix_qualifiers_dtype = _np.dtype([("structure", object), ("is_conjugate", "<i4")])
156
+
157
+
158
+ class MatmulNumericalImplFlags(IntEnum):
159
+ """
160
+ These flags can be combined with the | operator: OP_TYPE_FMA | OP_TYPE_TENSOR_HMMA ...
161
+ """
162
+
163
+ OP_TYPE_FMA = 0x01 << 0
164
+ OP_TYPE_TENSOR_HMMA = 0x02 << 0
165
+ OP_TYPE_TENSOR_IMMA = 0x04 << 0
166
+ OP_TYPE_TENSOR_DMMA = 0x08 << 0
167
+ OP_TYPE_TENSOR_MASK = 0xFE << 0
168
+ OP_TYPE_MASK = 0xFF << 0
169
+
170
+ ACCUMULATOR_16F = 0x01 << 8
171
+ ACCUMULATOR_32F = 0x02 << 8
172
+ ACCUMULATOR_64F = 0x04 << 8
173
+ ACCUMULATOR_32I = 0x08 << 8
174
+ ACCUMULATOR_TYPE_MASK = 0xFF << 8
175
+
176
+ INPUT_TYPE_16F = 0x01 << 16
177
+ INPUT_TYPE_16BF = 0x02 << 16
178
+ INPUT_TYPE_TF32 = 0x04 << 16
179
+ INPUT_TYPE_32F = 0x08 << 16
180
+ INPUT_TYPE_64F = 0x10 << 16
181
+ INPUT_TYPE_8I = 0x20 << 16
182
+ INPUT_TYPE_8F_E4M3 = 0x40 << 16
183
+ INPUT_TYPE_8F_E5M2 = 0x80 << 16
184
+ INPUT_TYPE_MASK = 0xFF << 16
185
+
186
+ GAUSSIAN = 0x01 << 32
187
+
188
+ ALL = (1 << 64) - 1
189
+
190
+
191
+ @dataclasses.dataclass
192
+ class MatmulEpilogPreferences:
193
+ """A data class for providing epilog options as part of ``preferences`` to the
194
+ :meth:`Matmul.plan` method and the wrapper function :func:`matmul`.
195
+
196
+ Attributes:
197
+ aux_type (nvmath.CudaDataType): The requested datatype of the
198
+ epilog auxiliary output. If not specified, this type will be determined based on
199
+ the input types. Non-default auxiliary output types are only supported for
200
+ narrow-precision operations and certain epilogs. For more details on the
201
+ supported combinations, see ``CUBLASLT_MATMUL_DESC_EPILOGUE_AUX_DATA_TYPE`` in
202
+ cuBLAS documentation. If this option is set to a narrow-precision data type,
203
+ an additional epilog input ``"aux_quantization_scale"`` needs to be specified.
204
+
205
+ aux_amax (bool): If set, the absolute maximum (amax) of the epilog
206
+ auxiliary output will be returned in the auxiliary output tensor.
207
+ Only supported when ``aux_type`` option is set to a narrow-precision
208
+ data type.
209
+
210
+ .. seealso::
211
+ :meth:`Matmul.plan`, :func:`matmul`, :class:`MatmulPlanPreferences`
212
+ """
213
+
214
+ aux_type: int | None = None
215
+ aux_amax: bool = False
216
+
217
+
218
+ @dataclasses.dataclass
219
+ class MatmulPlanPreferences:
220
+ """A data class for providing options to the :meth:`Matmul.plan` method and the
221
+ wrapper function :func:`matmul`.
222
+
223
+ Attributes:
224
+ reduction_scheme_mask (:class:`nvmath.linalg.advanced.MatmulReductionScheme`):
225
+ Enumerators from
226
+ :class:`nvmath.linalg.advanced.MatmulReductionScheme` combined with
227
+ bitwise operator ``|``. The default is all reduction schemes.
228
+
229
+ max_waves_count (float) : The maximum wave count. Selecting a value greater than 0.
230
+ will exclude algorithms with device utilization greater than specified. The
231
+ default is 0.
232
+
233
+ numerical_impl_mask (:class:`nvmath.linalg.advanced.MatmulNumericalImplFlags`):
234
+ Enumerators from
235
+ :class:`nvmath.linalg.advanced.MatmulNumericalImplFlags` combined with
236
+ bitwise operator ``|``. The default is all numerical implementation flag
237
+ choices.
238
+
239
+ limit (int) : The number of algorithms to consider. If not specified, a suitable
240
+ default will be chosen.
241
+
242
+ epilog (:class:`nvmath.linalg.advanced.MatmulEpilogPreferences`):
243
+ Epilog preferences (as an object of class
244
+ :class:`~nvmath.linalg.advanced.MatmulEpilogPreferences` or a `dict`).
245
+
246
+ .. seealso::
247
+ :meth:`Matmul.plan`, :func:`matmul`
248
+ """
249
+
250
+ reduction_scheme_mask: cublaslt.ReductionScheme | None = cublaslt.ReductionScheme.MASK
251
+ max_waves_count: float | None = 0.0
252
+ numerical_impl_mask: MatmulNumericalImplFlags | None = MatmulNumericalImplFlags.ALL
253
+ limit: int = 8
254
+ epilog: MatmulEpilogPreferences | None = None
255
+
256
+ def __post_init__(self):
257
+ if self.reduction_scheme_mask is None:
258
+ self.reduction_scheme_mask = MatmulPlanPreferences.reduction_scheme_mask
259
+ else:
260
+ self.reduction_scheme_mask = cublaslt.ReductionScheme(self.reduction_scheme_mask)
261
+
262
+ if self.max_waves_count is None:
263
+ self.max_waves_count = MatmulPlanPreferences.max_waves_count
264
+
265
+ if self.numerical_impl_mask is None:
266
+ self.numerical_impl_mask = MatmulPlanPreferences.numerical_impl_mask
267
+
268
+ if self.limit is None:
269
+ self.limit = MatmulPlanPreferences.limit
270
+
271
+ self.epilog = check_or_create_options(MatmulEpilogPreferences, self.epilog, "epilog preferences")
272
+
273
+
274
+ @dataclasses.dataclass
275
+ class MatmulQuantizationScales:
276
+ """A data class for providing quantization_scales to :class:`Matmul` constructor and the
277
+ wrapper function :func:`matmul`.
278
+
279
+ Scales can only be set for narrow-precision (FP8 and lower) matrices.
280
+
281
+ **FP8 operations** (``block_scaling=False``, per-tensor scaling):
282
+
283
+ * Scale format: **scalar** (integer or float) or single-element tensor
284
+ of shape ``()`` or ``(1,)``
285
+ * A single scale value is applied to the entire tensor.
286
+
287
+ **MXFP8 operations** (``block_scaling=True``, microscaling with FP8 operands):
288
+
289
+ * Scale format: **1D tensor** with layout matching cuBLAS MXFP8 requirements
290
+ * Scale dtype: ``uint8`` (interpreted as UE8M0 values by cuBLAS)
291
+ * A scale value :math:`x` causes cuBLAS to multiply the respective
292
+ block by :math:`2^{x-127}`.
293
+
294
+ **NVFP4 operations** (``block_scaling=True``, block scaling with FP4 operands):
295
+
296
+ * Scale format: **1D tensor** with layout matching cuBLAS NVFP4 requirements
297
+ * Scale dtype: ``float8_e4m3fn`` (interpreted by cuBLAS as unsigned UE4M3 values,
298
+ i.e. the bit sign is ignored).
299
+ * FP4 only supports block scaling; ``block_scaling=False`` is not supported for FP4.
300
+
301
+ .. note::
302
+ MXFP8 and NVFP4 use "block scaling" where each block of elements has its own
303
+ scale factor, as opposed to FP8 which uses a single per-tensor scale.
304
+ When ``block_scaling=True``, tensor scales are required; scalar
305
+ scales are not allowed.
306
+
307
+ .. note::
308
+ When scales are provided as tensors, they must be from the same package
309
+ and on the same memory space (CPU or GPU device) as the operands of the matmul.
310
+
311
+ Attributes:
312
+ a (int, float, or Tensor) : Scale for matrix A.
313
+
314
+ b (int, float, or Tensor) : Scale for matrix B.
315
+
316
+ c (int, float, or Tensor) : Scale for matrix C.
317
+
318
+ d (int, float, or Tensor) : Scale for matrix D.
319
+
320
+ .. seealso::
321
+ :class:`Matmul`, :func:`matmul`
322
+ """
323
+
324
+ a: int | float | AnyTensor | None = None
325
+ b: int | float | AnyTensor | None = None
326
+ c: int | float | AnyTensor | None = None
327
+ d: int | float | AnyTensor | None = None
328
+
329
+
330
+ _create_options = enum_utils.create_options_class_from_enum
331
+ _algo_cap_enum = cublaslt.MatmulAlgoCapAttribute
332
+ _get_dtype = cublaslt.get_matmul_algo_cap_attribute_dtype
333
+
334
+ AlgorithmCapabilities = _create_options(
335
+ "AlgorithmCapabilities", _algo_cap_enum, _get_dtype, "algorithm capabilities", "(?P<option_name>.*)"
336
+ )
337
+
338
+
339
+ def algorithm_capabilities_str(self):
340
+ names = [field.name for field in dataclasses.fields(self)]
341
+ width = max(len(n) for n in names)
342
+ s = """Algorithm Capabilities (refer to `MatmulAlgoCapAttribute` for documentation):
343
+ """
344
+ for name in names:
345
+ s += f" {name:{width}} = {getattr(self, name)}\n"
346
+ return s
347
+
348
+
349
+ AlgorithmCapabilities.__str__ = algorithm_capabilities_str
350
+
351
+ del _create_options, _algo_cap_enum, _get_dtype
@@ -0,0 +1,5 @@
1
+ # Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from . import matmul as matmul # noqa: F403