【问题标题】:A lot of 0's received when using cudaMemcpy()使用 cudaMemcpy() 时收到很多 0
【发布时间】:2016-09-02 08:21:52
【问题描述】:

我刚开始学习 CUDA,我想用随机数填充一个数组(表示为 1D 数组的 2D 数组)。我关注了另一个帖子以生成随机数,但我不知道数字的生成或从设备或其他任何东西恢复的内存是否存在问题。问题是,虽然我试图用正在参与它的线程的 id 填充数组的任何单元格,以便在复制到主机内存后查看结果,但我收到一个填充有 0 的数组用cudaMemcpy()恢复数据后的任意位置。

我在 Visual Studio 2013 上编程,使用 cuda 7.5,在 i5 2500k 作为我的处理器和 960 GTX 显卡上。

这是我尝试填充它的主要方法和方法。我也会更新 cuRand 初始化。如果您需要查看其他内容,请告诉我。

__global__ void setup_cuRand(curandState * state, unsigned long seed)
{
    int id = threadIdx.x;
    curand_init(seed, id, 0, &state[id]);
}

__global__ void poblar(int * adn, curandState * state){

    curandState localState = state[threadIdx.x];
    int random = curand(&localState);
    adn[threadIdx.x] = random;
    // It doesn't mind if i use the following instruction, the result is a lot of 0's
    //adn[threadIdx.x] = threadIdx.x;

}

int main()
{

    const int adnLength = NUMCROMOSOMAS * SIZECROMOSOMAS; // 256 * 128 (32.768)
    const size_t adnSize = adnLength * sizeof(int);
    int adnCPU[adnLength];
    int * adnDevice;

    cudaError_t error = cudaSetDevice(0);
    if (error != cudaSuccess) 
        exit(-EXIT_FAILURE);

    curandState * randState;
    error = cudaMalloc(&randState, adnLength * sizeof(curandState));
    if (error != cudaSuccess){
        cudaFree(randState);
        exit(-EXIT_FAILURE);
    }
    //Here is initialized cuRand
    setup_cuRand <<<1, adnLength >> > (randState, unsigned(time(NULL)));

    error = cudaMalloc((void **)&adnDevice, adnSize);

    if (error == cudaErrorMemoryAllocation){// cudaSuccess){
        cudaFree(adnDevice);
        cudaFree(randState);
        printf("\n error");
        exit(-EXIT_FAILURE);
    }


    poblar <<<1, adnLength >>> (adnDevice, randState);
    error = cudaMemcpy(adnCPU, adnDevice, adnSize, cudaMemcpyDeviceToHost);
    //After here, for any i, adnCPU[i] is 0 and i cannot figure what is wrong
    if (error == cudaSuccess){
        for (int i = 0; i < NUMCROMOSOMAS; i++){
            for (int j = 0; j < SIZECROMOSOMAS; j++){
                printf("%i,", adnCPU[(i*SIZECROMOSOMAS) + j]);
            }
            printf("\n");
        }
    }

    return 0;
} 

答案解决后编辑:给出的答案有一个特殊性,即您需要较少数量的线程(该数量的一半对我有用)才能正确播种随机数与 cuRand 的数字。出于某种原因,我可以完美地创建线程,但我无法为伪随机算法生成器提供种子。

【问题讨论】:

  • 本题代码不完整,无法编译运行。您所询问的(现在已修改)问题只能通过查看setup_cuRand 的代码来明确回答。但是请不要继续编辑这个问题,以至于接受的答案不再相关。如果您有关于播种和初始化 cuRand 生成器的问题,请务必询问。但是在一个新的问题上做。这不是您的个人帮助线程,它是一个问答对,旨在对所有人有用,而不仅仅是您。
  • @Talonmies 抱歉,如果我没有遵循正确的方法来解决我的错误。我在代码中遇到了另一个小问题,并在有人使用代码之前通知了它。之后我找到了解决方案并发布了。我将最后一次更改标题,因为前一个标题与我最终遇到的问题最相关(而且我不知道那是那个)。如果我有可能损害社区学习的行为,我想向大家道歉。

标签: arrays parallel-processing cuda gpu


【解决方案1】:

您的硬件上每个块的最大线程数为 1024,因此,如果它大于 1024,您可能不会使用 adnLength 安排调用。

您遇到的错误很可能是调用配置错误,它由cudaPeekAtLastError 返回,因为它发生在任何 GPU 工作之前,就在三角括号调用之后。实际上 cudaMemcpy 可能不会返回它,即使它从之前的异步调用返回错误。

可能出现的错误是cudaErrorLaunchOutOfResources。

【讨论】:

  • 为了解决这个问题,我刚刚运行了 256 个线程并循环了 128 次,它确实有效。非常感谢。
  • 我初始化cuRand的方式有问题吗?我获得的数字对于每个线程都是相同的。
  • 您应该设置一个播种方案,以便每个线程发出不同的值。您对子序列的概念很感兴趣。深入研究 curand 文档,如果您仍然卡住,可能会发布另一个问题。
  • 问题是另一个。由于某种原因,我的cuRand 只能使用最大线程数量的一半(1024 线程是我的最大 val 所以512 线程),因为来自cuRand 的伪随机生成器只使用 0 作为种子当更多这些线程正在运行时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 2013-07-20
  • 1970-01-01
  • 2020-08-11
相关资源
最近更新 更多