This question already has answers here:
Thrust inside user written kernels

(4个答案)


5年前关闭。




Thrust库可用于对数据进行排序。调用可能看起来像这样(带有键和值向量):
thrust::sort_by_key(d_keys.begin(), d_keys.end(), d_values.begin());

在CPU上调用,并且d_keysd_values在CPU内存中;并且大部分执行都在GPU上进行。

但是,我的数据已经在GPU上了吗?如何使用Thrust库直接在GPU上执行高效排序,即从内核调用sort_by_key函数?

另外,我的数据由以下两个键组成:unsigned long long intunsigned int以及始终为unsigned int的数据。对于这些类型,我该如何发出紧急呼吁?

最佳答案

如所链接的Talonmies问题中所述,您不能从CUDA函数(例如__device____global__)中调用Thrust。但是,这并不意味着您无法通过Thrust使用设备内存中已有的数据。相反,您可以使用包装原始数据的Thrust向量从主机调用所需的Thrust函数。例如

//raw pointer to device memory
unsigned int * raw_data;
unsigned int * raw_keys;
//allocate device memory for data and keys
cudaMalloc((void **) &raw_data, N_data * sizeof(int));
cudaMalloc((void **) &raw_keys, N_keys * sizeof(int));

//populate your device pointers in your kernel
kernel<<<...>>>(raw_data, raw_keys, ...);

...

//wrap raw pointer with a device_ptr to use with Thrust functions
thrust::device_ptr<unsigned int> dev_data_ptr(raw_data);
thrust::device_ptr<unsigned int> dev_keys_ptr(raw_keys);

//use the device memory with a thrust call
thrust::sort_by_key(d_keys, d_keys + N_keys, dev_data_ptr);

当您用raw_data包装它们时,raw_keysThrust::device_ptr指向的设备内存仍在设备内存中,因此,当您从主机调用Thrust函数时,它不必将任何内存从主机复制到设备,反之亦然。也就是说,您正在使用设备内存直接在GPU上进行排序;您唯一的开销就是启动Thrust内核并包装原始设备指针。

当然,如果以后需要在常规CUDA内核中使用它们,则可以找回原始指针:
unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr);

至于使用unsigned long long intunsigned int作为带有unsigned int数据的键,这不是问题,因为Thrust是模板化的。也就是说,sort_by_key的签名是
template<typename RandomAccessIterator1 , typename RandomAccessIterator2 >
void thrust::sort_by_key(
    RandomAccessIterator1   keys_first,
    RandomAccessIterator1   keys_last,
    RandomAccessIterator2   values_first )

这意味着您可以为 key 和数据使用不同的类型。只要您的所有键类型对于一个给定的调用都是同质的,Thrust应该能够自动推断出这些类型,而您不必做任何特殊的事情。希望这是有道理的

关于sorting - CUDA:如何直接在GPU上使用推力::: sort_by_key?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15609126/

10-11 22:11