CuPy: NumPy & SciPy for GPU - CUDA 11.x optimized distribution providing GPU-accelerated computing with Python
—
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.
Core random number generation infrastructure supporting multiple algorithms and state management.
class Generator:
"""
Container for the BitGenerator used to generate random numbers.
Generator exposes a number of methods for generating random numbers
drawn from a variety of probability distributions.
"""
def __init__(self, bit_generator): ...
def default_rng(seed=None):
"""
Construct a new Generator with the default BitGenerator (XORWOW).
Parameters:
seed: {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional - A seed to initialize the BitGenerator
"""
class RandomState:
"""
Container for the Mersenne Twister pseudo-random number generator.
RandomState exposes a number of methods for generating random numbers
drawn from a variety of probability distributions. This is the legacy
random API, users should prefer the new Generator API.
"""
def __init__(self, seed=None): ...
def get_random_state():
"""
Returns the random state for the current device.
"""
def set_random_state(rs):
"""
Sets the random state for the current device.
Parameters:
rs: RandomState - The random state to set
"""
def seed(seed=None):
"""
Seed the generator.
Parameters:
seed: int or 1-d array_like, optional - Seed for RandomState
"""
def reset_states():
"""
Reset the random states on all devices.
"""Low-level random bit generators providing the foundation for random number generation.
class BitGenerator:
"""
Base class for bit generators used by Generator.
Bit generators provide a stream of random bits which are then
transformed by the Generator class into useful random numbers.
"""
class XORWOW(BitGenerator):
"""
BitGenerator for XORWOW algorithm.
XORWOW is the default bit generator used by cuRAND and provides
good performance on GPU architectures.
"""
def __init__(self, seed=None): ...
class MRG32k3a(BitGenerator):
"""
BitGenerator for MRG32k3a algorithm.
MRG32k3a provides a long period and good statistical properties
but may be slower than XORWOW on some architectures.
"""
def __init__(self, seed=None): ...
class Philox4x32_10(BitGenerator):
"""
BitGenerator for Philox4x32-10 algorithm.
Philox provides counter-based random number generation which
allows for reproducible parallel random number generation.
"""
def __init__(self, seed=None): ...Basic random number generation functions for uniform and normal distributions.
def rand(*dn):
"""
Random values in a given shape.
Parameters:
dn: int - Dimensions of the returned array, should be all positive
"""
def randn(*dn):
"""
Return a sample (or samples) from the "standard normal" distribution.
Parameters:
dn: int - Dimensions of the returned array, should be all positive
"""
def randint(low, high=None, size=None, dtype=int):
"""
Return random integers from low (inclusive) to high (exclusive).
Parameters:
low: int or array-like of ints - Lowest (signed) integers to be drawn from the distribution
high: int or array-like of ints, optional - One above the largest (signed) integer to be drawn from the distribution
size: int or tuple of ints, optional - Output shape
dtype: dtype, optional - Desired dtype of the result
"""
def random_integers(low, high=None, size=None):
"""
Random integers of type int between low and high, inclusive.
Parameters:
low: int - Lowest (signed) integer to be drawn from the distribution
high: int, optional - Highest (signed) integer to be drawn from the distribution
size: int or tuple of ints, optional - Output shape
"""
def random_sample(size=None):
"""
Return random floats in the half-open interval [0.0, 1.0).
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def random(size=None):
"""
Return random floats in the half-open interval [0.0, 1.0).
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def ranf(size=None):
"""
Return random floats in the half-open interval [0.0, 1.0).
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def sample(size=None):
"""
Return random floats in the half-open interval [0.0, 1.0).
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def choice(a, size=None, replace=True, p=None):
"""
Generates a random sample from a given 1-D array.
Parameters:
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)
size: int or tuple of ints, optional - Output shape
replace: boolean, optional - Whether the sample is with or without replacement (default is True)
p: 1-D array-like, optional - Probabilities associated with each entry in a
"""
def bytes(length):
"""
Return random bytes.
Parameters:
length: int - Number of random bytes
"""Functions for shuffling and permuting arrays and sequences.
def shuffle(x):
"""
Modify a sequence in-place by shuffling its contents.
Parameters:
x: array_like - The array or list to be shuffled
"""
def permutation(x):
"""
Randomly permute a sequence, or return a permuted range.
Parameters:
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
"""Random number generation from continuous probability distributions.
def beta(a, b, size=None):
"""
Draw samples from a Beta distribution.
Parameters:
a: float or array_like of floats - Alpha, positive (>0)
b: float or array_like of floats - Beta, positive (>0)
size: int or tuple of ints, optional - Output shape
"""
def chisquare(df, size=None):
"""
Draw samples from a chi-square distribution.
Parameters:
df: float or array_like of floats - Number of degrees of freedom, must be > 0
size: int or tuple of ints, optional - Output shape
"""
def exponential(scale=1.0, size=None):
"""
Draw samples from an exponential distribution.
Parameters:
scale: float or array_like of floats - Scale parameter, beta = 1/lambda (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def f(dfnum, dfden, size=None):
"""
Draw samples from an F distribution.
Parameters:
dfnum: float or array_like of floats - Degrees of freedom in numerator, must be > 0
dfden: float or array_like of floats - Degrees of freedom in denominator, must be > 0
size: int or tuple of ints, optional - Output shape
"""
def gamma(shape, scale=1.0, size=None):
"""
Draw samples from a Gamma distribution.
Parameters:
shape: float or array_like of floats - Shape of the distribution, must be non-negative
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def gumbel(loc=0.0, scale=1.0, size=None):
"""
Draw samples from a Gumbel distribution.
Parameters:
loc: float or array_like of floats, optional - Location of the distribution (default is 0.0)
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def laplace(loc=0.0, scale=1.0, size=None):
"""
Draw samples from the Laplace or double exponential distribution.
Parameters:
loc: float or array_like of floats, optional - Location of the distribution (default is 0.0)
scale: float or array_like of floats, optional - Scale of the distribution (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def logistic(loc=0.0, scale=1.0, size=None):
"""
Draw samples from a logistic distribution.
Parameters:
loc: float or array_like of floats, optional - Parameter of the distribution (default is 0.0)
scale: float or array_like of floats, optional - Parameter of the distribution (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def lognormal(mean=0.0, sigma=1.0, size=None):
"""
Draw samples from a log-normal distribution.
Parameters:
mean: float or array_like of floats, optional - Mean of the underlying normal distribution (default is 0.0)
sigma: float or array_like of floats, optional - Standard deviation of the underlying normal distribution (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def normal(loc=0.0, scale=1.0, size=None):
"""
Draw random samples from a normal (Gaussian) distribution.
Parameters:
loc: float or array_like of floats - Mean (centre) of the distribution
scale: float or array_like of floats - Standard deviation (spread or "width") of the distribution
size: int or tuple of ints, optional - Output shape
"""
def pareto(a, size=None):
"""
Draw samples from a Pareto II or Lomax distribution with specified shape.
Parameters:
a: float or array_like of floats - Shape of the distribution, must be positive
size: int or tuple of ints, optional - Output shape
"""
def power(a, size=None):
"""
Draws samples in [0, 1] from a power distribution with positive exponent a - 1.
Parameters:
a: float or array_like of floats - Parameter of the distribution, must be non-negative
size: int or tuple of ints, optional - Output shape
"""
def rayleigh(scale=1.0, size=None):
"""
Draw samples from a Rayleigh distribution.
Parameters:
scale: float or array_like of floats, optional - Scale, also equals the mode (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def standard_cauchy(size=None):
"""
Draw samples from a standard Cauchy distribution with mode = 0.
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def standard_exponential(size=None):
"""
Draw samples from the standard exponential distribution.
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def standard_gamma(shape, size=None):
"""
Draw samples from a standard Gamma distribution.
Parameters:
shape: float or array_like of floats - Shape of the distribution, must be non-negative
size: int or tuple of ints, optional - Output shape
"""
def standard_normal(size=None):
"""
Draw samples from a standard Normal distribution (mean=0, stdev=1).
Parameters:
size: int or tuple of ints, optional - Output shape
"""
def standard_t(df, size=None):
"""
Draw samples from a standard Student's t distribution with df degrees of freedom.
Parameters:
df: float or array_like of floats - Degrees of freedom, must be > 0
size: int or tuple of ints, optional - Output shape
"""
def triangular(left, mode, right, size=None):
"""
Draw samples from the triangular distribution over the interval [left, right].
Parameters:
left: float or array_like of floats - Lower limit
mode: float or array_like of floats - Mode (peak) of the distribution
right: float or array_like of floats - Upper limit, must be larger than left
size: int or tuple of ints, optional - Output shape
"""
def uniform(low=0.0, high=1.0, size=None):
"""
Draw samples from a uniform distribution.
Parameters:
low: float or array_like of floats, optional - Lower boundary of the output interval (default is 0.0)
high: float or array_like of floats - Upper boundary of the output interval (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def vonmises(mu, kappa, size=None):
"""
Draw samples from a von Mises distribution.
Parameters:
mu: float or array_like of floats - Mode ("center") of the distribution
kappa: float or array_like of floats - Dispersion of the distribution, must be ≥ 0
size: int or tuple of ints, optional - Output shape
"""
def wald(mean, scale, size=None):
"""
Draw samples from a Wald, or inverse Gaussian, distribution.
Parameters:
mean: float or array_like of floats - Distribution mean, must be > 0
scale: float or array_like of floats - Scale parameter, must be > 0
size: int or tuple of ints, optional - Output shape
"""
def weibull(a, size=None):
"""
Draw samples from a Weibull distribution.
Parameters:
a: float or array_like of floats - Shape parameter of the distribution, must be nonnegative
size: int or tuple of ints, optional - Output shape
"""Random number generation from discrete probability distributions.
def binomial(n, p, size=None):
"""
Draw samples from a binomial distribution.
Parameters:
n: int or array_like of ints - Parameter of the distribution, ≥ 0
p: float or array_like of floats - Parameter of the distribution, must be in the interval [0, 1]
size: int or tuple of ints, optional - Output shape
"""
def geometric(p, size=None):
"""
Draw samples from the geometric distribution.
Parameters:
p: float or array_like of floats - Success probability of a single trial, must be in (0, 1]
size: int or tuple of ints, optional - Output shape
"""
def hypergeometric(ngood, nbad, nsample, size=None):
"""
Draw samples from a Hypergeometric distribution.
Parameters:
ngood: int or array_like of ints - Number of ways to make a good selection, must be nonnegative
nbad: int or array_like of ints - Number of ways to make a bad selection, must be nonnegative
nsample: int or array_like of ints - Number of items sampled, must be at least 1 and at most ngood + nbad
size: int or tuple of ints, optional - Output shape
"""
def logseries(p, size=None):
"""
Draw samples from a logarithmic series distribution.
Parameters:
p: float or array_like of floats - Shape parameter for the distribution, must be in (0, 1)
size: int or tuple of ints, optional - Output shape
"""
def negative_binomial(n, p, size=None):
"""
Draw samples from a negative binomial distribution.
Parameters:
n: float or array_like of floats - Target number of successes, must be > 0
p: float or array_like of floats - Probability of success in any given trial, must be in (0, 1]
size: int or tuple of ints, optional - Output shape
"""
def poisson(lam=1.0, size=None):
"""
Draw samples from a Poisson distribution.
Parameters:
lam: float or array_like of floats - Expectation of interval, must be >= 0 (default is 1.0)
size: int or tuple of ints, optional - Output shape
"""
def zipf(a, size=None):
"""
Draw samples from a Zipf distribution.
Parameters:
a: float or array_like of floats - Distribution parameter, must be > 1
size: int or tuple of ints, optional - Output shape
"""Random number generation from multivariate probability distributions.
def dirichlet(alpha, size=None):
"""
Draw samples from the Dirichlet distribution.
Parameters:
alpha: sequence of floats, length k - Parameter of the distribution (length k for sample of length k)
size: int or tuple of ints, optional - Output shape
"""
def multinomial(n, pvals, size=None):
"""
Draw samples from a multinomial distribution.
Parameters:
n: int - Number of experiments
pvals: sequence of floats, length k - Probabilities of each of the k different outcomes
size: int or tuple of ints, optional - Output shape
"""
def multivariate_normal(mean, cov, size=None, check_valid='warn', tol=1e-8):
"""
Draw random samples from a multivariate normal distribution.
Parameters:
mean: 1-D array_like, of length N - Mean of the N-dimensional distribution
cov: 2-D array_like, of shape (N, N) - Covariance matrix of the distribution
size: int or tuple of ints, optional - Given a shape of, for example, (m,n,k), m*n*k samples are generated
check_valid: { 'warn', 'raise', 'ignore' }, optional - Behavior when the covariance matrix is not positive semidefinite
tol: float, optional - Tolerance when checking the singular values in covariance matrix
"""Non-central versions of chi-square and F distributions.
def noncentral_chisquare(df, nonc, size=None):
"""
Draw samples from a noncentral chi-square distribution.
Parameters:
df: float or array_like of floats - Degrees of freedom, must be > 0
nonc: float or array_like of floats - Non-centrality, must be non-negative
size: int or tuple of ints, optional - Output shape
"""
def noncentral_f(dfnum, dfden, nonc, size=None):
"""
Draw samples from the noncentral F distribution.
Parameters:
dfnum: float or array_like of floats - Numerator degrees of freedom, must be > 0
dfden: float or array_like of floats - Denominator degrees of freedom, must be > 0
nonc: float or array_like of floats - Non-centrality parameter, the sum of the squares of the numerator means, must be >= 0
size: int or tuple of ints, optional - Output shape
"""import cupy as cp
import cupy.random as random
import matplotlib.pyplot as plt
# Set random seed for reproducibility
random.seed(42)
# Basic random number generation
uniform_data = random.random((1000, 1000))
normal_data = random.normal(0, 1, (1000, 1000))
integers = random.randint(0, 100, size=(10, 10))
# Using the new Generator API (recommended)
rng = random.default_rng(seed=42)
new_normal = rng.normal(0, 1, size=(1000,))
new_uniform = rng.random(size=(1000,))
# Different probability distributions
# Continuous distributions
beta_samples = random.beta(2, 5, size=1000)
gamma_samples = random.gamma(2, 2, size=1000)
exponential_samples = random.exponential(2, size=1000)
# Discrete distributions
binomial_samples = random.binomial(10, 0.5, size=1000)
poisson_samples = random.poisson(3, size=1000)
# Multivariate distributions
mean = [0, 0]
cov = [[1, 0.5], [0.5, 1]]
multivariate_samples = random.multivariate_normal(mean, cov, size=1000)
# Random sampling and permutations
data = cp.arange(100)
random.shuffle(data) # In-place shuffle
permuted = random.permutation(100) # New permuted array
choices = random.choice([1, 2, 3, 4, 5], size=20, p=[0.1, 0.2, 0.3, 0.3, 0.1])
# Statistical simulation example - Monte Carlo integration
def monte_carlo_pi(n_samples):
"""Estimate π using Monte Carlo method."""
x = random.uniform(-1, 1, n_samples)
y = random.uniform(-1, 1, n_samples)
inside_circle = (x**2 + y**2) <= 1
return 4 * cp.mean(inside_circle)
pi_estimate = monte_carlo_pi(1000000)
print(f"Estimated π: {pi_estimate}")
# Random walk simulation
def random_walk_2d(n_steps):
"""Simulate a 2D random walk."""
steps = random.choice([-1, 1], size=(n_steps, 2))
walk = cp.cumsum(steps, axis=0)
return walk
walk = random_walk_2d(1000)
# Bootstrap sampling
def bootstrap_mean(data, n_bootstrap=1000):
"""Calculate bootstrap confidence interval for the mean."""
n = len(data)
bootstrap_means = []
for _ in range(n_bootstrap):
bootstrap_sample = random.choice(data, size=n, replace=True)
bootstrap_means.append(cp.mean(bootstrap_sample))
bootstrap_means = cp.array(bootstrap_means)
return cp.percentile(bootstrap_means, [2.5, 97.5])
sample_data = random.normal(10, 2, 100)
confidence_interval = bootstrap_mean(sample_data)
# Random matrix generation
def random_correlation_matrix(n):
"""Generate a random positive definite correlation matrix."""
# Generate random matrix
A = random.normal(0, 1, (n, n))
# Make it positive definite
corr_matrix = cp.dot(A, A.T)
# Normalize to get correlations
d = cp.sqrt(cp.diag(corr_matrix))
corr_matrix = corr_matrix / cp.outer(d, d)
return corr_matrix
corr_mat = random_correlation_matrix(5)
# Stochastic process simulation - Geometric Brownian Motion
def geometric_brownian_motion(S0, mu, sigma, T, dt):
"""Simulate Geometric Brownian Motion (stock price model)."""
n_steps = int(T / dt)
t = cp.linspace(0, T, n_steps)
# Generate random increments
dW = random.normal(0, cp.sqrt(dt), n_steps-1)
# Calculate price path
log_returns = (mu - 0.5 * sigma**2) * dt + sigma * dW
log_S = cp.log(S0) + cp.cumsum(log_returns)
S = cp.concatenate([cp.array([S0]), cp.exp(log_S)])
return t, S
time, price_path = geometric_brownian_motion(S0=100, mu=0.05, sigma=0.2, T=1, dt=0.01)
# Performance comparison between different generators
def benchmark_generators(n_samples=1000000):
"""Compare performance of different random number generators."""
# Legacy RandomState
rs = random.RandomState(42)
# New Generator with XORWOW (default)
rng_xorwow = random.Generator(random.XORWOW(42))
# New Generator with Philox
rng_philox = random.Generator(random.Philox4x32_10(42))
import time
# Time legacy API
start = time.time()
legacy_data = rs.normal(0, 1, n_samples)
legacy_time = time.time() - start
# Time XORWOW
start = time.time()
xorwow_data = rng_xorwow.normal(0, 1, n_samples)
xorwow_time = time.time() - start
# Time Philox
start = time.time()
philox_data = rng_philox.normal(0, 1, n_samples)
philox_time = time.time() - start
return {
'legacy': legacy_time,
'xorwow': xorwow_time,
'philox': philox_time
}
# Multiple streams for parallel computation
def parallel_random_streams(n_streams, n_samples_per_stream):
"""Generate multiple independent random streams."""
streams = []
for i in range(n_streams):
rng = random.Generator(random.XORWOW(i))
stream_data = rng.normal(0, 1, n_samples_per_stream)
streams.append(stream_data)
return streams
parallel_data = parallel_random_streams(4, 1000)# Generate random data directly on GPU to avoid host-device transfers
gpu_random = random.normal(0, 1, (10000, 10000)) # Already on GPU
# Use appropriate data types
float32_random = random.normal(0, 1, (10000,), dtype=cp.float32) # Uses less memory# Set global seed
random.seed(42)
# Use Generator for better control
rng = random.default_rng(42)
# For multiple parallel streams with different seeds
seeds = [42 + i for i in range(4)]
rngs = [random.default_rng(seed) for seed in seeds]# Generate large batches efficiently
batch_size = 1000000
batch_data = random.normal(0, 1, batch_size)
# Multiple distributions in one call
multi_normal = random.multivariate_normal([0, 0], [[1, 0], [0, 1]], size=100000)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.
Install with Tessl CLI
npx tessl i tessl/pypi-cupy-cuda11x