C CUDA卷积错误(s)

C CUDA卷积错误(s),c,cuda,parallel-processing,gpu,C,Cuda,Parallel Processing,Gpu,我的程序有两个问题。 这是我节目的一部分 主程序将调用卷积2d函数 此时,内核仅由顺序代码组成。 因为这样我可以测试所有传递的数据是否正确 问题1是将过滤器传递到kenel中的dev_过滤器 我试了很多东西,但都没用 问题2是如何将其与顺序部分中的所有循环并行 我希望我把我的问题说清楚 #定义过滤器宽度3 #定义过滤器高度3 float SOBEL_FILTER_X[FILTER_HEIGTH][FILTER_WIDTH]={{-1,0,1},{-2,0,2},{-1,0,1}; float

我的程序有两个问题。 这是我节目的一部分

主程序将调用卷积2d函数 此时,内核仅由顺序代码组成。 因为这样我可以测试所有传递的数据是否正确

问题1是将过滤器传递到kenel中的dev_过滤器 我试了很多东西,但都没用

问题2是如何将其与顺序部分中的所有循环并行

我希望我把我的问题说清楚


#定义过滤器宽度3
#定义过滤器高度3
float SOBEL_FILTER_X[FILTER_HEIGTH][FILTER_WIDTH]={{-1,0,1},{-2,0,2},{-1,0,1};
float SOBEL_FILTER_Y[FILTER_HEIGTH][FILTER_WIDTH]={{1,2,1},{0,0,0},{-1,-2,-1};
灰度图像卷积2D(灰度图像卷积、整数imgW、整数imgH、浮点滤波器[滤波器高度][滤波器宽度]){
int imgS=imgW*imgH;
灰度图像输出,偏差输入,偏差输出;
浮动偏差过滤器[过滤器高度][过滤器宽度];
int filterS=过滤器高度*过滤器宽度;
//分配内存
out=(灰度图像)calloc(imgS,sizeof(float));
如果(out==NULL)返回NULL;
选中CudaCall(Cudamaloc(&dev_in,imgS*sizeof(float));
检查cudacall(cudamaloc(&dev_out,imgS*sizeof(float));
//记忆复制
选中cudacall(cudaMemcpy(dev_in,in,imgS*sizeof(float),cudaMemcpyHostToDevice));
计时器卷积2D_内核_计时器(“卷积2D_内核_计时器”);
卷积2D_内核_计时器.start();
卷积内核(dev_-in、dev_-out、imgW、imgH、dev_-filter);
卷积2D_内核_计时器.stop();
标准::cout=0&&yy=0&&xx


嗨,我用CudamAllocPicch和cudaMemcpy2D试过了
但是我仍然得到相同的错误

将dev_过滤器传递到内核的问题是dev_过滤器是主机内存指针。您应该像使用dev_in和dev_out一样使用cudamaloc分配它


这里有一个CUDA SDK示例。SDK中还有其他CUDA示例演示了其他类型的卷积,例如。更好的是,查看CUDA工具包附带的。CUDA 4.1增加了1000个图像处理功能,必然有一个你可以使用。

这个代码有很多低效之处,所以你可以考虑使用已经可用的CUDA卷积包中的一个。免责声明是,我正在开发一款我认为对您有用的产品,ArrayFire,您好,我用CudamAllocPictch和cudaMemcpy2D试用过,但我仍然收到相同的错误事实上,有一个专门用于Sobel过滤器的SDK示例:
#define FILTER_WIDTH          3
#define FILTER_HEIGTH         3

float SOBEL_FILTER_X[FILTER_HEIGTH][FILTER_WIDTH] = { {-1,  0,  1}, {-2, 0, 2}, {-1, 0, 1} };
float SOBEL_FILTER_Y[FILTER_HEIGTH][FILTER_WIDTH] = { { 1,  2,  1}, { 0, 0, 0}, {-1,-2,-1} };


gray_image_t convolution2D(gray_image_t in, int imgW, int imgH, float filter[FILTER_HEIGTH][FILTER_WIDTH]) {
    int imgS = imgW * imgH;
    gray_image_t out, dev_in, dev_out;
    float dev_filter[FILTER_HEIGTH][FILTER_WIDTH];
    int filterS = FILTER_HEIGTH * FILTER_WIDTH;


    //allocate memory
    out = (gray_image_t) calloc(imgS, sizeof(float));
    if (out == NULL) return NULL;
    checkCudaCall(cudaMalloc(&dev_in, imgS * sizeof(float)));
    checkCudaCall(cudaMalloc(&dev_out, imgS * sizeof(float)));

    //memcopy
    checkCudaCall(cudaMemcpy(dev_in,in,imgS * sizeof(float), cudaMemcpyHostToDevice));


    timer convolution2D_kernel_timer("Convolution2D_kernel_timer");
    convolution2D_kernel_timer.start();
    convolution_2DKernel<<<AMOUNT_OF_BLOCKS, THREADS_PER_BLOCK>>>(dev_in,dev_out,imgW,imgH,dev_filter);
    convolution2D_kernel_timer.stop();

    std::cout << convolution2D_kernel_timer;
    checkCudaCall(cudaThreadSynchronize());

    checkCudaCall(cudaMemcpy(out,dev_out,imgS * sizeof(float), cudaMemcpyDeviceToHost));
    cudaFree(dev_in);
    cudaFree(dev_out);
    return out;
}
__global__ void convolution_2DKernel(gray_image_t dev_in, gray_image_t dev_out, int imgW,int imgH,float dev_filter[FILTER_HEIGTH][FILTER_WIDTH]){
    // find center position of kernel (half of kernel size)
    int kCenterX = FILTER_WIDTH / 2;
    int kCenterY = FILTER_HEIGTH / 2;

    for(int y=0; y < imgH; y++) {
        for(int x=0; x < imgW; x++) {
            for(int m=0; m < FILTER_HEIGTH; ++m) {
                for(int n=0; n < FILTER_WIDTH; ++n) {

                    // index of input signal, used for checking boundary
                    int yy = y + (m - kCenterY);
                    int xx = x + (n - kCenterX);

                    // ignore input samples which are out of bound
                    if( yy >= 0 && yy < imgH && xx >= 0 && xx < imgW ) {
                        dev_out[y*imgW+x] += dev_in[yy*imgW+xx] * dev_filter[m][n];
                    }
                }
            }
        }
    }
}