Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <mutex>
7 : #include <unordered_map>
8 : #include <utility>
9 :
10 : #include "Parallel/ArrayComponentId.hpp"
11 : #include "Parallel/Callback.hpp"
12 : #include "Parallel/Phase.hpp"
13 : #include "Parallel/PhaseDependentActionList.hpp"
14 : #include "Utilities/TMPL.hpp"
15 : #include "Utilities/TaggedTuple.hpp"
16 : #include "Utilities/TypeTraits.hpp"
17 :
18 : namespace Parallel {
19 : namespace detail {
20 : template <class Action, class = std::void_t<>>
21 : struct get_inbox_tags_from_action {
22 : using type = tmpl::list<>;
23 : };
24 :
25 : template <class Action>
26 : struct get_inbox_tags_from_action<Action,
27 : std::void_t<typename Action::inbox_tags>> {
28 : using type = typename Action::inbox_tags;
29 : };
30 : } // namespace detail
31 :
32 : /*!
33 : * \ingroup ParallelGroup
34 : * \brief Given a list of Actions, get a list of the unique inbox tags
35 : */
36 : template <class ActionsList>
37 1 : using get_inbox_tags = tmpl::remove_duplicates<tmpl::join<tmpl::transform<
38 : ActionsList, detail::get_inbox_tags_from_action<tmpl::_1>>>>;
39 :
40 : namespace detail {
41 : // ParallelStruct is a metavariables, component, or action struct
42 : template <class ParallelStruct, class = std::void_t<>>
43 : struct get_const_global_cache_tags_from_parallel_struct {
44 : using type = tmpl::list<>;
45 : };
46 :
47 : template <class ParallelStruct>
48 : struct get_const_global_cache_tags_from_parallel_struct<
49 : ParallelStruct,
50 : std::void_t<typename ParallelStruct::const_global_cache_tags>> {
51 : using type = typename ParallelStruct::const_global_cache_tags;
52 : };
53 :
54 : template <class PhaseDependentActionList>
55 : struct get_const_global_cache_tags_from_pdal {
56 : using type = tmpl::join<tmpl::transform<
57 : tmpl::flatten<tmpl::transform<
58 : PhaseDependentActionList,
59 : get_action_list_from_phase_dep_action_list<tmpl::_1>>>,
60 : get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>>;
61 : };
62 :
63 : template <class Component>
64 : struct get_const_global_cache_tags_from_component {
65 : using type = typename get_const_global_cache_tags_from_pdal<
66 : typename Component::phase_dependent_action_list>::type;
67 : };
68 :
69 : template <class ParallelStruct, class = std::void_t<>>
70 : struct get_mutable_global_cache_tags_from_parallel_struct {
71 : using type = tmpl::list<>;
72 : };
73 :
74 : template <class ParallelStruct>
75 : struct get_mutable_global_cache_tags_from_parallel_struct<
76 : ParallelStruct,
77 : std::void_t<typename ParallelStruct::mutable_global_cache_tags>> {
78 : using type = typename ParallelStruct::mutable_global_cache_tags;
79 : };
80 :
81 : template <class PhaseDependentActionList>
82 : struct get_mutable_global_cache_tags_from_pdal {
83 : using type = tmpl::join<tmpl::transform<
84 : tmpl::flatten<tmpl::transform<
85 : PhaseDependentActionList,
86 : get_action_list_from_phase_dep_action_list<tmpl::_1>>>,
87 : get_mutable_global_cache_tags_from_parallel_struct<tmpl::_1>>>;
88 : };
89 :
90 : template <class Component>
91 : struct get_mutable_global_cache_tags_from_component {
92 : using type = typename get_mutable_global_cache_tags_from_pdal<
93 : typename Component::phase_dependent_action_list>::type;
94 : };
95 :
96 : } // namespace detail
97 :
98 : /*!
99 : * \ingroup ParallelGroup
100 : * \brief Given a list of Actions, get a list of the unique tags specified in
101 : * the actions' `const_global_cache_tags` aliases.
102 : */
103 : template <class ActionsList>
104 1 : using get_const_global_cache_tags_from_actions =
105 : tmpl::remove_duplicates<tmpl::join<tmpl::transform<
106 : ActionsList,
107 : detail::get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>>>;
108 :
109 : /*!
110 : * \ingroup ParallelGroup
111 : * \brief Given a list of Actions, get a list of the unique tags specified in
112 : * the actions' `mutable_global_cache_tags` aliases.
113 : */
114 : template <class ActionsList>
115 1 : using get_mutable_global_cache_tags_from_actions =
116 : tmpl::remove_duplicates<tmpl::join<tmpl::transform<
117 : ActionsList,
118 : detail::get_mutable_global_cache_tags_from_parallel_struct<tmpl::_1>>>>;
119 :
120 : /*!
121 : * \ingroup ParallelGroup
122 : * \brief Given the metavariables, get a list of the unique tags that will
123 : * specify the items in the GlobalCache.
124 : */
125 : template <typename Metavariables>
126 1 : using get_const_global_cache_tags =
127 : tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
128 : typename detail::get_const_global_cache_tags_from_parallel_struct<
129 : Metavariables>::type,
130 : tmpl::transform<
131 : typename Metavariables::component_list,
132 : detail::get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>,
133 : tmpl::transform<
134 : typename Metavariables::component_list,
135 : detail::get_const_global_cache_tags_from_component<tmpl::_1>>>>>;
136 :
137 : /*!
138 : * \ingroup ParallelGroup
139 : * \brief Given the metavariables, get a list of the unique tags that will
140 : * specify the mutable items in the GlobalCache.
141 : */
142 : template <typename Metavariables>
143 1 : using get_mutable_global_cache_tags =
144 : tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
145 : typename detail::get_mutable_global_cache_tags_from_parallel_struct<
146 : Metavariables>::type,
147 : tmpl::transform<
148 : typename Metavariables::component_list,
149 : detail::get_mutable_global_cache_tags_from_parallel_struct<
150 : tmpl::_1>>,
151 : tmpl::transform<
152 : typename Metavariables::component_list,
153 : detail::get_mutable_global_cache_tags_from_component<tmpl::_1>>>>>;
154 :
155 : /*!
156 : * \ingroup ParallelGroup
157 : * \brief Check whether a tag is retrievable from the const portion of
158 : * the global cache.
159 : */
160 : template <typename Metavariables, typename Tag>
161 1 : constexpr bool is_in_const_global_cache =
162 : tmpl::size<tmpl::filter<get_const_global_cache_tags<Metavariables>,
163 : std::is_base_of<tmpl::pin<Tag>, tmpl::_1>>>::value >
164 : 0;
165 :
166 : /*!
167 : * \ingroup ParallelGroup
168 : * \brief Check whether a tag is retrievable from the mutable portion of
169 : * the global cache.
170 : */
171 : template <typename Metavariables, typename Tag>
172 1 : constexpr bool is_in_mutable_global_cache =
173 : tmpl::size<tmpl::filter<get_mutable_global_cache_tags<Metavariables>,
174 : std::is_base_of<tmpl::pin<Tag>, tmpl::_1>>>::value >
175 : 0;
176 :
177 : /*!
178 : * \ingroup ParallelGroup
179 : * \brief Check whether a tag is retrievable from the global cache.
180 : */
181 : template <typename Metavariables, typename Tag>
182 1 : constexpr bool is_in_global_cache =
183 : is_in_const_global_cache<Metavariables, Tag> or
184 : is_in_mutable_global_cache<Metavariables, Tag>;
185 :
186 : template <typename Tag>
187 0 : struct MutexTag {
188 0 : using type = std::pair<std::mutex, std::mutex>;
189 : };
190 :
191 : template <typename Tag>
192 0 : struct MutableCacheTag {
193 0 : using tag = Tag;
194 0 : using type = std::tuple<typename Tag::type,
195 : std::unordered_map<Parallel::ArrayComponentId,
196 : std::unique_ptr<Callback>>>;
197 : };
198 :
199 : template <typename Tag>
200 0 : struct get_mutable_cache_tag {
201 0 : using type = MutableCacheTag<Tag>;
202 : };
203 :
204 : template <typename Metavariables>
205 0 : using get_mutable_global_cache_tag_storage =
206 : tmpl::transform<get_mutable_global_cache_tags<Metavariables>,
207 : get_mutable_cache_tag<tmpl::_1>>;
208 :
209 : namespace GlobalCache_detail {
210 :
211 : template <typename T>
212 : struct type_for_get_helper {
213 : using type = T;
214 : };
215 :
216 : template <typename T, typename D>
217 : struct type_for_get_helper<std::unique_ptr<T, D>> {
218 : using type = T;
219 : };
220 :
221 : // This struct provides a better error message if
222 : // an unknown tag is requested from the GlobalCache.
223 : template <typename GlobalCacheTag, typename ListOfPossibleTags>
224 : struct matching_tag_helper {
225 : using found_tags =
226 : tmpl::filter<ListOfPossibleTags,
227 : std::is_base_of<tmpl::pin<GlobalCacheTag>, tmpl::_1>>;
228 : static_assert(not std::is_same_v<found_tags, tmpl::list<>>,
229 : "Trying to get a nonexistent tag from the GlobalCache. "
230 : "To diagnose the problem, search for "
231 : "'matching_tag_helper' in the error message. "
232 : "The first template parameter of "
233 : "'matching_tag_helper' is the requested tag, and "
234 : "the second template parameter is a tmpl::list of all the "
235 : "tags in the GlobalCache. One possible bug that may "
236 : "lead to this error message is a missing or misspelled "
237 : "const_global_cache_tags or mutable_global_cache_tags "
238 : "type alias.");
239 : static_assert(tmpl::size<found_tags>::value == 1,
240 : "Found more than one matching tag. "
241 : "To diagnose the problem, search for "
242 : "'matching_tag_helper' in the error message. "
243 : "The first template parameter of "
244 : "'matching_tag_helper' is the requested tag, and "
245 : "the second template parameter is a tmpl::list of all the "
246 : "tags in the GlobalCache.");
247 : using type = tmpl::front<found_tags>;
248 : };
249 :
250 : template <class GlobalCacheTag, class Metavariables>
251 : using get_matching_mutable_tag = typename matching_tag_helper<
252 : GlobalCacheTag, get_mutable_global_cache_tags<Metavariables>>::type;
253 : } // namespace GlobalCache_detail
254 :
255 : namespace detail {
256 : template <typename PhaseAction>
257 : struct get_initialization_actions_list {
258 : using type = tmpl::list<>;
259 : };
260 :
261 : template <typename InitializationActionsList>
262 : struct get_initialization_actions_list<Parallel::PhaseActions<
263 : Parallel::Phase::Initialization, InitializationActionsList>> {
264 : using type = InitializationActionsList;
265 : };
266 : } // namespace detail
267 :
268 : /// \ingroup ParallelGroup
269 : /// \brief Given the phase dependent action list, return the list of
270 : /// actions in the Initialization phase (or an empty list if the Initialization
271 : /// phase is absent from the phase dependent action list)
272 : template <typename PhaseDepActionList>
273 1 : using get_initialization_actions_list = tmpl::flatten<tmpl::transform<
274 : PhaseDepActionList, detail::get_initialization_actions_list<tmpl::_1>>>;
275 :
276 : namespace detail {
277 : template <typename Action, typename = std::void_t<>>
278 : struct get_simple_tags_from_options_from_action {
279 : using type = tmpl::list<>;
280 : };
281 :
282 : template <typename Action>
283 : struct get_simple_tags_from_options_from_action<
284 : Action, std::void_t<typename Action::simple_tags_from_options>> {
285 : using type = typename Action::simple_tags_from_options;
286 : };
287 : } // namespace detail
288 :
289 : /// \ingroup ParallelGroup
290 : /// \brief Given a list of initialization actions, returns a list of the
291 : /// unique simple_tags_from_options for all the actions.
292 : template <typename InitializationActionsList>
293 1 : using get_simple_tags_from_options =
294 : tmpl::remove_duplicates<tmpl::flatten<tmpl::transform<
295 : InitializationActionsList,
296 : detail::get_simple_tags_from_options_from_action<tmpl::_1>>>>;
297 :
298 : namespace detail {
299 : template <typename SimpleTag, typename Metavariables,
300 : bool PassMetavariables = SimpleTag::pass_metavariables>
301 : struct get_option_tags_from_simple_tag_impl {
302 : using type = typename SimpleTag::option_tags;
303 : };
304 : template <typename SimpleTag, typename Metavariables>
305 : struct get_option_tags_from_simple_tag_impl<SimpleTag, Metavariables, true> {
306 : using type = typename SimpleTag::template option_tags<Metavariables>;
307 : };
308 : template <typename Metavariables>
309 : struct get_option_tags_from_simple_tag {
310 : template <typename SimpleTag>
311 : using f = tmpl::type_from<
312 : get_option_tags_from_simple_tag_impl<SimpleTag, Metavariables>>;
313 : };
314 : } // namespace detail
315 :
316 : /// \ingroup ParallelGroup
317 : /// \brief Given a list of simple tags, returns a list of the
318 : /// unique option tags required to construct them.
319 : template <typename SimpleTagsList, typename Metavariables>
320 1 : using get_option_tags = tmpl::remove_duplicates<tmpl::flatten<tmpl::transform<
321 : SimpleTagsList, tmpl::bind<detail::get_option_tags_from_simple_tag<
322 : Metavariables>::template f,
323 : tmpl::_1>>>>;
324 :
325 : /// \cond
326 : namespace Algorithms {
327 : struct Singleton;
328 : struct Array;
329 : struct Group;
330 : struct Nodegroup;
331 : } // namespace Algorithms
332 :
333 : template <class ChareType>
334 : struct get_array_index;
335 :
336 : template <>
337 : struct get_array_index<Parallel::Algorithms::Singleton> {
338 : template <class ParallelComponent>
339 : using f = int;
340 : };
341 :
342 : template <>
343 : struct get_array_index<Parallel::Algorithms::Array> {
344 : template <class ParallelComponent>
345 : using f = typename ParallelComponent::array_index;
346 : };
347 :
348 : template <>
349 : struct get_array_index<Parallel::Algorithms::Group> {
350 : template <class ParallelComponent>
351 : using f = int;
352 : };
353 :
354 : template <>
355 : struct get_array_index<Parallel::Algorithms::Nodegroup> {
356 : template <class ParallelComponent>
357 : using f = int;
358 : };
359 :
360 : template <typename ParallelComponent>
361 : using proxy_from_parallel_component =
362 : typename ParallelComponent::chare_type::template cproxy<
363 : ParallelComponent,
364 : typename get_array_index<typename ParallelComponent::chare_type>::
365 : template f<ParallelComponent>>;
366 :
367 : template <typename ParallelComponent>
368 : using index_from_parallel_component =
369 : typename ParallelComponent::chare_type::template ckindex<
370 : ParallelComponent,
371 : typename get_array_index<typename ParallelComponent::chare_type>::
372 : template f<ParallelComponent>>;
373 :
374 : template <class ParallelComponent, class... Args>
375 : struct charm_types_with_parameters {
376 : using cproxy =
377 : typename ParallelComponent::chare_type::template cproxy<ParallelComponent,
378 : Args...>;
379 : using cbase =
380 : typename ParallelComponent::chare_type::template cbase<ParallelComponent,
381 : Args...>;
382 : using algorithm =
383 : typename ParallelComponent::chare_type::template algorithm_type<
384 : ParallelComponent, Args...>;
385 : using ckindex = typename ParallelComponent::chare_type::template ckindex<
386 : ParallelComponent, Args...>;
387 : using cproxy_section =
388 : typename ParallelComponent::chare_type::template cproxy_section<
389 : ParallelComponent, Args...>;
390 : };
391 : /// \endcond
392 : } // namespace Parallel
|