100000 (1M) までの numDraws の場合、次のことを簡単に行うことができます
def Simple_Elt(numDraws):
import numpy as np
gauss = np.random.normal
import pycuda.gpuarray as ga
from pycuda.cumath import exp as gaexp
import pycuda.autoinit
from pycuda.elementwise import ElementwiseKernel
npgausses = gauss(size=(numDraws,)).astype(np.float32)
gausses = ga.to_gpu(npgausses)
eltComp = """p[i] = exp(p[i]);"""
kernel = ElementwiseKernel("float *p", eltComp, "expnorm")
kernel(gausses)
sumEN = ga.sum(gausses).get()
Simple_Elt(1000000)
ただし、N = 10000000 (10M) の場合、ランダムな値を GPU に転送するときに GPU メモリが不足します。一度に 2 つの問題を解決したいと考えています。(1) GPU を効率的に使用して乱数を生成し、(2) サイズ制限を取り除きます。
今、私はそれを行う最善の方法がわかりません。ここのコードは、「生の」PyCUDA を使用して、CPU で生成された一様乱数から Box-Muller を実行するカスタム通常乱数ジェネレーターを作成する方法を示していますが、CURAND を使用する方が理にかなっていると思います。ただし、PyCuda の CURAND インターフェイスを使用すると、同じサイズ制限が課せられるようです (そして、多くの乱数ジェネレーターが作成され、オーバーヘッドが高くなると思います。これは、PyCUDA CURAND API ドキュメントの警告hereからのものです。したがって、使用する可能性があると思います基礎となる CURAND へのカスタム呼び出しを含む PyCUDA これはすべて推測作業です。
しかし、私の本当の質問は、上記の 2 つの問題を解決する最善の方法です。
例、ポインタ、および提案は大歓迎です。