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,268 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Interface to seamlessly use CSC tensors from different libraries.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations # allows typehint of class methods to return the self class
|
|
10
|
+
|
|
11
|
+
__all__ = ["CSCTensorHolder"]
|
|
12
|
+
|
|
13
|
+
from typing import Literal, TypeVar
|
|
14
|
+
|
|
15
|
+
from nvmath._internal.layout import check_monotonic_strides, is_contiguous_and_dense
|
|
16
|
+
from nvmath.internal import tensor_wrapper
|
|
17
|
+
from nvmath.internal.package_ifc import StreamHolder
|
|
18
|
+
from nvmath.internal.tensor_ifc import TensorHolder
|
|
19
|
+
from nvmath.internal.utils import infer_object_package
|
|
20
|
+
|
|
21
|
+
from .sparse_tensor_ifc import SparseTensorHolder
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
A generic type for the third-party CSCTensor which a CSCTensorHolder implementation wraps
|
|
25
|
+
around.
|
|
26
|
+
"""
|
|
27
|
+
CSCTensor = TypeVar("CSCTensor")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CSCTensorHolder(SparseTensorHolder):
|
|
31
|
+
"""
|
|
32
|
+
A simple wrapper type for CSC sparse tensors to make the API package-agnostic. The
|
|
33
|
+
naming convention is sparse format name with the suffix "TensorHolder", which convention
|
|
34
|
+
is used in the sparse format helper.
|
|
35
|
+
|
|
36
|
+
Since the implementation is in terms of our dense tensor abstraction, package-specific
|
|
37
|
+
implementation is not needed.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
_format_name: str = "CSC"
|
|
41
|
+
|
|
42
|
+
def __init__(self, ccol_indices, row_indices, values, *, attr_name_map=None, shape=None, tensor=None):
|
|
43
|
+
# tensor is the native tensor.
|
|
44
|
+
self.tensor = tensor
|
|
45
|
+
|
|
46
|
+
# attr_name_map is the canonical attribute name to package attribute name map.
|
|
47
|
+
# It is set when constructing from a tensor, otherwise it is None.
|
|
48
|
+
self._attr_name_map = attr_name_map
|
|
49
|
+
|
|
50
|
+
assert (shape is not None) ^ (tensor is not None), "Internal error."
|
|
51
|
+
|
|
52
|
+
if shape is not None:
|
|
53
|
+
self._shape = shape
|
|
54
|
+
else:
|
|
55
|
+
self._shape = tuple(tensor.shape)
|
|
56
|
+
|
|
57
|
+
# Wrap constituent dense tensors, if required.
|
|
58
|
+
if not isinstance(ccol_indices, TensorHolder):
|
|
59
|
+
ccol_indices = tensor_wrapper.wrap_operand(ccol_indices)
|
|
60
|
+
|
|
61
|
+
if not isinstance(row_indices, TensorHolder):
|
|
62
|
+
row_indices = tensor_wrapper.wrap_operand(row_indices)
|
|
63
|
+
|
|
64
|
+
if not isinstance(values, TensorHolder):
|
|
65
|
+
values = tensor_wrapper.wrap_operand(values)
|
|
66
|
+
|
|
67
|
+
# The wrapped constituent dense tensors.
|
|
68
|
+
self._ccol_indices = ccol_indices
|
|
69
|
+
self._row_indices = row_indices
|
|
70
|
+
self._values = values
|
|
71
|
+
|
|
72
|
+
# Ensure constituent dense tensors are all on the same device.
|
|
73
|
+
device_ids = {d.device_id for d in (self._ccol_indices, self._row_indices, self._values)}
|
|
74
|
+
message = f"Internal error: the arrays defining the sparse format aren't on the same device {device_ids}."
|
|
75
|
+
assert len(device_ids) == 1, message
|
|
76
|
+
self._device_id = device_ids.pop()
|
|
77
|
+
|
|
78
|
+
self._device = self._values.device
|
|
79
|
+
|
|
80
|
+
# Capture the native tensor package for use in reset_unchecked().
|
|
81
|
+
self.tensor_package = infer_object_package(self.tensor)
|
|
82
|
+
|
|
83
|
+
# The tensor holder type for the dense constituent tensors (take from values, since
|
|
84
|
+
# all constituent tensors have the same type).
|
|
85
|
+
self._dense_tensorholder_type = values.__class__
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def create_from_tensor(cls, tensor, *, attr_name_map=None):
|
|
89
|
+
assert attr_name_map is not None, "Internal error."
|
|
90
|
+
|
|
91
|
+
# tensor is the native tensor.
|
|
92
|
+
# For UST, the buffers will be CuPy ndarrays.
|
|
93
|
+
ccol_indices = attr_name_map["ccol_indices"](tensor)
|
|
94
|
+
row_indices = attr_name_map["row_indices"](tensor)
|
|
95
|
+
values = attr_name_map["values"](tensor)
|
|
96
|
+
return CSCTensorHolder(ccol_indices, row_indices, values, attr_name_map=attr_name_map, tensor=tensor)
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def attr_name_map(self):
|
|
100
|
+
return self._attr_name_map
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def device(self):
|
|
104
|
+
return self._device
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def device_id(self):
|
|
108
|
+
return self._device_id
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def dtype(self):
|
|
112
|
+
return self._values.dtype
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def index_type(self):
|
|
116
|
+
return self._ccol_indices.dtype
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def format_name(self) -> str:
|
|
120
|
+
return CSCTensorHolder._format_name
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def num_dimensions(self):
|
|
124
|
+
return len(self._shape)
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def shape(self):
|
|
128
|
+
return self._shape
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def ccol_indices(self) -> TensorHolder:
|
|
132
|
+
"""The TensorHolder object wrapping the ccol_indices array."""
|
|
133
|
+
return self._ccol_indices
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def row_indices(self) -> TensorHolder:
|
|
137
|
+
"""The TensorHolder object wrapping the row_indices array."""
|
|
138
|
+
return self._row_indices
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def values(self) -> TensorHolder:
|
|
142
|
+
"""The TensorHolder object wrapping the values array."""
|
|
143
|
+
return self._values
|
|
144
|
+
|
|
145
|
+
def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
|
|
146
|
+
"""Copy the CSCTensor representation to a different device.
|
|
147
|
+
|
|
148
|
+
No copy is performed if the CSCTensor is already on the requested device.
|
|
149
|
+
"""
|
|
150
|
+
if self.tensor_package == "nvmath":
|
|
151
|
+
return super().to(device_id=device_id, stream_holder=stream_holder)
|
|
152
|
+
|
|
153
|
+
target_ccol_indices = self.ccol_indices.to(device_id=device_id, stream_holder=stream_holder)
|
|
154
|
+
target_row_indices = self.row_indices.to(device_id=device_id, stream_holder=stream_holder)
|
|
155
|
+
target_values = self.values.to(device_id=device_id, stream_holder=stream_holder)
|
|
156
|
+
|
|
157
|
+
return CSCTensorHolder(
|
|
158
|
+
target_ccol_indices, target_row_indices, target_values, attr_name_map=self.attr_name_map, shape=self.shape
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def copy_(self, src, stream_holder: StreamHolder | None) -> None:
|
|
162
|
+
"""Overwrite self.tensor (in-place) with a copy of src (CSCTensor)."""
|
|
163
|
+
|
|
164
|
+
self.ccol_indices.copy_(src=src.ccol_indices, stream_holder=stream_holder)
|
|
165
|
+
self.row_indices.copy_(src=src.row_indices, stream_holder=stream_holder)
|
|
166
|
+
self.values.copy_(src=src.values, stream_holder=stream_holder)
|
|
167
|
+
|
|
168
|
+
def to_ust(self, *, stream):
|
|
169
|
+
from nvmath.sparse.ust.tensor import Tensor
|
|
170
|
+
from nvmath.sparse.ust.tensor_format import NamedFormats
|
|
171
|
+
|
|
172
|
+
wrapped = self
|
|
173
|
+
tensor = wrapped.tensor
|
|
174
|
+
if not (wrapped.attr_name_map["is_coalesced"](tensor) and wrapped.attr_name_map["has_sorted_indices"](tensor)):
|
|
175
|
+
raise ValueError(
|
|
176
|
+
"The CSC tensor is not coalesced (metadata sorted with duplicates removed). \
|
|
177
|
+
To coalesce, use the operation provided by your sparse tensor library: `coalesce()`, `sum_duplicates()`, ..."
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if not (
|
|
181
|
+
is_contiguous_and_dense(wrapped.ccol_indices.shape, wrapped.ccol_indices.strides)
|
|
182
|
+
and is_contiguous_and_dense(wrapped.row_indices.shape, wrapped.row_indices.strides)
|
|
183
|
+
and is_contiguous_and_dense(wrapped.values.shape, wrapped.values.strides)
|
|
184
|
+
):
|
|
185
|
+
raise ValueError(
|
|
186
|
+
"The sparse tensor representation (ccol_indices(), row_indices(), and values() tensors) must be \
|
|
187
|
+
dense and contiguous."
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
values = wrapped.values.memory_buffer() # Typed memory viewed as a 1-D tensor.
|
|
191
|
+
|
|
192
|
+
num_dim = self.num_dimensions
|
|
193
|
+
num_sparse_dim = self.attr_name_map["num_sparse_dim"](tensor)
|
|
194
|
+
num_dense_dim = self.attr_name_map["num_dense_dim"](tensor)
|
|
195
|
+
num_batch_dim = num_dim - num_sparse_dim - num_dense_dim
|
|
196
|
+
tensor_format = NamedFormats.CSCd(num_batch_dim, num_dense_dim)
|
|
197
|
+
|
|
198
|
+
# Check if the batch axes are in C-order for all component dense arrays.
|
|
199
|
+
if not (
|
|
200
|
+
check_monotonic_strides(wrapped.ccol_indices.strides[:num_batch_dim], reverse=True)
|
|
201
|
+
and check_monotonic_strides(wrapped.row_indices.strides[:num_batch_dim], reverse=True)
|
|
202
|
+
and check_monotonic_strides(wrapped.values.strides[:num_batch_dim], reverse=True)
|
|
203
|
+
):
|
|
204
|
+
raise ValueError(
|
|
205
|
+
"The batch dimensions in the sparse tensor representation (ccol_indices(), row_indices(), \
|
|
206
|
+
and values() tensors) must use the C-layout."
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# Create the UST.
|
|
210
|
+
ust = Tensor(tensor.shape, tensor_format=tensor_format, index_type=wrapped.index_type, dtype=wrapped.dtype)
|
|
211
|
+
|
|
212
|
+
ust._pos[num_batch_dim + 1] = wrapped.ccol_indices
|
|
213
|
+
ust._crd[num_batch_dim + 1] = wrapped.row_indices
|
|
214
|
+
ust._val = values
|
|
215
|
+
|
|
216
|
+
return ust
|
|
217
|
+
|
|
218
|
+
def to_package(self):
|
|
219
|
+
"""
|
|
220
|
+
This will create a sparse tensor for the original package from which this
|
|
221
|
+
interface was created.
|
|
222
|
+
"""
|
|
223
|
+
create_csc = self.attr_name_map["sparse_format_helper"].create_csc
|
|
224
|
+
return create_csc(self.shape, self.ccol_indices, self.row_indices, self.values)
|
|
225
|
+
|
|
226
|
+
def release(self):
|
|
227
|
+
"""
|
|
228
|
+
This method will release the wrapped tensor and any format-specific data
|
|
229
|
+
by setting them to None.
|
|
230
|
+
"""
|
|
231
|
+
# The tensor reference.
|
|
232
|
+
self.tensor = None
|
|
233
|
+
|
|
234
|
+
# Format-specific data.
|
|
235
|
+
self._ccol_indices = None
|
|
236
|
+
self._row_indices = None
|
|
237
|
+
self._values = None
|
|
238
|
+
|
|
239
|
+
def reset_unchecked(self, tensor):
|
|
240
|
+
"""
|
|
241
|
+
This method will reset the wrapped tensor to the specified one, and update
|
|
242
|
+
any format-specific data accordingly. It assumes that all attributes
|
|
243
|
+
like the device, shape, etc are consistent between the existing and new tensor.
|
|
244
|
+
|
|
245
|
+
Args:
|
|
246
|
+
tensor: The native tensor to wrap.
|
|
247
|
+
"""
|
|
248
|
+
# Update the tensor reference.
|
|
249
|
+
self.tensor = tensor
|
|
250
|
+
|
|
251
|
+
# Format-specific data.
|
|
252
|
+
|
|
253
|
+
if self.tensor_package == "nvmath":
|
|
254
|
+
# The data arrays are already wrapped.
|
|
255
|
+
self._ccol_indices = self._attr_name_map["ccol_indices"](tensor)
|
|
256
|
+
self._row_indices = self._attr_name_map["row_indices"](tensor)
|
|
257
|
+
self._values = self._attr_name_map["values"](tensor)
|
|
258
|
+
else:
|
|
259
|
+
wrapper = self._dense_tensorholder_type
|
|
260
|
+
|
|
261
|
+
ccol_indices = self._attr_name_map["ccol_indices"](tensor)
|
|
262
|
+
self._ccol_indices = wrapper(ccol_indices)
|
|
263
|
+
|
|
264
|
+
row_indices = self._attr_name_map["row_indices"](tensor)
|
|
265
|
+
self._row_indices = wrapper(row_indices)
|
|
266
|
+
|
|
267
|
+
values = self._attr_name_map["values"](tensor)
|
|
268
|
+
self._values = wrapper(values)
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Interface to seamlessly use CSR tensors from different libraries.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations # allows typehint of class methods to return the self class
|
|
10
|
+
|
|
11
|
+
__all__ = ["CSRTensorHolder"]
|
|
12
|
+
|
|
13
|
+
from typing import Literal, TypeVar
|
|
14
|
+
|
|
15
|
+
from nvmath._internal.layout import check_monotonic_strides, is_contiguous_and_dense
|
|
16
|
+
from nvmath.internal import tensor_wrapper
|
|
17
|
+
from nvmath.internal.package_ifc import StreamHolder
|
|
18
|
+
from nvmath.internal.tensor_ifc import TensorHolder
|
|
19
|
+
from nvmath.internal.utils import infer_object_package
|
|
20
|
+
|
|
21
|
+
from .sparse_tensor_ifc import SparseTensorHolder
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
A generic type for the third-party CSRTensor which a CSRTensorHolder implementation wraps
|
|
25
|
+
around.
|
|
26
|
+
"""
|
|
27
|
+
CSRTensor = TypeVar("CSRTensor")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class CSRTensorHolder(SparseTensorHolder):
|
|
31
|
+
"""
|
|
32
|
+
A simple wrapper type for CSR sparse tensors to make the API package-agnostic. The
|
|
33
|
+
naming convention is sparse format name with the suffix "TensorHolder", which convention
|
|
34
|
+
is used in the sparse format helper.
|
|
35
|
+
|
|
36
|
+
Since the implementation is in terms of our dense tensor abstraction, package-specific
|
|
37
|
+
implementation is not needed.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
_format_name: str = "CSR"
|
|
41
|
+
|
|
42
|
+
def __init__(self, crow_indices, col_indices, values, *, attr_name_map=None, shape=None, tensor=None):
|
|
43
|
+
# tensor is the native tensor.
|
|
44
|
+
self.tensor = tensor
|
|
45
|
+
|
|
46
|
+
# attr_name_map is the canonical attribute name to package attribute name map.
|
|
47
|
+
# It is set when constructing from a tensor, otherwise it is None.
|
|
48
|
+
self._attr_name_map = attr_name_map
|
|
49
|
+
|
|
50
|
+
assert (shape is not None) ^ (tensor is not None), "Internal error."
|
|
51
|
+
|
|
52
|
+
if shape is not None:
|
|
53
|
+
self._shape = shape
|
|
54
|
+
else:
|
|
55
|
+
self._shape = tuple(tensor.shape)
|
|
56
|
+
|
|
57
|
+
# Wrap constituent dense tensors, if required.
|
|
58
|
+
if not isinstance(crow_indices, TensorHolder):
|
|
59
|
+
crow_indices = tensor_wrapper.wrap_operand(crow_indices)
|
|
60
|
+
|
|
61
|
+
if not isinstance(col_indices, TensorHolder):
|
|
62
|
+
col_indices = tensor_wrapper.wrap_operand(col_indices)
|
|
63
|
+
|
|
64
|
+
if not isinstance(values, TensorHolder):
|
|
65
|
+
values = tensor_wrapper.wrap_operand(values)
|
|
66
|
+
|
|
67
|
+
# The wrapped constituent dense tensors.
|
|
68
|
+
self._crow_indices = crow_indices
|
|
69
|
+
self._col_indices = col_indices
|
|
70
|
+
self._values = values
|
|
71
|
+
|
|
72
|
+
# Ensure constituent dense tensors are all on the same device.
|
|
73
|
+
device_ids = {d.device_id for d in (self._crow_indices, self._col_indices, self._values)}
|
|
74
|
+
message = f"Internal error: the arrays defining the sparse format aren't on the same device {device_ids}."
|
|
75
|
+
assert len(device_ids) == 1, message
|
|
76
|
+
self._device_id = device_ids.pop()
|
|
77
|
+
|
|
78
|
+
self._device = self._values.device
|
|
79
|
+
|
|
80
|
+
# Capture the native tensor package for use in reset_unchecked().
|
|
81
|
+
self.tensor_package = infer_object_package(self.tensor)
|
|
82
|
+
|
|
83
|
+
# The tensor holder type for the dense constituent tensors (take from values, since
|
|
84
|
+
# all constituent tensors have the same type).
|
|
85
|
+
self._dense_tensorholder_type = values.__class__
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def create_from_tensor(cls, tensor, *, attr_name_map=None):
|
|
89
|
+
assert attr_name_map is not None, "Internal error."
|
|
90
|
+
|
|
91
|
+
# tensor is the native tensor.
|
|
92
|
+
# For UST, the buffers will be CuPy ndarrays.
|
|
93
|
+
crow_indices = attr_name_map["crow_indices"](tensor)
|
|
94
|
+
col_indices = attr_name_map["col_indices"](tensor)
|
|
95
|
+
values = attr_name_map["values"](tensor)
|
|
96
|
+
return CSRTensorHolder(crow_indices, col_indices, values, attr_name_map=attr_name_map, tensor=tensor)
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def attr_name_map(self):
|
|
100
|
+
return self._attr_name_map
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def device(self):
|
|
104
|
+
return self._device
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def device_id(self):
|
|
108
|
+
return self._device_id
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def dtype(self):
|
|
112
|
+
return self._values.dtype
|
|
113
|
+
|
|
114
|
+
@property
|
|
115
|
+
def index_type(self):
|
|
116
|
+
return self._crow_indices.dtype
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def format_name(self) -> str:
|
|
120
|
+
return CSRTensorHolder._format_name
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def num_dimensions(self):
|
|
124
|
+
return len(self._shape)
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def shape(self):
|
|
128
|
+
return self._shape
|
|
129
|
+
|
|
130
|
+
@property
|
|
131
|
+
def crow_indices(self) -> TensorHolder:
|
|
132
|
+
"""The TensorHolder object wrapping the crow_indices array."""
|
|
133
|
+
return self._crow_indices
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def col_indices(self) -> TensorHolder:
|
|
137
|
+
"""The TensorHolder object wrapping the col_indices array."""
|
|
138
|
+
return self._col_indices
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def values(self) -> TensorHolder:
|
|
142
|
+
"""The TensorHolder object wrapping the values array."""
|
|
143
|
+
return self._values
|
|
144
|
+
|
|
145
|
+
def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
|
|
146
|
+
"""Copy the CSRTensor representation to a different device.
|
|
147
|
+
|
|
148
|
+
No copy is performed if the CSRTensor is already on the requested device.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
if self.tensor_package == "nvmath":
|
|
152
|
+
return super().to(device_id=device_id, stream_holder=stream_holder)
|
|
153
|
+
|
|
154
|
+
target_crow_indices = self.crow_indices.to(device_id=device_id, stream_holder=stream_holder)
|
|
155
|
+
target_col_indices = self.col_indices.to(device_id=device_id, stream_holder=stream_holder)
|
|
156
|
+
target_values = self.values.to(device_id=device_id, stream_holder=stream_holder)
|
|
157
|
+
|
|
158
|
+
return CSRTensorHolder(
|
|
159
|
+
target_crow_indices, target_col_indices, target_values, attr_name_map=self.attr_name_map, shape=self.shape
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def copy_(self, src, stream_holder: StreamHolder | None) -> None:
|
|
163
|
+
"""Overwrite self.tensor (in-place) with a copy of src (CSRTensor)."""
|
|
164
|
+
|
|
165
|
+
self.crow_indices.copy_(src=src.crow_indices, stream_holder=stream_holder)
|
|
166
|
+
self.col_indices.copy_(src=src.col_indices, stream_holder=stream_holder)
|
|
167
|
+
self.values.copy_(src=src.values, stream_holder=stream_holder)
|
|
168
|
+
|
|
169
|
+
def to_ust(self, *, stream):
|
|
170
|
+
from nvmath.sparse.ust.tensor import Tensor
|
|
171
|
+
from nvmath.sparse.ust.tensor_format import NamedFormats
|
|
172
|
+
|
|
173
|
+
wrapped = self
|
|
174
|
+
tensor = wrapped.tensor
|
|
175
|
+
if not (wrapped.attr_name_map["is_coalesced"](tensor) and wrapped.attr_name_map["has_sorted_indices"](tensor)):
|
|
176
|
+
raise ValueError(
|
|
177
|
+
"The CSR tensor is not coalesced (metadata sorted with duplicates removed). \
|
|
178
|
+
To coalesce, use the operation provided by your sparse tensor library: `coalesce()`, `sum_duplicates()`, ..."
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if not (
|
|
182
|
+
is_contiguous_and_dense(wrapped.crow_indices.shape, wrapped.crow_indices.strides)
|
|
183
|
+
and is_contiguous_and_dense(wrapped.col_indices.shape, wrapped.col_indices.strides)
|
|
184
|
+
and is_contiguous_and_dense(wrapped.values.shape, wrapped.values.strides)
|
|
185
|
+
):
|
|
186
|
+
raise ValueError(
|
|
187
|
+
"The sparse tensor representation (crow_indices(), col_indices(), and values() tensors) must be \
|
|
188
|
+
dense and contiguous."
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
values = wrapped.values.memory_buffer() # Typed memory viewed as a 1-D tensor.
|
|
192
|
+
|
|
193
|
+
num_dim = self.num_dimensions
|
|
194
|
+
num_sparse_dim = self.attr_name_map["num_sparse_dim"](tensor)
|
|
195
|
+
num_dense_dim = self.attr_name_map["num_dense_dim"](tensor)
|
|
196
|
+
num_batch_dim = num_dim - num_sparse_dim - num_dense_dim
|
|
197
|
+
tensor_format = NamedFormats.CSRd(num_batch_dim, num_dense_dim)
|
|
198
|
+
|
|
199
|
+
# Check if the batch axes are in C-order for all component dense arrays.
|
|
200
|
+
if not (
|
|
201
|
+
check_monotonic_strides(wrapped.crow_indices.strides[:num_batch_dim], reverse=True)
|
|
202
|
+
and check_monotonic_strides(wrapped.col_indices.strides[:num_batch_dim], reverse=True)
|
|
203
|
+
and check_monotonic_strides(wrapped.values.strides[:num_batch_dim], reverse=True)
|
|
204
|
+
):
|
|
205
|
+
raise ValueError(
|
|
206
|
+
"The batch dimensions in the sparse tensor representation (crow_indices(), col_indices(), \
|
|
207
|
+
and values() tensors) must use the C-layout."
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Create the UST.
|
|
211
|
+
ust = Tensor(tensor.shape, tensor_format=tensor_format, index_type=wrapped.index_type, dtype=wrapped.dtype)
|
|
212
|
+
|
|
213
|
+
ust._pos[num_batch_dim + 1] = wrapped.crow_indices
|
|
214
|
+
ust._crd[num_batch_dim + 1] = wrapped.col_indices
|
|
215
|
+
ust._val = values
|
|
216
|
+
|
|
217
|
+
return ust
|
|
218
|
+
|
|
219
|
+
def to_package(self):
|
|
220
|
+
"""
|
|
221
|
+
This will create a sparse tensor for the original package from which this
|
|
222
|
+
interface was created.
|
|
223
|
+
"""
|
|
224
|
+
create_csr = self.attr_name_map["sparse_format_helper"].create_csr
|
|
225
|
+
return create_csr(self.shape, self.crow_indices, self.col_indices, self.values)
|
|
226
|
+
|
|
227
|
+
def release(self):
|
|
228
|
+
"""
|
|
229
|
+
This method will release the wrapped tensor and any format-specific data
|
|
230
|
+
by setting them to None.
|
|
231
|
+
"""
|
|
232
|
+
# The tensor reference.
|
|
233
|
+
self.tensor = None
|
|
234
|
+
|
|
235
|
+
# Format-specific data.
|
|
236
|
+
self._crow_indices = None
|
|
237
|
+
self._col_indices = None
|
|
238
|
+
self._values = None
|
|
239
|
+
|
|
240
|
+
def reset_unchecked(self, tensor):
|
|
241
|
+
"""
|
|
242
|
+
This method will reset the wrapped tensor to the specified one, and update
|
|
243
|
+
any format-specific data accordingly. It assumes that all attributes
|
|
244
|
+
like the device, shape, etc are consistent between the existing and new tensor.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
tensor: The native tensor to wrap.
|
|
248
|
+
"""
|
|
249
|
+
# Update the tensor reference.
|
|
250
|
+
self.tensor = tensor
|
|
251
|
+
|
|
252
|
+
# Format-specific data.
|
|
253
|
+
|
|
254
|
+
if self.tensor_package == "nvmath":
|
|
255
|
+
# The data arrays are already wrapped.
|
|
256
|
+
self._crow_indices = self._attr_name_map["crow_indices"](tensor)
|
|
257
|
+
self._col_indices = self._attr_name_map["col_indices"](tensor)
|
|
258
|
+
self._values = self._attr_name_map["values"](tensor)
|
|
259
|
+
else:
|
|
260
|
+
wrapper = self._dense_tensorholder_type
|
|
261
|
+
|
|
262
|
+
crow_indices = self._attr_name_map["crow_indices"](tensor)
|
|
263
|
+
self._crow_indices = wrapper(crow_indices)
|
|
264
|
+
|
|
265
|
+
col_indices = self._attr_name_map["col_indices"](tensor)
|
|
266
|
+
self._col_indices = wrapper(col_indices)
|
|
267
|
+
|
|
268
|
+
values = self._attr_name_map["values"](tensor)
|
|
269
|
+
self._values = wrapper(values)
|
|
270
|
+
|
|
271
|
+
def release_keeping_shell(self):
|
|
272
|
+
"""Release the wrapped tensor and constituent data by setting them to None."""
|
|
273
|
+
self.tensor = None
|
|
274
|
+
self._crow_indices.tensor = None
|
|
275
|
+
self._col_indices.tensor = None
|
|
276
|
+
self._values.tensor = None
|
|
277
|
+
|
|
278
|
+
def reset_unchecked_keeping_shell(self, tensor):
|
|
279
|
+
"""Reset the wrapped tensor and update constituent data accordingly.
|
|
280
|
+
|
|
281
|
+
Assumes that the new tensor has the same shape, device, dtype, and
|
|
282
|
+
index type as the original.
|
|
283
|
+
"""
|
|
284
|
+
self.tensor = tensor
|
|
285
|
+
attr_map = self._attr_name_map
|
|
286
|
+
self._crow_indices.tensor = attr_map["crow_indices"](tensor)
|
|
287
|
+
self._col_indices.tensor = attr_map["col_indices"](tensor)
|
|
288
|
+
self._values.tensor = attr_map["values"](tensor)
|