【发布时间】:2017-12-12 02:23:09
【问题描述】:
我有一个名为“坐标”的类,它由一个 int 数组指针和一个 bool 变量组成。我想将此指针发送到 CUDA,对其进行修改,然后在 CPU 内存中使用它。
这是 Coordinate.h :
#ifndef __COORDINATE_H
#define __COORDINATE_H
#include <stdlib.h>
#include <cuda.h>
using namespace std;
class Coordinate {
public:
int *array_pointer;
bool flag;
Coordinate() { flag = false; }
Coordinate(int array_length) {
flag = false;
array_pointer = new int[array_length];
for (int i = 0; i < array_length; i++) {
array_pointer[i] = -1;
}
}
};
#endif
我在 cudamain.cu Check1 和 Check2 中创建了 2 个 global 函数,它们都将 Coordinate 作为参数。 Check1 函数只会改变布尔标志,而 Check2 会改变布尔标志并修改数组。
这里是 cudamain.cu :
#include <iostream>
#include <cuda.h>
#include "Coordinate.h"
using namespace std;
__global__ void check1(Coordinate *ptr) {
c->flag = true;
}
__global__ void check2(Coordinate *c) {
c->flag = true;
for (int i = 0; i < 10; i++) {
c->array_pointer[i] = i;
}
}
int main() {
Coordinate *d_a, *d_b, a, b;
a = Coordinate(10); b = Coordinate(10);
size_t size = sizeof(Coordinate);
cudaMalloc((void**)&d_a, size); cudaMalloc((void**)&d_b, size);
cudaMemcpy(d_a, &a, size, cudaMemcpyHostToDevice); cudaMemcpy(d_b, &b, size, cudaMemcpyHostToDevice);
check1 << <1, 1 >> > (d_a);
cudaMemcpy(&a, d_a, size, cudaMemcpyDeviceToHost);
cout <<"d_a result-> " <<a.flag <<" " <<a.array_pointer[9] << endl;
check2 << <1, 1 >> > (d_b);
cudaMemcpy(&b, d_b, size, cudaMemcpyDeviceToHost);
cout << "d_b result-> " << b.flag << " " << b.array_pointer[9] << endl;
return 0;
}
我制作了 2 个独立的坐标对象 a 和 b,a 将与 check1 一起使用,b 将与 check2 一起使用。 a 和 b 都以相同的方式初始化。
我得到的结果是
d_a result-> 1 -1
d_b result-> 0 -1
预期结果:
d_a result-> 1 -1
d_b result-> 1 9
不同的坐标对象可能有不同的数组长度,所以我无法在坐标类中初始化数组指针。
【问题讨论】:
-
1.使用proper cuda error checking。 2. 使用
cuda-memcheck运行您的代码。当我这样做时,我看到check2内核正在进行非法写访问 -
具有嵌入式指针的类需要在 CUDA 中进行特殊处理。学习this答案。
-
@RobertCrovella,通过内核访问主机指针是否合法?
-
@SullivanRisk 我相信这个问题和其他问题在我链接的另一个答案中得到了回答。这个问题可以说是那个问题的重复,因为该答案完全涵盖了这种情况(具有嵌入式指针的类)并解释了如何正确管理它。即使除了那个或这个类的例子之外,在设备代码中主机指针不应该被取消引用是一个基本的 CUDA 原则。