1. 程式人生 > 實用技巧 >適用於CUDA GPU的Numba 隨機數生成

適用於CUDA GPU的Numba 隨機數生成

適用於CUDA GPU的Numba隨機數生成

隨機數生成

Numba提供了可以在GPU上執行的隨機數生成演算法。由於NVIDIA如何實現cuRAND的技術問題,Numba的GPU隨機數生成器並非基於cuRAND。相反,Numba的GPU RNG是xoroshiro128 +演算法的實現。xoroshiro128 +演算法的週期為2**128-1,比cuRAND中預設使用的XORWOW演算法的週期短,但是xoroshiro128 +演算法仍然通過了隨機數發生器質量的BigCrush測試。

在GPU上使用任何RNG時,重要的是要確保每個執行緒都有其自己的RNG狀態,並且它們已初始化為產生不重疊的序列。numba.cuda.random模組提供了執行此操作的主機功能,以及提供統一或正態分佈的隨機數的CUDA裝置功能。

注意

Numba (like cuRAND) uses the Box-Muller transform <https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform>從統一生成器生成正態分佈的隨機數。但是,Box-Muller生成隨機數對,當前實現只返回其中之一。結果,生成正態分佈的值是均勻分佈的值的速度的一半。

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步的倍數。

引數:

  • nint)–要建立的RNG狀態數
  • seeduint64)–生成器列表的起始種子
  • subsequence_startuint64)–
  • StreamCUDA流)–在其上執行初始化核心的流

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步的倍數。

引數:

  • states (1D DeviceNDArray, dtype=xoroshiro128p_dtype)– RNG狀態陣列
  • seeduint64)–生成器列表的起始種子

numba.cuda.random.xoroshiro128p_uniform_float32

返回範圍為[0.0,1.0)的float32並前進states[index]

引數:

  • states (1D DeviceNDArray, dtype=xoroshiro128p_dtype)– RNG狀態陣列
  • indexint64)–要更新的狀態的偏移量

返回型別:

float32

numba.cuda.random.xoroshiro128p_uniform_float64

返回範圍為[0.0,1.0)的float64並前進states[index]

引數:

  • 狀態states (1D array, dtype=xoroshiro128p_dtype)– RNG狀態陣列
  • indexint64)–要更新的狀態的偏移量

返回型別:

float64

numba.cuda.random.xoroshiro128p_normal_float32

返回正態分佈的float32並前進states[index]

使用Box-Muller變換從平均值= 0和sigma = 1的高斯中得出返回值。這使RNG序列前進了兩個步驟。

引數:

  • states (1D array, dtype=xoroshiro128p_dtype)– RNG狀態陣列
  • indexint64)–要更新的狀態的偏移量

返回型別:

float32

numba.cuda.random.xoroshiro128p_normal_float64

返回正態分佈的float32並前進states[index]

使用Box-Muller變換從平均值= 0和sigma = 1的高斯中得出返回值。這使RNG序列前進了兩個步驟。

引數:

  • 狀態states (1D array, dtype=xoroshiro128p_dtype)– RNG狀態陣列
  • indexint64)–要更新的狀態的偏移量

返回型別:

float64

這是使用隨機數生成器的示例程式:

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())