Work with interleaved data in traction

What is the best way to work with interleaved data in a push, let's say I want to add values ​​with an interlace length of 3, for example:

[1, 2, 3, 4, 5, 6]

will give

[6, 15]

or data interleaving, therefore

[1, 2, 3, 4, 5, 6, 7, 8, 9]

will give

[1, 4, 7, 2, 5, 8, 3, 6, 9]

thank

+5
source share
1 answer

There are two questions here. First, he asks how to perform a structured reduction in the data set, and the second asks how to change the order of the data set during matching.

, . , reduce_by_key counting_iterator. , "" . reduce_by_key .

. gather. counting_iterator . ​​ (, transform) permutation_iterator. , .

, GPU - , .


, :

#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <thrust/gather.h>
#include <thrust/functional.h>

struct divide_by_three
  : thrust::unary_function<unsigned int, unsigned int>
{
  __host__ __device__
  unsigned int operator()(unsigned int i)
  {
    return i / 3;
  }
};

struct deinterleave_index
  : thrust::unary_function<unsigned int, unsigned int>
{
  __host__ __device__
  unsigned int operator()(unsigned int i)
  {
    return (i/3) + 3 * (i%3);
  }
};

int main()
{
  using namespace thrust;

  device_vector<int> example_one(6);
  example_one[0] = 1; example_one[1] = 2; example_one[2] = 3;
  example_one[3] = 4; example_one[4] = 5; example_one[5] = 6;

  // the result will have size two
  device_vector<int> example_one_result(2);

  // for each datum, associate an key, which is the datum index divided by three
  // reduce the data by key
  reduce_by_key(make_transform_iterator(make_counting_iterator(0u), divide_by_three()),
                make_transform_iterator(make_counting_iterator(6u), divide_by_three()),
                example_one.begin(),
                thrust::make_discard_iterator(),
                example_one_result.begin());

  std::cout << "example one input:  [ ";
  thrust::copy(example_one.begin(), example_one.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << "]" << std::endl;

  std::cout << "example one result: [ ";
  thrust::copy(example_one_result.begin(), example_one_result.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << "]" << std::endl;


  device_vector<int> example_two(9);
  example_two[0] = 1; example_two[1] = 2; example_two[2] = 3;
  example_two[3] = 4; example_two[4] = 5; example_two[5] = 6;
  example_two[6] = 7; example_two[7] = 8; example_two[8] = 9;

  // the result will be the same size
  device_vector<int> example_two_result(9);

  // gather using the mapping defined by deinterleave_index
  gather(make_transform_iterator(make_counting_iterator(0u), deinterleave_index()),
         make_transform_iterator(make_counting_iterator(9u), deinterleave_index()),
         example_two.begin(),
         example_two_result.begin());

  std::cout << "example two input:  [ ";
  thrust::copy(example_two.begin(), example_two.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << "]" << std::endl;

  std::cout << "example two result: [ ";
  thrust::copy(example_two_result.begin(), example_two_result.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << "]" << std::endl;

  return 0;
}

:

$ nvcc test.cu -run
example one input:  [ 1 2 3 4 5 6 ]
example one result: [ 6 15 ]
example two input:  [ 1 2 3 4 5 6 7 8 9 ]
example two result: [ 1 4 7 2 5 8 3 6 9 ]
+5

All Articles