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.
- nvmath/__init__.pxd +0 -0
- nvmath/__init__.py +45 -0
- nvmath/_internal/__init__.py +0 -0
- nvmath/_internal/attribute_ifc_factory.py +330 -0
- nvmath/_internal/layout.py +70 -0
- nvmath/_internal/templates.py +130 -0
- nvmath/_internal/threadsafe.py +106 -0
- nvmath/_internal/utils.py +43 -0
- nvmath/_internal/workspace.py +490 -0
- nvmath/_utils.py +147 -0
- nvmath/bindings/__init__.py +60 -0
- nvmath/bindings/_internal/__init__.pxd +0 -0
- nvmath/bindings/_internal/__init__.py +0 -0
- nvmath/bindings/_internal/common_types.pxd +31 -0
- nvmath/bindings/_internal/cublas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublas.pxd +530 -0
- nvmath/bindings/_internal/cublasLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublasLt.pxd +59 -0
- nvmath/bindings/_internal/cublasMp.pxd +52 -0
- nvmath/bindings/_internal/cudss.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cudss.pxd +54 -0
- nvmath/bindings/_internal/cufft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cufft.pxd +70 -0
- nvmath/bindings/_internal/cufftMp.pxd +77 -0
- nvmath/bindings/_internal/curand.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/curand.pxd +42 -0
- nvmath/bindings/_internal/cusolver.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolver.pxd +15 -0
- nvmath/bindings/_internal/cusolverDn.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverDn.pxd +406 -0
- nvmath/bindings/_internal/cusolverMp.pxd +71 -0
- nvmath/bindings/_internal/cusolverSp.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverSp.pxd +75 -0
- nvmath/bindings/_internal/cusparse.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparse.pxd +471 -0
- nvmath/bindings/_internal/cusparseLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparseLt.pxd +48 -0
- nvmath/bindings/_internal/cutensor.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cutensor.pxd +58 -0
- nvmath/bindings/_internal/mathdx.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/mathdx.pxd +116 -0
- nvmath/bindings/_internal/nvshmem.pxd +29 -0
- nvmath/bindings/_internal/utils.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/utils.pxd +174 -0
- nvmath/bindings/_internal/utils.pyi +10 -0
- nvmath/bindings/cublas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cublas.pxd +558 -0
- nvmath/bindings/cublas.pyi +812 -0
- nvmath/bindings/cublasLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cublasLt.pxd +109 -0
- nvmath/bindings/cublasLt.pyi +1461 -0
- nvmath/bindings/cublasMp.pxd +85 -0
- nvmath/bindings/cublasMp.pyi +267 -0
- nvmath/bindings/cudss.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cudss.pxd +98 -0
- nvmath/bindings/cudss.pyi +443 -0
- nvmath/bindings/cufft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cufft.pxd +118 -0
- nvmath/bindings/cufft.pyi +301 -0
- nvmath/bindings/cufftMp.pxd +124 -0
- nvmath/bindings/cufftMp.pyi +326 -0
- nvmath/bindings/curand.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/curand.pxd +71 -0
- nvmath/bindings/curand.pyi +189 -0
- nvmath/bindings/cusolver.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cusolver.pxd +62 -0
- nvmath/bindings/cusolver.pyi +320 -0
- nvmath/bindings/cusolverDn.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverDn.pxd +430 -0
- nvmath/bindings/cusolverDn.pyi +422 -0
- nvmath/bindings/cusolverMp.pxd +98 -0
- nvmath/bindings/cusolverMp.pyi +114 -0
- nvmath/bindings/cusolverSp.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverSp.pxd +95 -0
- nvmath/bindings/cusolverSp.pyi +70 -0
- nvmath/bindings/cusparse.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cusparse.pxd +546 -0
- nvmath/bindings/cusparse.pyi +1017 -0
- nvmath/bindings/cusparseLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cusparseLt.pxd +99 -0
- nvmath/bindings/cusparseLt.pyi +252 -0
- nvmath/bindings/cutensor.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cutensor.pxd +98 -0
- nvmath/bindings/cutensor.pyi +324 -0
- nvmath/bindings/cycublas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycublas.pxd +664 -0
- nvmath/bindings/cycublasLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycublasLt.pxd +1045 -0
- nvmath/bindings/cycublasMp.pxd +171 -0
- nvmath/bindings/cycudss.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycudss.pxd +277 -0
- nvmath/bindings/cycufft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycufft.pxd +333 -0
- nvmath/bindings/cycufftMp.pxd +342 -0
- nvmath/bindings/cycurand.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycurand.pxd +141 -0
- nvmath/bindings/cycusolver.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolver.pxd +137 -0
- nvmath/bindings/cycusolverDn.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverDn.pxd +443 -0
- nvmath/bindings/cycusolverMp.pxd +107 -0
- nvmath/bindings/cycusolverSp.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverSp.pxd +93 -0
- nvmath/bindings/cycusparse.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparse.pxd +679 -0
- nvmath/bindings/cycusparseLt.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparseLt.pxd +135 -0
- nvmath/bindings/cycutensor.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cycutensor.pxd +189 -0
- nvmath/bindings/cymathdx.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/cymathdx.pxd +552 -0
- nvmath/bindings/cynvshmem.pxd +118 -0
- nvmath/bindings/mathdx.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/mathdx.pxd +182 -0
- nvmath/bindings/mathdx.pyi +1562 -0
- nvmath/bindings/nvpl/__init__.pxd +0 -0
- nvmath/bindings/nvpl/__init__.py +13 -0
- nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
- nvmath/bindings/nvpl/_internal/__init__.py +0 -0
- nvmath/bindings/nvpl/_internal/blas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/_internal/blas.pxd +237 -0
- nvmath/bindings/nvpl/_internal/fft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
- nvmath/bindings/nvpl/blas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/blas.pxd +131 -0
- nvmath/bindings/nvpl/blas.pyi +168 -0
- nvmath/bindings/nvpl/cyblas.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/cyblas.pxd +280 -0
- nvmath/bindings/nvpl/cyfft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/cyfft.pxd +93 -0
- nvmath/bindings/nvpl/fft.cp314t-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/fft.pxd +100 -0
- nvmath/bindings/nvpl/fft.pyi +168 -0
- nvmath/bindings/nvshmem.pxd +54 -0
- nvmath/bindings/nvshmem.pyi +191 -0
- nvmath/device/__init__.py +38 -0
- nvmath/device/_deprecated.py +33 -0
- nvmath/device/common.py +315 -0
- nvmath/device/common_backend.py +131 -0
- nvmath/device/common_cuda.py +201 -0
- nvmath/device/common_numba.py +300 -0
- nvmath/device/common_numba_cuda_mlir.py +202 -0
- nvmath/device/common_opaque_tensor.py +201 -0
- nvmath/device/cublasdx.py +1606 -0
- nvmath/device/cublasdx_backend.py +860 -0
- nvmath/device/cublasdx_numba.py +1534 -0
- nvmath/device/cublasdx_numba_cuda_mlir.py +208 -0
- nvmath/device/cufftdx.py +373 -0
- nvmath/device/cufftdx_backend.py +220 -0
- nvmath/device/cufftdx_numba.py +140 -0
- nvmath/device/cufftdx_numba_cuda_mlir.py +79 -0
- nvmath/device/curand_kernel.py +9147 -0
- nvmath/device/cusolverdx.py +2708 -0
- nvmath/device/cusolverdx_backend.py +440 -0
- nvmath/device/cusolverdx_numba.py +567 -0
- nvmath/device/cusolverdx_numba_cuda_mlir.py +604 -0
- nvmath/device/cusolverdx_overload_backend.py +1029 -0
- nvmath/device/llvm_array.py +29 -0
- nvmath/device/random.py +441 -0
- nvmath/device/random_helpers.py +23 -0
- nvmath/device/random_states.py +187 -0
- nvmath/device/types.py +138 -0
- nvmath/device/vector_types_numba.py +259 -0
- nvmath/distributed/__init__.py +200 -0
- nvmath/distributed/_internal/__init__.py +0 -0
- nvmath/distributed/_internal/nccl.py +86 -0
- nvmath/distributed/_internal/nvshmem.py +307 -0
- nvmath/distributed/_internal/symmetric_memory.py +35 -0
- nvmath/distributed/_internal/tensor_ifc.py +70 -0
- nvmath/distributed/_internal/tensor_ifc_cupy.py +68 -0
- nvmath/distributed/_internal/tensor_ifc_host_device.py +172 -0
- nvmath/distributed/_internal/tensor_ifc_numpy.py +46 -0
- nvmath/distributed/_internal/tensor_ifc_torch.py +162 -0
- nvmath/distributed/_internal/tensor_wrapper.py +81 -0
- nvmath/distributed/_utils.py +167 -0
- nvmath/distributed/distribution/__init__.py +30 -0
- nvmath/distributed/distribution/_configuration.py +39 -0
- nvmath/distributed/distribution/distributions.py +1024 -0
- nvmath/distributed/distribution/redistribute.py +1284 -0
- nvmath/distributed/fft/__init__.py +7 -0
- nvmath/distributed/fft/_configuration.py +82 -0
- nvmath/distributed/fft/fft.py +2742 -0
- nvmath/distributed/linalg/__init__.py +22 -0
- nvmath/distributed/linalg/_internal/__init__.py +3 -0
- nvmath/distributed/linalg/_internal/epilog_protocol.py +586 -0
- nvmath/distributed/linalg/_internal/matmul_desc_ifc.py +28 -0
- nvmath/distributed/linalg/advanced/__init__.py +8 -0
- nvmath/distributed/linalg/advanced/_configuration.py +171 -0
- nvmath/distributed/linalg/advanced/matmulmod.py +3573 -0
- nvmath/distributed/linalg/generic/__init__.py +8 -0
- nvmath/distributed/linalg/generic/_caching.py +66 -0
- nvmath/distributed/linalg/generic/_configuration.py +61 -0
- nvmath/distributed/linalg/generic/_factorization.py +172 -0
- nvmath/distributed/linalg/generic/_initialization.py +966 -0
- nvmath/distributed/linalg/generic/_problem_spec.py +511 -0
- nvmath/distributed/linalg/generic/solvermod.py +1368 -0
- nvmath/distributed/process_group.py +408 -0
- nvmath/fft/__init__.py +7 -0
- nvmath/fft/_configuration.py +189 -0
- nvmath/fft/_exec_utils.py +82 -0
- nvmath/fft/_helpers.py +237 -0
- nvmath/fft/fft.py +3122 -0
- nvmath/internal/__init__.pxd +3 -0
- nvmath/internal/__init__.py +10 -0
- nvmath/internal/_bindings.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/_bindings.pxd +18 -0
- nvmath/internal/_device_utils.py +45 -0
- nvmath/internal/_layout/__init__.pxd +3 -0
- nvmath/internal/_layout/__init__.py +7 -0
- nvmath/internal/_layout/_layout.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/_layout/_layout.pxd +1303 -0
- nvmath/internal/_layout/_layout.pyi +1145 -0
- nvmath/internal/enum_utils.py +142 -0
- nvmath/internal/formatters.py +87 -0
- nvmath/internal/mem_limit.py +51 -0
- nvmath/internal/memory.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/memory.pxd +13 -0
- nvmath/internal/memory.pyi +50 -0
- nvmath/internal/ndbuffer/__init__.pxd +3 -0
- nvmath/internal/ndbuffer/__init__.py +9 -0
- nvmath/internal/ndbuffer/_copy_kernel.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/_copy_kernel.pxd +10 -0
- nvmath/internal/ndbuffer/_jit.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/_jit.pxd +7 -0
- nvmath/internal/ndbuffer/_ndbuffer.cp314t-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/_ndbuffer.pxd +40 -0
- nvmath/internal/ndbuffer/_ndbuffer.pyi +463 -0
- nvmath/internal/ndbuffer/copy_kernel/args.h +34 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/array_view.h +52 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/elementwise.h +68 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/grid_indexer.h +69 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/transposed.h +242 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/type_utils.h +39 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/utils.h +132 -0
- nvmath/internal/ndbuffer/copy_kernel/copy_kernel_impl/vec.h +159 -0
- nvmath/internal/ndbuffer/copy_kernel/elementwise.h +53 -0
- nvmath/internal/ndbuffer/copy_kernel/transposed.h +58 -0
- nvmath/internal/package_ifc.py +168 -0
- nvmath/internal/package_ifc_cuda.py +57 -0
- nvmath/internal/package_ifc_cupy.py +67 -0
- nvmath/internal/package_ifc_torch.py +69 -0
- nvmath/internal/package_wrapper.py +14 -0
- nvmath/internal/tensor_ifc.py +179 -0
- nvmath/internal/tensor_ifc_cupy.py +234 -0
- nvmath/internal/tensor_ifc_ndbuffer.py +147 -0
- nvmath/internal/tensor_ifc_numpy.py +184 -0
- nvmath/internal/tensor_ifc_torch.py +178 -0
- nvmath/internal/tensor_wrapper.py +160 -0
- nvmath/internal/typemaps.py +113 -0
- nvmath/internal/utils.py +805 -0
- nvmath/linalg/__init__.py +56 -0
- nvmath/linalg/_internal/__init__.py +3 -0
- nvmath/linalg/_internal/algo_cap_ifc.py +82 -0
- nvmath/linalg/_internal/algo_config_ifc.py +43 -0
- nvmath/linalg/_internal/batch.py +234 -0
- nvmath/linalg/_internal/enum_to_tuples.py +64 -0
- nvmath/linalg/_internal/epilog_protocol.py +766 -0
- nvmath/linalg/_internal/layout.py +624 -0
- nvmath/linalg/_internal/matmul_desc_ifc.py +28 -0
- nvmath/linalg/_internal/matmul_pref_ifc.py +27 -0
- nvmath/linalg/_internal/matrix_layout_ifc.py +26 -0
- nvmath/linalg/_internal/solver_utils.py +432 -0
- nvmath/linalg/_internal/typemaps.py +144 -0
- nvmath/linalg/_internal/utils.py +157 -0
- nvmath/linalg/advanced/__init__.py +8 -0
- nvmath/linalg/advanced/_algorithmmod.py +170 -0
- nvmath/linalg/advanced/_configuration.py +351 -0
- nvmath/linalg/advanced/helpers/__init__.py +5 -0
- nvmath/linalg/advanced/helpers/matmul.py +1316 -0
- nvmath/linalg/advanced/matmulmod.py +3734 -0
- nvmath/linalg/generic/__init__.py +53 -0
- nvmath/linalg/generic/_configuration/__init__.py +39 -0
- nvmath/linalg/generic/_configuration/layout.py +263 -0
- nvmath/linalg/generic/_configuration/match.py +734 -0
- nvmath/linalg/generic/_configuration/qualifiers.py +493 -0
- nvmath/linalg/generic/_configuration/solver_configuration.py +59 -0
- nvmath/linalg/generic/_configuration/wrap.py +217 -0
- nvmath/linalg/generic/_dtype.py +15 -0
- nvmath/linalg/generic/matmulmod.py +2094 -0
- nvmath/linalg/generic/solvermod.py +1301 -0
- nvmath/memory.py +279 -0
- nvmath/sparse/__init__.py +38 -0
- nvmath/sparse/_internal/__init__.py +21 -0
- nvmath/sparse/_internal/common_utils.py +147 -0
- nvmath/sparse/_internal/cudss_config_ifc.py +702 -0
- nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
- nvmath/sparse/_internal/cudss_utils.py +506 -0
- nvmath/sparse/_internal/cusparse_utils.py +382 -0
- nvmath/sparse/_internal/sparse_bsc_ifc.py +303 -0
- nvmath/sparse/_internal/sparse_bsr_ifc.py +305 -0
- nvmath/sparse/_internal/sparse_coo_ifc.py +256 -0
- nvmath/sparse/_internal/sparse_csc_ifc.py +268 -0
- nvmath/sparse/_internal/sparse_csr_ifc.py +288 -0
- nvmath/sparse/_internal/sparse_dia_ifc.py +242 -0
- nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
- nvmath/sparse/_internal/sparse_tensor_ifc.py +133 -0
- nvmath/sparse/_internal/sparse_ust_ifc.py +141 -0
- nvmath/sparse/_internal/utils.py +56 -0
- nvmath/sparse/advanced/__init__.py +7 -0
- nvmath/sparse/advanced/_configuration.py +227 -0
- nvmath/sparse/advanced/direct_solver.py +2069 -0
- nvmath/sparse/generic/__init__.py +7 -0
- nvmath/sparse/generic/_configuration.py +129 -0
- nvmath/sparse/generic/_helpers.py +137 -0
- nvmath/sparse/generic/_thunks.py +21 -0
- nvmath/sparse/generic/matmulmod.py +2353 -0
- nvmath/sparse/ust/__init__.py +7 -0
- nvmath/sparse/ust/_converters.py +422 -0
- nvmath/sparse/ust/_cpp.py +28 -0
- nvmath/sparse/ust/_drawer.py +565 -0
- nvmath/sparse/ust/_emitter.py +1033 -0
- nvmath/sparse/ust/_jit.py +188 -0
- nvmath/sparse/ust/_kernel.py +282 -0
- nvmath/sparse/ust/_utils.py +149 -0
- nvmath/sparse/ust/interfaces/__init__.py +0 -0
- nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
- nvmath/sparse/ust/tensor.py +1016 -0
- nvmath/sparse/ust/tensor_format.py +957 -0
- nvmath/tensor/__init__.py +6 -0
- nvmath/tensor/_configuration.py +120 -0
- nvmath/tensor/_internal/__init__.py +3 -0
- nvmath/tensor/_internal/cutensor_config_ifc.py +279 -0
- nvmath/tensor/_internal/cutensor_utils.py +230 -0
- nvmath/tensor/_internal/data.py +43 -0
- nvmath/tensor/_internal/einsum_parser.py +444 -0
- nvmath/tensor/_internal/typemaps.py +96 -0
- nvmath/tensor/contract.py +1900 -0
- nvmath_python-1.0.0.dist-info/METADATA +134 -0
- nvmath_python-1.0.0.dist-info/RECORD +332 -0
- nvmath_python-1.0.0.dist-info/WHEEL +5 -0
- nvmath_python-1.0.0.dist-info/licenses/LICENSE +177 -0
- nvmath_python-1.0.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,860 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
__all__ = ["LeadingDimension", "TransposeMode", "Arrangement", "Alignment", "Precision"]
|
|
6
|
+
|
|
7
|
+
import weakref
|
|
8
|
+
from collections import namedtuple
|
|
9
|
+
from collections.abc import Sequence
|
|
10
|
+
from functools import lru_cache
|
|
11
|
+
from typing import NamedTuple, Protocol
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
from cuda.core import (
|
|
15
|
+
Kernel,
|
|
16
|
+
Linker,
|
|
17
|
+
LinkerOptions,
|
|
18
|
+
ObjectCode,
|
|
19
|
+
Program,
|
|
20
|
+
ProgramOptions,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from nvmath.bindings import mathdx
|
|
24
|
+
|
|
25
|
+
from .common import check_in, check_sm
|
|
26
|
+
from .common_backend import (
|
|
27
|
+
EXECUTION_STR_TO_MATHDX,
|
|
28
|
+
NP_TYPES_TO_MATHDX_PRECISION,
|
|
29
|
+
NP_TYPES_TO_MATHDX_TYPES,
|
|
30
|
+
NVARG_GEN_OPT_LTO,
|
|
31
|
+
DescriptorWrapper,
|
|
32
|
+
build_get_int_traits,
|
|
33
|
+
build_get_str_trait,
|
|
34
|
+
get_isa_version,
|
|
35
|
+
get_lto,
|
|
36
|
+
get_mathdx_sm,
|
|
37
|
+
set_code_target_sm,
|
|
38
|
+
)
|
|
39
|
+
from .common_cuda import Code, CodeType, ComputeCapability, Dim3, ISAVersion
|
|
40
|
+
from .types import INT_NP_TYPES, REAL_NP_TYPES
|
|
41
|
+
|
|
42
|
+
# ==============================================
|
|
43
|
+
# Type definition args
|
|
44
|
+
# ==============================================
|
|
45
|
+
|
|
46
|
+
_BLAS_DEFINITION_ARGS = [
|
|
47
|
+
"size",
|
|
48
|
+
"precision",
|
|
49
|
+
"data_type",
|
|
50
|
+
"sm",
|
|
51
|
+
"block_size",
|
|
52
|
+
"block_dim",
|
|
53
|
+
"leading_dimension",
|
|
54
|
+
"transpose_mode",
|
|
55
|
+
"arrangement",
|
|
56
|
+
"function",
|
|
57
|
+
"execution",
|
|
58
|
+
"alignment",
|
|
59
|
+
"with_pipeline",
|
|
60
|
+
"enable_input_streaming",
|
|
61
|
+
"static_block_dim",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
_BLAS_COMPILED_ARGS = [
|
|
65
|
+
"a_value_type",
|
|
66
|
+
"b_value_type",
|
|
67
|
+
"c_value_type",
|
|
68
|
+
# value_type, input_type, and output_type not included intentionally,
|
|
69
|
+
# because they are deprecated.
|
|
70
|
+
"a_dim",
|
|
71
|
+
"b_dim",
|
|
72
|
+
"c_dim",
|
|
73
|
+
"a_size",
|
|
74
|
+
"b_size",
|
|
75
|
+
"c_size",
|
|
76
|
+
"leading_dimension",
|
|
77
|
+
"max_threads_per_block",
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
_DEVICE_PIPELINE_DEFINITION_ARGS = [
|
|
81
|
+
"mm",
|
|
82
|
+
"pipeline_depth",
|
|
83
|
+
"a",
|
|
84
|
+
"b",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
_DEVICE_PIPELINE_COMPILED_ARGS = [
|
|
88
|
+
"buffer_alignment",
|
|
89
|
+
"buffer_size",
|
|
90
|
+
"storage_bytes",
|
|
91
|
+
"storage_alignment",
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
_TILE_PIPELINE_DEFINITION_ARGS = [
|
|
95
|
+
"device_pipeline",
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
_TILE_PIPELINE_COMPILED_ARGS = [
|
|
99
|
+
"storage_bytes",
|
|
100
|
+
"storage_alignment",
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
# ==============================================
|
|
104
|
+
# backend implementation
|
|
105
|
+
# ==============================================
|
|
106
|
+
|
|
107
|
+
_BLAS_API_STR_TO_MATHDX = {
|
|
108
|
+
"static_leading_dimensions": mathdx.CublasdxApi.SMEM,
|
|
109
|
+
"dynamic_leading_dimensions": mathdx.CublasdxApi.SMEM_DYNAMIC_LD,
|
|
110
|
+
"tensors": mathdx.CublasdxApi.TENSORS,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_BLAS_ARRENGEMENT_STR_TO_MATHDX = {a.name.lower(): a for a in mathdx.CublasdxArrangement}
|
|
114
|
+
|
|
115
|
+
_BLAS_TYPE_STR_TO_MATHDX = {t.name.lower(): t for t in mathdx.CublasdxType}
|
|
116
|
+
|
|
117
|
+
_BLAS_TRANSPOSE_STR_TO_MATHDX = {tm.name.lower(): tm for tm in mathdx.CublasdxTransposeMode}
|
|
118
|
+
|
|
119
|
+
_BLAS_FUNCTION_STR_TO_MATHDX = {
|
|
120
|
+
"MM": mathdx.CublasdxFunction.MM,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
_TENSOR_TYPE_STR_TO_MATHDX = {t.name.lower(): t for t in mathdx.CublasdxTensorType}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def check_blas_sm(sm, library_name: str, var_name: str = "sm"):
|
|
127
|
+
check_sm(sm, library_name, var_name)
|
|
128
|
+
if sm.arch == "a" and sm.integer not in {900, 1000, 1030, 1100}:
|
|
129
|
+
raise ValueError(f"The 'a' SM modifier is only supported for SM 900, 1000, 1030, 1100, got {sm}")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class LeadingDimension(namedtuple("LeadingDimension", ["a", "b", "c"])):
|
|
133
|
+
"""
|
|
134
|
+
A namedtuple class that encapsulates the three leading dimensions in matrix
|
|
135
|
+
multiplication :math:`C = \\alpha Op(A) Op(B) + \\beta C`.
|
|
136
|
+
|
|
137
|
+
Attributes:
|
|
138
|
+
a (int): The leading dimension of two-dimensional array used to store the matrix
|
|
139
|
+
``A``.
|
|
140
|
+
|
|
141
|
+
b (int): The leading dimension of two-dimensional array used to store the matrix
|
|
142
|
+
``B``.
|
|
143
|
+
|
|
144
|
+
c (int): The leading dimension of two-dimensional array used to store the matrix
|
|
145
|
+
``C``.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
__slots__ = ()
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class TransposeMode(namedtuple("TransposeMode", ["a", "b"])):
|
|
152
|
+
"""
|
|
153
|
+
A namedtuple class that encapsulates the transpose mode for input matrices ``A`` and
|
|
154
|
+
``B`` in matrix multiplication.
|
|
155
|
+
|
|
156
|
+
Attributes:
|
|
157
|
+
a: The operation that needs to be performed with input matrix ``A``, currently
|
|
158
|
+
supports ``'non_transposed'``, ``'transposed'`` and ``'conj_transposed'``.
|
|
159
|
+
|
|
160
|
+
b: The operation that needs to be performed with input matrix ``B``, currently
|
|
161
|
+
supports ``'non_transposed'``, ``'transposed'`` and ``'conj_transposed'``.
|
|
162
|
+
"""
|
|
163
|
+
|
|
164
|
+
__slots__ = ()
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class Arrangement(NamedTuple):
|
|
168
|
+
"""
|
|
169
|
+
A namedtuple class that encapsulates the three arrangements in matrix allocation.
|
|
170
|
+
|
|
171
|
+
Attributes:
|
|
172
|
+
a (str): The arrangement of two-dimensional array used to store the matrix
|
|
173
|
+
``A``.
|
|
174
|
+
|
|
175
|
+
b (str): The arrangement of two-dimensional array used to store the matrix
|
|
176
|
+
``B``.
|
|
177
|
+
|
|
178
|
+
c (str): The arrangement of two-dimensional array used to store the matrix
|
|
179
|
+
``C``.
|
|
180
|
+
"""
|
|
181
|
+
|
|
182
|
+
a: str
|
|
183
|
+
b: str
|
|
184
|
+
c: str
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class Precision(NamedTuple):
|
|
188
|
+
"""
|
|
189
|
+
A namedtuple class that encapsulates the three precisions in matrix
|
|
190
|
+
multiplication :math:`C = \\alpha Op(A) Op(B) + \\beta C`.
|
|
191
|
+
|
|
192
|
+
Attributes:
|
|
193
|
+
a (type): The precision of two-dimensional array used to store the matrix
|
|
194
|
+
``A``.
|
|
195
|
+
|
|
196
|
+
b (type): The precision of two-dimensional array used to store the matrix
|
|
197
|
+
``B``.
|
|
198
|
+
|
|
199
|
+
c (type): The precision of two-dimensional array used to store the matrix
|
|
200
|
+
``C``.
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
a: type[object]
|
|
204
|
+
b: type[object]
|
|
205
|
+
c: type[object]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class Alignment(NamedTuple):
|
|
209
|
+
"""
|
|
210
|
+
A type to encapsulate the memory alignment in bytes of the matrix operands
|
|
211
|
+
A, B, and C.
|
|
212
|
+
|
|
213
|
+
Attributes:
|
|
214
|
+
a (int): The alignment of two-dimensional array used to store the matrix
|
|
215
|
+
``A``.
|
|
216
|
+
|
|
217
|
+
b (int): The alignment of two-dimensional array used to store the matrix
|
|
218
|
+
``B``.
|
|
219
|
+
|
|
220
|
+
c (int): The alignment of two-dimensional array used to store the matrix
|
|
221
|
+
``C``.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
a: int
|
|
225
|
+
b: int
|
|
226
|
+
c: int
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class CublasdxTensors(NamedTuple):
|
|
230
|
+
a: int
|
|
231
|
+
b: int
|
|
232
|
+
c: int
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
class CublasdxTensorsResponse:
|
|
236
|
+
target: CublasdxTensors
|
|
237
|
+
|
|
238
|
+
def __init__(self, target: CublasdxTensors):
|
|
239
|
+
self.target = target
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
MAX_ALIGNMENT = Alignment(16, 16, 16)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class CallableGetIntTraits(Protocol):
|
|
246
|
+
def __call__(self, handle: int, trait_type: mathdx.CublasdxTraitType, size: int) -> tuple: ...
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class CallableGetStrTrait(Protocol):
|
|
250
|
+
def __call__(self, handle: int, trait_type: mathdx.CublasdxTraitType) -> str: ...
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
get_int_traits: CallableGetIntTraits = build_get_int_traits(mathdx.cublasdx_get_trait_int64s)
|
|
254
|
+
|
|
255
|
+
get_str_trait: CallableGetStrTrait = build_get_str_trait(mathdx.cublasdx_get_trait_str_size, mathdx.cublasdx_get_trait_str)
|
|
256
|
+
|
|
257
|
+
get_str_device_trait: CallableGetStrTrait = build_get_str_trait(
|
|
258
|
+
mathdx.cublasdx_get_device_function_trait_str_size, mathdx.cublasdx_get_device_function_trait_str
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def get_tensor_int_traits(tensors: CublasdxTensors, trait: mathdx.CublasdxTensorTrait):
|
|
263
|
+
return (
|
|
264
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.a, trait)),
|
|
265
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.b, trait)),
|
|
266
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensors.c, trait)),
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
_ACCEPTED_PRECISION = REAL_NP_TYPES + INT_NP_TYPES
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def validate(
|
|
274
|
+
size,
|
|
275
|
+
data_type,
|
|
276
|
+
precision,
|
|
277
|
+
execution,
|
|
278
|
+
transpose_mode,
|
|
279
|
+
arrangement,
|
|
280
|
+
alignment,
|
|
281
|
+
block_dim,
|
|
282
|
+
sm,
|
|
283
|
+
function,
|
|
284
|
+
leading_dimension,
|
|
285
|
+
static_block_dim,
|
|
286
|
+
with_pipeline,
|
|
287
|
+
enable_input_streaming,
|
|
288
|
+
):
|
|
289
|
+
(m, n, k) = size
|
|
290
|
+
if m <= 0 or n <= 0 or k <= 0:
|
|
291
|
+
raise ValueError(f"m, n, k must be > 0. Got {m}, {n}, {k}")
|
|
292
|
+
if isinstance(precision, Precision):
|
|
293
|
+
for m in ["a", "b", "c"]:
|
|
294
|
+
check_in(f"precision.{m}", getattr(precision, m), _ACCEPTED_PRECISION)
|
|
295
|
+
else:
|
|
296
|
+
raise ValueError(
|
|
297
|
+
f"precision should be an instance of {Precision} or a 3-sequence, and individual fields "
|
|
298
|
+
f"should be one of {_ACCEPTED_PRECISION}. Instead got precision = {precision}"
|
|
299
|
+
)
|
|
300
|
+
check_blas_sm(sm, "cuBLASDx")
|
|
301
|
+
check_in("data_type", data_type, ["real", "complex"])
|
|
302
|
+
check_in("execution", execution, ["Block", "Thread"])
|
|
303
|
+
check_in("function", function, ["MM"])
|
|
304
|
+
check_in("static_block_dim", static_block_dim, [True, False])
|
|
305
|
+
if transpose_mode is not None:
|
|
306
|
+
allowed_values = ["non_transposed", "transposed", "conj_transposed"]
|
|
307
|
+
if isinstance(transpose_mode, TransposeMode):
|
|
308
|
+
check_in("transpose_mode.a", transpose_mode.a, allowed_values)
|
|
309
|
+
check_in("transpose_mode.b", transpose_mode.b, allowed_values)
|
|
310
|
+
else:
|
|
311
|
+
raise ValueError(
|
|
312
|
+
f"transpose_mode should be an instance of {TransposeMode} or a 2-tuple, and individual fields "
|
|
313
|
+
f"should be one of {allowed_values}. Instead got transpose_mode = {transpose_mode}"
|
|
314
|
+
)
|
|
315
|
+
if arrangement is not None:
|
|
316
|
+
allowed_values = _BLAS_ARRENGEMENT_STR_TO_MATHDX.keys()
|
|
317
|
+
if isinstance(arrangement, Arrangement):
|
|
318
|
+
check_in("arrangement.a", arrangement.a, allowed_values)
|
|
319
|
+
check_in("arrangement.b", arrangement.b, allowed_values)
|
|
320
|
+
check_in("arrangement.c", arrangement.c, allowed_values)
|
|
321
|
+
else:
|
|
322
|
+
raise ValueError(
|
|
323
|
+
f"arrangement should be an instance of {Arrangement} or a 3-tuple, and individual fields "
|
|
324
|
+
f"should be one of {allowed_values}. Instead got arrangement = {arrangement}"
|
|
325
|
+
)
|
|
326
|
+
if arrangement is not None and transpose_mode is not None:
|
|
327
|
+
raise ValueError("Only one of arrangement or transpose_mode must be provided. Instead got both")
|
|
328
|
+
if arrangement is None and transpose_mode is None:
|
|
329
|
+
raise ValueError("arrangement or transpose_mode must be provided. Instead got nothing")
|
|
330
|
+
if alignment is not None:
|
|
331
|
+
validate_alignment(alignment, precision, data_type)
|
|
332
|
+
if block_dim in (None, "suggested"):
|
|
333
|
+
pass
|
|
334
|
+
elif isinstance(block_dim, Dim3):
|
|
335
|
+
prod = block_dim[0] * block_dim[1] * block_dim[2]
|
|
336
|
+
if prod <= 0 or prod > 1024:
|
|
337
|
+
raise ValueError(
|
|
338
|
+
f"The product of the entries in block_dim should be between 1 and 1024 ; got block_dim = {block_dim}"
|
|
339
|
+
)
|
|
340
|
+
else:
|
|
341
|
+
raise ValueError(f"block_dim should be None, a Dim3 instance or 'suggested'; got block_dim = {block_dim}")
|
|
342
|
+
if leading_dimension in (None, "suggested") or isinstance(leading_dimension, LeadingDimension):
|
|
343
|
+
pass
|
|
344
|
+
else:
|
|
345
|
+
raise ValueError(
|
|
346
|
+
f"leading_dimension should be None, a LeadingDimension instance or 'suggested'; "
|
|
347
|
+
f"got leading_dimension = {leading_dimension}"
|
|
348
|
+
)
|
|
349
|
+
if not isinstance(with_pipeline, bool):
|
|
350
|
+
raise ValueError(f"with_pipeline should be a bool; got with_pipeline = {with_pipeline}")
|
|
351
|
+
if not isinstance(enable_input_streaming, bool):
|
|
352
|
+
raise ValueError(f"enable_input_streaming should be a bool; got enable_input_streaming = {enable_input_streaming}")
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def validate_execute_api(execute_api):
|
|
356
|
+
"""
|
|
357
|
+
Validate the execute_api argument.
|
|
358
|
+
"""
|
|
359
|
+
check_in("execute_api", execute_api, _BLAS_API_STR_TO_MATHDX.keys())
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def validate_tensor_types(tensor_types):
|
|
363
|
+
"""
|
|
364
|
+
Validate the tensor_types argument.
|
|
365
|
+
"""
|
|
366
|
+
allowed_values = _TENSOR_TYPE_STR_TO_MATHDX.keys()
|
|
367
|
+
if isinstance(tensor_types, Sequence) and len(tensor_types) == 3:
|
|
368
|
+
check_in("tensor_types[0]", tensor_types[0], allowed_values)
|
|
369
|
+
check_in("tensor_types[1]", tensor_types[1], allowed_values)
|
|
370
|
+
check_in("tensor_types[2]", tensor_types[2], allowed_values)
|
|
371
|
+
else:
|
|
372
|
+
raise ValueError(
|
|
373
|
+
f"tensor_types should be a 3-tuple, and individual fields "
|
|
374
|
+
f"should be one of {allowed_values}. Instead got tensor_types = {tensor_types}"
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def validate_alignment(alignment: Alignment, precision: Precision, data_type: str, gmem: bool = False):
|
|
379
|
+
"""
|
|
380
|
+
Validates alignment. precision and data_type must be already validated.
|
|
381
|
+
"""
|
|
382
|
+
name = "alignment" if not gmem else "global_memory_alignment"
|
|
383
|
+
default_a = default_alignment(precision, data_type)
|
|
384
|
+
for m in ["a", "b", "c"]:
|
|
385
|
+
a = getattr(alignment, m)
|
|
386
|
+
max_a = getattr(MAX_ALIGNMENT, m)
|
|
387
|
+
def_a = getattr(default_a, m)
|
|
388
|
+
if a <= 0:
|
|
389
|
+
raise ValueError(f"{name}.{m} must be > 0. Got {a}")
|
|
390
|
+
if a > max_a:
|
|
391
|
+
raise ValueError(f"{name}.{m} must not be greater than the maximum alignment {max_a}. Got {a}")
|
|
392
|
+
if a % def_a != 0:
|
|
393
|
+
raise ValueError(f"{name}.{m} must be a multiple of the input value type size ({def_a} bytes). Got {a}")
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def default_alignment(precision: Precision, data_type: str):
|
|
397
|
+
# supported precision's itemsize is always power of two, so we are safe
|
|
398
|
+
mul = 1 if data_type == "real" else 2
|
|
399
|
+
|
|
400
|
+
alignment = tuple(np.dtype(p).itemsize * mul for p in precision)
|
|
401
|
+
return Alignment(*alignment)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@lru_cache
|
|
405
|
+
def generate_MM(
|
|
406
|
+
size: tuple[int, int, int],
|
|
407
|
+
precision: Precision,
|
|
408
|
+
data_type: str,
|
|
409
|
+
function: str,
|
|
410
|
+
transpose_mode: TransposeMode | None,
|
|
411
|
+
arrangement: Arrangement | None,
|
|
412
|
+
alignment: Alignment | None,
|
|
413
|
+
sm: ComputeCapability,
|
|
414
|
+
block_dim: Dim3 | None,
|
|
415
|
+
static_block_dim: bool,
|
|
416
|
+
execution: str,
|
|
417
|
+
leading_dimension: LeadingDimension | None = None,
|
|
418
|
+
execute_api: str | None = None,
|
|
419
|
+
tensor_types: tuple[str, str, str] | None = None,
|
|
420
|
+
with_pipeline: bool = False,
|
|
421
|
+
enable_input_streaming: bool = False,
|
|
422
|
+
):
|
|
423
|
+
"""
|
|
424
|
+
Generate a cuBLASDx descriptor for matrix multiplication.
|
|
425
|
+
|
|
426
|
+
tenosr_types is only used to create cache properly.
|
|
427
|
+
"""
|
|
428
|
+
h = mathdx.cublasdx_create_descriptor()
|
|
429
|
+
|
|
430
|
+
(m, n, k) = size
|
|
431
|
+
|
|
432
|
+
# TODO: remove once libmathdx supports it
|
|
433
|
+
if execute_api is None:
|
|
434
|
+
execute_api = "static_leading_dimensions"
|
|
435
|
+
|
|
436
|
+
if execute_api is not None:
|
|
437
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.API, _BLAS_API_STR_TO_MATHDX[execute_api])
|
|
438
|
+
|
|
439
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SIZE, 3, [m, n, k])
|
|
440
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
441
|
+
h, mathdx.CublasdxOperatorType.PRECISION, len(precision), [NP_TYPES_TO_MATHDX_PRECISION[p] for p in precision]
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.FUNCTION, _BLAS_FUNCTION_STR_TO_MATHDX[function])
|
|
445
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.EXECUTION, EXECUTION_STR_TO_MATHDX[execution])
|
|
446
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.TYPE, _BLAS_TYPE_STR_TO_MATHDX[data_type])
|
|
447
|
+
|
|
448
|
+
sm_mathdx = get_mathdx_sm(sm)
|
|
449
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SM, len(sm_mathdx), sm_mathdx)
|
|
450
|
+
|
|
451
|
+
if block_dim:
|
|
452
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.BLOCK_DIM, 3, block_dim)
|
|
453
|
+
|
|
454
|
+
if static_block_dim:
|
|
455
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.STATIC_BLOCK_DIM, 1)
|
|
456
|
+
|
|
457
|
+
if leading_dimension:
|
|
458
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
459
|
+
h, mathdx.CublasdxOperatorType.LEADING_DIMENSION, 3, [leading_dimension.a, leading_dimension.b, leading_dimension.c]
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
if transpose_mode:
|
|
463
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
464
|
+
h,
|
|
465
|
+
mathdx.CublasdxOperatorType.TRANSPOSE_MODE,
|
|
466
|
+
2,
|
|
467
|
+
[_BLAS_TRANSPOSE_STR_TO_MATHDX[transpose_mode.a], _BLAS_TRANSPOSE_STR_TO_MATHDX[transpose_mode.b]],
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
if arrangement:
|
|
471
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
472
|
+
h,
|
|
473
|
+
mathdx.CublasdxOperatorType.ARRANGEMENT,
|
|
474
|
+
3,
|
|
475
|
+
[_BLAS_ARRENGEMENT_STR_TO_MATHDX[a] for a in arrangement],
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
if alignment:
|
|
479
|
+
mathdx.cublasdx_set_operator_int64s(
|
|
480
|
+
h,
|
|
481
|
+
mathdx.CublasdxOperatorType.ALIGNMENT,
|
|
482
|
+
3,
|
|
483
|
+
alignment,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
if with_pipeline:
|
|
487
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.WITH_PIPELINE, 1)
|
|
488
|
+
|
|
489
|
+
if enable_input_streaming:
|
|
490
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.ENABLE_INPUT_STREAMING, 1)
|
|
491
|
+
|
|
492
|
+
return DescriptorWrapper(h, mathdx.cublasdx_destroy_descriptor)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
@lru_cache
|
|
496
|
+
def generate_device_pipeline(
|
|
497
|
+
handle,
|
|
498
|
+
depth: int,
|
|
499
|
+
value_type_a: mathdx.CommondxValueType,
|
|
500
|
+
value_type_b: mathdx.CommondxValueType,
|
|
501
|
+
shape_a: list[int],
|
|
502
|
+
shape_b: list[int],
|
|
503
|
+
strides_a: list[int],
|
|
504
|
+
strides_b: list[int],
|
|
505
|
+
) -> DescriptorWrapper:
|
|
506
|
+
assert len(shape_a) == len(strides_a)
|
|
507
|
+
assert len(shape_b) == len(strides_b)
|
|
508
|
+
|
|
509
|
+
big_gmem_a = mathdx.cublasdx_create_tensor_strided(
|
|
510
|
+
mathdx.CublasdxMemorySpace.GMEM, value_type_a, 0, len(shape_a), shape_a, strides_a
|
|
511
|
+
)
|
|
512
|
+
big_gmem_b = mathdx.cublasdx_create_tensor_strided(
|
|
513
|
+
mathdx.CublasdxMemorySpace.GMEM, value_type_b, 0, len(shape_b), shape_b, strides_b
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
device_pipeline = mathdx.cublasdx_create_device_pipeline(
|
|
517
|
+
handle,
|
|
518
|
+
mathdx.CublasdxDevicePipelineType.SUGGESTED,
|
|
519
|
+
depth,
|
|
520
|
+
# FIXED for accumulator, HEURISTIC for epilogue
|
|
521
|
+
mathdx.CublasdxBlockSizeStrategy.FIXED,
|
|
522
|
+
big_gmem_a,
|
|
523
|
+
big_gmem_b,
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
tensors = [big_gmem_a, big_gmem_b]
|
|
527
|
+
pipelines = [device_pipeline]
|
|
528
|
+
|
|
529
|
+
mathdx.cublasdx_finalize_pipelines(len(pipelines), pipelines)
|
|
530
|
+
mathdx.cublasdx_finalize_tensors(len(tensors), tensors)
|
|
531
|
+
|
|
532
|
+
return DescriptorWrapper(device_pipeline, mathdx.cublasdx_destroy_pipeline)
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
@lru_cache
|
|
536
|
+
def generate_tile_pipeline(
|
|
537
|
+
handle,
|
|
538
|
+
device_pipeline_handle,
|
|
539
|
+
):
|
|
540
|
+
tile_pipeline = mathdx.cublasdx_create_tile_pipeline(
|
|
541
|
+
handle,
|
|
542
|
+
mathdx.CublasdxTilePipelineType.PIPELINE_DEFAULT,
|
|
543
|
+
device_pipeline_handle,
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
pipelines = [tile_pipeline]
|
|
547
|
+
|
|
548
|
+
mathdx.cublasdx_finalize_pipelines(len(pipelines), pipelines)
|
|
549
|
+
|
|
550
|
+
return DescriptorWrapper(tile_pipeline, mathdx.cublasdx_destroy_pipeline)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
@lru_cache
|
|
554
|
+
def generate_code(handle, version: ComputeCapability, device_functions: tuple | None = None):
|
|
555
|
+
code = mathdx.commondx_create_code()
|
|
556
|
+
|
|
557
|
+
set_code_target_sm(code, version)
|
|
558
|
+
mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVRTC_ARGS, NVARG_GEN_OPT_LTO)
|
|
559
|
+
if device_functions:
|
|
560
|
+
mathdx.cublasdx_finalize_device_functions(code, len(device_functions), list(device_functions))
|
|
561
|
+
else:
|
|
562
|
+
mathdx.cublasdx_finalize_code(code, handle)
|
|
563
|
+
|
|
564
|
+
return DescriptorWrapper(code, mathdx.commondx_destroy_code)
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
@lru_cache
|
|
568
|
+
def generate_tensor(h: int, tensor_type: str, gmem_alignment: int | None = None) -> DescriptorWrapper:
|
|
569
|
+
tensor = mathdx.cublasdx_create_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_type])
|
|
570
|
+
|
|
571
|
+
if gmem_alignment is not None:
|
|
572
|
+
try:
|
|
573
|
+
mathdx.cublasdx_set_tensor_option_int64(
|
|
574
|
+
tensor,
|
|
575
|
+
mathdx.CublasdxTensorOption.ALIGNMENT_BYTES,
|
|
576
|
+
gmem_alignment,
|
|
577
|
+
)
|
|
578
|
+
except Exception:
|
|
579
|
+
print(f"[WARN] Failed to set {tensor_type} tensor alignment {gmem_alignment}")
|
|
580
|
+
|
|
581
|
+
mathdx.cublasdx_finalize_tensors(1, [tensor])
|
|
582
|
+
|
|
583
|
+
return DescriptorWrapper(tensor, mathdx.cublasdx_destroy_tensor)
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
@lru_cache
|
|
587
|
+
def generate_tensor_like(h: int, src_tensor: int, dtype: np.number) -> DescriptorWrapper:
|
|
588
|
+
dx_type = NP_TYPES_TO_MATHDX_TYPES[dtype]
|
|
589
|
+
dst_tensor = mathdx.cublasdx_make_tensor_like(src_tensor, dx_type)
|
|
590
|
+
mathdx.cublasdx_finalize_tensors(1, [dst_tensor])
|
|
591
|
+
|
|
592
|
+
return DescriptorWrapper(dst_tensor, mathdx.cublasdx_destroy_tensor)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
@lru_cache
|
|
596
|
+
def get_tensor_traits(tensor: int) -> tuple[int, int, int, int]:
|
|
597
|
+
"""Get tensor traits: (uid, logical_size, storage_bytes, alignment)"""
|
|
598
|
+
return (
|
|
599
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensor, mathdx.CublasdxTensorTrait.UID)),
|
|
600
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensor, mathdx.CublasdxTensorTrait.LOGICAL_SIZE)),
|
|
601
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensor, mathdx.CublasdxTensorTrait.STORAGE_BYTES)),
|
|
602
|
+
int(mathdx.cublasdx_get_tensor_trait_int64(tensor, mathdx.CublasdxTensorTrait.ALIGNMENT_BYTES)),
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def generate_function_code(
|
|
607
|
+
MM_handler: int, function_type: mathdx.CublasdxDeviceFunctionType, args: Sequence[int], version: ISAVersion
|
|
608
|
+
):
|
|
609
|
+
function_handler = mathdx.cublasdx_create_device_function(MM_handler, function_type, len(args), list(args))
|
|
610
|
+
symbol = get_str_device_trait(function_handler, mathdx.CublasdxDeviceFunctionTrait.SYMBOL)
|
|
611
|
+
code = generate_code(MM_handler, version, (function_handler,))
|
|
612
|
+
|
|
613
|
+
return code, symbol
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
@lru_cache
|
|
617
|
+
def generate_function_with_pipelines_code(
|
|
618
|
+
MM_handler: int,
|
|
619
|
+
function_type: mathdx.CublasdxDeviceFunctionType,
|
|
620
|
+
tensors: tuple[int],
|
|
621
|
+
pipelines: tuple[int],
|
|
622
|
+
version: ISAVersion,
|
|
623
|
+
):
|
|
624
|
+
function_handler = mathdx.cublasdx_create_device_function_with_pipelines(
|
|
625
|
+
MM_handler,
|
|
626
|
+
function_type,
|
|
627
|
+
len(tensors),
|
|
628
|
+
list(tensors),
|
|
629
|
+
len(pipelines),
|
|
630
|
+
list(pipelines),
|
|
631
|
+
)
|
|
632
|
+
symbol = get_str_device_trait(function_handler, mathdx.CublasdxDeviceFunctionTrait.SYMBOL)
|
|
633
|
+
code = generate_code(MM_handler, version, (function_handler,))
|
|
634
|
+
|
|
635
|
+
return code, symbol
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
def get_function_code(
|
|
639
|
+
MM_handler: int,
|
|
640
|
+
function_type: mathdx.CublasdxDeviceFunctionType,
|
|
641
|
+
args: Sequence[int],
|
|
642
|
+
code_type: CodeType,
|
|
643
|
+
):
|
|
644
|
+
code, symbol = generate_function_code(MM_handler, function_type, args, code_type.cc)
|
|
645
|
+
|
|
646
|
+
# Compile
|
|
647
|
+
lto_fn = get_lto(code.descriptor)
|
|
648
|
+
isa_version = get_isa_version(code.descriptor)
|
|
649
|
+
|
|
650
|
+
lto = Code(code_type, isa_version, lto_fn)
|
|
651
|
+
|
|
652
|
+
return lto, symbol
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
@lru_cache
|
|
656
|
+
def generate_tensors(h, tensor_types):
|
|
657
|
+
type_mem_a = mathdx.cublasdx_create_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[0]])
|
|
658
|
+
type_mem_b = mathdx.cublasdx_create_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[1]])
|
|
659
|
+
type_mem_c = mathdx.cublasdx_create_tensor(h, _TENSOR_TYPE_STR_TO_MATHDX[tensor_types[2]])
|
|
660
|
+
|
|
661
|
+
tensors = [
|
|
662
|
+
type_mem_a,
|
|
663
|
+
type_mem_b,
|
|
664
|
+
type_mem_c,
|
|
665
|
+
]
|
|
666
|
+
|
|
667
|
+
mathdx.cublasdx_finalize_tensors(len(tensors), tensors)
|
|
668
|
+
|
|
669
|
+
target_tensors = CublasdxTensors(type_mem_a, type_mem_b, type_mem_c)
|
|
670
|
+
resp = CublasdxTensorsResponse(target_tensors)
|
|
671
|
+
|
|
672
|
+
weakref.finalize(resp, destroy_tensors, resp.target)
|
|
673
|
+
|
|
674
|
+
return resp
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
def destroy_tensors(tensors: CublasdxTensors):
|
|
678
|
+
mathdx.cublasdx_destroy_tensor(tensors.a)
|
|
679
|
+
mathdx.cublasdx_destroy_tensor(tensors.b)
|
|
680
|
+
mathdx.cublasdx_destroy_tensor(tensors.c)
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
def generate_copy_wait_lto(compute_capability: ComputeCapability):
|
|
684
|
+
return generate_device_function_lto(
|
|
685
|
+
compute_capability,
|
|
686
|
+
mathdx.CublasdxDeviceFunctionType.COPY_WAIT,
|
|
687
|
+
(),
|
|
688
|
+
)
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
@lru_cache
|
|
692
|
+
def generate_device_function_lto(compute_capability: ComputeCapability, function_type: mathdx.CublasdxDeviceFunctionType, args):
|
|
693
|
+
# Create the cuBLASDx descriptor
|
|
694
|
+
h = mathdx.cublasdx_create_descriptor()
|
|
695
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.FUNCTION, mathdx.CublasdxFunction.MM)
|
|
696
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.EXECUTION, mathdx.CommondxExecution.BLOCK)
|
|
697
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.API, mathdx.CublasdxApi.TENSORS)
|
|
698
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.PRECISION, mathdx.CommondxPrecision.F32)
|
|
699
|
+
sm_mathdx = get_mathdx_sm(compute_capability)
|
|
700
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SM, len(sm_mathdx), sm_mathdx)
|
|
701
|
+
mathdx.cublasdx_set_operator_int64(h, mathdx.CublasdxOperatorType.TYPE, mathdx.CublasdxType.REAL)
|
|
702
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.BLOCK_DIM, 3, [32, 1, 1])
|
|
703
|
+
mathdx.cublasdx_set_operator_int64s(h, mathdx.CublasdxOperatorType.SIZE, 3, [1, 1, 1])
|
|
704
|
+
|
|
705
|
+
function = mathdx.cublasdx_create_device_function(h, function_type, len(args), [*args])
|
|
706
|
+
symbol = get_str_device_trait(function, mathdx.CublasdxDeviceFunctionTrait.SYMBOL)
|
|
707
|
+
|
|
708
|
+
# Compile the device function to lto
|
|
709
|
+
code = mathdx.commondx_create_code()
|
|
710
|
+
set_code_target_sm(code, compute_capability)
|
|
711
|
+
mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVRTC_ARGS, NVARG_GEN_OPT_LTO)
|
|
712
|
+
mathdx.cublasdx_finalize_device_functions(code, 1, [function])
|
|
713
|
+
|
|
714
|
+
# Extract the LTOIR
|
|
715
|
+
lto_size = mathdx.commondx_get_code_ltoir_size(code)
|
|
716
|
+
lto = bytearray(lto_size)
|
|
717
|
+
mathdx.commondx_get_code_ltoir(code, lto_size, lto)
|
|
718
|
+
|
|
719
|
+
mathdx.commondx_destroy_code(code)
|
|
720
|
+
mathdx.cublasdx_destroy_device_function(function)
|
|
721
|
+
mathdx.cublasdx_destroy_descriptor(h)
|
|
722
|
+
|
|
723
|
+
return symbol, bytes(lto)
|
|
724
|
+
|
|
725
|
+
|
|
726
|
+
def _compile_blas_device_pipeline_init(
|
|
727
|
+
mm_descriptor: int,
|
|
728
|
+
pipeline_descriptor: int,
|
|
729
|
+
code_type: CodeType,
|
|
730
|
+
) -> tuple[Code, str]:
|
|
731
|
+
assert isinstance(code_type, CodeType)
|
|
732
|
+
|
|
733
|
+
code, symbol = generate_function_with_pipelines_code(
|
|
734
|
+
mm_descriptor,
|
|
735
|
+
mathdx.CublasdxDeviceFunctionType.CREATE,
|
|
736
|
+
(),
|
|
737
|
+
(pipeline_descriptor,),
|
|
738
|
+
code_type.cc,
|
|
739
|
+
)
|
|
740
|
+
|
|
741
|
+
# Compile
|
|
742
|
+
lto_fn = get_lto(code.descriptor)
|
|
743
|
+
isa_version = get_isa_version(code.descriptor)
|
|
744
|
+
|
|
745
|
+
lto = Code(code_type, isa_version, lto_fn)
|
|
746
|
+
|
|
747
|
+
return lto, symbol
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
@lru_cache
|
|
751
|
+
def _compile_blas_device_pipeline_init_kernel(
|
|
752
|
+
mm_descriptor: int,
|
|
753
|
+
pipeline_descriptor: int,
|
|
754
|
+
code_type: CodeType,
|
|
755
|
+
) -> Kernel:
|
|
756
|
+
lto, sym = _compile_blas_device_pipeline_init(mm_descriptor, pipeline_descriptor, code_type=code_type)
|
|
757
|
+
init_pipeline_func = ObjectCode.from_ltoir(lto.data)
|
|
758
|
+
|
|
759
|
+
# CUDA C source code for our kernel
|
|
760
|
+
init_pipeline_source = (
|
|
761
|
+
f"#define create_dev_pipe {sym}\n"
|
|
762
|
+
+ """
|
|
763
|
+
struct libmathdx_tensor_0s_0s { void* ptr; };
|
|
764
|
+
struct libmathdx_pipeline { void* ptr; };
|
|
765
|
+
|
|
766
|
+
extern "C" __device__ void create_dev_pipe(libmathdx_pipeline, libmathdx_tensor_0s_0s, libmathdx_tensor_0s_0s);
|
|
767
|
+
|
|
768
|
+
extern "C" __global__ void create_device_pipeline(void* device_pipeline_ptr, void* ga_storage, void* gb_storage) {
|
|
769
|
+
auto ga = libmathdx_tensor_0s_0s { ga_storage };
|
|
770
|
+
auto gb = libmathdx_tensor_0s_0s { gb_storage };
|
|
771
|
+
auto device_pipeline = libmathdx_pipeline { device_pipeline_ptr };
|
|
772
|
+
create_dev_pipe(device_pipeline, ga, gb);
|
|
773
|
+
}
|
|
774
|
+
"""
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
# Compiler arguments
|
|
778
|
+
arch = f"sm_{code_type.cc.major}{code_type.cc.minor}{code_type.cc.arch}"
|
|
779
|
+
program_options = ProgramOptions(link_time_optimization=True, arch=arch)
|
|
780
|
+
linker_options = LinkerOptions(link_time_optimization=True, arch=arch)
|
|
781
|
+
|
|
782
|
+
# Compile the CUDA code into a program
|
|
783
|
+
program = Program(init_pipeline_source, code_type="c++", options=program_options)
|
|
784
|
+
compiled_program = program.compile(target_type="ltoir")
|
|
785
|
+
|
|
786
|
+
linker = Linker(compiled_program, init_pipeline_func, options=linker_options)
|
|
787
|
+
linked_program = linker.link("cubin")
|
|
788
|
+
|
|
789
|
+
# Get the specific kernel function we want to use
|
|
790
|
+
kernel = linked_program.get_kernel("create_device_pipeline")
|
|
791
|
+
|
|
792
|
+
return kernel
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
def _compile_blas_device_pipeline_destroy(
|
|
796
|
+
mm_descriptor: int,
|
|
797
|
+
pipeline_descriptor: int,
|
|
798
|
+
code_type: CodeType,
|
|
799
|
+
) -> tuple[Code, str]:
|
|
800
|
+
code, symbol = generate_function_with_pipelines_code(
|
|
801
|
+
mm_descriptor,
|
|
802
|
+
mathdx.CublasdxDeviceFunctionType.DESTROY,
|
|
803
|
+
(),
|
|
804
|
+
(pipeline_descriptor,),
|
|
805
|
+
code_type.cc,
|
|
806
|
+
)
|
|
807
|
+
|
|
808
|
+
# Compile
|
|
809
|
+
lto_fn = get_lto(code.descriptor)
|
|
810
|
+
isa_version = get_isa_version(code.descriptor)
|
|
811
|
+
|
|
812
|
+
lto = Code(code_type, isa_version, lto_fn)
|
|
813
|
+
|
|
814
|
+
return lto, symbol
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
@lru_cache
|
|
818
|
+
def _compile_blas_device_pipeline_destroy_kernel(
|
|
819
|
+
mm_descriptor: int,
|
|
820
|
+
pipeline_descriptor: int,
|
|
821
|
+
code_type: CodeType,
|
|
822
|
+
) -> Kernel:
|
|
823
|
+
lto, sym = _compile_blas_device_pipeline_destroy(
|
|
824
|
+
mm_descriptor=mm_descriptor,
|
|
825
|
+
pipeline_descriptor=pipeline_descriptor,
|
|
826
|
+
code_type=code_type,
|
|
827
|
+
)
|
|
828
|
+
destroy_pipeline_func = ObjectCode.from_ltoir(lto.data)
|
|
829
|
+
|
|
830
|
+
# CUDA C source code for our kernel
|
|
831
|
+
destroy_pipeline_source = (
|
|
832
|
+
f"#define destroy_dev_pipe {sym}\n"
|
|
833
|
+
+ """
|
|
834
|
+
struct libmathdx_pipeline { void* ptr; };
|
|
835
|
+
|
|
836
|
+
extern "C" __device__ void destroy_dev_pipe(libmathdx_pipeline);
|
|
837
|
+
|
|
838
|
+
extern "C" __global__ void destroy_device_pipeline(void* device_pipeline_ptr) {
|
|
839
|
+
auto device_pipeline = libmathdx_pipeline { device_pipeline_ptr };
|
|
840
|
+
destroy_dev_pipe(device_pipeline);
|
|
841
|
+
}
|
|
842
|
+
"""
|
|
843
|
+
)
|
|
844
|
+
|
|
845
|
+
# Compiler arguments
|
|
846
|
+
arch = f"sm_{code_type.cc.major}{code_type.cc.minor}{code_type.cc.arch}"
|
|
847
|
+
program_options = ProgramOptions(link_time_optimization=True, arch=arch)
|
|
848
|
+
linker_options = LinkerOptions(link_time_optimization=True, arch=arch)
|
|
849
|
+
|
|
850
|
+
# Compile the CUDA code into a program
|
|
851
|
+
program = Program(destroy_pipeline_source, code_type="c++", options=program_options)
|
|
852
|
+
compiled_program = program.compile(target_type="ltoir")
|
|
853
|
+
|
|
854
|
+
linker = Linker(compiled_program, destroy_pipeline_func, options=linker_options)
|
|
855
|
+
linked_program = linker.link("cubin")
|
|
856
|
+
|
|
857
|
+
# Get the specific kernel function we want to use
|
|
858
|
+
kernel = linked_program.get_kernel("destroy_device_pipeline")
|
|
859
|
+
|
|
860
|
+
return kernel
|