如何在cuda内核函数中产生随机数(host端调用,device端产生)

2018-01-17 18:13:05 浏览数 (1)

最近,需要在kernel函数中调用浮点型的随机数。于是上网搜了下相关资料,一种方式是自己手动写一个随机数的__device__函数,然后在调用的时候调用这个函数。另一种,原来cuda在toolkit中给出了实现方式。

首先要用到三个函数:

代码语言:javascript复制
curandCreateGenerator(&gen,CURAND_RNG_PSEUDO_DEFAULT); 

指定触发器为gen,随机方式为CURAND_RNG_PSEUDO_DEFAULT

代码语言:javascript复制
curandSetPseudoRandomGeneratorSeed(gen,1234ULL);

指定种子为1234ULL(不同的种子产生的随机数列是不一样的)

代码语言:javascript复制
curandGenerateUniform(gen,devData,n);

根据触发器gen,输出目标指针为devData,规模大小为n

代码语言:javascript复制
/*
 * This program uses the host CURAND API to generate 100 
 * pseudorandom floats.
 */
#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <curand.h>

#define CUDA_CALL(x) do { if((x)!=cudaSuccess) { 
    printf("Error at %s:%dn",__FILE__,__LINE__);
    return EXIT_FAILURE;}} while(0)
#define CURAND_CALL(x) do { if((x)!=CURAND_STATUS_SUCCESS) { 
    printf("Error at %s:%dn",__FILE__,__LINE__);
    return EXIT_FAILURE;}} while(0)

int main(int argc, char *argv[])
{
    size_t n = 100;
    size_t i;
    curandGenerator_t gen;
    float *devData, *hostData;

    /* Allocate n floats on host */
    hostData = (float *)calloc(n, sizeof(float));

    /* Allocate n floats on device */
    CUDA_CALL(cudaMalloc((void **)&devData, n*sizeof(float)));

    /* Create pseudo-random number generator */
    CURAND_CALL(curandCreateGenerator(&gen, 
                CURAND_RNG_PSEUDO_DEFAULT));
    
    /* Set seed */
    CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 
                1234ULL));

    /* Generate n floats on device */
    CURAND_CALL(curandGenerateUniform(gen, devData, n));

    /* Copy device memory to host */
    CUDA_CALL(cudaMemcpy(hostData, devData, n * sizeof(float),
        cudaMemcpyDeviceToHost));

    /* Show result */
    for(i = 0; i < n; i  ) {
        printf("%1.4f ", hostData[i]);
    }
    printf("n");

    /* Cleanup */
    CURAND_CALL(curandDestroyGenerator(gen));
    CUDA_CALL(cudaFree(devData));
    free(hostData);    
    return EXIT_SUCCESS;
}

样例输出后,产生的结果为:(待补)

0 人点赞