请问怎样创建二维的动态结构体数组啊,我的是代码是这样的
cPoint** corner1=(cPoint**)malloc(sizeof(cPoint*)*width1);
(*corner1)->data=(int)malloc(sizeof(int)*width1);
(*corner1)->x=(int)malloc(sizeof(int)*width1);
(*corner1)->y=(int)malloc(sizeof(int)width1);
for (i=0;i<width1;i++)
{
corner1[i]=(cPoint)malloc(sizeof(cPoint)*height1);
corner1[i]->data=(int)malloc(sizeof(int)*height1);
corner1[i]->x=(int)malloc(sizeof(int)*height1);
corner1[i]->y=(int)malloc(sizeof(int)*height1);
}
但是不知道对不对,而且按照这种方法创建,我这个函数传进来的参数是没法复制到主存上面的?
希望有人能尽快解答我的疑惑,谢谢!
楼主您好:
如果您是在kernel中使用的malloc,那么您依然可以复制到host memory的,
但请您注意如下方面:
(1)首先请您将CPoint结构体的实例复制到host memory
(2)然后请您本地(host上)创建一个CPoint的实例。
(3)请您分别为本地实例的data/x/y/缓冲区分配空间。
(4)请您将刚才复制过来的实例的data/x/y指向的device memory中的内容,分别复制到本地实例的data/x/y缓冲区中。
(5)任务完成。
此解决方案可以为您解决问题,请立刻尝试。
感谢来访。
您好,那我的创建方法是没错是么?我的几个函数代码:
struct cPoint
{
int x; //height
int y;
int data;
};
device void qiu(int* reslut,int tid)
{
int width1=5;
int height1=10;
cPoint** corner1=(cPoint**)malloc(sizeof(cPoint*)*width1);
(*corner1)->data=(int)malloc(sizeof(int)*width1);
(*corner1)->x=(int)malloc(sizeof(int)*width1);
(*corner1)->y=(int)malloc(sizeof(int)width1);
for (int i=0;i<width1;i++)
{
corner1[i]=(cPoint)malloc(sizeof(cPoint)*height1);
corner1[i]->data=(int)malloc(sizeof(int)*height1);
corner1[i]->x=(int)malloc(sizeof(int)*height1);
corner1[i]->y=(int)malloc(sizeof(int)height1);
}
for (int i=0;i<THREAD_NUM4;i++)
{
reslut[i]=i;
}
}
global static void CudaPlite(char* gray1,char* gray2,int width1,int height1,int width2,int height2,int* reslut)
{
const int tid=threadIdx.x;
qiu(reslut,tid);
}
void CutGrayImg(char* grayData11,char* grayData22,int width1,int height1,int width2,int height2)
{
int n=THREAD_NUM;
int len=height1/n;
int imageSize1,imageSize2;
imageSize1=(width1+3)/44height1;
imageSize2=(width2+3)/44height2;
cudaSetDevice(0); //CUDA begin
cudaDeviceSynchronize();
cudaThreadSynchronize();
char* gpuImg1,* gpuImg2;
int* reslut;
int xyz[THREAD_NUM*4];
checkCudaErrors(cudaMalloc((void**)&gpuImg1,sizeof(char)*imageSize1));
checkCudaErrors(cudaMalloc((void**)&gpuImg2,sizeof(char)*imageSize2));
checkCudaErrors(cudaMalloc((void**)&reslut,sizeof(int)*n*4));
// checkCudaErrors(cudaMemset(reslut,0,sizeof(int)n4));
checkCudaErrors(cudaMemcpy(gpuImg1,grayData11,sizeof(char)*imageSize1,cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(gpuImg2,grayData22,sizeof(char)*imageSize2,cudaMemcpyHostToDevice));
CudaPlite<<<1,THREAD_NUM,THREAD_NUM*4*sizeof(int)>>>(gpuImg1,gpuImg2,width1,height1,width2,height2,reslut);
checkCudaErrors(cudaMemcpy(xyz,reslut,sizeof(int)*n*4,cudaMemcpyDeviceToHost));
cudaFree(gpuImg1);
cudaFree(gpuImg2);
cudaFree(reslut);
}
但是我如果在qiu函数里面添加了这段二维创建代码之后,在CutGrayImg函数里面就无法将reslut的值复制到xyz上面;如果删除二维数组创建代码,就能复制成功?我不明白为什么?
请您先排排版,
您的大量下标都被吃掉了,无法猜测含义。
谢谢合作。
不好意思哦。
struct cPoint
{
int x; //height
int y;
int data;
};
device void qiu(int* reslut,int tid)
{
int width1=5;
int height1=10;
cPoint** corner1=(cPoint**)malloc(sizeof(cPoint*)*width1);
(*corner1)->data=(int)malloc(sizeof(int)*width1);
(*corner1)->x=(int)malloc(sizeof(int)*width1);
(*corner1)->y=(int)malloc(sizeof(int)width1);
for (int i=0;i<width1;i++)
{
corner1[ i ]=(cPoint)malloc(sizeof(cPoint)*height1);
corner1[ i ]->data=(int)malloc(sizeof(int)*height1);
corner1 [ i ]->x=(int)malloc(sizeof(int)*height1);
corner1[ i ]->y=(int)malloc(sizeof(int)*height1);
}
for (int i=0;i<THREAD_NUM4;i++)
{
reslut[i]=i;
}
}
global static void CudaPlite(char gray1,char* gray2,int width1,int height1,int width2,int height2,int* reslut)
{
const int tid=threadIdx.x;
qiu(reslut,tid);
}
void CutGrayImg(char* grayData11,char* grayData22,int width1,int height1,int width2,int height2)
{
int n=THREAD_NUM;
int len=height1/n;
int imageSize1,imageSize2;
imageSize1=(width1+3)/44height1;
imageSize2=(width2+3)/44height2;
char* gpuImg1,* gpuImg2;
int* reslut;
int xyz[THREAD_NUM*4];
checkCudaErrors(cudaMalloc((void**)&gpuImg1,sizeof(char)imageSize1));
checkCudaErrors(cudaMalloc((void*)&gpuImg2,sizeof(char)imageSize2));
checkCudaErrors(cudaMalloc((void*)&reslut,sizeof(int)n4));
checkCudaErrors(cudaMemcpy(gpuImg1,grayData11,sizeof(char)*imageSize1,cudaMemcpyHostToDevice));
checkCudaErrors(cudaMemcpy(gpuImg2,grayData22,sizeof(char)*imageSize2,cudaMemcpyHostToDevice));
CudaPlite<<<1,THREAD_NUM,THREAD_NUM4sizeof(int)>>>(gpuImg1,gpuImg2,width1,height1,width2,height2,reslut);
checkCudaErrors(cudaMemcpy(xyz,reslut,sizeof(int)n4,cudaMemcpyDeviceToHost));
cudaFree(gpuImg1);
cudaFree(gpuImg2);
cudaFree(reslut);
}
这样可以吗?当我qiu函数中有添加那部分二维数组创建的代码后,主函数CutGrayImg函数中reslut将无法成功赋值给xyz数组。
LZ您好:
如果您发现某kernel后面原本应该正常执行的步骤并没有按预期执行,请检查一下该kernel 的执行情况,并逐步分析。
您可以在kernel后面添加cudaDeviceSynchronize()函数,并检查这个函数的返回值,以得到kernel的异步错误信息。
此外,关于二维结构体数组,2#中玫瑰斑竹已经说过,上详不赘。以及您3#的代码中并没有体现出您理解和实践了玫瑰斑竹的建议。
大致如此,祝您编码顺利~
我不需要得到二维数组那里的值,只是因为他的创建影响了我其它变量的值的操作,我只是想知道为什么,而不是去获取这个二维数组的值
我不需要知道您的问题是为什么,我只是想告诉您出了问题应该应该以怎样的步骤解决。
版主您好:
1.我不需要得到二维数组的值,它只用在kernel内,所以我看到玫瑰版主的回复就认为我没有正确的表达出我的意思,让他误解我是要将二维数组复制到主存上面,而我觉得我的要求不需要,所以就没按照他的意思来做。
2.在我这边没有看到有下标被吃掉的问题。
3.我在CutGrayImg函数里面用了cudaDviceSynchronize()函数,返回值是30
我也不知道是不是我表达能力过差,或者理解能力过弱,我还没理解版主们的意思,能否详说。
LZ您好:
1:我们存在的世界是因果性的,斑竹不可能提前预知您后面各个楼层的内容的。您的帖子题目是《cuda二维结构数组的创建》,以及您1#的内容也是如此“请问怎样创建二维的动态结构体数组啊,我的是代码是这样的…”。
然后玫瑰斑竹根据当时题目和1#的问题,反向估计出了您需要在kernel中创建结构体并分配空间,并以此给出了您详细的实现步骤。
然后您在后面表示您不需要这个。
这是非常不厚道的做法。
2:如果您的代码发出来以后出现了斜体(而不是您自己设定的),那么就是您代码中[ i ]被论坛识别为了转义字符。
请您使用代码模式发代码,以规避这一问题。
以及即便是您修正过的5#,也至少有“result=i;”这里[ i ]被转义,其他可能还有,所以您说“在我这边没有看到有下标被吃掉的问题。”是不正确的,请您仔细观察,或者直接使用代码模式发代码。
直接发布这种内容因为被转义而变得不完整的代码,而让其他人为您需找问题,这需要耗费其他人大量的时间和经历进行反猜您的原始代码,而且还不一定能猜得对,更不要说为您发现问题。这样做是非常不厚道的做法,也是不利于您自己快速解决问题的,请您理解这一点,并予以配合。
3:根据您9#的补充,您后来在“CutGrayImg函数里面用了cudaDviceSynchronize()函数,返回值是30”,这个做法是我在6#提出的推荐做法,以及30的返回值代表“error unknown”,这一般表示您的kernel中访存出现问题而导致kernel挂掉。
请您检查您的完整版的原始代码,寻找问题所在。
可以考虑使用nsight或者cuda memcheck,以便迅速发现问题。
此外,需要说一下,您上文给出的代码应该并非是完整的代码,而是经过您精简过的。代码是一个整体的,只有完整或者相对完整的代码才有助于确定问题,寻找问题时,借助调试手段逐步查错和缩小范围才是最能解决问题的做法。
而非完整的代码不利于寻找问题,主观猜测也仅能作为一种辅助手段使用。
大致如此,祝您早日debug成功。
谢谢,我取标题为二维结构体数组的创建是因为 我认为是我创建的方式不对而照成的问题,不好意思,那我想问是不是__device__函数里面能否这样创建结构体数组呢?还是需要像玫瑰斑竹说的要在主存里面先创建实例再复制?我那样创建是否有问题
不好意思,我也不是挺懂这个,第一次发帖所以不知道会识别为转义字符。造成不便,不好意思。
其它代码已经被我屏蔽掉了,但还是出现了那个问题,所以我就没有将其贴出来。
LZ您好:
这里和C语言中是一样的,仅从“创建”的角度讲,您这样用是可以的,但是您指向申请空间的指针变量是您__device__函数中的临时变量,而且您仅仅申请了空间而没有释放空间,这样在函数执行完之后,临时变量将不复存在,您分配的显存空间将不再有一个有效的指针指向,您的显存将出现泄露。
以及,这其实不是一个CUDA的问题,您在c语言中这么干,内存也会泄露的。
此外,不建议在kernel中使用malloc(),尤其不建议每个线程都上,这会带来大量的效率问题。
其他问题,玫瑰斑竹已经说得足够清楚,请您根据自己的需要把问题想清楚,决定具体的做法。
子曰:学而不思则罔,思而不学则殆。愿共勉。
以及如果LZ确定这一点,请您参照前面的建议,使用debug环境协助您寻找问题。
斑竹的肉眼不具备该神奇功能,不能为您进一步指出具体问题所在了,请见谅。
祝您debug顺利~
谢啦,我已为此痛苦了三天啦,也刚学习CUDA,并要用到项目中,弄不懂啊。
精诚所至,金石为开。
与LZ共勉。