nvmath-python 0.5.0__cp313-cp313-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.
- nvmath/__init__.pxd +0 -0
- nvmath/__init__.py +37 -0
- nvmath/_internal/__init__.py +0 -0
- nvmath/_internal/layout.py +58 -0
- nvmath/_utils.py +363 -0
- nvmath/bindings/__init__.pxd +0 -0
- nvmath/bindings/__init__.py +44 -0
- nvmath/bindings/_internal/__init__.pxd +0 -0
- nvmath/bindings/_internal/__init__.py +0 -0
- nvmath/bindings/_internal/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublas.pxd +518 -0
- nvmath/bindings/_internal/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublasLt.pxd +54 -0
- nvmath/bindings/_internal/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cudss.pxd +44 -0
- nvmath/bindings/_internal/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cufft.pxd +69 -0
- nvmath/bindings/_internal/cufftMp.pxd +77 -0
- nvmath/bindings/_internal/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/curand.pxd +42 -0
- nvmath/bindings/_internal/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolver.pxd +15 -0
- nvmath/bindings/_internal/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverDn.pxd +386 -0
- nvmath/bindings/_internal/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparse.pxd +270 -0
- nvmath/bindings/_internal/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/mathdx.pxd +79 -0
- nvmath/bindings/_internal/nvshmem.pxd +29 -0
- nvmath/bindings/_internal/utils.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/utils.pxd +186 -0
- nvmath/bindings/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublas.pxd +545 -0
- nvmath/bindings/cublas.pyi +18 -0
- nvmath/bindings/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublasLt.pxd +99 -0
- nvmath/bindings/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cudss.pxd +83 -0
- nvmath/bindings/cudss.pyi +249 -0
- nvmath/bindings/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cufft.pxd +114 -0
- nvmath/bindings/cufftMp.pxd +124 -0
- nvmath/bindings/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/curand.pxd +71 -0
- nvmath/bindings/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolver.pxd +60 -0
- nvmath/bindings/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverDn.pxd +410 -0
- nvmath/bindings/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusparse.pxd +329 -0
- nvmath/bindings/cycublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublas.pxd +657 -0
- nvmath/bindings/cycublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublasLt.pxd +1010 -0
- nvmath/bindings/cycudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycudss.pxd +191 -0
- nvmath/bindings/cycufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycufft.pxd +320 -0
- nvmath/bindings/cycufftMp.pxd +333 -0
- nvmath/bindings/cycurand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycurand.pxd +146 -0
- nvmath/bindings/cycusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolver.pxd +143 -0
- nvmath/bindings/cycusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverDn.pxd +414 -0
- nvmath/bindings/cycusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparse.pxd +476 -0
- nvmath/bindings/cymathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cymathdx.pxd +363 -0
- nvmath/bindings/cynvshmem.pxd +126 -0
- nvmath/bindings/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/mathdx.pxd +131 -0
- nvmath/bindings/mathdx.pyi +686 -0
- nvmath/bindings/nvpl/__init__.pxd +0 -0
- nvmath/bindings/nvpl/__init__.py +11 -0
- nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
- nvmath/bindings/nvpl/_internal/__init__.py +0 -0
- nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
- nvmath/bindings/nvpl/cyfft.pxd +87 -0
- nvmath/bindings/nvpl/fft.pxd +100 -0
- nvmath/bindings/nvshmem.pxd +54 -0
- nvmath/device/__init__.py +23 -0
- nvmath/device/_deprecated.py +33 -0
- nvmath/device/caching.py +51 -0
- nvmath/device/common.py +131 -0
- nvmath/device/common_backend.py +125 -0
- nvmath/device/common_cuda.py +156 -0
- nvmath/device/common_mathdx.py +97 -0
- nvmath/device/common_numba.py +159 -0
- nvmath/device/common_opaque_tensor.py +128 -0
- nvmath/device/cublasdx.py +1085 -0
- nvmath/device/cublasdx_backend.py +552 -0
- nvmath/device/cublasdx_numba.py +528 -0
- nvmath/device/cufftdx.py +551 -0
- nvmath/device/cufftdx_backend.py +194 -0
- nvmath/device/cufftdx_numba.py +123 -0
- nvmath/device/curand_kernel.py +9147 -0
- nvmath/device/nvrtc.py +95 -0
- nvmath/device/patch.py +35 -0
- nvmath/device/random.py +417 -0
- nvmath/device/random_helpers.py +23 -0
- nvmath/device/random_states.py +189 -0
- nvmath/device/types.py +11 -0
- nvmath/device/vector_types_numba.py +203 -0
- nvmath/distributed/__init__.py +117 -0
- nvmath/distributed/_internal/__init__.py +0 -0
- nvmath/distributed/_internal/nvshmem.py +243 -0
- nvmath/distributed/_internal/tensor_ifc_cupy.py +111 -0
- nvmath/distributed/_internal/tensor_ifc_numpy.py +53 -0
- nvmath/distributed/_internal/tensor_ifc_torch.py +108 -0
- nvmath/distributed/_internal/tensor_wrapper.py +59 -0
- nvmath/distributed/_utils.py +152 -0
- nvmath/distributed/fft/__init__.py +6 -0
- nvmath/distributed/fft/_configuration.py +86 -0
- nvmath/distributed/fft/fft.py +1737 -0
- nvmath/distributed/reshape/__init__.py +6 -0
- nvmath/distributed/reshape/_configuration.py +39 -0
- nvmath/distributed/reshape/reshape.py +1249 -0
- nvmath/fft/__init__.py +7 -0
- nvmath/fft/_configuration.py +208 -0
- nvmath/fft/_exec_utils.py +116 -0
- nvmath/fft/_helpers.py +260 -0
- nvmath/fft/fft.py +2346 -0
- nvmath/internal/__init__.py +5 -0
- nvmath/internal/enum_utils.py +142 -0
- nvmath/internal/formatters.py +87 -0
- nvmath/internal/mem_limit.py +51 -0
- nvmath/internal/package_ifc.py +119 -0
- nvmath/internal/package_ifc_cuda.py +43 -0
- nvmath/internal/package_ifc_cupy.py +49 -0
- nvmath/internal/package_ifc_torch.py +31 -0
- nvmath/internal/package_wrapper.py +14 -0
- nvmath/internal/tensor_ifc.py +143 -0
- nvmath/internal/tensor_ifc_cupy.py +185 -0
- nvmath/internal/tensor_ifc_numpy.py +157 -0
- nvmath/internal/tensor_ifc_torch.py +115 -0
- nvmath/internal/tensor_wrapper.py +160 -0
- nvmath/internal/typemaps.py +154 -0
- nvmath/internal/utils.py +634 -0
- nvmath/linalg/__init__.py +11 -0
- nvmath/linalg/_internal/__init__.py +3 -0
- nvmath/linalg/_internal/algo_cap_ifc.py +86 -0
- nvmath/linalg/_internal/algo_config_ifc.py +87 -0
- nvmath/linalg/_internal/enum_to_tuples.py +64 -0
- nvmath/linalg/_internal/epilog_protocol.py +738 -0
- nvmath/linalg/_internal/matmul_desc_ifc.py +72 -0
- nvmath/linalg/_internal/matmul_pref_ifc.py +65 -0
- nvmath/linalg/_internal/matrix_layout_ifc.py +59 -0
- nvmath/linalg/_internal/typemaps.py +135 -0
- nvmath/linalg/_internal/utils.py +96 -0
- nvmath/linalg/advanced/__init__.py +8 -0
- nvmath/linalg/advanced/_algorithmmod.py +142 -0
- nvmath/linalg/advanced/_configuration.py +320 -0
- nvmath/linalg/advanced/helpers/__init__.py +5 -0
- nvmath/linalg/advanced/helpers/matmul.py +173 -0
- nvmath/linalg/advanced/matmulmod.py +2855 -0
- nvmath/memory.py +266 -0
- nvmath/sparse/__init__.py +18 -0
- nvmath/sparse/_internal/__init__.py +21 -0
- nvmath/sparse/_internal/common_utils.py +81 -0
- nvmath/sparse/_internal/cudss_config_ifc.py +584 -0
- nvmath/sparse/_internal/cudss_data_ifc.py +291 -0
- nvmath/sparse/_internal/cudss_utils.py +398 -0
- nvmath/sparse/_internal/sparse_csr_ifc.py +154 -0
- nvmath/sparse/_internal/sparse_format_helpers.py +88 -0
- nvmath/sparse/_internal/sparse_tensor_ifc.py +80 -0
- nvmath/sparse/advanced/__init__.py +7 -0
- nvmath/sparse/advanced/_configuration.py +150 -0
- nvmath/sparse/advanced/direct_solver.py +1705 -0
- nvmath_python-0.5.0.dist-info/METADATA +122 -0
- nvmath_python-0.5.0.dist-info/RECORD +174 -0
- nvmath_python-0.5.0.dist-info/WHEEL +5 -0
- nvmath_python-0.5.0.dist-info/licenses/LICENSE +177 -0
- nvmath_python-0.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
__all__ = ["LeadingDimension", "TransposeMode", "Arrangement"]
|
|
6
|
+
|
|
7
|
+
from collections import namedtuple
|
|
8
|
+
from functools import lru_cache
|
|
9
|
+
from typing import NamedTuple, Protocol
|
|
10
|
+
from collections.abc import Sequence
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from .common import check_in, check_code_type
|
|
16
|
+
from .common_backend import (
|
|
17
|
+
EXECUTION_STR_TO_MATHDX,
|
|
18
|
+
NP_TYPES_TO_MATHDX_PRECISION,
|
|
19
|
+
NVARG_GEN_OPT_LTO,
|
|
20
|
+
build_get_int_traits,
|
|
21
|
+
build_get_str_trait,
|
|
22
|
+
)
|
|
23
|
+
from .common_cuda import CodeType, Dim3, ComputeCapability, ISAVersion
|
|
24
|
+
from .common_backend import DescriptorWrapper
|
|
25
|
+
from .types import REAL_NP_TYPES, INT_NP_TYPES
|
|
26
|
+
|
|
27
|
+
from nvmath.bindings import mathdx
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
_BLAS_API_STR_TO_MATHDX = {
|
|
31
|
+
"static_leading_dimensions": mathdx.CublasdxApi.SMEM,
|
|
32
|
+
"dynamic_leading_dimensions": mathdx.CublasdxApi.SMEM_DYNAMIC_LD,
|
|
33
|
+
"tensors": mathdx.CublasdxApi.TENSORS,
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
_BLAS_ARRENGEMENT_STR_TO_MATHDX = {a.name.lower(): a for a in mathdx.CublasdxArrangement}
|
|
37
|
+
|
|
38
|
+
_BLAS_TYPE_STR_TO_MATHDX = {t.name.lower(): t for t in mathdx.CublasdxType}
|
|
39
|
+
|
|
40
|
+
_BLAS_TRANSPOSE_STR_TO_MATHDX = {tm.name.lower(): tm for tm in mathdx.CublasdxTransposeMode}
|
|
41
|
+
|
|
42
|
+
_BLAS_FUNCTION_STR_TO_MATHDX = {
|
|
43
|
+
"MM": mathdx.CublasdxFunction.MM,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_TENSOR_TYPE_STR_TO_MATHDX = {t.name.lower(): t for t in mathdx.CublasdxTensorType}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class LeadingDimension(namedtuple("LeadingDimension", ["a", "b", "c"])):
|
|
50
|
+
"""
|
|
51
|
+
A namedtuple class that encapsulates the three leading dimensions in matrix
|
|
52
|
+
multiplication :math:`C = \\alpha Op(A) Op(B) + \\beta C`.
|
|
53
|
+
|
|
54
|
+
Attributes:
|
|
55
|
+
a (int): The leading dimension of two-dimensional array used to store the matrix
|
|
56
|
+
``A``.
|
|
57
|
+
|
|
58
|
+
b (int): The leading dimension of two-dimensional array used to store the matrix
|
|
59
|
+
``B``.
|
|
60
|
+
|
|
61
|
+
c (int): The leading dimension of two-dimensional array used to store the matrix
|
|
62
|
+
``C``.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class TransposeMode(namedtuple("TransposeMode", ["a", "b"])):
|
|
69
|
+
"""
|
|
70
|
+
A namedtuple class that encapsulates the transpose mode for input matrices ``A`` and
|
|
71
|
+
``B`` in matrix multiplication.
|
|
72
|
+
|
|
73
|
+
Attributes:
|
|
74
|
+
a: The operation that needs to be performed with input matrix ``A``, currently
|
|
75
|
+
supports ``'non_transposed'``, ``'transposed'`` and ``'conj_transposed'``.
|
|
76
|
+
|
|
77
|
+
b: The operation that needs to be performed with input matrix ``B``, currently
|
|
78
|
+
supports ``'non_transposed'``, ``'transposed'`` and ``'conj_transposed'``.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class Arrangement(NamedTuple):
|
|
85
|
+
"""
|
|
86
|
+
A namedtuple class that encapsulates the three arrangements in matrix allocation.
|
|
87
|
+
|
|
88
|
+
Attributes:
|
|
89
|
+
a (str): The arrangement of two-dimensional array used to store the matrix
|
|
90
|
+
``A``.
|
|
91
|
+
|
|
92
|
+
b (str): The arrangement of two-dimensional array used to store the matrix
|
|
93
|
+
``B``.
|
|
94
|
+
|
|
95
|
+
c (str): The arrangement of two-dimensional array used to store the matrix
|
|
96
|
+
``C``.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
a: str
|
|
100
|
+
b: str
|
|
101
|
+
c: str
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Precision(NamedTuple):
|
|
105
|
+
"""
|
|
106
|
+
A namedtuple class that encapsulates the three precisions in matrix
|
|
107
|
+
multiplication :math:`C = \\alpha Op(A) Op(B) + \\beta C`.
|
|
108
|
+
|
|
109
|
+
Attributes:
|
|
110
|
+
a (type): The precision of two-dimensional array used to store the matrix
|
|
111
|
+
``A``.
|
|
112
|
+
|
|
113
|
+
b (type): The precision of two-dimensional array used to store the matrix
|
|
114
|
+
``B``.
|
|
115
|
+
|
|
116
|
+
c (type): The precision of two-dimensional array used to store the matrix
|
|
117
|
+
``C``.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
a: type[object]
|
|
121
|
+
b: type[object]
|
|
122
|
+
c: type[object]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class Alignment(NamedTuple):
|
|
126
|
+
"""
|
|
127
|
+
A type to encapsulate the memory alignment in bytes of the matrix operands
|
|
128
|
+
A, B, and C.
|
|
129
|
+
|
|
130
|
+
Attributes:
|
|
131
|
+
a (int): The alignment of two-dimensional array used to store the matrix
|
|
132
|
+
``A``.
|
|
133
|
+
|
|
134
|
+
b (int): The alignment of two-dimensional array used to store the matrix
|
|
135
|
+
``B``.
|
|
136
|
+
|
|
137
|
+
c (int): The alignment of two-dimensional array used to store the matrix
|
|
138
|
+
``C``.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
a: int
|
|
142
|
+
b: int
|
|
143
|
+
c: int
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class CublasdxTensors(NamedTuple):
|
|
147
|
+
a: int
|
|
148
|
+
b: int
|
|
149
|
+
c: int
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class CublasdxTensorAPISymbols(NamedTuple):
|
|
153
|
+
copy_a: str
|
|
154
|
+
copy_b: str
|
|
155
|
+
copy_c: str
|
|
156
|
+
copy_c_back: str
|
|
157
|
+
clear_c: str
|
|
158
|
+
axpby: str
|
|
159
|
+
gemm: str
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
MAX_ALIGNMENT = Alignment(16, 16, 16)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class CallableGetIntTraits(Protocol):
|
|
166
|
+
def __call__(self, handle: int, trait_type: mathdx.CublasdxTraitType, size: int) -> tuple: ...
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class CallableGetStrTrait(Protocol):
|
|
170
|
+
def __call__(self, handle: int, trait_type: mathdx.CublasdxTraitType) -> str: ...
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
get_int_traits: CallableGetIntTraits = build_get_int_traits(mathdx.cublasdx_get_trait_int64s)
|
|
174
|
+
|
|
175
|
+
get_str_trait: CallableGetStrTrait = build_get_str_trait(mathdx.cublasdx_get_trait_str_size, mathdx.cublasdx_get_trait_str)
|
|
176
|
+
|
|
177
|
+
get_str_device_trait: CallableGetStrTrait = build_get_str_trait(
|
|
178
|
+
mathdx.cublasdx_get_device_function_trait_str_size, mathdx.cublasdx_get_device_function_trait_str
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def get_tensor_int_traits(tensors: CublasdxTensors, trait: mathdx.CublasdxTensorTrait):
|
|
183
|
+
return (
|
|
184
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.a, trait)),
|
|
185
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.b, trait)),
|
|
186
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.c, trait)),
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
_ACCEPTED_PRECISION = REAL_NP_TYPES + INT_NP_TYPES
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def validate(
|
|
194
|
+
size,
|
|
195
|
+
data_type,
|
|
196
|
+
precision,
|
|
197
|
+
execution,
|
|
198
|
+
transpose_mode,
|
|
199
|
+
arrangement,
|
|
200
|
+
alignment,
|
|
201
|
+
block_dim,
|
|
202
|
+
code_type,
|
|
203
|
+
function,
|
|
204
|
+
leading_dimension,
|
|
205
|
+
static_block_dim,
|
|
206
|
+
):
|
|
207
|
+
(m, n, k) = size
|
|
208
|
+
if m <= 0 or n <= 0 or k <= 0:
|
|
209
|
+
raise ValueError(f"m, n, k must be > 0. Got {m}, {n}, {k}")
|
|
210
|
+
if isinstance(precision, Precision):
|
|
211
|
+
for m in ["a", "b", "c"]:
|
|
212
|
+
check_in(f"precision.{m}", getattr(precision, m), _ACCEPTED_PRECISION)
|
|
213
|
+
else:
|
|
214
|
+
raise ValueError(
|
|
215
|
+
f"precision should be an instance of {Precision} or a 3-sequence, and individual fields "
|
|
216
|
+
f"should be one of {_ACCEPTED_PRECISION}. Instead got precision = {precision}"
|
|
217
|
+
)
|
|
218
|
+
check_in("data_type", data_type, ["real", "complex"])
|
|
219
|
+
check_in("execution", execution, ["Block", "Thread"])
|
|
220
|
+
check_in("function", function, ["MM"])
|
|
221
|
+
check_in("static_block_dim", static_block_dim, [True, False])
|
|
222
|
+
if transpose_mode is not None:
|
|
223
|
+
allowed_values = ["non_transposed", "transposed", "conj_transposed"]
|
|
224
|
+
if isinstance(transpose_mode, TransposeMode):
|
|
225
|
+
check_in("transpose_mode.a", transpose_mode.a, allowed_values)
|
|
226
|
+
check_in("transpose_mode.b", transpose_mode.b, allowed_values)
|
|
227
|
+
else:
|
|
228
|
+
raise ValueError(
|
|
229
|
+
f"transpose_mode should be an instance of {TransposeMode} or a 2-tuple, and individual fields "
|
|
230
|
+
f"should be one of {allowed_values}. Instead got transpose_mode = {transpose_mode}"
|
|
231
|
+
)
|
|
232
|
+
if arrangement is not None:
|
|
233
|
+
allowed_values = _BLAS_ARRENGEMENT_STR_TO_MATHDX.keys()
|
|
234
|
+
if isinstance(arrangement, Arrangement):
|
|
235
|
+
check_in("arrangement.a", arrangement.a, allowed_values)
|
|
236
|
+
check_in("arrangement.b", arrangement.b, allowed_values)
|
|
237
|
+
check_in("arrangement.c", arrangement.c, allowed_values)
|
|
238
|
+
else:
|
|
239
|
+
raise ValueError(
|
|
240
|
+
f"arrangement should be an instance of {Arrangement} or a 3-tuple, and individual fields "
|
|
241
|
+
f"should be one of {allowed_values}. Instead got arrangement = {arrangement}"
|
|
242
|
+
)
|
|
243
|
+
if arrangement is not None and transpose_mode is not None:
|
|
244
|
+
raise ValueError("only arrangement or transpose_mode must be provide. Instead got both")
|
|
245
|
+
if arrangement is None and transpose_mode is None:
|
|
246
|
+
raise ValueError("arrangement or transpose_mode must be provide. Instead got nothing")
|
|
247
|
+
if alignment is not None:
|
|
248
|
+
validate_alignment(alignment, precision, data_type)
|
|
249
|
+
if block_dim in (None, "suggested"):
|
|
250
|
+
pass
|
|
251
|
+
elif isinstance(block_dim, Dim3):
|
|
252
|
+
prod = block_dim[0] * block_dim[1] * block_dim[2]
|
|
253
|
+
if prod <= 0 or prod > 1024:
|
|
254
|
+
raise ValueError(
|
|
255
|
+
f"The product of the entries in block_dim should be between 1 and 1024 ; got block_dim = {block_dim}"
|
|
256
|
+
)
|
|
257
|
+
else:
|
|
258
|
+
raise ValueError(f"block_dim should be None, a Dim3 instance or 'suggested'; got block_dim = {block_dim}")
|
|
259
|
+
if code_type is not None:
|
|
260
|
+
check_code_type(code_type)
|
|
261
|
+
if leading_dimension in (None, "suggested") or isinstance(leading_dimension, LeadingDimension):
|
|
262
|
+
pass
|
|
263
|
+
else:
|
|
264
|
+
raise ValueError(
|
|
265
|
+
f"leading_dimension should be None, a LeadingDimension instance or 'suggested'; "
|
|
266
|
+
f"got leading_dimension = {leading_dimension}"
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def validate_execute_api(execute_api):
|
|
271
|
+
"""
|
|
272
|
+
Validate the execute_api argument.
|
|
273
|
+
"""
|
|
274
|
+
check_in("execute_api", execute_api, _BLAS_API_STR_TO_MATHDX.keys())
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def validate_tensor_types(tensor_types):
|
|
278
|
+
"""
|
|
279
|
+
Validate the tensor_types argument.
|
|
280
|
+
"""
|
|
281
|
+
allowed_values = _TENSOR_TYPE_STR_TO_MATHDX.keys()
|
|
282
|
+
if isinstance(tensor_types, Sequence) and len(tensor_types) == 3:
|
|
283
|
+
check_in("tensor_types[0]", tensor_types[0], allowed_values)
|
|
284
|
+
check_in("tensor_types[1]", tensor_types[1], allowed_values)
|
|
285
|
+
check_in("tensor_types[2]", tensor_types[2], allowed_values)
|
|
286
|
+
else:
|
|
287
|
+
raise ValueError(
|
|
288
|
+
f"tensor_types should be a 3-tuple, and individual fields "
|
|
289
|
+
f"should be one of {allowed_values}. Instead got tensor_types = {tensor_types}"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def validate_alignment(alignment: Alignment, precision: Precision, data_type: str, gmem: bool = False):
|
|
294
|
+
"""
|
|
295
|
+
Validates alignment. precision and data_type must be already validated.
|
|
296
|
+
"""
|
|
297
|
+
name = "alignment" if not gmem else "global_memory_alignment"
|
|
298
|
+
default_a = default_alignment(precision, data_type)
|
|
299
|
+
for m in ["a", "b", "c"]:
|
|
300
|
+
a = getattr(alignment, m)
|
|
301
|
+
max_a = getattr(MAX_ALIGNMENT, m)
|
|
302
|
+
def_a = getattr(default_a, m)
|
|
303
|
+
if a <= 0:
|
|
304
|
+
raise ValueError(f"{name}.{m} must be > 0. Got {a}")
|
|
305
|
+
if a > max_a:
|
|
306
|
+
raise ValueError(f"{name}.{m} must be less than maximum alignment {max_a}. Got {a}")
|
|
307
|
+
if a % def_a != 0:
|
|
308
|
+
raise ValueError(f"{name}.{m} must be a multiple of input value type {def_a}. Got {a}")
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def default_alignment(precision: Precision, data_type: str):
|
|
312
|
+
# supported precision's itemsize is always power of two, so we are safe
|
|
313
|
+
mul = 1 if data_type == "real" else 2
|
|
314
|
+
|
|
315
|
+
alignment = tuple(np.dtype(p).itemsize * mul for p in precision)
|
|
316
|
+
return Alignment(*alignment)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
@lru_cache
|
|
320
|
+
def generate_MM(
|
|
321
|
+
size: tuple[int, int, int],
|
|
322
|
+
precision: Precision,
|
|
323
|
+
data_type: str,
|
|
324
|
+
function: str,
|
|
325
|
+
transpose_mode: TransposeMode | None,
|
|
326
|
+
arrangement: Arrangement | None,
|
|
327
|
+
alignment: Alignment | None,
|
|
328
|
+
code_type: CodeType | None,
|
|
329
|
+
block_dim: Dim3 | None,
|
|
330
|
+
static_block_dim: bool,
|
|
331
|
+
execution: str,
|
|
332
|
+
leading_dimension: LeadingDimension | None,
|
|
333
|
+
execute_api: str | None = None,
|
|
334
|
+
tensor_types: tuple[str, str, str] | None = None,
|
|
335
|
+
):
|
|
336
|
+
"""
|
|
337
|
+
Generate a cuBLASDx descriptor for matrix multiplication.
|
|
338
|
+
|
|
339
|
+
tenosr_types is only used to create cache properly.
|
|
340
|
+
"""
|
|
341
|
+
h = mathdx.cublasdx_create_descriptor()
|
|
342
|
+
|
|
343
|
+
(m, n, k) = size
|
|
344
|
+
|
|
345
|
+
if execute_api is not None:
|
|
346
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.API, _BLAS_API_STR_TO_MATHDX[execute_api])
|
|
347
|
+
|
|
348
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SIZE, 3, [m, n, k])
|
|
349
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
350
|
+
h, mathdx.CublasdxOperatorType.PRECISION, len(precision), [NP_TYPES_TO_MATHDX_PRECISION[p] for p in precision]
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.FUNCTION, _BLAS_FUNCTION_STR_TO_MATHDX[function])
|
|
354
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.EXECUTION, EXECUTION_STR_TO_MATHDX[execution])
|
|
355
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.TYPE, _BLAS_TYPE_STR_TO_MATHDX[data_type])
|
|
356
|
+
|
|
357
|
+
if block_dim:
|
|
358
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.BLOCK_DIM, 3, block_dim)
|
|
359
|
+
|
|
360
|
+
if static_block_dim:
|
|
361
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.STATIC_BLOCK_DIM, 1)
|
|
362
|
+
|
|
363
|
+
if code_type:
|
|
364
|
+
mathdx.cublasdx_set_operator_int64(
|
|
365
|
+
h, mathdx.CublasdxOperatorType.SM, code_type.cc.major * 100 + code_type.cc.minor * 10
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
if leading_dimension:
|
|
369
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
370
|
+
h, mathdx.CublasdxOperatorType.LEADING_DIMENSION, 3, [leading_dimension.a, leading_dimension.b, leading_dimension.c]
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
if transpose_mode:
|
|
374
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
375
|
+
h,
|
|
376
|
+
mathdx.CublasdxOperatorType.TRANSPOSE_MODE,
|
|
377
|
+
2,
|
|
378
|
+
[_BLAS_TRANSPOSE_STR_TO_MATHDX[transpose_mode.a], _BLAS_TRANSPOSE_STR_TO_MATHDX[transpose_mode.b]],
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
if arrangement:
|
|
382
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
383
|
+
h,
|
|
384
|
+
mathdx.CublasdxOperatorType.ARRANGEMENT,
|
|
385
|
+
3,
|
|
386
|
+
[_BLAS_ARRENGEMENT_STR_TO_MATHDX[a] for a in arrangement],
|
|
387
|
+
)
|
|
388
|
+
|
|
389
|
+
if alignment:
|
|
390
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
391
|
+
h,
|
|
392
|
+
mathdx.CublasdxOperatorType.ALIGNMENT,
|
|
393
|
+
3,
|
|
394
|
+
alignment,
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
return DescriptorWrapper(h, mathdx.cublasdx_destroy_descriptor)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
@lru_cache
|
|
401
|
+
def generate_code(handle, version: ComputeCapability, device_functions: tuple | None = None):
|
|
402
|
+
code = mathdx.commondx_create_code()
|
|
403
|
+
|
|
404
|
+
mathdx.commondx_set_code_option_int64(
|
|
405
|
+
code,
|
|
406
|
+
mathdx.CommondxOption.TARGET_SM,
|
|
407
|
+
version.integer,
|
|
408
|
+
)
|
|
409
|
+
mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVTRC_ARGS, NVARG_GEN_OPT_LTO)
|
|
410
|
+
if device_functions:
|
|
411
|
+
mathdx.cublasdx_finalize_device_functions(code, len(device_functions), list(device_functions))
|
|
412
|
+
else:
|
|
413
|
+
mathdx.cublasdx_finalize_code(code, handle)
|
|
414
|
+
|
|
415
|
+
return DescriptorWrapper(code, mathdx.commondx_destroy_code)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
@lru_cache
|
|
419
|
+
def generate_tensors(h, tensor_types, gmem_alignment: Alignment | None = None):
|
|
420
|
+
type_mem_a = mathdx.cublasdx_bind_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[0]])
|
|
421
|
+
type_mem_b = mathdx.cublasdx_bind_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[1]])
|
|
422
|
+
type_mem_c = mathdx.cublasdx_bind_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[2]])
|
|
423
|
+
|
|
424
|
+
gmem_a = mathdx.cublasdx_bind_tensor(h, mathdx.CublasdxTensorType.GMEM_A)
|
|
425
|
+
gmem_b = mathdx.cublasdx_bind_tensor(h, mathdx.CublasdxTensorType.GMEM_B)
|
|
426
|
+
gmem_c = mathdx.cublasdx_bind_tensor(h, mathdx.CublasdxTensorType.GMEM_C)
|
|
427
|
+
|
|
428
|
+
if gmem_alignment:
|
|
429
|
+
mathdx.cublasdx_set_tensor_option_int64(
|
|
430
|
+
gmem_a,
|
|
431
|
+
mathdx.CublasdxTensorOption.ALIGNMENT_BYTES,
|
|
432
|
+
gmem_alignment.a,
|
|
433
|
+
)
|
|
434
|
+
mathdx.cublasdx_set_tensor_option_int64(
|
|
435
|
+
gmem_b,
|
|
436
|
+
mathdx.CublasdxTensorOption.ALIGNMENT_BYTES,
|
|
437
|
+
gmem_alignment.b,
|
|
438
|
+
)
|
|
439
|
+
mathdx.cublasdx_set_tensor_option_int64(
|
|
440
|
+
gmem_c,
|
|
441
|
+
mathdx.CublasdxTensorOption.ALIGNMENT_BYTES,
|
|
442
|
+
gmem_alignment.c,
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
tensors = [
|
|
446
|
+
type_mem_a,
|
|
447
|
+
type_mem_b,
|
|
448
|
+
type_mem_c,
|
|
449
|
+
gmem_a,
|
|
450
|
+
gmem_b,
|
|
451
|
+
gmem_c,
|
|
452
|
+
]
|
|
453
|
+
|
|
454
|
+
mathdx.cublasdx_finalize_tensors(h, len(tensors), tensors)
|
|
455
|
+
|
|
456
|
+
target_tensors = CublasdxTensors(type_mem_a, type_mem_b, type_mem_c)
|
|
457
|
+
gmem_tensors = CublasdxTensors(gmem_a, gmem_b, gmem_c)
|
|
458
|
+
|
|
459
|
+
return gmem_tensors, target_tensors
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
@lru_cache
|
|
463
|
+
def generate_code_tensors(
|
|
464
|
+
handle,
|
|
465
|
+
version: ISAVersion,
|
|
466
|
+
gmem_tensors: CublasdxTensors,
|
|
467
|
+
target_tensors: CublasdxTensors,
|
|
468
|
+
rmem_c: bool = False,
|
|
469
|
+
):
|
|
470
|
+
copy_a = mathdx.cublasdx_bind_device_function(
|
|
471
|
+
handle, mathdx.CublasdxDeviceFunctionType.COPY, 2, [gmem_tensors.a, target_tensors.a]
|
|
472
|
+
)
|
|
473
|
+
copy_b = mathdx.cublasdx_bind_device_function(
|
|
474
|
+
handle, mathdx.CublasdxDeviceFunctionType.COPY, 2, [gmem_tensors.b, target_tensors.b]
|
|
475
|
+
)
|
|
476
|
+
copy_c = mathdx.cublasdx_bind_device_function(
|
|
477
|
+
handle, mathdx.CublasdxDeviceFunctionType.COPY, 2, [gmem_tensors.c, target_tensors.c]
|
|
478
|
+
)
|
|
479
|
+
copy_c_back = mathdx.cublasdx_bind_device_function(
|
|
480
|
+
handle, mathdx.CublasdxDeviceFunctionType.COPY, 2, [target_tensors.c, gmem_tensors.c]
|
|
481
|
+
)
|
|
482
|
+
if rmem_c:
|
|
483
|
+
clear_c_fn = mathdx.cublasdx_bind_device_function(
|
|
484
|
+
handle, mathdx.CublasdxDeviceFunctionType.CLEAR, 1, [target_tensors.c]
|
|
485
|
+
)
|
|
486
|
+
axpby_fn = mathdx.cublasdx_bind_device_function(
|
|
487
|
+
handle, mathdx.CublasdxDeviceFunctionType.AXPBY, 2, [target_tensors.c, target_tensors.c]
|
|
488
|
+
)
|
|
489
|
+
gemm = mathdx.cublasdx_bind_device_function(
|
|
490
|
+
handle, mathdx.CublasdxDeviceFunctionType.EXECUTE, 3, [target_tensors.a, target_tensors.b, target_tensors.c]
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
clear_c_sym = get_str_device_trait(clear_c_fn, mathdx.CublasdxDeviceFunctionTrait.SYMBOL) if rmem_c else ""
|
|
494
|
+
axpby_sm = get_str_device_trait(axpby_fn, mathdx.CublasdxDeviceFunctionTrait.SYMBOL) if rmem_c else ""
|
|
495
|
+
|
|
496
|
+
tensor_symbols = CublasdxTensorAPISymbols(
|
|
497
|
+
get_str_device_trait(copy_a, mathdx.CublasdxDeviceFunctionTrait.SYMBOL),
|
|
498
|
+
get_str_device_trait(copy_b, mathdx.CublasdxDeviceFunctionTrait.SYMBOL),
|
|
499
|
+
get_str_device_trait(copy_c, mathdx.CublasdxDeviceFunctionTrait.SYMBOL),
|
|
500
|
+
get_str_device_trait(copy_c_back, mathdx.CublasdxDeviceFunctionTrait.SYMBOL),
|
|
501
|
+
clear_c_sym,
|
|
502
|
+
axpby_sm,
|
|
503
|
+
get_str_device_trait(gemm, mathdx.CublasdxDeviceFunctionTrait.SYMBOL),
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
function_list = [copy_a, copy_b, copy_c, copy_c_back, gemm]
|
|
507
|
+
if rmem_c:
|
|
508
|
+
function_list += [clear_c_fn, axpby_fn]
|
|
509
|
+
|
|
510
|
+
return generate_code(handle, version, tuple(function_list)), tensor_symbols
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def generate_copy_wait_lto(compute_capability: ComputeCapability):
|
|
514
|
+
return generate_device_function_lto(
|
|
515
|
+
compute_capability,
|
|
516
|
+
mathdx.CublasdxDeviceFunctionType.COPY_WAIT,
|
|
517
|
+
(),
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
@lru_cache
|
|
522
|
+
def generate_device_function_lto(compute_capability: ComputeCapability, function_type: mathdx.CublasdxDeviceFunctionType, args):
|
|
523
|
+
arch = compute_capability.integer
|
|
524
|
+
# Create the cuBLASDx descriptor
|
|
525
|
+
h = mathdx.cublasdx_create_descriptor()
|
|
526
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.FUNCTION, mathdx.CublasdxFunction.MM)
|
|
527
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.EXECUTION, mathdx.CommondxExecution.BLOCK)
|
|
528
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.API, mathdx.CublasdxApi.TENSORS)
|
|
529
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.PRECISION, mathdx.CommondxPrecision.F32)
|
|
530
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.SM, arch)
|
|
531
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.TYPE, mathdx.CublasdxType.REAL)
|
|
532
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.BLOCK_DIM, 3, [32, 1, 1])
|
|
533
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SIZE, 3, [1, 1, 1])
|
|
534
|
+
|
|
535
|
+
function = mathdx.cublasdx_bind_device_function(h, function_type, len(args), [*args])
|
|
536
|
+
symbol = get_str_device_trait(function, mathdx.CublasdxDeviceFunctionTrait.SYMBOL)
|
|
537
|
+
|
|
538
|
+
# Compile the device function to lto
|
|
539
|
+
code = mathdx.commondx_create_code()
|
|
540
|
+
mathdx.commondx_set_code_option_int64(code, mathdx.CommondxOption.TARGET_SM, arch)
|
|
541
|
+
mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVTRC_ARGS, NVARG_GEN_OPT_LTO)
|
|
542
|
+
mathdx.cublasdx_finalize_device_functions(code, 1, [function])
|
|
543
|
+
|
|
544
|
+
# Extract the LTOIR
|
|
545
|
+
lto_size = mathdx.commondx_get_code_ltoir_size(code)
|
|
546
|
+
lto = bytearray(lto_size)
|
|
547
|
+
mathdx.commondx_get_code_ltoir(code, lto_size, lto)
|
|
548
|
+
|
|
549
|
+
mathdx.commondx_destroy_code(code)
|
|
550
|
+
mathdx.cublasdx_destroy_descriptor(h)
|
|
551
|
+
|
|
552
|
+
return symbol, bytes(lto)
|