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 定義がないため、直接数値を指定する必要があります。
数値とその意味については以下のようになっています。
数値意味
100XORWOW 型の擬似乱数を発生する
使用する乱数生成器によっては更に初期化が必要になります。
上記の例では擬似乱数発生器を XORWOW 型の乱数生成器を初期化し、更に乱数の seed を与えています。

乱数発生の方法

初めに乱数を保存する領域をデバイスメモリに確保しておきます。
Pointer pr = new Pointer();
cudaMalloc(pr, Sizeof.FLOAT * n);
指定された領域に乱数を格納するには、例えば一様乱数であれば
curandGenerateUniform(generator, pr, n);
とします。
乱数は区間 (0.0, 1.0] における float 型で返されることに注意してください。
そのため、メモリを確保するためには Sizeof.FLOAT を掛ける必要があります。 他の分布の乱数は以下を参照してください。
関数名説明
curandGenerate整数の一様乱数を返す
curandGenerateLongLong64ビット整数の一様乱数を返す
curandGenerateUniform区間(0.0,1.0]の一様乱数を返す
curandGenerateNormal指定された正規分布の乱数を返す
curandGenerateLogNormal指定された対数正規分布の乱数を返す
curandGeneratePoisson指定されたλ値を持つ Poisson 分布の乱数を返す
なお、CUDA 3.0 から cudaMalloc() で取得したデバイスメモリと cuMemAlloc() で取得したデバイスメモリは互換性があるため、両者を混在させることも可能です。
Copyright (c) 2017-2019 by TeqStock.tokyo