| #include <thrust/transform_reduce.h> |
| #include <thrust/functional.h> |
| #include <thrust/device_vector.h> |
| #include <thrust/host_vector.h> |
| #include <thrust/iterator/constant_iterator.h> |
| #include <thrust/iterator/zip_iterator.h> |
| #include <thrust/random.h> |
| #include <thrust/extrema.h> |
| #include <cmath> |
| #include <iomanip> |
| #include <float.h> |
|
|
| |
| |
| |
|
|
|
|
| |
| |
| |
| template <typename IndexType, typename ValueType> |
| struct transform_tuple : |
| public thrust::unary_function< thrust::tuple<IndexType,ValueType>, |
| thrust::tuple<bool,ValueType,ValueType> > |
| { |
| typedef typename thrust::tuple<IndexType,ValueType> InputTuple; |
| typedef typename thrust::tuple<bool,ValueType,ValueType> OutputTuple; |
|
|
| IndexType n, N; |
|
|
| transform_tuple(IndexType n, IndexType N) : n(n), N(N) {} |
|
|
| __host__ __device__ |
| OutputTuple operator()(const InputTuple& t) const |
| { |
| bool is_valid = (thrust::get<0>(t) % N) < n; |
| return OutputTuple(is_valid, thrust::get<1>(t), thrust::get<1>(t)); |
| } |
| }; |
|
|
|
|
| |
| |
| template <typename IndexType, typename ValueType> |
| struct reduce_tuple : |
| public thrust::binary_function< thrust::tuple<bool,ValueType,ValueType>, |
| thrust::tuple<bool,ValueType,ValueType>, |
| thrust::tuple<bool,ValueType,ValueType> > |
| { |
| typedef typename thrust::tuple<bool,ValueType,ValueType> Tuple; |
|
|
| __host__ __device__ |
| Tuple operator()(const Tuple& t0, const Tuple& t1) const |
| { |
| if(thrust::get<0>(t0) && thrust::get<0>(t1)) |
| return Tuple(true, |
| thrust::min(thrust::get<1>(t0), thrust::get<1>(t1)), |
| thrust::max(thrust::get<2>(t0), thrust::get<2>(t1))); |
| else if (thrust::get<0>(t0)) |
| return t0; |
| else if (thrust::get<0>(t1)) |
| return t1; |
| else |
| return t1; |
| } |
| }; |
|
|
| int main(void) |
| { |
| int M = 10; |
| int n = 11; |
| int N = 16; |
|
|
| thrust::default_random_engine rng(12345); |
| thrust::uniform_real_distribution<float> dist(0.0f, 1.0f); |
|
|
| thrust::device_vector<float> data(M * N, -1); |
|
|
| |
| for(int i = 0; i < M; i++) |
| for(int j = 0; j < n; j++) |
| data[i * N + j] = dist(rng); |
|
|
| |
| std::cout << "padded grid" << std::endl; |
| std::cout << std::fixed << std::setprecision(4); |
| for(int i = 0; i < M; i++) |
| { |
| std::cout << " "; |
| for(int j = 0; j < N; j++) |
| { |
| std::cout << data[i * N + j] << " "; |
| } |
| std::cout << "\n"; |
| } |
| std::cout << "\n"; |
|
|
| |
| typedef thrust::tuple<bool, float, float> result_type; |
|
|
| result_type init(true, FLT_MAX, -FLT_MAX); |
| transform_tuple<int,float> unary_op(n, N); |
| reduce_tuple<int,float> binary_op; |
|
|
| result_type result = |
| thrust::transform_reduce( |
| thrust::make_zip_iterator(thrust::make_tuple(thrust::counting_iterator<int>(0), data.begin())), |
| thrust::make_zip_iterator(thrust::make_tuple(thrust::counting_iterator<int>(0), data.begin())) + data.size(), |
| unary_op, |
| init, |
| binary_op); |
|
|
| std::cout << "minimum value: " << thrust::get<1>(result) << std::endl; |
| std::cout << "maximum value: " << thrust::get<2>(result) << std::endl; |
|
|
| return 0; |
| } |
|
|
|
|