C++ 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的
这是我的问题: 我的设备上有一个3D数组C++ 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的,c++,cuda,C++,Cuda,这是我的问题: 我的设备上有一个3D数组float3: 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.pi
float3
:
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);
我正在将主机内存中的结果与我最初在turenderedVolume
(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
和test1
test2
- 在第二部分中,我在
和test1
中有相同的数据。但是,我应该在test2
(=每个片的主机内存+579072
浮点数,以及目标倾斜指针的
)中找到该数据,并在高度*间距
中找到它。它被主机内存+577504
字节关闭,这与我所知的任何内容都不对应,这就是为什么如果你们中的任何人知道我的代码中可能存在的问题,我将非常感激1568
cudamaloc3d
分配3D
内存,通过cudaMemcpy3D
将主机分配的1D
内存移动到3D
设备内存,通过test_kernel_3D
\u global__
函数对3D
设备数据执行一些操作,并再次通过cudaMemcpy3D
将3D
结果数据移回1D
主机内存
\uuuu global\uuuu
函数test\u kernel\u 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 %d\n", 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 %f\n",i,j,w,a[i][j][w]);
getch();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义块大小×16
#定义块大小_y 16
#定义N 128
#定义m64
#定义w16
/*****************/
/*库达门切克酒店*/
/*****************/
#定义gpuerchk(ans){gpuAssert((ans),_文件_,_行__)}
内联void gpuAssert(cudaError\u t代码,char*文件,int行,bool abort=true)
{
如果(代码!=cudaSuccess)
{
fprintf(标准,“GPUassert:%s%s%d\n”,cudaGetErrorString(代码)、文件、行);
如果(中止){getch();退出(代码);}
}
}
/*******************/
/*iDivUp函数*/
/*******************/
intidivup(inta,intb){返回((a%b)!=0)?(a/b+1):(a/b);}
/******************/
/*测试内核3D*/
/******************/
__全局无效测试内核3D(cudaPitchedPtr devPitchedPtr)
{
int tidx=blockIdx.x*blockDim.x+threadIdx.x;
int-tidy=blockIdx.y*blockDim.y+threadIdx.y;
char*devPtr=(char*)devPitchedPtr.ptr;
尺寸\u t节距=devPitchedPtr.节距;
大小\u t间距=间距*N;
对于(int w=0;w 对于(int i=0;i这是一个迟交的答案,用于从未回答列表中删除此问题
下面,我将提供一个完整的代码,展示如何通过cudamaloc3d
分配3D
内存,通过cudaMemcpy3D
将主机分配的1D
内存移动到3D
设备内存,通过test\u kernel\u 3D
函数对3D
设备数据执行一些操作再次通过cudaMemcpy3D
将3D
结果数据移动回1D
主机内存
\uuuu global\uuuuu
函数test\u kernel\u 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 %d\n", 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 %f\n",i,j,w,a[i][j][w]);
getch();
return 0;
}
#包括
#包括
#包括
#包括
#包括
#定义块大小×16
#定义块大小_y 16
#定义N 128
#定义m64
#定义w16
/*****************/
/*库达门切克酒店*/
/*****************/
#定义gpuerchk(ans){gpuAssert((ans),_文件_,_行__)}
内联void gpuAssert(cudaError\u t代码,char*文件,int行,bool abort=true)
{
如果(代码!=cudaSuccess)
{
fprintf(标准,“GPUassert:%s%s%d\n”,cudaGetErrorString(代码)、文件、行);
如果(中止){getch();退出(代码);}
}
}
/*******************/
/*iDivUp函数*/
/*******************/
intidivup(inta,intb){返回((a%b)!=0)?(a/b+1):(a/b);}
/******************/
/*测试内核3D*/
/******************/
__全局无效测试内核3D(cudaPitchedPtr devPitchedPtr)
{
int tidx=blockIdx.x*blockDim.x+threadIdx.x;
int-tidy=blockIdx.y*blockDim.y+threadIdx.y;
char*devPtr=(char*)devPitchedPtr.ptr;
尺寸\u t节距=devPitchedPtr.节距;
大小\u t间距=间距*N;
对于(int w=0;w 对于(int i=0;我如何显示所有变量的完整定义,包括toto
、myData
、和renderedVolume
?(我可能可以自己计算renderedVolume
)当然,我编辑过:renderedVolume是一个cudaPitchedPtr,toto不存在(它是主机内存)我的数据不是很相关,它是复制到renderedVolume的原始数据。我尝试使用您发布的代码构建一个示例应用程序。它似乎运行正常,并为主机内存
、测试1
和测试2