如Talonmies关联的问题所述,您不能从CUDA函数调用Thrust(例如__device__
或__global__
)。但是,这并不意味着您不能在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_keys
仍然在设备内存中,当你用Thrust::device_ptr
包装他们,所以当你调用来自主机的推力作用,它不具有复制任何记忆从主机到设备,反之亦然。也就是说,您使用设备内存直接在GPU上进行排序;唯一的开销就是启动Thrust内核并包装原始设备指针。
当然,你可以得到你的原始指针回来,如果你需要在常规CUDA内核以后使用它们:
unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr);
至于使用或者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)
这意味着你可以有不同类型的密钥和数据。只要所有的键类型对于给定的调用都是同质的,Thrust应该能够自动推断出类型,并且不需要做任何特殊的事情。希望这是有道理的
@ user1760748:这个答案是否满足你?如果没有,请说明它是否有问题... – einpoklum