CUDA:将设备数据复制到2D主机阵列

CUDA:将设备数据复制到2D主机阵列,cuda,Cuda,我有一个HostMatrix,声明为: float **HostMatrix 我必须将设备矩阵的内容(由devicePointer指向)复制到二维主机矩阵HostMatrix 我试过这个 for (int i=0; i<numberOfRows; i++){ cudaMemcpy(HostMatrix[i], devicePointer, numberOfColumns *sizeof(float), cudaMemcpyDeviceToHost

我有一个HostMatrix,声明为:

float **HostMatrix
我必须将设备矩阵的内容(由
devicePointer
指向)复制到二维主机矩阵
HostMatrix

我试过这个

for (int i=0; i<numberOfRows; i++){
    cudaMemcpy(HostMatrix[i], devicePointer, numberOfColumns *sizeof(float),
                 cudaMemcpyDeviceToHost);
    devicePointer += numberOfColumns;// so as to reach next row
}

对于(int i=0;i您基本上需要首先为devicePointer分配所有所需的内存。但是,始终增加它可能不是最简单的想法,因为这样最后的空闲内存就会被破坏。假设您有nRows行大小为ncol。那么这应该可以正常工作(我没有尝试过,但这个想法应该可以):

float*dPtr;
Cudamaloc(和dPtr、nRows*nCols);
对于(int i=0;i
问题是,如果你继续增加dPtr,最后的cudaFree只会在“最后一行”,所以这是错误的


这有意义吗?

您基本上需要首先为devicePointer分配所有所需的内存。但是,一直增加内存可能不是最简单的想法,因为这样最后的空闲内存就会被破坏。假设您有nRows行大小的NCOL。那么这应该可以正常工作(我没有尝试,但这个想法应该可以):

float*dPtr;
Cudamaloc(和dPtr、nRows*nCols);
对于(int i=0;i
问题是,如果你继续增加dPtr,最后的cudaFree只会在“最后一行”,所以这是错误的


这有意义吗?

您尝试过吗?似乎对我很好。devicePointer指向设备内存,但它仍然是主机上的一个变量,您可以执行devicePointer+=numberOfColumns。您所说的“
devicePointer
不能在主机函数中直接操作”是什么意思?指针不是具有秘密和神秘属性的神奇独角兽。它们是无符号整数,具有足够的位来保存内存中的地址值。除此之外,没有什么。当然,你可以“操纵它”在主机代码中。您所不能做的就是取消引用它,因为它的值不是主机内存空间中的有效地址。@Talonmes抱歉我弄糊涂了。现在它清楚了。我只想知道现在如何释放分配的内存。如果我使用cudaFree,它将给出错误。@leo您是正确的。请参阅我在上面的编辑。您尝试过吗?似乎是g我是ood。devicePointer指向设备内存,但它仍然是主机上的一个变量,您可以执行devicePointer+=numberOfColumns。您所说的“
devicePointer
不能在主机函数中直接操作”是什么意思?指针不是具有秘密和神秘属性的神奇独角兽。它们是无符号整数,具有足够的位来保存内存中的地址值。除此之外,没有什么。当然,你可以“操纵它”在主机代码中。您所不能做的就是取消引用它,因为它的值不是主机内存空间中的有效地址。@Talonmes抱歉,我弄糊涂了。现在它清楚了。我只想知道现在如何释放分配的内存。如果我使用cudaFree,它将给出错误。@leo您是正确的。请参阅我在上面的编辑。是的,它工作正常,没有错误n内存分配/取消分配。但是为什么cudaFree在没有将基址作为参数的情况下仍能工作(当我们增加指针时)。正如您所说,它位于最后一行。在我的例子中,我在cuda API cudamemcpy之外增加指针(请参阅我的编辑),在你的例子中,它在cudamemcpy中。为什么你的cudaFree工作而我的没有?你想说它改变了(增量)在你的情况下,指针对CUDAFRE是不可见的?如果是为什么?@ USSR991236:我认为你需要花一些时间来学习C++编程的基本知识,然后再使用CUDA。在这个答案中没有任何地方的代码< >代码> <代码> >在<代码> CUDAMOLC/<代码>和<代码> CUDAFRE 调用之间。如果你不这样做。理解为什么是taht。我怀疑这里的任何人都能帮到你。问题是你总是需要对从cudaMalloc(或只是malloc)得到的指针调用free(cudaFree或只是通常的主机代码上的free)。问题是free需要确切地知道你想要释放什么(你总是需要一次释放整个数组),并且它只能使用malloc的原始指针来完成。如果你给他一个递增版本的指针,它无法理解它还必须释放以前的内容。是的,它在内存分配/取消分配中没有错误。但是为什么cudaFree可以工作,即使它没有得到基址作为参数(当我们增加指针时)。正如您所说,它位于最后一行。在我的例子中,我在cuda API cudamemcpy外部增加指针(请参阅我的编辑),在您的例子中,它在cudamemcpy内部。为什么您的cudaFree工作而我的不工作?您想说这会改变(增加)在你的情况下,指针对CUDAFRE是不可见的?如果是为什么?@ USSR991236:我认为你需要花一些时间来学习C++编程的基本知识,然后再使用CUDA。在这个答案中没有任何地方的代码< >代码> <代码> >在<代码> CUDAMOLC/<代码>和<代码> CUDAFRE 调用之间。如果你不这样做。理解为什么是taht。我怀疑这里的任何人都能帮到你。问题是你总是需要对从cudaMalloc(或只是malloc)得到的指针调用free(cudaFree或只是通常的主机代码上的free)。问题是free需要确切地知道你想要释放什么(你总是需要一次释放整个数组),并且它只能使用malloc的原始指针来实现这一点。如果你给他一个该指针的递增版本,它就无法理解它还必须释放以前的指针。
 for (int i=0; i<numberOfRows; i++){
        cudaMemcpy(HostMatrix[i], devicePointer, numberOfColumns *sizeof(float),
                     cudaMemcpyDeviceToHost);
        devicePointer += numberOfColumns;// so as to reach next row
    }
   cudaFree(devicePointer); //invalid device pointer 
float* dPtr;
cudaMalloc(&dPtr, nRows * nCols);
for (int i=0; i< nRows; i++){
    cudaMemcpy(HostMatrix[i], dPtr + i * nCols, nCols * sizeof(float), cudaMemcpyDeviceToHost);
}
// do whatever you want
cudaFree(dPtr);