JCuda - jcurand の使い方
CUDA には付属のライブラリがいくつかありますが、jcurand は、乱数を発生させるライブラリです。
この記事では jcurand の使い方を説明します。
なお、現在の jcurand ライブラリは cuRAND のホスト API しかサポートしていません。
リンクする jar ファイル
jcurand の利用に当たっては、従来の jcuda.jar, jcuda-native-x86_64.jar の他、jcurand.jar, jcurand-native-x86_64.jar をリンクする必要があります。
jcurand の初期化
まず、JCuda を従来の方法で初期化しておきます。
cuInit(0);
CUcontext pctx = new CUcontext();
CUdevice dev = new CUdevice();
cuDeviecGet(dev, 0);
cuCtxCreate(pctx, 0, dev);
次に、generator を生成します。
private static final int CURAND_RNG_PSEUDO_DEFAULT = 100;
public static curandGenerator createGenerator(long long seed) {
curandGenerator = new curandGenerator();
curandCreateGenerator(curandGenerator, CURAND_RNG_PSEUDO_DEFAULT);
curandSetPseudoRandomGeneratorSeed(generator, seed);
return curandGenerator;
}
curandCreateGenerator の第2引数は生成する乱数系列種別ですが、enum 定義がないため、直接数値を指定する必要があります。
数値とその意味については以下のようになっています。
数値 | 意味 |
100 | XORWOW 型の擬似乱数を発生する |
使用する乱数生成器によっては更に初期化が必要になります。
上記の例では擬似乱数発生器を XORWOW 型の乱数生成器を初期化し、更に乱数の seed を与えています。
乱数発生の方法
初めに乱数を保存する領域をデバイスメモリに確保しておきます。
Pointer pr = new Pointer();
cudaMalloc(pr, Sizeof.FLOAT * n);
指定された領域に乱数を格納するには、例えば一様乱数であれば
curandGenerateUniform(generator, pr, n);
とします。
乱数は区間 (0.0, 1.0] における float 型で返されることに注意してください。
そのため、メモリを確保するためには Sizeof.FLOAT を掛ける必要があります。
他の分布の乱数は以下を参照してください。
関数名 | 説明 |
curandGenerate | 整数の一様乱数を返す |
curandGenerateLongLong | 64ビット整数の一様乱数を返す |
curandGenerateUniform | 区間(0.0,1.0]の一様乱数を返す |
curandGenerateNormal | 指定された正規分布の乱数を返す |
curandGenerateLogNormal | 指定された対数正規分布の乱数を返す |
curandGeneratePoisson | 指定されたλ値を持つ Poisson 分布の乱数を返す |
なお、CUDA 3.0 から cudaMalloc() で取得したデバイスメモリと cuMemAlloc() で取得したデバイスメモリは互換性があるため、両者を混在させることも可能です。
Copyright (c) 2017-2019 by TeqStock.tokyo