东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 1522|回复: 1
打印 上一主题 下一主题

[C/C++] Thrust的各种高级迭代器的使用(重要)

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14439
QQ
跳转到指定楼层
楼主
发表于 2021-7-26 16:19:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式



Thrust的各种高级迭代器的使用(重要)




  1. #include <thrust/iterator/constant_iterator.h>
  2. #include <thrust/iterator/transform_iterator.h>
  3. #include <thrust/iterator/counting_iterator.h>
  4. #include <thrust/iterator/permutation_iterator.h>
  5. #include <thrust/iterator/zip_iterator.h>
  6. #include <thrust/reduce.h>
  7. #include <thrust/device_vector.h>
  8. #include <iostream>


  9. void constant_iterator(){
  10.     //常量迭代器最明显的特点,是每次解引用时,都会返回一个相同的值
  11.     //当需要输入恒值序列时,常量迭代器将会是最便捷、高效的解决方案
  12.     // create iterators
  13.     thrust::constant_iterator<int> first(10);
  14.     thrust::constant_iterator<int> last = first + 3;

  15.     std::cout << "XXX" << std::endl;

  16.     std::cout << first[0] << std::endl;   // returns 10
  17.     std::cout << first[1] << std::endl;   // returns 10
  18.     std::cout << first[10000] << std::endl; // returns 10 不需要内存开销

  19.     // sum of [first, last)
  20.     std::cout << thrust::reduce(first, last) << std::endl;   // returns 30 (i.e. 3 * 10)
  21. }


  22. void counting_iterator(){
  23.     //如果一个序列需要不断增长的值,计数迭代器将是一个很好的选择 像数组一样访问该迭代器
  24.     //虽然常量迭代器和计数迭代器可以以数组形式访问,但实际上它们并不需要存储器开销
  25.     //每次解引用某个迭代器时,它会生成对应的值,并将该值返回给调用函数
  26.     // create iterators
  27.     thrust::counting_iterator<int> first(10);
  28.     thrust::counting_iterator<int> last = first + 3;
  29.     std::cout << first[0] << std::endl; // returns 10
  30.     std::cout << first[1] << std::endl; // returns 11
  31.     std::cout << last[0] << std::endl;  // returns 13
  32.     std::cout << first[100] << std::endl; // returns 110

  33.     // sum of [first, last)
  34.     std::cout << thrust::reduce(first, last) << std::endl; // returns 33 (i.e. 10 + 11 + 12)

  35. }


  36. void transform_iterator(){
  37.     //将transform算法和reduce算法,组合成单一的transform_reduce操作
  38.     //另一种融合transformation算法和reduction算法的方式
  39.     // initialize vector
  40.     thrust::device_vector<int> vec(3);
  41.     vec[0] = 10; vec[1] = 20; vec[2] = 30;

  42.     // create iterator (type omitted)
  43.     // 这里用的 预定义的一元函数对象 肯定是可以自定义的 uniay
  44.     typedef thrust::transform_iterator<thrust::negate<int>, thrust::device_vector<int>::iterator> J;
  45.     //转换迭代器的缺点之一,是它返回的迭代器类型很长
  46.    
  47.     J first = thrust::make_transform_iterator(vec.begin(), thrust::negate<int>());
  48.     J last  = thrust::make_transform_iterator(vec.end(),   thrust::negate<int>());

  49.     std::cout << first[0] << std::endl;   // returns -10
  50.     std::cout << first[1] << std::endl;   // returns -20
  51.     std::cout << first[2] << std::endl;   // returns -30

  52.     // sum of [first, last)
  53.     std::cout << thrust::reduce(first, last) << std::endl;   // returns -60 (i.e. -10 + -20 + -30)

  54.     // sum of [first, last)
  55.     //转换迭代器的缺点之一,是它返回的迭代器类型很长
  56.     //针对这个问题,通常的解决方法是:只要把make_transform_iterator放在被调用算法的参数里
  57.     //这样就避免了创建变量来存储第一个和最后一个迭代器
  58.     std::cout << thrust::reduce(thrust::make_transform_iterator(vec.begin(), thrust::negate<int>()),
  59.     thrust::make_transform_iterator(vec.end(), thrust::negate<int>())) << std::endl;
  60. }

  61. void permutation_iterator(){
  62.     //排列迭代器可以将分散(scatter)、聚集(gather)操作和Thrust算法进行融合
  63.      // gather locations
  64.      thrust::device_vector<int> map(4);
  65.      map[0] = 3;
  66.      map[1] = 1;
  67.      map[2] = 0;
  68.      map[3] = 5;

  69.      // array to gather from
  70.      thrust::device_vector<int> source(6);
  71.      source[0] = 10;
  72.      source[1] = 20;
  73.      source[2] = 30;
  74.      source[3] = 40;
  75.      source[4] = 50;
  76.      source[5] = 60;

  77.      // fuse gather with reduction:
  78.      //   sum = source[map[0]] + source[map[1]] + ...
  79.      int sum = thrust::reduce(thrust::make_permutation_iterator(source.begin(), map.begin()),
  80.                               thrust::make_permutation_iterator(source.begin(), map.end()));

  81.      // print sum = 130
  82.      //这里使用了make_permutation_iterator函数来构建排列迭代器
  83.      //make_permutation_iterator的第一个参数是聚合操作的源数组,第二个参数是索引数组
  84.      //当排列迭代器作为一个函数的输出序列时,它相当于分散操作与该函数的融合
  85.      //通常排列迭代器允许对序列的特定的值进行操作,而不需要对整个序列进行操作。
  86.      std::cout << "怎么求和的sum is " << sum << std::endl;
  87. }


  88. void zip_iterator(){  //最好的迭代器总是放在最后
  89.     //zip迭代器是一个非常实用的小工具:它将多个输入序列用来产生一个元组(tuple)序列
  90.     //zip迭代器之所以非常实用,是因为大多数算法只能容纳一个输入序列,或者最多可以容纳两个
  91.     //zip迭代器将多个独立的序列合并成一个单一的元组序列,使更多算法能够处理这些序列
  92.     //zip迭代器除了方便,还能使程序更有效地运行
  93.     //在CUDA里,将三维空间的点储存为float3型的数组是糟糕的,因为在访问操作时不能合并存储器的访问
  94.     //使用zip迭代器,可以将三个坐标分别存储在三个不同的数组中,这样就可以合并访存
  95.     //在这种情况下使用zip迭代器创建一个包含三维向量的(虚拟)数组,再作为thrust算法的参数
  96.     // initialize vectors
  97.     thrust::device_vector<int>  A(3);
  98.     thrust::device_vector<char> B(3);
  99.     A[0] = 10;  A[1] = 20;  A[2] = 30;
  100.     B[0] = 'x'; B[1] = 'y'; B[2] = 'z';

  101.     typedef thrust::device_vector<int>::iterator   IntIterator;  //整型的迭代器
  102.     typedef thrust::device_vector<char>::iterator  CharIterator;  //字符的
  103.     typedef thrust::tuple<IntIterator, CharIterator> IteratorTuple;  // 元组的
  104.     typedef thrust::zip_iterator<IteratorTuple> ZipIterator;      // zip的

  105.     // create iterator (type omitted)
  106.     ZipIterator first = thrust::make_zip_iterator(thrust::make_tuple(A.begin(), B.begin()));
  107.     ZipIterator last  = thrust::make_zip_iterator(thrust::make_tuple(A.end(),   B.end()));

  108.     std::cout << thrust::get<0>(first[0]) << std::endl;   // returns tuple(10, 'x')
  109.     std::cout << thrust::get<1>(first[0]) << std::endl;
  110.     //std::cout << first[1] << std::endl;   // returns tuple(20, 'y')
  111.     //std::cout << first[2] << std::endl;   // returns tuple(30, 'z')
  112.     std::cout << thrust::get<0>(first[2]) << std::endl;
  113.     std::cout << thrust::get<1>(first[2]) << std::endl;

  114.     // maximum of [first, last)
  115.     thrust::maximum< thrust::tuple<int,char> > binary_op;
  116.     thrust::tuple<int,char> init = first[0];
  117.     thrust::tuple<int,char> result = thrust::reduce(first, last, init, binary_op);  
  118.      // returns tuple(30, 'z')
  119.     std::cout << thrust::get<0>(result) << std::endl;
  120.     std::cout << thrust::get<1>(result) << std::endl;
  121. }

  122. //Thrust的各种高级迭代器的使用(重要)
  123. //对于那些熟悉的Boost C ++库的开发者,他们会发现Thrust的高级迭代器与Boost迭代器库非常相似。
  124. int main(){

  125.     // constant_iterator();

  126.     // counting_iterator();
  127.     // transform_iterator();
  128.     // permutation_iterator();

  129.     zip_iterator();


  130.    
  131.     return 0;
  132. }






复制代码


让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

0

主题

98

帖子

200

积分

中级会员

Rank: 3Rank: 3

积分
200
沙发
发表于 2021-11-23 19:35:17 | 只看该作者
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-5-19 11:47 , Processed in 0.172095 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表