nvmath-python 0.9.0__cp314-cp314-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 +383 -0
- nvmath/_utils.py +150 -0
- nvmath/bindings/__init__.py +51 -0
- nvmath/bindings/_internal/__init__.pxd +0 -0
- nvmath/bindings/_internal/__init__.py +0 -0
- nvmath/bindings/_internal/cublas.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublas.pxd +530 -0
- nvmath/bindings/_internal/cublasLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cublasLt.pxd +59 -0
- nvmath/bindings/_internal/cublasMp.pxd +52 -0
- nvmath/bindings/_internal/cudss.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cudss.pxd +47 -0
- nvmath/bindings/_internal/cufft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cufft.pxd +70 -0
- nvmath/bindings/_internal/cufftMp.pxd +77 -0
- nvmath/bindings/_internal/curand.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/curand.pxd +42 -0
- nvmath/bindings/_internal/cusolver.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolver.pxd +15 -0
- nvmath/bindings/_internal/cusolverDn.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusolverDn.pxd +406 -0
- nvmath/bindings/_internal/cusparse.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparse.pxd +277 -0
- nvmath/bindings/_internal/cusparseLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cusparseLt.pxd +48 -0
- nvmath/bindings/_internal/cutensor.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/cutensor.pxd +58 -0
- nvmath/bindings/_internal/mathdx.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/mathdx.pxd +116 -0
- nvmath/bindings/_internal/nvshmem.pxd +29 -0
- nvmath/bindings/_internal/utils.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/_internal/utils.pxd +179 -0
- nvmath/bindings/_internal/utils.pyi +10 -0
- nvmath/bindings/cublas.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cublas.pxd +558 -0
- nvmath/bindings/cublas.pyi +746 -0
- nvmath/bindings/cublasLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cublasLt.pxd +109 -0
- nvmath/bindings/cublasLt.pyi +1337 -0
- nvmath/bindings/cublasMp.pxd +85 -0
- nvmath/bindings/cublasMp.pyi +219 -0
- nvmath/bindings/cudss.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cudss.pxd +86 -0
- nvmath/bindings/cudss.pyi +282 -0
- nvmath/bindings/cufft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cufft.pxd +118 -0
- nvmath/bindings/cufft.pyi +241 -0
- nvmath/bindings/cufftMp.pxd +124 -0
- nvmath/bindings/cufftMp.pyi +260 -0
- nvmath/bindings/curand.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/curand.pxd +71 -0
- nvmath/bindings/curand.pyi +159 -0
- nvmath/bindings/cusolver.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cusolver.pxd +62 -0
- nvmath/bindings/cusolver.pyi +242 -0
- nvmath/bindings/cusolverDn.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cusolverDn.pxd +430 -0
- nvmath/bindings/cusolverDn.pyi +416 -0
- nvmath/bindings/cusparse.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cusparse.pxd +338 -0
- nvmath/bindings/cusparse.pyi +659 -0
- nvmath/bindings/cusparseLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cusparseLt.pxd +99 -0
- nvmath/bindings/cusparseLt.pyi +198 -0
- nvmath/bindings/cutensor.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cutensor.pxd +98 -0
- nvmath/bindings/cutensor.pyi +294 -0
- nvmath/bindings/cycublas.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycublas.pxd +684 -0
- nvmath/bindings/cycublasLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycublasLt.pxd +1055 -0
- nvmath/bindings/cycublasMp.pxd +183 -0
- nvmath/bindings/cycudss.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycudss.pxd +224 -0
- nvmath/bindings/cycufft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycufft.pxd +326 -0
- nvmath/bindings/cycufftMp.pxd +334 -0
- nvmath/bindings/cycurand.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycurand.pxd +146 -0
- nvmath/bindings/cycusolver.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolver.pxd +154 -0
- nvmath/bindings/cycusolverDn.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycusolverDn.pxd +446 -0
- nvmath/bindings/cycusparse.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparse.pxd +470 -0
- nvmath/bindings/cycusparseLt.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycusparseLt.pxd +150 -0
- nvmath/bindings/cycutensor.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cycutensor.pxd +192 -0
- nvmath/bindings/cymathdx.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/cymathdx.pxd +552 -0
- nvmath/bindings/cynvshmem.pxd +126 -0
- nvmath/bindings/mathdx.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/mathdx.pxd +182 -0
- nvmath/bindings/mathdx.pyi +1244 -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.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/_internal/blas.pxd +125 -0
- nvmath/bindings/nvpl/_internal/fft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
- nvmath/bindings/nvpl/blas.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/blas.pxd +85 -0
- nvmath/bindings/nvpl/blas.pyi +122 -0
- nvmath/bindings/nvpl/cyblas.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/cyblas.pxd +166 -0
- nvmath/bindings/nvpl/cyfft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/cyfft.pxd +92 -0
- nvmath/bindings/nvpl/fft.cp314-win_amd64.pyd +0 -0
- nvmath/bindings/nvpl/fft.pxd +100 -0
- nvmath/bindings/nvpl/fft.pyi +100 -0
- nvmath/bindings/nvshmem.pxd +54 -0
- nvmath/bindings/nvshmem.pyi +179 -0
- nvmath/device/__init__.py +21 -0
- nvmath/device/_deprecated.py +33 -0
- nvmath/device/common.py +313 -0
- nvmath/device/common_backend.py +131 -0
- nvmath/device/common_cuda.py +201 -0
- nvmath/device/common_numba.py +310 -0
- nvmath/device/common_opaque_tensor.py +201 -0
- nvmath/device/cublasdx.py +1805 -0
- nvmath/device/cublasdx_backend.py +807 -0
- nvmath/device/cublasdx_numba.py +1612 -0
- nvmath/device/cufftdx.py +510 -0
- nvmath/device/cufftdx_backend.py +196 -0
- nvmath/device/cufftdx_numba.py +196 -0
- nvmath/device/curand_kernel.py +9147 -0
- nvmath/device/cusolverdx.py +2690 -0
- nvmath/device/cusolverdx_backend.py +440 -0
- nvmath/device/cusolverdx_numba.py +1624 -0
- nvmath/device/llvm_array.py +29 -0
- nvmath/device/random.py +445 -0
- nvmath/device/random_helpers.py +23 -0
- nvmath/device/random_states.py +187 -0
- nvmath/device/types.py +147 -0
- nvmath/device/vector_types_numba.py +203 -0
- nvmath/distributed/__init__.py +205 -0
- nvmath/distributed/_internal/__init__.py +0 -0
- nvmath/distributed/_internal/nvshmem.py +302 -0
- nvmath/distributed/_internal/tensor_ifc.py +67 -0
- nvmath/distributed/_internal/tensor_ifc_cupy.py +62 -0
- nvmath/distributed/_internal/tensor_ifc_host_device.py +165 -0
- nvmath/distributed/_internal/tensor_ifc_numpy.py +41 -0
- nvmath/distributed/_internal/tensor_ifc_torch.py +141 -0
- nvmath/distributed/_internal/tensor_wrapper.py +78 -0
- nvmath/distributed/_utils.py +167 -0
- nvmath/distributed/distribution.py +770 -0
- nvmath/distributed/fft/__init__.py +7 -0
- nvmath/distributed/fft/_configuration.py +79 -0
- nvmath/distributed/fft/fft.py +2801 -0
- nvmath/distributed/linalg/__init__.py +12 -0
- nvmath/distributed/linalg/_internal/__init__.py +3 -0
- nvmath/distributed/linalg/_internal/epilog_protocol.py +496 -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 +166 -0
- nvmath/distributed/linalg/advanced/matmulmod.py +2908 -0
- nvmath/distributed/process_group.py +408 -0
- nvmath/distributed/reshape/__init__.py +6 -0
- nvmath/distributed/reshape/_configuration.py +39 -0
- nvmath/distributed/reshape/reshape.py +1256 -0
- nvmath/fft/__init__.py +7 -0
- nvmath/fft/_configuration.py +208 -0
- nvmath/fft/_exec_utils.py +109 -0
- nvmath/fft/_helpers.py +237 -0
- nvmath/fft/fft.py +2903 -0
- nvmath/internal/__init__.pxd +3 -0
- nvmath/internal/__init__.py +10 -0
- nvmath/internal/_bindings.cp314-win_amd64.pyd +0 -0
- nvmath/internal/_bindings.pxd +12 -0
- nvmath/internal/_device_utils.py +54 -0
- nvmath/internal/enum_utils.py +142 -0
- nvmath/internal/formatters.py +87 -0
- nvmath/internal/mem_limit.py +51 -0
- nvmath/internal/memory.cp314-win_amd64.pyd +0 -0
- nvmath/internal/memory.pxd +10 -0
- nvmath/internal/memory.pyi +46 -0
- nvmath/internal/ndbuffer/__init__.pxd +3 -0
- nvmath/internal/ndbuffer/__init__.py +7 -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 +240 -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/ndbuffer/copy_kernel.cp314-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/copy_kernel.pxd +9 -0
- nvmath/internal/ndbuffer/copy_kernel.pyi +9 -0
- nvmath/internal/ndbuffer/data_layout.cp314-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/data_layout.pxd +72 -0
- nvmath/internal/ndbuffer/data_layout.pyi +23 -0
- nvmath/internal/ndbuffer/jit.cp314-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/jit.pxd +7 -0
- nvmath/internal/ndbuffer/jit.pyi +6 -0
- nvmath/internal/ndbuffer/ndbuffer.cp314-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/ndbuffer.pxd +36 -0
- nvmath/internal/ndbuffer/ndbuffer.pyi +41 -0
- nvmath/internal/ndbuffer/package_utils.cp314-win_amd64.pyd +0 -0
- nvmath/internal/ndbuffer/package_utils.pxd +11 -0
- nvmath/internal/ndbuffer/package_utils.pyi +12 -0
- nvmath/internal/package_ifc.py +147 -0
- nvmath/internal/package_ifc_cuda.py +49 -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 +194 -0
- nvmath/internal/tensor_ifc_cupy.py +241 -0
- nvmath/internal/tensor_ifc_ndbuffer.py +153 -0
- nvmath/internal/tensor_ifc_numpy.py +183 -0
- nvmath/internal/tensor_ifc_torch.py +176 -0
- nvmath/internal/tensor_wrapper.py +157 -0
- nvmath/internal/typemaps.py +162 -0
- nvmath/internal/utils.py +771 -0
- nvmath/linalg/__init__.py +46 -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 +217 -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/typemaps.py +144 -0
- nvmath/linalg/_internal/utils.py +134 -0
- nvmath/linalg/advanced/__init__.py +8 -0
- nvmath/linalg/advanced/_algorithmmod.py +149 -0
- nvmath/linalg/advanced/_configuration.py +349 -0
- nvmath/linalg/advanced/helpers/__init__.py +5 -0
- nvmath/linalg/advanced/helpers/matmul.py +1348 -0
- nvmath/linalg/advanced/matmulmod.py +3937 -0
- nvmath/linalg/generic/__init__.py +43 -0
- nvmath/linalg/generic/_configuration/__init__.py +37 -0
- nvmath/linalg/generic/_configuration/layout.py +263 -0
- nvmath/linalg/generic/_configuration/match.py +609 -0
- nvmath/linalg/generic/_configuration/qualifiers.py +494 -0
- nvmath/linalg/generic/_configuration/wrap.py +217 -0
- nvmath/linalg/generic/_dtype.py +15 -0
- nvmath/linalg/generic/matmulmod.py +1060 -0
- nvmath/memory.py +282 -0
- nvmath/sparse/__init__.py +38 -0
- nvmath/sparse/_internal/__init__.py +21 -0
- nvmath/sparse/_internal/common_utils.py +144 -0
- nvmath/sparse/_internal/cudss_config_ifc.py +741 -0
- nvmath/sparse/_internal/cudss_data_ifc.py +399 -0
- nvmath/sparse/_internal/cudss_utils.py +445 -0
- nvmath/sparse/_internal/cusparse_utils.py +382 -0
- nvmath/sparse/_internal/sparse_bsc_ifc.py +300 -0
- nvmath/sparse/_internal/sparse_bsr_ifc.py +303 -0
- nvmath/sparse/_internal/sparse_coo_ifc.py +254 -0
- nvmath/sparse/_internal/sparse_csc_ifc.py +266 -0
- nvmath/sparse/_internal/sparse_csr_ifc.py +266 -0
- nvmath/sparse/_internal/sparse_dia_ifc.py +239 -0
- nvmath/sparse/_internal/sparse_format_helpers.py +601 -0
- nvmath/sparse/_internal/sparse_tensor_ifc.py +121 -0
- nvmath/sparse/_internal/sparse_ust_ifc.py +146 -0
- nvmath/sparse/_internal/utils.py +56 -0
- nvmath/sparse/advanced/__init__.py +7 -0
- nvmath/sparse/advanced/_configuration.py +230 -0
- nvmath/sparse/advanced/direct_solver.py +1884 -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 +2426 -0
- nvmath/sparse/ust/__init__.py +7 -0
- nvmath/sparse/ust/_converters.py +378 -0
- nvmath/sparse/ust/_drawer.py +552 -0
- nvmath/sparse/ust/_emitter.py +553 -0
- nvmath/sparse/ust/_jit.py +212 -0
- nvmath/sparse/ust/_kernel.py +346 -0
- nvmath/sparse/ust/_semiring.py +71 -0
- nvmath/sparse/ust/_utils.py +102 -0
- nvmath/sparse/ust/interfaces/__init__.py +0 -0
- nvmath/sparse/ust/interfaces/torch_interface.py +476 -0
- nvmath/sparse/ust/semiring_ops.py +71 -0
- nvmath/sparse/ust/tensor.py +1027 -0
- nvmath/sparse/ust/tensor_drawer.py +552 -0
- nvmath/sparse/ust/tensor_emitter.py +558 -0
- nvmath/sparse/ust/tensor_format.py +935 -0
- nvmath/sparse/ust/tensor_jit.py +212 -0
- nvmath/sparse/ust/tensor_kernel.py +348 -0
- nvmath/sparse/ust/tensor_utils.py +380 -0
- nvmath/tensor/__init__.py +6 -0
- nvmath/tensor/_configuration.py +95 -0
- nvmath/tensor/_internal/__init__.py +3 -0
- nvmath/tensor/_internal/cutensor_config_ifc.py +247 -0
- nvmath/tensor/_internal/cutensor_utils.py +162 -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 +1861 -0
- nvmath_python-0.9.0.dist-info/METADATA +127 -0
- nvmath_python-0.9.0.dist-info/RECORD +309 -0
- nvmath_python-0.9.0.dist-info/WHEEL +5 -0
- nvmath_python-0.9.0.dist-info/licenses/LICENSE +177 -0
- nvmath_python-0.9.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
"""APIs in this module are for NVIDIA-use only.
|
|
7
|
+
|
|
8
|
+
APIs in internal are not intended for third-party developers, but are shared between NVIDIA
|
|
9
|
+
packages.
|
|
10
|
+
"""
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from libc.stdint cimport intptr_t, int64_t, uint64_t
|
|
6
|
+
|
|
7
|
+
cpdef memcpy_async(intptr_t dst_ptr, intptr_t src_ptr, int64_t size, intptr_t stream)
|
|
8
|
+
cpdef stream_sync(intptr_t stream)
|
|
9
|
+
cpdef uint64_t get_memory_pool_reserved_memory_size(pool) except? -1
|
|
10
|
+
cpdef uint64_t get_memory_pool_used_memory_size(pool) except? -1
|
|
11
|
+
cpdef free_memory_pool_reserved_memory(pool)
|
|
12
|
+
cpdef launch_kernel(intptr_t f, intptr_t kernel_params, int gx, int gy, int gz, int bx, int by, int bz, unsigned int shared_mem_bytes, intptr_t stream_handle)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from cuda.core import Device, system
|
|
7
|
+
except ImportError:
|
|
8
|
+
from cuda.core.experimental import Device, system
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
import threading
|
|
12
|
+
|
|
13
|
+
thread_local = threading.local()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_device(device_id: int) -> Device:
|
|
17
|
+
"""
|
|
18
|
+
NOTE: the function DOES NOT change the current cuda device. If it needs
|
|
19
|
+
to call .set_current(), it immediately restores the previous device
|
|
20
|
+
before exiting. To temporarily change the current device,
|
|
21
|
+
please use utils.device_ctx().
|
|
22
|
+
|
|
23
|
+
A counterpart to cuda.core.Device(int), with extra initialization.
|
|
24
|
+
Returns initialized cuda.core.Device(device_id) object, i.e.
|
|
25
|
+
makes sure to call .set_current() on the instance once per thread.
|
|
26
|
+
Calling .set_current() is not just about a valid CUDA context in a thread,
|
|
27
|
+
but specifically cuda.core requirement to initialize the device instance.
|
|
28
|
+
|
|
29
|
+
The function keeps a thread-local cache of "initialized"
|
|
30
|
+
device instances. It mirrors cuda.core.Device(int) caching,
|
|
31
|
+
adding the set_current() call on the first access.
|
|
32
|
+
"""
|
|
33
|
+
try:
|
|
34
|
+
devices = thread_local.devices
|
|
35
|
+
except AttributeError:
|
|
36
|
+
try:
|
|
37
|
+
num_devices = system.get_num_devices()
|
|
38
|
+
except AttributeError:
|
|
39
|
+
# cuda.core < 0.5.0
|
|
40
|
+
num_devices = system.num_devices
|
|
41
|
+
thread_local.devices = devices = [None] * num_devices
|
|
42
|
+
|
|
43
|
+
device = devices[device_id]
|
|
44
|
+
if device is None:
|
|
45
|
+
current_device = Device()
|
|
46
|
+
current_device_id = current_device.device_id
|
|
47
|
+
try:
|
|
48
|
+
device = Device(device_id)
|
|
49
|
+
device.set_current()
|
|
50
|
+
devices[device_id] = device
|
|
51
|
+
finally:
|
|
52
|
+
if current_device_id != device_id:
|
|
53
|
+
current_device.set_current()
|
|
54
|
+
return device
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Factories for create options dataclasses, as well as utilities to add docstring to enum
|
|
7
|
+
classes.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import dataclasses
|
|
11
|
+
import re
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from enum import IntEnum
|
|
14
|
+
from typing import Any, ClassVar
|
|
15
|
+
|
|
16
|
+
import numpy
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def create_options_class_from_enum(
|
|
20
|
+
options_class_name: str,
|
|
21
|
+
enum_class: IntEnum,
|
|
22
|
+
get_attr_dtype: Callable,
|
|
23
|
+
description: str,
|
|
24
|
+
filter_re: str = r"(?P<option_name>.*)",
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Create an options dataclass from a Python enum class. Names can be filtered if desired.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
options_class_name: Name of the dataclass that will be created.
|
|
31
|
+
|
|
32
|
+
enum_class: The IntEnum class that contains the options for the dataclass.
|
|
33
|
+
|
|
34
|
+
get_attr_dtype: A callable that takes in an enum value as the argument and returns
|
|
35
|
+
the size in bytes of the cuTensorNet.
|
|
36
|
+
|
|
37
|
+
filter_re: A re definition that defines the match named 'option_name'.
|
|
38
|
+
"""
|
|
39
|
+
if r"(?P<option_name>" not in filter_re:
|
|
40
|
+
message = """Incorrect re.
|
|
41
|
+
The re for the filter must contain the named group 'option_name'."""
|
|
42
|
+
raise ValueError(message)
|
|
43
|
+
|
|
44
|
+
# Helper vars for creating attribute docstring.
|
|
45
|
+
doc = f"""A data class for capturing the {description} options.
|
|
46
|
+
|
|
47
|
+
Attributes:
|
|
48
|
+
"""
|
|
49
|
+
indent = " " * 8
|
|
50
|
+
prefix = determine_enum_prefix(enum_class, "_ATTRIBUTE")
|
|
51
|
+
|
|
52
|
+
filter_pattern = re.compile(filter_re)
|
|
53
|
+
option_to_enum: dict[str, IntEnum] = {}
|
|
54
|
+
option_to_dtype: dict[str, Any] = {}
|
|
55
|
+
# mypy claims that IntEnum is not iterable
|
|
56
|
+
for e in enum_class: # type: ignore
|
|
57
|
+
m = filter_pattern.match(e.name)
|
|
58
|
+
if not m:
|
|
59
|
+
continue
|
|
60
|
+
option_name = m.group("option_name").lower()
|
|
61
|
+
option_to_enum[option_name] = e
|
|
62
|
+
option_to_dtype[option_name] = get_attr_dtype(e)
|
|
63
|
+
|
|
64
|
+
# Add docstring for this attribute.
|
|
65
|
+
doc += indent + option_name + ":" + f" See `{prefix + '_' + m.group(0)}`.\n"
|
|
66
|
+
|
|
67
|
+
field: tuple[str, Any, None | dict]
|
|
68
|
+
fields: list[tuple[str, Any, None | dict]] = []
|
|
69
|
+
for option_name, dtype in option_to_dtype.items():
|
|
70
|
+
if numpy.issubdtype(dtype, numpy.integer):
|
|
71
|
+
field = option_name, int | None, dataclasses.field(default=None)
|
|
72
|
+
else:
|
|
73
|
+
field = option_name, Any | None, dataclasses.field(default=None)
|
|
74
|
+
fields.append(field)
|
|
75
|
+
|
|
76
|
+
# Add class attributes.
|
|
77
|
+
|
|
78
|
+
field = "option_to_enum", ClassVar[dict], dataclasses.field(default=option_to_enum)
|
|
79
|
+
fields.append(field)
|
|
80
|
+
|
|
81
|
+
field = "option_to_dtype", ClassVar[dict], dataclasses.field(default=option_to_dtype)
|
|
82
|
+
fields.append(field)
|
|
83
|
+
|
|
84
|
+
# Create the options class.
|
|
85
|
+
options_class = dataclasses.make_dataclass(options_class_name, fields, slots=True)
|
|
86
|
+
options_class.__doc__ = doc
|
|
87
|
+
|
|
88
|
+
return options_class
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def snake_to_camel(names):
|
|
92
|
+
name = ""
|
|
93
|
+
for i, sub_name in enumerate(names):
|
|
94
|
+
if i == 0:
|
|
95
|
+
name += sub_name.lower()
|
|
96
|
+
else:
|
|
97
|
+
name += sub_name[0].upper() + sub_name[1:]
|
|
98
|
+
name += "_t"
|
|
99
|
+
return name
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def camel_to_snake(name, upper=True):
|
|
103
|
+
"""
|
|
104
|
+
Convert string from camel case to snake style.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
def transformer(m):
|
|
108
|
+
prefix = iter(("", "_", ""))
|
|
109
|
+
for i in 1, 3, 5:
|
|
110
|
+
first, second = i, i + 1
|
|
111
|
+
s = next(prefix)
|
|
112
|
+
if m.group(second):
|
|
113
|
+
if m.group(first): # If the second group doesn't exist, the first won't either by the design of the RE.
|
|
114
|
+
s += m.group(first).lower() + "_"
|
|
115
|
+
s += m.group(second).lower()
|
|
116
|
+
break
|
|
117
|
+
return s
|
|
118
|
+
|
|
119
|
+
name = re.sub(r"^([A-Z]*)([A-Z])|(?<!_)([A-Z]*)([A-Z])|([A-Z]*)([A-Z])", transformer, name)
|
|
120
|
+
if upper:
|
|
121
|
+
name = name.upper()
|
|
122
|
+
return name
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def determine_enum_prefix(enum_class, chomp):
|
|
126
|
+
"""
|
|
127
|
+
This function assumes that the convention used to translate C enumerators to Python enum
|
|
128
|
+
names holds.
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
prefix = enum_class.__module__.split(".")[-1].upper()
|
|
132
|
+
prefix += "_" + camel_to_snake(enum_class.__name__)
|
|
133
|
+
prefix = re.sub(chomp, "", prefix)
|
|
134
|
+
return prefix
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def add_enum_class_doc(enum_class, chomp):
|
|
138
|
+
"""
|
|
139
|
+
Add docstring to enum classes.
|
|
140
|
+
"""
|
|
141
|
+
for e in enum_class:
|
|
142
|
+
e.__doc__ = f"See `{determine_enum_prefix(enum_class, chomp) + '_' + e.name.upper()}`."
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Formatters for printing data.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MemoryStr:
|
|
13
|
+
"""
|
|
14
|
+
A simple type to pretty-print memory-like values.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, memory, base_unit="B"):
|
|
18
|
+
self.memory = memory
|
|
19
|
+
self.base_unit = base_unit
|
|
20
|
+
self.base = 1024
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
"""
|
|
24
|
+
Convert large values to powers of 1024 for readability.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
base, base_unit, memory = self.base, self.base_unit, self.memory
|
|
28
|
+
|
|
29
|
+
if memory < base:
|
|
30
|
+
value, unit = memory, base_unit
|
|
31
|
+
elif memory < base**2:
|
|
32
|
+
value, unit = memory / base, f"Ki{base_unit}"
|
|
33
|
+
elif memory < base**3:
|
|
34
|
+
value, unit = memory / base**2, f"Mi{base_unit}"
|
|
35
|
+
else:
|
|
36
|
+
value, unit = memory / base**3, f"Gi{base_unit}"
|
|
37
|
+
|
|
38
|
+
return f"{value:0.2f} {unit}"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class FLOPSStr:
|
|
42
|
+
"""
|
|
43
|
+
A simple type to pretty-print FLOP count and FLOP/s-like values.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self, flops, base_unit):
|
|
47
|
+
self.flops = flops
|
|
48
|
+
self.base_unit = base_unit
|
|
49
|
+
self.base = 1000
|
|
50
|
+
|
|
51
|
+
def __str__(self):
|
|
52
|
+
"""
|
|
53
|
+
Convert large values to powers of 1000 for readability.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
base, base_unit, flops = self.base, self.base_unit, self.flops
|
|
57
|
+
|
|
58
|
+
if flops < base:
|
|
59
|
+
value, unit = flops, base_unit
|
|
60
|
+
elif flops < base**2:
|
|
61
|
+
value, unit = flops / base, f"K{base_unit}"
|
|
62
|
+
elif flops < base**3:
|
|
63
|
+
value, unit = flops / base**2, f"M{base_unit}"
|
|
64
|
+
elif flops < base**4:
|
|
65
|
+
value, unit = flops / base**3, f"G{base_unit}"
|
|
66
|
+
elif flops < base**5:
|
|
67
|
+
value, unit = flops / base**4, f"T{base_unit}"
|
|
68
|
+
else:
|
|
69
|
+
value, unit = flops / base**5, f"P{base_unit}"
|
|
70
|
+
|
|
71
|
+
return f"{value:0.3f} {unit}"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def array2string(array_like):
|
|
75
|
+
"""
|
|
76
|
+
String representation of an array-like object with possible truncation of "interior"
|
|
77
|
+
values to limit string size.
|
|
78
|
+
|
|
79
|
+
The NumPy function "set_printoptions" can be used to control the display of the array.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
return np.array2string(
|
|
83
|
+
np.asanyarray(array_like, dtype=object),
|
|
84
|
+
separator=", ",
|
|
85
|
+
# NumPy hates empty strings so we print 'None' instead.
|
|
86
|
+
formatter={"object": lambda s: s if s != "" else "None"},
|
|
87
|
+
)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Memory specification regular expression.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__ = ["MEM_LIMIT_RE_PCT", "MEM_LIMIT_RE_VAL", "MEM_LIMIT_DOC", "check_memory_str"]
|
|
10
|
+
|
|
11
|
+
import re
|
|
12
|
+
|
|
13
|
+
MEM_LIMIT_RE_PCT = re.compile(r"(?P<value>[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)\s*%\s*$")
|
|
14
|
+
MEM_LIMIT_RE_VAL = re.compile(
|
|
15
|
+
r"(?P<value>[+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?)\s*(?P<units>[kmg])?(?P<binary>(?<=[kmg])i)?b\s*$",
|
|
16
|
+
re.IGNORECASE,
|
|
17
|
+
)
|
|
18
|
+
MEM_LIMIT_DOC = """The {kind} must be specified in one of the following forms:
|
|
19
|
+
(1) A number (int or float). If the number is a float between 0 and 1 inclusive, the
|
|
20
|
+
{kind} is interpreted as a fraction of the total device memory; otherwise it is
|
|
21
|
+
interpreted as the number of bytes of memory, with float value being cast to int.
|
|
22
|
+
Examples: 0.75, 50E6, 50000000, ...
|
|
23
|
+
(2) A string containing a positive value followed by B, kB, MB, or GB for powers of 1000.
|
|
24
|
+
Examples: "0.05 GB", "50 MB", "50000000 B" ...
|
|
25
|
+
(3) A string containing a positive value followed by kiB, MiB, or GiB for powers of 1024.
|
|
26
|
+
Examples: "0.05 GiB", "51.2 MiB", "53687091 B" ...
|
|
27
|
+
(4) A string with value in the range [0, 100] followed by a % symbol.
|
|
28
|
+
Examples: "26%","82%", ...
|
|
29
|
+
|
|
30
|
+
Whitespace between values and units is optional.
|
|
31
|
+
|
|
32
|
+
The provided {kind} is "{value}".
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def check_memory_str(value, kind):
|
|
37
|
+
"""
|
|
38
|
+
Check if the memory specification string is valid.
|
|
39
|
+
|
|
40
|
+
value = the memory specification string.
|
|
41
|
+
kind = a string denoting the type of memory being checked, used in error messages.
|
|
42
|
+
"""
|
|
43
|
+
if not isinstance(value, int | float):
|
|
44
|
+
m1 = MEM_LIMIT_RE_PCT.match(value)
|
|
45
|
+
if m1:
|
|
46
|
+
factor = float(m1.group("value"))
|
|
47
|
+
if factor < 0 or factor > 100:
|
|
48
|
+
raise ValueError(f"The {kind} percentage must be in the range [0, 100].")
|
|
49
|
+
m2 = MEM_LIMIT_RE_VAL.match(value)
|
|
50
|
+
if not (m1 or m2):
|
|
51
|
+
raise ValueError(MEM_LIMIT_DOC.format(kind=kind, value=value))
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
cimport cython
|
|
6
|
+
from libc.stdint cimport int64_t, intptr_t, uint64_t
|
|
7
|
+
|
|
8
|
+
cpdef get_device_memory_resource(int device_id)
|
|
9
|
+
cpdef allocate_from_mr(mr, int64_t size, stream, int device_id, logger=*)
|
|
10
|
+
cpdef free_reserved_memory(bint sync=*)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
import _cython_3_2_4
|
|
6
|
+
from typing import Any, ClassVar
|
|
7
|
+
|
|
8
|
+
__pyx_capi__: dict
|
|
9
|
+
__test__: dict
|
|
10
|
+
allocate_from_mr: _cython_3_2_4.cython_function_or_method
|
|
11
|
+
free_reserved_memory: _cython_3_2_4.cython_function_or_method
|
|
12
|
+
get_device_memory_resource: _cython_3_2_4.cython_function_or_method
|
|
13
|
+
|
|
14
|
+
class _MemoryPointer:
|
|
15
|
+
"""
|
|
16
|
+
Temporary internal NDBuffer allocation adapter class. NDBuffer expects
|
|
17
|
+
custom allocator to return a cuda.core.Buffer instance. Until all supported
|
|
18
|
+
cuda.core versions have unified support for wrapping external allocations
|
|
19
|
+
with Buffer.from_handle, this class servers as an adapter/workaround.
|
|
20
|
+
|
|
21
|
+
WARNING: This is internal tool subject to change/removal without notice.
|
|
22
|
+
|
|
23
|
+
Internally, it is used conditionally if any of the following is needed:
|
|
24
|
+
* wrap external allocations that don't come as cuda.core.Buffer (e.g. from cupy).
|
|
25
|
+
This is needed because prior to cuda.core 0.5.0, it's not possible to
|
|
26
|
+
pass reference to externall RAII object as ``owner`` parameter to Buffer.from_handle.
|
|
27
|
+
* provide debug logging on deallocation. In the future, we can use
|
|
28
|
+
Buffer.from_handle(owner=...) to inject deallocation callback (cuda.core >= 0.5.0)
|
|
29
|
+
or weakref.finalize for Buffer (cuda.core >= 0.6.0).
|
|
30
|
+
|
|
31
|
+
The only publicly exposed field is the handle - a base pointer to the allocated memory.
|
|
32
|
+
"""
|
|
33
|
+
from_handle: ClassVar[method] = ...
|
|
34
|
+
__pyx_vtable__: ClassVar[PyCapsule] = ...
|
|
35
|
+
handle: handle
|
|
36
|
+
owner: owner
|
|
37
|
+
@classmethod
|
|
38
|
+
def __init__(cls, *args, **kwargs) -> None:
|
|
39
|
+
"""Create and return a new object. See help(type) for accurate signature."""
|
|
40
|
+
def __del__(self, *args, **kwargs) -> None: ...
|
|
41
|
+
def __reduce__(self):
|
|
42
|
+
"""_MemoryPointer.__reduce_cython__(self)"""
|
|
43
|
+
def __reduce_cython__(self) -> Any:
|
|
44
|
+
"""_MemoryPointer.__reduce_cython__(self)"""
|
|
45
|
+
def __setstate_cython__(self, __pyx_state) -> Any:
|
|
46
|
+
"""_MemoryPointer.__setstate_cython__(self, __pyx_state)"""
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#ifndef NVMATH_COPY_KERNEL_IMPL_ARGS_H
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_ARGS_H
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/type_utils.h"
|
|
9
|
+
|
|
10
|
+
#if defined(_MSC_VER)
|
|
11
|
+
// For Visual Studio, use __restrict
|
|
12
|
+
#define RESTRICT __restrict
|
|
13
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
14
|
+
// For GCC and Clang, use __restrict__
|
|
15
|
+
#define RESTRICT __restrict__
|
|
16
|
+
#else
|
|
17
|
+
// Fallback for other compilers, or if restrict is not supported
|
|
18
|
+
#define RESTRICT
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
namespace nvmath {
|
|
22
|
+
template <int N>
|
|
23
|
+
struct KernelArgs {
|
|
24
|
+
void * RESTRICT dst_ptr;
|
|
25
|
+
const void * RESTRICT src_ptr;
|
|
26
|
+
int64_t dst_shape[N];
|
|
27
|
+
int64_t src_shape[N];
|
|
28
|
+
int64_t dst_strides[N];
|
|
29
|
+
int64_t src_strides[N];
|
|
30
|
+
int64_t grid_arg;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_ARGS_H
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#ifndef NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/utils.h"
|
|
9
|
+
#include "copy_kernel_impl/vec.h"
|
|
10
|
+
|
|
11
|
+
#if defined(_MSC_VER)
|
|
12
|
+
// For Visual Studio, use __restrict
|
|
13
|
+
#define RESTRICT __restrict
|
|
14
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
15
|
+
// For GCC and Clang, use __restrict__
|
|
16
|
+
#define RESTRICT __restrict__
|
|
17
|
+
#else
|
|
18
|
+
// Fallback for other compilers, or if restrict is not supported
|
|
19
|
+
#define RESTRICT
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
namespace nvmath {
|
|
23
|
+
|
|
24
|
+
template <typename T, typename _coords_t> struct array_view {
|
|
25
|
+
// While indices cannot be negative (only strides can),
|
|
26
|
+
// we're using the same 32- or 64-bit signed type to represent both
|
|
27
|
+
// indices and strides for simplicity. In the end we need to convert
|
|
28
|
+
// both to the same signed type when computing the offset.
|
|
29
|
+
using coords_t = _coords_t;
|
|
30
|
+
using stride_t = typename coords_t::type;
|
|
31
|
+
using dtype_t = T;
|
|
32
|
+
static constexpr int ndim = coords_t::ndim;
|
|
33
|
+
|
|
34
|
+
HOST_DEV constexpr array_view(T *__restrict__ data, coords_t shape, coords_t strides)
|
|
35
|
+
: shape_(shape), strides_(strides), data_(data) {}
|
|
36
|
+
|
|
37
|
+
HOST_DEV __forceinline__ T &operator[](const coords_t idx) const { return data_[offset(idx)]; }
|
|
38
|
+
HOST_DEV __forceinline__ T &operator[](const stride_t offset) const { return data_[offset]; }
|
|
39
|
+
HOST_DEV __forceinline__ stride_t offset(const coords_t idx) const { return dot(idx, strides()); }
|
|
40
|
+
HOST_DEV __forceinline__ coords_t shape() const { return shape_; }
|
|
41
|
+
HOST_DEV __forceinline__ coords_t strides() const { return strides_; }
|
|
42
|
+
HOST_DEV __forceinline__ T *data() const { return data_; }
|
|
43
|
+
|
|
44
|
+
protected:
|
|
45
|
+
coords_t shape_;
|
|
46
|
+
coords_t strides_;
|
|
47
|
+
T *RESTRICT data_;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
} // namespace nvmath
|
|
51
|
+
|
|
52
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_ARRAY_VIEW_H_
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#ifndef NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/array_view.h"
|
|
9
|
+
#include "copy_kernel_impl/grid_indexer.h"
|
|
10
|
+
#include "copy_kernel_impl/type_utils.h"
|
|
11
|
+
#include "copy_kernel_impl/utils.h"
|
|
12
|
+
#include "copy_kernel_impl/vec.h"
|
|
13
|
+
|
|
14
|
+
namespace nvmath {
|
|
15
|
+
|
|
16
|
+
namespace detail {
|
|
17
|
+
|
|
18
|
+
template <typename coords_t, typename stride_t = typename coords_t::type>
|
|
19
|
+
__device__ __forceinline__ coords_t unravel_idx(const stride_t flat_idx, const coords_t shape) {
|
|
20
|
+
constexpr int ndim = coords_t::ndim;
|
|
21
|
+
if constexpr (ndim <= 0) {
|
|
22
|
+
return {};
|
|
23
|
+
} else if constexpr (ndim == 1) {
|
|
24
|
+
return {flat_idx};
|
|
25
|
+
} else if constexpr (ndim > 1) {
|
|
26
|
+
|
|
27
|
+
// the extents cannot be negative and the arithmetic on unsigned integer
|
|
28
|
+
// is noticeably faster
|
|
29
|
+
using u_stride_t = typename type_traits::unsign<stride_t>::type;
|
|
30
|
+
u_stride_t u_flat_idx = flat_idx;
|
|
31
|
+
coords_t unraveled_coords;
|
|
32
|
+
#pragma unroll
|
|
33
|
+
for (int i = ndim - 1; i >= 1; i--) {
|
|
34
|
+
u_stride_t extent = shape[i];
|
|
35
|
+
if (extent & (extent - 1)) {
|
|
36
|
+
u_stride_t next_flat_idx = u_flat_idx / extent;
|
|
37
|
+
unraveled_coords[i] = u_flat_idx - next_flat_idx * extent;
|
|
38
|
+
u_flat_idx = next_flat_idx;
|
|
39
|
+
} else {
|
|
40
|
+
unraveled_coords[i] = u_flat_idx & (extent - 1);
|
|
41
|
+
u_flat_idx >>= ffs(extent) - 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
unraveled_coords[0] = u_flat_idx;
|
|
45
|
+
return unraveled_coords;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} // namespace detail
|
|
50
|
+
|
|
51
|
+
template <bool has_equal_shapes, typename dst_array_view_t, typename src_array_view_t, typename grid_indexer_t>
|
|
52
|
+
struct elementwise_copy_impl {
|
|
53
|
+
using stride_t = typename dst_array_view_t::stride_t;
|
|
54
|
+
|
|
55
|
+
void __forceinline__ __device__ operator()(const dst_array_view_t &&dst_view, const src_array_view_t &&src_view,
|
|
56
|
+
const grid_indexer_t &&grid_helper) {
|
|
57
|
+
grid_helper.with_grid_stride_loop([=](const stride_t flat_element_idx) {
|
|
58
|
+
const auto dst_coords = detail::unravel_idx(flat_element_idx, dst_view.shape());
|
|
59
|
+
const auto src_coords =
|
|
60
|
+
cond_val(bconst<has_equal_shapes>(), dst_coords, detail::unravel_idx(flat_element_idx, src_view.shape()));
|
|
61
|
+
dst_view[dst_coords] = src_view[src_coords];
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
} // namespace nvmath
|
|
67
|
+
|
|
68
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_ELEMENTWISE_H
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
#ifndef NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/utils.h"
|
|
9
|
+
#include "copy_kernel_impl/vec.h"
|
|
10
|
+
|
|
11
|
+
namespace nvmath {
|
|
12
|
+
|
|
13
|
+
template <typename stride_t, bool _needs_grid_stride_loop> struct element_indexer {
|
|
14
|
+
// stride_t can be 32-bit integer for tensor_volume and gridDim * blockDim up to INT_MAX,
|
|
15
|
+
// this way unsigned x < INT_MAX; x += INT_MAX cannot overflow
|
|
16
|
+
using ustride_t = typename type_traits::unsign<stride_t>::type;
|
|
17
|
+
static constexpr bool needs_grid_stride_loop = _needs_grid_stride_loop;
|
|
18
|
+
|
|
19
|
+
constexpr HOST_DEV __forceinline__ element_indexer(const stride_t tensor_volume) : tensor_volume(tensor_volume) {}
|
|
20
|
+
|
|
21
|
+
template <typename Cb> __device__ __forceinline__ void with_grid_stride_loop(Cb &&cb) const {
|
|
22
|
+
// early cast the special indexing variables to the desired integer width type
|
|
23
|
+
// to avoid arithmetic on 32-bit integers when 64-bit stride_t is used
|
|
24
|
+
const ustride_t thread_idx = threadIdx.x;
|
|
25
|
+
const ustride_t block_idx = blockIdx.x;
|
|
26
|
+
const ustride_t block_dim = blockDim.x;
|
|
27
|
+
if constexpr (!needs_grid_stride_loop) {
|
|
28
|
+
const ustride_t x = block_idx * block_dim + thread_idx;
|
|
29
|
+
if (x < tensor_volume) {
|
|
30
|
+
cb(x);
|
|
31
|
+
}
|
|
32
|
+
} else if constexpr (needs_grid_stride_loop) {
|
|
33
|
+
const ustride_t grid_dim = gridDim.x;
|
|
34
|
+
const ustride_t grid_size = grid_dim * block_dim;
|
|
35
|
+
for (ustride_t x = block_idx * block_dim + thread_idx; x < tensor_volume; x += grid_size) {
|
|
36
|
+
cb(x);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ustride_t tensor_volume;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
template <typename stride_t, bool _needs_grid_stride_loop> struct block_indexer {
|
|
45
|
+
using ustride_t = typename type_traits::unsign<stride_t>::type;
|
|
46
|
+
static constexpr bool needs_grid_stride_loop = _needs_grid_stride_loop;
|
|
47
|
+
|
|
48
|
+
constexpr HOST_DEV __forceinline__ block_indexer(const stride_t n_blocks) : n_blocks(n_blocks) {}
|
|
49
|
+
|
|
50
|
+
template <typename Cb> __device__ __forceinline__ void with_grid_stride_loop(Cb &&cb) const {
|
|
51
|
+
// early cast the special indexing variables to the desired integer width type
|
|
52
|
+
// to avoid arithmetic on 32-bit integers when 64-bit stride_t is used
|
|
53
|
+
const ustride_t thread_idx = threadIdx.x;
|
|
54
|
+
const ustride_t block_idx = blockIdx.x;
|
|
55
|
+
if constexpr (!needs_grid_stride_loop) {
|
|
56
|
+
cb(block_idx, thread_idx);
|
|
57
|
+
} else if constexpr (needs_grid_stride_loop) {
|
|
58
|
+
const ustride_t grid_dim = gridDim.x;
|
|
59
|
+
for (ustride_t x = block_idx; x < n_blocks; x += grid_dim) {
|
|
60
|
+
cb(x, thread_idx);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ustride_t n_blocks;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
} // namespace nvmath
|
|
69
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_GRID_INDEXER_H_
|