分段故障C ++ Cuda

时间:2014-04-01 10:16:22

标签: c++ cuda

我是一名Java程序员,也是C ++和Cuda的新手。我在下面遇到了分段错误:

Input.h class输入{

public:
    const LucyDecimal * sellingPrice; //Ri
    const LucyDecimal qc;

public:
    Input(
            const LucyDecimal * _sellingPrice, 
            const LucyDecimal _qc);

    virtual ~Input();

};

Input.cpp

Input::Input(
        const LucyDecimal * _sellingPrice, //Ri
        const LucyDecimal _qc):sellingPrice(_sellingPrice),qc(_qc)
{};

Input::~Input() {
}

现在在CudaRun.cu

void mainRun(Input in) {
    Input *deviceIn;
    deviceIn = new Input(NULL, NULL, NULL, NULL, 0.0, NULL,0.0,0.0,NULL,0.0,NULL,0.0);
    //line-a

    printf("Started. Just abt to call cuda \n");
    int size = sizeof(Input);
    cudaMalloc((void**) &deviceIn, size);
    cudaMemcpy(deviceIn, &in, size, cudaMemcpyHostToDevice);

    cudaMalloc((void**) deviceIn->sellingPrice, 4 * sizeof(LucyDecimal));
    //line-b
        ....
}

我在line-b收到了细分错误。是否与line-a初始化有关?

1 个答案:

答案 0 :(得分:3)

您无法创建指向设备内存的指针:

cudaMalloc((void**) &deviceIn, size);

然后取消引用主机代码中的指针:

cudaMalloc((void**) deviceIn->sellingPrice, 4 * sizeof(LucyDecimal));

要在sellingPrice结构中实际设置deviceIn指针的值,编译器必须取消引用从基指针(deviceIn)计算的指针,以便写入分配的指针值,并且此解除引用在主机代码中是非法的。

复制包含指针的结构称为"深层复制"而且有点单调乏味。

相反,您需要分配一个单独的指针:

LucyDecimal * sellingPrice_temp;
cudaMalloc((void**) &sellingPrice_temp, 4 * sizeof(LucyDecimal));

然后将分配的指针从主机复制到设备,在适当的位置:

cudaMemcpy(&(deviceIn->sellingPrice), &sellingPrice_temp, sizeof(LucyDecimal *), cudaMemcpyHostToDevice);

请注意,在结构(&(deviceIn->sellingPrice))中查找特定位置的地址是编译器可以计算的,而不会取消引用基指针(deviceIn)。

如果要在某个时刻将嵌入指针区域中的数据复制回主机,则需要再次使用sellingPrice_temp

本主题提供了一些频率,如果您搜索例如,您可以找到许多其他示例。 " CUDA复制结构嵌入式指针"。该方法类似于从主机到设备复制双重下标(**)动态分配的矩阵。

我也建议proper cuda error checking虽然在这种情况下它不会很有启发性。