C CUDA卷积错误(s)
我的程序有两个问题。 这是我节目的一部分 主程序将调用卷积2d函数 此时,内核仅由顺序代码组成。 因为这样我可以测试所有传递的数据是否正确 问题1是将过滤器传递到kenel中的dev_过滤器 我试了很多东西,但都没用 问题2是如何将其与顺序部分中的所有循环并行 我希望我把我的问题说清楚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
#定义过滤器宽度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];
}
}
}
}
}
}