nvmath-python 0.5.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. nvmath/__init__.pxd +0 -0
  2. nvmath/__init__.py +37 -0
  3. nvmath/_internal/__init__.py +0 -0
  4. nvmath/_internal/layout.py +58 -0
  5. nvmath/_utils.py +363 -0
  6. nvmath/bindings/__init__.pxd +0 -0
  7. nvmath/bindings/__init__.py +44 -0
  8. nvmath/bindings/_internal/__init__.pxd +0 -0
  9. nvmath/bindings/_internal/__init__.py +0 -0
  10. nvmath/bindings/_internal/cublas.cp313-win_amd64.pyd +0 -0
  11. nvmath/bindings/_internal/cublas.pxd +518 -0
  12. nvmath/bindings/_internal/cublasLt.cp313-win_amd64.pyd +0 -0
  13. nvmath/bindings/_internal/cublasLt.pxd +54 -0
  14. nvmath/bindings/_internal/cudss.cp313-win_amd64.pyd +0 -0
  15. nvmath/bindings/_internal/cudss.pxd +44 -0
  16. nvmath/bindings/_internal/cufft.cp313-win_amd64.pyd +0 -0
  17. nvmath/bindings/_internal/cufft.pxd +69 -0
  18. nvmath/bindings/_internal/cufftMp.pxd +77 -0
  19. nvmath/bindings/_internal/curand.cp313-win_amd64.pyd +0 -0
  20. nvmath/bindings/_internal/curand.pxd +42 -0
  21. nvmath/bindings/_internal/cusolver.cp313-win_amd64.pyd +0 -0
  22. nvmath/bindings/_internal/cusolver.pxd +15 -0
  23. nvmath/bindings/_internal/cusolverDn.cp313-win_amd64.pyd +0 -0
  24. nvmath/bindings/_internal/cusolverDn.pxd +386 -0
  25. nvmath/bindings/_internal/cusparse.cp313-win_amd64.pyd +0 -0
  26. nvmath/bindings/_internal/cusparse.pxd +270 -0
  27. nvmath/bindings/_internal/mathdx.cp313-win_amd64.pyd +0 -0
  28. nvmath/bindings/_internal/mathdx.pxd +79 -0
  29. nvmath/bindings/_internal/nvshmem.pxd +29 -0
  30. nvmath/bindings/_internal/utils.cp313-win_amd64.pyd +0 -0
  31. nvmath/bindings/_internal/utils.pxd +186 -0
  32. nvmath/bindings/cublas.cp313-win_amd64.pyd +0 -0
  33. nvmath/bindings/cublas.pxd +545 -0
  34. nvmath/bindings/cublas.pyi +18 -0
  35. nvmath/bindings/cublasLt.cp313-win_amd64.pyd +0 -0
  36. nvmath/bindings/cublasLt.pxd +99 -0
  37. nvmath/bindings/cudss.cp313-win_amd64.pyd +0 -0
  38. nvmath/bindings/cudss.pxd +83 -0
  39. nvmath/bindings/cudss.pyi +249 -0
  40. nvmath/bindings/cufft.cp313-win_amd64.pyd +0 -0
  41. nvmath/bindings/cufft.pxd +114 -0
  42. nvmath/bindings/cufftMp.pxd +124 -0
  43. nvmath/bindings/curand.cp313-win_amd64.pyd +0 -0
  44. nvmath/bindings/curand.pxd +71 -0
  45. nvmath/bindings/cusolver.cp313-win_amd64.pyd +0 -0
  46. nvmath/bindings/cusolver.pxd +60 -0
  47. nvmath/bindings/cusolverDn.cp313-win_amd64.pyd +0 -0
  48. nvmath/bindings/cusolverDn.pxd +410 -0
  49. nvmath/bindings/cusparse.cp313-win_amd64.pyd +0 -0
  50. nvmath/bindings/cusparse.pxd +329 -0
  51. nvmath/bindings/cycublas.cp313-win_amd64.pyd +0 -0
  52. nvmath/bindings/cycublas.pxd +657 -0
  53. nvmath/bindings/cycublasLt.cp313-win_amd64.pyd +0 -0
  54. nvmath/bindings/cycublasLt.pxd +1010 -0
  55. nvmath/bindings/cycudss.cp313-win_amd64.pyd +0 -0
  56. nvmath/bindings/cycudss.pxd +191 -0
  57. nvmath/bindings/cycufft.cp313-win_amd64.pyd +0 -0
  58. nvmath/bindings/cycufft.pxd +320 -0
  59. nvmath/bindings/cycufftMp.pxd +333 -0
  60. nvmath/bindings/cycurand.cp313-win_amd64.pyd +0 -0
  61. nvmath/bindings/cycurand.pxd +146 -0
  62. nvmath/bindings/cycusolver.cp313-win_amd64.pyd +0 -0
  63. nvmath/bindings/cycusolver.pxd +143 -0
  64. nvmath/bindings/cycusolverDn.cp313-win_amd64.pyd +0 -0
  65. nvmath/bindings/cycusolverDn.pxd +414 -0
  66. nvmath/bindings/cycusparse.cp313-win_amd64.pyd +0 -0
  67. nvmath/bindings/cycusparse.pxd +476 -0
  68. nvmath/bindings/cymathdx.cp313-win_amd64.pyd +0 -0
  69. nvmath/bindings/cymathdx.pxd +363 -0
  70. nvmath/bindings/cynvshmem.pxd +126 -0
  71. nvmath/bindings/mathdx.cp313-win_amd64.pyd +0 -0
  72. nvmath/bindings/mathdx.pxd +131 -0
  73. nvmath/bindings/mathdx.pyi +686 -0
  74. nvmath/bindings/nvpl/__init__.pxd +0 -0
  75. nvmath/bindings/nvpl/__init__.py +11 -0
  76. nvmath/bindings/nvpl/_internal/__init__.pxd +0 -0
  77. nvmath/bindings/nvpl/_internal/__init__.py +0 -0
  78. nvmath/bindings/nvpl/_internal/fft.pxd +36 -0
  79. nvmath/bindings/nvpl/cyfft.pxd +87 -0
  80. nvmath/bindings/nvpl/fft.pxd +100 -0
  81. nvmath/bindings/nvshmem.pxd +54 -0
  82. nvmath/device/__init__.py +23 -0
  83. nvmath/device/_deprecated.py +33 -0
  84. nvmath/device/caching.py +51 -0
  85. nvmath/device/common.py +131 -0
  86. nvmath/device/common_backend.py +125 -0
  87. nvmath/device/common_cuda.py +156 -0
  88. nvmath/device/common_mathdx.py +97 -0
  89. nvmath/device/common_numba.py +159 -0
  90. nvmath/device/common_opaque_tensor.py +128 -0
  91. nvmath/device/cublasdx.py +1085 -0
  92. nvmath/device/cublasdx_backend.py +552 -0
  93. nvmath/device/cublasdx_numba.py +528 -0
  94. nvmath/device/cufftdx.py +551 -0
  95. nvmath/device/cufftdx_backend.py +194 -0
  96. nvmath/device/cufftdx_numba.py +123 -0
  97. nvmath/device/curand_kernel.py +9147 -0
  98. nvmath/device/nvrtc.py +95 -0
  99. nvmath/device/patch.py +35 -0
  100. nvmath/device/random.py +417 -0
  101. nvmath/device/random_helpers.py +23 -0
  102. nvmath/device/random_states.py +189 -0
  103. nvmath/device/types.py +11 -0
  104. nvmath/device/vector_types_numba.py +203 -0
  105. nvmath/distributed/__init__.py +117 -0
  106. nvmath/distributed/_internal/__init__.py +0 -0
  107. nvmath/distributed/_internal/nvshmem.py +243 -0
  108. nvmath/distributed/_internal/tensor_ifc_cupy.py +111 -0
  109. nvmath/distributed/_internal/tensor_ifc_numpy.py +53 -0
  110. nvmath/distributed/_internal/tensor_ifc_torch.py +108 -0
  111. nvmath/distributed/_internal/tensor_wrapper.py +59 -0
  112. nvmath/distributed/_utils.py +152 -0
  113. nvmath/distributed/fft/__init__.py +6 -0
  114. nvmath/distributed/fft/_configuration.py +86 -0
  115. nvmath/distributed/fft/fft.py +1737 -0
  116. nvmath/distributed/reshape/__init__.py +6 -0
  117. nvmath/distributed/reshape/_configuration.py +39 -0
  118. nvmath/distributed/reshape/reshape.py +1249 -0
  119. nvmath/fft/__init__.py +7 -0
  120. nvmath/fft/_configuration.py +208 -0
  121. nvmath/fft/_exec_utils.py +116 -0
  122. nvmath/fft/_helpers.py +260 -0
  123. nvmath/fft/fft.py +2346 -0
  124. nvmath/internal/__init__.py +5 -0
  125. nvmath/internal/enum_utils.py +142 -0
  126. nvmath/internal/formatters.py +87 -0
  127. nvmath/internal/mem_limit.py +51 -0
  128. nvmath/internal/package_ifc.py +119 -0
  129. nvmath/internal/package_ifc_cuda.py +43 -0
  130. nvmath/internal/package_ifc_cupy.py +49 -0
  131. nvmath/internal/package_ifc_torch.py +31 -0
  132. nvmath/internal/package_wrapper.py +14 -0
  133. nvmath/internal/tensor_ifc.py +143 -0
  134. nvmath/internal/tensor_ifc_cupy.py +185 -0
  135. nvmath/internal/tensor_ifc_numpy.py +157 -0
  136. nvmath/internal/tensor_ifc_torch.py +115 -0
  137. nvmath/internal/tensor_wrapper.py +160 -0
  138. nvmath/internal/typemaps.py +154 -0
  139. nvmath/internal/utils.py +634 -0
  140. nvmath/linalg/__init__.py +11 -0
  141. nvmath/linalg/_internal/__init__.py +3 -0
  142. nvmath/linalg/_internal/algo_cap_ifc.py +86 -0
  143. nvmath/linalg/_internal/algo_config_ifc.py +87 -0
  144. nvmath/linalg/_internal/enum_to_tuples.py +64 -0
  145. nvmath/linalg/_internal/epilog_protocol.py +738 -0
  146. nvmath/linalg/_internal/matmul_desc_ifc.py +72 -0
  147. nvmath/linalg/_internal/matmul_pref_ifc.py +65 -0
  148. nvmath/linalg/_internal/matrix_layout_ifc.py +59 -0
  149. nvmath/linalg/_internal/typemaps.py +135 -0
  150. nvmath/linalg/_internal/utils.py +96 -0
  151. nvmath/linalg/advanced/__init__.py +8 -0
  152. nvmath/linalg/advanced/_algorithmmod.py +142 -0
  153. nvmath/linalg/advanced/_configuration.py +320 -0
  154. nvmath/linalg/advanced/helpers/__init__.py +5 -0
  155. nvmath/linalg/advanced/helpers/matmul.py +173 -0
  156. nvmath/linalg/advanced/matmulmod.py +2855 -0
  157. nvmath/memory.py +266 -0
  158. nvmath/sparse/__init__.py +18 -0
  159. nvmath/sparse/_internal/__init__.py +21 -0
  160. nvmath/sparse/_internal/common_utils.py +81 -0
  161. nvmath/sparse/_internal/cudss_config_ifc.py +584 -0
  162. nvmath/sparse/_internal/cudss_data_ifc.py +291 -0
  163. nvmath/sparse/_internal/cudss_utils.py +398 -0
  164. nvmath/sparse/_internal/sparse_csr_ifc.py +154 -0
  165. nvmath/sparse/_internal/sparse_format_helpers.py +88 -0
  166. nvmath/sparse/_internal/sparse_tensor_ifc.py +80 -0
  167. nvmath/sparse/advanced/__init__.py +7 -0
  168. nvmath/sparse/advanced/_configuration.py +150 -0
  169. nvmath/sparse/advanced/direct_solver.py +1705 -0
  170. nvmath_python-0.5.0.dist-info/METADATA +122 -0
  171. nvmath_python-0.5.0.dist-info/RECORD +174 -0
  172. nvmath_python-0.5.0.dist-info/WHEEL +5 -0
  173. nvmath_python-0.5.0.dist-info/licenses/LICENSE +177 -0
  174. nvmath_python-0.5.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,154 @@
