扫描并生成地图(用于推力::散射)

时间:2014-10-21 09:01:16

标签: cuda thrust

我想使用推力创建一个包含通过测试的所有索引的数组。我想我在这里遗漏了一些东西,因为我似乎无法弄明白。使用推力有没有一种简单的方法呢?

struct is_odd
{
  __device__
  bool operator()(int &x)
  {
    return (x % 2) == 1;
  }
};

int A[] = {1, 2, 1, 1, 4, 1};
int result[] = {-1, -1, -1, -1, -1};

thrust::find_map_if(A, A+5, result, is_odd()); // this function doesn't exist!

// result = {0, 2, 3, 5, -1} 

我需要这个地图来分散任意数据数组(不是A)。

1 个答案:

答案 0 :(得分:3)

可能有很多方法可以解决这个问题。这是一种可能的方法:

  1. 创建索引数组(或使用计数迭代器)

    int  A[] = {1, 2, 1, 1, 4, 1};
    int iA[] = {0, 1, 2, 3, 4, 5};  
    
    例如,

    您可以使用thrust::sequence来执行此操作。或者,您可以跳过iA的显式生成,并在下一步中使用counting_iterator。

  2. 使用thrust::remove_copy_if获取索引数组并将其减少为与测试结果对应的元素。

  3. 这是一个完全有效的例子。请注意,remove_copy_if复制仿函数测试为 false 的元素:

    $ cat t596.cu
    #include <iostream>
    #include <thrust/device_vector.h>
    #include <thrust/iterator/counting_iterator.h>
    #include <thrust/remove.h>
    #include <thrust/copy.h>
    
    #define DSIZE 6
    
    struct is_odd
    {
      __device__
      bool operator()(int x) const
      {
        return !(x&1);
      }
    };
    
    int main(){
    
      int A[] = {1, 2, 1, 1, 4, 1};
      thrust::device_vector<int> d_A(A, A+DSIZE);
      thrust::device_vector<int> result(DSIZE, -1);
      thrust::counting_iterator<int> first(0);
      thrust::counting_iterator<int> last = first+DSIZE;
      thrust::device_vector<int>::iterator r_end = thrust::remove_copy_if(first, last, d_A.begin(), result.begin(), is_odd());
      thrust::copy(result.begin(), r_end, std::ostream_iterator<int>(std::cout, " "));
      std::cout << std::endl;
      thrust::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, " "));
      std::cout << std::endl;
    }
    
    $ nvcc -arch=sm_20 -o t596 t596.cu
    $ ./t596
    0 2 3 5
    0 2 3 5 -1 -1
    $