cudaMemCpy2D正在崩溃

cudaMemCpy2D正在崩溃,cuda,gpgpu,gpu,Cuda,Gpgpu,Gpu,我正在尝试在cuda中实现Sauvola二值化。为此,我已在主机中读取2d数组中的图像,并使用pitch为设备中的2d数组分配内存。分配内存后,我尝试使用cudaMemcpy2D将主机2d数组复制到设备2d数组,它编译得很好,但在运行时崩溃了。我无法理解我遗漏了什么,请提出一些建议。我编写的代码如下: #include "BinMain.h" #include "Binarization.h" #include <stdlib.h> #include <stdio.h>

我正在尝试在cuda中实现Sauvola二值化。为此,我已在主机中读取2d数组中的图像,并使用pitch为设备中的2d数组分配内存。分配内存后,我尝试使用cudaMemcpy2D将主机2d数组复制到设备2d数组,它编译得很好,但在运行时崩溃了。我无法理解我遗漏了什么,请提出一些建议。我编写的代码如下:

#include "BinMain.h"
#include "Binarization.h"
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <cuda.h>
#include <cuda_runtime.h>

void printDevProp(cudaDeviceProp);
void CUDA_SAFE_CALL( cudaError_t);


int main()
{
    //Read an IplImage in imgOriginal as grayscale
    IplImage * imgOriginal = cvLoadImage("E:\\1.tiff",CV_LOAD_IMAGE_GRAYSCALE);

    //Create a size variable of type CvSize for cvCreateImage Parameter
    CvSize size = cvSize(imgOriginal->width,imgOriginal->height);

    //create an image for storing the result image with same height and width as     imgOriginal
    IplImage * imgResult = cvCreateImage(size,imgOriginal->depth,imgOriginal-    >nChannels);

    //Create a 2D array for storing the pixels value of each of the pixel of imgOriginal grayscale image
    int ** arrOriginal = (int **)malloc(imgOriginal->height * sizeof(int *));
    for (int i = 0; i < imgOriginal->height; i++) 
{
    arrOriginal[i] = (int*)malloc(imgOriginal->width * sizeof(int));
}

//Create a 2D array for storing the returned device array
int ** arrReturn = (int **)malloc(imgOriginal->height * sizeof(int *));
for (int i = 0; i < imgOriginal->height; i++) 
{
    arrReturn[i] = (int*)malloc(imgOriginal->width * sizeof(int));
}

//Create a CvScalar variable to copy pixel values in 2D array (arrOriginal)
CvScalar s;

//Copying the pixl values
for(int j = 0;j<imgOriginal->height;j++)
{
    for(int k =0;k<imgOriginal->width;k++)
    {
        s = cvGet2D(imgOriginal,j,k);
        arrOriginal[j][k] = s.val[0];
    }
}

//Cuda Device Property
int devCount;
cudaGetDeviceCount(&devCount);
printf("CUDA Device Query...\n");
printf("There are %d CUDA devices.\n", devCount);

// Iterate through devices
for (int i = 0; i < devCount; ++i)
{
    // Get device properties
    printf("\nCUDA Device #%d\n", i);
    cudaDeviceProp devProp;
    cudaGetDeviceProperties(&devProp, i);
    printDevProp(devProp);
}

//Start the clock
clock_t start = clock();

//Allocating Device memory for 2D array using pitch
size_t host_orig_pitch = imgOriginal->width * sizeof(int)* imgOriginal->height; //host original array pitch in bytes
size_t dev_pitch;   //device array pitch in bytes which will be used in cudaMallocPitch
size_t dev_pitchReturn; //device return array pitch in bytes
size_t host_ret_pitch = imgOriginal->width * sizeof(int)* imgOriginal->height;  //host return array pitch in bytes

int * devArrOriginal;   //device 2d array of original image
int * result;   //device 2d array for returned array
int dynmicRange = 128; //Dynamic Range for calculating the threshold from sauvola's formula

//Allocating memory by using cudaMallocPitch
CUDA_SAFE_CALL(cudaMallocPitch((void**)&devArrOriginal,&dev_pitch,imgOriginal->width * sizeof(int),imgOriginal->height * sizeof(int)));

//Allocating memory for returned array
CUDA_SAFE_CALL(cudaMallocPitch((void**)&result,&dev_pitchReturn,imgOriginal->width * sizeof(int),imgOriginal->height * sizeof(int)));

//Copying 2D array from host memory to device mempry by using cudaMemCpy2D
CUDA_SAFE_CALL(cudaMemcpy2D((void*)devArrOriginal,dev_pitch,(void*)arrOriginal,host_orig_pitch,imgOriginal->width * sizeof(float),imgOriginal->height,cudaMemcpyHostToDevice));
    int windowSize = 19;    //Size of the window for calculating mean and variance
    //Launching the kernel by calling myKernelLauncher function.
    myKernelLauncher(devArrOriginal,result,windowSize,imgOriginal->width,imgOriginal-    >height,dev_pitch,dynmicRange);
    //Calling the sauvola binarization function by passing the parameters as 
    //1.arrOriginal 2D array 2.Original image height 3.Original image width
    //int ** result = AdaptiveBinarization(arrOriginal,imgOriginal->height,imgOriginal-    >width);//binarization(arrOriginal,imgOriginal->width,imgOriginal->height);
    //
CUDA_SAFE_CALL(cudaMemcpy2D(arrReturn,host_ret_pitch,result,dev_pitchReturn,imgOriginal->width * sizeof(int),imgOriginal->height * sizeof(int),cudaMemcpyDeviceToHost));
//create a CvScalar variable to set the data in imgResult
CvScalar ss;

//Copy the pixel values from returned array to imgResult
for(int i=0;i<imgOriginal->height;i++)
{
    for(int j=0;j<imgOriginal->width;j++)
    {
        ss = cvScalar(arrReturn[i][j]*255);
        cvSet2D(imgResult,i,j,ss);
        //k++; //No need for k if returned array is 2D
    }
}

printf("Done \n");
//calculate and print the time elapsed
printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);

