0
# SciPy Compatibility
1
2
GPU-accelerated SciPy-compatible functions through the cupyx.scipy module, providing comprehensive scientific computing capabilities. CuPy extends NumPy compatibility to include major SciPy functionality including sparse matrices, signal processing, image processing, special functions, statistics, and advanced linear algebra operations.
3
4
## Capabilities
5
6
### Sparse Matrices
7
8
Comprehensive sparse matrix support with GPU acceleration for memory-efficient operations on large sparse datasets.
9
10
```python { .api }
11
# Sparse matrix formats (cupyx.scipy.sparse)
12
class csr_matrix:
13
"""Compressed Sparse Row matrix format"""
14
def __init__(self, arg1, shape=None, dtype=None, copy=False): ...
15
def dot(self, other): ...
16
def multiply(self, other): ...
17
def transpose(self, axes=None, copy=False): ...
18
def tocsc(self, copy=False): ...
19
def tocoo(self, copy=False): ...
20
def toarray(self, order=None, out=None): ...
21
def sum(self, axis=None, dtype=None, out=None): ...
22
23
class csc_matrix:
24
"""Compressed Sparse Column matrix format"""
25
def __init__(self, arg1, shape=None, dtype=None, copy=False): ...
26
def dot(self, other): ...
27
def multiply(self, other): ...
28
def transpose(self, axes=None, copy=False): ...
29
def tocsr(self, copy=False): ...
30
def tocoo(self, copy=False): ...
31
32
class coo_matrix:
33
"""Coordinate format sparse matrix"""
34
def __init__(self, arg1, shape=None, dtype=None, copy=False): ...
35
def tocsr(self, copy=False): ...
36
def tocsc(self, copy=False): ...
37
def sum_duplicates(self): ...
38
39
class dia_matrix:
40
"""Sparse matrix with DIAgonal storage"""
41
def __init__(self, arg1, shape=None, dtype=None, copy=False): ...
42
def tocsr(self, copy=False): ...
43
44
# Construction functions
45
def eye(m, n=None, k=0, dtype=float, format=None):
46
"""Sparse identity matrix"""
47
48
def identity(n, dtype=float, format=None):
49
"""Identity matrix in sparse format"""
50
51
def diags(diagonals, offsets=0, shape=None, format=None, dtype=None):
52
"""Construct sparse matrix from diagonals"""
53
54
def spdiags(data, diags, m, n, format=None):
55
"""Create sparse matrix from diagonals"""
56
57
def random(m, n, density=0.01, format='coo', dtype=None, random_state=None):
58
"""Generate random sparse matrix"""
59
60
# Utility functions
61
def find(A):
62
"""Find indices and values of nonzero elements"""
63
64
def tril(A, k=0, format=None):
65
"""Lower triangular portion of sparse matrix"""
66
67
def triu(A, k=0, format=None):
68
"""Upper triangular portion of sparse matrix"""
69
70
def kron(A, B, format=None):
71
"""Kronecker product of sparse matrices"""
72
```
73
74
### Signal Processing
75
76
Digital signal processing functions for filtering, convolution, spectral analysis, and signal generation.
77
78
```python { .api }
79
# Convolution and correlation (cupyx.scipy.signal)
80
def convolve(in1, in2, mode='full', method='auto'):
81
"""
82
Convolve two N-dimensional arrays.
83
84
Parameters:
85
- in1: array_like, first input array
86
- in2: array_like, second input array
87
- mode: {'full', 'valid', 'same'}, convolution mode
88
- method: {'auto', 'direct', 'fft'}, computation method
89
90
Returns:
91
- ndarray: Convolution of in1 and in2
92
"""
93
94
def correlate(in1, in2, mode='full', method='auto'):
95
"""
96
Cross-correlate two N-dimensional arrays.
97
98
Parameters:
99
- in1: array_like, first input array
100
- in2: array_like, second input array
101
- mode: {'full', 'valid', 'same'}, correlation mode
102
- method: {'auto', 'direct', 'fft'}, computation method
103
104
Returns:
105
- ndarray: Cross-correlation of in1 and in2
106
"""
107
108
def convolve2d(in1, in2, mode='full', boundary='fill', fillvalue=0):
109
"""2D convolution of matrices"""
110
111
def correlate2d(in1, in2, mode='full', boundary='fill', fillvalue=0):
112
"""2D cross-correlation of matrices"""
113
114
# Filtering
115
def lfilter(b, a, x, axis=-1, zi=None):
116
"""Filter data along one dimension using IIR or FIR filter"""
117
118
def filtfilt(b, a, x, axis=-1, padtype='odd', padlen=None, method='pad', irlen=None):
119
"""Apply filter forward and backward to remove phase shift"""
120
121
# Window functions
122
def get_window(window, Nx, fftbins=True):
123
"""Return window of given length and type"""
124
125
def hann(M, sym=True):
126
"""Hann window"""
127
128
def hamming(M, sym=True):
129
"""Hamming window"""
130
131
def blackman(M, sym=True):
132
"""Blackman window"""
133
134
def bartlett(M, sym=True):
135
"""Bartlett window"""
136
137
# Spectral analysis
138
def periodogram(x, fs=1.0, window='boxcar', nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1):
139
"""Estimate power spectral density using periodogram"""
140
141
def welch(x, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=True, scaling='density', axis=-1):
142
"""Estimate power spectral density using Welch's method"""
143
```
144
145
### N-Dimensional Image Processing
146
147
Comprehensive image processing functions for filtering, morphology, measurements, and geometric transformations.
148
149
```python { .api }
150
# Filters (cupyx.scipy.ndimage)
151
def gaussian_filter(input, sigma, order=0, output=None, mode='reflect', cval=0.0, truncate=4.0):
152
"""
153
Multidimensional Gaussian filter.
154
155
Parameters:
156
- input: array_like, input array
157
- sigma: scalar or sequence, standard deviation for Gaussian kernel
158
- order: int or sequence, order of derivative
159
- output: array, optional, output array
160
- mode: {'reflect', 'constant', 'nearest', 'mirror', 'wrap'}, boundary mode
161
- cval: scalar, value for constant mode
162
- truncate: float, truncate filter at this sigma
163
164
Returns:
165
- ndarray: Filtered array
166
"""
167
168
def uniform_filter(input, size, output=None, mode='reflect', cval=0.0, origin=0):
169
"""Multidimensional uniform filter"""
170
171
def median_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0):
172
"""Multidimensional median filter"""
173
174
def maximum_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0):
175
"""Multidimensional maximum filter"""
176
177
def minimum_filter(input, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0):
178
"""Multidimensional minimum filter"""
179
180
def rank_filter(input, rank, size=None, footprint=None, output=None, mode='reflect', cval=0.0, origin=0):
181
"""Multidimensional rank filter"""
182
183
# Morphological operations
184
def binary_erosion(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False):
185
"""Multidimensional binary erosion"""
186
187
def binary_dilation(input, structure=None, iterations=1, mask=None, output=None, border_value=0, origin=0, brute_force=False):
188
"""Multidimensional binary dilation"""
189
190
def binary_opening(input, structure=None, iterations=1, output=None, origin=0):
191
"""Multidimensional binary opening"""
192
193
def binary_closing(input, structure=None, iterations=1, output=None, origin=0):
194
"""Multidimensional binary closing"""
195
196
# Geometric transformations
197
def rotate(input, angle, axes=(1, 0), reshape=True, output=None, order=1, mode='constant', cval=0.0, prefilter=True):
198
"""Rotate array around given axes"""
199
200
def shift(input, shift, output=None, order=1, mode='constant', cval=0.0, prefilter=True):
201
"""Shift array by given offset"""
202
203
def zoom(input, zoom, output=None, order=1, mode='constant', cval=0.0, prefilter=True):
204
"""Zoom array by given factors"""
205
206
def affine_transform(input, matrix, offset=0.0, output_shape=None, output=None, order=1, mode='constant', cval=0.0, prefilter=True):
207
"""Apply affine transformation"""
208
209
# Measurements
210
def label(input, structure=None, output=None):
211
"""Label features in binary image"""
212
213
def center_of_mass(input, labels=None, index=None):
214
"""Calculate center of mass of features"""
215
216
def find_objects(input, max_label=0):
217
"""Find objects in labeled array"""
218
219
def sum_labels(input, labels=None, index=None):
220
"""Sum of values for labeled regions"""
221
```
222
223
### Special Functions
224
225
Mathematical special functions including Bessel functions, gamma functions, error functions, and orthogonal polynomials.
226
227
```python { .api }
228
# Error functions and related (cupyx.scipy.special)
229
def erf(x):
230
"""Error function"""
231
232
def erfc(x):
233
"""Complementary error function"""
234
235
def erfinv(x):
236
"""Inverse error function"""
237
238
def erfcinv(x):
239
"""Inverse complementary error function"""
240
241
# Gamma and related functions
242
def gamma(x):
243
"""Gamma function"""
244
245
def gammaln(x):
246
"""Natural logarithm of absolute value of gamma function"""
247
248
def digamma(x):
249
"""Digamma function (derivative of log gamma)"""
250
251
def polygamma(n, x):
252
"""Polygamma function"""
253
254
def beta(a, b):
255
"""Beta function"""
256
257
def betaln(a, b):
258
"""Natural logarithm of beta function"""
259
260
# Bessel functions
261
def j0(x):
262
"""Bessel function of first kind of order 0"""
263
264
def j1(x):
265
"""Bessel function of first kind of order 1"""
266
267
def jn(n, x):
268
"""Bessel function of first kind of integer order n"""
269
270
def y0(x):
271
"""Bessel function of second kind of order 0"""
272
273
def y1(x):
274
"""Bessel function of second kind of order 1"""
275
276
def yn(n, x):
277
"""Bessel function of second kind of integer order n"""
278
279
def i0(x):
280
"""Modified Bessel function of first kind of order 0"""
281
282
def i1(x):
283
"""Modified Bessel function of first kind of order 1"""
284
285
def iv(v, x):
286
"""Modified Bessel function of first kind of real order"""
287
288
def k0(x):
289
"""Modified Bessel function of second kind of order 0"""
290
291
def k1(x):
292
"""Modified Bessel function of second kind of order 1"""
293
294
def kv(v, x):
295
"""Modified Bessel function of second kind of real order"""
296
297
# Hypergeometric functions
298
def hyp2f1(a, b, c, z):
299
"""Gaussian hypergeometric function 2F1"""
300
301
# Elliptic functions and integrals
302
def ellipk(m):
303
"""Complete elliptic integral of first kind"""
304
305
def ellipe(m):
306
"""Complete elliptic integral of second kind"""
307
308
# Convenience functions
309
def expit(x):
310
"""Expit (inverse logit) function"""
311
312
def logit(x):
313
"""Logit function"""
314
315
def softmax(x, axis=None):
316
"""Softmax function"""
317
318
def log_softmax(x, axis=None):
319
"""Log-softmax function"""
320
```
321
322
### Statistics
323
324
Statistical functions for probability distributions, hypothesis testing, and descriptive statistics.
325
326
```python { .api }
327
# Distribution statistics (cupyx.scipy.stats)
328
def entropy(pk, qk=None, base=None, axis=0):
329
"""Calculate entropy of distribution"""
330
331
def kurtosis(a, axis=0, fisher=True, bias=True, nan_policy='propagate'):
332
"""Compute kurtosis of dataset"""
333
334
def skew(a, axis=0, bias=True, nan_policy='propagate'):
335
"""Compute skewness of dataset"""
336
337
def moment(a, moment=1, axis=0, nan_policy='propagate'):
338
"""Calculate nth moment about mean"""
339
340
def variation(a, axis=0, nan_policy='propagate'):
341
"""Compute coefficient of variation"""
342
343
def zscore(a, axis=0, ddof=0, nan_policy='propagate'):
344
"""Compute z-scores"""
345
346
# Correlation functions
347
def pearsonr(x, y):
348
"""Pearson correlation coefficient and p-value"""
349
350
def spearmanr(a, b=None, axis=0, nan_policy='propagate'):
351
"""Spearman correlation coefficient and p-value"""
352
353
def kendalltau(x, y, initial_lexsort=None, nan_policy='propagate', method='auto'):
354
"""Kendall's tau correlation coefficient and p-value"""
355
356
# Statistical tests
357
def ttest_1samp(a, popmean, axis=0, nan_policy='propagate', alternative='two-sided'):
358
"""One-sample t-test"""
359
360
def ttest_ind(a, b, axis=0, equal_var=True, nan_policy='propagate', permutations=None, random_state=None, alternative='two-sided'):
361
"""Independent two-sample t-test"""
362
363
def ttest_rel(a, b, axis=0, nan_policy='propagate', alternative='two-sided'):
364
"""Related/paired sample t-test"""
365
366
def kstest(rvs, cdf, args=(), N=20, alternative='two-sided', method='auto'):
367
"""Kolmogorov-Smirnov test"""
368
369
def chisquare(f_obs, f_exp=None, ddof=0, axis=0):
370
"""Chi-square goodness of fit test"""
371
372
# Distribution fitting
373
def norm():
374
"""Normal distribution object with methods for statistics"""
375
376
def uniform():
377
"""Uniform distribution object"""
378
379
def expon():
380
"""Exponential distribution object"""
381
382
def gamma():
383
"""Gamma distribution object"""
384
```
385
386
### Advanced Linear Algebra
387
388
Extended linear algebra functions beyond core CuPy functionality, including advanced decompositions and matrix functions.
389
390
```python { .api }
391
# Matrix decompositions (cupyx.scipy.linalg)
392
def lu(a, permute_l=False, overwrite_a=False, check_finite=True):
393
"""LU decomposition with partial pivoting"""
394
395
def lu_factor(a, overwrite_a=False, check_finite=True):
396
"""LU decomposition returning factors in compact form"""
397
398
def lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True):
399
"""Solve linear system using LU decomposition"""
400
401
def qr(a, overwrite_a=False, lwork=None, mode='full', pivoting=False, check_finite=True):
402
"""QR decomposition"""
403
404
def rq(a, overwrite_a=False, lwork=None, mode='full', check_finite=True):
405
"""RQ decomposition"""
406
407
def schur(a, output='real', lwork=None, overwrite_a=False, sort=None, check_finite=True):
408
"""Schur decomposition"""
409
410
def hessenberg(a, calc_q=True, overwrite_a=False, check_finite=True):
411
"""Hessenberg decomposition"""
412
413
# Matrix functions
414
def expm(A):
415
"""Matrix exponential"""
416
417
def logm(A, disp=True):
418
"""Matrix logarithm"""
419
420
def sqrtm(A, disp=True, blocksize=64):
421
"""Matrix square root"""
422
423
def fractional_matrix_power(A, t):
424
"""Fractional matrix power"""
425
426
# Eigenvalue problems
427
def eigvals(a, b=None, overwrite_a=False, check_finite=True, homogeneous_eigvals=False):
428
"""Eigenvalues of general matrix"""
429
430
def eigvalsh(a, b=None, lower=True, overwrite_a=False, overwrite_b=False, turbo=True, eigvals=None, type=1, check_finite=True):
431
"""Eigenvalues of symmetric/Hermitian matrix"""
432
433
def eig(a, b=None, left=False, right=True, overwrite_a=False, overwrite_b=False, check_finite=True, homogeneous_eigvals=False):
434
"""Eigenvalues and vectors of general matrix"""
435
436
def eigh(a, b=None, lower=True, eigvals_only=False, overwrite_a=False, overwrite_b=False, turbo=True, eigvals=None, type=1, check_finite=True):
437
"""Eigenvalues and vectors of symmetric/Hermitian matrix"""
438
439
# Linear system solvers
440
def solve_triangular(a, b, trans=0, lower=False, unit_diagonal=False, overwrite_b=False, debug=None, check_finite=True):
441
"""Solve triangular linear system"""
442
443
def solve_banded(l_and_u, ab, b, overwrite_ab=False, overwrite_b=False, debug=None, check_finite=True):
444
"""Solve banded linear system"""
445
446
def solveh_banded(ab, b, overwrite_ab=False, overwrite_b=False, lower=False, check_finite=True):
447
"""Solve symmetric/Hermitian banded linear system"""
448
449
# Matrix analysis
450
def norm(a, ord=None, axis=None, keepdims=False, check_finite=True):
451
"""Matrix or vector norm"""
452
453
def det(a, overwrite_a=False, check_finite=True):
454
"""Determinant of matrix"""
455
456
def slogdet(a, overwrite_a=False, check_finite=True):
457
"""Sign and log determinant of matrix"""
458
459
def cond(x, p=None):
460
"""Condition number of matrix"""
461
462
def matrix_rank(M, tol=None, hermitian=False):
463
"""Matrix rank using SVD"""
464
```
465
466
### Interpolation
467
468
Interpolation and approximation functions for data fitting and function approximation.
469
470
```python { .api }
471
# 1D interpolation (cupyx.scipy.interpolate)
472
def interp1d(x, y, kind='linear', axis=-1, copy=True, bounds_error=None, fill_value=float('nan'), assume_sorted=False):
473
"""
474
1D interpolation function.
475
476
Parameters:
477
- x: array_like, x-coordinates of data points
478
- y: array_like, y-coordinates of data points
479
- kind: str or int, interpolation type ('linear', 'nearest', 'cubic', etc.)
480
- axis: int, axis along which y is varying
481
- copy: bool, whether to copy data
482
- bounds_error: bool, whether to raise error for out-of-bounds
483
- fill_value: value to use for out-of-bounds points
484
- assume_sorted: bool, whether x is already sorted
485
486
Returns:
487
- callable: Interpolation function
488
"""
489
490
# Spline interpolation
491
def splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0, per=0, quiet=1):
492
"""Find B-spline representation of 1D curve"""
493
494
def splev(x, tck, der=0, ext=0):
495
"""Evaluate B-spline or its derivatives"""
496
497
def sproot(tck, mest=10):
498
"""Find roots of cubic B-spline"""
499
500
def spalde(x, tck):
501
"""Evaluate all derivatives of B-spline at given points"""
502
503
# 2D interpolation
504
def griddata(points, values, xi, method='linear', fill_value=float('nan'), rescale=False):
505
"""
506
Interpolate unstructured D-dimensional data.
507
508
Parameters:
509
- points: ndarray, coordinates of data points
510
- values: ndarray, data values at points
511
- xi: ndarray, coordinates where to interpolate
512
- method: {'linear', 'nearest', 'cubic'}, interpolation method
513
- fill_value: value for points outside convex hull
514
- rescale: bool, whether to rescale points to unit cube
515
516
Returns:
517
- ndarray: Interpolated values at xi
518
"""
519
```
520
521
### Spatial Algorithms
522
523
Spatial data structures and algorithms for computational geometry and spatial analysis.
524
525
```python { .api }
526
# Distance computations (cupyx.scipy.spatial)
527
def distance_matrix(x, y, p=2, threshold=1000000):
528
"""
529
Compute distance matrix between arrays.
530
531
Parameters:
532
- x: ndarray, first set of points
533
- y: ndarray, second set of points
534
- p: float, which Minkowski norm to use (1, 2, inf)
535
- threshold: int, maximum size for direct computation
536
537
Returns:
538
- ndarray: Distance matrix
539
"""
540
541
def pdist(X, metric='euclidean', *args, **kwargs):
542
"""Pairwise distances between observations"""
543
544
def cdist(XA, XB, metric='euclidean', *args, **kwargs):
545
"""Distances between each pair of observations from two collections"""
546
547
def squareform(X, force='no', checks=True):
548
"""Convert between condensed and square distance matrices"""
549
550
# Convex hull
551
class ConvexHull:
552
"""Convex hull of points"""
553
def __init__(self, points, incremental=False, qhull_options=None): ...
554
@property
555
def vertices(self): ...
556
@property
557
def simplices(self): ...
558
@property
559
def volume(self): ...
560
561
# Voronoi diagrams
562
class Voronoi:
563
"""Voronoi diagram of points"""
564
def __init__(self, points, furthest_site=False, incremental=False, qhull_options=None): ...
565
566
# KD-tree for fast nearest neighbor searches
567
class KDTree:
568
"""k-dimensional tree for fast nearest neighbor queries"""
569
def __init__(self, data, leafsize=10, compact_nodes=True, copy_data=False, balanced_tree=True, boxsize=None): ...
570
def query(self, x, k=1, eps=0, p=2, distance_upper_bound=float('inf'), workers=1): ...
571
def query_ball_point(self, x, r, p=2.0, eps=0): ...
572
def query_pairs(self, r, p=2.0, eps=0): ...
573
```
574
575
### Usage Examples
576
577
#### Sparse Matrix Operations
578
579
```python
580
import cupy as cp
581
import cupyx.scipy.sparse as sparse
582
583
# Create sparse matrices
584
data = cp.array([1, 2, 3, 4, 5])
585
row = cp.array([0, 1, 2, 1, 3])
586
col = cp.array([0, 1, 2, 3, 2])
587
588
# COO format
589
coo = sparse.coo_matrix((data, (row, col)), shape=(4, 4))
590
591
# Convert to CSR for efficient arithmetic
592
csr = coo.tocsr()
593
594
# Matrix operations
595
result = csr.dot(cp.ones(4))
596
transposed = csr.T
597
squared = csr.multiply(csr)
598
599
# Create identity matrix
600
identity = sparse.identity(1000, format='csr')
601
```
602
603
#### Signal Processing
604
605
```python
606
import cupy as cp
607
import cupyx.scipy.signal as signal
608
609
# Generate test signal
610
t = cp.linspace(0, 1, 1000, endpoint=False)
611
sig = cp.sin(2 * cp.pi * 50 * t) + cp.sin(2 * cp.pi * 120 * t)
612
sig += 0.1 * cp.random.randn(1000)
613
614
# Apply filters
615
b, a = signal.butter(4, 0.2) # Butterworth filter
616
filtered = signal.lfilter(b, a, sig)
617
618
# Convolution with kernel
619
kernel = cp.array([0.25, 0.5, 0.25])
620
convolved = signal.convolve(sig, kernel, mode='same')
621
622
# Spectral analysis
623
freqs, psd = signal.welch(sig, fs=1000, nperseg=256)
624
```
625
626
#### Image Processing
627
628
```python
629
import cupy as cp
630
import cupyx.scipy.ndimage as ndimage
631
632
# Load image data
633
image = cp.random.random((512, 512))
634
635
# Apply filters
636
blurred = ndimage.gaussian_filter(image, sigma=2.0)
637
edges = ndimage.sobel(image)
638
denoised = ndimage.median_filter(image, size=3)
639
640
# Geometric transformations
641
rotated = ndimage.rotate(image, 45, reshape=False)
642
zoomed = ndimage.zoom(image, 1.5)
643
shifted = ndimage.shift(image, (10, -5))
644
645
# Binary morphology
646
binary = image > 0.5
647
eroded = ndimage.binary_erosion(binary)
648
dilated = ndimage.binary_dilation(binary)
649
```
650
651
#### Statistical Analysis
652
653
```python
654
import cupy as cp
655
import cupyx.scipy.stats as stats
656
657
# Generate sample data
658
data1 = cp.random.normal(0, 1, 1000)
659
data2 = cp.random.normal(0.5, 1.2, 1000)
660
661
# Descriptive statistics
662
mean_val = cp.mean(data1)
663
std_val = cp.std(data1)
664
skewness = stats.skew(data1)
665
kurt = stats.kurtosis(data1)
666
667
# Statistical tests
668
t_stat, p_val = stats.ttest_ind(data1, data2)
669
correlation, p_corr = stats.pearsonr(data1[:100], data2[:100])
670
671
# Distribution fitting and analysis
672
z_scores = stats.zscore(data1)
673
entropy_val = stats.entropy(cp.abs(data1))
674
```
675
676
## Notes
677
678
- All cupyx.scipy functions operate on GPU arrays and return GPU arrays
679
- Use `cupyx.scipy.get_array_module()` for writing CPU/GPU generic code
680
- Sparse matrices support all major formats (CSR, CSC, COO, DIA) with efficient conversions
681
- Signal processing functions leverage cuFFT for optimal FFT-based operations
682
- Image processing functions support various boundary conditions and data types
683
- Statistical functions handle NaN values and provide multiple testing options
684
- Linear algebra functions use cuBLAS and cuSOLVER for optimal GPU performance
685
- Most functions maintain compatibility with their SciPy counterparts while providing GPU acceleration