推力::如何做这个选择性复制的情况

时间:2015-08-14 15:36:20

标签: cuda thrust

我正在使用推力在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结构,但无法使它与这些多个数组一起使用。

1 个答案:

答案 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操作创建一个显式仿函数。)