CUDA的隨機數生成方法

本博客已遷往http://coredumper.cn


CUDA Runtime API 沒有提供用於生成隨機數的接口,但是CURAND這個庫提供了通過GPU生成隨機數的接口,詳細內容可參考http://docs.nvidia.com/cuda/curand/index.html

下面給出了通過GPU生成0.0到1.0之間(不包括0.0,包括1.0)服從均勻分佈的單精度浮點僞隨機數的CUDA程序。

#include <cuda.h>
#include <curand.h>

#define ERROR_EXIT -1

/* Check the return value of CUDA Runtime API */
#define CHECK_CUDA(err) do{\
    if((err) != cudaSuccess){\
        fprintf(stderr, "CUDA Runtime API error %d at file %s line %d: %s.\n",\
                               (int)(err), __FILE__, __LINE__, cudaGetErrorString((err)));\
        exit(ERROR_EXIT);\
    }}while(0)

/* Check the return value of CURAND api. */
#define CHECK_CURAND(err) do{\
    if( (err) != CURAND_STATUS_SUCCESS ){\
        fprintf(stderr, "CURAND error %d at file %s line %d.\n", (int)(err), __FILE__, __LINE__);\
	exit(ERROR_EXIT);\
    }}while(0)

/* Function: produce random float data by GPU
 * Input:   dataHost: the memory to store data produced
 *          number: the number of data to produce
 *          seed: the seed for random generator
 * Output: void
 */
extern "C"
void randomGenerator(float *dataHost, int number, unsigned long long seed)
{   
    float *dataDev;
    CHECK_CUDA( cudaMalloc( (void **) &dataDev, number * sizeof(float) ) );

    curandGenerator_t gen;
    CHECK_CURAND( curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT) );
    CHECK_CURAND( curandSetPseudoRandomGeneratorSeed(gen, seed) );
    CHECK_CURAND( curandGenerateUniform(gen, dataDev, number) );
    CHECK_CURAND( curandDestroyGenerator(gen) );

    CHECK_CUDA( cudaMemcpy(dataHost, dataDev, number * sizeof(float), cudaMemcpyDeviceToHost) );
    CHECK_CUDA( cudaFree(dataDev) );

    return;
}

使用CURAND生成隨機數需要注意以下幾個問題:

1. 函數curandCreateGenerator()的第二個參數指定的是隨機數生成器的類型,共有7種類型,分爲僞隨機數生成器和準隨機數生成器兩類。

2. 函數curandSetPseudoRandomGeneratorSeed()的第二個參數爲隨機數生成器指定種子,相同的種子將會生成相同的隨機數序列。

3. 函數curandGenerateUniform()用於生成0.0到1.0之間(不包括0.0,包括1.0)服從均勻分佈的單精度浮點數,共有8個類似的函數,分別用於生成服從不同分佈的不同類型的隨機數。另外一個比較常用的函數是curandGenerate(),用於生成unsigned int類型的隨機數。

4. 在編譯包含CURAND接口的文件時,需要添加指定鏈接庫的編譯選項-lcurand。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章