Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的_C++_Cuda - Fatal编程技术网

C++ 从cuda 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

这是我的问题:

我的设备上有一个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.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);
我正在将主机内存中的结果与我最初在tu
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
    )正常,主机内存中有相同的数据,
    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