visual-c++ - CUDA - 数组在 GPU 上生成随机数组及其使用内核的修改

标签 visual-c++ cuda

在此代码中,我使用 CUDA 在 GPU 上生成一维 float 组。这些数字介于 0 和 1 之间。出于我的目的,我需要它们介于 -1 和 1 之间,因此我制作了简单的内核,将每个元素乘以 2,然后从中减去 1。然而这里出了点问题。当我将原始数组打印到 .bmp 时,我得到这个 /image/tpdhn.png (典型的噪声模式)。但是当我尝试用我的内核修改该数组时,我得到空白的黑色图片 /image/tisIp.jpg 。该程序是可执行的,但在调试中我得到这个:

First-chance exception at 0x75f0c41f in Midpoint_CUDA_Alpha.exe: Microsoft C++ exception: cudaError_enum at memory location 0x003cfacc..

First-chance exception at 0x75f0c41f in Midpoint_CUDA_Alpha.exe: Microsoft C++ exception: cudaError_enum at memory location 0x003cfb08..

First-chance exception at 0x75f0c41f in Midpoint_CUDA_Alpha.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000..

对于此事的任何帮助,甚至是一点提示,我将不胜感激。谢谢 ! (已编辑)

#include <device_functions.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
#include "EasyBMP.h"
#include <curand.h> //curand.lib must be added in project propetties > linker > input
#include "device_launch_parameters.h"

float *heightMap_cpu;
float *randomArray_gpu;
int randCount = 0;
int rozmer = 513;

void createRandoms(int size){
    curandGenerator_t generator;
    cudaMalloc((void**)&randomArray_gpu, size*size*sizeof(float));
    curandCreateGenerator(&generator,CURAND_RNG_PSEUDO_XORWOW);
    curandSetPseudoRandomGeneratorSeed(generator,(int)time(NULL));
    curandGenerateUniform(generator,randomArray_gpu,size*size);
}

__global__ void polarizeRandoms(int size, float *randomArray_gpu){
    int index = threadIdx.x + blockDim.x * blockIdx.x;
    if(index<size*size){
        randomArray_gpu[index] = randomArray_gpu[index]*2.0f - 1.0f;
    }
}

//helper fucnction for getting address in 1D using 2D coords
int ad(int x,int y){
    return x*rozmer+y;
}

void printBmp(){
    BMP AnImage;
    AnImage.SetSize(rozmer,rozmer);
    AnImage.SetBitDepth(24);
    int i,j;
    for(i=0;i<=rozmer-1;i++){
        for(j=0;j<=rozmer-1;j++){
            AnImage(i,j)->Red = (int)((heightMap_cpu[ad(i,j)]*127)+128);
            AnImage(i,j)->Green = (int)((heightMap_cpu[ad(i,j)]*127)+128);
            AnImage(i,j)->Blue = (int)((heightMap_cpu[ad(i,j)]*127)+128);
            AnImage(i,j)->Alpha = 0;
        }
    }
    AnImage.WriteToFile("HeightMap.bmp");
}

int main(){
    createRandoms(rozmer);
    polarizeRandoms<<<((rozmer*rozmer)/1024)+1,1024>>>(rozmer,randomArray_gpu);
    heightMap_cpu = (float*)malloc((rozmer*rozmer)*sizeof(float));
    cudaMemcpy(heightMap_cpu,randomArray_gpu,rozmer*rozmer*sizeof(float),cudaMemcpyDeviceToHost);
    printBmp();

    //cleanup
    cudaFree(randomArray_gpu);
    free(heightMap_cpu);
    return 0;
}

最佳答案

这是错误的:

cudaMalloc((void**)&randomArray_gpu, size*size*sizeof(float));

我们不将 cudaMalloc__device__ 变量一起使用。如果你做正确的cuda error checking我很确定该行会抛出错误。

如果您确实想以这种方式使用 __device__ 指针,则需要创建一个单独的普通指针 cudaMalloc ,然后将指针值复制到设备指针使用cudaMemcpyToSymbol:

float *my_dev_pointer;
cudaMalloc((void**)&my_dev_pointer, size*size*sizeof(float));
cudaMemcpyToSymbol(randomArray_gpu, &my_dev_pointer, sizeof(float *));

每当您的 CUDA 程序遇到问题时,您都应该进行适当的 cuda 错误检查。它可能会将您的注意力集中在问题所在上。

而且,是的,内核可以访问__device__变量,而无需将该变量作为参数显式传递给内核。

programming guide涵盖了 __device__ 变量的正确用法以及用于从主机访问它们的 api 函数。

关于visual-c++ - CUDA - 数组在 GPU 上生成随机数组及其使用内核的修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18727850/

相关文章:

.net - 将 VC++ 静态库包装在 DLL 中以与 .Net 托管程序集一起使用

c++ - 初学者 CUDA 程序中未解析的外部符号

xcode - OpenCV 2.4.7 在 MacOS 上构建(Maverick + Xcode 5.01 + CUDA 5.5)

c++ - 发生泄漏检查错误时如何使cuda-memcheck返回非零

c++ - 为什么 `is_constructible<function<int(int)>, int(*)(int,int)>::value`在VC2015RC下为true

c++ - 如何处理 .dump/.dump 文件?

c++ - 查找并替换文本文件中的字符串并输出到另一个文件

c++ - 不完整的全局内存访问合并了吗?

while-loop - 在迭代循环中避免 CudaMemcpy

c++ - Visual C++ 2015 表达 : _stat not working on Windows XP