从cuda 3D内存复制到线性内存:复制的数据不是我所期望的
Copying from cuda 3D memory to linear memory: copied data is not where I expected
我的问题是:
我的设备上有一个float3
的3D数组:
int size[3] = {416,464,512};
cudaExtent extent = make_cudaExtent(size[0]*sizeof(float3),size[1],size[2]);
cudaPitchedPtr renderedVolume;
int ret = cudaMalloc3D(&renderedVolume, extent);
size_t pitch = renderedVolume.pitch; //pitch = 5,120
size_t slicePitch = pitch * size[1]; //slicePitch = 2,375,680
然后我使用它,使它充满了出色的数据。
之后,我想把它复制到我主机上的1D线性存储器上:
float *host_memory = (float*)malloc(size[0]*size[1]*size[2]*sizeof(float3));
cudaMemcpy3DParms p = {0};
p.srcPtr = renderedVolume;
p.dstPtr = make_cudaPitchedPtr(host_memory,size[0]*sizeof(float3),size[0],size[1]);
p.extent = make_cudaExtent(size[0]*sizeof(float3),size[1],size[2]);
p.srcPos = make_cudaPos(0,0,0);
p.dstPos = make_cudaPos(0,0,0);
p.kind=cudaMemcpyDeviceToHost;
cudaMemcpy3D(&p);
我将host_memory中的结果与我最初写入renderedVolume
(my_data
)的数据以及我在3Dmemory
中逐片读取的数据进行比较:
float* test1 = (float*)malloc(size[0]*size[1]*sizeof(float3));
cudaMemcpy(test1, myData, size[0]*size[1]*sizeof(float3) , cudaMemcpyDeviceToHost);
float* test2 = (float*)malloc(size[0]*size[1]*sizeof(float3));
cudaMemcpy(test2,(char*)renderedVolume.ptr + slicePitch * i,size[0]*size[1]*sizeof(float3), cudaMemcpyDeviceToHost);
问题:
- 第一片(
i=0
)是可以的,我在host_memory,test1
和test2
中有相同的数据。 - 在第二个切片中,我在
test1
和test2
中具有相同的数据。然而,我应该在host_memory+579072
中找到这个数据(=每片float
的数量,也是目标倾斜指针的heigth*pitch
),我在host_memory+577504
中找到它。它是由1568
字节关闭的,这对应于我所知道的任何东西,这就是为什么我会非常感激,如果你们中的任何一个人知道问题可能在我的代码中?
这是为将此问题从未回答列表中删除而提供的最新答案。
下面,我提供了一个完整的代码,展示了如何通过cudaMalloc3D
分配3D
内存,通过cudaMemcpy3D
将分配1D
内存的主机移动到3D
设备内存,通过test_kernel_3D
__global__
函数对3D
设备数据执行一些操作,并将3D
结果数据移动回1D
主机内存,再次通过cudaMemcpy3D
。
__global__
函数test_kernel_3D
对3D
器件内存的每个元素进行平方。特别是,2D
网格的每个线程都负责沿着"深度"维度执行for
循环。
#include<stdio.h>
#include<cuda.h>
#include<cuda_runtime.h>
#include<device_launch_parameters.h>
#include<conio.h>
#define BLOCKSIZE_x 16
#define BLOCKSIZE_y 16
#define N 128
#define M 64
#define W 16
/*****************/
/* CUDA MEMCHECK */
/*****************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %dn", cudaGetErrorString(code), file, line);
if (abort) { getch(); exit(code); }
}
}
/*******************/
/* iDivUp FUNCTION */
/*******************/
int iDivUp(int a, int b){ return ((a % b) != 0) ? (a / b + 1) : (a / b); }
/******************/
/* TEST KERNEL 3D */
/******************/
__global__ void test_kernel_3D(cudaPitchedPtr devPitchedPtr)
{
int tidx = blockIdx.x*blockDim.x+threadIdx.x;
int tidy = blockIdx.y*blockDim.y+threadIdx.y;
char* devPtr = (char*) devPitchedPtr.ptr;
size_t pitch = devPitchedPtr.pitch;
size_t slicePitch = pitch * N;
for (int w = 0; w < W; w++) {
char* slice = devPtr + w * slicePitch;
float* row = (float*)(slice + tidy * pitch);
row[tidx] = row[tidx] * row[tidx];
}
}
/********/
/* MAIN */
/********/
int main()
{
float a[N][M][W];
for (int i=0; i<N; i++)
for (int j=0; j<M; j++)
for (int w=0; w<W; w++) {
a[i][j][w] = 3.f;
//printf("row %i column %i depth %i value %f n",i,j,w,a[i][j][w]);
}
// --- 3D pitched allocation and host->device memcopy
cudaExtent extent = make_cudaExtent(M * sizeof(float), N, W);
cudaPitchedPtr devPitchedPtr;
gpuErrchk(cudaMalloc3D(&devPitchedPtr, extent));
cudaMemcpy3DParms p = { 0 };
p.srcPtr.ptr = a;
p.srcPtr.pitch = M * sizeof(float);
p.srcPtr.xsize = M;
p.srcPtr.ysize = N;
p.dstPtr.ptr = devPitchedPtr.ptr;
p.dstPtr.pitch = devPitchedPtr.pitch;
p.dstPtr.xsize = M;
p.dstPtr.ysize = N;
p.extent.width = M * sizeof(float);
p.extent.height = N;
p.extent.depth = W;
p.kind = cudaMemcpyHostToDevice;
gpuErrchk(cudaMemcpy3D(&p));
dim3 GridSize(iDivUp(M,BLOCKSIZE_x),iDivUp(N,BLOCKSIZE_y));
dim3 BlockSize(BLOCKSIZE_y,BLOCKSIZE_x);
test_kernel_3D<<<GridSize,BlockSize>>>(devPitchedPtr);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
p.srcPtr.ptr = devPitchedPtr.ptr;
p.srcPtr.pitch = devPitchedPtr.pitch;
p.dstPtr.ptr = a;
p.dstPtr.pitch = M * sizeof(float);
p.kind = cudaMemcpyDeviceToHost;
gpuErrchk(cudaMemcpy3D(&p));
for (int i=0; i<N; i++)
for (int j=0; j<M; j++)
for (int w=0; w<W; w++)
printf("row %i column %i depth %i value %fn",i,j,w,a[i][j][w]);
getch();
return 0;
}
相关文章:
- C#中等价的C++内存复制
- 坚持将双指针管理的内存复制到二维数组
- OpenCL 将字符从全局内存复制到本地内存
- 内存C++复制是否将内存地址复制到另一个阵列
- 将内存复制到结构时,exc_bad_access
- 动态内存复制是如何工作的
- Cuda-从设备全局内存复制到纹理内存
- 使用动态内存复制类
- 将内存复制到标准::复制
- 通过指针的内存复制有时会丢失数据
- 内存访问与内存复制
- 使用汇编代码从内存复制到c++中的寄存器
- 执行 SSE 内存复制导致的堆损坏 - CRT 检查找不到任何内容
- 内存复制导致偏移量
- 如何将图像从全局内存复制到openCL的本地内存
- 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的
- 使用内存复制对象时出现双自由或损坏错误
- c++内存复制结构体到字节数组中
- 使用内存复制对象数组
- 将原始数据从内存复制到文件(cuda)