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
nvmath/device/cufftdx.py
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
__all__ = ["fft", "FFT", "compile_fft_execute"]
|
|
6
|
+
import warnings
|
|
7
|
+
from functools import cached_property
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from nvmath.bindings import mathdx
|
|
11
|
+
from nvmath.internal.utils import docstring_decorator
|
|
12
|
+
|
|
13
|
+
from ._deprecated import deprecated
|
|
14
|
+
from .common import (
|
|
15
|
+
SHARED_DEVICE_DOCSTRINGS,
|
|
16
|
+
check_code_type,
|
|
17
|
+
parse_code_type,
|
|
18
|
+
parse_sm,
|
|
19
|
+
)
|
|
20
|
+
from .common_backend import MATHDX_TYPES_TO_NP, get_isa_version, get_lto
|
|
21
|
+
from .common_cuda import (
|
|
22
|
+
Code,
|
|
23
|
+
Dim3,
|
|
24
|
+
)
|
|
25
|
+
from .cufftdx_backend import (
|
|
26
|
+
generate_code,
|
|
27
|
+
generate_FFT,
|
|
28
|
+
get_data_type_trait,
|
|
29
|
+
get_int_trait,
|
|
30
|
+
get_int_traits,
|
|
31
|
+
get_knobs,
|
|
32
|
+
get_str_trait,
|
|
33
|
+
validate,
|
|
34
|
+
validate_execute_api,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
CUFFTDX_DATABASE = None
|
|
38
|
+
|
|
39
|
+
FFTDX_DOCSTRING = SHARED_DEVICE_DOCSTRINGS.copy()
|
|
40
|
+
FFTDX_DOCSTRING.update(
|
|
41
|
+
{
|
|
42
|
+
"size": """\
|
|
43
|
+
The size of the FFT to calculate.""".replace("\n", " "),
|
|
44
|
+
#
|
|
45
|
+
"fft_type": """\
|
|
46
|
+
A string specifying the type of FFT operation, can be ``'c2c'``, ``'c2r'`` or ``'r2c'``.""".replace("\n", " "),
|
|
47
|
+
#
|
|
48
|
+
"direction": """\
|
|
49
|
+
A string specifying the direction of FFT, can be ``'forward'`` or ``'inverse'``. If not provided, will be ``'forward'``
|
|
50
|
+
if real-to-complex FFT is specified and ``'inverse'`` if complex-to-real FFT is specified.""".replace("\n", " "),
|
|
51
|
+
#
|
|
52
|
+
"ffts_per_block": """\
|
|
53
|
+
The number of FFTs calculated per CUDA block, optional. The default is 1. Alternatively, if provided as ``'suggested'``
|
|
54
|
+
will be set to a suggested value""".replace("\n", " "),
|
|
55
|
+
#
|
|
56
|
+
"elements_per_thread": """\
|
|
57
|
+
The number of elements per thread, optional. The default is 1. Alternatively, if provided as ``'suggested'``, will be
|
|
58
|
+
set to a suggested value. """.replace("\n", " "),
|
|
59
|
+
#
|
|
60
|
+
"real_fft_options": """\
|
|
61
|
+
A dictionary specifying the options for real FFT operation, optional.""".replace("\n", " "),
|
|
62
|
+
"execute_api": """\
|
|
63
|
+
A string specifying the signature of the function that handles problems with input in register or in shared memory buffers.
|
|
64
|
+
Could be ``'shared_memory'`` or ``'register_memory'``.""".replace("\n", " "),
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
_workspace_deprecation_warning = lambda: warnings.warn(
|
|
69
|
+
"Using workspaces is deprecated and will be removed in future release.", DeprecationWarning
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@docstring_decorator(FFTDX_DOCSTRING, skip_missing=False)
|
|
74
|
+
class FFT:
|
|
75
|
+
"""
|
|
76
|
+
A class that encapsulates a partial FFT device function. A partial device function can
|
|
77
|
+
be queried for available or optimal values for some knobs (such as `ffts_per_block`
|
|
78
|
+
or `elements_per_thread`). It does not contain a compiled, ready-to-use,
|
|
79
|
+
device function until finalized using :meth:`create`.
|
|
80
|
+
|
|
81
|
+
.. versionchanged:: 0.7.0
|
|
82
|
+
`FFT` has replaced `FFTOptions` and `FFTOptionsComplete`.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
size (int): {size}
|
|
86
|
+
|
|
87
|
+
precision (str): {precision}
|
|
88
|
+
|
|
89
|
+
fft_type (str): {fft_type}
|
|
90
|
+
|
|
91
|
+
sm (ComputeCapability): {sm}
|
|
92
|
+
|
|
93
|
+
execution (str): {execution}
|
|
94
|
+
|
|
95
|
+
direction (str): {direction}
|
|
96
|
+
|
|
97
|
+
ffts_per_block (int): {ffts_per_block}
|
|
98
|
+
|
|
99
|
+
elements_per_thread (int): {elements_per_thread}
|
|
100
|
+
|
|
101
|
+
real_fft_options (dict): {real_fft_options} User may specify the following options
|
|
102
|
+
in the dictionary:
|
|
103
|
+
|
|
104
|
+
- ``'complex_layout'``, currently supports ``'natural'``, ``'packed'``, and
|
|
105
|
+
``'full'``.
|
|
106
|
+
- ``'real_mode'``, currently supports ``'normal'`` and ``'folded``.
|
|
107
|
+
|
|
108
|
+
.. seealso::
|
|
109
|
+
The attributes of this class provide a 1:1 mapping with the CUDA C++ cuFFTDx APIs.
|
|
110
|
+
For further details, please refer to :cufftdx_doc:`cuFFTDx documentation
|
|
111
|
+
<index.html>`.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
def __init__(
|
|
115
|
+
self,
|
|
116
|
+
size,
|
|
117
|
+
precision,
|
|
118
|
+
fft_type,
|
|
119
|
+
execution,
|
|
120
|
+
*,
|
|
121
|
+
sm=None,
|
|
122
|
+
direction=None,
|
|
123
|
+
ffts_per_block=None,
|
|
124
|
+
elements_per_thread=None,
|
|
125
|
+
real_fft_options=None,
|
|
126
|
+
):
|
|
127
|
+
sm = parse_sm(sm)
|
|
128
|
+
|
|
129
|
+
#
|
|
130
|
+
# Check that the knobs are, individually, valid
|
|
131
|
+
#
|
|
132
|
+
|
|
133
|
+
validate(
|
|
134
|
+
size=size,
|
|
135
|
+
precision=precision,
|
|
136
|
+
fft_type=fft_type,
|
|
137
|
+
sm=sm,
|
|
138
|
+
execution=execution,
|
|
139
|
+
direction=direction,
|
|
140
|
+
ffts_per_block=ffts_per_block,
|
|
141
|
+
elements_per_thread=elements_per_thread,
|
|
142
|
+
real_fft_options=real_fft_options,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
if direction is None and fft_type == "r2c":
|
|
146
|
+
direction = "forward"
|
|
147
|
+
elif direction is None and fft_type == "c2r":
|
|
148
|
+
direction = "inverse"
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# Traits set by input
|
|
152
|
+
#
|
|
153
|
+
|
|
154
|
+
self._precision = precision
|
|
155
|
+
self._fft_type = fft_type
|
|
156
|
+
self._direction = direction
|
|
157
|
+
self._size = size
|
|
158
|
+
self._execution = execution
|
|
159
|
+
self._ffts_per_block = ffts_per_block
|
|
160
|
+
self._elements_per_thread = elements_per_thread
|
|
161
|
+
self._real_fft_options = real_fft_options
|
|
162
|
+
self._sm = sm
|
|
163
|
+
|
|
164
|
+
#
|
|
165
|
+
# Update suggested traits
|
|
166
|
+
#
|
|
167
|
+
|
|
168
|
+
if elements_per_thread == "suggested":
|
|
169
|
+
self._elements_per_thread = self._suggested_elements_per_thread
|
|
170
|
+
|
|
171
|
+
if ffts_per_block == "suggested":
|
|
172
|
+
self._ffts_per_block = self._suggested_ffts_per_block
|
|
173
|
+
|
|
174
|
+
@cached_property
|
|
175
|
+
def _traits(self):
|
|
176
|
+
return _FFTTraits(self)
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def elements_per_thread(self):
|
|
180
|
+
if self._elements_per_thread is None:
|
|
181
|
+
return self._traits.elements_per_thread
|
|
182
|
+
return self._elements_per_thread
|
|
183
|
+
|
|
184
|
+
@property
|
|
185
|
+
def precision(self):
|
|
186
|
+
return self._precision
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def ffts_per_block(self):
|
|
190
|
+
if self._ffts_per_block is None:
|
|
191
|
+
return self._traits.ffts_per_block
|
|
192
|
+
return self._ffts_per_block
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def fft_type(self):
|
|
196
|
+
return self._fft_type
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def direction(self):
|
|
200
|
+
return self._direction
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
def size(self):
|
|
204
|
+
return self._size
|
|
205
|
+
|
|
206
|
+
@property
|
|
207
|
+
def execution(self):
|
|
208
|
+
return self._execution
|
|
209
|
+
|
|
210
|
+
@property
|
|
211
|
+
def real_fft_options(self):
|
|
212
|
+
return self._real_fft_options
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def sm(self):
|
|
216
|
+
return self._sm
|
|
217
|
+
|
|
218
|
+
#
|
|
219
|
+
# Extensions
|
|
220
|
+
#
|
|
221
|
+
|
|
222
|
+
def valid(self, *knobs):
|
|
223
|
+
if not (set(knobs) <= {"ffts_per_block", "elements_per_thread"}):
|
|
224
|
+
raise ValueError(f"Unsupported knob. Only valid knobs are ffts_per_block and elements_per_thread but got {knobs}")
|
|
225
|
+
|
|
226
|
+
return self._get_knobs(*knobs)
|
|
227
|
+
|
|
228
|
+
@deprecated("definition is deprecated and may be removed in future versions")
|
|
229
|
+
def definition(self):
|
|
230
|
+
"""
|
|
231
|
+
.. deprecated:: 0.7.0
|
|
232
|
+
"""
|
|
233
|
+
dd = {
|
|
234
|
+
"size": self.size,
|
|
235
|
+
"precision": self.precision,
|
|
236
|
+
"fft_type": self.fft_type,
|
|
237
|
+
"sm": self.sm,
|
|
238
|
+
"execution": self.execution,
|
|
239
|
+
"direction": self.direction,
|
|
240
|
+
"ffts_per_block": self.ffts_per_block,
|
|
241
|
+
"elements_per_thread": self.elements_per_thread,
|
|
242
|
+
"real_fft_options": self.real_fft_options,
|
|
243
|
+
}
|
|
244
|
+
return dd
|
|
245
|
+
|
|
246
|
+
@deprecated("create is deprecated and may be removed in future versions. Use `functools.partial` instead")
|
|
247
|
+
def create(self, **kwargs):
|
|
248
|
+
"""
|
|
249
|
+
Creates a copy of the instance with provided arguments updated.
|
|
250
|
+
|
|
251
|
+
.. deprecated:: 0.7.0
|
|
252
|
+
Please use :py:func:`functools.partial` instead.
|
|
253
|
+
"""
|
|
254
|
+
code_type = kwargs.pop("code_type", None)
|
|
255
|
+
if code_type is not None:
|
|
256
|
+
DeprecationWarning("code_type is deprecated and will be removed in future releases. It is no longer needed.")
|
|
257
|
+
compiler = kwargs.pop("compiler", None)
|
|
258
|
+
if compiler is not None:
|
|
259
|
+
DeprecationWarning("compiler is deprecated and will be removed in future releases. It is no longer needed.")
|
|
260
|
+
dd = self.definition()
|
|
261
|
+
dd.update(**kwargs)
|
|
262
|
+
return FFT(**dd)
|
|
263
|
+
|
|
264
|
+
@property
|
|
265
|
+
def value_type(self):
|
|
266
|
+
return self._traits.value_type
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def input_type(self):
|
|
270
|
+
return self._traits.input_type
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def output_type(self):
|
|
274
|
+
return self._traits.output_type
|
|
275
|
+
|
|
276
|
+
@property
|
|
277
|
+
def storage_size(self):
|
|
278
|
+
return self._traits.storage_size
|
|
279
|
+
|
|
280
|
+
@property
|
|
281
|
+
def shared_memory_size(self):
|
|
282
|
+
return self._traits.shared_memory_size
|
|
283
|
+
|
|
284
|
+
@property
|
|
285
|
+
def stride(self):
|
|
286
|
+
return self._traits.stride
|
|
287
|
+
|
|
288
|
+
@property
|
|
289
|
+
def block_dim(self):
|
|
290
|
+
return self._traits.block_dim
|
|
291
|
+
|
|
292
|
+
@property
|
|
293
|
+
def requires_workspace(self):
|
|
294
|
+
_workspace_deprecation_warning()
|
|
295
|
+
return False
|
|
296
|
+
|
|
297
|
+
@property
|
|
298
|
+
def workspace_size(self):
|
|
299
|
+
return self._traits.workspace_size
|
|
300
|
+
|
|
301
|
+
@property
|
|
302
|
+
def implicit_type_batching(self):
|
|
303
|
+
return self._traits.implicit_type_batching
|
|
304
|
+
|
|
305
|
+
@property
|
|
306
|
+
def extensions(self):
|
|
307
|
+
raise NotImplementedError("Extensions not supported yet")
|
|
308
|
+
|
|
309
|
+
def execute(*args):
|
|
310
|
+
raise RuntimeError("execute is a device function and can not be called on host.")
|
|
311
|
+
|
|
312
|
+
@deprecated("Calling MM(...) directly is deprecated, please use MM.execute(...) method instead.")
|
|
313
|
+
def __call__(self, *args):
|
|
314
|
+
raise RuntimeError("__call__ is a device function and can not be called on host.")
|
|
315
|
+
|
|
316
|
+
@property
|
|
317
|
+
@deprecated("files is deprecated and is no longer required and will be removed in future releases.")
|
|
318
|
+
def files(self) -> list:
|
|
319
|
+
return []
|
|
320
|
+
|
|
321
|
+
#
|
|
322
|
+
# Private implementations
|
|
323
|
+
#
|
|
324
|
+
|
|
325
|
+
def _suggested(self, what):
|
|
326
|
+
# Generate full PTX
|
|
327
|
+
h = generate_FFT(
|
|
328
|
+
size=self._size,
|
|
329
|
+
precision=self._precision,
|
|
330
|
+
fft_type=self._fft_type,
|
|
331
|
+
direction=self._direction,
|
|
332
|
+
ffts_per_block=(None if self._ffts_per_block == "suggested" else self._ffts_per_block),
|
|
333
|
+
elements_per_thread=(None if self._elements_per_thread == "suggested" else self._elements_per_thread),
|
|
334
|
+
real_fft_options=frozenset(self._real_fft_options.items()) if self._real_fft_options else None,
|
|
335
|
+
sm=self._sm,
|
|
336
|
+
execution=self._execution,
|
|
337
|
+
)
|
|
338
|
+
|
|
339
|
+
if what == "elements_per_thread":
|
|
340
|
+
return get_int_trait(h.descriptor, mathdx.CufftdxTraitType.ELEMENTS_PER_THREAD)
|
|
341
|
+
|
|
342
|
+
if what == "suggested_ffts_per_block":
|
|
343
|
+
return get_int_trait(h.descriptor, mathdx.CufftdxTraitType.SUGGESTED_FFTS_PER_BLOCK)
|
|
344
|
+
|
|
345
|
+
raise Exception(f"Unknown suggested option '{what}'")
|
|
346
|
+
|
|
347
|
+
@cached_property
|
|
348
|
+
def _suggested_ffts_per_block(self):
|
|
349
|
+
return self._suggested("suggested_ffts_per_block")
|
|
350
|
+
|
|
351
|
+
@cached_property
|
|
352
|
+
def _suggested_elements_per_thread(self):
|
|
353
|
+
return self._suggested("elements_per_thread")
|
|
354
|
+
|
|
355
|
+
def _get_knobs(self, *knobs):
|
|
356
|
+
if not (set(knobs) <= {"ffts_per_block", "elements_per_thread"}):
|
|
357
|
+
raise ValueError(f"Unsupported knob. Only valid knobs are ffts_per_block and elements_per_thread but got {knobs}")
|
|
358
|
+
|
|
359
|
+
h = generate_FFT(
|
|
360
|
+
size=self._size,
|
|
361
|
+
precision=self._precision,
|
|
362
|
+
fft_type=self._fft_type,
|
|
363
|
+
direction=self._direction,
|
|
364
|
+
ffts_per_block=self._ffts_per_block,
|
|
365
|
+
elements_per_thread=self._elements_per_thread,
|
|
366
|
+
real_fft_options=frozenset(self._real_fft_options.items()) if self._real_fft_options else None,
|
|
367
|
+
sm=self._sm,
|
|
368
|
+
execution=self._execution,
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
return get_knobs(h.descriptor, knobs)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
class _FFTTraits:
|
|
375
|
+
def __init__(self, FFT: FFT):
|
|
376
|
+
h = generate_FFT(
|
|
377
|
+
size=FFT._size,
|
|
378
|
+
precision=FFT._precision,
|
|
379
|
+
fft_type=FFT._fft_type,
|
|
380
|
+
direction=FFT._direction,
|
|
381
|
+
sm=FFT._sm,
|
|
382
|
+
execution=FFT._execution,
|
|
383
|
+
ffts_per_block=FFT._ffts_per_block if FFT._execution == "Block" else None,
|
|
384
|
+
elements_per_thread=FFT._elements_per_thread if FFT._execution == "Block" else None,
|
|
385
|
+
real_fft_options=frozenset(FFT._real_fft_options.items()) if FFT._real_fft_options else None,
|
|
386
|
+
).descriptor
|
|
387
|
+
|
|
388
|
+
self.value_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.VALUE_TYPE)]
|
|
389
|
+
self.input_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.INPUT_TYPE)]
|
|
390
|
+
self.output_type = MATHDX_TYPES_TO_NP[get_data_type_trait(h, mathdx.CufftdxTraitType.OUTPUT_TYPE)]
|
|
391
|
+
|
|
392
|
+
self.storage_size = get_int_trait(h, mathdx.CufftdxTraitType.STORAGE_SIZE)
|
|
393
|
+
self.stride = get_int_trait(h, mathdx.CufftdxTraitType.STRIDE)
|
|
394
|
+
self.elements_per_thread = get_int_trait(h, mathdx.CufftdxTraitType.ELEMENTS_PER_THREAD)
|
|
395
|
+
self.implicit_type_batching = get_int_trait(h, mathdx.CufftdxTraitType.IMPLICIT_TYPE_BATCHING)
|
|
396
|
+
|
|
397
|
+
self.workspace_size = 0
|
|
398
|
+
if FFT.execution == "Block":
|
|
399
|
+
self.block_dim: Dim3 | None = Dim3(*get_int_traits(h, mathdx.CufftdxTraitType.BLOCK_DIM, 3))
|
|
400
|
+
self.shared_memory_size: int | None = get_int_trait(h, mathdx.CufftdxTraitType.SHARED_MEMORY_SIZE)
|
|
401
|
+
self.ffts_per_block: int | None = get_int_trait(h, mathdx.CufftdxTraitType.FFTS_PER_BLOCK)
|
|
402
|
+
else:
|
|
403
|
+
self.block_dim = None
|
|
404
|
+
self.shared_memory_size = None
|
|
405
|
+
self.ffts_per_block = None
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def compile_fft_execute(
|
|
409
|
+
fft: FFT,
|
|
410
|
+
code_type: Any,
|
|
411
|
+
execute_api: str | None = None,
|
|
412
|
+
) -> tuple[Code, str]:
|
|
413
|
+
code_type = parse_code_type(code_type)
|
|
414
|
+
check_code_type(code_type, "cuFFTDx")
|
|
415
|
+
validate_execute_api(fft.execution, execute_api)
|
|
416
|
+
|
|
417
|
+
h = generate_FFT(
|
|
418
|
+
size=fft._size,
|
|
419
|
+
precision=fft._precision,
|
|
420
|
+
fft_type=fft._fft_type,
|
|
421
|
+
direction=fft._direction,
|
|
422
|
+
sm=fft._sm,
|
|
423
|
+
execution=fft._execution,
|
|
424
|
+
ffts_per_block=fft._ffts_per_block if fft._execution == "Block" else None,
|
|
425
|
+
elements_per_thread=fft._elements_per_thread if fft._execution == "Block" else None,
|
|
426
|
+
real_fft_options=frozenset(fft._real_fft_options.items()) if fft._real_fft_options else None,
|
|
427
|
+
execute_api=execute_api,
|
|
428
|
+
).descriptor
|
|
429
|
+
|
|
430
|
+
code = generate_code(h, code_type.cc)
|
|
431
|
+
|
|
432
|
+
# Compile
|
|
433
|
+
lto_fn = get_lto(code.descriptor)
|
|
434
|
+
isa_version = get_isa_version(code.descriptor)
|
|
435
|
+
|
|
436
|
+
symbol = get_str_trait(h, mathdx.CufftdxTraitType.SYMBOL_NAME)
|
|
437
|
+
|
|
438
|
+
return Code(code_type, isa_version, lto_fn), symbol
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
@docstring_decorator(FFTDX_DOCSTRING, skip_missing=False)
|
|
442
|
+
def fft(*, compiler=None, code_type=None, execute_api=None, **kwargs):
|
|
443
|
+
"""
|
|
444
|
+
Create an :class:`FFT` object that encapsulates a compiled and ready-to-use FFT
|
|
445
|
+
device function.
|
|
446
|
+
|
|
447
|
+
.. deprecated:: 0.7.0
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
size (int): {size}
|
|
451
|
+
|
|
452
|
+
precision (str): {precision}
|
|
453
|
+
|
|
454
|
+
fft_type (str): {fft_type}
|
|
455
|
+
|
|
456
|
+
sm (ComputeCapability): {sm}
|
|
457
|
+
|
|
458
|
+
execution (str): {execution}
|
|
459
|
+
|
|
460
|
+
direction (str): {direction}
|
|
461
|
+
|
|
462
|
+
ffts_per_block (int): {ffts_per_block}
|
|
463
|
+
|
|
464
|
+
elements_per_thread (int): {elements_per_thread}
|
|
465
|
+
|
|
466
|
+
real_fft_options (dict): {real_fft_options} User may specify the following options
|
|
467
|
+
in the dictionary:
|
|
468
|
+
|
|
469
|
+
- ``'complex_layout'``, currently supports ``'natural'``, ``'packed'``, and
|
|
470
|
+
``'full'``.
|
|
471
|
+
- ``'real_mode'``, currently supports ``'normal'`` and ``'folded'``.
|
|
472
|
+
|
|
473
|
+
compiler: {compiler}
|
|
474
|
+
|
|
475
|
+
.. versionchanged:: 0.7.0
|
|
476
|
+
compiler is no longer needed and does not take effect. Use
|
|
477
|
+
:py:func:`nvmath.device.compile_fft_execute` to get device
|
|
478
|
+
function code.
|
|
479
|
+
|
|
480
|
+
code_type (CodeType): {code_type}
|
|
481
|
+
|
|
482
|
+
.. versionchanged:: 0.7.0
|
|
483
|
+
code_type should be used by
|
|
484
|
+
:py:func:`nvmath.device.compile_fft_execute` and no longer
|
|
485
|
+
needed for numba-cuda usage.
|
|
486
|
+
|
|
487
|
+
execute_api (str): {execute_api}
|
|
488
|
+
|
|
489
|
+
.. versionchanged:: 0.7.0
|
|
490
|
+
execute_api should be used by
|
|
491
|
+
:py:func:`nvmath.device.compile_fft_execute` and no longer
|
|
492
|
+
needed for numba-cuda usage.
|
|
493
|
+
|
|
494
|
+
.. seealso::
|
|
495
|
+
The attributes of :class:`FFT` provide a 1:1 mapping with the CUDA C++
|
|
496
|
+
cuFFTDx APIs. For further details, please refer to
|
|
497
|
+
:cufftdx_doc:`cuFFTDx documentation <index.html>`.
|
|
498
|
+
|
|
499
|
+
Examples:
|
|
500
|
+
Examples can be found in the `nvmath/examples/device
|
|
501
|
+
<https://github.com/NVIDIA/nvmath-python/tree/main/examples/device>`_ directory.
|
|
502
|
+
"""
|
|
503
|
+
DeprecationWarning("fft is deprecated and will be removed in future releases. Please use FFT class directly.")
|
|
504
|
+
if code_type is not None:
|
|
505
|
+
DeprecationWarning("code_type is deprecated and will be removed in future releases. It is no longer needed.")
|
|
506
|
+
if compiler is not None:
|
|
507
|
+
DeprecationWarning("compiler is deprecated and will be removed in future releases. It is no longer needed.")
|
|
508
|
+
if execute_api is not None:
|
|
509
|
+
DeprecationWarning("execute_api is deprecated and will be removed in future releases. It is no longer needed.")
|
|
510
|
+
return FFT(**kwargs)
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from collections.abc import Sequence
|
|
6
|
+
from functools import lru_cache
|
|
7
|
+
from typing import Protocol
|
|
8
|
+
|
|
9
|
+
import numpy
|
|
10
|
+
|
|
11
|
+
from nvmath.bindings import mathdx
|
|
12
|
+
from nvmath.device.common_backend import DescriptorWrapper
|
|
13
|
+
from nvmath.device.common_cuda import ComputeCapability
|
|
14
|
+
|
|
15
|
+
from .common import check_contains, check_in, check_not_in, check_sm
|
|
16
|
+
from .common_backend import (
|
|
17
|
+
EXECUTION_STR_TO_MATHDX,
|
|
18
|
+
NP_TYPES_TO_MATHDX_PRECISION,
|
|
19
|
+
NVARG_GEN_OPT_LTO,
|
|
20
|
+
build_get_int_traits,
|
|
21
|
+
build_get_str_trait,
|
|
22
|
+
set_code_target_sm,
|
|
23
|
+
)
|
|
24
|
+
from .types import REAL_NP_TYPES
|
|
25
|
+
|
|
26
|
+
_FFT_TYPE_TO_MATHDX = {t.name.lower(): t for t in mathdx.CufftdxType}
|
|
27
|
+
|
|
28
|
+
_FFT_DIRECTION_TO_MATHDX = {d.name.lower(): d for d in mathdx.CufftdxDirection}
|
|
29
|
+
|
|
30
|
+
_FFT_COMPLEX_LAYOUT_TO_MATHDX = {cl.name.lower(): cl for cl in mathdx.CufftdxComplexLayout}
|
|
31
|
+
|
|
32
|
+
_FFT_REAL_MODE_TO_MATHDX = {m.name.lower(): m for m in mathdx.CufftdxRealMode}
|
|
33
|
+
|
|
34
|
+
_FFT_API_STR_TO_MATHDX = {
|
|
35
|
+
"register_memory": mathdx.CufftdxApi.LMEM,
|
|
36
|
+
"shared_memory": mathdx.CufftdxApi.SMEM,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_FFT_KNOB_TYPE_TO_MATHDX = {t.name.lower(): t for t in mathdx.CufftdxKnobType}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class CallableGetIntTraits(Protocol):
|
|
43
|
+
def __call__(self, handle: int, trait_type: mathdx.CufftdxTraitType, size: int) -> tuple: ...
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class CallableGetStrTrait(Protocol):
|
|
47
|
+
def __call__(self, handle: int, trait_type: mathdx.CufftdxTraitType) -> str: ...
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
get_int_traits: CallableGetIntTraits = build_get_int_traits(mathdx.cufftdx_get_trait_int64s)
|
|
51
|
+
|
|
52
|
+
get_str_trait: CallableGetStrTrait = build_get_str_trait(mathdx.cufftdx_get_trait_str_size, mathdx.cufftdx_get_trait_str)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_int_trait(handle: int, trait_type: mathdx.CufftdxTraitType) -> int:
|
|
56
|
+
return int(mathdx.cufftdx_get_trait_int64(handle, trait_type))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_data_type_trait(handle: int, trait_type: mathdx.CufftdxTraitType) -> mathdx.CommondxValueType:
|
|
60
|
+
return mathdx.CommondxValueType(mathdx.cufftdx_get_trait_commondx_data_type(handle, trait_type))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def validate(
|
|
64
|
+
size,
|
|
65
|
+
precision,
|
|
66
|
+
fft_type,
|
|
67
|
+
execution,
|
|
68
|
+
direction,
|
|
69
|
+
ffts_per_block,
|
|
70
|
+
elements_per_thread,
|
|
71
|
+
real_fft_options,
|
|
72
|
+
sm,
|
|
73
|
+
):
|
|
74
|
+
if size <= 0:
|
|
75
|
+
raise ValueError(f"size must be > 0. Got {size}")
|
|
76
|
+
check_in("precision", precision, REAL_NP_TYPES)
|
|
77
|
+
check_in("fft_type", fft_type, ["c2c", "c2r", "r2c"])
|
|
78
|
+
check_in("execution", execution, ["Block", "Thread"])
|
|
79
|
+
if direction is not None:
|
|
80
|
+
check_in("direction", direction, ["forward", "inverse"])
|
|
81
|
+
if ffts_per_block in (None, "suggested"):
|
|
82
|
+
pass
|
|
83
|
+
else:
|
|
84
|
+
if ffts_per_block <= 0:
|
|
85
|
+
raise ValueError(
|
|
86
|
+
f"ffts_per_block must be None, 'suggested' or a positive integer ; got ffts_per_block = {ffts_per_block}"
|
|
87
|
+
)
|
|
88
|
+
if elements_per_thread in (None, "suggested"):
|
|
89
|
+
pass
|
|
90
|
+
else:
|
|
91
|
+
if elements_per_thread <= 0:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
f"elements_per_thread must be None, 'suggested' or a positive integer ; "
|
|
94
|
+
f"got elements_per_thread = {elements_per_thread}"
|
|
95
|
+
)
|
|
96
|
+
if real_fft_options is None:
|
|
97
|
+
pass
|
|
98
|
+
else:
|
|
99
|
+
check_contains(real_fft_options, "complex_layout")
|
|
100
|
+
check_contains(real_fft_options, "real_mode")
|
|
101
|
+
check_in("real_fft_options['complex_layout']", real_fft_options["complex_layout"], ["natural", "packed", "full"])
|
|
102
|
+
check_in("real_fft_options['real_mode']", real_fft_options["real_mode"], ["normal", "folded"])
|
|
103
|
+
check_sm(sm, "sm")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def validate_execute_api(execution: str, execute_api: str | None):
|
|
107
|
+
"""
|
|
108
|
+
Validate the execute_api argument.
|
|
109
|
+
"""
|
|
110
|
+
if execution == "Block":
|
|
111
|
+
check_in("execute_api", execute_api, list(_FFT_API_STR_TO_MATHDX.keys()) + [None])
|
|
112
|
+
else:
|
|
113
|
+
if execute_api is not None:
|
|
114
|
+
raise ValueError(f"api may be set only for block execution ; got execution = {execution}")
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@lru_cache
|
|
118
|
+
def generate_FFT(
|
|
119
|
+
size,
|
|
120
|
+
precision,
|
|
121
|
+
fft_type,
|
|
122
|
+
direction,
|
|
123
|
+
sm,
|
|
124
|
+
execution,
|
|
125
|
+
ffts_per_block,
|
|
126
|
+
elements_per_thread,
|
|
127
|
+
real_fft_options,
|
|
128
|
+
execute_api=None,
|
|
129
|
+
):
|
|
130
|
+
check_not_in("ffts_per_block", ffts_per_block, ["suggested"])
|
|
131
|
+
check_not_in("elements_per_thread", elements_per_thread, ["suggested"])
|
|
132
|
+
|
|
133
|
+
h = mathdx.cufftdx_create_descriptor()
|
|
134
|
+
|
|
135
|
+
# TODO: remove after migrating to libmathdx 0.2.4+
|
|
136
|
+
if execute_api is None:
|
|
137
|
+
execute_api = "register_memory"
|
|
138
|
+
|
|
139
|
+
if execute_api is not None:
|
|
140
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.API, _FFT_API_STR_TO_MATHDX[execute_api])
|
|
141
|
+
|
|
142
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.SM, sm.major * 100 + sm.minor * 10)
|
|
143
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.SIZE, size)
|
|
144
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.PRECISION, NP_TYPES_TO_MATHDX_PRECISION[precision])
|
|
145
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.TYPE, _FFT_TYPE_TO_MATHDX[fft_type])
|
|
146
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.DIRECTION, _FFT_DIRECTION_TO_MATHDX[direction])
|
|
147
|
+
|
|
148
|
+
if real_fft_options:
|
|
149
|
+
real_fft_options = dict(real_fft_options)
|
|
150
|
+
ll = real_fft_options["complex_layout"]
|
|
151
|
+
mm = real_fft_options["real_mode"]
|
|
152
|
+
mathdx.cufftdx_set_operator_int64s(
|
|
153
|
+
h, mathdx.CufftdxOperatorType.REAL_FFT_OPTIONS, 2, [_FFT_COMPLEX_LAYOUT_TO_MATHDX[ll], _FFT_REAL_MODE_TO_MATHDX[mm]]
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.EXECUTION, EXECUTION_STR_TO_MATHDX[execution])
|
|
157
|
+
|
|
158
|
+
if ffts_per_block:
|
|
159
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.FFTS_PER_BLOCK, ffts_per_block)
|
|
160
|
+
|
|
161
|
+
if elements_per_thread:
|
|
162
|
+
mathdx.cufftdx_set_operator_int64(h, mathdx.CufftdxOperatorType.ELEMENTS_PER_THREAD, elements_per_thread)
|
|
163
|
+
|
|
164
|
+
return DescriptorWrapper(h, mathdx.cufftdx_destroy_descriptor)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@lru_cache
|
|
168
|
+
def generate_code(handle, version: ComputeCapability):
|
|
169
|
+
code = mathdx.commondx_create_code()
|
|
170
|
+
|
|
171
|
+
set_code_target_sm(code, version)
|
|
172
|
+
mathdx.commondx_set_code_option_str(code, mathdx.CommondxOption.EXTRA_NVRTC_ARGS, NVARG_GEN_OPT_LTO)
|
|
173
|
+
mathdx.cufftdx_finalize_code(code, handle)
|
|
174
|
+
|
|
175
|
+
return DescriptorWrapper(code, mathdx.commondx_destroy_code)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@lru_cache
|
|
179
|
+
def get_knobs(handle, knobs: Sequence[str]):
|
|
180
|
+
knobs_dx: list[mathdx.CufftdxKnobType] = [_FFT_KNOB_TYPE_TO_MATHDX[k] for k in knobs]
|
|
181
|
+
knobs_size = mathdx.cufftdx_get_knob_int64size(handle, len(knobs), knobs_dx)
|
|
182
|
+
|
|
183
|
+
knobs_result_dx = numpy.empty(knobs_size, dtype=numpy.int64)
|
|
184
|
+
mathdx.cufftdx_get_knob_int64s(
|
|
185
|
+
handle,
|
|
186
|
+
len(knobs),
|
|
187
|
+
knobs_dx,
|
|
188
|
+
knobs_size,
|
|
189
|
+
knobs_result_dx.ctypes.data,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
knobs_result = [
|
|
193
|
+
tuple(int(knobs_result_dx[j]) for j in range(i, i + len(knobs))) for i in range(0, len(knobs_result_dx), len(knobs))
|
|
194
|
+
]
|
|
195
|
+
|
|
196
|
+
return knobs_result
|