将庞大的数组结构复制到 GPU

Copy huge structure of arrays to GPU

本文关键字:复制 GPU 结构 数组      更新时间:2023-10-16

我需要将现有的关于SPH(=平滑粒子流体动力学(的代码转换为可以在GPU上运行的代码。

不幸的是,它有很多数据结构,我需要从 CPU 复制到 GPU。我已经在网上查找了,我想,我为我的复制代码做了正确的事情,但不幸的是,我遇到了一个错误(带有未处理异常的东西(。

当我打开调试器时,我看到没有传递给我的变量的信息应该复制到 GPU。它只是说"无法读取内存"。

因此,下面是一个需要复制到 GPU 的数据结构的示例:

__device__ struct d_particle_data
{
  float Pos[3];         /*!< particle position at its current time */
  float PosMap[3];      /*!< initial boundary particle postions */
  float Mass;           /*!< particle mass */
  float Vel[3];         /*!< particle velocity at its current time */
  float GravAccel[3];       /*!< particle acceleration due to gravity */
}*d_P;

我通过以下方式将其传递到 GPU 上:

cudaMalloc((void**)&d_P, N*sizeof(sph_particle_data)); cudaMemcpy(d_P, P, N*sizeof(d_sph_particle_data), cudaMemcpyHostToDevice);

数据结构 P 看起来与数据结构d_P相同。有人可以帮助我吗?


编辑

因此,这是该代码的一小部分:

首先,我必须在代码中使用的标头:

  1. Allvars.h:我在主机上需要的变量

    struct particle_data { float a; float b; } *P;

  2. proto.h:包含所有函数的标头

    extern void main_GPU(int N, int Ntask);
    
  3. Allvars_gpu.h:必须在 GPU 上的所有变量

    __device__ struct d_particle_data { float a; float b; } *d_P;

所以,现在我从.cpp文件调用 -.cu-File:九头蛇.cpp:

#include <stdio.h>
#include <cuda_runtime.h>

extern "C" {
#include "proto.h"
}
int main(void) {
int N_gas = 100; // Number of particles
int NTask = 1; // Number of CPUs (Code has MPI-stuff included)
main_GPU(N_gas,NTask);
return 0;
}

现在,操作发生在 .cu-File 中:hydro_gpu.cu:

#include <cuda_runtime.h>
#include <stdio.h>
extern "C" {
#include "Allvars_gpu.h"
#include "allvars.h"
#include "proto.h"
}
__device__ void hydro_evaluate(int target, int mode, struct d_particle_data *P) {
int c = 5;
float a,b;
a = P[target].a;
b = P[target].b;
P[target].a = a+c;
P[target].b = b+c;
}

__global__ void hydro_particle(struct d_particle_data *P) {
int i = threadIdx.x + blockIdx.x*blockDim.x;
hydro_evaluate(i,0,P);
}

void main_GPU(int N, int Ntask) {
int Blocks;
cudaMalloc((void**)&d_P, N*sizeof(d_particle_data));
cudaMemcpy(d_P, P, N*sizeof(d_particle_data), cudaMemcpyHostToDevice);
Blocks = (N+N-1)/N;
hydro_particle<<<Blocks,N>>>(d_P);
cudaMemcpy(P, d_P, N*sizeof(d_particle_data), cudaMemcpyDeviceToHost);
cudaFree(d_P);
}

真正简短的答案可能是不要将*d_P声明为静态__device__符号。这些不能作为设备指针参数传递给cudaMalloccudaMemcpy或内核启动,并且在此示例中,您对__device__的使用既不必要又不正确。

如果进行该更改,则代码可能会开始工作。请注意,前段时间我对尝试实际编译MCVE代码失去了兴趣,并且很可能还有其他问题,但是我对这个问题太无聊了,无法寻找它们。添加此答案主要是为了将此问题从 CUDA 标签的未回答队列中移除。