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,120 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"ContractionAlgo",
|
|
7
|
+
"ContractionAutotuneMode",
|
|
8
|
+
"ContractionJitMode",
|
|
9
|
+
"ContractionCacheMode",
|
|
10
|
+
"ContractionOptions",
|
|
11
|
+
"ExecutionCUDA",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from logging import Logger
|
|
17
|
+
from typing import Literal
|
|
18
|
+
|
|
19
|
+
from nvmath._internal import templates
|
|
20
|
+
from nvmath.bindings import cutensor
|
|
21
|
+
from nvmath.memory import BaseCUDAMemoryManager
|
|
22
|
+
|
|
23
|
+
ContractionAlgo = cutensor.Algo
|
|
24
|
+
ContractionAutotuneMode = cutensor.AutotuneMode
|
|
25
|
+
ContractionJitMode = cutensor.JitMode
|
|
26
|
+
ContractionCacheMode = cutensor.CacheMode
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class ContractionOptions:
|
|
31
|
+
"""
|
|
32
|
+
A data class for providing options to the :class:`BinaryContraction` and
|
|
33
|
+
:class:`TernaryContraction` objects, or the wrapper functions
|
|
34
|
+
:func:`binary_contraction`and :func:`ternary_contraction`.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
compute_type: The compute type to use for the contraction.
|
|
38
|
+
See :class:`~nvmath.tensor.ComputeDesc` for available compute types.
|
|
39
|
+
logger (logging.Logger): Python Logger object. The root logger will be used if a
|
|
40
|
+
logger object is not provided.
|
|
41
|
+
|
|
42
|
+
blocking: A flag specifying the behavior of the execution functions and methods,
|
|
43
|
+
such as :func:`binary_contraction` and :meth:`TernaryContraction.execute`.
|
|
44
|
+
When ``blocking`` is `True`, the execution methods do not return until the
|
|
45
|
+
operation is complete. When
|
|
46
|
+
``blocking`` is ``"auto"``, the methods return immediately when the input tensor
|
|
47
|
+
is on the GPU. The execution methods always block when the input tensor is
|
|
48
|
+
on the CPU to ensure that the user doesn't inadvertently use the result
|
|
49
|
+
before it becomes available. The default is ``"auto"``.
|
|
50
|
+
|
|
51
|
+
handle: cuTensor library handle. A handle will be created if one is not provided.
|
|
52
|
+
|
|
53
|
+
allocator: An object that supports the :class:`BaseCUDAMemoryManager` protocol, used
|
|
54
|
+
to draw device memory. If an allocator is not provided, a memory allocator from
|
|
55
|
+
the library package will be used (:func:`torch.cuda.caching_allocator_alloc` for
|
|
56
|
+
PyTorch operands, :func:`cupy.cuda.alloc` otherwise).
|
|
57
|
+
|
|
58
|
+
memory_limit: Maximum memory available to the contraction operation.
|
|
59
|
+
It can be specified as a value (with optional suffix like K[iB], M[iB],
|
|
60
|
+
G[iB]) or as a percentage. The default is 80% of the device memory.
|
|
61
|
+
|
|
62
|
+
result_layout: The layout policy to use for the result: ``"auto"`` (default),
|
|
63
|
+
``"C"`` (row-major), ``"F"`` (column-major), or ``"optimized"``.
|
|
64
|
+
With ``"auto"``, cuTENSOR execution requirements take precedence. When
|
|
65
|
+
those requirements permit, an optimized layout is chosen for this
|
|
66
|
+
contraction; otherwise, a compatible fallback layout is used. With
|
|
67
|
+
``"optimized"``, strides are chosen directly from the contraction
|
|
68
|
+
expression and operand shapes to improve performance for this operation.
|
|
69
|
+
The chosen layout is local to this contraction and may not be optimal for
|
|
70
|
+
later operations that consume the result. This option is ignored if the
|
|
71
|
+
output operand is explicitly provided.
|
|
72
|
+
|
|
73
|
+
.. note::
|
|
74
|
+
|
|
75
|
+
- optimized ``result_layout`` currently only supports binary contraction via
|
|
76
|
+
:func:`binary_contraction` and :class:`BinaryContraction` when the addend
|
|
77
|
+
``c`` is not specified.
|
|
78
|
+
- For both binary and ternary contractions, cuTENSOR may require the addend
|
|
79
|
+
and output operands to have the same strides. When an addend operand is
|
|
80
|
+
provided, explicitly specifying ``result_layout`` to ``"C"`` or ``"F"`` may
|
|
81
|
+
therefore fail at runtime if that layout is incompatible with the addend.
|
|
82
|
+
This constraint depends on the cuTENSOR library version.
|
|
83
|
+
|
|
84
|
+
.. seealso::
|
|
85
|
+
For supported compute types by data type, refer to the cuTENSOR documentation:
|
|
86
|
+
|
|
87
|
+
* `Binary contraction <https://docs.nvidia.com/cuda/cutensor/latest/api/cutensor.html#cutensorcreatecontraction>`_
|
|
88
|
+
* `Ternary contraction <https://docs.nvidia.com/cuda/cutensor/latest/api/cutensor.html#cutensorcreatecontractiontrinary>`_
|
|
89
|
+
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
compute_type: int | None = None
|
|
93
|
+
logger: Logger | None = None
|
|
94
|
+
blocking: Literal[True, "auto"] = "auto"
|
|
95
|
+
handle: int | None = None
|
|
96
|
+
allocator: BaseCUDAMemoryManager | None = None
|
|
97
|
+
memory_limit: int | str | None = r"80%"
|
|
98
|
+
result_layout: Literal["auto", "C", "F", "optimized"] = "auto"
|
|
99
|
+
|
|
100
|
+
def __post_init__(self):
|
|
101
|
+
if self.blocking not in (True, "auto"):
|
|
102
|
+
raise ValueError("The value specified for 'blocking' must be either True or 'auto'.")
|
|
103
|
+
if self.result_layout not in ("auto", "C", "F", "optimized"):
|
|
104
|
+
raise ValueError("The value specified for 'result_layout' must be either 'auto', 'C', 'F', or 'optimized'.")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@dataclass(frozen=True, slots=True, kw_only=True)
|
|
108
|
+
class ExecutionCUDA(templates.ExecutionCUDA):
|
|
109
|
+
"""
|
|
110
|
+
A data class for providing GPU execution options to the :class:`BinaryContraction` and
|
|
111
|
+
:class:`TernaryContraction` objects, or the wrapper functions
|
|
112
|
+
:func:`binary_contraction`and :func:`ternary_contraction`.
|
|
113
|
+
|
|
114
|
+
Attributes:
|
|
115
|
+
device_id: CUDA device ordinal (only used if the operand resides on the CPU). The
|
|
116
|
+
default value is 0.
|
|
117
|
+
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
pass
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Interface classes to encapsulate low-level calls to get or set configuration information.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__ = ["ContractionPlanPreference"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
|
|
14
|
+
from nvmath.bindings import cutensor
|
|
15
|
+
from nvmath.internal import utils
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ContractionPlanPreference:
|
|
19
|
+
"""
|
|
20
|
+
An interface to configure :meth:`nvmath.tensor.BinaryContraction.plan` and
|
|
21
|
+
:meth:`nvmath.tensor.TernaryContraction.plan`. The
|
|
22
|
+
current configuration can also be queried.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
def __init__(self, contraction):
|
|
26
|
+
"""
|
|
27
|
+
ctor for internal use only.
|
|
28
|
+
"""
|
|
29
|
+
self._contraction = contraction
|
|
30
|
+
self._handle = self._contraction.handle
|
|
31
|
+
|
|
32
|
+
get_dtype = cutensor.get_plan_preference_attribute_dtype
|
|
33
|
+
|
|
34
|
+
self._autotune_mode = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.AUTOTUNE_MODE))
|
|
35
|
+
self._cache_mode = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.CACHE_MODE))
|
|
36
|
+
self._incremental_count = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.INCREMENTAL_COUNT))
|
|
37
|
+
self._algo = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.ALGO))
|
|
38
|
+
self._kernel_rank = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.KERNEL_RANK))
|
|
39
|
+
self._jit = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.JIT))
|
|
40
|
+
self._gpu_arch = np.zeros((1,), dtype=get_dtype(cutensor.PlanPreferenceAttribute.GPU_ARCH))
|
|
41
|
+
|
|
42
|
+
def _check_valid_contraction_wrapper(self, *args, **kwargs):
|
|
43
|
+
if not self._contraction.valid_state:
|
|
44
|
+
raise RuntimeError("The ContractionPlanPreference object cannot be used after its contraction object is free'd.")
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def _get_scalar_attribute(contraction, name, attribute):
|
|
48
|
+
"""
|
|
49
|
+
name = cutensor PlanPreference enum for the attribute
|
|
50
|
+
attribute = numpy ndarray object into which the value is stored by cutensornet
|
|
51
|
+
"""
|
|
52
|
+
assert contraction.plan_preference_ptr is not None, "Internal error"
|
|
53
|
+
cutensor.plan_preference_get_attribute(
|
|
54
|
+
contraction.handle, contraction.plan_preference_ptr, name, attribute.ctypes.data, attribute.dtype.itemsize
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
@staticmethod
|
|
58
|
+
def _set_scalar_attribute(contraction, name, attribute, value):
|
|
59
|
+
"""
|
|
60
|
+
name = cutensor PlanPreference enum for the attribute
|
|
61
|
+
attribute = numpy ndarray object into which the value is stored
|
|
62
|
+
value = the value to set the the attribute to
|
|
63
|
+
"""
|
|
64
|
+
assert contraction.plan_preference_ptr is not None, "Internal error"
|
|
65
|
+
attribute[0] = value
|
|
66
|
+
cutensor.plan_preference_set_attribute(
|
|
67
|
+
contraction.handle, contraction.plan_preference_ptr, name, attribute.ctypes.data, attribute.dtype.itemsize
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
72
|
+
def autotune_mode(self):
|
|
73
|
+
"""
|
|
74
|
+
Query the autotune mode. See the
|
|
75
|
+
`cuTensor documentation
|
|
76
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorautotunemode-t>`__
|
|
77
|
+
for more information.
|
|
78
|
+
"""
|
|
79
|
+
ContractionPlanPreference._get_scalar_attribute(
|
|
80
|
+
self._contraction, cutensor.PlanPreferenceAttribute.AUTOTUNE_MODE, self._autotune_mode
|
|
81
|
+
)
|
|
82
|
+
return self._autotune_mode.item()
|
|
83
|
+
|
|
84
|
+
@autotune_mode.setter
|
|
85
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
86
|
+
def autotune_mode(self, autotune_mode):
|
|
87
|
+
"""
|
|
88
|
+
Set the autotune mode. See the
|
|
89
|
+
`cuTensor documentation
|
|
90
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorautotunemode-t>`__
|
|
91
|
+
for more information.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
autotune_mode: (nvmath.tensor.ContractionAutotuneMode) The autotune mode.
|
|
95
|
+
|
|
96
|
+
"""
|
|
97
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
98
|
+
self._contraction, cutensor.PlanPreferenceAttribute.AUTOTUNE_MODE, self._autotune_mode, autotune_mode
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
103
|
+
def cache_mode(self):
|
|
104
|
+
"""
|
|
105
|
+
Query the cache mode. See the
|
|
106
|
+
`cuTensor documentation
|
|
107
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorcachemode-t>`__
|
|
108
|
+
for more information.
|
|
109
|
+
"""
|
|
110
|
+
ContractionPlanPreference._get_scalar_attribute(
|
|
111
|
+
self._contraction, cutensor.PlanPreferenceAttribute.CACHE_MODE, self._cache_mode
|
|
112
|
+
)
|
|
113
|
+
return self._cache_mode.item()
|
|
114
|
+
|
|
115
|
+
@cache_mode.setter
|
|
116
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
117
|
+
def cache_mode(self, cache_mode):
|
|
118
|
+
"""
|
|
119
|
+
Set the cache mode. See the
|
|
120
|
+
`cuTensor documentation
|
|
121
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorcachemode-t>`__
|
|
122
|
+
for more information.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
cache_mode: (nvmath.tensor.ContractionCacheMode) The cache mode.
|
|
126
|
+
|
|
127
|
+
"""
|
|
128
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
129
|
+
self._contraction, cutensor.PlanPreferenceAttribute.CACHE_MODE, self._cache_mode, cache_mode
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
134
|
+
def incremental_count(self):
|
|
135
|
+
"""
|
|
136
|
+
Query the incremental count. See the
|
|
137
|
+
`cuTensor documentation
|
|
138
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorincrementalcount-t>`__
|
|
139
|
+
for more information.
|
|
140
|
+
"""
|
|
141
|
+
ContractionPlanPreference._get_scalar_attribute(
|
|
142
|
+
self._contraction, cutensor.PlanPreferenceAttribute.INCREMENTAL_COUNT, self._incremental_count
|
|
143
|
+
)
|
|
144
|
+
return self._incremental_count.item()
|
|
145
|
+
|
|
146
|
+
@incremental_count.setter
|
|
147
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
148
|
+
def incremental_count(self, incremental_count):
|
|
149
|
+
"""
|
|
150
|
+
Set the incremental count. See the
|
|
151
|
+
`cuTensor documentation
|
|
152
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorincrementalcount-t>`__
|
|
153
|
+
for more information.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
incremental_count: The incremental count.
|
|
157
|
+
|
|
158
|
+
"""
|
|
159
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
160
|
+
self._contraction, cutensor.PlanPreferenceAttribute.INCREMENTAL_COUNT, self._incremental_count, incremental_count
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
@property
|
|
164
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
165
|
+
def algo(self):
|
|
166
|
+
"""
|
|
167
|
+
Query the algo. See the
|
|
168
|
+
`cuTensor documentation
|
|
169
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensoralgo-t>`__
|
|
170
|
+
for more information.
|
|
171
|
+
"""
|
|
172
|
+
ContractionPlanPreference._get_scalar_attribute(self._contraction, cutensor.PlanPreferenceAttribute.ALGO, self._algo)
|
|
173
|
+
return self._algo.item()
|
|
174
|
+
|
|
175
|
+
@algo.setter
|
|
176
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
177
|
+
def algo(self, algo):
|
|
178
|
+
"""
|
|
179
|
+
Set the algo. See the
|
|
180
|
+
`cuTensor documentation
|
|
181
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensoralgo-t>`__
|
|
182
|
+
for more information.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
algo: (nvmath.tensor.ContractionAlgo) The contraction algorithm.
|
|
186
|
+
|
|
187
|
+
"""
|
|
188
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
189
|
+
self._contraction, cutensor.PlanPreferenceAttribute.ALGO, self._algo, algo
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
194
|
+
def kernel_rank(self):
|
|
195
|
+
"""
|
|
196
|
+
Query the kernel rank. See the
|
|
197
|
+
`cuTensor documentation
|
|
198
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorkernelrank-t>`__
|
|
199
|
+
for more information.
|
|
200
|
+
"""
|
|
201
|
+
ContractionPlanPreference._get_scalar_attribute(
|
|
202
|
+
self._contraction, cutensor.PlanPreferenceAttribute.KERNEL_RANK, self._kernel_rank
|
|
203
|
+
)
|
|
204
|
+
return self._kernel_rank.item()
|
|
205
|
+
|
|
206
|
+
@kernel_rank.setter
|
|
207
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
208
|
+
def kernel_rank(self, kernel_rank):
|
|
209
|
+
"""
|
|
210
|
+
Set the kernel rank. See the
|
|
211
|
+
`cuTensor documentation
|
|
212
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorkernelrank-t>`__
|
|
213
|
+
for more information.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
kernel_rank: The kernel rank.
|
|
217
|
+
|
|
218
|
+
"""
|
|
219
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
220
|
+
self._contraction, cutensor.PlanPreferenceAttribute.KERNEL_RANK, self._kernel_rank, kernel_rank
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
225
|
+
def jit(self):
|
|
226
|
+
"""
|
|
227
|
+
Query the jit compilation mode. See the
|
|
228
|
+
`cuTensor documentation
|
|
229
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorjit-t>`__
|
|
230
|
+
for more information.
|
|
231
|
+
"""
|
|
232
|
+
ContractionPlanPreference._get_scalar_attribute(self._contraction, cutensor.PlanPreferenceAttribute.JIT, self._jit)
|
|
233
|
+
return self._jit.item()
|
|
234
|
+
|
|
235
|
+
@jit.setter
|
|
236
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
237
|
+
def jit(self, jit):
|
|
238
|
+
"""
|
|
239
|
+
Set the jit compilation mode. See the
|
|
240
|
+
`cuTensor documentation
|
|
241
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorjit-t>`__
|
|
242
|
+
for more information.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
jit: (nvmath.tensor.ContractionJitMode) The JIT compilation mode.
|
|
246
|
+
|
|
247
|
+
"""
|
|
248
|
+
ContractionPlanPreference._set_scalar_attribute(self._contraction, cutensor.PlanPreferenceAttribute.JIT, self._jit, jit)
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
252
|
+
def gpu_arch(self):
|
|
253
|
+
"""
|
|
254
|
+
Query the GPU architecture. See the
|
|
255
|
+
`cuTensor documentation
|
|
256
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorplanpreferenceattribute-t>`__
|
|
257
|
+
for more information.
|
|
258
|
+
"""
|
|
259
|
+
ContractionPlanPreference._get_scalar_attribute(
|
|
260
|
+
self._contraction, cutensor.PlanPreferenceAttribute.GPU_ARCH, self._gpu_arch
|
|
261
|
+
)
|
|
262
|
+
return self._gpu_arch.item()
|
|
263
|
+
|
|
264
|
+
@gpu_arch.setter
|
|
265
|
+
@utils.precondition(_check_valid_contraction_wrapper)
|
|
266
|
+
def gpu_arch(self, gpu_arch: int):
|
|
267
|
+
"""
|
|
268
|
+
Set the GPU architecture. See the
|
|
269
|
+
`cuTensor documentation
|
|
270
|
+
<https://docs.nvidia.com/cuda/cutensor/latest/api/types.html#cutensorplanpreferenceattribute-t>`__
|
|
271
|
+
for more information.
|
|
272
|
+
|
|
273
|
+
Args:
|
|
274
|
+
gpu_arch: (int) The GPU architecture.
|
|
275
|
+
|
|
276
|
+
"""
|
|
277
|
+
ContractionPlanPreference._set_scalar_attribute(
|
|
278
|
+
self._contraction, cutensor.PlanPreferenceAttribute.GPU_ARCH, self._gpu_arch, gpu_arch
|
|
279
|
+
)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
import weakref
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
|
|
9
|
+
from nvmath.bindings import cutensor
|
|
10
|
+
from nvmath.internal.tensor_ifc import TensorHolder
|
|
11
|
+
from nvmath.internal.typemaps import NAME_TO_DATA_TYPE
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"compute_pointer_alignment",
|
|
15
|
+
"compute_strides",
|
|
16
|
+
"TensorDescriptor",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
DEFAULT_ALIGNMENT_REQUIREMENT = 256
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def compute_pointer_alignment(ptr: int) -> int:
|
|
23
|
+
"""
|
|
24
|
+
Compute the pointer alignment for the given pointer.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
ptr: Pointer address as integer
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The alignment value (256, 128, 64, 32, 16, 8, 4, 2, or 1)
|
|
31
|
+
"""
|
|
32
|
+
return 256 if ptr == 0 else min(ptr & -ptr, 256)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def compute_strides(shape: Sequence[int], order: str = "C") -> Sequence[int]:
|
|
36
|
+
"""
|
|
37
|
+
Compute the strides for the given shape and order.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
shape: Shape of the tensor
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
The strides
|
|
44
|
+
"""
|
|
45
|
+
assert order in {"C", "F"}, f"Invalid order: {order}"
|
|
46
|
+
strides = [0] * len(shape)
|
|
47
|
+
stride = 1
|
|
48
|
+
if order == "C":
|
|
49
|
+
for axis in range(len(shape) - 1, -1, -1):
|
|
50
|
+
strides[axis] = stride
|
|
51
|
+
stride *= shape[axis]
|
|
52
|
+
elif order == "F":
|
|
53
|
+
for axis in range(len(shape)):
|
|
54
|
+
strides[axis] = stride
|
|
55
|
+
stride *= shape[axis]
|
|
56
|
+
else:
|
|
57
|
+
raise ValueError(f"Invalid order: {order}")
|
|
58
|
+
return strides
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def get_optimized_strides(
|
|
62
|
+
input_modes: Sequence[Sequence[str]],
|
|
63
|
+
output_modes: Sequence[str],
|
|
64
|
+
output_shape: Sequence[int],
|
|
65
|
+
) -> Sequence[int]:
|
|
66
|
+
"""
|
|
67
|
+
Get the optimized strides for a **binary** contraction output.
|
|
68
|
+
|
|
69
|
+
Output modes are split into three groups:
|
|
70
|
+
- hypermodes in both operands,
|
|
71
|
+
- un-contracted modes from operand A,
|
|
72
|
+
- un-contracted modes from operand B.
|
|
73
|
+
|
|
74
|
+
In the optimized/canonical output layout, the hyper modes are
|
|
75
|
+
placed at the beginning, followed by the group of modes with larger
|
|
76
|
+
combined size, then the other group of modes.
|
|
77
|
+
|
|
78
|
+
For example, "Pijab,Pabcd->Picjd" labels hypermode "P", A-only modes "i,j",
|
|
79
|
+
and B-only modes "c,d". The canonical mode order is either "Pijcd" or "Pcdij",
|
|
80
|
+
depending on which group has the larger combined size.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
input_modes: Two sequences of mode labels (typically characters), one per operand.
|
|
84
|
+
output_modes: Output subscript aligned with ``output_shape``.
|
|
85
|
+
output_shape: Extent along each output mode.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Strides in elements matching the memory order implied by ``output_modes``.
|
|
89
|
+
"""
|
|
90
|
+
if len(input_modes) != 2:
|
|
91
|
+
raise ValueError("Only binary contraction is supported for optimized strides")
|
|
92
|
+
a_modes, b_modes = input_modes
|
|
93
|
+
|
|
94
|
+
size_dict = dict(zip(output_modes, output_shape, strict=True))
|
|
95
|
+
|
|
96
|
+
output_set = set(output_modes)
|
|
97
|
+
b_set = set(b_modes)
|
|
98
|
+
|
|
99
|
+
hyper_modes = [m for m in a_modes if m in output_set and m in b_set]
|
|
100
|
+
a_remaining_modes = [m for m in a_modes if m in output_set and m not in b_set]
|
|
101
|
+
b_remaining_modes = [m for m in b_modes if m in output_set and m not in hyper_modes]
|
|
102
|
+
|
|
103
|
+
combined_size_a = math.prod(size_dict[mode] for mode in a_remaining_modes)
|
|
104
|
+
combined_size_b = math.prod(size_dict[mode] for mode in b_remaining_modes)
|
|
105
|
+
|
|
106
|
+
if combined_size_a >= combined_size_b:
|
|
107
|
+
canonical_output_modes = hyper_modes + a_remaining_modes + b_remaining_modes
|
|
108
|
+
else:
|
|
109
|
+
canonical_output_modes = hyper_modes + b_remaining_modes + a_remaining_modes
|
|
110
|
+
|
|
111
|
+
canonical_output_shape = [size_dict[mode] for mode in canonical_output_modes]
|
|
112
|
+
canonical_strides = compute_strides(canonical_output_shape, order="C")
|
|
113
|
+
|
|
114
|
+
stride_map = dict(zip(canonical_output_modes, canonical_strides, strict=True))
|
|
115
|
+
|
|
116
|
+
# Permute strides back to the caller's output mode order.
|
|
117
|
+
optimized_strides = [stride_map[mode] for mode in output_modes]
|
|
118
|
+
return optimized_strides
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class TensorDescriptor:
|
|
122
|
+
"""
|
|
123
|
+
A managed wrapper for cuTensor tensor descriptors with automatic resource cleanup.
|
|
124
|
+
|
|
125
|
+
This class wraps a cuTensor tensor descriptor (``cutensorTensorDescriptor_t``) and
|
|
126
|
+
automatically manages its lifetime. The underlying C descriptor is created on
|
|
127
|
+
initialization and automatically destroyed when this object is garbage collected.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
handle: The cuTensor library handle.
|
|
131
|
+
extents: The extents (shape) of each mode of the tensor. Must have the same
|
|
132
|
+
length as ``strides``.
|
|
133
|
+
strides: The stride for each mode of the tensor, in elements of the base type.
|
|
134
|
+
Must have the same length as ``extents``.
|
|
135
|
+
dtype: The data type of the tensor as a string.
|
|
136
|
+
alignment: The alignment requirement in bytes for the base pointer that will
|
|
137
|
+
be used with this descriptor.
|
|
138
|
+
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
def __init__(
|
|
142
|
+
self,
|
|
143
|
+
handle: int,
|
|
144
|
+
extents: Sequence[int],
|
|
145
|
+
strides: Sequence[int],
|
|
146
|
+
dtype: str,
|
|
147
|
+
alignment: int,
|
|
148
|
+
):
|
|
149
|
+
self._extents = extents
|
|
150
|
+
self._strides = strides
|
|
151
|
+
self._dtype = dtype
|
|
152
|
+
self._alignment = alignment
|
|
153
|
+
num_modes = len(extents)
|
|
154
|
+
assert num_modes == len(strides), "The number of modes and strides must be the same"
|
|
155
|
+
self._tensor_desc = cutensor.create_tensor_descriptor(
|
|
156
|
+
handle, num_modes, extents, strides, NAME_TO_DATA_TYPE[dtype], alignment
|
|
157
|
+
)
|
|
158
|
+
self._finalizer = weakref.finalize(self, cutensor.destroy_tensor_descriptor, self._tensor_desc)
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def ptr(self) -> int:
|
|
162
|
+
return self._tensor_desc
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def shape(self) -> Sequence[int]:
|
|
166
|
+
return self._extents
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def dtype(self) -> str:
|
|
170
|
+
return self._dtype
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
def alignment(self) -> int:
|
|
174
|
+
return self._alignment
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def strides(self) -> Sequence[int]:
|
|
178
|
+
return self._strides
|
|
179
|
+
|
|
180
|
+
@classmethod
|
|
181
|
+
def from_tensor_holder(cls, handle: int, tensor: TensorHolder) -> "TensorDescriptor":
|
|
182
|
+
"""
|
|
183
|
+
Create a TensorDescriptor from a TensorHolder.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
handle: The cuTensor library handle.
|
|
187
|
+
tensor: The TensorHolder to create the descriptor from.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
A TensorDescriptor with properties derived from the TensorHolder.
|
|
191
|
+
"""
|
|
192
|
+
return cls(
|
|
193
|
+
handle=handle,
|
|
194
|
+
extents=tensor.shape,
|
|
195
|
+
strides=tensor.strides,
|
|
196
|
+
dtype=tensor.dtype,
|
|
197
|
+
alignment=compute_pointer_alignment(tensor.data_ptr),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
@classmethod
|
|
201
|
+
def from_metadata(
|
|
202
|
+
cls,
|
|
203
|
+
handle: int,
|
|
204
|
+
shape: Sequence[int],
|
|
205
|
+
dtype: str,
|
|
206
|
+
strides: Sequence[int] | None = None,
|
|
207
|
+
alignment: int = DEFAULT_ALIGNMENT_REQUIREMENT,
|
|
208
|
+
) -> "TensorDescriptor":
|
|
209
|
+
"""
|
|
210
|
+
Create a TensorDescriptor for the given shape, data type, strides, and alignment.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
handle: The cuTensor library handle.
|
|
214
|
+
shape: The shape (extents) of the tensor.
|
|
215
|
+
dtype: The data type of the tensor as a string.
|
|
216
|
+
strides: The strides of the tensor. Defaults to C order strides.
|
|
217
|
+
alignment: The alignment requirement in bytes. Defaults to 256.
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
A TensorDescriptor with the specified properties.
|
|
221
|
+
"""
|
|
222
|
+
if strides is None:
|
|
223
|
+
strides = compute_strides(shape, order="C")
|
|
224
|
+
return cls(
|
|
225
|
+
handle=handle,
|
|
226
|
+
extents=shape,
|
|
227
|
+
strides=strides,
|
|
228
|
+
dtype=dtype,
|
|
229
|
+
alignment=alignment,
|
|
230
|
+
)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
# Defined in CPython:
|
|
6
|
+
# https://github.com/python/cpython/blob/26bc2cc06128890ac89492eca20e83abe0789c1c/Objects/unicodetype_db.h#L6311-L6349
|
|
7
|
+
|
|
8
|
+
__all__ = ["WHITESPACE_UNICODE"]
|
|
9
|
+
|
|
10
|
+
_WHITESPACE_UNICODE_INTS = [
|
|
11
|
+
0x0009,
|
|
12
|
+
0x000A,
|
|
13
|
+
0x000B,
|
|
14
|
+
0x000C,
|
|
15
|
+
0x000D,
|
|
16
|
+
0x001C,
|
|
17
|
+
0x001D,
|
|
18
|
+
0x001E,
|
|
19
|
+
0x001F,
|
|
20
|
+
0x0020,
|
|
21
|
+
0x0085,
|
|
22
|
+
0x00A0,
|
|
23
|
+
0x1680,
|
|
24
|
+
0x2000,
|
|
25
|
+
0x2001,
|
|
26
|
+
0x2002,
|
|
27
|
+
0x2003,
|
|
28
|
+
0x2004,
|
|
29
|
+
0x2005,
|
|
30
|
+
0x2006,
|
|
31
|
+
0x2007,
|
|
32
|
+
0x2008,
|
|
33
|
+
0x2009,
|
|
34
|
+
0x200A,
|
|
35
|
+
0x2028,
|
|
36
|
+
0x2029,
|
|
37
|
+
0x202F,
|
|
38
|
+
0x205F,
|
|
39
|
+
0x3000,
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
WHITESPACE_UNICODE = "".join(chr(s) for s in _WHITESPACE_UNICODE_INTS)
|