在尝试将我的C++光线跟踪代码转换为CUDA时,我无法遵从device_ptr的device_reference,这是在遍历device_ptr的device_vector时无意中创建的。
class hittable_list : public hittable {
public:
__device__ hittable_list() {}
__device__ hittable_list(device_ptr<hittable> object) { add(object); }
__device__ void clear() { objects.clear(); }
__device__ void add(device_ptr<hittable> object) { objects.push_back(object); }
__device__ virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const override;
public:
device_vector<device_ptr<hittable>> objects;
};
我希望在循环此向量时,会收到其中的device_ptrs
__device__ bool hittable_list::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {
hit_record temp_rec; // temp_rec is used to store the hit_record of all objects
bool hit_anything = false; // hit_anything is used to check if any object is hit
float total_prob = 1.0; // total_prob is used to store the total probability of the transmission
for (const auto object: objects) { // loop through all objects
if (object->hit(r, t_min, t_max, temp_rec)) {
hit_anything = true;
total_prob *= temp_rec.trans_prob; // update the total_prob
temp_rec.trans_prob = total_prob;
rec = temp_rec;
}
}
return hit_anything;
但是,当我在对象上使用箭头操作符时,我得到以下错误:
error: operator -> or ->* applied to "const thrust::device_reference<const thrust::device_ptr<hittable>>" instead of to a pointer type
那么device_ptr是如何变成device_reference的呢?我又是如何获得device_ptr的呢?文档中确实提到“device_reference不打算直接使用;类似地,获取device_reference的地址将生成device_ptr”((device_reference的文档)但是,获取引用的地址对我来说没有任何意义,即使使用&object->hit()
尝试也会导致相同的错误。
我尝试使用箭头运算符(*object).hit()
的同义词,但错误仍然显示它仍然是设备引用
2条答案
按热度按时间5t7ly7z51#
虽然可以在设备代码中使用 Package 器,如
thrust::device_ptr
和thrust::device_reference
,但它们并不设计为将指针作为值类型保存。解引用device_ptr
给出device_reference
,其具有实现的典型值类型的许多运算符,但不具有指针类型的运算符,如进一步解引用,->
或通常使用成员方法(在下面的示例中为.get()
)。因此,必须强制(但安全地)将引用强制转换为它的底层类型,即static_cast
。我不知道为什么device_reference::operator value_type (void)
没有出现在documentation中,但是从device_reference<T>
到T
的转换/转换肯定是一个预期的特性。这创建了一个副本,而不是一个引用T&
,这对T = device_ptr<...>
来说很好,因为指针是轻量级的。因此,虽然可以使用
device_vector<device_ptr<T>>
(见下面的示例),但这可能不是一个好主意。这些 Package 器的主要目的是避免在Thrust算法中使用显式执行策略。当用于设备代码时,无法向主机调度,因此设备 Package 器最多只能携带不必要的信息。使用嵌套
device_ptr
的示例(即使它确实有效,也要避免这种情况):如果要使用
*
解引用,则需要两次强制转换,即因为X1 M15 N1 X不具有X1 M16 N1 X成员函数。
不使用 Package (这样做是为了提高可读性):
kx5bkwkv2#
根据迭代器和静态调度,您应该为此使用 raw_pointer_cast: