vramsuite 0.5.0__py3-none-any.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 (49) hide show
  1. vramsuite/__init__.py +18 -0
  2. vramsuite/__main__.py +59 -0
  3. vramsuite/backends/__init__.py +0 -0
  4. vramsuite/backends/cublas.py +281 -0
  5. vramsuite/backends/cublaslt/__init__.py +44 -0
  6. vramsuite/backends/cublaslt/descriptors.py +243 -0
  7. vramsuite/backends/cublaslt/enums.py +52 -0
  8. vramsuite/backends/cublaslt/errors.py +29 -0
  9. vramsuite/backends/cublaslt/heuristics.py +139 -0
  10. vramsuite/backends/cublaslt/layouts.py +159 -0
  11. vramsuite/backends/cublaslt/matmul.py +69 -0
  12. vramsuite/backends/cublaslt/runtime.py +296 -0
  13. vramsuite/backends/cublaslt/workspace.py +41 -0
  14. vramsuite/backends/cuda.py +511 -0
  15. vramsuite/backends/cuda_driver.py +267 -0
  16. vramsuite/backends/native_loader.py +153 -0
  17. vramsuite/backends/nvml.py +504 -0
  18. vramsuite/backends/windows_gpu.py +206 -0
  19. vramsuite/cli/__init__.py +0 -0
  20. vramsuite/cli/main.py +591 -0
  21. vramsuite/compute/__init__.py +0 -0
  22. vramsuite/compute/compute_math.py +142 -0
  23. vramsuite/compute/cublaslt_math.py +327 -0
  24. vramsuite/compute/minifloat.py +115 -0
  25. vramsuite/compute/validation.py +13 -0
  26. vramsuite/core/__init__.py +0 -0
  27. vramsuite/core/advise.py +160 -0
  28. vramsuite/core/bundle.py +103 -0
  29. vramsuite/core/comfy.py +79 -0
  30. vramsuite/core/compare.py +162 -0
  31. vramsuite/core/doctor.py +140 -0
  32. vramsuite/core/estimate.py +176 -0
  33. vramsuite/core/fingerprint.py +95 -0
  34. vramsuite/core/model_inspect.py +135 -0
  35. vramsuite/core/probe.py +180 -0
  36. vramsuite/core/processes.py +190 -0
  37. vramsuite/core/profile.py +197 -0
  38. vramsuite/core/reports.py +618 -0
  39. vramsuite/core/risk.py +127 -0
  40. vramsuite/core/runtime.py +102 -0
  41. vramsuite/core/transfer.py +160 -0
  42. vramsuite/core/validate.py +141 -0
  43. vramsuite/core/vramcard.py +282 -0
  44. vramsuite/core/workflow.py +298 -0
  45. vramsuite-0.5.0.dist-info/METADATA +273 -0
  46. vramsuite-0.5.0.dist-info/RECORD +49 -0
  47. vramsuite-0.5.0.dist-info/WHEEL +4 -0
  48. vramsuite-0.5.0.dist-info/entry_points.txt +2 -0
  49. vramsuite-0.5.0.dist-info/licenses/LICENSE +21 -0
