我正在使用推力在GPU上生成一些随机排列,如下所示:
// Compute a random list on CPU
int iterations = 500;
int src_size = 2048;
thrust::host_vector<int> cpu_rand_list (iterations * 4);
for(size_t i = 0; i < cpu_rand_list.size(); ++i) {
cpu_rand_list[i] = src_size * (rand()/(1.0 + RAND_MAX));
}
// Copy the random list to GPU
thrust::device_vector<int> gpu_rand_list = cpu_rand_list;
现在gpu_rand_list
包含一些索引的整数,我有另一个数组,如:
thrust:;device_vector<float> values(2048);
// These are now filled with some values
...
我想要做的是创建另一个列表,该列表仅包含来自gpu_rand_list
的条目,这些条目对应于values
中不等于-1的条目。所以在CPU代码中有类似的东西:
std::vector<int> refined;
for (int i = 0; i < gpu_rand_list.size(); ++i) {
if (values[gpu_rand_list[i]] != -1)
refined.push_back(gpu_rand_list[i]);
}
有没有办法实现这一目标?我试图使用copy_if结构,但无法使它与这些多个数组一起使用。
答案 0 :(得分:2)
thrust :: copy_if(特别是the stencil version,我认为)是一个合理的起点。我看到的唯一其他复杂性似乎是索引&#34;通过&#34; gpu_rand_list
。这可以通过permutation iterator完成。
(除了:当你想要对-1进行精确比较时,使用float
数组作为模板似乎对我来说有点奇怪,但也许它是有道理的。)
这样的事可能适合你:
$ cat t881.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
#include <thrust/iterator/permutation_iterator.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
using namespace thrust::placeholders;
int main(){
// Compute a random list on CPU
int iterations = 500;
int src_size = 2048;
thrust::host_vector<int> cpu_rand_list (iterations * 4);
for(size_t i = 0; i < cpu_rand_list.size(); ++i) {
cpu_rand_list[i] = src_size * (rand()/(1.0 + RAND_MAX));
}
// Copy the random list to GPU
thrust::device_vector<int> gpu_rand_list = cpu_rand_list;
thrust::device_vector<float> values(src_size, -1.0f);
// pick some values to copy
values[2] = 0; values[3] = 0; values[5] = 0;
thrust::device_vector<int> result(iterations * 4);
thrust::copy_if(gpu_rand_list.begin(), gpu_rand_list.end(),thrust::make_permutation_iterator(values.begin(), gpu_rand_list.begin()), result.begin(), _1 != -1.0f);
std::vector<float> h_values(src_size);
thrust::copy(values.begin(), values.end(), h_values.begin());
thrust::host_vector<int> h_result = result;
std::vector<int> refined;
for (int i = 0; i < cpu_rand_list.size(); ++i) {
if (h_values[cpu_rand_list[i]] != -1)
refined.push_back(gpu_rand_list[i]);
}
for (int i = 0; i < refined.size(); i++)
if (refined[i] != h_result[i]) { std::cout << "mismatch at: " << i << "was: " << h_result[i] << "should be: " << refined[i] << std::endl; return 1;}
else std::cout << refined[i] << std::endl;
return 0;
}
$ nvcc -o t881 t881.cu
$ ./t881
2
5
5
$
(我使用thrust placeholders因此我不必为copy_if操作创建一个显式仿函数。)