# 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)使用 <cite>Box-Muller 变换&lt; https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform></cite> 从均匀发生器生成正态分布的随机数。但是,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())
```
- 1. 用户手册
- 1.1。 Numba 的约 5 分钟指南
- 1.2。概述
- 1.3。安装
- 1.4。使用@jit 编译 Python 代码
- 1.5。使用@generated_jit 进行灵活的专业化
- 1.6。创建 Numpy 通用函数
- 1.7。用@jitclass 编译 python 类
- 1.8。使用@cfunc 创建 C 回调
- 1.9。提前编译代码
- 1.10。使用@jit 自动并行化
- 1.11。使用@stencil装饰器
- 1.12。从 JIT 代码 中回调到 Python 解释器
- 1.13。性能提示
- 1.14。线程层
- 1.15。故障排除和提示
- 1.16。常见问题
- 1.17。示例
- 1.18。会谈和教程
- 2. 参考手册
- 2.1。类型和签名
- 2.2。即时编译
- 2.3。提前编译
- 2.4。公用事业
- 2.5。环境变量
- 2.6。支持的 Python 功能
- 2.7。支持的 NumPy 功能
- 2.8。与 Python 语义的偏差
- 2.9。浮点陷阱
- 2.10。 Python 2.7 寿命终止计划
- 3. 用于 CUDA GPU 的 Numba
- 3.1。概述
- 3.2。编写 CUDA 内核
- 3.3。内存管理
- 3.4。编写设备功能
- 3.5。 CUDA Python 中支持的 Python 功能
- 3.6。支持的原子操作
- 3.7。随机数生成
- 3.8。设备管理
- 3.10。示例
- 3.11。使用 CUDA 模拟器 调试 CUDA Python
- 3.12。 GPU 减少
- 3.13。 CUDA Ufuncs 和广义 Ufuncs
- 3.14。共享 CUDA 内存
- 3.15。 CUDA 阵列接口
- 3.16。 CUDA 常见问题
- 4. CUDA Python 参考
- 4.1。 CUDA 主机 API
- 4.2。 CUDA 内核 API
- 4.3。内存管理
- 5. 用于 AMD ROC GPU 的 Numba
- 5.1。概述
- 5.2。编写 HSA 内核
- 5.3。内存管理
- 5.4。编写设备功能
- 5.5。支持的原子操作
- 5.6。代理商
- 5.7。 ROC Ufuncs 和广义 Ufuncs
- 5.8。示例
- 6. 扩展 Numba
- 6.1。高级扩展 API
- 6.2。低级扩展 API
- 6.3。示例:间隔类型
- 7. 开发者手册
- 7.1。贡献给 Numba
- 7.2。 Numba 建筑
- 7.3。多态调度
- 7.4。关于发电机的注意事项
- 7.5。关于 Numba Runtime 的注意事项
- 7.6。使用 Numba Rewrite Pass 获得乐趣和优化
- 7.7。实时变量分析
- 7.8。上市
- 7.9。模板注释
- 7.10。关于自定义管道的注意事项
- 7.11。环境对象
- 7.12。哈希 的注意事项
- 7.13。 Numba 项目路线图
- 8. Numba 增强建议
- 9. 术语表