1
+ # Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use CSR tensors from different libraries.
7
+ """
8
+
9
+ from __future__ import annotations # allows typehint of class methods to return the self class
10
+
11
+ __all__ = ["CSRTensorHolder"]
12
+
13
+ from typing import Literal, TypeVar
14
+
15
+ from .sparse_tensor_ifc import SparseTensorHolder
16
+ from nvmath.internal import tensor_wrapper
17
+ from nvmath.internal.package_ifc import StreamHolder
18
+ from nvmath.internal.tensor_ifc import TensorHolder
19
+
20
+
21
+ """
22
+ A generic type for the third-party CSRTensor which a CSRTensorHolder implementation wraps
23
+ around.
24
+ """
25
+ CSRTensor = TypeVar("CSRTensor")
26
+
27
+
28
+ class CSRTensorHolder(SparseTensorHolder):
29
+ """
30
+ A simple wrapper type for CSR sparse tensors to make the API package-agnostic. The
31
+ naming convention is sparse format name with the suffix "TensorHolder", which convention
32
+ is used in the sparse format helper.
33
+
34
+ Since the implementation is in terms of our dense tensor abstraction, package-specific
35
+ implementation is not needed.
36
+ """
37
+
38
+ _format_name: str = "CSR"
39
+
40
+ def __init__(self, crow_indices, col_indices, values, *, attr_name_map=None, shape=None, tensor=None):
41
+ # tensor is the native tensor.
42
+ self.tensor = tensor
43
+
44
+ # attr_name_map is the canonical attribute name to package attribute name map.
45
+ # It is set when constructing from a tensor, otherwise it is None.
46
+ self._attr_name_map = attr_name_map
47
+
48
+ assert (shape is not None) ^ (tensor is not None), "Internal error."
49
+
50
+ if shape is not None:
51
+ self._shape = shape
52
+ else:
53
+ self._shape = tuple(tensor.shape)
54
+
55
+ # Wrap constituent dense tensors, if required.
56
+ if not isinstance(crow_indices, TensorHolder):
57
+ crow_indices = tensor_wrapper.wrap_operand(crow_indices)
58
+
59
+ if not isinstance(col_indices, TensorHolder):
60
+ col_indices = tensor_wrapper.wrap_operand(col_indices)
61
+
62
+ if not isinstance(values, TensorHolder):
63
+ values = tensor_wrapper.wrap_operand(values)
64
+
65
+ # The wrapped constituent dense tensors.
66
+ self._crow_indices = crow_indices
67
+ self._col_indices = col_indices
68
+ self._values = values
69
+
70
+ # Ensure constituent dense tensors are all on the same device.
71
+ device_ids = {d.device_id for d in (self._crow_indices, self._col_indices, self._values)}
72
+ message = f"Internal error: the arrays defining the sparse format aren't on the same device {device_ids}."
73
+ assert len(device_ids) == 1, message
74
+ self._device_id = device_ids.pop()
75
+
76
+ self._device = self._values.device
77
+
78
+ @classmethod
79
+ def create_from_tensor(cls, tensor, *, attr_name_map=None):
80
+ assert attr_name_map is not None, "Internal error."
81
+
82
+ # tensor is the native tensor.
83
+ crow_indices = attr_name_map["crow_indices"](tensor)
84
+ col_indices = attr_name_map["col_indices"](tensor)
85
+ values = attr_name_map["values"](tensor)
86
+ return CSRTensorHolder(crow_indices, col_indices, values, attr_name_map=attr_name_map, tensor=tensor)
87
+
88
+ @property
89
+ def attr_name_map(self):
90
+ return self._attr_name_map
91
+
92
+ @property
93
+ def device(self):
94
+ return self._device
95
+
96
+ @property
97
+ def device_id(self):
98
+ return self._device_id
99
+
100
+ @property
101
+ def dtype(self):
102
+ return self._values.dtype
103
+
104
+ @property
105
+ def index_type(self):
106
+ return self._crow_indices.dtype
107
+
108
+ @property
109
+ def format_name(self) -> str:
110
+ return CSRTensorHolder._format_name
111
+
112
+ @property
113
+ def num_dimensions(self):
114
+ return len(self._shape)
115
+
116
+ @property
117
+ def shape(self):
118
+ return self._shape
119
+
120
+ @property
121
+ def crow_indices(self) -> TensorHolder:
122
+ """The TensorHolder object wrapping the crow_indices array."""
123
+ return self._crow_indices
124
+
125
+ @property
126
+ def col_indices(self) -> TensorHolder:
127
+ """The TensorHolder object wrapping the col_indices array."""
128
+ return self._col_indices
129
+
130
+ @property
131
+ def values(self) -> TensorHolder:
132
+ """The TensorHolder object wrapping the values array."""
133
+ return self._values
134
+
135
+ def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
136
+ """Copy the CSRTensor representation to a different device.
137
+
138
+ No copy is performed if the CSRTensor is already on the requested device.
139
+ """
140
+
141
+ target_crow_indices = self.crow_indices.to(device_id=device_id, stream_holder=stream_holder)
142
+ target_col_indices = self.col_indices.to(device_id=device_id, stream_holder=stream_holder)
143
+ target_values = self.values.to(device_id=device_id, stream_holder=stream_holder)
144
+
145
+ return CSRTensorHolder(
146
+ target_crow_indices, target_col_indices, target_values, attr_name_map=self.attr_name_map, shape=self.shape
147
+ )
148
+
149
+ def copy_(self, src, stream_holder: StreamHolder | None) -> None:
150
+ """Overwrite self.tensor (in-place) with a copy of src (CSRTensor)."""
151
+
152
+ self.crow_indices.copy_(src=src.crow_indices, stream_holder=stream_holder)
153
+ self.col_indices.copy_(src=src.col_indices, stream_holder=stream_holder)
154
+ self.values.copy_(src=src.values, stream_holder=stream_holder)
@@ -0,0 +1,88 @@
1
+ # Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Package-agnostic interface for key sparse tensor attributes.
7
+ """
8
+
9
+ __all__ = ["PACKAGE_HELPER_MAP", "CupySparseFormatHelper", "ScipySparseFormatHelper", "TorchSparseFormatHelper"]
10
+
11
+ from abc import ABC, abstractmethod
12
+
13
+ import re
14
+
15
+
16
+ class SparseFormatHelper(ABC):
17
+ @staticmethod
18
+ @abstractmethod
19
+ def sparse_format_name(tensor):
20
+ raise NotImplementedError
21
+
22
+ # Attribute name map: canonical name <> package name.
23
+ # One for each named sparse format type.
24
+ @staticmethod
25
+ @abstractmethod
26
+ def csr_attribute_names():
27
+ raise NotImplementedError
28
+
29
+ # A ctor for each named sparse format type.
30
+ @staticmethod
31
+ @abstractmethod
32
+ def create_csr(shape, crow_indices, col_indices, values):
33
+ raise NotImplementedError
34
+
35
+
36
+ class TorchSparseFormatHelper(SparseFormatHelper):
37
+ @staticmethod
38
+ def sparse_format_name(tensor):
39
+ name = re.sub(r"^torch\.sparse_", "", str(tensor.layout)).upper()
40
+ return name
41
+
42
+ @staticmethod
43
+ def csr_attribute_names():
44
+ return {
45
+ "crow_indices": lambda a: a.crow_indices(),
46
+ "col_indices": lambda a: a.col_indices(),
47
+ "values": lambda a: a.values(),
48
+ }
49
+
50
+ @staticmethod
51
+ def create_csr(shape, crow_indices, col_indices, values):
52
+ # import torch
53
+ # return torch.sparse_csr_tensor(crow_indices.tensor, col_indices.tensor,
54
+ # values.tensor, shape, device=values.device_id)
55
+ raise NotImplementedError
56
+
57
+
58
+ class CupySparseFormatHelper(SparseFormatHelper):
59
+ @staticmethod
60
+ def sparse_format_name(tensor):
61
+ name = re.sub(r"_(array|matrix)$", "", type(tensor).__name__).upper()
62
+ return name
63
+
64
+ @staticmethod
65
+ def csr_attribute_names():
66
+ return {"crow_indices": lambda a: a.indptr, "col_indices": lambda a: a.indices, "values": lambda a: a.data}
67
+
68
+ @staticmethod
69
+ def create_csr(shape, crow_indices, col_indices, values):
70
+ raise NotImplementedError
71
+
72
+
73
+ class ScipySparseFormatHelper(SparseFormatHelper):
74
+ @staticmethod
75
+ def sparse_format_name(tensor):
76
+ name = re.sub(r"_(array|matrix)$", "", type(tensor).__name__).upper()
77
+ return name
78
+
79
+ @staticmethod
80
+ def csr_attribute_names():
81
+ return {"crow_indices": lambda a: a.indptr, "col_indices": lambda a: a.indices, "values": lambda a: a.data}
82
+
83
+ @staticmethod
84
+ def create_csr(shape, crow_indices, col_indices, values):
85
+ raise NotImplementedError
86
+
87
+
88
+ PACKAGE_HELPER_MAP = {"cupyx": CupySparseFormatHelper, "scipy": ScipySparseFormatHelper, "torch": TorchSparseFormatHelper}
@@ -0,0 +1,80 @@
1
+ # Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ """
6
+ Interface to seamlessly use sparse tensors from different libraries.
7
+ """
8
+
9
+ from __future__ import annotations # allows typehint of class methods to return the self class
10
+
11
+ __all__ = ["SparseTensorHolder"]
12
+
13
+
14
+ from abc import ABC, abstractmethod
15
+ from typing import Literal
16
+
17
+ from nvmath.internal.package_ifc import StreamHolder
18
+
19
+
20
+ class SparseTensorHolder(ABC):
21
+ """
22
+ A simple base type for attributes common to *all* sparse formats.
23
+ """
24
+
25
+ @classmethod
26
+ @abstractmethod
27
+ def create_from_tensor(cls, attr_name_map, tensor):
28
+ raise NotImplementedError
29
+
30
+ @property
31
+ @abstractmethod
32
+ def attr_name_map(self):
33
+ raise NotImplementedError
34
+
35
+ @property
36
+ @abstractmethod
37
+ def device(self):
38
+ raise NotImplementedError
39
+
40
+ @property
41
+ @abstractmethod
42
+ def device_id(self):
43
+ raise NotImplementedError
44
+
45
+ @property
46
+ @abstractmethod
47
+ def dtype(self):
48
+ raise NotImplementedError
49
+
50
+ @property
51
+ @abstractmethod
52
+ def index_type(self):
53
+ raise NotImplementedError
54
+
55
+ @property
56
+ @abstractmethod
57
+ def format_name(self) -> str:
58
+ raise NotImplementedError
59
+
60
+ @property
61
+ @abstractmethod
62
+ def num_dimensions(self):
63
+ raise NotImplementedError
64
+
65
+ @property
66
+ @abstractmethod
67
+ def shape(self):
68
+ raise NotImplementedError
69
+
70
+ @abstractmethod
71
+ def to(self, device_id: int | Literal["cpu"], stream_holder: StreamHolder | None):
72
+ """Copy the SparseTensor representation to a different device.
73
+
74
+ No copy is performed if the SparseTensor is already on the requested device.
75
+ """
76
+ raise NotImplementedError
77
+
78
+ def copy_(self, src: SparseTensorHolder, stream_holder: StreamHolder | None) -> None:
79
+ """Overwrite the sparse tensor (in-place) with a copy of src."""
80
+ raise NotImplementedError
@@ -0,0 +1,7 @@
1
+ # Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from ._configuration import * # noqa: F403
6
+ from .direct_solver import * # noqa: F403
7
+ from .._internal.cudss_data_ifc import memory_estimates_dtype # noqa: F401
@@ -0,0 +1,150 @@
1
+ # Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ __all__ = [
6
+ "DirectSolverOptions",
7
+ "DirectSolverMatrixType",
8
+ "DirectSolverMatrixViewType",
9
+ "ExecutionCUDA",
10
+ "ExecutionHybrid",
11
+ "HybridMemoryModeOptions",
12
+ ]
13
+
14
+
15
+ from dataclasses import dataclass, field
16
+ from logging import Logger
17
+ from typing import ClassVar, Literal, TypeAlias
18
+
19
+ from nvmath.bindings import cudss
20
+ from nvmath.internal import mem_limit
21
+
22
+ DirectSolverMatrixType: TypeAlias = cudss.MatrixType
23
+ DirectSolverMatrixViewType: TypeAlias = cudss.MatrixViewType
24
+
25
+
26
+ @dataclass
27
+ class HybridMemoryModeOptions:
28
+ """
29
+ A data class for providing options related to the use of hybrid (CPU-GPU) memory to
30
+ those execution spaces that support it.
31
+
32
+ Attributes:
33
+ hybrid_memory_mode: If set to True, use CPU memory to store factors (default:
34
+ ``False``). See :attr:`nvmath.bindings.cudss.ConfigParam.HYBRID_MODE`.
35
+ device_memory_limit: The maximum device memory available for execution. It can
36
+ be specified as a value (with optional suffix like K[iB], M[iB], G[iB]) or as a
37
+ percentage. The default is based on internal heuristics. See
38
+ :attr:`nvmath.bindings.cudss.ConfigParam.HYBRID_DEVICE_MEMORY_LIMIT`.
39
+ register_cuda_memory: Specify whether to register memory using
40
+ ``cudaHostRegister()`` if hybrid memory mode is used. The default is
41
+ ``True``. See
42
+ :attr:`nvmath.bindings.cudss.ConfigParam.USE_CUDA_REGISTER_MEMORY`.
43
+
44
+ See Also:
45
+ :class:`ExecutionHybrid`, :class:`DirectSolver`, :func:`direct_solver`.
46
+ """
47
+
48
+ hybrid_memory_mode: bool = False
49
+ hybrid_device_memory_limit: int | str | None = None # Internal heuristic.
50
+ register_cuda_memory: bool = True
51
+
52
+ def __post_init__(self):
53
+ if self.hybrid_device_memory_limit is not None:
54
+ mem_limit.check_memory_str(self.hybrid_device_memory_limit, "hybrid device memory limit")
55
+
56
+
57
+ @dataclass
58
+ class ExecutionCUDA:
59
+ """
60
+ A data class for providing GPU execution options to the :class:`DirectSolver`
61
+ object and the wrapper function :func:`direct_solver`.
62
+
63
+ Attributes:
64
+ device_id: CUDA device ordinal (only used if the operand resides on the CPU). The
65
+ default value is 0.
66
+ hybrid_memory_mode_options: Options controlling the use of hybrid (CPU-GPU) memory
67
+ as an object of type :class:`HybridMemoryModeOptions` or a `dict`.
68
+
69
+ See Also:
70
+ :class:`ExecutionHybrid`, :class:`HybridMemoryModeOptions`, :class:`DirectSolver`,
71
+ :func:`direct_solver`.
72
+ """
73
+
74
+ name: ClassVar[Literal["cuda"]] = "cuda"
75
+ device_id: int = 0
76
+ hybrid_memory_mode_options: object = field(default_factory=HybridMemoryModeOptions)
77
+
78
+
79
+ @dataclass
80
+ class ExecutionHybrid:
81
+ """
82
+ A data class for providing hybrid (CPU-GPU) execution options to the
83
+ :class:`DirectSolver` object and the wrapper function :func:`direct_solver`.
84
+
85
+ Attributes:
86
+ device_id: CUDA device ordinal (only used if the operand resides on the CPU). The
87
+ default value is 0.
88
+ num_threads: The number of CPU threads used to execute the plan.
89
+ If not specified, defaults to the number of CPU cores available to the process.
90
+
91
+ See Also:
92
+ :class:`ExecutionCUDA`, :class:`DirectSolver`, :func:`direct_solver`.
93
+ """
94
+
95
+ name: ClassVar[Literal["hybrid"]] = "hybrid"
96
+ device_id: int = 0
97
+ num_threads: int | None = None
98
+
99
+
100
+ # TODO: docstring
101
+ @dataclass
102
+ class DirectSolverOptions:
103
+ """
104
+ A data class for providing options to the :class:`DirectSolver` object and the wrapper
105
+ function :func:`direct_solver`.
106
+
107
+ Attributes:
108
+ sparse_system_type (:class:`DirectSolverMatrixType`): The type of the sparse
109
+ system of equations (general, symmetric, symmetric positive definite, etc).
110
+ The default is ``DirectSolverMatrixType.GENERAL``.
111
+
112
+ sparse_system_view (:class:`DirectSolverMatrixViewType`): The desired view of the
113
+ sparse system of equations (full, upper, lower). The default is
114
+ ``DirectSolverMatrixViewType.FULL``.
115
+
116
+ multithreading_lib: The location (full path) to the library implementing the
117
+ threading layer interface. **TODO**: link to docs and default pip path.
118
+
119
+ logger (logging.Logger): Python Logger object. The root logger will be used if a
120
+ logger object is not provided.
121
+
122
+ blocking: A flag specifying the behavior of the execution functions and methods,
123
+ such as :func:`direct_solver` and :meth:`DirectSolver.solve`.
124
+ When ``blocking`` is `True`, the execution methods do not return until the
125
+ operation is complete. When
126
+ ``blocking`` is ``"auto"``, the methods return immediately when the input tensor
127
+ is on the GPU and ``execution`` is set to 'CUDA'. The execution methods always
128
+ block when the input tensor is on the CPU or ``execution`` is specified to 'CPU'
129
+ to ensure that the user doesn't inadvertently use the result before it becomes
130
+ available. The default is ``"auto"``.
131
+
132
+ handle: cuDSS library handle. A handle will be created if one is not provided.
133
+
134
+ See Also:
135
+ :class:`ExecutionCUDA`, :class:`ExecutionHybrid`, :class:`DirectSolver`, and
136
+ :func:`direct_solver`.
137
+ """
138
+
139
+ sparse_system_type: int = DirectSolverMatrixType.GENERAL
140
+ sparse_system_view: int = DirectSolverMatrixViewType.FULL
141
+ multithreading_lib: str | None = None
142
+ logger: Logger | None = None
143
+ blocking: Literal[True, "auto"] = "auto"
144
+ handle: int | None = None
145
+
146
+ def __post_init__(self):
147
+ if self.blocking not in (True, "auto"):
148
+ raise ValueError("The value specified for 'blocking' must be either True or 'auto'.")
149
+ self.sparse_system_type = DirectSolverMatrixType(self.sparse_system_type)
150
+ self.sparse_system_view = DirectSolverMatrixViewType(self.sparse_system_view)