推力 我如何使用 thrust::make_zip_iterator 访问我的展平数组

Thrust How could i acces my flatten array with a thrust::make_zip_iterator

谁能解释一下为什么我无法访问我的数据。

我得到了一个展平向量

thrust::host_vector<double> input(10*3);

里面我有点数据X,Y,Z

我尝试使用 zip_iterator 来访问我的数据,所以我做了 :

typedef thrust::tuple<double, double, double, int>  tpl4int;
typedef thrust::host_vector<double>::iterator doubleiter;
typedef thrust::host_vector<int>::iterator intiter;

typedef thrust::tuple<doubleiter, doubleiter, doubleiter, intiter>  tpl4doubleiter;
typedef thrust::zip_iterator<tpl4doubleiter>  tpl4zip;

tpl4zip first = thrust::make_zip_iterator(thrust::make_tuple(input.begin(), input.begin() + N/3, input.begin() + 2*N/3, K.begin()));

我尝试这样访问我的数据:

  std::vector<tpl4int> result_sorted(N);
  thrust::copy(first,first+N/3,result_sorted.begin());  

  std::cout << "row 0 = " << result_sorted[0].get<0>() << std::endl;
  std::cout << "row 1 = " << result_sorted[0].get<1>() << std::endl;
  std::cout << "row 2 = " << result_sorted[0].get<2>() << std::endl;
  std::cout << "row 0 = " << result_sorted[0].get<3>() << std::endl;

但是我没有得到预期的结果

X = 1.0245
Y = 1.0215
Z = 5.001
index = 0

而不是

      input[0] = 1.0245;
      input[1] = 2.54;
      input[2] = 3.001;
      index    = 0;

有人能告诉我哪里错了吗?

这里是完整代码

#include <thrust/host_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/sequence.h>
#include <thrust/fill.h>
#include <thrust/tuple.h>

#define N 30 // make this evenly divisible by 3 for this example

typedef thrust::tuple<double, double, double, int>  tpl4int;
typedef thrust::host_vector<double>::iterator doubleiter;
typedef thrust::host_vector<int>::iterator intiter;

typedef thrust::tuple<doubleiter, doubleiter, doubleiter, intiter>  tpl4doubleiter;
typedef thrust::zip_iterator<tpl4doubleiter>  tpl4zip;

int main() 
{
   thrust::host_vector<double> input(10*3);

      int i=0;

//     input[0] = vec3(0,0,5.005);
      input[i++] = 1.0245;
      input[i++] = 2.54;
      input[i++] = 3.001;

//     input[1] = vec3(0,0,5.005);
      input[i++] = 2.0;
      input[i++] = 1.0;
      input[i++] = 5.01125;

//     input[2] = vec3(0,0,5.005);
      input[i++] = 6.0;
      input[i++] = 1.0;
      input[i++] = 5.0145;

    
//     input[3] = vec3(2,1,5.001);
      input[i++] = 6.0;
      input[i++] = 1.0215;
      input[i++] = 6.001;

//     input[4] = vec3(3,0,5.001);
      input[i++] = 6.0;
      input[i++] = 1.0845;
      input[i++] = 5.00125;

//     input[5] = vec3(4,0,5.001);
      input[i++] = 5.0;
      input[i++] = 0.0;
      input[i++] = 5.001;
    
//     input[6] = vec3(5,0,5.001);
      input[i++] = 5.0;
      input[i++] = 0.0;
      input[i++] = 5.001;

//     input[7] = vec3(6,0,10.501);
      input[i++] = 6.0;
      input[i++] = 0.0;
      input[i++] = 10.501;

//     input[8] = vec3(0,0,5.001);
      input[i++] = 1.0;
      input[i++] = 0.0;
      input[i++] = 5.0015478;

//     input[8] = vec3(0,0,5.001);
      input[i++] = 6.0;
      input[i++] = 1.005;
      input[i++] = 5.001;
      

  thrust::host_vector<int> K(N/3);          // keys in one row
  thrust::sequence(K.begin(), K.end(), 0);  // set index for key

  tpl4zip first = thrust::make_zip_iterator(thrust::make_tuple(input.begin(), input.begin() + N/3, input.begin() + 2*N/3, K.begin()));

  std::vector<tpl4int> result_sorted(N/3);
  thrust::copy(first,first+N/3,result_sorted.begin());  

  std::cout << "row 0 = " << result_sorted[0].get<0>() << std::endl;
  std::cout << "row 1 = " << result_sorted[0].get<1>() << std::endl;
  std::cout << "row 2 = " << result_sorted[0].get<2>() << std::endl;
  std::cout << "row 0 = " << result_sorted[0].get<3>() << std::endl;

  return 0;
}

提前致谢..

因为 zip 迭代器是这样工作的:它需要多个缓冲区(数组结构:SoA)并允许您像访问一个元组缓冲区(结构数组:AoS)一样访问它们。

zip 迭代器访问的第一个元素是元组 input[0]input[10]input[20](忽略整数)。第二个元素是input[1]input[11]input[21]等。在查看如何使用 input.begin()input.begin() + N/3input.begin() + 2*N/3 而不是 input.begin()input.begin() + 1 和 [= 初始化 zip 迭代器时,这对您来说应该有点意义21=](这是行不通的,因为您需要一个具有可配置步幅的迭代器才能这样做)。

使用 zip 迭代器通常有利于 GPU 的性能,因为它允许内存合并。如果您想使用 SIMD 向量化,这在 CPU 上也是一个好习惯。

如果您输入的是 AoS 格式,则必须“转置”它才能正确使用 zip 迭代器。根据用例,这种“转置”可能不值得付出努力,因为它是对大向量的昂贵操作。理想情况下,您首先会获得三个输入向量 xyz

使用 zip 迭代器的另一个很好的理由是它们允许您在许多算法的每个操作中使用更多的输入或输出。