Branch data Line data Source code
1 : : //
2 : : // Class BareField
3 : : // A BareField consists of multple LFields and represents a field.
4 : : //
5 : : #include "Ippl.h"
6 : :
7 : : #include <Kokkos_ReductionIdentity.hpp>
8 : : #include <cstdlib>
9 : : #include <limits>
10 : : #include <map>
11 : : #include <utility>
12 : :
13 : : #include "Communicate/DataTypes.h"
14 : :
15 : : #include "Utility/Inform.h"
16 : : #include "Utility/IpplInfo.h"
17 : : namespace Kokkos {
18 : : template <typename T, unsigned Dim>
19 : : struct reduction_identity<ippl::Vector<T, Dim>> {
20 : : KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> sum() {
21 [ + - + - : 28 : return ippl::Vector<T, Dim>(0);
+ - + - ]
22 : : }
23 : : KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> prod() {
24 : : return ippl::Vector<T, Dim>(1);
25 : : }
26 : : KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> min() {
27 : 24 : return ippl::Vector<T, Dim>(std::numeric_limits<T>::infinity());
28 : : }
29 : : KOKKOS_FORCEINLINE_FUNCTION static ippl::Vector<T, Dim> max() {
30 : 24 : return ippl::Vector<T, Dim>(-std::numeric_limits<T>::infinity());
31 : : }
32 : : };
33 : : } // namespace Kokkos
34 : :
35 : : namespace KokkosCorrection {
36 : : template <typename Scalar, class Space = Kokkos::HostSpace>
37 : : struct Max : Kokkos::Max<Scalar, Space> {
38 : : using Super = Kokkos::Max<Scalar, Space>;
39 : : using value_type = typename Super::value_type;
40 : 24 : KOKKOS_INLINE_FUNCTION Max(value_type& vref)
41 : 24 : : Super(vref) {}
42 : : KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
43 : : using ippl::max;
44 : : using Kokkos::max;
45 : : dest = max(dest, src);
46 : : }
47 : : };
48 : : template <typename Scalar, class Space = Kokkos::HostSpace>
49 : : struct Min : Kokkos::Min<Scalar, Space> {
50 : : using Super = Kokkos::Min<Scalar, Space>;
51 : : using value_type = typename Super::value_type;
52 : 24 : KOKKOS_INLINE_FUNCTION Min(value_type& vref)
53 : 24 : : Super(vref) {}
54 : : KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
55 : : using ippl::min;
56 : : using Kokkos::min;
57 : : dest = min(dest, src);
58 : : }
59 : : };
60 : : template <typename Scalar, class Space = Kokkos::HostSpace>
61 : : struct Sum : Kokkos::Sum<Scalar, Space> {
62 : : using Super = Kokkos::Sum<Scalar, Space>;
63 : : using value_type = typename Super::value_type;
64 : 84 : KOKKOS_INLINE_FUNCTION Sum(value_type& vref)
65 : 84 : : Super(vref) {}
66 : : KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
67 : : dest += src;
68 : : }
69 : : };
70 : : template <typename Scalar, class Space = Kokkos::HostSpace>
71 : : struct Prod : Kokkos::Prod<Scalar, Space> {
72 : : using Super = Kokkos::Prod<Scalar, Space>;
73 : : using value_type = typename Super::value_type;
74 : 12 : KOKKOS_INLINE_FUNCTION Prod(value_type& vref)
75 : 12 : : Super(vref) {}
76 : : KOKKOS_INLINE_FUNCTION void join(value_type& dest, const value_type& src) const {
77 : : dest *= src;
78 : : }
79 : : };
80 : : } // namespace KokkosCorrection
81 : :
82 : : namespace ippl {
83 : : namespace detail {
84 : : template <typename T, unsigned Dim, class... ViewArgs>
85 : : struct isExpression<BareField<T, Dim, ViewArgs...>> : std::true_type {};
86 : : } // namespace detail
87 : :
88 : : template <typename T, unsigned Dim, class... ViewArgs>
89 : 24 : BareField<T, Dim, ViewArgs...>::BareField()
90 : 24 : : nghost_m(1)
91 [ + - ]: 24 : , layout_m(nullptr) {}
92 : :
93 : : template <typename T, unsigned Dim, class... ViewArgs>
94 : 12 : BareField<T, Dim, ViewArgs...> BareField<T, Dim, ViewArgs...>::deepCopy() const {
95 : 12 : BareField<T, Dim, ViewArgs...> copy(*layout_m, nghost_m);
96 [ + - ]: 12 : Kokkos::deep_copy(copy.dview_m, dview_m);
97 : 12 : return copy;
98 : 0 : }
99 : :
100 : : template <typename T, unsigned Dim, class... ViewArgs>
101 : 712 : BareField<T, Dim, ViewArgs...>::BareField(Layout_t& l, int nghost)
102 : 712 : : nghost_m(nghost)
103 : : // , owned_m(0)
104 [ + - ]: 712 : , layout_m(&l) {
105 [ + - ]: 712 : setup();
106 : 712 : }
107 : :
108 : : template <typename T, unsigned Dim, class... ViewArgs>
109 : 24 : void BareField<T, Dim, ViewArgs...>::initialize(Layout_t& l, int nghost) {
110 [ + - ]: 24 : if (layout_m == 0) {
111 : 24 : layout_m = &l;
112 : 24 : nghost_m = nghost;
113 : 24 : setup();
114 : : }
115 : 24 : }
116 : :
117 : : // ML
118 : : template <typename T, unsigned Dim, class... ViewArgs>
119 : 48 : void BareField<T, Dim, ViewArgs...>::updateLayout(Layout_t& l, int nghost) {
120 : : // std::cout << "Got in BareField::updateLayout()" << std::endl;
121 : 48 : layout_m = &l;
122 : 48 : nghost_m = nghost;
123 : 48 : setup();
124 : 48 : }
125 : :
126 : : template <typename T, unsigned Dim, class... ViewArgs>
127 : 784 : void BareField<T, Dim, ViewArgs...>::setup() {
128 [ + - ]: 784 : owned_m = layout_m->getLocalNDIndex();
129 : :
130 : 2352 : auto resize = [&]<size_t... Idx>(const std::index_sequence<Idx...>&) {
131 : 784 : this->resize((owned_m[Idx].length() + 2 * nghost_m)...);
132 : : };
133 [ + - ]: 784 : resize(std::make_index_sequence<Dim>{});
134 : 784 : }
135 : :
136 : : template <typename T, unsigned Dim, class... ViewArgs>
137 : : template <typename... Args>
138 : 784 : void BareField<T, Dim, ViewArgs...>::resize(Args... args) {
139 : 784 : Kokkos::resize(dview_m, args...);
140 : 784 : }
141 : :
142 : : template <typename T, unsigned Dim, class... ViewArgs>
143 : 122 : void BareField<T, Dim, ViewArgs...>::fillHalo() {
144 [ - + ]: 122 : if (layout_m->comm.size() > 1) {
145 : 0 : halo_m.fillHalo(dview_m, layout_m);
146 : : }
147 [ - + ]: 122 : if (layout_m->isAllPeriodic_m) {
148 : : using Op = typename detail::HaloCells<T, Dim, ViewArgs...>::assign;
149 : 0 : halo_m.template applyPeriodicSerialDim<Op>(dview_m, layout_m, nghost_m);
150 : : }
151 : 122 : }
152 : :
153 : : template <typename T, unsigned Dim, class... ViewArgs>
154 : 60 : void BareField<T, Dim, ViewArgs...>::accumulateHalo() {
155 [ - + ]: 60 : if (layout_m->comm.size() > 1) {
156 : 0 : halo_m.accumulateHalo(dview_m, layout_m);
157 : : }
158 [ + + ]: 60 : if (layout_m->isAllPeriodic_m) {
159 : : using Op = typename detail::HaloCells<T, Dim, ViewArgs...>::rhs_plus_assign;
160 : 36 : halo_m.template applyPeriodicSerialDim<Op>(dview_m, layout_m, nghost_m);
161 : : }
162 : 60 : }
163 : :
164 : : template <typename T, unsigned Dim, class... ViewArgs>
165 : 336 : BareField<T, Dim, ViewArgs...>& BareField<T, Dim, ViewArgs...>::operator=(T x) {
166 : : using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type;
167 [ + - + - ]: 336 : ippl::parallel_for(
168 : 336 : "BareField::operator=(T)", getRangePolicy(dview_m),
169 [ + - + - : 43562288 : KOKKOS_CLASS_LAMBDA(const index_array_type& args) { apply(dview_m, args) = x; });
- - ]
170 : 336 : return *this;
171 : : }
172 : :
173 : : template <typename T, unsigned Dim, class... ViewArgs>
174 : : template <typename E, size_t N>
175 : 254 : BareField<T, Dim, ViewArgs...>& BareField<T, Dim, ViewArgs...>::operator=(
176 : : const detail::Expression<E, N>& expr) {
177 : : using capture_type = detail::CapturedExpression<E, N>;
178 : 254 : capture_type expr_ = reinterpret_cast<const capture_type&>(expr);
179 : : using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type;
180 [ + - + - ]: 254 : ippl::parallel_for(
181 : 254 : "BareField::operator=(const Expression&)", getRangePolicy(dview_m, nghost_m),
182 [ + - + - : 10040444 : KOKKOS_CLASS_LAMBDA(const index_array_type& args) {
- - ]
183 [ + - + - : 5019968 : apply(dview_m, args) = apply(expr_, args);
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
[ # # # #
# # # # #
# ]
[ # # # # ]
[ # # # #
# # # # #
# # # # #
# # ][ # #
# # # # #
# ]
184 : : });
185 : 254 : return *this;
186 : : }
187 : :
188 : : template <typename T, unsigned Dim, class... ViewArgs>
189 : 0 : void BareField<T, Dim, ViewArgs...>::write(std::ostream& out) const {
190 [ # # # # ]: 0 : Kokkos::fence();
191 : 0 : detail::write<T, Dim>(dview_m, out);
192 : 0 : }
193 : :
194 : : template <typename T, unsigned Dim, class... ViewArgs>
195 : 0 : void BareField<T, Dim, ViewArgs...>::write(Inform& inf) const {
196 : 0 : write(inf.getDestination());
197 : 0 : }
198 : :
199 : : #define DefineReduction(fun, name, op, MPI_Op) \
200 : : template <typename T, unsigned Dim, class... ViewArgs> \
201 : : T BareField<T, Dim, ViewArgs...>::name(int nghost) const { \
202 : : PAssert_LE(nghost, nghost_m); \
203 : : T temp = Kokkos::reduction_identity<T>::name(); \
204 : : using index_array_type = typename RangePolicy<Dim, execution_space>::index_array_type; \
205 : : ippl::parallel_reduce( \
206 : : "fun", getRangePolicy(dview_m, nghost_m - nghost), \
207 : : KOKKOS_CLASS_LAMBDA(const index_array_type& args, T& valL) { \
208 : : T myVal = apply(dview_m, args); \
209 : : op; \
210 : : }, \
211 : : KokkosCorrection::fun<T>(temp)); \
212 : : T globaltemp = 0.0; \
213 : : layout_m->comm.allreduce(temp, globaltemp, 1, MPI_Op<T>()); \
214 : : return globaltemp; \
215 : : }
216 : :
217 [ + + + - : 1670940 : DefineReduction(Sum, sum, valL += myVal, std::plus)
+ - + - +
- + - + -
+ - ]
218 [ + + + - : 477420 : DefineReduction(Max, max, using Kokkos::max; valL = max(valL, myVal), std::greater)
+ - + - +
- + - + -
+ - ]
219 [ + + + - : 477420 : DefineReduction(Min, min, using Kokkos::min; valL = min(valL, myVal), std::less)
+ - + - +
- + - + -
+ - ]
220 [ - + - - : 238704 : DefineReduction(Prod, prod, valL *= myVal, std::multiplies)
+ - + - +
- + - + -
+ - ]
221 : :
222 : : } // namespace ippl
|