//Create a windoe and show the resule image
cvNamedWindow("Result",CV_WINDOW_AUTOSIZE);
cvShowImage("Result",imgResult);
cvWaitKey(0);
getch();

//Release the various resources
cvReleaseImage(&imgResult);
cvReleaseImage(&imgOriginal);
cvDestroyWindow("Result");
for(int i = 0; i < imgOriginal->height; i++)
    free(arrOriginal[i]);

free(arrOriginal);
free(result);
cudaFree(&devArrOriginal);
cudaFree(&result);

}

// Print device properties
void printDevProp(cudaDeviceProp devProp)
{
printf("Major revision number:         %d\n",  devProp.major);
printf("Minor revision number:         %d\n",  devProp.minor);
printf("Name:                          %s\n",  devProp.name);
printf("Total global memory:           %u\n",  devProp.totalGlobalMem);
printf("Total shared memory per block: %u\n",  devProp.sharedMemPerBlock);
printf("Total registers per block:     %d\n",  devProp.regsPerBlock);
printf("Warp size:                     %d\n",  devProp.warpSize);
printf("Maximum memory pitch:          %u\n",  devProp.memPitch);
printf("Maximum threads per block:     %d\n",  devProp.maxThreadsPerBlock);
for (int i = 0; i < 3; ++i)
printf("Maximum dimension %d of block:  %d\n", i, devProp.maxThreadsDim[i]);
for (int i = 0; i < 3; ++i)
printf("Maximum dimension %d of grid:   %d\n", i, devProp.maxGridSize[i]);
printf("Clock rate:                    %d\n",  devProp.clockRate);
printf("Total constant memory:         %u\n",  devProp.totalConstMem);
printf("Texture alignment:             %u\n",  devProp.textureAlignment);
printf("Concurrent copy and execution: %s\n",  (devProp.deviceOverlap ? "Yes" : "No"));
printf("Number of multiprocessors:     %d\n",  devProp.multiProcessorCount);
printf("Kernel execution timeout:      %s\n",  (devProp.kernelExecTimeoutEnabled ? "Yes" : "No"));
return;
}

