中文第一计算机图形学社区OpenGPU 版权所有2007-2018

 找回密码
 注册

扫一扫,访问微社区

搜索
查看: 951|回复: 3

kernel里面如何使用随机数

[复制链接]
发表于 2017-10-11 11:20:16 | 显示全部楼层 |阅读模式
由于kernel里面用不了rand(),不知道还有没有其他的办法?求帮忙。
发表于 2017-10-11 11:47:58 | 显示全部楼层
这里有个问题,是一个Kernel需要一个外部的随机数,还是你的Kernel内存在循环,需要随机数。

如果是1。外部生成好了,构造一个数组,丢给每一个Kernel,每一个Kernel都能获取。比如CUDA做好了一堆,https://developer.nvidia.com/curand

如果是2。得内部实现一个生成器,具体来说,每一个Kernel需要一个预先的状态,这样每个Kernel内部的序列都不相同,从而实现局部的伪随机序列。

比如Windows的rand()就是这样实现的。这些线性同余的RND道理都一样,但是状态有些会很复杂,比如mt19937等等。
int ms_rand(int& seed)
{
  seed = seed*0x343fd+0x269EC3;  // a=214013, b=2531011
  return (seed >> 0x10) & 0x7FFF;
}


发表于 2017-11-22 06:15:00 | 显示全部楼层
SDK example 里面有随机数的例子
发表于 2017-11-22 06:17:35 | 显示全部楼层
CUDA Random Example

In order to use cuRAND, we need to add two include files into our program:

#include <curand.h>
#include <curand_kernel.h>
cuRAND uses a curandState_t type to keep track of the state of the random sequence. The normal C rand function also has a state, but it is global, and hidden from the programmer. This makes rand not thread-safe, but easier to use.

A curandState_t object must be initialized with a call to curand_init which has the following parameters:

seed

The seed determines the beginning point of the sequence of random numbers.

sequence

The sequence number is another seed-like value. It is used so that, if all cores have the same seed, but different sequence numbers, then they will get different random values.

offset

The amount we skip ahead in the random sequence. This can be zero.

state

A pointer to the curandState_t object to initialize.

Once we have an initialized curandState_t object, we can get random numbers with the curand function which takes a pointer to a curandState_t object and returns to us a random unsigned integer.

The following program uses these functions to generate random numbers:

#include <unistd.h>
#include <stdio.h>

/* we need these includes for CUDA's random number stuff */
#include <curand.h>
#include <curand_kernel.h>

#define MAX 100

/* this GPU kernel function calculates a random number and stores it in the parameter */
__global__ void random(int* result) {
  /* CUDA's random number library uses curandState_t to keep track of the seed value
     we will store a random state for every thread  */
  curandState_t state;

  /* we have to initialize the state */
  curand_init(0, /* the seed controls the sequence of random values that are produced */
              0, /* the sequence number is only important with multiple cores */
              0, /* the offset is how much extra we advance in the sequence for each call, can be 0 */
              &state);

  /* curand works like rand - except that it takes a state as a parameter */
  *result = curand(&state) % MAX;
}

int main( ) {
  /* allocate an int on the GPU */
  int* gpu_x;
  cudaMalloc((void**) &gpu_x, sizeof(int));

  /* invoke the GPU to initialize all of the random states */
  random<<<1, 1>>>(gpu_x);

  /* copy the random number back */
  int x;
  cudaMemcpy(&x, gpu_x, sizeof(int), cudaMemcpyDeviceToHost);

  printf("Random number = %d.\n", x);

  /* free the memory we allocated */
  cudaFree(gpu_x);

  return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|小黑屋|Archiver|手机版|中文第一计算机图形学社区OpenGPU

GMT+8, 2018-4-20 08:56 , Processed in 0.038403 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表