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,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_
|
|
@@ -0,0 +1,242 @@
|
|
|
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_TRANSPOSED_H
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_TRANSPOSED_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
|
+
#if defined(_MSC_VER)
|
|
15
|
+
// For Visual Studio, use __restrict
|
|
16
|
+
#define RESTRICT __restrict
|
|
17
|
+
#elif defined(__GNUC__) || defined(__clang__)
|
|
18
|
+
// For GCC and Clang, use __restrict__
|
|
19
|
+
#define RESTRICT __restrict__
|
|
20
|
+
#else
|
|
21
|
+
// Fallback for other compilers, or if restrict is not supported
|
|
22
|
+
#define RESTRICT
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
namespace nvmath {
|
|
26
|
+
|
|
27
|
+
namespace detail {
|
|
28
|
+
|
|
29
|
+
template <typename _T, typename _stride_t, int _transposed_dim, int _block_height, int _block_width,
|
|
30
|
+
char _reading_order>
|
|
31
|
+
struct transpose2d {
|
|
32
|
+
using T = _T;
|
|
33
|
+
using stride_t = _stride_t;
|
|
34
|
+
|
|
35
|
+
// the thread position in the tile is represented as a 2d index
|
|
36
|
+
using thread_coords_t = vec<2, stride_t>;
|
|
37
|
+
|
|
38
|
+
// Consecutive flat thread index can be unraveled into 2d coordinates
|
|
39
|
+
// so that either the left or right coordinate changes faster.
|
|
40
|
+
// Reading order tells which of the two ways to pick for global memory reads.
|
|
41
|
+
static constexpr char reading_order = _reading_order;
|
|
42
|
+
static_assert(reading_order == 'C' || reading_order == 'F', "reading_order must be 'C' or 'F'");
|
|
43
|
+
|
|
44
|
+
// Describes splitting of the src/dst shape into two parts
|
|
45
|
+
// [0, transposed_dim] and [transposed_dim + 1, ndim - 1] to be traversed
|
|
46
|
+
// with the thread_coords.
|
|
47
|
+
static constexpr int transposed_dim = _transposed_dim;
|
|
48
|
+
|
|
49
|
+
// to unravel flat cuda thread index to 2d index in the tile fast,
|
|
50
|
+
// we require the tile extents (_block_height, _block_height)
|
|
51
|
+
// to be powers of 2, and use compile-time helpers that turn
|
|
52
|
+
// the division/modulo into a bit shift/mask.
|
|
53
|
+
using warp_size_t = mod_div<32>;
|
|
54
|
+
using block_height_t = mod_div<_block_height>;
|
|
55
|
+
using block_width_t = mod_div<_block_width>;
|
|
56
|
+
using swizzle_stride_t = mod_div<(_block_height > 32 ? 1 : 32 / _block_height)>;
|
|
57
|
+
using warps_in_width_t = mod_div<(_block_width < 32 ? 1 : _block_width / 32)>;
|
|
58
|
+
static constexpr block_height_t block_height = block_height_t{};
|
|
59
|
+
static constexpr block_width_t block_width = block_width_t{};
|
|
60
|
+
static constexpr swizzle_stride_t swizzle_stride = swizzle_stride_t{};
|
|
61
|
+
static constexpr warps_in_width_t warps_in_width = warps_in_width_t{};
|
|
62
|
+
static constexpr warp_size_t warp_size = warp_size_t{};
|
|
63
|
+
static constexpr int tile_num_elements = _block_height * _block_width;
|
|
64
|
+
|
|
65
|
+
HOST_DEV __forceinline__ transpose2d(T *RESTRICT data, stride_t *RESTRICT dst_offset)
|
|
66
|
+
: data(data), dst_offset(dst_offset) {}
|
|
67
|
+
|
|
68
|
+
// 2d index of the thread in the tile in C-like order (i.e. second index changing faster)
|
|
69
|
+
HOST_DEV __forceinline__ constexpr thread_coords_t unravel_thread_idx_c(const stride_t thread_idx) const {
|
|
70
|
+
return {thread_idx / block_width, thread_idx % block_width};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 2d index of the thread in the tile in Fortran-like order (i.e. first index changing faster)
|
|
74
|
+
HOST_DEV __forceinline__ constexpr thread_coords_t unravel_thread_idx_f(const stride_t thread_idx) const {
|
|
75
|
+
return {thread_idx % block_height, thread_idx / block_height};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
HOST_DEV __forceinline__ constexpr thread_coords_t unravel_thread_idx_reading(const stride_t thread_idx) const {
|
|
79
|
+
if constexpr (reading_order == 'C') {
|
|
80
|
+
return unravel_thread_idx_c(thread_idx);
|
|
81
|
+
} else {
|
|
82
|
+
return unravel_thread_idx_f(thread_idx);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
HOST_DEV __forceinline__ constexpr thread_coords_t unravel_thread_idx_writing(const stride_t thread_idx) const {
|
|
87
|
+
if constexpr (reading_order == 'C') {
|
|
88
|
+
return unravel_thread_idx_f(thread_idx);
|
|
89
|
+
} else {
|
|
90
|
+
return unravel_thread_idx_c(thread_idx);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
HOST_DEV __forceinline__ constexpr stride_t shm_offset(const thread_coords_t idx) const {
|
|
95
|
+
const stride_t y = idx[0];
|
|
96
|
+
const stride_t x = idx[1];
|
|
97
|
+
// Note, offset(unravel_thread_idx_c(thread_idx)) = idx
|
|
98
|
+
const stride_t offset = y * block_width + x;
|
|
99
|
+
const stride_t offset_y = offset / warp_size;
|
|
100
|
+
const stride_t offset_x = offset % warp_size;
|
|
101
|
+
// In the simplest case of 32x32 tile, we need to rotate elements
|
|
102
|
+
// by one every 32 elements to make sure that accessing with
|
|
103
|
+
// unravel_thread_idx_f(thread_idx)=((0, x), ..., (31, x)) does not
|
|
104
|
+
// introduce bank conflicts. If block_height is smaller than 32,
|
|
105
|
+
// there will be 32/block_height different xs in the
|
|
106
|
+
// unravel_thread_idx_f(thread_idx) warp, so we rotate by
|
|
107
|
+
// swizzle_stride to make sure that different xs do not land in the same bank.
|
|
108
|
+
// If block_width is bigger than 32, we want to make sure that
|
|
109
|
+
// we make one rotation per one y, hence the division by warps_in_width.
|
|
110
|
+
const stride_t swizzle = (offset_y / warps_in_width) * swizzle_stride;
|
|
111
|
+
return offset_y * warp_size + ((offset_x + swizzle) % warp_size);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// shared memory array to store the elements read from the src tensor
|
|
115
|
+
T *RESTRICT data;
|
|
116
|
+
// for data[i], the dst_offset[i] is the offset of the element data[i] in the dst tensor.
|
|
117
|
+
stride_t *RESTRICT dst_offset;
|
|
118
|
+
};
|
|
119
|
+
} // namespace detail
|
|
120
|
+
|
|
121
|
+
template <typename dst_array_view_t, typename src_array_view_t, typename grid_indexer_t, typename copy_helper_t>
|
|
122
|
+
struct transpose_copy_impl {
|
|
123
|
+
// 32 or 64 bit signed integer
|
|
124
|
+
using stride_t = typename dst_array_view_t::stride_t;
|
|
125
|
+
// ndim vector of stride_t integers
|
|
126
|
+
using coords_t = typename dst_array_view_t::coords_t;
|
|
127
|
+
static constexpr int ndim = dst_array_view_t::ndim;
|
|
128
|
+
static_assert(ndim == src_array_view_t::ndim, "src and dst must have the same number of dimensions");
|
|
129
|
+
static constexpr int transposed_dim = copy_helper_t::transposed_dim;
|
|
130
|
+
static_assert(0 <= transposed_dim && transposed_dim < ndim - 1, "transposed_dim must be between 0 and ndim - 2");
|
|
131
|
+
|
|
132
|
+
// use min possible offset to indicate that the element index is out of tensor bounds
|
|
133
|
+
static constexpr stride_t out_of_bounds_sentinel = type_traits::min_val<stride_t>::value;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @brief Unravel flat block index and 2d thread index to ndim index of the element in the `shape`.
|
|
137
|
+
*
|
|
138
|
+
* E. g. Given tensor of shape 2x3x4 and transposed_dim = 1
|
|
139
|
+
* [[[0, 1, 2, 3,],
|
|
140
|
+
* [4, 5, 6, 7,],
|
|
141
|
+
* [8, 9, 10, 11,]],
|
|
142
|
+
|
|
143
|
+
* [[12, 13, 14, 15,],
|
|
144
|
+
* [16, 17, 18, 19,],
|
|
145
|
+
* [20, 21, 22, 23,]]]
|
|
146
|
+
*
|
|
147
|
+
* and a 2x3 tile:
|
|
148
|
+
* [[(0,0), (0, 1), (0, 2)],
|
|
149
|
+
* [(1,0), (1, 1), (1, 2)]]
|
|
150
|
+
*
|
|
151
|
+
* maps to the 3D indices of the following elements:
|
|
152
|
+
* block_idx = 0 block_idx = 1 block_idx = 2 block_idx = 3
|
|
153
|
+
* [[0, 1, 2], [[3, 8, 9], [[10, 11, 16], [[17, 18, 19],
|
|
154
|
+
* [4, 5, 6]] [7, 12, 13]] [14, 15, 20]] [21, 22, 23]]
|
|
155
|
+
*
|
|
156
|
+
*
|
|
157
|
+
* Note, if the tiled extents are not divisible by the tile dimensions,
|
|
158
|
+
* the parts of the tile are carried over to the next position. Potential
|
|
159
|
+
* uncoalesced memory accesses are preferred over threads with no work to do
|
|
160
|
+
* (when mapped to invalid positions in the tensors).
|
|
161
|
+
*
|
|
162
|
+
* @param block_idx The threadblock index in the grid
|
|
163
|
+
* @param shape The shape of the tensor
|
|
164
|
+
* @param thread_idx The 2d index of the thread in the tile
|
|
165
|
+
* @return The ndim index of the element in the tensor
|
|
166
|
+
*/
|
|
167
|
+
__device__ __forceinline__ coords_t unravel_tiled_idx(const stride_t block_idx, const coords_t shape,
|
|
168
|
+
const vec<2, stride_t> thread_idx) {
|
|
169
|
+
|
|
170
|
+
static_assert(ndim >= 2, "ndim must be at least 2");
|
|
171
|
+
// the extents cannot be negative and the arithmetic on unsigned integer
|
|
172
|
+
// is noticeably faster
|
|
173
|
+
using u_stride_t = typename type_traits::unsign<stride_t>::type;
|
|
174
|
+
u_stride_t flat_idx;
|
|
175
|
+
coords_t unraveled_idx;
|
|
176
|
+
auto unravel_extent = [&flat_idx, &unraveled_idx, &shape](int i) {
|
|
177
|
+
u_stride_t extent = shape[i];
|
|
178
|
+
if (extent & (extent - 1)) {
|
|
179
|
+
u_stride_t next_flat_idx = flat_idx / extent;
|
|
180
|
+
unraveled_idx[i] = flat_idx - next_flat_idx * extent;
|
|
181
|
+
flat_idx = next_flat_idx;
|
|
182
|
+
} else {
|
|
183
|
+
unraveled_idx[i] = flat_idx & (extent - 1);
|
|
184
|
+
flat_idx >>= ffs(extent) - 1;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
flat_idx = block_idx * copy_helper_t::block_width + thread_idx[1];
|
|
188
|
+
#pragma unroll
|
|
189
|
+
for (int i = ndim - 1; i > transposed_dim; i--) {
|
|
190
|
+
unravel_extent(i);
|
|
191
|
+
}
|
|
192
|
+
flat_idx = flat_idx * copy_helper_t::block_height + thread_idx[0];
|
|
193
|
+
#pragma unroll
|
|
194
|
+
for (int i = transposed_dim; i > 0; i--) {
|
|
195
|
+
unravel_extent(i);
|
|
196
|
+
}
|
|
197
|
+
unraveled_idx[0] = flat_idx;
|
|
198
|
+
return unraveled_idx;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
void __forceinline__ __device__ operator()(const dst_array_view_t dst_view, const src_array_view_t src_view,
|
|
202
|
+
const grid_indexer_t grid_helper, const copy_helper_t transpose_helper) {
|
|
203
|
+
grid_helper.with_grid_stride_loop([=](const stride_t flat_block_idx, const stride_t flat_thread_idx) {
|
|
204
|
+
{
|
|
205
|
+
// 2d index of the thread
|
|
206
|
+
const auto thread_coords = transpose_helper.unravel_thread_idx_reading(flat_thread_idx);
|
|
207
|
+
// ndim index of the element in the source tensor
|
|
208
|
+
const auto src_coords = unravel_tiled_idx(flat_block_idx, src_view.shape(), thread_coords);
|
|
209
|
+
// note, all other idxs are 0 < ... < shape[i] by the unravel_tiled_idx,
|
|
210
|
+
// there's no need to check all of them.
|
|
211
|
+
const bool is_in_bounds = src_coords[0] < src_view.shape()[0];
|
|
212
|
+
if constexpr (grid_indexer_t::needs_grid_stride_loop) {
|
|
213
|
+
__syncthreads();
|
|
214
|
+
}
|
|
215
|
+
// flat index in the shared memory arrays where thread_coords should store its data
|
|
216
|
+
const auto shm_offset = transpose_helper.shm_offset(thread_coords);
|
|
217
|
+
if (is_in_bounds) {
|
|
218
|
+
// The data is copied from src to dst through shared memory in two steps:
|
|
219
|
+
// 1. src[unravel_tiled_idx(.., thread_coords)] -> shm[shm_offset(thread_coords)]
|
|
220
|
+
// 2. shm[shm_offset(thread_coords_transposed)] -> dst[unravel_tiled_idx(.., thread_coords_transposed)]
|
|
221
|
+
// To avoid computing the unravel_tiled_idx twice, we compute the dst stride here
|
|
222
|
+
// and store it together with the data.
|
|
223
|
+
transpose_helper.data[shm_offset] = src_view[src_coords];
|
|
224
|
+
transpose_helper.dst_offset[shm_offset] = dst_view.offset(src_coords);
|
|
225
|
+
} else {
|
|
226
|
+
transpose_helper.dst_offset[shm_offset] = out_of_bounds_sentinel;
|
|
227
|
+
}
|
|
228
|
+
__syncthreads();
|
|
229
|
+
}
|
|
230
|
+
// 2d index of the thread with flipped order (i.e. the other index is changing faster)
|
|
231
|
+
const auto thread_coords = transpose_helper.unravel_thread_idx_writing(flat_thread_idx);
|
|
232
|
+
const auto shm_offset = transpose_helper.shm_offset(thread_coords);
|
|
233
|
+
const auto dst_offset = transpose_helper.dst_offset[shm_offset];
|
|
234
|
+
if (dst_offset != out_of_bounds_sentinel) {
|
|
235
|
+
dst_view[dst_offset] = transpose_helper.data[shm_offset];
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
} // namespace nvmath
|
|
241
|
+
|
|
242
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_TRANSPOSED_H
|
|
@@ -0,0 +1,39 @@
|
|
|
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_TYPE_UTILS_H_
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_TYPE_UTILS_H_
|
|
7
|
+
|
|
8
|
+
namespace nvmath {
|
|
9
|
+
using int32_t = int;
|
|
10
|
+
using uint32_t = unsigned int;
|
|
11
|
+
using int64_t = long long int;
|
|
12
|
+
using uint64_t = unsigned long long int;
|
|
13
|
+
static_assert(sizeof(int32_t) == 4, "int32_t must be 4 bytes");
|
|
14
|
+
static_assert(sizeof(uint32_t) == 4, "uint32_t must be 4 bytes");
|
|
15
|
+
static_assert(sizeof(int64_t) == 8, "int64_t must be 8 bytes");
|
|
16
|
+
static_assert(sizeof(uint64_t) == 8, "uint64_t must be 8 bytes");
|
|
17
|
+
|
|
18
|
+
// Use a struct to represent type of element so that we don't rely
|
|
19
|
+
// on actual representation of the type, available arithmetic etc.
|
|
20
|
+
template <int n_bytes> struct alignas(n_bytes) opaque_t {
|
|
21
|
+
char data[n_bytes];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
static_assert(sizeof(opaque_t<1>) == 1, "opaque_t<1> must be 1 byte");
|
|
25
|
+
static_assert(sizeof(opaque_t<2>) == 2, "opaque_t<2> must be 2 bytes");
|
|
26
|
+
static_assert(sizeof(opaque_t<4>) == 4, "opaque_t<4> must be 4 bytes");
|
|
27
|
+
static_assert(sizeof(opaque_t<8>) == 8, "opaque_t<8> must be 8 bytes");
|
|
28
|
+
static_assert(sizeof(opaque_t<16>) == 16, "opaque_t<16> must be 16 bytes");
|
|
29
|
+
|
|
30
|
+
static_assert(alignof(opaque_t<1>) == alignof(unsigned char), "opaque_t<1> must be 1 byte");
|
|
31
|
+
static_assert(alignof(opaque_t<2>) == alignof(unsigned short), "opaque_t<2> must be 2 bytes");
|
|
32
|
+
static_assert(alignof(opaque_t<4>) == alignof(unsigned int), "opaque_t<4> must be 4 bytes");
|
|
33
|
+
static_assert(alignof(opaque_t<8>) == alignof(unsigned long long int), "opaque_t<8> must be 8 bytes");
|
|
34
|
+
#ifdef __CUDA_ARCH__
|
|
35
|
+
static_assert(alignof(opaque_t<16>) == 16, "opaque_t<16> must be 16 bytes");
|
|
36
|
+
#endif
|
|
37
|
+
} // namespace nvmath
|
|
38
|
+
|
|
39
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_TYPE_UTILS_H_
|
|
@@ -0,0 +1,132 @@
|
|
|
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_UTILS_H_
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_UTILS_H_
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/type_utils.h"
|
|
9
|
+
|
|
10
|
+
#if defined(__CUDACC__)
|
|
11
|
+
#define HOST_DEV __host__ __device__
|
|
12
|
+
#else
|
|
13
|
+
#define HOST_DEV
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
namespace nvmath {
|
|
17
|
+
|
|
18
|
+
// Some of stl type traits are not available with nvrtc
|
|
19
|
+
namespace type_traits {
|
|
20
|
+
template <bool B, class T, class F> struct conditional {};
|
|
21
|
+
|
|
22
|
+
template <class T, class F> struct conditional<true, T, F> {
|
|
23
|
+
using type = T;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
template <class T, class F> struct conditional<false, T, F> {
|
|
27
|
+
using type = F;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
template <bool B, class T = void> struct enable_if {};
|
|
31
|
+
template <class T> struct enable_if<true, T> {
|
|
32
|
+
typedef T type;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
template <typename T> struct unsign {};
|
|
36
|
+
|
|
37
|
+
template <> struct unsign<int64_t> {
|
|
38
|
+
using type = uint64_t;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
template <> struct unsign<int32_t> {
|
|
42
|
+
using type = uint32_t;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
template <typename T> struct is_32_or_64_int {
|
|
46
|
+
static constexpr bool value = false;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
template <> struct is_32_or_64_int<int32_t> {
|
|
50
|
+
static constexpr bool value = true;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
template <> struct is_32_or_64_int<int64_t> {
|
|
54
|
+
static constexpr bool value = true;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
template <typename T> struct min_val {};
|
|
58
|
+
|
|
59
|
+
template <> struct min_val<int32_t> {
|
|
60
|
+
static constexpr int32_t value = -2147483648;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
template <> struct min_val<int64_t> {
|
|
64
|
+
static constexpr int64_t value = -9223372036854775808LL;
|
|
65
|
+
};
|
|
66
|
+
} // namespace type_traits
|
|
67
|
+
|
|
68
|
+
template <typename T, T val> struct const_val {
|
|
69
|
+
using type = T;
|
|
70
|
+
static constexpr T value = val;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
template <int N> using iconst = const_val<int, N>;
|
|
74
|
+
|
|
75
|
+
template <bool B> using bconst = const_val<bool, B>;
|
|
76
|
+
|
|
77
|
+
template <typename true_val_t, typename false_val_t>
|
|
78
|
+
auto HOST_DEV __forceinline__ constexpr cond_val(bconst<false>, true_val_t &&true_val, false_val_t &&false_val) {
|
|
79
|
+
return false_val;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
template <typename true_val_t, typename false_val_t>
|
|
83
|
+
auto HOST_DEV __forceinline__ constexpr cond_val(bconst<true>, true_val_t &&true_val, false_val_t &&false_val) {
|
|
84
|
+
return true_val;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
#if defined(__CUDACC__)
|
|
88
|
+
|
|
89
|
+
__device__ __forceinline__ int ffs(uint32_t x) { return __ffs(x); }
|
|
90
|
+
|
|
91
|
+
__device__ __forceinline__ int ffs(int32_t x) { return __ffs(x); }
|
|
92
|
+
|
|
93
|
+
__device__ __forceinline__ int ffs(uint64_t x) { return __ffsll(x); }
|
|
94
|
+
|
|
95
|
+
__device__ __forceinline__ int ffs(int64_t x) { return __ffsll(x); }
|
|
96
|
+
|
|
97
|
+
#endif
|
|
98
|
+
|
|
99
|
+
constexpr int log2_floor(const int k) {
|
|
100
|
+
return k == 1 ? 0 : 1 + log2_floor(k >> 1);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
template <int k>
|
|
104
|
+
struct mod_div {
|
|
105
|
+
static_assert(k > 0, "k must be positive");
|
|
106
|
+
static_assert((k & (k - 1)) == 0, "k must be a power of 2");
|
|
107
|
+
static constexpr int value = k;
|
|
108
|
+
static constexpr int log2 = log2_floor(k);
|
|
109
|
+
static constexpr int mask = k - 1;
|
|
110
|
+
constexpr int operator()() const {
|
|
111
|
+
return k;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
template <typename T, int k>
|
|
116
|
+
HOST_DEV __forceinline__ constexpr T operator/(const T a, const mod_div<k>) {
|
|
117
|
+
return a >> mod_div<k>::log2;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
template <typename T, int k>
|
|
121
|
+
HOST_DEV __forceinline__ constexpr T operator%(const T a, const mod_div<k>) {
|
|
122
|
+
return a & mod_div<k>::mask;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
template <typename T, int k>
|
|
126
|
+
HOST_DEV __forceinline__ constexpr T operator*(const T a, const mod_div<k>) {
|
|
127
|
+
return a << mod_div<k>::log2;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
} // namespace nvmath
|
|
131
|
+
|
|
132
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_UTILS_H_
|
|
@@ -0,0 +1,159 @@
|
|
|
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_VEC_H_
|
|
6
|
+
#define NVMATH_COPY_KERNEL_IMPL_VEC_H_
|
|
7
|
+
|
|
8
|
+
#include "copy_kernel_impl/utils.h"
|
|
9
|
+
|
|
10
|
+
namespace nvmath {
|
|
11
|
+
|
|
12
|
+
template <typename T, int N> struct vec_base {
|
|
13
|
+
T v[N];
|
|
14
|
+
|
|
15
|
+
template <typename... Components,
|
|
16
|
+
typename = typename type_traits::enable_if<sizeof...(Components) <= N &&
|
|
17
|
+
(type_traits::is_32_or_64_int<Components>::value && ...)>::type>
|
|
18
|
+
HOST_DEV constexpr vec_base(Components... components) : v{T(components)...} {}
|
|
19
|
+
|
|
20
|
+
template <typename U, typename = typename type_traits::enable_if<type_traits::is_32_or_64_int<U>::value>::type>
|
|
21
|
+
HOST_DEV constexpr vec_base(const U *ptr) {
|
|
22
|
+
for (int i = 0; i < N; i++) {
|
|
23
|
+
v[i] = ptr[i];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
HOST_DEV __forceinline__ constexpr T &operator[](int i) { return v[i]; }
|
|
28
|
+
HOST_DEV __forceinline__ constexpr const T &operator[](int i) const { return v[i]; }
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
template <typename T> struct vec_base<T, 0> {};
|
|
32
|
+
|
|
33
|
+
template <int N, typename T> struct vec : vec_base<T, N> {
|
|
34
|
+
using base_t = vec_base<T, N>;
|
|
35
|
+
using type = T;
|
|
36
|
+
constexpr static int ndim = N;
|
|
37
|
+
|
|
38
|
+
constexpr vec() = default;
|
|
39
|
+
|
|
40
|
+
template <typename... Components> HOST_DEV constexpr vec(Components... components) : base_t{components...} {}
|
|
41
|
+
|
|
42
|
+
template <typename U> HOST_DEV constexpr vec(const U *ptr, int ndim) : base_t(ptr, ndim) {}
|
|
43
|
+
|
|
44
|
+
HOST_DEV __forceinline__ constexpr int size() const { return ndim; }
|
|
45
|
+
|
|
46
|
+
template <int K> HOST_DEV __forceinline__ constexpr auto last(const iconst<K>) const {
|
|
47
|
+
static_assert(K <= ndim);
|
|
48
|
+
return slice(iconst<ndim - K>(), iconst<ndim>());
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
template <int K> HOST_DEV __forceinline__ constexpr auto first(const iconst<K>) const {
|
|
52
|
+
static_assert(K <= ndim);
|
|
53
|
+
return slice(iconst<0>(), iconst<K>());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
template <int start, int end>
|
|
57
|
+
HOST_DEV __forceinline__ constexpr vec<end - start, T> slice(const iconst<start>, const iconst<end>) const {
|
|
58
|
+
static_assert(start >= 0 && end <= ndim);
|
|
59
|
+
constexpr int slice_ndim = end - start;
|
|
60
|
+
static_assert(slice_ndim >= 0);
|
|
61
|
+
if constexpr (slice_ndim != 0) {
|
|
62
|
+
vec<slice_ndim, T> result;
|
|
63
|
+
#pragma unroll
|
|
64
|
+
for (int i = 0; i < slice_ndim; i++) {
|
|
65
|
+
result[i] = this->operator[](start + i);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
template <int N, int M, typename T>
|
|
74
|
+
HOST_DEV __forceinline__ constexpr vec<N + M, T> cat(const vec<N, T> a, const vec<M, T> b) {
|
|
75
|
+
constexpr int ndim = N + M;
|
|
76
|
+
if constexpr (ndim != 0) {
|
|
77
|
+
vec<ndim, T> result;
|
|
78
|
+
if constexpr (N > 0) {
|
|
79
|
+
#pragma unroll
|
|
80
|
+
for (int i = 0; i < N; i++) {
|
|
81
|
+
result[i] = a[i];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if constexpr (M > 0) {
|
|
85
|
+
#pragma unroll
|
|
86
|
+
for (int i = 0; i < M; i++) {
|
|
87
|
+
result[N + i] = b[i];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
return {};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
template <int N, typename T, typename Op>
|
|
96
|
+
HOST_DEV __forceinline__ constexpr auto vector_bin_op(const vec<N, T> a, const vec<N, T> b, Op &&op) {
|
|
97
|
+
if constexpr (N == 0) {
|
|
98
|
+
return {};
|
|
99
|
+
} else if constexpr (N != 0) {
|
|
100
|
+
using result_t = decltype(op(a[0], b[0]));
|
|
101
|
+
vec<N, result_t> result;
|
|
102
|
+
#pragma unroll
|
|
103
|
+
for (int i = 0; i < N; i++) {
|
|
104
|
+
result[i] = op(a[i], b[i]);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
template <int N, typename T> HOST_DEV __forceinline__ constexpr auto operator+(const vec<N, T> a, const vec<N, T> b) {
|
|
111
|
+
return vector_bin_op(a, b, [](T a, T b) { return a + b; });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
template <int N, typename T> HOST_DEV __forceinline__ constexpr auto operator*(const vec<N, T> a, const vec<N, T> b) {
|
|
115
|
+
return vector_bin_op(a, b, [](T a, T b) { return a * b; });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
template <int N, typename T> HOST_DEV __forceinline__ constexpr auto operator-(const vec<N, T> a, const vec<N, T> b) {
|
|
119
|
+
return vector_bin_op(a, b, [](T a, T b) { return a - b; });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
template <int N, typename T> HOST_DEV __forceinline__ constexpr auto operator/(const vec<N, T> a, const vec<N, T> b) {
|
|
123
|
+
return vector_bin_op(a, b, [](T a, T b) { return a / b; });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
template <int N, typename Pred, typename T, typename... Ts>
|
|
127
|
+
HOST_DEV __forceinline__ constexpr bool any(Pred &&pred, const vec<N, T> a, const vec<N, Ts>... vs) {
|
|
128
|
+
for (int i = 0; i < N; i++) {
|
|
129
|
+
if (pred(a[i], vs[i]...))
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
template <int N, typename Pred, typename T, typename... Ts>
|
|
136
|
+
HOST_DEV __forceinline__ constexpr bool all(Pred &&pred, const vec<N, T> a, const vec<N, Ts>... vs) {
|
|
137
|
+
for (int i = 0; i < N; i++) {
|
|
138
|
+
if (!pred(a[i], vs[i]...))
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
template <int N, typename T> HOST_DEV __forceinline__ constexpr T dot(const vec<N, T> a, const vec<N, T> b) {
|
|
145
|
+
if constexpr (N == 0) {
|
|
146
|
+
return 0;
|
|
147
|
+
} else if constexpr (N != 0) {
|
|
148
|
+
T sum = a[0] * b[0];
|
|
149
|
+
#pragma unroll
|
|
150
|
+
for (int i = 1; i < N; i++) {
|
|
151
|
+
sum += a[i] * b[i];
|
|
152
|
+
}
|
|
153
|
+
return sum;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
} // namespace nvmath
|
|
158
|
+
|
|
159
|
+
#endif // NVMATH_COPY_KERNEL_IMPL_VEC_H_
|