|
Thrust的各种高级迭代器的使用(重要)
- #include <thrust/iterator/constant_iterator.h>
- #include <thrust/iterator/transform_iterator.h>
- #include <thrust/iterator/counting_iterator.h>
- #include <thrust/iterator/permutation_iterator.h>
- #include <thrust/iterator/zip_iterator.h>
- #include <thrust/reduce.h>
- #include <thrust/device_vector.h>
- #include <iostream>
- void constant_iterator(){
- //常量迭代器最明显的特点,是每次解引用时,都会返回一个相同的值
- //当需要输入恒值序列时,常量迭代器将会是最便捷、高效的解决方案
- // create iterators
- thrust::constant_iterator<int> first(10);
- thrust::constant_iterator<int> last = first + 3;
- std::cout << "XXX" << std::endl;
- std::cout << first[0] << std::endl; // returns 10
- std::cout << first[1] << std::endl; // returns 10
- std::cout << first[10000] << std::endl; // returns 10 不需要内存开销
- // sum of [first, last)
- std::cout << thrust::reduce(first, last) << std::endl; // returns 30 (i.e. 3 * 10)
- }
- void counting_iterator(){
- //如果一个序列需要不断增长的值,计数迭代器将是一个很好的选择 像数组一样访问该迭代器
- //虽然常量迭代器和计数迭代器可以以数组形式访问,但实际上它们并不需要存储器开销
- //每次解引用某个迭代器时,它会生成对应的值,并将该值返回给调用函数
- // create iterators
- thrust::counting_iterator<int> first(10);
- thrust::counting_iterator<int> last = first + 3;
- std::cout << first[0] << std::endl; // returns 10
- std::cout << first[1] << std::endl; // returns 11
- std::cout << last[0] << std::endl; // returns 13
- std::cout << first[100] << std::endl; // returns 110
- // sum of [first, last)
- std::cout << thrust::reduce(first, last) << std::endl; // returns 33 (i.e. 10 + 11 + 12)
- }
- void transform_iterator(){
- //将transform算法和reduce算法,组合成单一的transform_reduce操作
- //另一种融合transformation算法和reduction算法的方式
- // initialize vector
- thrust::device_vector<int> vec(3);
- vec[0] = 10; vec[1] = 20; vec[2] = 30;
- // create iterator (type omitted)
- // 这里用的 预定义的一元函数对象 肯定是可以自定义的 uniay
- typedef thrust::transform_iterator<thrust::negate<int>, thrust::device_vector<int>::iterator> J;
- //转换迭代器的缺点之一,是它返回的迭代器类型很长
-
- J first = thrust::make_transform_iterator(vec.begin(), thrust::negate<int>());
- J last = thrust::make_transform_iterator(vec.end(), thrust::negate<int>());
- std::cout << first[0] << std::endl; // returns -10
- std::cout << first[1] << std::endl; // returns -20
- std::cout << first[2] << std::endl; // returns -30
- // sum of [first, last)
- std::cout << thrust::reduce(first, last) << std::endl; // returns -60 (i.e. -10 + -20 + -30)
- // sum of [first, last)
- //转换迭代器的缺点之一,是它返回的迭代器类型很长
- //针对这个问题,通常的解决方法是:只要把make_transform_iterator放在被调用算法的参数里
- //这样就避免了创建变量来存储第一个和最后一个迭代器
- std::cout << thrust::reduce(thrust::make_transform_iterator(vec.begin(), thrust::negate<int>()),
- thrust::make_transform_iterator(vec.end(), thrust::negate<int>())) << std::endl;
- }
- void permutation_iterator(){
- //排列迭代器可以将分散(scatter)、聚集(gather)操作和Thrust算法进行融合
- // gather locations
- thrust::device_vector<int> map(4);
- map[0] = 3;
- map[1] = 1;
- map[2] = 0;
- map[3] = 5;
-
- // array to gather from
- thrust::device_vector<int> source(6);
- source[0] = 10;
- source[1] = 20;
- source[2] = 30;
- source[3] = 40;
- source[4] = 50;
- source[5] = 60;
-
- // fuse gather with reduction:
- // sum = source[map[0]] + source[map[1]] + ...
- int sum = thrust::reduce(thrust::make_permutation_iterator(source.begin(), map.begin()),
- thrust::make_permutation_iterator(source.begin(), map.end()));
-
- // print sum = 130
- //这里使用了make_permutation_iterator函数来构建排列迭代器
- //make_permutation_iterator的第一个参数是聚合操作的源数组,第二个参数是索引数组
- //当排列迭代器作为一个函数的输出序列时,它相当于分散操作与该函数的融合
- //通常排列迭代器允许对序列的特定的值进行操作,而不需要对整个序列进行操作。
- std::cout << "怎么求和的sum is " << sum << std::endl;
- }
- void zip_iterator(){ //最好的迭代器总是放在最后
- //zip迭代器是一个非常实用的小工具:它将多个输入序列用来产生一个元组(tuple)序列
- //zip迭代器之所以非常实用,是因为大多数算法只能容纳一个输入序列,或者最多可以容纳两个
- //zip迭代器将多个独立的序列合并成一个单一的元组序列,使更多算法能够处理这些序列
- //zip迭代器除了方便,还能使程序更有效地运行
- //在CUDA里,将三维空间的点储存为float3型的数组是糟糕的,因为在访问操作时不能合并存储器的访问
- //使用zip迭代器,可以将三个坐标分别存储在三个不同的数组中,这样就可以合并访存
- //在这种情况下使用zip迭代器创建一个包含三维向量的(虚拟)数组,再作为thrust算法的参数
- // initialize vectors
- thrust::device_vector<int> A(3);
- thrust::device_vector<char> B(3);
- A[0] = 10; A[1] = 20; A[2] = 30;
- B[0] = 'x'; B[1] = 'y'; B[2] = 'z';
- typedef thrust::device_vector<int>::iterator IntIterator; //整型的迭代器
- typedef thrust::device_vector<char>::iterator CharIterator; //字符的
- typedef thrust::tuple<IntIterator, CharIterator> IteratorTuple; // 元组的
- typedef thrust::zip_iterator<IteratorTuple> ZipIterator; // zip的
- // create iterator (type omitted)
- ZipIterator first = thrust::make_zip_iterator(thrust::make_tuple(A.begin(), B.begin()));
- ZipIterator last = thrust::make_zip_iterator(thrust::make_tuple(A.end(), B.end()));
- std::cout << thrust::get<0>(first[0]) << std::endl; // returns tuple(10, 'x')
- std::cout << thrust::get<1>(first[0]) << std::endl;
- //std::cout << first[1] << std::endl; // returns tuple(20, 'y')
- //std::cout << first[2] << std::endl; // returns tuple(30, 'z')
- std::cout << thrust::get<0>(first[2]) << std::endl;
- std::cout << thrust::get<1>(first[2]) << std::endl;
- // maximum of [first, last)
- thrust::maximum< thrust::tuple<int,char> > binary_op;
- thrust::tuple<int,char> init = first[0];
- thrust::tuple<int,char> result = thrust::reduce(first, last, init, binary_op);
- // returns tuple(30, 'z')
- std::cout << thrust::get<0>(result) << std::endl;
- std::cout << thrust::get<1>(result) << std::endl;
- }
- //Thrust的各种高级迭代器的使用(重要)
- //对于那些熟悉的Boost C ++库的开发者,他们会发现Thrust的高级迭代器与Boost迭代器库非常相似。
- int main(){
- // constant_iterator();
- // counting_iterator();
- // transform_iterator();
- // permutation_iterator();
- zip_iterator();
-
- return 0;
- }
复制代码
|
|