vramsuite/__init__.py ADDED
@@ -0,0 +1,18 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.metadata
4
+
5
+ from vramsuite.core.doctor import run_doctor
6
+ from vramsuite.core.fingerprint import collect_fingerprint
7
+ from vramsuite.core.vramcard import create_vramcard, load_vramcard, save_vramcard
8
+
9
+ __version__ = importlib.metadata.version("vramsuite")
10
+
11
+ __all__ = [
12
+ "__version__",
13
+ "run_doctor",
14
+ "collect_fingerprint",
15
+ "create_vramcard",
16
+ "save_vramcard",
17
+ "load_vramcard",
18
+ ]
vramsuite/__main__.py ADDED
@@ -0,0 +1,59 @@
1
+ """
2
+ `python -m vramsuite` and the entry point of the Windows exe.
3
+
4
+ Double-clicking the exe opens a console that closes as soon as the program
5
+ exits. In that case the exe runs `doctor` and waits for Enter instead of
6
+ printing the help and vanishing.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ import platform
13
+ import sys
14
+ import traceback
15
+
16
+ from vramsuite.cli.main import app
17
+
18
+
19
+ def _started_by_double_click() -> bool:
20
+ """
21
+ True when no other program shares this console: Explorer created it for us.
22
+
23
+ From a terminal, the shell is attached too. The one-file exe runs as two
24
+ processes (the PyInstaller bootloader and its Python child, this one),
25
+ both attached to the console, so the bootloader parent does not count.
26
+ """
27
+ if platform.system() != "Windows":
28
+ return False
29
+ import ctypes
30
+
31
+ kernel32 = ctypes.windll.kernel32
32
+ kernel32.GetConsoleProcessList.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.c_uint32]
33
+ kernel32.GetConsoleProcessList.restype = ctypes.c_uint32
34
+ processes = (ctypes.c_uint32 * 16)()
35
+ count = kernel32.GetConsoleProcessList(processes, 16)
36
+
37
+ ours = {os.getpid()}
38
+ if getattr(sys, "frozen", False):
39
+ ours.add(os.getppid())
40
+ return 0 < count <= 16 and not set(processes[:count]) - ours
41
+
42
+
43
+ def main() -> None:
44
+ if len(sys.argv) == 1 and _started_by_double_click():
45
+ sys.argv += ["doctor", "--no-write-card"]
46
+ try:
47
+ app()
48
+ except SystemExit:
49
+ pass
50
+ except Exception:
51
+ # Show the error instead of a window that closes before it can be read.
52
+ traceback.print_exc()
53
+ input("\nPress Enter to close...")
54
+ return
55
+ app()
56
+
57
+
58
+ if __name__ == "__main__":
59
+ main()
File without changes
@@ -0,0 +1,281 @@
1
+ from __future__ import annotations
2
+
3
+ import ctypes
4
+ import platform
5
+ from dataclasses import asdict, dataclass
6
+ from types import TracebackType
7
+ from typing import Any
8
+
9
+ from vramsuite.backends.cublaslt.errors import decode_cublas_status
10
+ from vramsuite.backends.native_loader import load_native_library
11
+
12
+
13
+ CUBLAS_STATUS_SUCCESS = 0
14
+
15
+ CUBLAS_OP_N = 0
16
+ CUBLAS_OP_T = 1
17
+ CUBLAS_OP_C = 2
18
+
19
+ @dataclass(frozen=True)
20
+ class CublasInfo:
21
+ available: bool
22
+ error: str | None
23
+ library_path: str | None
24
+ handle_created: bool
25
+ version: int | None
26
+ version_text: str | None
27
+
28
+
29
+ def _candidate_library_names() -> list[str]:
30
+ system = platform.system()
31
+
32
+ if system == "Windows":
33
+ return [
34
+ "cublas64_13.dll",
35
+ "cublas64_12.dll",
36
+ "cublas64_11.dll",
37
+ ]
38
+
39
+ if system == "Linux":
40
+ return [
41
+ "libcublas.so",
42
+ "libcublas.so.13",
43
+ "libcublas.so.12",
44
+ "libcublas.so.11",
45
+ ]
46
+
47
+ return ["libcublas.so"]
48
+
49
+
50
+ def _check(status: int, operation: str) -> str | None:
51
+ if status == CUBLAS_STATUS_SUCCESS:
52
+ return None
53
+
54
+ return f"{operation} failed: {decode_cublas_status(status)}"
55
+
56
+ def _format_cublas_version(version: int | None) -> str | None:
57
+ if version is None:
58
+ return None
59
+
60
+ major = version // 10000
61
+ minor = (version % 10000) // 100
62
+ patch = version % 100
63
+
64
+ return f"{major}.{minor}.{patch}"
65
+
66
+ def _configure_signatures(cublas: ctypes.CDLL) -> None:
67
+ cublas.cublasCreate_v2.argtypes = [ctypes.POINTER(ctypes.c_void_p)]
68
+ cublas.cublasCreate_v2.restype = ctypes.c_int
69
+
70
+ cublas.cublasDestroy_v2.argtypes = [ctypes.c_void_p]
71
+ cublas.cublasDestroy_v2.restype = ctypes.c_int
72
+
73
+ cublas.cublasGetVersion_v2.argtypes = [
74
+ ctypes.c_void_p,
75
+ ctypes.POINTER(ctypes.c_int),
76
+ ]
77
+ cublas.cublasGetVersion_v2.restype = ctypes.c_int
78
+
79
+ cublas.cublasSgemm_v2.argtypes = [
80
+ ctypes.c_void_p, # handle
81
+ ctypes.c_int, # transa
82
+ ctypes.c_int, # transb
83
+ ctypes.c_int, # m
84
+ ctypes.c_int, # n
85
+ ctypes.c_int, # k
86
+ ctypes.POINTER(ctypes.c_float), # alpha
87
+ ctypes.c_void_p, # A
88
+ ctypes.c_int, # lda
89
+ ctypes.c_void_p, # B
90
+ ctypes.c_int, # ldb
91
+ ctypes.POINTER(ctypes.c_float), # beta
92
+ ctypes.c_void_p, # c
93
+ ctypes.c_int, # ldc
94
+ ]
95
+ cublas.cublasSgemm_v2.restype = ctypes.c_int
96
+
97
+
98
+ class CublasRuntime:
99
+ def __init__(self) -> None:
100
+ self._native_library = None
101
+ self.cublas: ctypes.CDLL | None = None
102
+ self.library_path: str | None = None
103
+ self.handle: ctypes.c_void_p | None = None
104
+
105
+ def __enter__(self) -> "CublasRuntime":
106
+ venv_patterns = (
107
+ ["cublas*.dll"]
108
+ if platform.system() == "Windows"
109
+ else ["libcublas.so*"]
110
+ )
111
+
112
+ self._native_library = load_native_library(
113
+ logical_name="cublas",
114
+ candidates=_candidate_library_names(),
115
+ venv_patterns=venv_patterns,
116
+ )
117
+
118
+ try:
119
+ loaded = self._native_library.__enter__()
120
+
121
+ self.cublas = loaded.require_library()
122
+ self.library_path = loaded.library_path
123
+
124
+ _configure_signatures(self.cublas)
125
+
126
+ self.handle = self._create_handle()
127
+
128
+ return self
129
+
130
+ except Exception:
131
+ if self._native_library is not None:
132
+ self._native_library.__exit__(None, None, None)
133
+
134
+ self._native_library = None
135
+ self.cublas = None
136
+ self.library_path = None
137
+ self.handle = None
138
+
139
+ raise
140
+
141
+ def __exit__(
142
+ self,
143
+ exc_type: type[BaseException] | None,
144
+ exc: BaseException | None,
145
+ traceback: TracebackType | None,
146
+ ) -> None:
147
+ if self.handle is not None:
148
+ try:
149
+ self._destroy_handle(self.handle)
150
+ finally:
151
+ self.handle = None
152
+
153
+ self.cublas = None
154
+ self.library_path = None
155
+
156
+ if self._native_library is not None:
157
+ self._native_library.__exit__(exc_type, exc, traceback)
158
+
159
+ self._native_library = None
160
+
161
+ def _require_cublas(self) -> ctypes.CDLL:
162
+ if self.cublas is None:
163
+ raise RuntimeError("cuBLAS runtime is not loaded")
164
+
165
+ return self.cublas
166
+
167
+ def _require_handle(self) -> ctypes.c_void_p:
168
+ if self.handle is None:
169
+ raise RuntimeError("cuBLAS handle is not created")
170
+
171
+ return self.handle
172
+
173
+ def _check_status(self, status: int, operation: str) -> None:
174
+ error = _check(status, operation)
175
+ if error is not None:
176
+ raise RuntimeError(error)
177
+
178
+
179
+ def _create_handle(self) -> ctypes.c_void_p:
180
+ cublas = self._require_cublas()
181
+
182
+ handle = ctypes.c_void_p()
183
+ status = cublas.cublasCreate_v2(ctypes.byref(handle))
184
+ self._check_status(status, "cublasCreate_v2")
185
+
186
+ if handle.value is None:
187
+ raise RuntimeError("cublasCreate_v2 returned NULL handle")
188
+
189
+
190
+ return handle
191
+
192
+ def _destroy_handle(self, handle: ctypes.c_void_p) -> None:
193
+ cublas = self._require_cublas()
194
+
195
+ status = cublas.cublasDestroy_v2(handle)
196
+ self._check_status(status, "cublasDestroy_v2")
197
+
198
+ def get_version(self) -> int:
199
+ cublas = self._require_cublas()
200
+ handle = self._require_handle()
201
+
202
+ version = ctypes.c_int()
203
+ status = cublas.cublasGetVersion_v2(handle, ctypes.byref(version))
204
+ self._check_status(status, "cublasGetVersion_v2")
205
+
206
+ return int(version.value)
207
+
208
+ def sgemm(
209
+ self,
210
+ *,
211
+ m: int,
212
+ n: int,
213
+ k: int,
214
+ alpha: float,
215
+ a_ptr: ctypes.c_void_p,
216
+ lda: int,
217
+ b_ptr: ctypes.c_void_p,
218
+ ldb: int,
219
+ beta: float,
220
+ c_ptr: ctypes.c_void_p,
221
+ ldc: int,
222
+ transa: int = CUBLAS_OP_N,
223
+ transb: int = CUBLAS_OP_N,
224
+ ) -> None:
225
+ cublas = self._require_cublas()
226
+ handle = self._require_handle()
227
+
228
+ alpha_value = ctypes.c_float(alpha)
229
+ beta_value = ctypes.c_float(beta)
230
+
231
+ status = cublas.cublasSgemm_v2(
232
+ handle,
233
+ transa,
234
+ transb,
235
+ m,
236
+ n,
237
+ k,
238
+ ctypes.byref(alpha_value),
239
+ a_ptr,
240
+ lda,
241
+ b_ptr,
242
+ ldb,
243
+ ctypes.byref(beta_value),
244
+ c_ptr,
245
+ ldc,
246
+ )
247
+
248
+ self._check_status(status, "cublasSgemm_v2")
249
+
250
+
251
+ def collect_info(self) -> CublasInfo:
252
+ version = self.get_version()
253
+
254
+ return CublasInfo(
255
+ available=True,
256
+ error=None,
257
+ library_path=self.library_path,
258
+ handle_created=self.handle is not None and self.handle.value is not None,
259
+ version=version,
260
+ version_text=_format_cublas_version(version),
261
+ )
262
+
263
+
264
+
265
+ def collect_cublas_info() -> CublasInfo:
266
+ try:
267
+ with CublasRuntime() as runtime:
268
+ return runtime.collect_info()
269
+
270
+ except Exception as exc:
271
+ return CublasInfo(
272
+ available=False,
273
+ error=f"Unexpected cuBLAS runtime backend error: {exc}",
274
+ library_path=None,
275
+ handle_created=False,
276
+ version=None,
277
+ version_text=None
278
+ )
279
+
280
+ def collect_cublas_info_dict() -> dict[str, Any]:
281
+ return asdict(collect_cublas_info())
@@ -0,0 +1,44 @@
1
+ from __future__ import annotations
2
+
3
+ from vramsuite.backends.cublaslt.descriptors import (
4
+ MatmulDesc,
5
+ MatrixLayout,
6
+ MatmulPreference,
7
+ )
8
+ from vramsuite.backends.cublaslt.runtime import (
9
+ CublasLtInfo,
10
+ CublasLtRuntime,
11
+ collect_cublaslt_info,
12
+ collect_cublaslt_info_dict,
13
+ )
14
+
15
+ from vramsuite.backends.cublaslt.layouts import (
16
+ GemmShape,
17
+ MatrixLayoutSpec,
18
+ MatmulLayoutSpec,
19
+ )
20
+ from vramsuite.backends.cublaslt.workspace import DeviceWorkspace
21
+
22
+ from vramsuite.backends.cublaslt.heuristics import (
23
+ RawMatmulHeuristic,
24
+ select_matmul_algorithm,
25
+ )
26
+
27
+ from vramsuite.backends.cublaslt.matmul import run_cublaslt_matmul
28
+
29
+ __all__ = [
30
+ "CublasLtInfo",
31
+ "CublasLtRuntime",
32
+ "collect_cublaslt_info",
33
+ "collect_cublaslt_info_dict",
34
+ "MatmulDesc",
35
+ "MatrixLayout",
36
+ "MatmulPreference",
37
+ "GemmShape",
38
+ "MatrixLayoutSpec",
39
+ "MatmulLayoutSpec",
40
+ "DeviceWorkspace",
41
+ "RawMatmulHeuristic",
42
+ "select_matmul_algorithm",
43
+ "run_cublaslt_matmul",
44
+ ]
@@ -0,0 +1,243 @@
1
+ from __future__ import annotations
2
+
3
+ import ctypes
4
+ from types import TracebackType
5
+
6
+ from vramsuite.backends.cublaslt.enums import (
7
+ CUBLAS_COMPUTE_32F,
8
+ CUBLAS_OP_N,
9
+ CUBLASLT_MATMUL_DESC_TRANSA,
10
+ CUBLASLT_MATMUL_DESC_TRANSB,
11
+ CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES,
12
+ CUDA_R_32F,
13
+ )
14
+ from vramsuite.backends.cublaslt.errors import check_cublas_status
15
+ from vramsuite.backends.cublaslt.runtime import CublasLtRuntime
16
+
17
+
18
+
19
+ class CublasLtDescriptor:
20
+ def __init__(self, runtime: CublasLtRuntime) -> None:
21
+ self.runtime = runtime
22
+ self.ptr: ctypes.c_void_p | None = None
23
+
24
+ def _require_cublaslt(self) -> ctypes.CDLL:
25
+ if self.runtime.cublaslt is None:
26
+ raise RuntimeError("cuBLASLt runtime is not loaded")
27
+
28
+ return self.runtime.cublaslt
29
+
30
+ def _require_ptr(self) -> ctypes.c_void_p:
31
+ if self.ptr is None or self.ptr.value is None:
32
+ raise RuntimeError(f"{self.__class__.__name__} is not created")
33
+
34
+ return self.ptr
35
+
36
+ def __enter__(self):
37
+ self.create()
38
+ return self
39
+
40
+ def __exit__(
41
+ self,
42
+ exc_type: type[BaseException] | None,
43
+ exc: BaseException | None,
44
+ traceback: TracebackType | None,
45
+ ) -> None:
46
+ self.destroy()
47
+
48
+
49
+ class MatmulDesc(CublasLtDescriptor):
50
+ def __init__(
51
+ self,
52
+ runtime: CublasLtRuntime,
53
+ *,
54
+ compute_type: int = CUBLAS_COMPUTE_32F,
55
+ scale_type: int = CUDA_R_32F,
56
+ transa: int = CUBLAS_OP_N,
57
+ transb: int = CUBLAS_OP_N,
58
+ ) -> None:
59
+ super().__init__(runtime)
60
+ self.compute_type = compute_type
61
+ self.scale_type = scale_type
62
+ self.transa = transa
63
+ self.transb = transb
64
+
65
+ def create(self) -> None:
66
+ if self.ptr is not None:
67
+ return
68
+
69
+ cublaslt = self._require_cublaslt()
70
+
71
+ desc = ctypes.c_void_p()
72
+ status = cublaslt.cublasLtMatmulDescCreate(
73
+ ctypes.byref(desc),
74
+ self.compute_type,
75
+ self.scale_type,
76
+ )
77
+ check_cublas_status(status, "cublasLtMatmulDescCreate")
78
+
79
+ if desc.value is None:
80
+ raise RuntimeError("cublasLtMatmulDescCreate returned NULL descriptor")
81
+
82
+ self.ptr = desc
83
+
84
+ try:
85
+ self.set_int32_attribute(CUBLASLT_MATMUL_DESC_TRANSA, self.transa)
86
+ self.set_int32_attribute(CUBLASLT_MATMUL_DESC_TRANSB, self.transb)
87
+ except Exception:
88
+ # __exit__ is not called when __enter__ raises, so destroy here.
89
+ self.destroy()
90
+ raise
91
+
92
+ def set_int32_attribute(self, attr: int, value: int) -> None:
93
+ cublaslt = self._require_cublaslt()
94
+ desc = self._require_ptr()
95
+
96
+ raw = ctypes.c_int32(value)
97
+ status = cublaslt.cublasLtMatmulDescSetAttribute(
98
+ desc,
99
+ attr,
100
+ ctypes.cast(ctypes.byref(raw), ctypes.c_void_p),
101
+ ctypes.sizeof(raw),
102
+ )
103
+ check_cublas_status(status, "cublasLtMatmulDescSetAttribute")
104
+
105
+ def destroy(self) -> None:
106
+ if self.ptr is None:
107
+ return
108
+
109
+ cublaslt = self._require_cublaslt()
110
+
111
+ try:
112
+ status = cublaslt.cublasLtMatmulDescDestroy(self.ptr)
113
+ check_cublas_status(status, "cublasLtMatmulDescDestroy")
114
+ finally:
115
+ self.ptr = None
116
+
117
+ class MatrixLayout(CublasLtDescriptor):
118
+ def __init__(
119
+ self,
120
+ runtime: CublasLtRuntime,
121
+ *,
122
+ data_type: int = CUDA_R_32F,
123
+ rows: int,
124
+ cols: int,
125
+ ld: int,
126
+ ) -> None:
127
+ super().__init__(runtime)
128
+ self.data_type = data_type
129
+ self.rows = rows
130
+ self.cols = cols
131
+ self.ld = ld
132
+
133
+ def create(self) -> None:
134
+ if self.ptr is not None:
135
+ return
136
+
137
+ if self.rows <= 0:
138
+ raise ValueError("rows must be positive")
139
+ if self.cols <= 0:
140
+ raise ValueError("cols must be positive")
141
+ if self.ld <= 0:
142
+ raise ValueError("ld must be positive")
143
+ if self.ld < self.rows:
144
+ raise ValueError("ld must be >= rows for column-major layout")
145
+
146
+
147
+ cublaslt = self._require_cublaslt()
148
+
149
+ layout = ctypes.c_void_p()
150
+ status = cublaslt.cublasLtMatrixLayoutCreate(
151
+ ctypes.byref(layout),
152
+ self.data_type,
153
+ self.rows,
154
+ self.cols,
155
+ self.ld,
156
+ )
157
+ check_cublas_status(status, "cublasLtMatrixLayoutCreate")
158
+
159
+ if layout.value is None:
160
+ raise RuntimeError("cublasLtMatrixLayoutCreate returned NULL descriptor")
161
+
162
+ self.ptr = layout
163
+
164
+ def destroy(self) -> None:
165
+ if self.ptr is None:
166
+ return
167
+
168
+ cublaslt = self._require_cublaslt()
169
+
170
+ try:
171
+ status = cublaslt.cublasLtMatrixLayoutDestroy(self.ptr)
172
+ check_cublas_status(status, "cublasLtMatrixLayoutDestroy")
173
+ finally:
174
+ self.ptr = None
175
+
176
+
177
+ class MatmulPreference(CublasLtDescriptor):
178
+ def __init__(
179
+ self,
180
+ runtime: CublasLtRuntime,
181
+ *,
182
+ max_workspace_bytes: int = 0,
183
+ ) -> None:
184
+ super().__init__(runtime)
185
+ self.max_workspace_bytes = max_workspace_bytes
186
+
187
+
188
+ def create(self) -> None:
189
+ if self.ptr is not None:
190
+ return
191
+
192
+ if self.max_workspace_bytes < 0:
193
+ raise ValueError("max_workspace_bytes must be >= 0")
194
+
195
+ cublaslt = self._require_cublaslt()
196
+
197
+ pref = ctypes.c_void_p()
198
+ status = cublaslt.cublasLtMatmulPreferenceCreate(ctypes.byref(pref))
199
+ check_cublas_status(status, "cublasLtMatmulPreferenceCreate")
200
+
201
+ if pref.value is None:
202
+ raise RuntimeError("cublasLtMatmulPreferenceCreate returned NULL descriptor")
203
+
204
+ self.ptr = pref
205
+
206
+ try:
207
+ self.set_max_workspace_bytes(self.max_workspace_bytes)
208
+ except Exception:
209
+ # __exit__ is not called when __enter__ raises, so destroy here.
210
+ self.destroy()
211
+ raise
212
+
213
+ def destroy(self) -> None:
214
+ if self.ptr is None:
215
+ return
216
+
217
+ cublaslt = self._require_cublaslt()
218
+
219
+ try:
220
+ status = cublaslt.cublasLtMatmulPreferenceDestroy(self.ptr)
221
+ check_cublas_status(status, "cublasLtMatmulPreferenceDestroy")
222
+ finally:
223
+ self.ptr = None
224
+
225
+ def set_max_workspace_bytes(self, value: int) -> None:
226
+ if value < 0:
227
+ raise ValueError("max workspace bytes must be >= 0")
228
+
229
+ cublaslt = self._require_cublaslt()
230
+ pref = self._require_ptr()
231
+
232
+ workspace_value = ctypes.c_uint64(value)
233
+ workspace_ptr = ctypes.cast(ctypes.byref(workspace_value), ctypes.c_void_p)
234
+
235
+ status = cublaslt.cublasLtMatmulPreferenceSetAttribute(
236
+ pref,
237
+ CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES,
238
+ workspace_ptr,
239
+ ctypes.sizeof(workspace_value),
240
+ )
241
+ check_cublas_status(status, "cublasLtMatmulPreferenceSetAttribute")
242
+
243
+ self.max_workspace_bytes = value
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+
4
+
5
+
6
+
7
+ # cudaDataType_t
8
+ CUDA_R_32F = 0
9
+ CUDA_R_64F = 1
10
+ CUDA_R_16F = 2
11
+ CUDA_R_8I = 3
12
+ CUDA_C_32F = 4
13
+ CUDA_C_64F = 5
14
+ CUDA_C_16F = 6
15
+ CUDA_R_8U = 8
16
+ CUDA_R_32I = 10
17
+ CUDA_R_32U = 11
18
+ CUDA_R_16BF = 14
19
+ CUDA_R_8F_E4M3 = 28
20
+ CUDA_R_8F_E5M2 = 29
21
+ CUDA_R_8F_UE8M0 = 30
22
+ CUDA_R_4F_E2M1 = 33
23
+
24
+
25
+ # cublasComputeType_t
26
+ CUBLAS_COMPUTE_16F = 64
27
+ CUBLAS_COMPUTE_16F_PEDANTIC = 65
28
+ CUBLAS_COMPUTE_32F = 68
29
+ CUBLAS_COMPUTE_32F_PEDANTIC = 69
30
+ CUBLAS_COMPUTE_64F = 70
31
+ CUBLAS_COMPUTE_64F_PEDANTIC = 71
32
+ CUBLAS_COMPUTE_32I = 72
33
+ CUBLAS_COMPUTE_32I_PEDANTIC = 73
34
+ CUBLAS_COMPUTE_32F_FAST_16F = 74
35
+ CUBLAS_COMPUTE_32F_FAST_16BF = 75
36
+ CUBLAS_COMPUTE_32F_FAST_TF32 = 77
37
+
38
+
39
+ # cublasOperation_t
40
+ CUBLAS_OP_N = 0
41
+ CUBLAS_OP_T = 1
42
+ CUBLAS_OP_C = 2
43
+
44
+
45
+ # cublasLtMatmulDescAttributes_t
46
+ CUBLASLT_MATMUL_DESC_TRANSA = 3
47
+ CUBLASLT_MATMUL_DESC_TRANSB = 4
48
+
49
+
50
+ # cublasLtMatmulPreferenceAttributes_t
51
+ CUBLASLT_MATMUL_PREF_SEARCH_MODE = 0
52
+ CUBLASLT_MATMUL_PREF_MAX_WORKSPACE_BYTES = 1