【问题标题】:cuda random number not always return 0 and 1cuda 随机数并不总是返回 0 和 1
【发布时间】:2023-04-04 05:15:01
【问题描述】:

我正在尝试生成一组只有 1 和 0 的随机数。下面的代码几乎可以工作。当我执行 print for 循环时,我注意到有时我生成的数字不是 1 或 0。我知道我遗漏了一些东西,只是不确定是什么。我认为这是记忆错位。

#include <stdio.h>
#include <curand.h>
#include <curand_kernel.h>
#include <math.h>
#include <assert.h>
#define MIN 1
#define MAX (2048*20)

#define MOD 2 // only need one and zero for each random value.
#define THREADS_PER_BLOCK 256

__global__ void setup_kernel(curandState *state, unsigned long seed)
{
  int idx = threadIdx.x+blockDim.x*blockIdx.x;
  curand_init(seed, idx, 0, state+idx);
}

__global__ void generate_kernel(curandState *state,  unsigned int *result){

  int idx = threadIdx.x + blockDim.x*blockIdx.x;
   result[idx] = curand(state+idx) % MOD;
}

int main(){

  curandState *d_state;
  cudaMalloc(&d_state, sizeof(curandState));

  unsigned *d_result, *h_result;
  cudaMalloc(&d_result, (MAX-MIN+1) * sizeof(unsigned));
  h_result = (unsigned *)malloc((MAX-MIN+1)*sizeof(unsigned));

  cudaMemset(d_result, 0, (MAX-MIN+1)*sizeof(unsigned));

  setup_kernel<<<MAX/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>(d_state,time(NULL));

  generate_kernel<<<MAX/THREADS_PER_BLOCK,THREADS_PER_BLOCK>>>(d_state, d_result);

  cudaMemcpy(h_result, d_result, (MAX-MIN+1) * sizeof(unsigned), cudaMemcpyDeviceToHost);  

  printf("Bin:    Count: \n");
  for (int i = MIN; i <= MAX; i++)
    printf("%d    %d\n", i, h_result[i-MIN]);

  free(h_result);
  cudaFree(d_result);

  system("pause");
  return 0;
}

我正在尝试从这个站点转换遗传算法。

http://www.ai-junkie.com/ga/intro/gat3.html

我认为学习 CUDA 并同时获得一些乐趣会是一个很好的问题。

第一部分是生成我的随机数组。

【问题讨论】:

  • @PaulR:虽然这是真的,但在这种情况下无关紧要。随机生成器的返回值是无符号的,因此模分母提升为无符号。没有负值可以参与取模,不会出现意外行为。
  • @talonmies:谢谢 - 我猜错了 - 我会删除我的评论。

标签: c++ visual-studio-2012 random cuda


【解决方案1】:

这里的问题是您的setup_kernelgenerate_kernel 都没有运行完成,因为内存访问越界。两个内核都期望每个线程都有一个生成器状态,但您只在设备上分配一个状态。这会导致两个内核上的内存读取和写入越界。改变这个:

curandState *d_state;
cudaMalloc(&d_state, sizeof(curandState));

类似

curandState *d_state;
cudaMalloc(&d_state, sizeof(curandState) * (MAX-MIN+1));

这样您正在运行的每个线程都有一个生成器状态,并且事情应该开始工作。如果您尝试从运行时 API 返回状态或使用 cuda-memcheck 检查错误,那么错误的来源就会立即显现出来。

【讨论】:

  • 就是这样。谢谢,我错过了,并认为它必须是内存问题。只是不确定在哪里。程序正在运行。
  • 如果答案解决了问题,那么您应该接受它。
猜你喜欢
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2011-03-03
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 2011-04-01
相关资源
最近更新 更多