正如 Talonmies 链接的问题中所述,您不能从 CUDA 函数调用 Thrust(例如__device__
or __global__
)。但是,这并不意味着您不能通过 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
and raw_keys
当您用以下命令包装它们时,它们仍在设备内存中Thrust::device_ptr
,因此当您从主机调用 Thrust 函数时,它不必将任何内存从主机复制到设备,反之亦然。也就是说,您可以使用设备内存直接在 GPU 上进行排序;唯一的开销是启动 Thrust 内核并包装原始设备指针。
当然,如果您之后需要在常规 CUDA 内核中使用它们,您可以取回原始指针:
unsigned int * raw_ptr = thrust::raw_pointer_cast(dev_data_ptr);
至于使用unsigned long long int
or unsigned int
作为你的钥匙与数据unsigned int
,这不是问题,因为 Thrust 是模板化的。也就是说,签名为sort_by_key
is
template<typename RandomAccessIterator1 , typename RandomAccessIterator2 >
void thrust::sort_by_key(
RandomAccessIterator1 keys_first,
RandomAccessIterator1 keys_last,
RandomAccessIterator2 values_first )
这意味着您可以使用不同类型的键和数据。只要给定调用的所有键类型都是同质的,Thrust 就应该能够自动推断类型,并且您无需执行任何特殊操作。希望这是有道理的