CUDA:如何直接在GPU上使用thrust :: sort_by_key?

use*_*748 8 sorting cuda thrust

Thrust库可用于对数据进行排序.调用可能看起来像这样(带有键和值向量):

thrust::sort_by_key(d_keys.begin(), d_keys.end(), d_values.begin());
Run Code Online (Sandbox Code Playgroud)

称为在CPU上,以d_keys及d_values在CPU存储器是; 并且大部分执行都发生在GPU上.

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

此外,我的数据包括或者是unsigned long long int或者unsigned int始终是数据的键 unsigned int.我应该如何对这些类型进行推力调用?

alr*_*kai 8

正如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);
Run Code Online (Sandbox Code Playgroud)

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

当然,如果您需要在以后的常规CUDA内核中使用它们,您可以获得原始指针:

unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr);
Run Code Online (Sandbox Code Playgroud)

至于使用任何一个unsigned long long int或unsigned 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 )
Run Code Online (Sandbox Code Playgroud)

意味着您可以为键和数据设置不同的类型.只要你的所有键类型对于给定的调用都是同质的,Thrust就应该能够自动推断出类型,你不必做任何特别的事情.希望这是有道理的