C++ 将阵列的巨大结构复制到GPU

C++ 将阵列的巨大结构复制到GPU,c++,cuda,C++,Cuda,我需要将现有的关于SPH=平滑粒子流体动力学的代码转换为可以在GPU上运行的代码 不幸的是,它有很多数据结构,我需要从CPU复制到GPU。我已经在网上查过了,我想,我在复制代码时做了正确的事情,但不幸的是,我得到了一个带有未处理异常的错误 当我打开调试器时,我看到没有传递给变量的信息应该复制到GPU。只是说记忆无法读取 下面是一个需要复制到GPU的数据结构示例: __device__ struct d_particle_data { float Pos[3]; /*!<

我需要将现有的关于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;
Allvars_gpu.h:必须在gpu上的所有变量

__设备\uuuu结构d\u粒子\u数据 { 浮动a; 浮球b; } *d_P

现在,我从.cpp文件调用-.cu文件: hydra.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文件中进行: Hydrogpu.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声明为静态设备符号。这些不能作为设备指针参数传递给cudamaloc、cudaMemcpy或内核启动,在本例中,您使用_device__既不必要,也不正确


如果进行了更改,代码可能会开始工作。请注意,前一段时间我对实际编译您的MCVE代码失去了兴趣,可能还有其他问题,但我对这个问题太厌倦了,以至于找不到它们。添加此答案主要是为了将此问题从CUDA标签的未回答队列中删除。

您能否尝试提供一个答案?什么是sph_粒子数据和d_sph_粒子数据?您必须提供一个简短、完整的示例,如果您需要帮助,其他人可以编译和分析。我们不使用带有u设备u标记变量的cudamaloc或cudaMemcpy。每当你在使用cuda代码时遇到问题,你都应该使用等等来回答这样的问题,为什么我的代码不起作用?当我编译你这里的代码时,我收到了4条警告,形式如下:t1070.cu37:警告:设备变量d_P不能在主机函数中直接读取你收到过这样的警告吗?你不应该忽视这些警告。您可以通过从d_P定义中删除_device_uu标记来修复它,如@talonmies所示。此外,您还没有在宿主代码中为变量P提供任何分配。当P是未分配的指针时,不能从P到d_P。修复这些项目后,使用cuda-memcheck运行代码。哈哈,好吧,你的建议并没有真正帮助我,它不会改变任何东西;。我想,我的问题更深了一点,但我会试着用罗伯特·克罗维拉的暗示自己去解决它,因为我不想让你厌烦到流泪。亲爱的,很抱歉耽误了你的时间。@A:正如我说的,你的代码中还有其他错误。例如,在您发布的内容中,没有任何地方显示*P的分配或初始化。这可能会导致segfault或CUDA运行时错误。但是,尽管在5天前提出了这个问题并对其进行了3次编辑,您仍然无法提供其他人可以实际编译和运行的代码,也无法充分描述确切的问题是什么。我不明白你怎么会期望得到比我提供的答案更简洁、更有用的答案。它正在我的电脑上编译。。。现在我很困惑。不管怎样,我把设备放在结构前面,因为我想能够调用结构,它保存粒子的所有属性,从设备函数开始,在那里进行流体力学的计算。然后,在计算完成后,将其复制回CPU,在CPU中,其他的东西正在成形。很抱歉造成混淆,但我必须编辑的代码非常长,嵌套得很厉害。所以很难找到一个简单的例子。。。
#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);
}