C++ 推力:访问使用cudaMallocPitch创建的设备变量

C++ 推力:访问使用cudaMallocPitch创建的设备变量,c++,memory-management,cuda,C++,Memory Management,Cuda,我有一个数据矩阵,我应该使用GPU(和推力库,如果可能的话)对其进行一些细化。到目前为止,我能够将数据复制到GPU并编写自己的内核函数。现在,基于我的内核函数的输出,我将利用推力库对相同的数据矩阵进行其他细化,如果可能的话,避免从GPUCPU下载和重新上传数据 因此,我在GPU中使用CudamAllocPicch函数创建了一个设备变量: float *d_M; size_t pitch; cudaStatus = cudaMallocPitch(&d_M, &pitch, siz

我有一个数据矩阵,我应该使用GPU(和推力库,如果可能的话)对其进行一些细化。到目前为止,我能够将数据复制到GPU并编写自己的内核函数。现在,基于我的内核函数的输出,我将利用推力库对相同的数据矩阵进行其他细化,如果可能的话,避免从GPUCPU下载和重新上传数据

因此,我在GPU中使用CudamAllocPicch函数创建了一个设备变量:

float *d_M;
size_t pitch;
cudaStatus = cudaMallocPitch(&d_M, &pitch, sizeof(float)*(N), M+1);
if (cudaStatus != cudaSuccess)
{
    fprintf(stderr, "cudaMalloc Failed!");
    INFO;
    return CUDA_MALLOC_ERROR;
}
此变量表示维度为NxM+1的矩阵。在使用一个特别的cuda函数对GPU做了一些详细说明之后,我想使用推力库对每行的元素求和,并将结果放在每行的M+1列上

对于这种操作,我将使用推力库。 我的目的应该是检索使用CUDAMALLOCITCH创建的原始指针,将其转换为推力::设备_ptr,然后使用推力功能对其进行操作。因此,在代码中:

    thrust::device_ptr<float> dd_M = thrust::device_pointer_cast(d_M);

我得到不同的地址值。我不知道我做错了什么。对于这样的操作,我刚刚在链接处遵循了推力手册。

Cudamallocitch
基本上无法使用推力。这是因为它创建了如下分配:

D D D D D D D D D D D D D D X X
D D D D D D D D D D D D D D X X
D D D D D D D D D D D D D D X X
D D D D D D D D D D D D D D X X
D D D D D D D D D D D D D D X X
...
其中,
D
项表示实际数据,
X
项表示附加到每行的额外空间,以使数据宽度与所需机器节距匹配

问题是推力没有这个由
X
表示的“未使用”区域的概念。当数据中有“未使用的”间隙时,没有方便的方法告诉推力函数分配线程(并生成适当的连续索引)。所以如果我们把上面的转换成推力向量:

D D D D D D D D D D D D D D X X D D D D D D D D D D D D D D X X D D ...
在推力算法和索引中,无法方便地“跳过”散布在向量中的
X
区域。如果您真的想这样做,可能会提出一个解决上述映射的
推力::置换迭代器
,但这将有其自身的低效率,这将超过对倾斜数据进行操作所带来的任何性能好处


如果您改用
cudamaloc
,那么您的数据将是连续的,这是推力所期望的。

我认为没有一种简单的方法可以做到这一点,您将无法方便地将推力与
cudamallocitch
一起使用。改用
cudamaloc
。好的,我试试cudamaloc。感谢您,这里没有一种方便的方法来使用
cudaMallocPitch
。但是,
printfs
的输出不匹配的原因是,您正在打印两个不同变量的地址,而不是您真正感兴趣的原始指针。您想打印原始指针
d_m
dd_m.get()
的值。感谢您提供了详细的答案。我认为使用指针语义的自定义容器类可能是实现这一点的“最简单”方法。置换迭代器可能不起作用,因为不能保证(或要求)分配节距是数组类型sizeI的整数倍。我同意你关于置换迭代器不洁的观点——至少对于不能均匀划分节距的非POD类型(即使在豆荚类型上依赖它也不符合犹太教)。因此,我真的不知道在一般情况下如何做到这一点。
D D D D D D D D D D D D D D X X D D D D D D D D D D D D D D X X D D ...