Spaces:
Runtime error
Runtime error
| template <typename T> | |
| struct NegateBody | |
| { | |
| void operator()(T& x) const | |
| { | |
| x = -x; | |
| } | |
| }; | |
| template <typename Vector> | |
| struct ForBody | |
| { | |
| typedef typename Vector::value_type T; | |
| private: | |
| Vector& v; | |
| public: | |
| ForBody(Vector& x) : v(x) {} | |
| void operator()(tbb::blocked_range<std::size_t> const& r) const | |
| { | |
| for (std::size_t i = r.begin(); i != r.end(); ++i) | |
| v[i] = -v[i]; | |
| } | |
| }; | |
| template <typename Vector> | |
| struct ReduceBody | |
| { | |
| typedef typename Vector::value_type T; | |
| private: | |
| Vector& v; | |
| public: | |
| T sum; | |
| ReduceBody(Vector& x) : v(x), sum(0) {} | |
| ReduceBody(ReduceBody& x, tbb::split) : v(x.v), sum(0) {} | |
| void operator()(tbb::blocked_range<std::size_t> const& r) | |
| { | |
| for (std::size_t i = r.begin(); i != r.end(); ++i) | |
| sum += v[i]; | |
| } | |
| void join(ReduceBody const& x) { sum += x.sum; } | |
| }; | |
| template <typename Vector> | |
| struct ScanBody | |
| { | |
| typedef typename Vector::value_type T; | |
| private: | |
| Vector& v; | |
| public: | |
| T sum; | |
| ScanBody(Vector& x) : sum(0), v(x) {} | |
| ScanBody(ScanBody& x, tbb::split) : v(x.v), sum(0) {} | |
| template <typename Tag> | |
| void operator()(tbb::blocked_range<std::size_t> const& r, Tag) | |
| { | |
| T temp = sum; | |
| for (std::size_t i = r.begin(); i < r.end(); ++i) | |
| { | |
| temp = temp + x[i]; | |
| if (Tag::is_final_scan()) | |
| x[i] = temp; | |
| } | |
| sum = temp; | |
| } | |
| void assign(ScanBody const& x) { sum = x.sum; } | |
| T get_sum() const { return sum; } | |
| void reverse_join(ScanBody const& x) { sum = x.sum + sum;} | |
| }; | |
| template <typename Vector> | |
| struct CopyBody | |
| { | |
| typedef typename Vector::value_type T; | |
| private: | |
| Vector &v; | |
| Vector &u; | |
| public: | |
| CopyBody(Vector& x, Vector& y) : v(x), u(y) {} | |
| void operator()(tbb::blocked_range<size_t> const& r) const | |
| { | |
| for (std::size_t i = r.begin(); i != r.end(); ++i) | |
| v[i] = u[i]; | |
| } | |
| }; | |
| template <typename Vector> | |
| typename Vector::value_type tbb_reduce(Vector& v) | |
| { | |
| ReduceBody<Vector> body(v); | |
| tbb::parallel_reduce(tbb::blocked_range<size_t>(0, v.size()), body); | |
| return body.sum; | |
| } | |
| template <typename Vector> | |
| void tbb_sort(Vector& v) | |
| { | |
| tbb::parallel_sort(v.begin(), v.end()); | |
| } | |
| template <typename Vector> | |
| void tbb_transform(Vector& v) | |
| { | |
| ForBody<Vector> body(v); | |
| tbb::parallel_for(tbb::blocked_range<size_t>(0, v.size()), body); | |
| } | |
| template <typename Vector> | |
| void tbb_scan(Vector& v) | |
| { | |
| ScanBody<Vector> body(v); | |
| tbb::parallel_scan(tbb::blocked_range<size_t>(0, v.size()), body); | |
| } | |
| template <typename Vector> | |
| void tbb_copy(Vector& v, Vector& u) | |
| { | |
| CopyBody<Vector> body(v, u); | |
| tbb::parallel_for(tbb::blocked_range<size_t>(0, v.size()), body); | |
| } | |
| void test_tbb() | |
| { | |
| std::size_t elements = 1 << 20; | |
| std::vector<int> A(elements); | |
| std::vector<int> B(elements); | |
| std::vector<int> C(elements); | |
| std::vector<int> D(elements); | |
| randomize(A); | |
| randomize(B); | |
| assert(std::accumulate(A.begin(), A.end(), 0) == tbb_reduce(A)); | |
| randomize(A); | |
| randomize(B); | |
| std::transform(A.begin(), A.end(), A.begin(), thrust::negate<int>()); | |
| tbb_transform(B); | |
| assert(A == B); | |
| randomize(A); | |
| randomize(B); | |
| std::partial_sum(A.begin(), A.end(), A.begin()); | |
| tbb_scan(B); | |
| assert(A == B); | |
| randomize(A); | |
| randomize(B); | |
| std::sort(A.begin(), A.end()); | |
| tbb_sort(B); | |
| assert(A == B); | |
| randomize(A); | |
| randomize(B); | |
| randomize(C); | |
| randomize(D); | |
| std::copy(A.begin(), A.end(), C.begin()); | |
| tbb_copy(B, D); | |
| assert(A == B); | |
| assert(C == D); | |
| } | |