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,766 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""Internal interface for epilog input handling."""
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"EPILOG_INPUT_HANDLERS_MAP",
|
|
9
|
+
"EPILOG_OUTPUT_HANDLERS_MAP",
|
|
10
|
+
"BiasHandler",
|
|
11
|
+
"BgradHandler",
|
|
12
|
+
"ReluAuxHandler",
|
|
13
|
+
"DReluAuxHandler",
|
|
14
|
+
"GeluAuxHandler",
|
|
15
|
+
"DGeluAuxHandler",
|
|
16
|
+
"EpilogInputHandler",
|
|
17
|
+
"EpilogOutputHandler",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
import math
|
|
21
|
+
from abc import abstractmethod
|
|
22
|
+
from typing import Protocol, runtime_checkable
|
|
23
|
+
|
|
24
|
+
from nvmath.bindings import cublasLt as cublaslt
|
|
25
|
+
from nvmath.internal import typemaps
|
|
26
|
+
from nvmath.linalg._internal.utils import axis_order_in_memory, calculate_strides, check_batch_tileable
|
|
27
|
+
|
|
28
|
+
Epilog = cublaslt.Epilogue
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@runtime_checkable
|
|
32
|
+
class EpilogInputHandler(Protocol):
|
|
33
|
+
"""
|
|
34
|
+
Protocol for epilog handler input validation and setting the appropriate MM descriptor
|
|
35
|
+
attributes.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
@abstractmethod
|
|
39
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def name(self):
|
|
45
|
+
"""
|
|
46
|
+
The name of the epilog input that is handled (bias, ...).
|
|
47
|
+
"""
|
|
48
|
+
raise NotImplementedError
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def order(self) -> cublaslt.Order | None:
|
|
53
|
+
"""
|
|
54
|
+
The result order that is needed by this epilog (cublaslt.Order or None, if no
|
|
55
|
+
restriction on order).
|
|
56
|
+
"""
|
|
57
|
+
raise NotImplementedError
|
|
58
|
+
|
|
59
|
+
@abstractmethod
|
|
60
|
+
def validate(self, epilog_input):
|
|
61
|
+
"""
|
|
62
|
+
Validate the provided epilog input.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
epilog_input: The epilog input to validate.
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
raise NotImplementedError
|
|
69
|
+
|
|
70
|
+
@abstractmethod
|
|
71
|
+
def update(self, mm_desc_ifc, epilog_input):
|
|
72
|
+
"""
|
|
73
|
+
Update the matmul descriptor attributes for this epilog from the given input.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
mm_desc_ifc: The MM descriptor to update, provided as
|
|
77
|
+
a MatmulDescInterface object.
|
|
78
|
+
epilog_input: The epilog input.
|
|
79
|
+
"""
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def update_pointer(self, mm_desc_ifc, data_ptr) -> None:
|
|
84
|
+
"""
|
|
85
|
+
Update the matmul descriptor data pointer for this epilog.
|
|
86
|
+
|
|
87
|
+
Unlike ``update``, this only sets the pointer, assuming all other
|
|
88
|
+
descriptor attributes (batch stride, leading dimension, data type)
|
|
89
|
+
are already valid.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
mm_desc_ifc: The MM descriptor to update, provided
|
|
93
|
+
as a MatmulDescInterface object.
|
|
94
|
+
data_ptr: The device pointer value to set.
|
|
95
|
+
"""
|
|
96
|
+
raise NotImplementedError
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@runtime_checkable
|
|
100
|
+
class EpilogOutputHandler(Protocol):
|
|
101
|
+
"""
|
|
102
|
+
Protocol for epilog handler output validation and setting the appropriate MM descriptor
|
|
103
|
+
attributes.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
108
|
+
raise NotImplementedError
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
@abstractmethod
|
|
112
|
+
def name(self):
|
|
113
|
+
"""
|
|
114
|
+
The name of the epilog output that is handled (relu_aux, gelu_aux, bgrad, bragda,
|
|
115
|
+
bgradb, ...).
|
|
116
|
+
"""
|
|
117
|
+
raise NotImplementedError
|
|
118
|
+
|
|
119
|
+
@property
|
|
120
|
+
@abstractmethod
|
|
121
|
+
def order(self):
|
|
122
|
+
"""
|
|
123
|
+
The result order that is needed by this epilog (cublaslt.Order or None, if no
|
|
124
|
+
restriction on order).
|
|
125
|
+
"""
|
|
126
|
+
raise NotImplementedError
|
|
127
|
+
|
|
128
|
+
@abstractmethod
|
|
129
|
+
def attributes(self):
|
|
130
|
+
"""
|
|
131
|
+
The shape, stride, and dtype name of the output tensor.
|
|
132
|
+
"""
|
|
133
|
+
raise NotImplementedError
|
|
134
|
+
|
|
135
|
+
@abstractmethod
|
|
136
|
+
def update(self, mm_desc_ifc):
|
|
137
|
+
"""
|
|
138
|
+
Update all the attributes for this epilog, except the pointer.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
mm_desc_ifc: The MM descriptor to update, provided as a MatmulDescInterface
|
|
142
|
+
object.
|
|
143
|
+
"""
|
|
144
|
+
raise NotImplementedError
|
|
145
|
+
|
|
146
|
+
@abstractmethod
|
|
147
|
+
def update_pointer(self, mm_desc_ifc, ptr):
|
|
148
|
+
"""
|
|
149
|
+
Set the pointer for this epilog.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
mm_desc_ifc: The MM descriptor to update, provided as a MatmulDescInterface
|
|
153
|
+
object.
|
|
154
|
+
|
|
155
|
+
ptr: The pointer to set.
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
raise NotImplementedError
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class BiasHandler(EpilogInputHandler):
|
|
162
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
163
|
+
self.logger = logger
|
|
164
|
+
self.mm_traits = mm_traits
|
|
165
|
+
|
|
166
|
+
assert enumerator in [
|
|
167
|
+
Epilog.BIAS,
|
|
168
|
+
Epilog.RELU_BIAS,
|
|
169
|
+
Epilog.RELU_AUX_BIAS,
|
|
170
|
+
Epilog.GELU_BIAS,
|
|
171
|
+
Epilog.GELU_AUX_BIAS,
|
|
172
|
+
], "Internal error."
|
|
173
|
+
self.enumerator = enumerator
|
|
174
|
+
|
|
175
|
+
self.d_dtype_name = d_dtype_name
|
|
176
|
+
|
|
177
|
+
self.batch_offset = None
|
|
178
|
+
|
|
179
|
+
self._name = "bias"
|
|
180
|
+
|
|
181
|
+
self.version = cublaslt.get_version()
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def name(self):
|
|
185
|
+
return self._name
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
def order(self):
|
|
189
|
+
return cublaslt.Order.COL
|
|
190
|
+
|
|
191
|
+
def validate(self, bias_tensor):
|
|
192
|
+
# The bias_tensor must be of rank 1, or rank 2 with (M, 1) or batched versions of
|
|
193
|
+
# the latter (..., M, 1) consistent with the C operand.
|
|
194
|
+
|
|
195
|
+
bias_shape = list(bias_tensor.shape)
|
|
196
|
+
bias_strides = list(bias_tensor.strides)
|
|
197
|
+
|
|
198
|
+
mm_traits = self.mm_traits
|
|
199
|
+
|
|
200
|
+
# Determine the rank of bias_tensor input.
|
|
201
|
+
bias_batch_shape, bias_mm_shape = bias_shape[:-2], bias_shape[-2:]
|
|
202
|
+
bias_batch_strides, bias_mm_strides = bias_strides[:-2], bias_strides[-2:]
|
|
203
|
+
if len(bias_mm_shape) == 1:
|
|
204
|
+
s, d = bias_mm_shape[0], bias_mm_strides[0]
|
|
205
|
+
bias_mm_shape += [1]
|
|
206
|
+
bias_mm_strides += [s * d]
|
|
207
|
+
self.logger.debug(f"The MM shape for the bias is {bias_mm_shape} with strides {bias_mm_strides}.")
|
|
208
|
+
|
|
209
|
+
Mb, Nb = bias_mm_shape
|
|
210
|
+
if Mb != mm_traits.M:
|
|
211
|
+
raise ValueError(f"The M dimension of the bias vector ({Mb}) must match the M dimension of A.")
|
|
212
|
+
|
|
213
|
+
if Nb != 1:
|
|
214
|
+
raise ValueError(f"The N dimension of the bias vector ({Nb}) must be equal to 1.")
|
|
215
|
+
|
|
216
|
+
# Check if the bias_tensor batch shape and axis order match that of the MM, and it's
|
|
217
|
+
# tileable.
|
|
218
|
+
if len(bias_batch_shape) > 0 and bias_batch_shape != mm_traits.batch_shape:
|
|
219
|
+
raise ValueError(
|
|
220
|
+
f"The batch dimensions of the bias {bias_batch_shape} must match with that of the matrix multiplication "
|
|
221
|
+
f"definition {mm_traits.batch_shape}."
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if self.version < 110902 and len(bias_batch_shape) == 0 and len(mm_traits.batch_shape) > 0:
|
|
225
|
+
raise ValueError(
|
|
226
|
+
f"Bias broadcasting is not supported in cuBLASLt version < 110902 (you have version {self.version})."
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if len(bias_batch_shape) > 0:
|
|
230
|
+
if self.version < 11703:
|
|
231
|
+
raise ValueError(
|
|
232
|
+
f"Batch dimensions are not supported for the bias tensor in cuBLASLt version < 11703 "
|
|
233
|
+
f"(you have version {self.version})."
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
bias_batch_axis_order = axis_order_in_memory(bias_batch_strides)
|
|
237
|
+
if bias_batch_axis_order != mm_traits.batch_axis_order:
|
|
238
|
+
raise ValueError(
|
|
239
|
+
f"The batch axis order of the bias {bias_batch_axis_order} must match with that "
|
|
240
|
+
f"of the other operands {mm_traits.batch_axis_order}."
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
if not check_batch_tileable(bias_batch_shape, bias_batch_strides):
|
|
244
|
+
message = (
|
|
245
|
+
f"The batch layout for bias corresponding to shape = {bias_batch_shape} "
|
|
246
|
+
f"and strides = {bias_batch_strides} is currently not supported because it is not tileable."
|
|
247
|
+
)
|
|
248
|
+
raise ValueError(message)
|
|
249
|
+
|
|
250
|
+
if bias_mm_strides[0] != 1:
|
|
251
|
+
raise ValueError(
|
|
252
|
+
f"The stride of the bias {bias_strides} must be 1 along the dimension {len(bias_strides) - 2}, "
|
|
253
|
+
f"which corresponds to the M dimension."
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
self.batch_offset = min(bias_batch_strides) if bias_batch_strides else 0 # bias broadcast
|
|
257
|
+
|
|
258
|
+
def update_pointer(self, mm_desc_ifc, data_ptr):
|
|
259
|
+
mm_desc_ifc.bias_pointer = data_ptr
|
|
260
|
+
|
|
261
|
+
def update(self, mm_desc_ifc, bias_tensor):
|
|
262
|
+
# Set the bias pointer.
|
|
263
|
+
mm_desc_ifc.bias_pointer = bias_tensor.data_ptr
|
|
264
|
+
# Set the bias batch offset.
|
|
265
|
+
mm_desc_ifc.bias_batch_stride = self.batch_offset
|
|
266
|
+
# Set the bias data type.
|
|
267
|
+
if bias_tensor.dtype != self.d_dtype_name:
|
|
268
|
+
if self.version < 111103:
|
|
269
|
+
raise ValueError(
|
|
270
|
+
f"The bias tensor dtype '{bias_tensor.dtype}' must be the same as the result dtype "
|
|
271
|
+
f"'{self.d_dtype_name}' in cuBLASLt version < 111103 (you have {self.version})."
|
|
272
|
+
)
|
|
273
|
+
mm_desc_ifc.bias_data_type = typemaps.NAME_TO_DATA_TYPE[bias_tensor.dtype]
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def round_up(m, base):
|
|
277
|
+
return m + (base - m) % base
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def relu_aux_mm_shape(m, n):
|
|
281
|
+
"""
|
|
282
|
+
Return the RELU auxiliary bitmask matrix shape when stored as uint8 and M is padded to
|
|
283
|
+
128-bit/16-byte multiples.
|
|
284
|
+
"""
|
|
285
|
+
# Store bitflag mask using int8 dtype, padded to (128//8 ==) 16 bytes.
|
|
286
|
+
m = round_up(math.ceil(m / 8), base=16)
|
|
287
|
+
return m, n
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def gelu_aux_mm_shape(m, n):
|
|
291
|
+
"""
|
|
292
|
+
Return the GELU auxiliary matrix shape when M is padded to 8-byte multiples.
|
|
293
|
+
"""
|
|
294
|
+
m = round_up(m, base=8)
|
|
295
|
+
return m, n
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
class ReluAuxHandler(EpilogOutputHandler):
|
|
299
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
300
|
+
self.logger = logger
|
|
301
|
+
self.mm_traits = mm_traits
|
|
302
|
+
|
|
303
|
+
assert enumerator in [Epilog.RELU_AUX, Epilog.RELU_AUX_BIAS], "Internal error."
|
|
304
|
+
self.enumerator = enumerator
|
|
305
|
+
|
|
306
|
+
self._name = "relu_aux"
|
|
307
|
+
|
|
308
|
+
m, n = relu_aux_mm_shape(mm_traits.M, mm_traits.N)
|
|
309
|
+
batch_len = len(mm_traits.batch_axis_order)
|
|
310
|
+
|
|
311
|
+
self.aux_shape = mm_traits.batch_shape + [m, n]
|
|
312
|
+
aux_axis_order = [batch_len, batch_len + 1] + list(mm_traits.batch_axis_order) # Column order for the bitmask.
|
|
313
|
+
self.aux_strides = calculate_strides(self.aux_shape, aux_axis_order)
|
|
314
|
+
if aux_dtype_name is not None:
|
|
315
|
+
raise ValueError("Custom type for auxiliary outputs is not supported for RELU epilogs.")
|
|
316
|
+
self.aux_dtype_name = "uint8"
|
|
317
|
+
|
|
318
|
+
# We store bitmask using int8 dtype but the values below are in number of elements.
|
|
319
|
+
self.aux_ld = m * 8 # should be consistent with order (currently COL).
|
|
320
|
+
self.aux_batch_offset = m * 8 * n
|
|
321
|
+
|
|
322
|
+
@property
|
|
323
|
+
def name(self):
|
|
324
|
+
return self._name
|
|
325
|
+
|
|
326
|
+
@property
|
|
327
|
+
def order(self):
|
|
328
|
+
return cublaslt.Order.COL
|
|
329
|
+
|
|
330
|
+
def attributes(self):
|
|
331
|
+
return self.aux_shape, self.aux_strides, self.aux_dtype_name
|
|
332
|
+
|
|
333
|
+
def update(self, mm_desc_ifc):
|
|
334
|
+
# Set the aux LD.
|
|
335
|
+
mm_desc_ifc.epilogue_aux_ld = self.aux_ld
|
|
336
|
+
# Set the aux batch offset.
|
|
337
|
+
mm_desc_ifc.epilogue_aux_batch_stride = self.aux_batch_offset
|
|
338
|
+
# Set the pointer to 0x1 to bypass the cuBLAS check.
|
|
339
|
+
mm_desc_ifc.epilogue_aux_pointer = 0x1
|
|
340
|
+
|
|
341
|
+
def update_pointer(self, mm_desc_ifc, ptr):
|
|
342
|
+
# Set the aux pointer.
|
|
343
|
+
mm_desc_ifc.epilogue_aux_pointer = ptr
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
class GeluAuxHandler(EpilogOutputHandler):
|
|
347
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
348
|
+
self.logger = logger
|
|
349
|
+
self.mm_traits = mm_traits
|
|
350
|
+
|
|
351
|
+
assert enumerator in [Epilog.GELU_AUX, Epilog.GELU_AUX_BIAS], "Internal error."
|
|
352
|
+
self.enumerator = enumerator
|
|
353
|
+
|
|
354
|
+
self.d_dtype_name = d_dtype_name
|
|
355
|
+
|
|
356
|
+
self._name = "gelu_aux"
|
|
357
|
+
|
|
358
|
+
m, n = gelu_aux_mm_shape(mm_traits.M, mm_traits.N)
|
|
359
|
+
batch_len = len(mm_traits.batch_axis_order)
|
|
360
|
+
|
|
361
|
+
self.aux_shape = mm_traits.batch_shape + [m, n]
|
|
362
|
+
aux_axis_order = [batch_len, batch_len + 1] + list(mm_traits.batch_axis_order) # Column order for the GELU inputs.
|
|
363
|
+
self.aux_strides = calculate_strides(self.aux_shape, aux_axis_order)
|
|
364
|
+
|
|
365
|
+
self.version = cublaslt.get_version()
|
|
366
|
+
|
|
367
|
+
if aux_dtype_name:
|
|
368
|
+
if self.version < 120800:
|
|
369
|
+
raise ValueError("Specifying custom AUX data type is not supported for cuBLAS < 12.8.")
|
|
370
|
+
self.aux_dtype_name = aux_dtype_name
|
|
371
|
+
else:
|
|
372
|
+
self.aux_dtype_name = c_dtype_name if "float8" in d_dtype_name else d_dtype_name
|
|
373
|
+
|
|
374
|
+
self.aux_ld = m # should be consistent with order (currently COL).
|
|
375
|
+
self.aux_batch_offset = m * n
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def name(self):
|
|
379
|
+
return self._name
|
|
380
|
+
|
|
381
|
+
@property
|
|
382
|
+
def order(self):
|
|
383
|
+
return cublaslt.Order.COL
|
|
384
|
+
|
|
385
|
+
def attributes(self):
|
|
386
|
+
return self.aux_shape, self.aux_strides, self.aux_dtype_name
|
|
387
|
+
|
|
388
|
+
def update(self, mm_desc_ifc):
|
|
389
|
+
# Set the aux LD.
|
|
390
|
+
mm_desc_ifc.epilogue_aux_ld = self.aux_ld
|
|
391
|
+
# Set the aux batch offset.
|
|
392
|
+
mm_desc_ifc.epilogue_aux_batch_stride = self.aux_batch_offset
|
|
393
|
+
# Set the pointer to 0x1 to bypass the cuBLAS check.
|
|
394
|
+
mm_desc_ifc.epilogue_aux_pointer = 0x1
|
|
395
|
+
if self.aux_dtype_name is not None and self.version >= 120800:
|
|
396
|
+
mm_desc_ifc.epilogue_aux_data_type = typemaps.NAME_TO_DATA_TYPE[self.aux_dtype_name]
|
|
397
|
+
|
|
398
|
+
def update_pointer(self, mm_desc_ifc, ptr):
|
|
399
|
+
# Set the aux pointer.
|
|
400
|
+
mm_desc_ifc.epilogue_aux_pointer = ptr
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
class BgradHandler(EpilogOutputHandler):
|
|
404
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
405
|
+
self.logger = logger
|
|
406
|
+
self.mm_traits = mm_traits
|
|
407
|
+
|
|
408
|
+
assert enumerator in [Epilog.DRELU_BGRAD, Epilog.DGELU_BGRAD, Epilog.BGRADA, Epilog.BGRADB], "Internal error."
|
|
409
|
+
self.enumerator = enumerator
|
|
410
|
+
|
|
411
|
+
version = cublaslt.get_version()
|
|
412
|
+
if mm_traits.K == 1 and enumerator in [Epilog.BGRADA, Epilog.BGRADB] and version < 120304:
|
|
413
|
+
raise ValueError(
|
|
414
|
+
f"K=1 is not supported for {enumerator.name} epilog in cuBLASLt version < 120304 (you have version {version})."
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
self._name = enumerator.name.lower()
|
|
418
|
+
|
|
419
|
+
if aux_dtype_name is not None:
|
|
420
|
+
raise ValueError("Custom type for auxiliary outputs is not supported for BGRAD epilogs.")
|
|
421
|
+
|
|
422
|
+
m = mm_traits.N if enumerator == Epilog.BGRADB else mm_traits.M
|
|
423
|
+
batch_len = len(mm_traits.batch_axis_order)
|
|
424
|
+
|
|
425
|
+
self.bgrad_shape = shape = [m]
|
|
426
|
+
if mm_traits.batch_shape:
|
|
427
|
+
shape = shape + [1]
|
|
428
|
+
self.bgrad_shape = mm_traits.batch_shape + self.bgrad_shape + [1]
|
|
429
|
+
|
|
430
|
+
bgrad_axis_order = [batch_len + a for a in range(len(shape))] + list(mm_traits.batch_axis_order) # Column order.
|
|
431
|
+
self.bgrad_strides = calculate_strides(self.bgrad_shape, bgrad_axis_order)
|
|
432
|
+
|
|
433
|
+
self.d_dtype_name = d_dtype_name
|
|
434
|
+
self.bgrad_dtype_name = d_dtype_name
|
|
435
|
+
self.bgrad_batch_offset = m
|
|
436
|
+
|
|
437
|
+
@property
|
|
438
|
+
def name(self):
|
|
439
|
+
return self._name
|
|
440
|
+
|
|
441
|
+
@property
|
|
442
|
+
def order(self):
|
|
443
|
+
"""
|
|
444
|
+
For BGRADA or BGRADB, there is no layout constraint but DRELU_BGRAD and DGELU_BGRAD
|
|
445
|
+
require COL. However currently use COL for BGRADB as well to workaround a library
|
|
446
|
+
issue.
|
|
447
|
+
"""
|
|
448
|
+
if self.enumerator in [Epilog.DRELU_BGRAD, Epilog.DGELU_BGRAD, Epilog.BGRADB]:
|
|
449
|
+
return cublaslt.Order.COL
|
|
450
|
+
return None
|
|
451
|
+
|
|
452
|
+
def attributes(self):
|
|
453
|
+
return self.bgrad_shape, self.bgrad_strides, self.bgrad_dtype_name
|
|
454
|
+
|
|
455
|
+
def update(self, mm_desc_ifc):
|
|
456
|
+
# Set the bgrad batch offset.
|
|
457
|
+
mm_desc_ifc.bias_batch_stride = self.bgrad_batch_offset
|
|
458
|
+
# The bgrad data type is by default the data type of the result for all the cases we
|
|
459
|
+
# support.
|
|
460
|
+
assert self.bgrad_dtype_name == self.d_dtype_name, "Internal error."
|
|
461
|
+
|
|
462
|
+
def update_pointer(self, mm_desc_ifc, ptr):
|
|
463
|
+
# Set the bgrad pointer.
|
|
464
|
+
mm_desc_ifc.bias_pointer = ptr
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
class DReluAuxHandler(EpilogInputHandler):
|
|
468
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
469
|
+
self.logger = logger
|
|
470
|
+
self.mm_traits = mm_traits
|
|
471
|
+
|
|
472
|
+
assert enumerator in [Epilog.DRELU, Epilog.DRELU_BGRAD], "Internal error."
|
|
473
|
+
self.enumerator = enumerator
|
|
474
|
+
|
|
475
|
+
self.batch_offset = None
|
|
476
|
+
|
|
477
|
+
self._name = "relu_aux"
|
|
478
|
+
|
|
479
|
+
# The bitmask int8 matrix shape, including padding.
|
|
480
|
+
self.mm_m, self.mm_n = relu_aux_mm_shape(mm_traits.M, mm_traits.N)
|
|
481
|
+
|
|
482
|
+
# We store bitmask using int8 dtype but the values below are in number of elements.
|
|
483
|
+
self.aux_ld = self.mm_m * 8 # should be consistent with order (currently COL).
|
|
484
|
+
|
|
485
|
+
# K=1 is not supported by cuBLAS
|
|
486
|
+
if mm_traits.K == 1:
|
|
487
|
+
raise ValueError("K=1 is not supported for DRELU epilogs")
|
|
488
|
+
|
|
489
|
+
@property
|
|
490
|
+
def name(self):
|
|
491
|
+
return self._name
|
|
492
|
+
|
|
493
|
+
@property
|
|
494
|
+
def order(self):
|
|
495
|
+
return cublaslt.Order.COL
|
|
496
|
+
|
|
497
|
+
def validate(self, relu_aux_tensor):
|
|
498
|
+
# The relu_aux_tensor must be of rank 2 or its batched version of the latter (...,
|
|
499
|
+
# M, N).
|
|
500
|
+
relu_aux_shape = list(relu_aux_tensor.shape)
|
|
501
|
+
relu_aux_strides = list(relu_aux_tensor.strides)
|
|
502
|
+
|
|
503
|
+
# The dtype must be uint8.
|
|
504
|
+
if relu_aux_tensor.dtype != "uint8":
|
|
505
|
+
raise ValueError(
|
|
506
|
+
f"The dtype of the RELU auxiliary input for epilog {self.enumerator.name} must be 'uint8'. "
|
|
507
|
+
f"The epilog input's dtype is '{relu_aux_tensor.dtype}'."
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
mm_traits = self.mm_traits
|
|
511
|
+
|
|
512
|
+
# Determine the rank of relu_aux_tensor input.
|
|
513
|
+
relu_aux_batch_shape, relu_aux_mm_shape = relu_aux_shape[:-2], relu_aux_shape[-2:]
|
|
514
|
+
relu_aux_batch_strides, relu_aux_mm_strides = relu_aux_strides[:-2], relu_aux_strides[-2:]
|
|
515
|
+
|
|
516
|
+
# The MM shape must match, the MM must be in col order, and the batch order must
|
|
517
|
+
# match.
|
|
518
|
+
Ma, Na = relu_aux_mm_shape
|
|
519
|
+
if Ma != self.mm_m or Na != self.mm_n:
|
|
520
|
+
raise ValueError(
|
|
521
|
+
f"The auxiliary epilog input for epilog {self.enumerator.name} must have the MM shape "
|
|
522
|
+
f"(..., {self.mm_m}, {self.mm_n}). The epilog input's MM shape is (..., {Ma}, {Na})."
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
# Check if the relu_aux_tensor batch shape and axis order match that of the MM, and
|
|
526
|
+
# it's tileable.
|
|
527
|
+
if len(relu_aux_batch_shape) > 0:
|
|
528
|
+
if relu_aux_batch_shape != mm_traits.batch_shape:
|
|
529
|
+
raise ValueError(
|
|
530
|
+
f"The batch dimensions of the RELU auxiliary input {relu_aux_batch_shape} must match with that "
|
|
531
|
+
f"of the matrix multiplication definition {mm_traits.batch_shape}."
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
if (relu_aux_batch_axis_order := axis_order_in_memory(relu_aux_batch_strides)) != mm_traits.batch_axis_order:
|
|
535
|
+
raise ValueError(
|
|
536
|
+
f"The batch axis order of the RELU auxiliary input {relu_aux_batch_axis_order} must match with that "
|
|
537
|
+
f"of the other operands {mm_traits.batch_axis_order}."
|
|
538
|
+
)
|
|
539
|
+
|
|
540
|
+
if not check_batch_tileable(relu_aux_batch_shape, relu_aux_batch_strides):
|
|
541
|
+
message = (
|
|
542
|
+
f"The batch layout for RELU auxiliary input corresponding to shape = {relu_aux_batch_shape} "
|
|
543
|
+
f"and strides = {relu_aux_batch_strides} is currently not supported because it is not tileable."
|
|
544
|
+
)
|
|
545
|
+
raise ValueError(message)
|
|
546
|
+
|
|
547
|
+
if relu_aux_mm_strides[0] != 1:
|
|
548
|
+
raise ValueError(
|
|
549
|
+
f"The stride of the RELU auxiliary input {relu_aux_strides} must be 1 "
|
|
550
|
+
f"along the dimension {len(relu_aux_strides) - 2}, which corresponds to the M dimension."
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
# Convert from bits to elements.
|
|
554
|
+
self.batch_offset = min(relu_aux_batch_strides) * 8 if relu_aux_batch_strides else 0 # relu_aux broadcast
|
|
555
|
+
|
|
556
|
+
if self.batch_offset > 0:
|
|
557
|
+
assert self.batch_offset >= self.mm_m * 8 * self.mm_n, "Tensor data must not overlap."
|
|
558
|
+
|
|
559
|
+
def update_pointer(self, mm_desc_ifc, data_ptr):
|
|
560
|
+
mm_desc_ifc.epilogue_aux_pointer = data_ptr
|
|
561
|
+
|
|
562
|
+
def update(self, mm_desc_ifc, relu_aux_tensor):
|
|
563
|
+
# Set the epilog aux pointer.
|
|
564
|
+
mm_desc_ifc.epilogue_aux_pointer = relu_aux_tensor.data_ptr
|
|
565
|
+
# Set the relu_aux batch offset.
|
|
566
|
+
mm_desc_ifc.epilogue_aux_batch_stride = self.batch_offset
|
|
567
|
+
# Set the aux LD.
|
|
568
|
+
mm_desc_ifc.epilogue_aux_ld = self.aux_ld
|
|
569
|
+
# The relu aux data type is bitmask, don't set.
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
class DGeluAuxHandler(EpilogInputHandler):
|
|
573
|
+
def __init__(self, logger, mm_traits, enumerator, c_dtype_name, d_dtype_name, aux_dtype_name):
|
|
574
|
+
self.logger = logger
|
|
575
|
+
self.mm_traits = mm_traits
|
|
576
|
+
|
|
577
|
+
assert enumerator in [Epilog.DGELU, Epilog.DGELU_BGRAD], "Internal error."
|
|
578
|
+
self.enumerator = enumerator
|
|
579
|
+
|
|
580
|
+
self.d_dtype_name = d_dtype_name
|
|
581
|
+
|
|
582
|
+
self.batch_offset = None
|
|
583
|
+
|
|
584
|
+
self._name = "gelu_aux"
|
|
585
|
+
|
|
586
|
+
# The GELU aux matrix shape, including padding.
|
|
587
|
+
self.mm_m, self.mm_n = gelu_aux_mm_shape(mm_traits.M, mm_traits.N)
|
|
588
|
+
|
|
589
|
+
self.aux_ld = self.mm_m # should be consistent with order (currently COL).
|
|
590
|
+
|
|
591
|
+
self.version = cublaslt.get_version()
|
|
592
|
+
|
|
593
|
+
# K=1 is not supported by cuBLAS
|
|
594
|
+
if mm_traits.K == 1:
|
|
595
|
+
raise ValueError("K=1 is not supported for DGELU epilogs")
|
|
596
|
+
|
|
597
|
+
@property
|
|
598
|
+
def name(self):
|
|
599
|
+
return self._name
|
|
600
|
+
|
|
601
|
+
@property
|
|
602
|
+
def order(self):
|
|
603
|
+
return cublaslt.Order.COL
|
|
604
|
+
|
|
605
|
+
def validate(self, gelu_aux_tensor):
|
|
606
|
+
# The gelu_aux_tensor must be of rank 2 or its batched version of the latter (...,
|
|
607
|
+
# M, N).
|
|
608
|
+
gelu_aux_shape = list(gelu_aux_tensor.shape)
|
|
609
|
+
gelu_aux_strides = list(gelu_aux_tensor.strides)
|
|
610
|
+
|
|
611
|
+
# The dtype must be the same as that of D.
|
|
612
|
+
if gelu_aux_tensor.dtype != self.d_dtype_name:
|
|
613
|
+
raise ValueError(
|
|
614
|
+
f"The dtype of the GELU auxiliary input for epilog {self.enumerator.name} must be '{self.d_dtype_name}'. "
|
|
615
|
+
f"The epilog input's dtype is '{gelu_aux_tensor.dtype}'."
|
|
616
|
+
)
|
|
617
|
+
|
|
618
|
+
mm_traits = self.mm_traits
|
|
619
|
+
|
|
620
|
+
# Determine the rank of gelu_aux_tensor input.
|
|
621
|
+
gelu_aux_batch_shape, gelu_aux_mm_shape = gelu_aux_shape[:-2], gelu_aux_shape[-2:]
|
|
622
|
+
gelu_aux_batch_strides, gelu_aux_mm_strides = gelu_aux_strides[:-2], gelu_aux_strides[-2:]
|
|
623
|
+
|
|
624
|
+
# The MM shape must match, the MM must be in col order, and the batch order must
|
|
625
|
+
# match.
|
|
626
|
+
Ma, Na = gelu_aux_mm_shape
|
|
627
|
+
if Ma != self.mm_m or Na != self.mm_n:
|
|
628
|
+
raise ValueError(
|
|
629
|
+
f"The auxiliary epilog input for epilog {self.enumerator.name} must have "
|
|
630
|
+
f"the MM shape (..., {self.mm_m}, {self.mm_n}). The epilog input's MM shape is (..., {Ma}, {Na})."
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
# Check if the gelu_aux_tensor batch shape and axis order match that of the MM, and
|
|
634
|
+
# it's tileable.
|
|
635
|
+
if len(gelu_aux_batch_shape) > 0:
|
|
636
|
+
if gelu_aux_batch_shape != mm_traits.batch_shape:
|
|
637
|
+
raise ValueError(
|
|
638
|
+
f"The batch dimensions of the GELU auxiliary input {gelu_aux_batch_shape} must match with that "
|
|
639
|
+
f"of the matrix multiplication definition {mm_traits.batch_shape}."
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
if (gelu_aux_batch_axis_order := axis_order_in_memory(gelu_aux_batch_strides)) != mm_traits.batch_axis_order:
|
|
643
|
+
raise ValueError(
|
|
644
|
+
f"The batch axis order of the GELU auxiliary input {gelu_aux_batch_axis_order} "
|
|
645
|
+
f"must match with that of the other operands {mm_traits.batch_axis_order}."
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
if not check_batch_tileable(gelu_aux_batch_shape, gelu_aux_batch_strides):
|
|
649
|
+
message = (
|
|
650
|
+
f"The batch layout for GELU auxiliary input corresponding to shape = {gelu_aux_batch_shape} and "
|
|
651
|
+
f"strides = {gelu_aux_batch_strides} is currently not supported because it is not tileable."
|
|
652
|
+
)
|
|
653
|
+
raise ValueError(message)
|
|
654
|
+
|
|
655
|
+
if gelu_aux_mm_strides[0] != 1:
|
|
656
|
+
raise ValueError(
|
|
657
|
+
f"The stride of the GELU auxiliary input {gelu_aux_strides} must be 1 "
|
|
658
|
+
f"along the dimension {len(gelu_aux_strides) - 2}, which corresponds to the M dimension."
|
|
659
|
+
)
|
|
660
|
+
|
|
661
|
+
self.batch_offset = min(gelu_aux_batch_strides) if gelu_aux_batch_strides else 0 # gelu_aux broadcast
|
|
662
|
+
|
|
663
|
+
if self.batch_offset > 0:
|
|
664
|
+
assert self.batch_offset >= self.mm_m * self.mm_n, "Tensor data must not overlap."
|
|
665
|
+
|
|
666
|
+
def update_pointer(self, mm_desc_ifc, data_ptr):
|
|
667
|
+
mm_desc_ifc.epilogue_aux_pointer = data_ptr
|
|
668
|
+
|
|
669
|
+
def update(self, mm_desc_ifc, gelu_aux_tensor):
|
|
670
|
+
# Set the epilog aux pointer.
|
|
671
|
+
mm_desc_ifc.epilogue_aux_pointer = gelu_aux_tensor.data_ptr
|
|
672
|
+
# Set the gelu_aux batch offset.
|
|
673
|
+
mm_desc_ifc.epilogue_aux_batch_stride = self.batch_offset
|
|
674
|
+
# Set the aux LD.
|
|
675
|
+
mm_desc_ifc.epilogue_aux_ld = self.aux_ld
|
|
676
|
+
# Set the gelu aux data type.
|
|
677
|
+
if gelu_aux_tensor.dtype != self.d_dtype_name:
|
|
678
|
+
if self.version < 111103:
|
|
679
|
+
raise ValueError(
|
|
680
|
+
f"The GELU auxiliary tensor dtype '{gelu_aux_tensor.dtype}' must be the same as "
|
|
681
|
+
f"the result dtype '{self.d_dtype_name}' in cuBLASLt version < 111103 (you have {self.version})."
|
|
682
|
+
)
|
|
683
|
+
mm_desc_ifc.epilogue_aux_data_type = typemaps.NAME_TO_DATA_TYPE[gelu_aux_tensor.dtype]
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
EPILOG_INPUT_HANDLERS_MAP: dict[cublaslt.Epilogue, list[type[EpilogInputHandler]]] = {
|
|
687
|
+
Epilog.RELU: [],
|
|
688
|
+
Epilog.RELU_AUX: [],
|
|
689
|
+
Epilog.GELU: [],
|
|
690
|
+
Epilog.GELU_AUX: [],
|
|
691
|
+
Epilog.BIAS: [BiasHandler],
|
|
692
|
+
Epilog.RELU_BIAS: [BiasHandler],
|
|
693
|
+
Epilog.RELU_AUX_BIAS: [BiasHandler],
|
|
694
|
+
Epilog.GELU_BIAS: [BiasHandler],
|
|
695
|
+
Epilog.GELU_AUX_BIAS: [BiasHandler],
|
|
696
|
+
Epilog.DRELU: [DReluAuxHandler],
|
|
697
|
+
Epilog.DRELU_BGRAD: [DReluAuxHandler],
|
|
698
|
+
Epilog.DGELU: [DGeluAuxHandler],
|
|
699
|
+
Epilog.DGELU_BGRAD: [DGeluAuxHandler],
|
|
700
|
+
Epilog.BGRADA: [],
|
|
701
|
+
Epilog.BGRADB: [],
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
EPILOG_OUTPUT_HANDLERS_MAP: dict[cublaslt.Epilogue, list[type[EpilogOutputHandler]]] = {
|
|
705
|
+
Epilog.RELU: [],
|
|
706
|
+
Epilog.RELU_AUX: [ReluAuxHandler],
|
|
707
|
+
Epilog.GELU: [],
|
|
708
|
+
Epilog.GELU_AUX: [GeluAuxHandler],
|
|
709
|
+
Epilog.BIAS: [],
|
|
710
|
+
Epilog.RELU_BIAS: [],
|
|
711
|
+
Epilog.RELU_AUX_BIAS: [ReluAuxHandler],
|
|
712
|
+
Epilog.GELU_BIAS: [],
|
|
713
|
+
Epilog.GELU_AUX_BIAS: [GeluAuxHandler],
|
|
714
|
+
Epilog.DRELU: [],
|
|
715
|
+
Epilog.DRELU_BGRAD: [BgradHandler],
|
|
716
|
+
Epilog.DGELU: [],
|
|
717
|
+
Epilog.DGELU_BGRAD: [BgradHandler],
|
|
718
|
+
Epilog.BGRADA: [BgradHandler],
|
|
719
|
+
Epilog.BGRADB: [BgradHandler],
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
EPILOG_MINIMUM_VERSIONS_MAP: dict[cublaslt.Epilogue | None, dict[str, int | str]] = {
|
|
723
|
+
None: {"cublaslt": 00000, "ctk": ""},
|
|
724
|
+
# RELU was the first implemented epilog
|
|
725
|
+
Epilog.RELU: {"cublaslt": 11000, "ctk": "11.0.1"},
|
|
726
|
+
# 11301, 11.2.0 supports ^
|
|
727
|
+
# 11401, 11.2.2 supports ^
|
|
728
|
+
# 11402, 11.3.0 supports ^
|
|
729
|
+
# Even though some *BIAS epilogs appear in earlier headers, because
|
|
730
|
+
# CUBLASLT_MATMUL_DESC_BIAS_BATCH_STRIDE is not defined we cannot use them.
|
|
731
|
+
Epilog.GELU: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
732
|
+
Epilog.BIAS: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
733
|
+
Epilog.RELU_AUX: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
734
|
+
Epilog.GELU_AUX: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
735
|
+
Epilog.RELU_BIAS: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
736
|
+
Epilog.RELU_AUX_BIAS: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
737
|
+
Epilog.GELU_BIAS: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
738
|
+
Epilog.GELU_AUX_BIAS: {"cublaslt": 11501, "ctk": "11.3.1"},
|
|
739
|
+
# 11501, 11.3.1 supports ^
|
|
740
|
+
# 11504, 11.4.1 supports ^
|
|
741
|
+
# 11601, 11.4.2 supports ^
|
|
742
|
+
# 11703, 11.5.0 supports ^
|
|
743
|
+
# 11704, 11.5.1 supports ^
|
|
744
|
+
# 11801, 11.6.0 supports ^
|
|
745
|
+
# 11801, 11.6.1 supports ^
|
|
746
|
+
# 110902, 11.6.2 supports ^
|
|
747
|
+
# Even though BGRAD[A,B] and D[R,G]ELU appear in earlier headers, our unit tests mark
|
|
748
|
+
# them as unsupported before 111103 for in order to avoid API changes.
|
|
749
|
+
Epilog.DRELU: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
750
|
+
Epilog.DGELU: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
751
|
+
Epilog.BGRADA: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
752
|
+
Epilog.BGRADB: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
753
|
+
Epilog.DRELU_BGRAD: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
754
|
+
Epilog.DGELU_BGRAD: {"cublaslt": 111103, "ctk": "11.8.0"},
|
|
755
|
+
# 111103, 11.8.0 supports ^
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
BATCHED_EPILOG_MINIMUM_VERSIONS_MAP = EPILOG_MINIMUM_VERSIONS_MAP.copy()
|
|
759
|
+
BATCHED_EPILOG_MINIMUM_VERSIONS_MAP.update(
|
|
760
|
+
{
|
|
761
|
+
Epilog.RELU_AUX: {"cublaslt": 11703, "ctk": "11.5"},
|
|
762
|
+
Epilog.GELU_AUX: {"cublaslt": 11703, "ctk": "11.5"},
|
|
763
|
+
Epilog.RELU_AUX_BIAS: {"cublaslt": 11703, "ctk": "11.5"},
|
|
764
|
+
Epilog.GELU_AUX_BIAS: {"cublaslt": 11703, "ctk": "11.5"},
|
|
765
|
+
}
|
|
766
|
+
)
|