0
# Random Number Generation
1
2
CuPy provides comprehensive random number generation capabilities for GPU-accelerated computation, offering NumPy-compatible random number generators, probability distributions, and statistical sampling functions optimized for CUDA and ROCm platforms.
3
4
## Capabilities
5
6
### Random Number Generators
7
8
Core random number generation infrastructure supporting multiple algorithms and state management.
9
10
```python { .api }
11
class Generator:
12
"""
13
Container for the BitGenerator used to generate random numbers.
14
15
Generator exposes a number of methods for generating random numbers
16
drawn from a variety of probability distributions.
17
"""
18
def __init__(self, bit_generator): ...
19
20
def default_rng(seed=None):
21
"""
22
Construct a new Generator with the default BitGenerator (XORWOW).
23
24
Parameters:
25
seed: {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional - A seed to initialize the BitGenerator
26
"""
27
28
class RandomState:
29
"""
30
Container for the Mersenne Twister pseudo-random number generator.
31
32
RandomState exposes a number of methods for generating random numbers
33
drawn from a variety of probability distributions. This is the legacy
34
random API, users should prefer the new Generator API.
35
"""
36
def __init__(self, seed=None): ...
37
38
def get_random_state():
39
"""
40
Returns the random state for the current device.
41
"""
42
43
def set_random_state(rs):
44
"""
45
Sets the random state for the current device.
46
47
Parameters:
48
rs: RandomState - The random state to set
49
"""
50
51
def seed(seed=None):
52
"""
53
Seed the generator.
54
55
Parameters:
56
seed: int or 1-d array_like, optional - Seed for RandomState
57
"""
58
59
def reset_states():
60
"""
61
Reset the random states on all devices.
62
"""
63
```
64
65
### Bit Generators
66
67
Low-level random bit generators providing the foundation for random number generation.
68
69
```python { .api }
70
class BitGenerator:
71
"""
72
Base class for bit generators used by Generator.
73
74
Bit generators provide a stream of random bits which are then
75
transformed by the Generator class into useful random numbers.
76
"""
77
78
class XORWOW(BitGenerator):
79
"""
80
BitGenerator for XORWOW algorithm.
81
82
XORWOW is the default bit generator used by cuRAND and provides
83
good performance on GPU architectures.
84
"""
85
def __init__(self, seed=None): ...
86
87
class MRG32k3a(BitGenerator):
88
"""
89
BitGenerator for MRG32k3a algorithm.
90
91
MRG32k3a provides a long period and good statistical properties
92
but may be slower than XORWOW on some architectures.
93
"""
94
def __init__(self, seed=None): ...
95
96
class Philox4x32_10(BitGenerator):
97
"""
98
BitGenerator for Philox4x32-10 algorithm.
99
100
Philox provides counter-based random number generation which
101
allows for reproducible parallel random number generation.
102
"""
103
def __init__(self, seed=None): ...
104
```
105
106
### Simple Random Data
107
108
Basic random number generation functions for uniform and normal distributions.
109
110
```python { .api }
111
def rand(*dn):
112
"""
113
Random values in a given shape.
114
115
Parameters:
116
dn: int - Dimensions of the returned array, should be all positive
117
"""
118
119
def randn(*dn):
120
"""
121
Return a sample (or samples) from the "standard normal" distribution.
122
123
Parameters:
124
dn: int - Dimensions of the returned array, should be all positive
125
"""
126
127
def randint(low, high=None, size=None, dtype=int):
128
"""
129
Return random integers from low (inclusive) to high (exclusive).
130
131
Parameters:
132
low: int or array-like of ints - Lowest (signed) integers to be drawn from the distribution
133
high: int or array-like of ints, optional - One above the largest (signed) integer to be drawn from the distribution
134
size: int or tuple of ints, optional - Output shape
135
dtype: dtype, optional - Desired dtype of the result
136
"""
137
138
def random_integers(low, high=None, size=None):
139
"""
140
Random integers of type int between low and high, inclusive.
141
142
Parameters:
143
low: int - Lowest (signed) integer to be drawn from the distribution
144
high: int, optional - Highest (signed) integer to be drawn from the distribution
145
size: int or tuple of ints, optional - Output shape
146
"""
147
148
def random_sample(size=None):
149
"""
150
Return random floats in the half-open interval [0.0, 1.0).
151
152
Parameters:
153
size: int or tuple of ints, optional - Output shape
154
"""
155
156
def random(size=None):
157
"""
158
Return random floats in the half-open interval [0.0, 1.0).
159
160
Parameters:
161
size: int or tuple of ints, optional - Output shape
162
"""
163
164
def ranf(size=None):
165
"""
166
Return random floats in the half-open interval [0.0, 1.0).
167
168
Parameters:
169
size: int or tuple of ints, optional - Output shape
170
"""
171
172
def sample(size=None):
173
"""
174
Return random floats in the half-open interval [0.0, 1.0).
175
176
Parameters:
177
size: int or tuple of ints, optional - Output shape
178
"""
179
180
def choice(a, size=None, replace=True, p=None):
181
"""
182
Generates a random sample from a given 1-D array.
183
184
Parameters:
185
a: 1-D array-like or int - If an ndarray, a random sample is generated from its elements. If an int, the random sample is generated as if it were np.arange(a)
186
size: int or tuple of ints, optional - Output shape
187
replace: boolean, optional - Whether the sample is with or without replacement (default is True)
188
p: 1-D array-like, optional - Probabilities associated with each entry in a
189
"""
190
191
def bytes(length):
192
"""
193
Return random bytes.
194
195
Parameters:
196
length: int - Number of random bytes
197
"""
198
```
199
200
### Permutations
201
202
Functions for shuffling and permuting arrays and sequences.
203
204
```python { .api }
205
def shuffle(x):
206
"""
207
Modify a sequence in-place by shuffling its contents.
208
209
Parameters:
210
x: array_like - The array or list to be shuffled
211
"""
212
213
def permutation(x):
214
"""
215
Randomly permute a sequence, or return a permuted range.
216
217
Parameters:
218
x: int or array_like - If x is an integer, randomly permute np.arange(x). If x is an array, make a copy and shuffle the elements randomly
219
"""
220
```
221
222
### Continuous Distributions
223
224
Random number generation from continuous probability distributions.
225
226
```python { .api }
227
def beta(a, b, size=None):
228
"""
229
Draw samples from a Beta distribution.
230
231
Parameters:
232
a: float or array_like of floats - Alpha, positive (>0)
233
b: float or array_like of floats - Beta, positive (>0)
234
size: int or tuple of ints, optional - Output shape
235
"""
236
237
def chisquare(df, size=None):
238
"""
239
Draw samples from a chi-square distribution.
240
241
Parameters:
242
df: float or array_like of floats - Number of degrees of freedom, must be > 0
243
size: int or tuple of ints, optional - Output shape
244
"""
245
246
def exponential(scale=1.0, size=None):
247
"""
248
Draw samples from an exponential distribution.
249
250
Parameters:
251
scale: float or array_like of floats - Scale parameter, beta = 1/lambda (default is 1.0)
252
size: int or tuple of ints, optional - Output shape
253
"""
254
255
def f(dfnum, dfden, size=None):
256
"""
257
Draw samples from an F distribution.
258
259
Parameters:
260
dfnum: float or array_like of floats - Degrees of freedom in numerator, must be > 0
261
dfden: float or array_like of floats - Degrees of freedom in denominator, must be > 0
262
size: int or tuple of ints, optional - Output shape
263
"""
264
265
def gamma(shape, scale=1.0, size=None):
266
"""
267
Draw samples from a Gamma distribution.
268
269
Parameters:
270
shape: float or array_like of floats - Shape of the distribution, must be non-negative
271
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
272
size: int or tuple of ints, optional - Output shape
273
"""
274
275
def gumbel(loc=0.0, scale=1.0, size=None):
276
"""
277
Draw samples from a Gumbel distribution.
278
279
Parameters:
280
loc: float or array_like of floats, optional - Location of the distribution (default is 0.0)
281
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
282
size: int or tuple of ints, optional - Output shape
283
"""
284
285
def laplace(loc=0.0, scale=1.0, size=None):
286
"""
287
Draw samples from the Laplace or double exponential distribution.
288
289
Parameters:
290
loc: float or array_like of floats, optional - Location of the distribution (default is 0.0)
291
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
292
size: int or tuple of ints, optional - Output shape
293
"""
294
295
def logistic(loc=0.0, scale=1.0, size=None):
296
"""
297
Draw samples from a logistic distribution.
298
299
Parameters:
300
loc: float or array_like of floats, optional - Parameter of the distribution (default is 0.0)
301
scale: float or array_like of floats, optional - Parameter of the distribution (default is 1.0)
302
size: int or tuple of ints, optional - Output shape
303
"""
304
305
def lognormal(mean=0.0, sigma=1.0, size=None):
306
"""
307
Draw samples from a log-normal distribution.
308
309
Parameters:
310
mean: float or array_like of floats, optional - Mean of the underlying normal distribution (default is 0.0)
311
sigma: float or array_like of floats, optional - Standard deviation of the underlying normal distribution (default is 1.0)
312
size: int or tuple of ints, optional - Output shape
313
"""
314
315
def normal(loc=0.0, scale=1.0, size=None):
316
"""
317
Draw random samples from a normal (Gaussian) distribution.
318
319
Parameters:
320
loc: float or array_like of floats - Mean (centre) of the distribution
321
scale: float or array_like of floats - Standard deviation (spread or "width") of the distribution
322
size: int or tuple of ints, optional - Output shape
323
"""
324
325
def pareto(a, size=None):
326
"""
327
Draw samples from a Pareto II or Lomax distribution with specified shape.
328
329
Parameters:
330
a: float or array_like of floats - Shape of the distribution, must be positive
331
size: int or tuple of ints, optional - Output shape
332
"""
333
334
def power(a, size=None):
335
"""
336
Draws samples in [0, 1] from a power distribution with positive exponent a - 1.
337
338
Parameters:
339
a: float or array_like of floats - Parameter of the distribution, must be non-negative
340
size: int or tuple of ints, optional - Output shape
341
"""
342
343
def rayleigh(scale=1.0, size=None):
344
"""
345
Draw samples from a Rayleigh distribution.
346
347
Parameters:
348
scale: float or array_like of floats, optional - Scale, also equals the mode (default is 1.0)
349
size: int or tuple of ints, optional - Output shape
350
"""
351
352
def standard_cauchy(size=None):
353
"""
354
Draw samples from a standard Cauchy distribution with mode = 0.
355
356
Parameters:
357
size: int or tuple of ints, optional - Output shape
358
"""
359
360
def standard_exponential(size=None):
361
"""
362
Draw samples from the standard exponential distribution.
363
364
Parameters:
365
size: int or tuple of ints, optional - Output shape
366
"""
367
368
def standard_gamma(shape, size=None):
369
"""
370
Draw samples from a standard Gamma distribution.
371
372
Parameters:
373
shape: float or array_like of floats - Shape of the distribution, must be non-negative
374
size: int or tuple of ints, optional - Output shape
375
"""
376
377
def standard_normal(size=None):
378
"""
379
Draw samples from a standard Normal distribution (mean=0, stdev=1).
380
381
Parameters:
382
size: int or tuple of ints, optional - Output shape
383
"""
384
385
def standard_t(df, size=None):
386
"""
387
Draw samples from a standard Student's t distribution with df degrees of freedom.
388
389
Parameters:
390
df: float or array_like of floats - Degrees of freedom, must be > 0
391
size: int or tuple of ints, optional - Output shape
392
"""
393
394
def triangular(left, mode, right, size=None):
395
"""
396
Draw samples from the triangular distribution over the interval [left, right].
397
398
Parameters:
399
left: float or array_like of floats - Lower limit
400
mode: float or array_like of floats - Mode (peak) of the distribution
401
right: float or array_like of floats - Upper limit, must be larger than left
402
size: int or tuple of ints, optional - Output shape
403
"""
404
405
def uniform(low=0.0, high=1.0, size=None):
406
"""
407
Draw samples from a uniform distribution.
408
409
Parameters:
410
low: float or array_like of floats, optional - Lower boundary of the output interval (default is 0.0)
411
high: float or array_like of floats - Upper boundary of the output interval (default is 1.0)
412
size: int or tuple of ints, optional - Output shape
413
"""
414
415
def vonmises(mu, kappa, size=None):
416
"""
417
Draw samples from a von Mises distribution.
418
419
Parameters:
420
mu: float or array_like of floats - Mode ("center") of the distribution
421
kappa: float or array_like of floats - Dispersion of the distribution, must be ≥ 0
422
size: int or tuple of ints, optional - Output shape
423
"""
424
425
def wald(mean, scale, size=None):
426
"""
427
Draw samples from a Wald, or inverse Gaussian, distribution.
428
429
Parameters:
430
mean: float or array_like of floats - Distribution mean, must be > 0
431
scale: float or array_like of floats - Scale parameter, must be > 0
432
size: int or tuple of ints, optional - Output shape
433
"""
434
435
def weibull(a, size=None):
436
"""
437
Draw samples from a Weibull distribution.
438
439
Parameters:
440
a: float or array_like of floats - Shape parameter of the distribution, must be nonnegative
441
size: int or tuple of ints, optional - Output shape
442
"""
443
```
444
445
### Discrete Distributions
446
447
Random number generation from discrete probability distributions.
448
449
```python { .api }
450
def binomial(n, p, size=None):
451
"""
452
Draw samples from a binomial distribution.
453
454
Parameters:
455
n: int or array_like of ints - Parameter of the distribution, ≥ 0
456
p: float or array_like of floats - Parameter of the distribution, must be in the interval [0, 1]
457
size: int or tuple of ints, optional - Output shape
458
"""
459
460
def geometric(p, size=None):
461
"""
462
Draw samples from the geometric distribution.
463
464
Parameters:
465
p: float or array_like of floats - Success probability of a single trial, must be in (0, 1]
466
size: int or tuple of ints, optional - Output shape
467
"""
468
469
def hypergeometric(ngood, nbad, nsample, size=None):
470
"""
471
Draw samples from a Hypergeometric distribution.
472
473
Parameters:
474
ngood: int or array_like of ints - Number of ways to make a good selection, must be nonnegative
475
nbad: int or array_like of ints - Number of ways to make a bad selection, must be nonnegative
476
nsample: int or array_like of ints - Number of items sampled, must be at least 1 and at most ngood + nbad
477
size: int or tuple of ints, optional - Output shape
478
"""
479
480
def logseries(p, size=None):
481
"""
482
Draw samples from a logarithmic series distribution.
483
484
Parameters:
485
p: float or array_like of floats - Shape parameter for the distribution, must be in (0, 1)
486
size: int or tuple of ints, optional - Output shape
487
"""
488
489
def negative_binomial(n, p, size=None):
490
"""
491
Draw samples from a negative binomial distribution.
492
493
Parameters:
494
n: float or array_like of floats - Target number of successes, must be > 0
495
p: float or array_like of floats - Probability of success in any given trial, must be in (0, 1]
496
size: int or tuple of ints, optional - Output shape
497
"""
498
499
def poisson(lam=1.0, size=None):
500
"""
501
Draw samples from a Poisson distribution.
502
503
Parameters:
504
lam: float or array_like of floats - Expectation of interval, must be >= 0 (default is 1.0)
505
size: int or tuple of ints, optional - Output shape
506
"""
507
508
def zipf(a, size=None):
509
"""
510
Draw samples from a Zipf distribution.
511
512
Parameters:
513
a: float or array_like of floats - Distribution parameter, must be > 1
514
size: int or tuple of ints, optional - Output shape
515
"""
516
```
517
518
### Multivariate Distributions
519
520
Random number generation from multivariate probability distributions.
521
522
```python { .api }
523
def dirichlet(alpha, size=None):
524
"""
525
Draw samples from the Dirichlet distribution.
526
527
Parameters:
528
alpha: sequence of floats, length k - Parameter of the distribution (length k for sample of length k)
529
size: int or tuple of ints, optional - Output shape
530
"""
531
532
def multinomial(n, pvals, size=None):
533
"""
534
Draw samples from a multinomial distribution.
535
536
Parameters:
537
n: int - Number of experiments
538
pvals: sequence of floats, length k - Probabilities of each of the k different outcomes
539
size: int or tuple of ints, optional - Output shape
540
"""
541
542
def multivariate_normal(mean, cov, size=None, check_valid='warn', tol=1e-8):
543
"""
544
Draw random samples from a multivariate normal distribution.
545
546
Parameters:
547
mean: 1-D array_like, of length N - Mean of the N-dimensional distribution
548
cov: 2-D array_like, of shape (N, N) - Covariance matrix of the distribution
549
size: int or tuple of ints, optional - Given a shape of, for example, (m,n,k), m*n*k samples are generated
550
check_valid: { 'warn', 'raise', 'ignore' }, optional - Behavior when the covariance matrix is not positive semidefinite
551
tol: float, optional - Tolerance when checking the singular values in covariance matrix
552
"""
553
```
554
555
### Non-central Distributions
556
557
Non-central versions of chi-square and F distributions.
558
559
```python { .api }
560
def noncentral_chisquare(df, nonc, size=None):
561
"""
562
Draw samples from a noncentral chi-square distribution.
563
564
Parameters:
565
df: float or array_like of floats - Degrees of freedom, must be > 0
566
nonc: float or array_like of floats - Non-centrality, must be non-negative
567
size: int or tuple of ints, optional - Output shape
568
"""
569
570
def noncentral_f(dfnum, dfden, nonc, size=None):
571
"""
572
Draw samples from the noncentral F distribution.
573
574
Parameters:
575
dfnum: float or array_like of floats - Numerator degrees of freedom, must be > 0
576
dfden: float or array_like of floats - Denominator degrees of freedom, must be > 0
577
nonc: float or array_like of floats - Non-centrality parameter, the sum of the squares of the numerator means, must be >= 0
578
size: int or tuple of ints, optional - Output shape
579
"""
580
```
581
582
## Usage Examples
583
584
```python
585
import cupy as cp
586
import cupy.random as random
587
import matplotlib.pyplot as plt
588
589
# Set random seed for reproducibility
590
random.seed(42)
591
592
# Basic random number generation
593
uniform_data = random.random((1000, 1000))
594
normal_data = random.normal(0, 1, (1000, 1000))
595
integers = random.randint(0, 100, size=(10, 10))
596
597
# Using the new Generator API (recommended)
598
rng = random.default_rng(seed=42)
599
new_normal = rng.normal(0, 1, size=(1000,))
600
new_uniform = rng.random(size=(1000,))
601
602
# Different probability distributions
603
# Continuous distributions
604
beta_samples = random.beta(2, 5, size=1000)
605
gamma_samples = random.gamma(2, 2, size=1000)
606
exponential_samples = random.exponential(2, size=1000)
607
608
# Discrete distributions
609
binomial_samples = random.binomial(10, 0.5, size=1000)
610
poisson_samples = random.poisson(3, size=1000)
611
612
# Multivariate distributions
613
mean = [0, 0]
614
cov = [[1, 0.5], [0.5, 1]]
615
multivariate_samples = random.multivariate_normal(mean, cov, size=1000)
616
617
# Random sampling and permutations
618
data = cp.arange(100)
619
random.shuffle(data) # In-place shuffle
620
permuted = random.permutation(100) # New permuted array
621
choices = random.choice([1, 2, 3, 4, 5], size=20, p=[0.1, 0.2, 0.3, 0.3, 0.1])
622
623
# Statistical simulation example - Monte Carlo integration
624
def monte_carlo_pi(n_samples):
625
"""Estimate π using Monte Carlo method."""
626
x = random.uniform(-1, 1, n_samples)
627
y = random.uniform(-1, 1, n_samples)
628
inside_circle = (x**2 + y**2) <= 1
629
return 4 * cp.mean(inside_circle)
630
631
pi_estimate = monte_carlo_pi(1000000)
632
print(f"Estimated π: {pi_estimate}")
633
634
# Random walk simulation
635
def random_walk_2d(n_steps):
636
"""Simulate a 2D random walk."""
637
steps = random.choice([-1, 1], size=(n_steps, 2))
638
walk = cp.cumsum(steps, axis=0)
639
return walk
640
641
walk = random_walk_2d(1000)
642
643
# Bootstrap sampling
644
def bootstrap_mean(data, n_bootstrap=1000):
645
"""Calculate bootstrap confidence interval for the mean."""
646
n = len(data)
647
bootstrap_means = []
648
649
for _ in range(n_bootstrap):
650
bootstrap_sample = random.choice(data, size=n, replace=True)
651
bootstrap_means.append(cp.mean(bootstrap_sample))
652
653
bootstrap_means = cp.array(bootstrap_means)
654
return cp.percentile(bootstrap_means, [2.5, 97.5])
655
656
sample_data = random.normal(10, 2, 100)
657
confidence_interval = bootstrap_mean(sample_data)
658
659
# Random matrix generation
660
def random_correlation_matrix(n):
661
"""Generate a random positive definite correlation matrix."""
662
# Generate random matrix
663
A = random.normal(0, 1, (n, n))
664
# Make it positive definite
665
corr_matrix = cp.dot(A, A.T)
666
# Normalize to get correlations
667
d = cp.sqrt(cp.diag(corr_matrix))
668
corr_matrix = corr_matrix / cp.outer(d, d)
669
return corr_matrix
670
671
corr_mat = random_correlation_matrix(5)
672
673
# Stochastic process simulation - Geometric Brownian Motion
674
def geometric_brownian_motion(S0, mu, sigma, T, dt):
675
"""Simulate Geometric Brownian Motion (stock price model)."""
676
n_steps = int(T / dt)
677
t = cp.linspace(0, T, n_steps)
678
679
# Generate random increments
680
dW = random.normal(0, cp.sqrt(dt), n_steps-1)
681
682
# Calculate price path
683
log_returns = (mu - 0.5 * sigma**2) * dt + sigma * dW
684
log_S = cp.log(S0) + cp.cumsum(log_returns)
685
S = cp.concatenate([cp.array([S0]), cp.exp(log_S)])
686
687
return t, S
688
689
time, price_path = geometric_brownian_motion(S0=100, mu=0.05, sigma=0.2, T=1, dt=0.01)
690
691
# Performance comparison between different generators
692
def benchmark_generators(n_samples=1000000):
693
"""Compare performance of different random number generators."""
694
695
# Legacy RandomState
696
rs = random.RandomState(42)
697
698
# New Generator with XORWOW (default)
699
rng_xorwow = random.Generator(random.XORWOW(42))
700
701
# New Generator with Philox
702
rng_philox = random.Generator(random.Philox4x32_10(42))
703
704
import time
705
706
# Time legacy API
707
start = time.time()
708
legacy_data = rs.normal(0, 1, n_samples)
709
legacy_time = time.time() - start
710
711
# Time XORWOW
712
start = time.time()
713
xorwow_data = rng_xorwow.normal(0, 1, n_samples)
714
xorwow_time = time.time() - start
715
716
# Time Philox
717
start = time.time()
718
philox_data = rng_philox.normal(0, 1, n_samples)
719
philox_time = time.time() - start
720
721
return {
722
'legacy': legacy_time,
723
'xorwow': xorwow_time,
724
'philox': philox_time
725
}
726
727
# Multiple streams for parallel computation
728
def parallel_random_streams(n_streams, n_samples_per_stream):
729
"""Generate multiple independent random streams."""
730
streams = []
731
for i in range(n_streams):
732
rng = random.Generator(random.XORWOW(i))
733
stream_data = rng.normal(0, 1, n_samples_per_stream)
734
streams.append(stream_data)
735
return streams
736
737
parallel_data = parallel_random_streams(4, 1000)
738
```
739
740
## Performance Considerations
741
742
### Memory Efficiency
743
744
```python
745
# Generate random data directly on GPU to avoid host-device transfers
746
gpu_random = random.normal(0, 1, (10000, 10000)) # Already on GPU
747
748
# Use appropriate data types
749
float32_random = random.normal(0, 1, (10000,), dtype=cp.float32) # Uses less memory
750
```
751
752
### Reproducibility
753
754
```python
755
# Set global seed
756
random.seed(42)
757
758
# Use Generator for better control
759
rng = random.default_rng(42)
760
761
# For multiple parallel streams with different seeds
762
seeds = [42 + i for i in range(4)]
763
rngs = [random.default_rng(seed) for seed in seeds]
764
```
765
766
### Batch Operations
767
768
```python
769
# Generate large batches efficiently
770
batch_size = 1000000
771
batch_data = random.normal(0, 1, batch_size)
772
773
# Multiple distributions in one call
774
multi_normal = random.multivariate_normal([0, 0], [[1, 0], [0, 1]], size=100000)
775
```
776
777
Random number generation in CuPy provides comprehensive statistical sampling capabilities optimized for GPU acceleration, enabling efficient Monte Carlo simulations, statistical analysis, and stochastic modeling with familiar NumPy interfaces while leveraging the parallel processing power of modern GPUs.