/* Utility Macro : CUDA SAFE CALL */ 
void CUDA_SAFE_CALL( cudaError_t call) 
{ 

cudaError_t ret = call; 
switch(ret) 
{ 
    case cudaSuccess: 
         break; 
    default : 
            {
                printf(" ERROR at line :%i.%d' ' %s\n", 
                __LINE__,ret,cudaGetErrorString(ret)); 
                exit(-1); 
                break; 
            } 
} 
} 
#包括“BinMain.h”
#包括“Binarization.h”
#包括
#包括
#包括
#包括
#包括
作废打印devprop(cudaDeviceProp);
无效CUDA_安全呼叫(cudaError_t);
int main()
{
//将原始图像中的IplImage读取为灰度
IplImage*imgOriginal=cvLoadImage(“E:\\1.tiff”,CV\u LOAD\u IMAGE\u灰度);
//为cvCreateImage参数创建CvSize类型的大小变量
CvSize size=CvSize(imgOriginal->width,imgOriginal->height);
//创建用于存储结果图像的图像,其高度和宽度与imgOriginal相同
IplImage*imgResult=cvCreateImage(大小,imgOriginal->depth,imgOriginal->nChannels);
//创建一个2D数组,用于存储原始灰度图像每个像素的像素值
int**arroginal=(int**)malloc(imgOriginal->height*sizeof(int*);
对于(int i=0;iheight;i++)
{
原始[i]=(int*)malloc(imgOriginal->width*sizeof(int));
}
//创建一个2D数组以存储返回的设备数组
int**arrrurn=(int**)malloc(imgOriginal->height*sizeof(int*);
对于(int i=0;iheight;i++)
{
arrrurn[i]=(int*)malloc(imgOriginal->width*sizeof(int));
}
//创建CvScalar变量以复制2D数组中的像素值(原始)
cvs;
//复制pixl值
for(int j=0;jheight;j++)
{
for(int k=0;kwidth;k++)
{
s=cvGet2D(原始图像,j,k);
原始[j][k]=s.val[0];
}
}
//Cuda设备属性
国际发展账户;
cudaGetDeviceCount(&devCount);
printf(“CUDA设备查询…\n”);
printf(“有%d个CUDA设备。\n”,devCount);
//遍历设备
对于(int i=0;iwidth*sizeof(int)*imgOriginal->height;//主机原始数组间距(字节)
size\u t dev\u pitch;//将在cudaMallocPitch中使用的设备数组间距(字节)
size\u t dev\u pitchReturn;//设备返回数组间距(字节)
size\u t host\u ret\u pitch=imgOriginal->width*sizeof(int)*imgOriginal->height;//主机返回数组间距(字节)
int*devArrOriginal;//设备原始图像的2d数组
int*result;//返回数组的设备2d数组
int dynmicRange=128;//根据sauvola公式计算阈值的动态范围
//使用cudaMallocPitch分配内存
CUDA_安全呼叫(CUDAMALLOCITCH((void**)和devArrOriginal,&dev_pitch,imgOriginal->width*sizeof(int),imgOriginal->height*sizeof(int));
//为返回的数组分配内存
CUDA_SAFE_调用(cudamallocitch((void**)和result,&dev_pitchReturn,imgOriginal->width*sizeof(int),imgOriginal->height*sizeof(int));
//使用cudaMemCpy2D将2D阵列从主机内存复制到设备mempry
CUDA_安全调用(cudaMemcpy2D((void*)原始值,原始值,(void*)原始值,原始值,原始值->宽度*大小(浮动),原始值->高度,CUDAMEMCPYHOSTTO设备);
int windowSize=19;//用于计算均值和方差的窗口大小
//通过调用mykernellancher函数启动内核。
MyKernelleLancher(去箭头、结果、窗口大小、图像原始->宽度、图像原始->高度、发展间距、动态范围);
//通过如下方式传递参数来调用sauvola二值化函数
//1.原始2D阵列2.原始图像高度3.原始图像宽度
//int**result=adaptiveBinalization(原始,原始->高度,原始->宽度);//二值化(原始,原始->宽度,原始->高度);
//
CUDA_SAFE_调用(cudaMemcpy2D(arrrurn,host_ret_pitch,result,dev_pitchReturn,imgOriginal->width*sizeof(int),imgOriginal->height*sizeof(int),cudamemcpydevicetoost));
//创建一个CvScalar变量来设置imgResult中的数据
CVSS;
//将返回数组中的像素值复制到imgResult
for(int i=0;iheight;i++)
{
for(int j=0;jwidth;j++)
{
ss=cvScalar(arrrurn[i][j]*255);
cvSet2D(imgResult,i,j,ss);
//k++;//如果返回的数组是2D,则不需要k
}
}
printf(“完成”\n);
//计算并打印经过的时间
printf(“经过的时间:%f\n”,((双)时钟()-开始)/每秒时钟数);
//创建windoe并显示结果图像
cvNamedWindow(“结果”,CV_窗口_自动调整大小);
cvShowImage(“结果”,imgResult);
cvWaitKey(0);
getch();
//释放各种资源
cvReleaseImage(&imgResult);
cvReleaseImage(&imgOriginal);
“结果”;
对于(int i=0;iheight;i++)
自由(原[i]);
自由的(原始的);
自由(结果);
cudaFree(和Devaroriginal);
cudaFree(和结果);
}
//打印设备属性
作废打印devProp(cudaDeviceProp devProp)
{
printf(“主要修订号:%d\n”,devProp.Major);
printf(“次要修订号:%d\n”,devProp.Minor);
printf(“名称:%s\n”,devProp.Name);
printf(“总全局内存:%u\n”,devrop.totalGlobalMem);
printf(“每个块的总共享内存:%u\n”,devrop.SharedTemperBlock);
printf(“每个块的寄存器总数:%d\n”,devProp.regsPerBlock);
printf(“扭曲大小:%d\n”,devProp.warpSize);
printf(“最大内存间距:%u\n”,devProp.memPitch);
printf(“每个块的最大线程数:%d\n”,devProp.maxThreadsPerBlock);
对于(int i=0;i<3;++i)
printf(“块的最大尺寸%d:%d\n”,i
imgOriginal->height * sizeof(int)
imgOriginal->height
//Create a 2D array for storing the pixels value of each of the pixel of imgOriginal grayscale image
    int ** arrOriginal = (int **)malloc(imgOriginal->height * sizeof(int *));
    for (int i = 0; i < imgOriginal->height; i++) 
{
    arrOriginal[i] = (int*)malloc(imgOriginal->width * sizeof(int));
}
CUDA_SAFE_CALL(cudaMemcpy2D((void*)devArrOriginal,dev_pitch,(void*)arrOriginal,host_orig_pitch,imgOriginal->width * sizeof(float),imgOriginal->height,cudaMemcpyHostToDevice));
 (void*)arrOriginal
int * arrOriginal = (int *)malloc(imgOriginal->height * imgOriginal->width * sizeof(int));
 "imgOriginal->width * sizeof(int)"