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,72 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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 matmul descriptor attributes.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__ = ["MatmulDescInterface"]
|
|
10
|
+
|
|
11
|
+
import ctypes
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
from nvmath.bindings import cublasLt as cublaslt
|
|
17
|
+
|
|
18
|
+
logger = logging.getLogger()
|
|
19
|
+
|
|
20
|
+
DescEnum = cublaslt.MatmulDescAttribute
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def scalar_attributes():
|
|
24
|
+
return [e.name for e in DescEnum]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESC_ENUM_SCALAR_ATTR = scalar_attributes()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _get_attribute_ctype(name):
|
|
31
|
+
return np.ctypeslib.as_ctypes_type(cublaslt.get_matmul_desc_attribute_dtype(DescEnum[name]))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
DESC_ENUM_SCALAR_ATTR_INFO = {name: (DescEnum[name].value, _get_attribute_ctype(name)) for name in DESC_ENUM_SCALAR_ATTR}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class MatmulDescInterface:
|
|
38
|
+
def __init__(self, matmul_desc):
|
|
39
|
+
""" """
|
|
40
|
+
self.matmul_desc = matmul_desc
|
|
41
|
+
|
|
42
|
+
def __getattr__(self, name):
|
|
43
|
+
_name = name.upper()
|
|
44
|
+
logging.debug("Getting Matmul Description attribute %s.", _name)
|
|
45
|
+
info = DESC_ENUM_SCALAR_ATTR_INFO.get(_name)
|
|
46
|
+
if info is None:
|
|
47
|
+
return super().__getattr__(name)
|
|
48
|
+
enum_value, ctype = info
|
|
49
|
+
name = _name
|
|
50
|
+
attribute_buffer = ctype()
|
|
51
|
+
size_written = ctypes.c_uint64()
|
|
52
|
+
cublaslt.matmul_desc_get_attribute(
|
|
53
|
+
self.matmul_desc,
|
|
54
|
+
enum_value,
|
|
55
|
+
ctypes.addressof(attribute_buffer),
|
|
56
|
+
ctypes.sizeof(attribute_buffer),
|
|
57
|
+
ctypes.addressof(size_written),
|
|
58
|
+
)
|
|
59
|
+
return attribute_buffer.value
|
|
60
|
+
|
|
61
|
+
def __setattr__(self, name, value):
|
|
62
|
+
_name = name.upper()
|
|
63
|
+
logging.debug("Setting Matmul Description attribute %s to %s.", _name, value)
|
|
64
|
+
info = DESC_ENUM_SCALAR_ATTR_INFO.get(_name)
|
|
65
|
+
if info is None:
|
|
66
|
+
return super().__setattr__(name, value)
|
|
67
|
+
enum_value, ctype = info
|
|
68
|
+
name = _name
|
|
69
|
+
ctypes_value = ctype(value)
|
|
70
|
+
cublaslt.matmul_desc_set_attribute(
|
|
71
|
+
self.matmul_desc, enum_value, ctypes.addressof(ctypes_value), ctypes.sizeof(ctypes_value)
|
|
72
|
+
)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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 matmul plan preference
|
|
7
|
+
attributes.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
__all__ = ["MatmulPreferenceInterface"]
|
|
11
|
+
|
|
12
|
+
import logging
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
from nvmath.bindings import cublasLt as cublaslt
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger()
|
|
20
|
+
|
|
21
|
+
PreferenceEnum = cublaslt.MatmulPreferenceAttribute
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def scalar_attributes():
|
|
25
|
+
return [e.name for e in PreferenceEnum]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
PREF_ENUM_SCALAR_ATTR = scalar_attributes()
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MatmulPreferenceInterface:
|
|
32
|
+
def __init__(self, matmul_pref):
|
|
33
|
+
""" """
|
|
34
|
+
self.matmul_pref = matmul_pref
|
|
35
|
+
|
|
36
|
+
def __getattr__(self, name):
|
|
37
|
+
_name = name.upper()
|
|
38
|
+
logging.debug("Getting Matmul Preference attribute %s.", _name)
|
|
39
|
+
if _name not in PREF_ENUM_SCALAR_ATTR:
|
|
40
|
+
return super().__getattr__(name)
|
|
41
|
+
name = _name
|
|
42
|
+
get_dtype = cublaslt.get_matmul_preference_attribute_dtype
|
|
43
|
+
attribute_buffer = np.zeros((1,), dtype=get_dtype(PreferenceEnum[name]))
|
|
44
|
+
size_written = np.zeros((1,), dtype=np.uint64)
|
|
45
|
+
cublaslt.matmul_preference_get_attribute(
|
|
46
|
+
self.matmul_pref,
|
|
47
|
+
PreferenceEnum[name].value,
|
|
48
|
+
attribute_buffer.ctypes.data,
|
|
49
|
+
attribute_buffer.itemsize,
|
|
50
|
+
size_written.ctypes.data,
|
|
51
|
+
)
|
|
52
|
+
return attribute_buffer[0]
|
|
53
|
+
|
|
54
|
+
def __setattr__(self, name, value):
|
|
55
|
+
_name = name.upper()
|
|
56
|
+
logging.debug("Setting Matmul Preference attribute %s to %s.", _name, value)
|
|
57
|
+
if _name not in PREF_ENUM_SCALAR_ATTR:
|
|
58
|
+
return super().__setattr__(name, value)
|
|
59
|
+
name = _name
|
|
60
|
+
get_dtype = cublaslt.get_matmul_preference_attribute_dtype
|
|
61
|
+
attribute_buffer = np.zeros((1,), dtype=get_dtype(PreferenceEnum[name]))
|
|
62
|
+
attribute_buffer[0] = value
|
|
63
|
+
cublaslt.matmul_preference_set_attribute(
|
|
64
|
+
self.matmul_pref, PreferenceEnum[name].value, attribute_buffer.ctypes.data, attribute_buffer.itemsize
|
|
65
|
+
)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
from nvmath.bindings import cublasLt as cublaslt
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
LayoutEnum = cublaslt.MatrixLayoutAttribute
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def scalar_attributes():
|
|
21
|
+
return [e.name for e in LayoutEnum]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
LAYOUT_ENUM_SCALAR_ATTR = scalar_attributes()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MatrixLayoutInterface:
|
|
28
|
+
def __init__(self, matrix_layout):
|
|
29
|
+
""" """
|
|
30
|
+
self.matrix_layout = matrix_layout
|
|
31
|
+
|
|
32
|
+
def __getattr__(self, name):
|
|
33
|
+
_name = name.upper()
|
|
34
|
+
if _name not in LAYOUT_ENUM_SCALAR_ATTR:
|
|
35
|
+
return super().__getattr__(name)
|
|
36
|
+
name = _name
|
|
37
|
+
get_dtype = cublaslt.get_matrix_layout_attribute_dtype
|
|
38
|
+
attribute_buffer = np.zeros((1,), dtype=get_dtype(LayoutEnum[name]))
|
|
39
|
+
size_written = np.zeros((1,), dtype=np.uint64)
|
|
40
|
+
cublaslt.matrix_layout_get_attribute(
|
|
41
|
+
self.matrix_layout,
|
|
42
|
+
LayoutEnum[name].value,
|
|
43
|
+
attribute_buffer.ctypes.data,
|
|
44
|
+
attribute_buffer.itemsize,
|
|
45
|
+
size_written.ctypes.data,
|
|
46
|
+
)
|
|
47
|
+
return attribute_buffer[0]
|
|
48
|
+
|
|
49
|
+
def __setattr__(self, name, value):
|
|
50
|
+
_name = name.upper()
|
|
51
|
+
if _name not in LAYOUT_ENUM_SCALAR_ATTR:
|
|
52
|
+
return super().__setattr__(name, value)
|
|
53
|
+
name = _name
|
|
54
|
+
get_dtype = cublaslt.get_matrix_layout_attribute_dtype
|
|
55
|
+
attribute_buffer = np.zeros((1,), dtype=get_dtype(LayoutEnum[name]))
|
|
56
|
+
attribute_buffer[0] = value
|
|
57
|
+
cublaslt.matrix_layout_set_attribute(
|
|
58
|
+
self.matrix_layout, LayoutEnum[name].value, attribute_buffer.ctypes.data, attribute_buffer.itemsize
|
|
59
|
+
)
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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
|
+
scale_type_map["float8_e4m3fn", "float8_e5m2"] = dt.CUDA_R_32F
|
|
31
|
+
scale_type_map["float8_e5m2", "float8_e4m3fn"] = dt.CUDA_R_32F
|
|
32
|
+
scale_type_map["float8_e4m3fn", "float8_e4m3fn"] = dt.CUDA_R_32F
|
|
33
|
+
scale_type_map["bfloat16", "bfloat16"] = dt.CUDA_R_32F
|
|
34
|
+
scale_type_map["float16", "float16"] = dt.CUDA_R_32F
|
|
35
|
+
scale_type_map["float32", "float32"] = dt.CUDA_R_32F
|
|
36
|
+
scale_type_map["float64", "float64"] = dt.CUDA_R_64F
|
|
37
|
+
scale_type_map["complex32", "complex32"] = dt.CUDA_C_32F
|
|
38
|
+
scale_type_map["complex64", "complex64"] = dt.CUDA_C_32F
|
|
39
|
+
scale_type_map["complex128", "complex128"] = dt.CUDA_C_64F
|
|
40
|
+
|
|
41
|
+
return scale_type_map
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def create_compute_type_to_scale_type_map(is_complex):
|
|
45
|
+
"""
|
|
46
|
+
Map the compute type to the corresponding CUDA data type that's appropriate for
|
|
47
|
+
default scale.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
dt = cudaDataType
|
|
51
|
+
ct = cublas.ComputeType
|
|
52
|
+
|
|
53
|
+
scale_type_map = {}
|
|
54
|
+
scale_type_map[ct.COMPUTE_16F] = dt.CUDA_R_16F
|
|
55
|
+
scale_type_map[ct.COMPUTE_16F_PEDANTIC] = dt.CUDA_R_16F
|
|
56
|
+
|
|
57
|
+
f32 = dt.CUDA_C_32F if is_complex else dt.CUDA_R_32F
|
|
58
|
+
f64 = dt.CUDA_C_64F if is_complex else dt.CUDA_R_64F
|
|
59
|
+
|
|
60
|
+
scale_type_map[ct.COMPUTE_32F] = f32
|
|
61
|
+
scale_type_map[ct.COMPUTE_32F_PEDANTIC] = f32
|
|
62
|
+
scale_type_map[ct.COMPUTE_32F_FAST_16F] = f32
|
|
63
|
+
scale_type_map[ct.COMPUTE_32F_FAST_16BF] = f32
|
|
64
|
+
scale_type_map[ct.COMPUTE_32F_FAST_TF32] = f32
|
|
65
|
+
scale_type_map[ct.COMPUTE_64F] = f64
|
|
66
|
+
scale_type_map[ct.COMPUTE_64F_PEDANTIC] = f64
|
|
67
|
+
|
|
68
|
+
return scale_type_map
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def create_scale_type_to_compute_type_map():
|
|
72
|
+
"""
|
|
73
|
+
Map the scale type to the corresponding compute type that's an appropriate default.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
dt = cudaDataType
|
|
77
|
+
ct = cublas.ComputeType
|
|
78
|
+
|
|
79
|
+
compute_type_map = {}
|
|
80
|
+
compute_type_map[dt.CUDA_R_16F] = ct.COMPUTE_16F
|
|
81
|
+
compute_type_map[dt.CUDA_R_16BF] = ct.COMPUTE_32F
|
|
82
|
+
compute_type_map[dt.CUDA_R_32F] = ct.COMPUTE_32F
|
|
83
|
+
compute_type_map[dt.CUDA_C_32F] = ct.COMPUTE_32F
|
|
84
|
+
compute_type_map[dt.CUDA_R_64F] = ct.COMPUTE_64F
|
|
85
|
+
compute_type_map[dt.CUDA_C_64F] = ct.COMPUTE_64F
|
|
86
|
+
return compute_type_map
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def create_compute_type_map():
|
|
90
|
+
"""
|
|
91
|
+
Map the data type name to the corresponding CUDA data type that's appropriate for
|
|
92
|
+
default scale.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
ct = cublas.ComputeType
|
|
96
|
+
|
|
97
|
+
compute_type_map = {}
|
|
98
|
+
compute_type_map["float8_e4m3fn", "float8_e5m2"] = ct.COMPUTE_32F
|
|
99
|
+
compute_type_map["float8_e5m2", "float8_e4m3fn"] = ct.COMPUTE_32F
|
|
100
|
+
compute_type_map["float8_e4m3fn", "float8_e4m3fn"] = ct.COMPUTE_32F
|
|
101
|
+
compute_type_map["bfloat16", "bfloat16"] = ct.COMPUTE_32F
|
|
102
|
+
compute_type_map["float16", "float16"] = ct.COMPUTE_32F
|
|
103
|
+
compute_type_map["float32", "float32"] = ct.COMPUTE_32F
|
|
104
|
+
compute_type_map["float64", "float64"] = ct.COMPUTE_64F
|
|
105
|
+
compute_type_map["complex32", "complex32"] = ct.COMPUTE_32F
|
|
106
|
+
compute_type_map["complex64", "complex64"] = ct.COMPUTE_32F
|
|
107
|
+
compute_type_map["complex128", "complex128"] = ct.COMPUTE_64F
|
|
108
|
+
|
|
109
|
+
return compute_type_map
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
CUBLAS_COMPUTE_TYPE_TO_NAME = {
|
|
113
|
+
cublas.ComputeType.COMPUTE_32F: ("float32", "complex64"),
|
|
114
|
+
cublas.ComputeType.COMPUTE_64F: ("float64", "complex128"),
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
NAMES_TO_DEFAULT_SCALE_TYPE = create_default_scale_type_map()
|
|
118
|
+
NAMES_TO_DEFAULT_COMPUTE_TYPE = create_compute_type_map()
|
|
119
|
+
COMPUTE_TYPE_TO_DEFAULT_SCALE_TYPE = {
|
|
120
|
+
"real": create_compute_type_to_scale_type_map(is_complex=False),
|
|
121
|
+
"complex": create_compute_type_to_scale_type_map(is_complex=True),
|
|
122
|
+
}
|
|
123
|
+
SCALE_TYPE_TO_DEFAULT_COMPUTE_TYPE = create_scale_type_to_compute_type_map()
|
|
124
|
+
|
|
125
|
+
SUPPORTED_TYPES = [
|
|
126
|
+
"float8_e4m3fn",
|
|
127
|
+
"float8_e5m2",
|
|
128
|
+
"bfloat16",
|
|
129
|
+
"float16",
|
|
130
|
+
"float32",
|
|
131
|
+
"float64",
|
|
132
|
+
"complex32",
|
|
133
|
+
"complex64",
|
|
134
|
+
"complex128",
|
|
135
|
+
]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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
|
+
"create_handle",
|
|
14
|
+
"destroy_handle",
|
|
15
|
+
"get_handle",
|
|
16
|
+
"pointer_aligned_to",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
import typing
|
|
20
|
+
|
|
21
|
+
from nvmath.bindings import cublasLt as cublaslt
|
|
22
|
+
from nvmath.internal import utils
|
|
23
|
+
|
|
24
|
+
HANDLES: dict[int, int] = {}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_handle(device_id: int) -> int:
|
|
28
|
+
"""
|
|
29
|
+
Currently for internal use only.
|
|
30
|
+
"""
|
|
31
|
+
with utils.device_ctx(device_id):
|
|
32
|
+
handle = cublaslt.create()
|
|
33
|
+
|
|
34
|
+
return handle
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def destroy_handle(handle: int):
|
|
38
|
+
"""
|
|
39
|
+
Currently for internal use only.
|
|
40
|
+
"""
|
|
41
|
+
cublaslt.destroy(handle)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_handle(device_id: int) -> int:
|
|
45
|
+
"""
|
|
46
|
+
Retrieve the BLAS library handle for the specified device. If one doesn't exist, create,
|
|
47
|
+
cache, and return the handle.
|
|
48
|
+
"""
|
|
49
|
+
return HANDLES.setdefault(device_id, create_handle(device_id))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def pointer_aligned_to(address):
|
|
53
|
+
"""
|
|
54
|
+
Return the number of bytes the address is aligned to.
|
|
55
|
+
"""
|
|
56
|
+
return address & ~(address - 1)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def axis_order_in_memory(strides):
|
|
60
|
+
"""
|
|
61
|
+
Compute the order in which the axes appear in memory.
|
|
62
|
+
"""
|
|
63
|
+
if len(strides) == 0:
|
|
64
|
+
return ()
|
|
65
|
+
|
|
66
|
+
_, axis_order = zip(*sorted(zip(strides, range(len(strides)), strict=True)), strict=True)
|
|
67
|
+
|
|
68
|
+
return axis_order
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def calculate_strides(shape: typing.Sequence[int], axis_order: typing.Sequence[int]):
|
|
72
|
+
"""
|
|
73
|
+
Calculate the strides for the provided shape and axis order.
|
|
74
|
+
"""
|
|
75
|
+
strides: list[None | int] = [None] * len(shape)
|
|
76
|
+
|
|
77
|
+
stride = 1
|
|
78
|
+
for axis in axis_order:
|
|
79
|
+
strides[axis] = stride
|
|
80
|
+
stride *= shape[axis]
|
|
81
|
+
|
|
82
|
+
return strides
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _contiguous_layout(sorted_shape, sorted_strides):
|
|
86
|
+
return all(sorted_shape[s - 1] * sorted_strides[s - 1] == sorted_strides[s] for s in range(1, len(sorted_strides)))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def check_batch_tileable(batch_shape, batch_strides):
|
|
90
|
+
"""
|
|
91
|
+
Check if the matrix layout is tileable across the specified batch layout.
|
|
92
|
+
"""
|
|
93
|
+
sorted_batch_strides, sorted_batch_shape = zip(
|
|
94
|
+
*sorted((batch_strides[a], batch_shape[a]) for a in range(len(batch_shape))), strict=True
|
|
95
|
+
)
|
|
96
|
+
return _contiguous_layout(sorted_batch_shape, sorted_batch_strides)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from ._algorithmmod import * # noqa: F403
|
|
6
|
+
from ._configuration import * # noqa: F403
|
|
7
|
+
from .matmulmod import * # noqa: F403
|
|
8
|
+
from . import helpers as helpers # noqa: F403
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, 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
|
+
|
|
14
|
+
from nvmath.linalg.advanced._configuration import AlgorithmCapabilities
|
|
15
|
+
from nvmath.linalg._internal.algo_cap_ifc import AlgoCapInterface
|
|
16
|
+
from nvmath.linalg._internal.algo_config_ifc import AlgoConfigInterface
|
|
17
|
+
from nvmath.bindings.cublasLt import MatmulHeuristicResult # type: ignore
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class Algorithm:
|
|
21
|
+
"""
|
|
22
|
+
An interface class to query algorithm capabilities and configure the algorithm.
|
|
23
|
+
|
|
24
|
+
Note that objects of this type should not be constructed directly by the user.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, algorithm):
|
|
28
|
+
assert isinstance(algorithm, MatmulHeuristicResult), "Internal error."
|
|
29
|
+
self.algorithm = algorithm
|
|
30
|
+
self.cap_ifc = AlgoCapInterface(algorithm)
|
|
31
|
+
self.config_ifc = AlgoConfigInterface(algorithm)
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def capabilities(self):
|
|
35
|
+
"""
|
|
36
|
+
Return the capabilities of this algorithm as a
|
|
37
|
+
:class:`nvmath.linalg.advanced.AlgorithmCapabilities` dataclass.
|
|
38
|
+
"""
|
|
39
|
+
names = [field.name for field in dataclasses.fields(AlgorithmCapabilities)]
|
|
40
|
+
_capabilities = {}
|
|
41
|
+
for name in names:
|
|
42
|
+
# Not all capabilities in the enum are supported in all CTK versions.
|
|
43
|
+
try:
|
|
44
|
+
_capabilities[name] = getattr(self.cap_ifc, name)
|
|
45
|
+
except:
|
|
46
|
+
pass
|
|
47
|
+
return AlgorithmCapabilities(**_capabilities)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def algorithm_id(self):
|
|
51
|
+
"The ID of the algorithm (integer)."
|
|
52
|
+
return self.config_ifc.id
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def tile(self):
|
|
56
|
+
"""A tuple representing the tile (see MatmulAlgoConfigAttribute.TILE_ID).
|
|
57
|
+
The value provided must be one of the `tile_ids` in the algorithm capabilities."""
|
|
58
|
+
return self.config_ifc.tile_id
|
|
59
|
+
|
|
60
|
+
@tile.setter
|
|
61
|
+
def tile(self, tile):
|
|
62
|
+
self.config_ifc.tile_id = tile
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def stages(self):
|
|
66
|
+
"""A tuple representing the stages (see MatmulAlgoConfigAttribute.STAGES_ID).
|
|
67
|
+
The value provided must be one of the `stages_ids` in the algorithm capabilities."""
|
|
68
|
+
return self.config_ifc.stages_id
|
|
69
|
+
|
|
70
|
+
@stages.setter
|
|
71
|
+
def stages(self, stages):
|
|
72
|
+
self.config_ifc.stages_id = stages
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def split_k(self):
|
|
76
|
+
"""The number of split-k steps (see MatmulAlgoConfigAttribute.SPLITK_NUM).
|
|
77
|
+
|
|
78
|
+
This can be set only if `splitk_support` is 1 in the algorithm capabilities."""
|
|
79
|
+
return self.config_ifc.splitk_num
|
|
80
|
+
|
|
81
|
+
@split_k.setter
|
|
82
|
+
def split_k(self, number):
|
|
83
|
+
self.config_ifc.splitk_num = number
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def reduction_scheme(self):
|
|
87
|
+
"""The reduction scheme used (see MatmulAlgoConfigAttribute.REDUCTION_SCHEME).
|
|
88
|
+
|
|
89
|
+
The value provided must be consistent with the `reduction_scheme_mask` in the
|
|
90
|
+
algorithm capabilities."""
|
|
91
|
+
return self.config_ifc.reduction_scheme
|
|
92
|
+
|
|
93
|
+
@reduction_scheme.setter
|
|
94
|
+
def reduction_scheme(self, scheme_id):
|
|
95
|
+
self.config_ifc.reduction_scheme = scheme_id
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def cta_swizzling(self):
|
|
99
|
+
"""A flag indicating CTA swizzling (see MatmulAlgoConfigAttribute.CTA_SWIZZLING).
|
|
100
|
+
|
|
101
|
+
This can be set only if `cta_swizzling` is 1 in the algorithm capabilities."""
|
|
102
|
+
return self.config_ifc.cta_swizzling
|
|
103
|
+
|
|
104
|
+
@cta_swizzling.setter
|
|
105
|
+
def cta_swizzling(self, flag: bool):
|
|
106
|
+
self.config_ifc.cta_swizzling = flag
|
|
107
|
+
|
|
108
|
+
@property
|
|
109
|
+
def custom_option(self):
|
|
110
|
+
"""A value indicating the custom option (see
|
|
111
|
+
MatmulAlgoConfigAttribute.CUSTOM_OPTION).
|
|
112
|
+
|
|
113
|
+
The value provided must be less than `custom_option_max` in the algorithm
|
|
114
|
+
capabilities."""
|
|
115
|
+
return self.config_ifc.custom_option
|
|
116
|
+
|
|
117
|
+
@custom_option.setter
|
|
118
|
+
def custom_option(self, value: int):
|
|
119
|
+
self.config_ifc.custom_option = value
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def inner_shape(self):
|
|
123
|
+
"""A value indicating the inner shape (see
|
|
124
|
+
MatmulAlgoConfigAttribute.INNER_SHAPE_ID)."""
|
|
125
|
+
return self.config_ifc.inner_shape_id
|
|
126
|
+
|
|
127
|
+
@inner_shape.setter
|
|
128
|
+
def inner_shape(self, shape):
|
|
129
|
+
self.config_ifc.inner_shape_id = shape
|
|
130
|
+
|
|
131
|
+
@property
|
|
132
|
+
def cluster_shape(self):
|
|
133
|
+
"""A tuple representing the cluster shape (see
|
|
134
|
+
MatmulAlgoConfigAttribute.CLUSTER_SHAPE_ID).
|
|
135
|
+
|
|
136
|
+
The value provided must be one of the `cluster_shape_ids` in the algorithm
|
|
137
|
+
capabilities."""
|
|
138
|
+
return self.config_ifc.cluster_shape_id
|
|
139
|
+
|
|
140
|
+
@cluster_shape.setter
|
|
141
|
+
def cluster_shape(self, shape):
|
|
142
|
+
self.config_ifc.cluster_shape_id = shape
|