tricoder 1.2.8__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.
- tricoder/__about__.py +6 -0
- tricoder/__init__.py +19 -0
- tricoder/calibration.py +276 -0
- tricoder/cli.py +890 -0
- tricoder/context_view.py +228 -0
- tricoder/data_loader.py +144 -0
- tricoder/extract.py +622 -0
- tricoder/fusion.py +203 -0
- tricoder/git_tracker.py +203 -0
- tricoder/gpu_utils.py +414 -0
- tricoder/graph_view.py +583 -0
- tricoder/model.py +476 -0
- tricoder/optimize.py +263 -0
- tricoder/subtoken_utils.py +196 -0
- tricoder/train.py +857 -0
- tricoder/typed_view.py +313 -0
- tricoder-1.2.8.dist-info/METADATA +306 -0
- tricoder-1.2.8.dist-info/RECORD +22 -0
- tricoder-1.2.8.dist-info/WHEEL +4 -0
- tricoder-1.2.8.dist-info/entry_points.txt +3 -0
- tricoder-1.2.8.dist-info/licenses/LICENSE +56 -0
- tricoder-1.2.8.dist-info/licenses/LICENSE_COMMERCIAL.md +68 -0
tricoder/gpu_utils.py
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
"""GPU acceleration utilities using CuPy (CUDA) or PyTorch (MPS for Mac)."""
|
|
2
|
+
import warnings
|
|
3
|
+
import platform
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Optional, Tuple
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from scipy import sparse
|
|
9
|
+
|
|
10
|
+
# Try CuPy for CUDA (NVIDIA GPUs)
|
|
11
|
+
try:
|
|
12
|
+
import cupy as cp
|
|
13
|
+
import cupyx.scipy.sparse as cusp
|
|
14
|
+
CUPY_AVAILABLE = True
|
|
15
|
+
except ImportError:
|
|
16
|
+
CUPY_AVAILABLE = False
|
|
17
|
+
cp = None
|
|
18
|
+
cusp = None
|
|
19
|
+
|
|
20
|
+
# Try PyTorch for MPS (Mac GPUs) or CUDA fallback
|
|
21
|
+
try:
|
|
22
|
+
import torch
|
|
23
|
+
TORCH_AVAILABLE = True
|
|
24
|
+
TORCH_VERSION = torch.__version__
|
|
25
|
+
except ImportError:
|
|
26
|
+
TORCH_AVAILABLE = False
|
|
27
|
+
TORCH_VERSION = None
|
|
28
|
+
torch = None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def diagnose_gpu_support() -> dict:
|
|
32
|
+
"""
|
|
33
|
+
Diagnose GPU support availability and provide helpful information.
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Dictionary with diagnostic information
|
|
37
|
+
"""
|
|
38
|
+
diagnostics = {
|
|
39
|
+
'platform': platform.system(),
|
|
40
|
+
'is_mac': platform.system() == 'Darwin',
|
|
41
|
+
'python_version': sys.version,
|
|
42
|
+
'cupy_available': CUPY_AVAILABLE,
|
|
43
|
+
'torch_available': TORCH_AVAILABLE,
|
|
44
|
+
'torch_version': TORCH_VERSION,
|
|
45
|
+
'gpu_backends': []
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Check CuPy/CUDA
|
|
49
|
+
if CUPY_AVAILABLE:
|
|
50
|
+
try:
|
|
51
|
+
_ = cp.array([1, 2, 3])
|
|
52
|
+
device = cp.cuda.Device(0)
|
|
53
|
+
device.use()
|
|
54
|
+
diagnostics['gpu_backends'].append('CUDA (CuPy)')
|
|
55
|
+
except Exception as e:
|
|
56
|
+
diagnostics['cupy_error'] = str(e)
|
|
57
|
+
|
|
58
|
+
# Check PyTorch MPS (Mac)
|
|
59
|
+
if TORCH_AVAILABLE and diagnostics['is_mac']:
|
|
60
|
+
try:
|
|
61
|
+
if hasattr(torch.backends, 'mps') and hasattr(torch.backends.mps, 'is_available'):
|
|
62
|
+
if torch.backends.mps.is_available():
|
|
63
|
+
diagnostics['gpu_backends'].append('MPS (Mac)')
|
|
64
|
+
else:
|
|
65
|
+
diagnostics['mps_unavailable_reason'] = 'MPS backend not available (requires macOS 12.3+ and Apple Silicon)'
|
|
66
|
+
else:
|
|
67
|
+
diagnostics['mps_unavailable_reason'] = f'PyTorch {TORCH_VERSION} does not support MPS (requires PyTorch 1.12+)'
|
|
68
|
+
except Exception as e:
|
|
69
|
+
diagnostics['mps_error'] = str(e)
|
|
70
|
+
|
|
71
|
+
# Check PyTorch CUDA
|
|
72
|
+
if TORCH_AVAILABLE:
|
|
73
|
+
try:
|
|
74
|
+
if torch.cuda.is_available():
|
|
75
|
+
diagnostics['gpu_backends'].append('CUDA (PyTorch)')
|
|
76
|
+
except Exception:
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
return diagnostics
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class GPUAccelerator:
|
|
83
|
+
"""GPU accelerator with automatic CPU fallback. Supports CUDA (NVIDIA) and MPS (Mac)."""
|
|
84
|
+
|
|
85
|
+
def __init__(self, use_gpu: bool = False):
|
|
86
|
+
"""
|
|
87
|
+
Initialize GPU accelerator.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
use_gpu: Whether to attempt GPU acceleration
|
|
91
|
+
"""
|
|
92
|
+
self.use_gpu = False
|
|
93
|
+
self.device_type = None # 'cuda', 'mps', or None
|
|
94
|
+
self.device = None
|
|
95
|
+
self.backend = None # 'cupy' or 'torch'
|
|
96
|
+
|
|
97
|
+
if not use_gpu:
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
# Detect platform and available GPU backends
|
|
101
|
+
is_mac = platform.system() == 'Darwin'
|
|
102
|
+
|
|
103
|
+
# Try CuPy (CUDA) first on non-Mac systems
|
|
104
|
+
if not is_mac and CUPY_AVAILABLE:
|
|
105
|
+
try:
|
|
106
|
+
_ = cp.array([1, 2, 3])
|
|
107
|
+
self.device = cp.cuda.Device(0)
|
|
108
|
+
self.device.use()
|
|
109
|
+
self.use_gpu = True
|
|
110
|
+
self.device_type = 'cuda'
|
|
111
|
+
self.backend = 'cupy'
|
|
112
|
+
return
|
|
113
|
+
except Exception:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
# Try PyTorch MPS (Mac GPU)
|
|
117
|
+
if TORCH_AVAILABLE and is_mac:
|
|
118
|
+
try:
|
|
119
|
+
# Check if MPS backend is available (requires PyTorch 1.12+ and macOS 12.3+)
|
|
120
|
+
if hasattr(torch.backends, 'mps') and hasattr(torch.backends.mps, 'is_available'):
|
|
121
|
+
if torch.backends.mps.is_available():
|
|
122
|
+
self.device = torch.device('mps')
|
|
123
|
+
# Test with a small operation
|
|
124
|
+
test_tensor = torch.tensor([1.0, 2.0, 3.0], device=self.device)
|
|
125
|
+
_ = test_tensor * 2
|
|
126
|
+
self.use_gpu = True
|
|
127
|
+
self.device_type = 'mps'
|
|
128
|
+
self.backend = 'torch'
|
|
129
|
+
return
|
|
130
|
+
else:
|
|
131
|
+
warnings.warn("MPS backend is not available. This requires macOS 12.3+ and Apple Silicon (M1/M2/M3). Falling back to CPU.")
|
|
132
|
+
else:
|
|
133
|
+
warnings.warn("PyTorch MPS backend not available. Please upgrade PyTorch to version 1.12+ for Mac GPU support. Falling back to CPU.")
|
|
134
|
+
except Exception as e:
|
|
135
|
+
warnings.warn(f"MPS GPU acceleration failed: {e}. Falling back to CPU.")
|
|
136
|
+
|
|
137
|
+
# Try PyTorch CUDA as fallback (if available)
|
|
138
|
+
if TORCH_AVAILABLE and torch.cuda.is_available():
|
|
139
|
+
try:
|
|
140
|
+
self.device = torch.device('cuda')
|
|
141
|
+
test_tensor = torch.tensor([1.0, 2.0, 3.0], device=self.device)
|
|
142
|
+
_ = test_tensor * 2
|
|
143
|
+
self.use_gpu = True
|
|
144
|
+
self.device_type = 'cuda'
|
|
145
|
+
self.backend = 'torch'
|
|
146
|
+
return
|
|
147
|
+
except Exception:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
# No GPU available
|
|
151
|
+
if use_gpu:
|
|
152
|
+
warnings.warn("GPU acceleration requested but no GPU backend available. Falling back to CPU.")
|
|
153
|
+
|
|
154
|
+
def to_gpu(self, arr: np.ndarray):
|
|
155
|
+
"""Convert numpy array to GPU array."""
|
|
156
|
+
if not self.use_gpu:
|
|
157
|
+
return arr
|
|
158
|
+
|
|
159
|
+
if self.backend == 'cupy':
|
|
160
|
+
return cp.asarray(arr)
|
|
161
|
+
elif self.backend == 'torch':
|
|
162
|
+
return torch.from_numpy(arr).to(self.device)
|
|
163
|
+
return arr
|
|
164
|
+
|
|
165
|
+
def to_cpu(self, arr) -> np.ndarray:
|
|
166
|
+
"""Convert GPU array back to CPU numpy array."""
|
|
167
|
+
if not self.use_gpu:
|
|
168
|
+
return arr
|
|
169
|
+
|
|
170
|
+
if self.backend == 'cupy' and isinstance(arr, cp.ndarray):
|
|
171
|
+
return cp.asnumpy(arr)
|
|
172
|
+
elif self.backend == 'torch' and isinstance(arr, torch.Tensor):
|
|
173
|
+
return arr.cpu().numpy()
|
|
174
|
+
return arr
|
|
175
|
+
|
|
176
|
+
def sparse_to_gpu(self, sp_matrix: sparse.spmatrix) -> 'cusp.spmatrix':
|
|
177
|
+
"""Convert scipy sparse matrix to CuPy sparse matrix."""
|
|
178
|
+
if self.use_gpu:
|
|
179
|
+
if isinstance(sp_matrix, sparse.csr_matrix):
|
|
180
|
+
return cusp.csr_matrix(sp_matrix)
|
|
181
|
+
elif isinstance(sp_matrix, sparse.csc_matrix):
|
|
182
|
+
return cusp.csc_matrix(sp_matrix)
|
|
183
|
+
elif isinstance(sp_matrix, sparse.coo_matrix):
|
|
184
|
+
return cusp.coo_matrix(sp_matrix)
|
|
185
|
+
return sp_matrix
|
|
186
|
+
|
|
187
|
+
def sparse_to_cpu(self, sp_matrix) -> sparse.spmatrix:
|
|
188
|
+
"""Convert CuPy sparse matrix back to scipy sparse matrix."""
|
|
189
|
+
if self.use_gpu and hasattr(sp_matrix, 'get'):
|
|
190
|
+
# CuPy sparse matrix
|
|
191
|
+
return sp_matrix.get()
|
|
192
|
+
return sp_matrix
|
|
193
|
+
|
|
194
|
+
def svd(self, matrix: np.ndarray, n_components: int,
|
|
195
|
+
random_state: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
196
|
+
"""
|
|
197
|
+
Perform Truncated SVD on GPU or CPU.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
matrix: Input matrix (n_samples, n_features)
|
|
201
|
+
n_components: Number of components
|
|
202
|
+
random_state: Random seed
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
(U, S, Vt) where U @ diag(S) @ Vt approximates the input
|
|
206
|
+
"""
|
|
207
|
+
if self.use_gpu:
|
|
208
|
+
try:
|
|
209
|
+
gpu_matrix = self.to_gpu(matrix)
|
|
210
|
+
|
|
211
|
+
if self.backend == 'cupy':
|
|
212
|
+
# CuPy SVD
|
|
213
|
+
U, S, Vt = cp.linalg.svd(gpu_matrix, full_matrices=False)
|
|
214
|
+
elif self.backend == 'torch':
|
|
215
|
+
# PyTorch SVD
|
|
216
|
+
U, S, Vt = torch.linalg.svd(gpu_matrix, full_matrices=False)
|
|
217
|
+
else:
|
|
218
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
219
|
+
|
|
220
|
+
# Truncate to n_components
|
|
221
|
+
U = U[:, :n_components]
|
|
222
|
+
S = S[:n_components]
|
|
223
|
+
Vt = Vt[:n_components, :]
|
|
224
|
+
|
|
225
|
+
# Convert back to CPU
|
|
226
|
+
return self.to_cpu(U), self.to_cpu(S), self.to_cpu(Vt)
|
|
227
|
+
except Exception as e:
|
|
228
|
+
warnings.warn(f"GPU SVD failed: {e}. Falling back to CPU.")
|
|
229
|
+
self.use_gpu = False
|
|
230
|
+
|
|
231
|
+
# CPU fallback using sklearn
|
|
232
|
+
from sklearn.decomposition import TruncatedSVD
|
|
233
|
+
svd = TruncatedSVD(n_components=n_components, random_state=random_state, n_iter=5)
|
|
234
|
+
U = svd.fit_transform(matrix)
|
|
235
|
+
S = svd.singular_values_
|
|
236
|
+
Vt = svd.components_
|
|
237
|
+
return U, S, Vt
|
|
238
|
+
|
|
239
|
+
def pca(self, matrix: np.ndarray, n_components: int,
|
|
240
|
+
random_state: Optional[int] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
241
|
+
"""
|
|
242
|
+
Perform PCA on GPU or CPU.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
matrix: Input matrix (n_samples, n_features)
|
|
246
|
+
n_components: Number of components
|
|
247
|
+
random_state: Random seed
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
(transformed, components, mean)
|
|
251
|
+
"""
|
|
252
|
+
if self.use_gpu:
|
|
253
|
+
try:
|
|
254
|
+
gpu_matrix = self.to_gpu(matrix)
|
|
255
|
+
|
|
256
|
+
# Center the data
|
|
257
|
+
if self.backend == 'cupy':
|
|
258
|
+
mean = cp.mean(gpu_matrix, axis=0)
|
|
259
|
+
centered = gpu_matrix - mean
|
|
260
|
+
# SVD
|
|
261
|
+
U, S, Vt = cp.linalg.svd(centered, full_matrices=False)
|
|
262
|
+
# Transform: U @ diag(S)
|
|
263
|
+
transformed = U @ cp.diag(S)
|
|
264
|
+
elif self.backend == 'torch':
|
|
265
|
+
mean = torch.mean(gpu_matrix, axis=0)
|
|
266
|
+
centered = gpu_matrix - mean
|
|
267
|
+
# SVD
|
|
268
|
+
U, S, Vt = torch.linalg.svd(centered, full_matrices=False)
|
|
269
|
+
# Transform: U @ diag(S)
|
|
270
|
+
transformed = U @ torch.diag(S)
|
|
271
|
+
else:
|
|
272
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
273
|
+
|
|
274
|
+
# Truncate
|
|
275
|
+
U = U[:, :n_components]
|
|
276
|
+
S = S[:n_components]
|
|
277
|
+
Vt = Vt[:n_components, :]
|
|
278
|
+
transformed = transformed[:, :n_components]
|
|
279
|
+
|
|
280
|
+
# Convert back to CPU
|
|
281
|
+
return self.to_cpu(transformed), self.to_cpu(Vt), self.to_cpu(mean)
|
|
282
|
+
except Exception as e:
|
|
283
|
+
warnings.warn(f"GPU PCA failed: {e}. Falling back to CPU.")
|
|
284
|
+
self.use_gpu = False
|
|
285
|
+
|
|
286
|
+
# CPU fallback using sklearn
|
|
287
|
+
from sklearn.decomposition import PCA
|
|
288
|
+
pca = PCA(n_components=n_components, random_state=random_state)
|
|
289
|
+
transformed = pca.fit_transform(matrix)
|
|
290
|
+
return transformed, pca.components_, pca.mean_
|
|
291
|
+
|
|
292
|
+
def matmul(self, a, b):
|
|
293
|
+
"""Matrix multiplication on GPU or CPU."""
|
|
294
|
+
if self.use_gpu:
|
|
295
|
+
try:
|
|
296
|
+
a_gpu = self.to_gpu(a) if isinstance(a, np.ndarray) else a
|
|
297
|
+
b_gpu = self.to_gpu(b) if isinstance(b, np.ndarray) else b
|
|
298
|
+
|
|
299
|
+
if self.backend == 'cupy':
|
|
300
|
+
result = cp.matmul(a_gpu, b_gpu)
|
|
301
|
+
elif self.backend == 'torch':
|
|
302
|
+
result = torch.matmul(a_gpu, b_gpu)
|
|
303
|
+
else:
|
|
304
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
305
|
+
|
|
306
|
+
return self.to_cpu(result)
|
|
307
|
+
except Exception as e:
|
|
308
|
+
warnings.warn(f"GPU matmul failed: {e}. Falling back to CPU.")
|
|
309
|
+
self.use_gpu = False
|
|
310
|
+
|
|
311
|
+
return np.matmul(a, b)
|
|
312
|
+
|
|
313
|
+
def sparse_matmul(self, a, b):
|
|
314
|
+
"""Sparse matrix multiplication on GPU or CPU."""
|
|
315
|
+
if self.use_gpu:
|
|
316
|
+
try:
|
|
317
|
+
# PyTorch sparse support is limited, so prefer CuPy for sparse ops
|
|
318
|
+
if self.backend == 'cupy':
|
|
319
|
+
a_gpu = self.sparse_to_gpu(a) if isinstance(a, sparse.spmatrix) else a
|
|
320
|
+
b_gpu = self.to_gpu(b) if isinstance(b, np.ndarray) else b
|
|
321
|
+
result = a_gpu @ b_gpu
|
|
322
|
+
return self.to_cpu(result)
|
|
323
|
+
elif self.backend == 'torch':
|
|
324
|
+
# PyTorch: convert sparse to dense for now (MPS doesn't support sparse well)
|
|
325
|
+
if isinstance(a, sparse.spmatrix):
|
|
326
|
+
a_dense = self.to_gpu(a.toarray())
|
|
327
|
+
b_gpu = self.to_gpu(b) if isinstance(b, np.ndarray) else b
|
|
328
|
+
result = torch.matmul(a_dense, b_gpu)
|
|
329
|
+
return self.to_cpu(result)
|
|
330
|
+
except Exception as e:
|
|
331
|
+
warnings.warn(f"GPU sparse matmul failed: {e}. Falling back to CPU.")
|
|
332
|
+
self.use_gpu = False
|
|
333
|
+
|
|
334
|
+
if isinstance(a, sparse.spmatrix):
|
|
335
|
+
return a @ b
|
|
336
|
+
return np.matmul(a, b)
|
|
337
|
+
|
|
338
|
+
def norm(self, arr: np.ndarray, axis: Optional[int] = None, keepdims: bool = False) -> np.ndarray:
|
|
339
|
+
"""Compute L2 norm on GPU or CPU."""
|
|
340
|
+
if self.use_gpu:
|
|
341
|
+
try:
|
|
342
|
+
gpu_arr = self.to_gpu(arr)
|
|
343
|
+
|
|
344
|
+
if self.backend == 'cupy':
|
|
345
|
+
result = cp.linalg.norm(gpu_arr, axis=axis, keepdims=keepdims)
|
|
346
|
+
elif self.backend == 'torch':
|
|
347
|
+
result = torch.linalg.norm(gpu_arr, dim=axis, keepdim=keepdims)
|
|
348
|
+
else:
|
|
349
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
350
|
+
|
|
351
|
+
return self.to_cpu(result)
|
|
352
|
+
except Exception as e:
|
|
353
|
+
warnings.warn(f"GPU norm failed: {e}. Falling back to CPU.")
|
|
354
|
+
self.use_gpu = False
|
|
355
|
+
|
|
356
|
+
return np.linalg.norm(arr, axis=axis, keepdims=keepdims)
|
|
357
|
+
|
|
358
|
+
def sum(self, arr, axis: Optional[int] = None, keepdims: bool = False):
|
|
359
|
+
"""Sum array on GPU or CPU."""
|
|
360
|
+
if self.use_gpu:
|
|
361
|
+
try:
|
|
362
|
+
gpu_arr = self.to_gpu(arr) if isinstance(arr, np.ndarray) else arr
|
|
363
|
+
|
|
364
|
+
if self.backend == 'cupy':
|
|
365
|
+
result = cp.sum(gpu_arr, axis=axis, keepdims=keepdims)
|
|
366
|
+
elif self.backend == 'torch':
|
|
367
|
+
result = torch.sum(gpu_arr, dim=axis, keepdim=keepdims)
|
|
368
|
+
else:
|
|
369
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
370
|
+
|
|
371
|
+
return self.to_cpu(result) if hasattr(result, 'cpu') or isinstance(result, cp.ndarray) else result
|
|
372
|
+
except Exception as e:
|
|
373
|
+
warnings.warn(f"GPU sum failed: {e}. Falling back to CPU.")
|
|
374
|
+
self.use_gpu = False
|
|
375
|
+
|
|
376
|
+
return np.sum(arr, axis=axis, keepdims=keepdims)
|
|
377
|
+
|
|
378
|
+
def maximum(self, a, b):
|
|
379
|
+
"""Element-wise maximum on GPU or CPU."""
|
|
380
|
+
if self.use_gpu:
|
|
381
|
+
try:
|
|
382
|
+
a_gpu = self.to_gpu(a) if isinstance(a, np.ndarray) else a
|
|
383
|
+
b_gpu = self.to_gpu(b) if isinstance(b, np.ndarray) else b
|
|
384
|
+
|
|
385
|
+
if self.backend == 'cupy':
|
|
386
|
+
result = cp.maximum(a_gpu, b_gpu)
|
|
387
|
+
elif self.backend == 'torch':
|
|
388
|
+
result = torch.maximum(a_gpu, b_gpu)
|
|
389
|
+
else:
|
|
390
|
+
raise ValueError(f"Unknown backend: {self.backend}")
|
|
391
|
+
|
|
392
|
+
return self.to_cpu(result)
|
|
393
|
+
except Exception as e:
|
|
394
|
+
warnings.warn(f"GPU maximum failed: {e}. Falling back to CPU.")
|
|
395
|
+
self.use_gpu = False
|
|
396
|
+
|
|
397
|
+
return np.maximum(a, b)
|
|
398
|
+
|
|
399
|
+
def __enter__(self):
|
|
400
|
+
"""Context manager entry."""
|
|
401
|
+
return self
|
|
402
|
+
|
|
403
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
404
|
+
"""Context manager exit - cleanup GPU memory."""
|
|
405
|
+
if self.use_gpu:
|
|
406
|
+
try:
|
|
407
|
+
if self.backend == 'cupy':
|
|
408
|
+
cp.get_default_memory_pool().free_all_blocks()
|
|
409
|
+
elif self.backend == 'torch':
|
|
410
|
+
torch.mps.empty_cache() if self.device_type == 'mps' else torch.cuda.empty_cache()
|
|
411
|
+
except:
|
|
412
|
+
pass
|
|
413
|
+
return False
|
|
414
|
+
|