Line data Source code
1 : //
2 : // Class HaloCells
3 : // The guard / ghost cells of BareField.
4 : //
5 : #ifndef IPPL_HALO_CELLS_H
6 : #define IPPL_HALO_CELLS_H
7 :
8 : #include <array>
9 :
10 : #include "Types/IpplTypes.h"
11 : #include "Types/ViewTypes.h"
12 :
13 : #include "Communicate/Archive.h"
14 : #include "FieldLayout/FieldLayout.h"
15 : #include "Index/NDIndex.h"
16 :
17 : namespace ippl {
18 : namespace detail {
19 : /*!
20 : * Helper class to send / receive field data.
21 : */
22 : template <typename T, class... ViewArgs>
23 : struct FieldBufferData {
24 : using view_type = typename detail::ViewType<T, 1, ViewArgs...>::view_type;
25 : using archive_type = Archive<typename view_type::memory_space>;
26 :
27 0 : void serialize(archive_type& ar, size_type nsends) { ar.serialize(buffer, nsends); }
28 :
29 0 : void deserialize(archive_type& ar, size_type nrecvs) { ar.deserialize(buffer, nrecvs); }
30 :
31 : view_type buffer;
32 : };
33 :
34 : /*!
35 : * This class provides the functionality to do field halo exchange.
36 : * @file HaloCells.h
37 : */
38 : template <typename T, unsigned Dim, class... ViewArgs>
39 : class HaloCells {
40 : public:
41 : using view_type = typename detail::ViewType<T, Dim, ViewArgs...>::view_type;
42 : using Layout_t = FieldLayout<Dim>;
43 : using bound_type = typename Layout_t::bound_type;
44 : using databuffer_type = FieldBufferData<T, ViewArgs...>;
45 :
46 : enum SendOrder {
47 : HALO_TO_INTERNAL,
48 : INTERNAL_TO_HALO,
49 : HALO_TO_INTERNAL_NOGHOST
50 : };
51 :
52 : HaloCells();
53 :
54 : /*!
55 : * Send halo data to internal cells. This operation uses
56 : * assign_plus functor to assign the data.
57 : * @param view the original field data
58 : * @param layout the field layout storing the domain decomposition
59 : */
60 : void accumulateHalo(view_type& view, Layout_t* layout);
61 :
62 : /*!
63 : * Send halo data to internal cells for only the physical cells
64 : * along that dimension. The halo cells on the corners are not sent.
65 : * This operation uses assign_plus functor to assign the data.
66 : * @param view the original field data
67 : * @param layout the field layout storing the domain decomposition
68 : * @param nghost the number of ghost cells
69 : */
70 : void accumulateHalo_noghost(view_type& view, Layout_t* layout, int nghost);
71 :
72 : /*!
73 : * Send interal data to halo cells. This operation uses
74 : * assign functor to assign the data.
75 : * @param view the original field data
76 : * @param layout the field layout storing the domain decomposition
77 : */
78 : void fillHalo(view_type&, Layout_t* layout);
79 :
80 : /*!
81 : * Pack the field data to be sent into a contiguous array.
82 : * @param range the bounds of the subdomain to be sent
83 : * @param view the original view
84 : * @param fd the buffer to pack into
85 : */
86 : void pack(const bound_type& range, const view_type& view, databuffer_type& fd,
87 : size_type& nsends);
88 :
89 : /*!
90 : * Unpack the received field data and assign it.
91 : * @param range the bounds of the subdomain to be received
92 : * @param view the original view
93 : * @param fd the buffer to unpack from (received data)
94 : * @tparam Op the data assigment operator
95 : */
96 : template <typename Op>
97 : void unpack(const bound_type& range, const view_type& view, databuffer_type& fd);
98 :
99 : /*!
100 : * Operator for the unpack function.
101 : * This operator is used in case of INTERNAL_TO_HALO.
102 : */
103 : struct assign {
104 0 : KOKKOS_INLINE_FUNCTION void operator()(T& lhs, const T& rhs) const { lhs = rhs; }
105 : };
106 :
107 : /*!
108 : * Operator for the unpack function.
109 : * This operator is used in case of HALO_TO_INTERNAL.
110 : */
111 : struct lhs_plus_assign {
112 0 : KOKKOS_INLINE_FUNCTION void operator()(T& lhs, const T& rhs) const { lhs += rhs; }
113 : };
114 :
115 : /*!
116 : * This operator is used in case of HALO_TO_INTERNAL for
117 : * all periodic BCs application in BareField.
118 : */
119 : struct rhs_plus_assign {
120 7233804 : KOKKOS_INLINE_FUNCTION void operator()(const T& lhs, T& rhs) const { rhs += lhs; }
121 : };
122 :
123 : /*!
124 : * Apply all periodic boundary conditions for the
125 : * serial dimensions. Used in case of both fillHalo
126 : * and accumulateHalo with the help of operator as
127 : * template parameter.
128 : */
129 : template <typename Op>
130 : void applyPeriodicSerialDim(view_type& view, const Layout_t* layout, const int nghost);
131 :
132 : private:
133 : /*!
134 : * Exchange the data of halo cells.
135 : * @param view is the original field data
136 : * @param layout the field layout storing the domain decomposition
137 : * @param order the data send orientation
138 : * @tparam Op the data assigment operator of the
139 : * unpack function call
140 : */
141 : template <class Op>
142 : void exchangeBoundaries(view_type& view, Layout_t* layout, SendOrder order, int nghost = 1);
143 :
144 : /*!
145 : * Extract the subview of the original data. This does not copy.
146 : * A subview points to the same memory.
147 : * @param view is the original field data
148 : * @param intersect the bounds of the intersection
149 : */
150 : auto makeSubview(const view_type& view, const bound_type& intersect);
151 :
152 : databuffer_type haloData_m;
153 : };
154 : } // namespace detail
155 : } // namespace ippl
156 :
157 : #include "Field/HaloCells.hpp"
158 :
159 : #endif
|