我正在尝试初始化设备上的某些结构,但是当它们回来时,它们都很杂乱。 我知道我使用指针的方式有问题,但是我似乎无法弄清楚。

这是我在主机上的内存分配

body* devBodies;
body** devBodyList;
float* devRandoms;
cudaMalloc((void**)&devBodies, n * sizeof(body));
cudaMalloc((void**)&devBodyList, n * sizeof(body*));
cudaMalloc((void**)&devRandoms, n * 3 * sizeof(float));

这是我的函数调用,这里devRandoms只是浮点列表。

CUDAInitBodies<<<n,1>>>(devBodyList, devBodies, devRandoms);

这是我的方法:

__global__ void CUDAInitBodies(body** devBodyList, body* devBody, float* rand)
{
    int j;
    int tid = blockIdx.x;
    *(devBodyList[tid]) = devBody[tid];
    devBodyList[tid]->id = tid;
    devBodyList[tid]->m = 10;
    for(j = 0; j < 3; j++) 
    {
        devBodyList[tid]->a[j] = 0;
        devBodyList[tid]->v[j] = 0;
        devBodyList[tid]->pos[j] = rand[(tid * 3) + j];
    }   

}

然后将数据复制回主机时:

body* bodies = (body*)malloc(n * sizeof(body));
cudaMemcpy(bodies, devBodies, n * sizeof(body), cudaMemcpyDeviceToHost);

当我打印出“ body”的变量时,得到以下信息:

====BODY[-581043205]====
    M = -42522218781525353518415985938704367616.000000
    V = [-311601248975690312470654313562112.000000, 17269896096570671104.000000, 307939529506715418513587721849804947456.000000]
    X = -19247336126697914498972549714433540096.000000
    Y = 17731266573644159438123340575306416128.000000
    Z = -544771403677696.000000

我已经尝试了很多种方式,但是似乎没有任何办法

===============>>#1 票数:1 已采纳

之所以得到垃圾输出,是因为您在内核中的这一行代码中取消引用了未初始化的指针:

*(devBodyList[tid]) = devBody[tid];

在主机上,您在此处为指针数组分配了存储空间:

cudaMalloc((void**)&devBodyList, n * sizeof(body*));

这样只会为指针数组创建存储。 它不会将数组中的任何指针设置为指向任何有效的指针。

数组的每个成员都是指向 body结构的指针 ,以第一个成员为例:

devBodyList[0]

但是该指针不会指向任何内容(有效),除非您使用诸如(在设备代码中)的语句对其进行初始化:

devBodyList[0] = &(devBody[0]);

现在,我可以将devBodyList[0]用作指向devBody[0]处分配的主体结构的指针。 注意devBodyList[0]存储在设备上 ,因此要初始化它,我必须:

  1. 在使用之前(例如上面的代码行),请先在设备代码中对其进行初始化。
  2. 在主机上对其进行初始化,但是设置一个有效的指针,然后使用诸如cudaMemcpy类的操作将该初始化值复制到已分配的设备存储中。

除非您考虑了上述情况,否则当您使用指针时,它将包含一个垃圾值,而取消引用它会产生无效的访问。 通过使用cuda-memcheck运行代码,您可以查看这些无效访问的证据。 您将收到诸如“无效的全局写入...”之类的消息。

这是一个完全有效的代码,基于您的代码,不会产生垃圾结果。 (我并不是说这特别明智,因为使用devBodyList[x]引用devBody[x]对我来说似乎是不必要的。)但这是合法代码,不会产生任何内核错误:

#include <stdio.h>

struct body {
int id;
int m;
int a[3];
int v[3];
float pos[3];
};

__global__ void CUDAInitBodies(body** devBodyList, body* devBody, float* rand)
{
    int j;
    int tid = blockIdx.x;
    devBodyList[tid] = &(devBody[tid]);
    *(devBodyList[tid]) = devBody[tid];
    devBodyList[tid]->id = tid;
    devBodyList[tid]->m = 10;
    for(j = 0; j < 3; j++)
    {
        devBodyList[tid]->a[j] = 0;
        devBodyList[tid]->v[j] = 0;
        devBodyList[tid]->pos[j] = rand[(tid * 3) + j];
    }

}

int main(){
  int n = 1;
  body *devBodies;
  body **devBodyList;
  float *devRandoms;

  cudaMalloc((void**)&devBodies, n * sizeof(body));
  cudaMalloc((void**)&devBodyList, n * sizeof(body*));
  cudaMalloc((void**)&devRandoms, n * 3 * sizeof(float));

  CUDAInitBodies<<<n,1>>>(devBodyList, devBodies, devRandoms);

  body* bodies = (body*)malloc(n * sizeof(body));
  cudaMemcpy(bodies, devBodies, n * sizeof(body), cudaMemcpyDeviceToHost);

  printf("Body %d\n", bodies[0].id);
  printf("M : %d\n", bodies[0].m);
  printf("V : %d\n", bodies[0].v[0]);
  return 0;
}

  ask by Chris Phillips translate from so

未解决问题?本站智能推荐: