JCuda:将多维数组从设备复制到主机
我已经和JCuda合作几个月了,我无法将多维数组从设备内存复制到主机内存。有趣的是,在相反的方向上这样做没有问题(我可以用多维数组调用我的内核,所有东西都使用正确的值) 简单地说,我把内核的结果放在一个二维的short数组中,数组的第一个维度是线程数,这样每个线程都可以在不同的位置写入 这里有一个例子:JCuda:将多维数组从设备复制到主机,cuda,jcuda,Cuda,Jcuda,我已经和JCuda合作几个月了,我无法将多维数组从设备内存复制到主机内存。有趣的是,在相反的方向上这样做没有问题(我可以用多维数组调用我的内核,所有东西都使用正确的值) 简单地说,我把内核的结果放在一个二维的short数组中,数组的第一个维度是线程数,这样每个线程都可以在不同的位置写入 这里有一个例子: CUdeviceptr指针\u dev=new CUdeviceptr(); 积垢(指针_dev,Sizeof.pointer);//在本例中,作为一个示例,它是一个包含一个元素(一个线程)的
CUdeviceptr指针\u dev=new CUdeviceptr();
积垢(指针_dev,Sizeof.pointer);//在本例中,作为一个示例,它是一个包含一个元素(一个线程)的数组,但这并不重要
//以指针_dev作为参数调用内核。现在它应该包含一些结果
CUdeviceptr[]arrayPtr=新的CUdeviceptr[1];//它将指出结果
arrayPtr[0]=新的CUdeviceptr();
short[]resultArray=新的short[3];//内核中分配了一个由3个短片组成的数组
积垢(Arrayptor[0],短3*Sizeof.);
cuMemcpyDtoH(Pointer.to(arrayPtr)、Pointer_dev、Sizeof.Pointer);//使用调试器,arrayPtr[0]的值似乎没有在此处更改!
cuMemcpyDtoH(指向(resultArray)的指针,arrayptor[0],3*Sizeof.SHORT);//不是resultArray中的预期值,可能是因为前面的指令
我做错了什么
编辑:
显然,有一些限制不允许将设备分配的内存复制回主机,如以下(以及更多)线程中所述:
有解决办法吗?我使用的是CUDA Toolkit v5.0,这里我们将一个二维整数数组从设备复制到主机
int hostOutputData[] = new int[numberofelementsInArray * blockSizeX];
cuMemcpyDtoH(Pointer.to(hostOutputData), hostDevicePointers[i], numberofelementsInArray * blockSizeX * Sizeof.INT);
for (int j = 0; j < size; j++)
{
sum = sum + hostOutputData[j];
}
blockSizeX
)
kernelLauncher.call(........, hostDevicePointersArray);
int hostOutputData[] = new int[numberofelementsInArray * blockSizeX];
cuMemcpyDtoH(Pointer.to(hostOutputData), hostDevicePointers[i], numberofelementsInArray * blockSizeX * Sizeof.INT);
for (int j = 0; j < size; j++)
{
sum = sum + hostOutputData[j];
}
int hostOutputData[]=new int[numberofelementsInArray*blockSizeX];
cuMemcpyDtoH(指针指向(主机输出数据)、主机设备指针[i]、numberofelementsInArray*blockSizeX*Sizeof.INT);
对于(int j=0;j
在这里,我们将一个二维整数数组从设备复制到主机
int hostOutputData[] = new int[numberofelementsInArray * blockSizeX];
cuMemcpyDtoH(Pointer.to(hostOutputData), hostDevicePointers[i], numberofelementsInArray * blockSizeX * Sizeof.INT);
for (int j = 0; j < size; j++)
{
sum = sum + hostOutputData[j];
}
blockSizeX
)
kernelLauncher.call(........, hostDevicePointersArray);
int hostOutputData[] = new int[numberofelementsInArray * blockSizeX];
cuMemcpyDtoH(Pointer.to(hostOutputData), hostDevicePointers[i], numberofelementsInArray * blockSizeX * Sizeof.INT);
for (int j = 0; j < size; j++)
{
sum = sum + hostOutputData[j];
}
int hostOutputData[]=new int[numberofelementsInArray*blockSizeX];
cuMemcpyDtoH(指针指向(主机输出数据)、主机设备指针[i]、numberofelementsInArray*blockSizeX*Sizeof.INT);
对于(int j=0;j
至少有两个可能的问题。一个是您所说的,使用设备功能(如
malloc
或new
分配的内存不能直接复制到主机。复制包含指向其他动态分配数据的指针的动态分配数据也有各种各样的挑战,围绕这一点还有很多问题。不幸的是,我对java或JCUDA语法不太熟悉,无法准确地告诉您如何解决此问题。对于您发布的编辑问题,一个可能的解决方法是,在将数据复制回主机之前,在设备代码中将数据从设备分配的区域复制到主机分配的区域。谢谢,我也是这么做的。但问题依然存在:主机分配区域的大小在内核计算之前是固定的,我无法预先确定输出的维度。目前,我已经决定建立一个足够大的固定大小,以在大多数情况下工作,但我认为这不是一个“好”的解决方案。至少有两个可能的问题。一个是您所说的,使用设备功能(如malloc
或new
分配的内存不能直接复制到主机。复制包含指向其他动态分配数据的指针的动态分配数据也有各种各样的挑战,围绕这一点还有很多问题。不幸的是,我对java或JCUDA语法不太熟悉,无法准确地告诉您如何解决此问题。对于您发布的编辑问题,一个可能的解决方法是,在将数据复制回主机之前,在设备代码中将数据从设备分配的区域复制到主机分配的区域。谢谢,我也是这么做的。但问题依然存在:主机分配区域的大小在内核计算之前是固定的,我无法预先确定输出的维度。目前,我已经决定建立一个固定的大小足以在大多数情况下工作,但我认为这不是一个“好”的解决方案。