gpt4 book ai didi

cuda - CUDA中结构的简单操作 : Segmentation fault

转载 作者:行者123 更新时间:2023-12-02 06:49:05 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Copying a struct containing pointers to CUDA device

(3 个回答)


6年前关闭。




这是我第一次在 CUDA 中实现结构。在下面的程序中,我将一个结构复制到 GPU 并对数据执行基本操作,然后将结果复制回主机。

#include<stdio.h>

inline cudaError_t checkCuda(cudaError_t result)
{
#if defined(DEBUG) || defined(_DEBUG)
if (result != cudaSuccess) {
fprintf(stderr, "CUDA Runtime Error: %sn", cudaGetErrorString(result));
assert(result == cudaSuccess);
}
#endif
return result;
}

typedef struct myStruct {
int* a;
int b;
}MyStruct;

__global__ void structOperation(MyStruct *d_data){
int idx = threadIdx.x;

d_data->a[idx] += 10;
}

int main(){
MyStruct *h_data, *d_data, *out_data;

size_t structSize = sizeof(MyStruct);
size_t intSize = sizeof(int);


h_data = (MyStruct *) malloc(structSize * 1);
h_data->b = 32;
h_data->a = (int *)malloc(intSize * h_data->b);

out_data = (MyStruct *) malloc(structSize * 1);
out_data->b = 32;
out_data->a = (int *)malloc(intSize * out_data->b);

for(int i = 0; i<32; i++){
h_data->a[i] = i;
}

//Memory allocation for the Struct
checkCuda(cudaMalloc(&d_data, sizeof(MyStruct) * 1));
checkCuda(cudaMalloc(&(d_data->a), sizeof(int) * 32));


checkCuda(cudaMemcpy(&d_data, &h_data, sizeof(MyStruct) * 1, cudaMemcpyHostToDevice));
checkCuda(cudaMemcpy(&(d_data->a), &(h_data->a), sizeof(int) * 32, cudaMemcpyHostToDevice));


structOperation<<<1,32>>>(d_data);


checkCuda(cudaMemcpy(&out_data, &d_data, sizeof(myStruct) * 1, cudaMemcpyDeviceToHost));
//cudaMemcpy(&(out_data->a), &(d_data->a), sizeof(int) * d_data->b, cudaMemcpyDeviceToHost);

printf("\nDataElements : ");
for(int i = 0; i<32; i++){
printf(" %d",out_data->a[i]);
}
printf("\n");
}

执行结果是“段错误”。我想我的结构操作不正确。什么是正确的实现方式?

最佳答案

提供的代码中有几个无效的内存访问。

  • 从主机访问设备内存(使用 cudaMalloc 分配),如 d_data->a将导致未定义的行为(段错误等)。
  • cudaMemcpy将指针作为参数,而不是指针的地址。所以cudaMemcpy(&d_data, &h_data...应替换为 cudaMemcpy(d_data, h_data... .

  • 使用设备指针作为成员分配设备对象有点棘手。它可以实现如下:
  • 分配一个临时主机对象 (MyStruct temp)。
  • 将设备内存分配给我们想要在设备上的成员 (cudaMalloc(&temp.a, bytes))。
  • 分配设备对象 (cudaMalloc(&d_data, sizeof(MyStruct))。
  • 将临时主机对象复制到设备对象 (cudaMemcpy(d_data, &temp, sizeof(MyStruct), cudaMemcpyHostToDevice))。

  • 请记住,当您修改 d_data->a 的内容时在设备上, temp.a也将被修改,因为它们实际上指向设备上相同的内存位置。

    您的最终主要功能将如下所示:
    int main(){
    MyStruct *h_data, *d_data, *out_data;

    size_t structSize = sizeof(MyStruct);
    size_t intSize = sizeof(int);


    h_data = (MyStruct *) malloc(structSize * 1);
    h_data->b = 32;
    h_data->a = (int *)malloc(intSize * h_data->b);

    out_data = (MyStruct *) malloc(structSize * 1);
    out_data->b = 32;
    out_data->a = (int *)malloc(intSize * out_data->b);

    for(int i = 0; i<32; i++){
    h_data->a[i] = i;
    }

    //Create temporary MyStruct object on host and allocate memory to its member "a" on device
    MyStruct temp;
    temp.b = h_data->b;
    checkCuda(cudaMalloc(&temp.a, 32 * sizeof(int)));

    //Copy host data to temp.a
    checkCuda(cudaMemcpy(temp.a, h_data->a, 32 * sizeof(int), cudaMemcpyHostToDevice));

    //Memory allocation for the device MyStruct
    checkCuda(cudaMalloc(&d_data, sizeof(MyStruct) * 1));
    //Copy actual object to device
    checkCuda(cudaMemcpy(d_data, &temp, sizeof(MyStruct) * 1, cudaMemcpyHostToDevice));


    structOperation<<<1,32>>>(d_data);

    //temp.a will be updated after kernel launch
    checkCuda(cudaMemcpy(out_data->a, temp.a, 32 * sizeof(int), cudaMemcpyDeviceToHost));

    printf("\nDataElements : ");
    for(int i = 0; i<32; i++)
    {
    printf(" %d",out_data->a[i]);
    }
    printf("\n");

    checkCuda(cudaFree(temp.a));
    checkCuda(cudaFree(d_data));

    free(h_data->a);
    free(out_data->a);
    free(h_data);
    free(out_data);
    }

    关于cuda - CUDA中结构的简单操作 : Segmentation fault,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31133522/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com