ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 3.7。随机数生成 > 原文: [http://numba.pydata.org/numba-doc/latest/cuda/random.html](http://numba.pydata.org/numba-doc/latest/cuda/random.html) Numba 提供可在 GPU 上执行的随机数生成算法。然而,由于 NVIDIA 如何实施 cuRAND 的技术问题,Numba 的 GPU 随机数发生器并非基于 cuRAND。相反,Numba 的 GPU RNG 是 [xoroshiro128 +算法](http://xoroshiro.di.unimi.it/)的实现。 xoroshiro128 +算法的周期为`2**128 - 1`,短于 cuRAND 默认使用的 XORWOW 算法的周期,但 xoroshiro128 +仍然通过随机数生成器质量的 BigCrush 测试。 在 GPU 上使用任何 RNG 时,务必确保每个线程都有自己的 RNG 状态,并且已经初始化它们以生成非重叠序列。 numba.cuda.random 模块提供了执行此操作的主机功能,以及用于获取均匀或正态分布的随机数的 CUDA 设备功能。 注意 Numba(如 cuRAND)使用 &lt;cite&gt;Box-Muller 变换&lt; https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform&gt;&lt;/cite&gt; 从均匀发生器生成正态分布的随机数。但是,Box-Muller 会生成一对随机数,而当前的实现仅返回其中一个。结果,生成正态分布值是均匀分布值的一半。 ```py numba.cuda.random.create_xoroshiro128p_states(n, seed, subsequence_start=0, stream=0) ``` 返回为 n 个随机数生成器初始化的新设备数组。 这初始化了 RNG 状态,使得阵列中的每个状态对应于主序列中彼此分开 2 ** 64 步的子序列。因此,只要没有 CUDA 线程请求超过 2 ** 64 个随机数,该函数产生的所有 RNG 状态都保证是独立的。 subsequence_start 参数可用于使第一 RNG 状态前进 2 ** 64 步的倍数。 | 参数: | * **n** ( [_int_](https://docs.python.org/3/library/functions.html#int "(in Python v3.7)")) - 产生 * **种子**的 RNG 状态数 _uint64_ ) - 发生器列表的起始种子 * **subsequence_start** ( _uint64_ ) - * **流**( _CUDA 流 _) - 在 上运行初始化内核的流 | | --- | --- | ```py numba.cuda.random.init_xoroshiro128p_states(states, seed, subsequence_start=0, stream=0) ``` 在 GPU 上为并行生成器初始化 RNG 状态。 这初始化了 RNG 状态,使得阵列中的每个状态对应于主序列中彼此分开 2 ** 64 步的子序列。因此,只要没有 CUDA 线程请求超过 2 ** 64 个随机数,该函数产生的所有 RNG 状态都保证是独立的。 subsequence_start 参数可用于使第一 RNG 状态前进 2 ** 64 步的倍数。 | 参数: | * **状态**( _1D DeviceNDArray_ _,_ _dtype = xoroshiro128p_dtype_ ) - RNG 状态数组 * **种子**( _uint64_ ) - 发生器列表的起始种子 | | --- | --- | ```py numba.cuda.random.xoroshiro128p_uniform_float32 ``` 返回范围[0.0,1.0)中的 float32 并前进`states[index]`。 | 参数: | * **状态**( _1D 阵列 _ _,_ _dtype = xoroshiro128p_dtype_ ) - RNG 状态数组 * **指数**( _int64_ ) - 更新状态的偏移 | | --- | --- | | 返回类型: | FLOAT32 | | --- | --- | ```py numba.cuda.random.xoroshiro128p_uniform_float64 ``` 返回范围[0.0,1.0)中的 float64 并前进`states[index]`。 | 参数: | * **状态**( _1D 阵列 _ _,_ _dtype = xoroshiro128p_dtype_ ) - RNG 状态数组 * **指数**( _int64_ ) - 更新状态的偏移 | | --- | --- | | 返回类型: | float64 | | --- | --- | ```py numba.cuda.random.xoroshiro128p_normal_float32 ``` 返回正态分布的 float32 并前进`states[index]`。 使用 Box-Muller 变换从高斯均值= 0 和 sigma = 1 绘制返回值。这使 RNG 序列前进两步。 | 参数: | * **状态**( _1D 阵列 _ _,_ _dtype = xoroshiro128p_dtype_ ) - RNG 状态数组 * **指数**( _int64_ ) - 更新状态的偏移 | | --- | --- | | 返回类型: | FLOAT32 | | --- | --- | ```py numba.cuda.random.xoroshiro128p_normal_float64 ``` 返回正态分布的 float32 并前进`states[index]`。 使用 Box-Muller 变换从高斯均值= 0 和 sigma = 1 绘制返回值。这使 RNG 序列前进两步。 | 参数: | * **状态**( _1D 阵列 _ _,_ _dtype = xoroshiro128p_dtype_ ) - RNG 状态数组 * **指数**( _int64_ ) - 更新状态的偏移 | | --- | --- | | 返回类型: | float64 | | --- | --- | ## 3.7.1。示例 这是一个使用随机数生成器的示例程序: ```py from __future__ import print_function, absolute_import from numba import cuda from numba.cuda.random import create_xoroshiro128p_states, xoroshiro128p_uniform_float32 import numpy as np @cuda.jit def compute_pi(rng_states, iterations, out): """Find the maximum value in values and store in result[0]""" thread_id = cuda.grid(1) # Compute pi by drawing random (x, y) points and finding what # fraction lie inside a unit circle inside = 0 for i in range(iterations): x = xoroshiro128p_uniform_float32(rng_states, thread_id) y = xoroshiro128p_uniform_float32(rng_states, thread_id) if x**2 + y**2 <= 1.0: inside += 1 out[thread_id] = 4.0 * inside / iterations threads_per_block = 64 blocks = 24 rng_states = create_xoroshiro128p_states(threads_per_block * blocks, seed=1) out = np.zeros(threads_per_block * blocks, dtype=np.float32) compute_pi[blocks, threads_per_block](rng_states, 10000, out) print('pi:', out.mean()) ```