nvmath-python 0.5.0__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nvmath/__init__.pxd +0 -0
- nvmath/__init__.py +37 -0
- nvmath/_internal/__init__.py +0 -0
- nvmath/_internal/layout.py +58 -0
- nvmath/_utils.py +363 -0
- nvmath/bindings/__init__.pxd +0 -0
- nvmath/bindings/__init__.py +44 -0
- nvmath/bindings/_internal/__init__.pxd +0 -0
- nvmath/bindings/_internal/__init__.py +0 -0
- nvmath/bindings/_internal/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublas.pxd +518 -0
- nvmath/bindings/_internal/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublasLt.pxd +54 -0
- nvmath/bindings/_internal/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cudss.pxd +44 -0
- nvmath/bindings/_internal/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cufft.pxd +69 -0
- nvmath/bindings/_internal/cufftMp.pxd +77 -0
- nvmath/bindings/_internal/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/curand.pxd +42 -0
- nvmath/bindings/_internal/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolver.pxd +15 -0
- nvmath/bindings/_internal/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverDn.pxd +386 -0
- nvmath/bindings/_internal/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparse.pxd +270 -0
- nvmath/bindings/_internal/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/mathdx.pxd +79 -0
- nvmath/bindings/_internal/nvshmem.pxd +29 -0
- nvmath/bindings/_internal/utils.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/utils.pxd +186 -0
- nvmath/bindings/cublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublas.pxd +545 -0
- nvmath/bindings/cublas.pyi +18 -0
- nvmath/bindings/cublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cublasLt.pxd +99 -0
- nvmath/bindings/cudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cudss.pxd +83 -0
- nvmath/bindings/cudss.pyi +249 -0
- nvmath/bindings/cufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cufft.pxd +114 -0
- nvmath/bindings/cufftMp.pxd +124 -0
- nvmath/bindings/curand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/curand.pxd +71 -0
- nvmath/bindings/cusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolver.pxd +60 -0
- nvmath/bindings/cusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverDn.pxd +410 -0
- nvmath/bindings/cusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cusparse.pxd +329 -0
- nvmath/bindings/cycublas.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublas.pxd +657 -0
- nvmath/bindings/cycublasLt.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycublasLt.pxd +1010 -0
- nvmath/bindings/cycudss.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycudss.pxd +191 -0
- nvmath/bindings/cycufft.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycufft.pxd +320 -0
- nvmath/bindings/cycufftMp.pxd +333 -0
- nvmath/bindings/cycurand.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycurand.pxd +146 -0
- nvmath/bindings/cycusolver.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolver.pxd +143 -0
- nvmath/bindings/cycusolverDn.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverDn.pxd +414 -0
- nvmath/bindings/cycusparse.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparse.pxd +476 -0
- nvmath/bindings/cymathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/cymathdx.pxd +363 -0
- nvmath/bindings/cynvshmem.pxd +126 -0
- nvmath/bindings/mathdx.cp313-win_amd64.pyd +0 -0
- nvmath/bindings/mathdx.pxd +131 -0
- nvmath/bindings/mathdx.pyi +686 -0
- nvmath/bindings/nvpl/__init__.pxd +0 -0
- nvmath/bindings/nvpl/__init__.py +11 -0
- nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
- nvmath/bindings/nvpl/_internal/__init__.py +0 -0
- nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
- nvmath/bindings/nvpl/cyfft.pxd +87 -0
- nvmath/bindings/nvpl/fft.pxd +100 -0
- nvmath/bindings/nvshmem.pxd +54 -0
- nvmath/device/__init__.py +23 -0
- nvmath/device/_deprecated.py +33 -0
- nvmath/device/caching.py +51 -0
- nvmath/device/common.py +131 -0
- nvmath/device/common_backend.py +125 -0
- nvmath/device/common_cuda.py +156 -0
- nvmath/device/common_mathdx.py +97 -0
- nvmath/device/common_numba.py +159 -0
- nvmath/device/common_opaque_tensor.py +128 -0
- nvmath/device/cublasdx.py +1085 -0
- nvmath/device/cublasdx_backend.py +552 -0
- nvmath/device/cublasdx_numba.py +528 -0
- nvmath/device/cufftdx.py +551 -0
- nvmath/device/cufftdx_backend.py +194 -0
- nvmath/device/cufftdx_numba.py +123 -0
- nvmath/device/curand_kernel.py +9147 -0
- nvmath/device/nvrtc.py +95 -0
- nvmath/device/patch.py +35 -0
- nvmath/device/random.py +417 -0
- nvmath/device/random_helpers.py +23 -0
- nvmath/device/random_states.py +189 -0
- nvmath/device/types.py +11 -0
- nvmath/device/vector_types_numba.py +203 -0
- nvmath/distributed/__init__.py +117 -0
- nvmath/distributed/_internal/__init__.py +0 -0
- nvmath/distributed/_internal/nvshmem.py +243 -0
- nvmath/distributed/_internal/tensor_ifc_cupy.py +111 -0
- nvmath/distributed/_internal/tensor_ifc_numpy.py +53 -0
- nvmath/distributed/_internal/tensor_ifc_torch.py +108 -0
- nvmath/distributed/_internal/tensor_wrapper.py +59 -0
- nvmath/distributed/_utils.py +152 -0
- nvmath/distributed/fft/__init__.py +6 -0
- nvmath/distributed/fft/_configuration.py +86 -0
- nvmath/distributed/fft/fft.py +1737 -0
- nvmath/distributed/reshape/__init__.py +6 -0
- nvmath/distributed/reshape/_configuration.py +39 -0
- nvmath/distributed/reshape/reshape.py +1249 -0
- nvmath/fft/__init__.py +7 -0
- nvmath/fft/_configuration.py +208 -0
- nvmath/fft/_exec_utils.py +116 -0
- nvmath/fft/_helpers.py +260 -0
- nvmath/fft/fft.py +2346 -0
- nvmath/internal/__init__.py +5 -0
- nvmath/internal/enum_utils.py +142 -0
- nvmath/internal/formatters.py +87 -0
- nvmath/internal/mem_limit.py +51 -0
- nvmath/internal/package_ifc.py +119 -0
- nvmath/internal/package_ifc_cuda.py +43 -0
- nvmath/internal/package_ifc_cupy.py +49 -0
- nvmath/internal/package_ifc_torch.py +31 -0
- nvmath/internal/package_wrapper.py +14 -0
- nvmath/internal/tensor_ifc.py +143 -0
- nvmath/internal/tensor_ifc_cupy.py +185 -0
- nvmath/internal/tensor_ifc_numpy.py +157 -0
- nvmath/internal/tensor_ifc_torch.py +115 -0
- nvmath/internal/tensor_wrapper.py +160 -0
- nvmath/internal/typemaps.py +154 -0
- nvmath/internal/utils.py +634 -0
- nvmath/linalg/__init__.py +11 -0
- nvmath/linalg/_internal/__init__.py +3 -0
- nvmath/linalg/_internal/algo_cap_ifc.py +86 -0
- nvmath/linalg/_internal/algo_config_ifc.py +87 -0
- nvmath/linalg/_internal/enum_to_tuples.py +64 -0
- nvmath/linalg/_internal/epilog_protocol.py +738 -0
- nvmath/linalg/_internal/matmul_desc_ifc.py +72 -0
- nvmath/linalg/_internal/matmul_pref_ifc.py +65 -0
- nvmath/linalg/_internal/matrix_layout_ifc.py +59 -0
- nvmath/linalg/_internal/typemaps.py +135 -0
- nvmath/linalg/_internal/utils.py +96 -0
- nvmath/linalg/advanced/__init__.py +8 -0
- nvmath/linalg/advanced/_algorithmmod.py +142 -0
- nvmath/linalg/advanced/_configuration.py +320 -0
- nvmath/linalg/advanced/helpers/__init__.py +5 -0
- nvmath/linalg/advanced/helpers/matmul.py +173 -0
- nvmath/linalg/advanced/matmulmod.py +2855 -0
- nvmath/memory.py +266 -0
- nvmath/sparse/__init__.py +18 -0
- nvmath/sparse/_internal/__init__.py +21 -0
- nvmath/sparse/_internal/common_utils.py +81 -0
- nvmath/sparse/_internal/cudss_config_ifc.py +584 -0
- nvmath/sparse/_internal/cudss_data_ifc.py +291 -0
- nvmath/sparse/_internal/cudss_utils.py +398 -0
- nvmath/sparse/_internal/sparse_csr_ifc.py +154 -0
- nvmath/sparse/_internal/sparse_format_helpers.py +88 -0
- nvmath/sparse/_internal/sparse_tensor_ifc.py +80 -0
- nvmath/sparse/advanced/__init__.py +7 -0
- nvmath/sparse/advanced/_configuration.py +150 -0
- nvmath/sparse/advanced/direct_solver.py +1705 -0
- nvmath_python-0.5.0.dist-info/METADATA +122 -0
- nvmath_python-0.5.0.dist-info/RECORD +174 -0
- nvmath_python-0.5.0.dist-info/WHEEL +5 -0
- nvmath_python-0.5.0.dist-info/licenses/LICENSE +177 -0
- nvmath_python-0.5.0.dist-info/top_level.txt +1 -0
nvmath/memory.py
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""Interface for pluggable memory handlers."""
|
|
6
|
+
|
|
7
|
+
__all__ = ["BaseCUDAMemoryManager", "MemoryPointer"]
|
|
8
|
+
|
|
9
|
+
from abc import abstractmethod
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from typing import Protocol, runtime_checkable
|
|
12
|
+
import logging
|
|
13
|
+
import weakref
|
|
14
|
+
|
|
15
|
+
import cuda.core.experimental as ccx
|
|
16
|
+
|
|
17
|
+
from nvmath.internal import utils
|
|
18
|
+
from nvmath.internal.package_ifc_cuda import CUDAPackage
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class MemoryPointer:
|
|
22
|
+
"""
|
|
23
|
+
An RAII class for a device memory buffer.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
device_ptr: The address of the device memory buffer.
|
|
27
|
+
size: The size of the memory buffer in bytes.
|
|
28
|
+
finalizer: A nullary callable that will be called when the buffer is to be freed.
|
|
29
|
+
|
|
30
|
+
.. seealso:: :class:`numba.cuda.MemoryPointer`
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, device_ptr: int, size: int, finalizer: None | Callable[[], None]):
|
|
34
|
+
self.device_ptr = device_ptr
|
|
35
|
+
self.size = size
|
|
36
|
+
self._finalizer: weakref.finalize | None
|
|
37
|
+
if finalizer is not None:
|
|
38
|
+
self._finalizer = weakref.finalize(self, finalizer)
|
|
39
|
+
else:
|
|
40
|
+
self._finalizer = None
|
|
41
|
+
|
|
42
|
+
def free(self):
|
|
43
|
+
"""
|
|
44
|
+
"Frees" the memory buffer by calling the finalizer.
|
|
45
|
+
"""
|
|
46
|
+
if self._finalizer is None:
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
if not self._finalizer.alive:
|
|
50
|
+
raise RuntimeError("The buffer has already been freed.")
|
|
51
|
+
self._finalizer()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@runtime_checkable
|
|
55
|
+
class BaseCUDAMemoryManager(Protocol):
|
|
56
|
+
"""
|
|
57
|
+
Protocol for memory manager plugins.
|
|
58
|
+
|
|
59
|
+
.. seealso:: :class:`numba.cuda.BaseCUDAMemoryManager`
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def __init__(self, device_id: int, logger: logging.Logger):
|
|
64
|
+
raise NotImplementedError
|
|
65
|
+
|
|
66
|
+
@abstractmethod
|
|
67
|
+
def memalloc(self, size: int) -> MemoryPointer:
|
|
68
|
+
"""
|
|
69
|
+
Allocate device memory synchronously or on the current stream.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
size: The size of the memory buffer in bytes.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
An object that owns the allocated memory and is responsible for releasing it (to
|
|
76
|
+
the OS or a pool). The object must have an attribute named ``device_ptr``,
|
|
77
|
+
``device_pointer``, or ``ptr`` specifying the pointer to the allocated memory
|
|
78
|
+
buffer. See :class:`MemoryPointer` for an example interface.
|
|
79
|
+
|
|
80
|
+
Note:
|
|
81
|
+
Objects of type :class:`numba.cuda.MemoryPointer` as well as
|
|
82
|
+
:class:`cupy.cuda.MemoryPointer` meet the requirements listed above for the
|
|
83
|
+
device memory pointer object.
|
|
84
|
+
"""
|
|
85
|
+
raise NotImplementedError
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@runtime_checkable
|
|
89
|
+
class BaseCUDAMemoryManagerAsync(Protocol):
|
|
90
|
+
"""
|
|
91
|
+
Protocol for async memory manager plugins.
|
|
92
|
+
|
|
93
|
+
.. seealso:: :class:`BaseCUDAMemoryManager`
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
@abstractmethod
|
|
97
|
+
def __init__(self, device_id: int, logger: logging.Logger):
|
|
98
|
+
raise NotImplementedError
|
|
99
|
+
|
|
100
|
+
@abstractmethod
|
|
101
|
+
def memalloc_async(self, size: int, stream: ccx.Stream) -> MemoryPointer:
|
|
102
|
+
"""
|
|
103
|
+
Allocate device memory asynchronously on the provided stream.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
size: The size of the memory buffer in bytes.
|
|
107
|
+
stream: A cuda.core.Stream object on which the allocation will be performed.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
An object that owns the allocated memory and is responsible for releasing it (to
|
|
111
|
+
the OS or a pool). The object must have an attribute named ``device_ptr``,
|
|
112
|
+
``device_pointer``, or ``ptr`` specifying the pointer to the allocated memory
|
|
113
|
+
buffer. See :class:`MemoryPointer` for an example interface.
|
|
114
|
+
|
|
115
|
+
Note:
|
|
116
|
+
Objects of type :class:`numba.cuda.MemoryPointer` as well as
|
|
117
|
+
:class:`cupy.cuda.MemoryPointer` meet the requirements listed above for the
|
|
118
|
+
device memory pointer object.
|
|
119
|
+
"""
|
|
120
|
+
raise NotImplementedError
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class _RawCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
|
|
124
|
+
"""
|
|
125
|
+
Raw device memory allocator.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
device_id: The ID (int) of the device on which memory is to be allocated.
|
|
129
|
+
logger (logging.Logger): Python Logger object.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
def __init__(self, device_id: int, logger: logging.Logger):
|
|
133
|
+
"""
|
|
134
|
+
__init__(device_id)
|
|
135
|
+
"""
|
|
136
|
+
self.device_id = device_id
|
|
137
|
+
self.logger = logger
|
|
138
|
+
|
|
139
|
+
def memalloc_async(self, size: int, stream: ccx.Stream) -> MemoryPointer:
|
|
140
|
+
with utils.device_ctx(self.device_id) as device:
|
|
141
|
+
buffer = device.allocate(size=size, stream=stream)
|
|
142
|
+
device_ptr = int(buffer.handle)
|
|
143
|
+
|
|
144
|
+
self.logger.debug(
|
|
145
|
+
"_RawCUDAMemoryManager (allocate memory): size = %d, ptr = %d, device_id = %d, stream = %s",
|
|
146
|
+
size,
|
|
147
|
+
device_ptr,
|
|
148
|
+
self.device_id,
|
|
149
|
+
stream,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def finalizer():
|
|
153
|
+
nonlocal buffer, stream, device_ptr
|
|
154
|
+
self.logger.debug(
|
|
155
|
+
"_RawCUDAMemoryManager (release memory): ptr = %d, device_id = %d, stream = %s",
|
|
156
|
+
device_ptr,
|
|
157
|
+
self.device_id,
|
|
158
|
+
stream,
|
|
159
|
+
)
|
|
160
|
+
with utils.device_ctx(self.device_id):
|
|
161
|
+
buffer.close(stream=stream)
|
|
162
|
+
|
|
163
|
+
return MemoryPointer(device_ptr, size, finalizer=finalizer)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
_MEMORY_MANAGER: dict[str, type[BaseCUDAMemoryManager] | type[BaseCUDAMemoryManagerAsync]] = {
|
|
167
|
+
"_raw": _RawCUDAMemoryManager,
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def lazy_load_cupy():
|
|
172
|
+
global _MEMORY_MANAGER
|
|
173
|
+
import cupy as cp
|
|
174
|
+
from nvmath.internal.package_ifc_cupy import CupyPackage
|
|
175
|
+
|
|
176
|
+
class _CupyCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
|
|
177
|
+
"""
|
|
178
|
+
CuPy device memory allocator.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
device_id: The ID (int) of the device on which memory is to be allocated.
|
|
182
|
+
logger (logging.Logger): Python Logger object.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
def __init__(self, device_id: int, logger: logging.Logger):
|
|
186
|
+
"""
|
|
187
|
+
__init__(device_id)
|
|
188
|
+
"""
|
|
189
|
+
self.device_id = device_id
|
|
190
|
+
self.logger = logger
|
|
191
|
+
|
|
192
|
+
def memalloc_async(self, size: int, stream) -> MemoryPointer:
|
|
193
|
+
stream_ctx = CupyPackage.to_stream_context(
|
|
194
|
+
CupyPackage.create_external_stream(self.device_id, CUDAPackage.to_stream_pointer(stream))
|
|
195
|
+
)
|
|
196
|
+
with utils.device_ctx(self.device_id), stream_ctx:
|
|
197
|
+
cp_mem_ptr = cp.cuda.alloc(size)
|
|
198
|
+
device_ptr = cp_mem_ptr.ptr
|
|
199
|
+
|
|
200
|
+
self.logger.debug(
|
|
201
|
+
"_CupyCUDAMemoryManager (allocate memory): size = %d, ptr = %d, device_id = %d, stream = %s",
|
|
202
|
+
size,
|
|
203
|
+
device_ptr,
|
|
204
|
+
self.device_id,
|
|
205
|
+
stream,
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def finalizer():
|
|
209
|
+
# The cupy MemoryPointer object is RAII, so we keep a reference to it
|
|
210
|
+
# until we don't need it anymore.
|
|
211
|
+
nonlocal cp_mem_ptr, device_ptr
|
|
212
|
+
self.logger.debug("_CupyCUDAMemoryManager (release memory): ptr = %d", device_ptr)
|
|
213
|
+
del cp_mem_ptr
|
|
214
|
+
|
|
215
|
+
return MemoryPointer(device_ptr, size, finalizer=finalizer)
|
|
216
|
+
|
|
217
|
+
_MEMORY_MANAGER["cupy"] = _CupyCUDAMemoryManager
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def lazy_load_torch():
|
|
221
|
+
global _MEMORY_MANAGER
|
|
222
|
+
|
|
223
|
+
from torch.cuda import caching_allocator_alloc, caching_allocator_delete
|
|
224
|
+
from nvmath.internal.package_ifc_torch import TorchPackage
|
|
225
|
+
|
|
226
|
+
class _TorchCUDAMemoryManager(BaseCUDAMemoryManagerAsync):
|
|
227
|
+
"""
|
|
228
|
+
Torch caching memory allocator.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
device_id: The ID (int) of the device on which memory is to be allocated.
|
|
232
|
+
logger (logging.Logger): Python Logger object.
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
def __init__(self, device_id: int, logger: logging.Logger):
|
|
236
|
+
"""
|
|
237
|
+
__init__(device_id)
|
|
238
|
+
"""
|
|
239
|
+
self.device_id = device_id
|
|
240
|
+
self.logger = logger
|
|
241
|
+
|
|
242
|
+
def memalloc_async(self, size: int, stream: ccx.Stream) -> MemoryPointer:
|
|
243
|
+
torch_stream = TorchPackage.create_external_stream(self.device_id, CUDAPackage.to_stream_pointer(stream))
|
|
244
|
+
device_ptr = caching_allocator_alloc(size, device=self.device_id, stream=torch_stream)
|
|
245
|
+
|
|
246
|
+
self.logger.debug(
|
|
247
|
+
"_TorchCUDAMemoryManager (allocate memory): size = %d, ptr = %d, device_id = %d, stream = %s",
|
|
248
|
+
size,
|
|
249
|
+
device_ptr,
|
|
250
|
+
self.device_id,
|
|
251
|
+
stream,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
def finalizer():
|
|
255
|
+
nonlocal device_ptr, stream
|
|
256
|
+
self.logger.debug(
|
|
257
|
+
"_TorchCUDAMemoryManager (release memory): ptr = %d, device_id = %d, stream = %s",
|
|
258
|
+
device_ptr,
|
|
259
|
+
self.device_id,
|
|
260
|
+
stream,
|
|
261
|
+
)
|
|
262
|
+
caching_allocator_delete(device_ptr)
|
|
263
|
+
|
|
264
|
+
return MemoryPointer(device_ptr, size, finalizer=finalizer)
|
|
265
|
+
|
|
266
|
+
_MEMORY_MANAGER["torch"] = _TorchCUDAMemoryManager
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from nvmath._utils import force_loading_cudss
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
force_loading_cudss("12")
|
|
9
|
+
except RuntimeError:
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
del force_loading_cudss
|
|
13
|
+
|
|
14
|
+
from . import advanced # noqa: E402
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"advanced",
|
|
18
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from . import common_utils as common_utils
|
|
6
|
+
from . import cudss_config_ifc as cudss_config_ifc
|
|
7
|
+
from . import cudss_data_ifc as cudss_data_ifc
|
|
8
|
+
from . import cudss_utils as cudss_utils
|
|
9
|
+
from . import sparse_csr_ifc as sparse_csr_ifc
|
|
10
|
+
from . import sparse_format_helpers as sparse_format_helpers
|
|
11
|
+
from . import sparse_tensor_ifc as sparse_tensor_ifc
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"common_utils",
|
|
15
|
+
"cudss_config_ifc",
|
|
16
|
+
"cudss_data_ifc",
|
|
17
|
+
"cudss_utils",
|
|
18
|
+
"sparse_csr_ifc",
|
|
19
|
+
"sparse_format_helpers",
|
|
20
|
+
"sparse_tensor_ifc",
|
|
21
|
+
]
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
A collection of sparse utilities.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import importlib
|
|
10
|
+
from collections.abc import Sequence
|
|
11
|
+
|
|
12
|
+
from nvmath.internal.utils import infer_object_package
|
|
13
|
+
from nvmath.sparse._internal.sparse_format_helpers import PACKAGE_HELPER_MAP
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def check_supported_package(native_operands):
|
|
17
|
+
"""
|
|
18
|
+
Check if the operands belong to one of the supported packages.
|
|
19
|
+
"""
|
|
20
|
+
package = {infer_object_package(o) for o in native_operands}
|
|
21
|
+
if len(package) != 1:
|
|
22
|
+
raise ValueError(f"The sparse operands do not belong to the same package: {package}.")
|
|
23
|
+
|
|
24
|
+
package = package.pop()
|
|
25
|
+
if package not in PACKAGE_HELPER_MAP:
|
|
26
|
+
raise TypeError(f"The sparse operand package {package} is not supported.")
|
|
27
|
+
|
|
28
|
+
return package
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def wrap_sparse_operand(native_operand):
|
|
32
|
+
"""
|
|
33
|
+
Wrap one "native" sparse operand so that package-agnostic API can be used.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
helper = PACKAGE_HELPER_MAP[infer_object_package(native_operand)]
|
|
37
|
+
sparse_format = helper.sparse_format_name(native_operand)
|
|
38
|
+
attr_name_map = getattr(helper, f"{sparse_format.lower()}_attribute_names")()
|
|
39
|
+
|
|
40
|
+
module_name = f"nvmath.sparse._internal.sparse_{sparse_format.lower()}_ifc"
|
|
41
|
+
module = importlib.import_module(module_name)
|
|
42
|
+
SparseHolder = getattr(module, f"{sparse_format}TensorHolder")
|
|
43
|
+
|
|
44
|
+
return SparseHolder.create_from_tensor(native_operand, attr_name_map=attr_name_map)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def wrap_sparse_operands(native_operands):
|
|
48
|
+
"""
|
|
49
|
+
Wrap each "native" sparse operand so that package-agnostic API can be used.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
if not isinstance(native_operands, Sequence):
|
|
53
|
+
return wrap_sparse_operand(native_operands)
|
|
54
|
+
|
|
55
|
+
package = check_supported_package(native_operands)
|
|
56
|
+
helper = PACKAGE_HELPER_MAP[package]
|
|
57
|
+
|
|
58
|
+
sparse_format = {helper.sparse_format_name(o) for o in native_operands}
|
|
59
|
+
if len(sparse_format) != 1:
|
|
60
|
+
raise ValueError(f"The sparse operands do not have the same sparse format: {sparse_format}")
|
|
61
|
+
sparse_format = sparse_format.pop()
|
|
62
|
+
attr_name_map = getattr(helper, f"{sparse_format.lower()}_attribute_names")()
|
|
63
|
+
|
|
64
|
+
module_name = f"nvmath.sparse._internal.sparse_{sparse_format.lower()}_ifc"
|
|
65
|
+
module = importlib.import_module(module_name)
|
|
66
|
+
SparseHolder = getattr(module, f"{sparse_format}TensorHolder")
|
|
67
|
+
|
|
68
|
+
return [SparseHolder.create_from_tensor(o, attr_name_map=attr_name_map) for o in native_operands]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# TODO: Unify all the get_attribute functions in internal.utils
|
|
72
|
+
# as get(operands, attribute, attribute_desc).
|
|
73
|
+
def get_operands_index_type(operands):
|
|
74
|
+
"""
|
|
75
|
+
Return the index type name of the tensors.
|
|
76
|
+
"""
|
|
77
|
+
index_type = operands[0].index_type
|
|
78
|
+
if not all(operand.index_type == index_type for operand in operands):
|
|
79
|
+
index_types = {operand.index_type for operand in operands}
|
|
80
|
+
raise ValueError(f"All operands must have the same index type. The index types found = {index_types}.")
|
|
81
|
+
return index_type
|