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,567 @@
|
|
|
1
|
+
# Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from typing import NamedTuple, NoReturn
|
|
7
|
+
|
|
8
|
+
from numba import cuda
|
|
9
|
+
from numba.core import typing
|
|
10
|
+
from numba.extending import intrinsic, overload_method, types
|
|
11
|
+
|
|
12
|
+
from nvmath.device import (
|
|
13
|
+
Solver,
|
|
14
|
+
compile_solver_execute,
|
|
15
|
+
)
|
|
16
|
+
from nvmath.device.common_cuda import get_default_code_type
|
|
17
|
+
from nvmath.device.cusolverdx_backend import get_universal_fatbin
|
|
18
|
+
|
|
19
|
+
from .common_numba import (
|
|
20
|
+
NUMBA_FE_TYPES_TO_NUMBA_IR,
|
|
21
|
+
declare_cabi_device,
|
|
22
|
+
get_array_ptr,
|
|
23
|
+
get_uint32_value_ptr,
|
|
24
|
+
register_dummy_numba_type,
|
|
25
|
+
)
|
|
26
|
+
from .cusolverdx_overload_backend import (
|
|
27
|
+
_SOLVER_DEFINITION_ARGS,
|
|
28
|
+
_SOLVER_PROPS,
|
|
29
|
+
_USER_API_DISPATCH_SPECS,
|
|
30
|
+
_Arg,
|
|
31
|
+
_ArgType,
|
|
32
|
+
_get_function_signatures,
|
|
33
|
+
_Signature,
|
|
34
|
+
_UserApiDeviceMethod,
|
|
35
|
+
_UserApiDispatchFactory,
|
|
36
|
+
_UserApiSpec,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# ==========================
|
|
40
|
+
# Numba type
|
|
41
|
+
# ==========================
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class SolverNumbaType(types.Type):
|
|
45
|
+
def __init__(self, solver: Solver) -> None:
|
|
46
|
+
self._solver = solver
|
|
47
|
+
|
|
48
|
+
attributes = [f"{attr}={getattr(solver, attr)}" for attr in _SOLVER_DEFINITION_ARGS if getattr(solver, attr)]
|
|
49
|
+
attributes.sort()
|
|
50
|
+
attr_str = ", ".join(attributes)
|
|
51
|
+
|
|
52
|
+
super().__init__(name=f"Solver({attr_str})")
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def solver(self) -> Solver:
|
|
56
|
+
return self._solver
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
register_dummy_numba_type(
|
|
60
|
+
SolverNumbaType,
|
|
61
|
+
Solver,
|
|
62
|
+
"solver",
|
|
63
|
+
_SOLVER_DEFINITION_ARGS + _SOLVER_PROPS,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# ==========================
|
|
68
|
+
# Intrinsics
|
|
69
|
+
# ==========================
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@intrinsic
|
|
73
|
+
def _link_fatbin(typingctx: typing.Context):
|
|
74
|
+
sig = types.void()
|
|
75
|
+
|
|
76
|
+
fatbin = get_universal_fatbin()
|
|
77
|
+
|
|
78
|
+
def codegen(context, builder, sig, args):
|
|
79
|
+
context.active_code_library.add_linking_file(fatbin)
|
|
80
|
+
|
|
81
|
+
return sig, codegen
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@intrinsic
|
|
85
|
+
def _do_nothing(typingctx: typing.Context, value: types.Type):
|
|
86
|
+
sig = value(value)
|
|
87
|
+
|
|
88
|
+
def codegen(context, builder, sig, args):
|
|
89
|
+
return args[0]
|
|
90
|
+
|
|
91
|
+
return sig, codegen
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ==========================
|
|
95
|
+
# Overloads: Type conversions
|
|
96
|
+
# ==========================
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _numba_solver_value_type_ptr(solver_type: SolverNumbaType) -> types.Type:
|
|
100
|
+
return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.value_type])
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _numba_solver_precision_type_ptr(solver_type: SolverNumbaType) -> types.Type:
|
|
104
|
+
return types.CPointer(NUMBA_FE_TYPES_TO_NUMBA_IR[solver_type.solver.precision])
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def _numba_solver_integer_value(solver_type: SolverNumbaType) -> types.Type:
|
|
108
|
+
return types.Integer
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _numba_solver_int32_ptr(solver_type: SolverNumbaType) -> types.Type:
|
|
112
|
+
return types.CPointer(types.int32)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _convert_to_ir_type(arg_type: _ArgType, solver_type: SolverNumbaType) -> types.Type:
|
|
116
|
+
TO_IR_TYPE_MAP = {
|
|
117
|
+
_ArgType.value_type_ptr: _numba_solver_value_type_ptr,
|
|
118
|
+
_ArgType.precision_type_ptr: _numba_solver_precision_type_ptr,
|
|
119
|
+
_ArgType.integer_value: _numba_solver_integer_value,
|
|
120
|
+
_ArgType.int32_ptr: _numba_solver_int32_ptr,
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
factory = TO_IR_TYPE_MAP[arg_type]
|
|
124
|
+
return factory(solver_type)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# ==========================
|
|
128
|
+
# Overloads: Method Dispatch Implementation
|
|
129
|
+
# ==========================
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _validate_arg_type(user_type: types.Type, expected_type: types.Type) -> bool:
|
|
133
|
+
if expected_type == types.Integer:
|
|
134
|
+
return isinstance(user_type, types.Integer)
|
|
135
|
+
|
|
136
|
+
assert isinstance(expected_type, types.CPointer)
|
|
137
|
+
dtype, _ = expected_type.key
|
|
138
|
+
|
|
139
|
+
return isinstance(user_type, types.Array) and user_type.dtype == dtype
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _get_libmathdx_type(expected_type: types.Type) -> types.Type:
|
|
143
|
+
if expected_type == types.Integer:
|
|
144
|
+
return types.CPointer(types.uint32)
|
|
145
|
+
return expected_type
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _get_error_message_type(numba_type: types.Type) -> types.Type | str:
|
|
149
|
+
"""
|
|
150
|
+
Converts a type to its user-friendly representation for error messages.
|
|
151
|
+
"""
|
|
152
|
+
if numba_type == types.Integer:
|
|
153
|
+
return numba_type.__name__
|
|
154
|
+
return numba_type
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _check_all_none(args: list[types.Type]) -> bool:
|
|
158
|
+
"""Checks if all elements are None"""
|
|
159
|
+
return all(unwanted_arg in {None, types.Omitted(None), types.none} for unwanted_arg in args)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _validate_arg_types(solver_type: SolverNumbaType, arg_types: list[_Arg], args_fit: list[types.Type]) -> bool:
|
|
163
|
+
"""Validates whether provided arguments match the expected types for a signature."""
|
|
164
|
+
return all(
|
|
165
|
+
_validate_arg_type(arg, _convert_to_ir_type(arg_spec.arg_type, solver_type))
|
|
166
|
+
for arg_spec, arg in zip(arg_types, args_fit, strict=True)
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _find_overload(args: list[types.Type], solver_type: SolverNumbaType) -> _Signature | None:
|
|
171
|
+
"""
|
|
172
|
+
Iterates through all available signatures for the solver's function and finds
|
|
173
|
+
the first one where:
|
|
174
|
+
1. The number of arguments matches (no extra arguments provided)
|
|
175
|
+
2. All argument types are valid for the signature
|
|
176
|
+
"""
|
|
177
|
+
|
|
178
|
+
signatures = _get_function_signatures(solver_type.solver.function)
|
|
179
|
+
assert signatures is not None
|
|
180
|
+
|
|
181
|
+
for sig in signatures:
|
|
182
|
+
expected_args_num = len(sig.args)
|
|
183
|
+
|
|
184
|
+
args_fit = args[:expected_args_num]
|
|
185
|
+
if not _check_all_none(args[expected_args_num:]):
|
|
186
|
+
continue
|
|
187
|
+
|
|
188
|
+
if not _validate_arg_types(solver_type, sig.args, args_fit):
|
|
189
|
+
continue
|
|
190
|
+
|
|
191
|
+
return sig
|
|
192
|
+
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _compile_device_function(solver_type: SolverNumbaType, signature: _Signature) -> Callable:
|
|
197
|
+
"""
|
|
198
|
+
Compile cusolverdx execute device function and wrap it into numba device function.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
# Call libmathdx to jit the function
|
|
202
|
+
code, symbol = compile_solver_execute(
|
|
203
|
+
solver_type.solver,
|
|
204
|
+
code_type=get_default_code_type(),
|
|
205
|
+
execution_api=signature.api,
|
|
206
|
+
)
|
|
207
|
+
lto = cuda.LTOIR(code.data)
|
|
208
|
+
|
|
209
|
+
numba_args = [_get_libmathdx_type(_convert_to_ir_type(arg_spec.arg_type, solver_type)) for arg_spec in signature.args]
|
|
210
|
+
sig = types.void(*numba_args)
|
|
211
|
+
|
|
212
|
+
# Convert to cabi from numba abi
|
|
213
|
+
return declare_cabi_device(symbol, sig, link=lto)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _format_signature(solver_type: SolverNumbaType, sig: _Signature) -> str:
|
|
217
|
+
arg_list = ", ".join(
|
|
218
|
+
f"{arg_spec.name}: {_get_error_message_type(_convert_to_ir_type(arg_spec.arg_type, solver_type))}"
|
|
219
|
+
for arg_spec in sig.args
|
|
220
|
+
)
|
|
221
|
+
return f"({arg_list}) -> None"
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def _raise_overload_resolution_error(solver_type: SolverNumbaType, args: list[types.Type]) -> NoReturn:
|
|
225
|
+
"""
|
|
226
|
+
Raises a detailed TypeError when no matching function signature is found.
|
|
227
|
+
|
|
228
|
+
Constructs an informative error message showing:
|
|
229
|
+
- The signature that was provided by the user
|
|
230
|
+
- All available signatures for the solver function
|
|
231
|
+
"""
|
|
232
|
+
signatures = _get_function_signatures(solver_type.solver.function)
|
|
233
|
+
assert signatures is not None
|
|
234
|
+
|
|
235
|
+
available_sigs = ", ".join(_format_signature(solver_type, sig) for sig in signatures)
|
|
236
|
+
provided_args = [
|
|
237
|
+
types.CPointer(arg.dtype) if isinstance(arg, types.Array) else arg
|
|
238
|
+
for arg in args
|
|
239
|
+
if arg not in {None, types.Omitted(None), types.none}
|
|
240
|
+
]
|
|
241
|
+
provided_sig = types.void(*provided_args)
|
|
242
|
+
|
|
243
|
+
raise TypeError(
|
|
244
|
+
'Failed to find matching overload of "SOLVER.execute()" function.'
|
|
245
|
+
f" Provided signature: {provided_sig}, but only these are available: {available_sigs}"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
@overload_method(SolverNumbaType, "execute", target="cuda", jit_options={"forceinline": True}, strict=False)
|
|
250
|
+
def _overload_execute(solver_type: SolverNumbaType, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
|
251
|
+
"""Numba overload for Solver.execute(), resolves signature and compiles function."""
|
|
252
|
+
assert isinstance(solver_type, SolverNumbaType)
|
|
253
|
+
|
|
254
|
+
# Find matching signature for the provided arguments
|
|
255
|
+
args = [arg0, arg1, arg2, arg3, arg4, arg5]
|
|
256
|
+
overload = _find_overload(args, solver_type)
|
|
257
|
+
|
|
258
|
+
if overload is None:
|
|
259
|
+
_raise_overload_resolution_error(solver_type, args)
|
|
260
|
+
|
|
261
|
+
# Compile the device function for the matched signature
|
|
262
|
+
device_func = _compile_device_function(solver_type, overload)
|
|
263
|
+
|
|
264
|
+
# Generate the implementation wrapper
|
|
265
|
+
def prepare_arg_intrinsic(arg):
|
|
266
|
+
if isinstance(arg, types.Integer):
|
|
267
|
+
return get_uint32_value_ptr
|
|
268
|
+
elif isinstance(arg, types.Array):
|
|
269
|
+
return get_array_ptr
|
|
270
|
+
else:
|
|
271
|
+
return _do_nothing
|
|
272
|
+
|
|
273
|
+
intrinsic0 = prepare_arg_intrinsic(arg0)
|
|
274
|
+
intrinsic1 = prepare_arg_intrinsic(arg1)
|
|
275
|
+
intrinsic2 = prepare_arg_intrinsic(arg2)
|
|
276
|
+
intrinsic3 = prepare_arg_intrinsic(arg3)
|
|
277
|
+
intrinsic4 = prepare_arg_intrinsic(arg4)
|
|
278
|
+
intrinsic5 = prepare_arg_intrinsic(arg5)
|
|
279
|
+
|
|
280
|
+
num_args = len(overload.args)
|
|
281
|
+
|
|
282
|
+
def execute_impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None):
|
|
283
|
+
_link_fatbin()
|
|
284
|
+
converted_args = (
|
|
285
|
+
intrinsic0(arg0),
|
|
286
|
+
intrinsic1(arg1),
|
|
287
|
+
intrinsic2(arg2),
|
|
288
|
+
intrinsic3(arg3),
|
|
289
|
+
intrinsic4(arg4),
|
|
290
|
+
intrinsic5(arg5),
|
|
291
|
+
)
|
|
292
|
+
device_func(*converted_args[:num_args])
|
|
293
|
+
|
|
294
|
+
return execute_impl
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# ==========================
|
|
298
|
+
# User API helpers
|
|
299
|
+
# =========================
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@cuda.jit(device=True, forceinline=True)
|
|
303
|
+
def _calculate_strides(shape: tuple[int, int], ld: int, is_col_major: bool) -> tuple[int, int, int]:
|
|
304
|
+
return (ld * shape[1], 1, ld) if is_col_major else (ld * shape[0], ld, 1)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def _validate_ld_type(ld, name):
|
|
308
|
+
if ld not in {None, types.Omitted(None), types.none} and not isinstance(ld, types.Integer):
|
|
309
|
+
raise RuntimeError(f"{name} must be an Integer!")
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def _ensure_no_positional_arguments(arg0, function):
|
|
313
|
+
if arg0 not in {None, types.Omitted(None), types.none}:
|
|
314
|
+
raise RuntimeError(f"Function {function} does not accept positional arguments")
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
# ==========================
|
|
318
|
+
# Stride and size device-method impls
|
|
319
|
+
# ==========================
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def _a_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
323
|
+
return _calculate_strides(
|
|
324
|
+
(solver.a_shape[1], solver.a_shape[2]),
|
|
325
|
+
lda if lda is not None else solver.lda,
|
|
326
|
+
solver.a_arrangement == "col_major",
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def _b_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
331
|
+
return _calculate_strides(
|
|
332
|
+
(solver.b_shape[1], solver.b_shape[2]),
|
|
333
|
+
ldb if ldb is not None else solver.ldb,
|
|
334
|
+
solver.b_arrangement == "col_major",
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _c_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
339
|
+
return _calculate_strides(
|
|
340
|
+
(solver.c_shape[1], solver.c_shape[2]),
|
|
341
|
+
ldc if ldc is not None else solver.ldb,
|
|
342
|
+
solver.b_arrangement == "col_major",
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def _bx_strides_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
347
|
+
return _calculate_strides(
|
|
348
|
+
(max(solver.m, solver.n), solver.k),
|
|
349
|
+
ldb if ldb is not None else solver.ldb,
|
|
350
|
+
solver.b_arrangement == "col_major",
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _a_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
355
|
+
return solver.a_strides(lda=lda)[0] * solver.a_shape[0]
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def _b_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
359
|
+
return solver.b_strides(ldb=ldb)[0] * solver.b_shape[0]
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _c_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
363
|
+
return solver.c_strides(ldc=ldc)[0] * solver.c_shape[0]
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def _bx_size_impl(solver, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
367
|
+
return solver.bx_strides(ldb=ldb)[0] * solver.batches_per_block
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
# ==========================
|
|
371
|
+
# Execute() call-shape builders
|
|
372
|
+
# ==========================
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
def _impl_a0_a1(solver: Solver) -> Callable:
|
|
376
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
377
|
+
solver.execute(arg0, arg1)
|
|
378
|
+
|
|
379
|
+
return impl
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
def _impl_a0_a1_a2(solver: Solver) -> Callable:
|
|
383
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
384
|
+
solver.execute(arg0, arg1, arg2)
|
|
385
|
+
|
|
386
|
+
return impl
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _impl_a0_lda_a1(solver: Solver) -> Callable:
|
|
390
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
391
|
+
solver.execute(arg0, lda, arg1)
|
|
392
|
+
|
|
393
|
+
return impl
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _impl_a0_lda_a1_ldb(solver: Solver) -> Callable:
|
|
397
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
398
|
+
solver.execute(arg0, lda, arg1, ldb)
|
|
399
|
+
|
|
400
|
+
return impl
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def _impl_a0_lda_a1_a2(solver: Solver) -> Callable:
|
|
404
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
405
|
+
solver.execute(arg0, lda, arg1, arg2)
|
|
406
|
+
|
|
407
|
+
return impl
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def _impl_a0_lda_a1_a2_ldb(solver: Solver) -> Callable:
|
|
411
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
412
|
+
solver.execute(arg0, lda, arg1, arg2, ldb)
|
|
413
|
+
|
|
414
|
+
return impl
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def _impl_a0_lda_a1_a2_ldc(solver: Solver) -> Callable:
|
|
418
|
+
def impl(_, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None):
|
|
419
|
+
solver.execute(arg0, lda, arg1, arg2, ldc)
|
|
420
|
+
|
|
421
|
+
return impl
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
class _CallShape(NamedTuple):
|
|
425
|
+
plain: Callable # impl builder for the no-leading-dims path
|
|
426
|
+
lds: Callable # impl builder for the runtime-leading-dims path
|
|
427
|
+
requires_square: bool = False # solve operations: solver is None when the matrix isn't square
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
# ==========================
|
|
431
|
+
# Mappings
|
|
432
|
+
# ==========================
|
|
433
|
+
|
|
434
|
+
_DEVICE_METHODS_IMPL = {
|
|
435
|
+
_UserApiDeviceMethod.a_strides: _a_strides_impl,
|
|
436
|
+
_UserApiDeviceMethod.b_strides: _b_strides_impl,
|
|
437
|
+
_UserApiDeviceMethod.c_strides: _c_strides_impl,
|
|
438
|
+
_UserApiDeviceMethod.bx_strides: _bx_strides_impl,
|
|
439
|
+
_UserApiDeviceMethod.a_size: _a_size_impl,
|
|
440
|
+
_UserApiDeviceMethod.b_size: _b_size_impl,
|
|
441
|
+
_UserApiDeviceMethod.c_size: _c_size_impl,
|
|
442
|
+
_UserApiDeviceMethod.bx_size: _bx_size_impl,
|
|
443
|
+
} # fmt: skip
|
|
444
|
+
assert set(_DEVICE_METHODS_IMPL) == set(_UserApiDeviceMethod)
|
|
445
|
+
|
|
446
|
+
_CALL_SHAPES = {
|
|
447
|
+
_UserApiDispatchFactory.factorize_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1),
|
|
448
|
+
_UserApiDispatchFactory.solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb,
|
|
449
|
+
requires_square=True),
|
|
450
|
+
_UserApiDispatchFactory.triangular_solve_factory: _CallShape(_impl_a0_a1, _impl_a0_lda_a1_ldb),
|
|
451
|
+
_UserApiDispatchFactory.factorize_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2),
|
|
452
|
+
_UserApiDispatchFactory.solve_pivot_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb,
|
|
453
|
+
requires_square=True),
|
|
454
|
+
_UserApiDispatchFactory.orthogonal_multiply_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldc),
|
|
455
|
+
_UserApiDispatchFactory.least_squares_solve_factory: _CallShape(_impl_a0_a1_a2, _impl_a0_lda_a1_a2_ldb),
|
|
456
|
+
} # fmt: skip
|
|
457
|
+
assert set(_CALL_SHAPES) == set(_UserApiDispatchFactory)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
# ==========================
|
|
461
|
+
# Dispatch Methods Factories
|
|
462
|
+
# ==========================
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def _create_solver_dispatch_overload(numba_type, method, solver_attr, call_shape: _CallShape, expected_lds):
|
|
466
|
+
@overload_method(numba_type, method, target="cuda", jit_options={"forceinline": True}, strict=False)
|
|
467
|
+
def overload_user_api_method(
|
|
468
|
+
user_api, arg0, arg1, arg2=None, arg3=None, arg4=None, arg5=None, lda=None, ldb=None, ldc=None
|
|
469
|
+
):
|
|
470
|
+
assert isinstance(user_api, numba_type)
|
|
471
|
+
|
|
472
|
+
def expected_ensure_provided(ld, name, expected):
|
|
473
|
+
if expected == name and ld is None:
|
|
474
|
+
raise RuntimeError(f"{name} must be provided to use runtime leading dimensions")
|
|
475
|
+
|
|
476
|
+
_validate_ld_type(lda, "lda")
|
|
477
|
+
_validate_ld_type(ldb, "ldb")
|
|
478
|
+
_validate_ld_type(ldc, "ldc")
|
|
479
|
+
|
|
480
|
+
use_lds = (
|
|
481
|
+
lda not in {None, types.Omitted(None), types.none}
|
|
482
|
+
or ldb not in {None, types.Omitted(None), types.none}
|
|
483
|
+
or ldc not in {None, types.Omitted(None), types.none}
|
|
484
|
+
)
|
|
485
|
+
if use_lds:
|
|
486
|
+
for expected_ld in expected_lds:
|
|
487
|
+
expected_ensure_provided(lda, "lda", expected_ld)
|
|
488
|
+
expected_ensure_provided(ldb, "ldb", expected_ld)
|
|
489
|
+
expected_ensure_provided(ldc, "ldc", expected_ld)
|
|
490
|
+
|
|
491
|
+
solver = getattr(user_api.solver, solver_attr)
|
|
492
|
+
if call_shape.requires_square:
|
|
493
|
+
if solver is None:
|
|
494
|
+
raise RuntimeError(
|
|
495
|
+
"Device function: solve is not available with this configuration: "
|
|
496
|
+
"Operation is permitted only for square matrices"
|
|
497
|
+
)
|
|
498
|
+
assert solver.m == solver.n
|
|
499
|
+
else:
|
|
500
|
+
assert solver is not None
|
|
501
|
+
return (call_shape.lds if use_lds else call_shape.plain)(solver)
|
|
502
|
+
|
|
503
|
+
return overload_user_api_method
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def _create_device_method_overload(numba_type, method: _UserApiDeviceMethod):
|
|
507
|
+
impl = _DEVICE_METHODS_IMPL[method]
|
|
508
|
+
|
|
509
|
+
@overload_method(numba_type, method.value, target="cuda", jit_options={"forceinline": True}, strict=False)
|
|
510
|
+
def overload_user_api_method(user_api, arg0=None, arg1=None, arg2=None, lda=None, ldb=None, ldc=None):
|
|
511
|
+
assert isinstance(user_api, numba_type)
|
|
512
|
+
|
|
513
|
+
_ensure_no_positional_arguments(arg0, method.value)
|
|
514
|
+
_validate_ld_type(lda, "lda")
|
|
515
|
+
_validate_ld_type(ldb, "ldb")
|
|
516
|
+
_validate_ld_type(ldc, "ldc")
|
|
517
|
+
|
|
518
|
+
return impl
|
|
519
|
+
|
|
520
|
+
return overload_user_api_method
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
def _register_user_api_dispatch(user_api_spec: _UserApiSpec):
|
|
524
|
+
"""
|
|
525
|
+
Registers new numba type for a user API class and overloads the device methods.
|
|
526
|
+
|
|
527
|
+
Assumes the API object has hidden fields containing Solver objects.
|
|
528
|
+
Uses device_methods_attrs (which maps method names to solver fields)
|
|
529
|
+
to forward execution to the execute() method of the corresponding solver.
|
|
530
|
+
"""
|
|
531
|
+
|
|
532
|
+
class UserApiNumbaType(types.Type):
|
|
533
|
+
def __init__(self, solver) -> None:
|
|
534
|
+
self._solver = solver
|
|
535
|
+
|
|
536
|
+
attributes = [f"{attr}={getattr(solver, attr)}" for attr in user_api_spec.definition_args if getattr(solver, attr)]
|
|
537
|
+
attributes.sort()
|
|
538
|
+
attr_str = ", ".join(attributes)
|
|
539
|
+
|
|
540
|
+
super().__init__(name=f"{user_api_spec.user_api_class.__name__}({attr_str})")
|
|
541
|
+
|
|
542
|
+
@property
|
|
543
|
+
def solver(self):
|
|
544
|
+
return self._solver
|
|
545
|
+
|
|
546
|
+
register_dummy_numba_type(
|
|
547
|
+
UserApiNumbaType,
|
|
548
|
+
user_api_spec.user_api_class,
|
|
549
|
+
"solver",
|
|
550
|
+
user_api_spec.definition_args + user_api_spec.helpers_prop,
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
for solver_dispath_method in user_api_spec.solver_dispath_methods:
|
|
554
|
+
_create_solver_dispatch_overload(
|
|
555
|
+
UserApiNumbaType,
|
|
556
|
+
solver_dispath_method.method,
|
|
557
|
+
solver_dispath_method.solver_attr,
|
|
558
|
+
_CALL_SHAPES[solver_dispath_method.factory],
|
|
559
|
+
solver_dispath_method.expected_lds,
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
for device_method in user_api_spec.device_methods:
|
|
563
|
+
_create_device_method_overload(UserApiNumbaType, device_method)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
for user_api_spec in _USER_API_DISPATCH_SPECS:
|
|
567
|
+
_register_user_api_dispatch(user_api_spec)
|