| 51 | |
| 52 | template <typename T, int N> |
| 53 | void test_comp (ArrayND<T,N,true> const& a, T tot) |
| 54 | { |
| 55 | ReduceOps<ReduceOpSum> reduce_op; |
| 56 | ReduceData<T> reduce_data(reduce_op); |
| 57 | using ReduceTuple = typename decltype(reduce_data)::Type; |
| 58 | BoxND<N-1> box(IntVectShrink<N-1,N>(a.begin), |
| 59 | IntVectShrink<N-1,N>(a.end-1)); |
| 60 | reduce_op.eval(box, a.nComp(), reduce_data, |
| 61 | [=] AMREX_GPU_DEVICE (IntVectND<N-1> const& iv, int n) -> ReduceTuple |
| 62 | { |
| 63 | auto iv_full = IntVectExpand<N,N-1>(iv,n); |
| 64 | auto v0 = a(iv,n); |
| 65 | auto v1 = a(iv_full); |
| 66 | auto* p0 = a.ptr(iv,n); |
| 67 | auto* p1 = a.ptr(iv_full); |
| 68 | ArrayND<T const, N, true> b(a, n); |
| 69 | T v2 = amrex::Apply([&] (auto&&... i) { |
| 70 | return b(i...); |
| 71 | }, iv); |
| 72 | T const* p2 = amrex::Apply([&] (auto&&... i) { |
| 73 | return b.ptr(i...,0); |
| 74 | }, iv); |
| 75 | return (v0+v1+v2+*p0+*p1+*p2)/6; |
| 76 | }); |
| 77 | ReduceTuple hv = reduce_data.value(reduce_op); |
| 78 | AMREX_ALWAYS_ASSERT(tot == amrex::get<0>(hv)); |
| 79 | } |
| 80 | |
| 81 | template <typename T, int N, bool C> |
| 82 | void test (ArrayND<T,N,C>& a) |