C CUDA 从设备向主机发送结构数组

标签 c struct cuda

我有这个结构

struct Data {
    int x
    int y;
    float z;
};

我把它毫无问题地发送给了内核

__global__ void calculate(Data *d_data) {
    d_data[myCounter].x = 1;
    d_data[myCounter].y = 1;
    d_data[myCounter].z = 1.0;
}

#DEFINE MAX_SIZE 100

int main() {
  Data * data = (Data *)malloc(MAX_SIZE * sizeof(Data));
  Data *d_data;

  const int DATA_BYTES = MAX_SIZE * sizeof(Data);
  int elements = 20;

  cudaError_t cudaStatus;

  cudaStatus = cudaMalloc((void **)&d_data, DATA_BYTES);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMalloc failed!");
  }

  cudaStatus = cudaMemcpy(d_data, data, DATA_BYTES, cudaMemcpyHostToDevice);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMemcpy failed!");
  }

  calculate << < 1, elements >> > (d_data);

  cudaMemcpy(data, d_data, DATA_BYTES, cudaMemcpyDeviceToHost);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMemcpy failed!");
  }

  cudaDeviceSynchronize();

  for (i = 0; i < elements; i++) {
    printf("%2d %2.1f %s\n", d_data[i].x, d_data[i].y, 
    d_data[i].z);    // this prints nothing
  }
  cudaStatus = cudaDeviceReset();

}

当我在内核函数中测试结构数组时,计算它打印出正确的结果,但是当我尝试使用 cudaMemcpy 程序从设备向主机发送数据时,程序崩溃,没有错误并且什么都不打印,我如何从设备传输这个结构数组?

最佳答案

您显示的代码存在几个问题。

  1. 您的结构定义中缺少一个分号。
  2. 内核代码中没有为变量myCounter提供定义
  3. 没有为main中的变量i提供定义
  4. 您正在尝试从设备变量 d_data 而不是主机变量 data 进行打印。这在 CUDA 中是非法的。复制到主机变量 data 后,从那里打印。
  5. 您使用的 printf 格式说明符不正确。结构中的数据类型是 intintfloat。您使用的 %2d %2.1f %s 将匹配一个 int、一个 float 和一个字符串变量(以 null 结尾的数组字符),但对于您的结构不正确。

以下代码解决了上述问题并且对我来说似乎可以正确运行:

$ cat t430.cu
#include <stdio.h>

struct Data {
    int x;  // was missing semicolon
    int y;
    float z;
};

__global__ void calculate(Data *d_data) {
    int myCounter = threadIdx.x;  // this line was missing
    d_data[myCounter].x = 1;
    d_data[myCounter].y = 1;
    d_data[myCounter].z = 1.0;
}

#define MAX_SIZE 100

int main() {
  Data * data = (Data *)malloc(MAX_SIZE * sizeof(Data));
  Data *d_data;
  int i;   // this line was missing
  const int DATA_BYTES = MAX_SIZE * sizeof(Data);
  int elements = 20;

  cudaError_t cudaStatus;

  cudaStatus = cudaMalloc((void **)&d_data, DATA_BYTES);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMalloc failed!");
  }

  cudaStatus = cudaMemcpy(d_data, data, DATA_BYTES, cudaMemcpyHostToDevice);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMemcpy failed!");
  }

  calculate << < 1, elements >> > (d_data);

  cudaMemcpy(data, d_data, DATA_BYTES, cudaMemcpyDeviceToHost);
  if (cudaStatus != cudaSuccess) {
    fprintf(stderr, "cudaMemcpy failed!");
  }

  cudaDeviceSynchronize();

  for (i = 0; i < elements; i++) {
    printf("%2d %2d %2.1f\n", data[i].x, data[i].y,
    data[i].z);    // this was trying to print from d_data
  }
  cudaStatus = cudaDeviceReset();

}
$ nvcc -arch=sm_61 -o t430 t430.cu
$ cuda-memcheck ./t430
========= CUDA-MEMCHECK
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
 1  1 1.0
========= ERROR SUMMARY: 0 errors
$

关于C CUDA 从设备向主机发送结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46521220/

相关文章:

foreach - 如何解决 CUDA Thrust 库 - for_each 同步错误?

c++ - 如何在 C++ 中使用 Thrust 和 odeint 求解简单的 ODE

c - 使用信号量的共享内存安全写入

c++ - 在 C++ 中从控制台获取触发器

c - 在结构中保存变量

c - 字节交换结构

c - 定义预处理器指令中的字符串文字

cs50 pset5 字典.c : this code is giving segmentation fault

c - 另一个结构中的嵌套结构数组

运行 "CUDA By Example"julia_gpu.cu 时出现 CUDA 错误