15 #include "Parallel/ParallelComponentHelpers.hpp"
18 #include "Utilities/TaggedTuple.hpp"
19 #include "Utilities/TypeTraits.hpp"
20 #include "Utilities/TypeTraits/IsA.hpp"
24 template <
typename Component>
25 class MockDistributedObject;
26 template <
typename SimpleTagsList,
typename ComputeTagsList = tmpl::list<>>
27 struct InitializeDataBox;
39 template <
typename Component>
40 struct get_initialization {
41 using phase =
typename Component::metavariables::Phase;
44 struct is_initialization_phase {
49 using initialization_pdal_list =
50 tmpl::filter<
typename Component::phase_dependent_action_list,
51 is_initialization_phase<tmpl::_1>>;
53 tmpl::size<initialization_pdal_list>::value == 1,
54 "Must have exactly one Initialization PhaseDependentActionList");
56 using initialization_pdal =
typename tmpl::front<initialization_pdal_list>;
60 tmpl::front<typename initialization_pdal::action_list>>,
61 "The first action in the initialization phase must be "
62 "ActionTesting::InitializeDataBox, even if the simple and "
63 "compute tags are empty.");
65 using initialize_databox_action =
66 tmpl::front<typename initialization_pdal::action_list>;
68 using InitialValues =
typename initialize_databox_action::InitialValues;
72 template <
typename Metavariables,
typename = std::
void_t<>>
75 template <
typename Metavariables>
76 struct has_initialization_phase<
77 Metavariables, std::void_t<decltype(Metavariables::Phase::Initialization)>>
80 template <
typename Metavariables>
81 constexpr
bool has_initialization_phase_v =
82 has_initialization_phase<Metavariables>::value;
90 template <
typename Metavariables>
101 template <
typename Component>
104 typename Component::array_index,
105 tuples::tagged_tuple_from_typelist<
106 typename MockDistributedObject<Component>::inbox_tags_list>>;
109 template <
typename Component>
116 using CacheTuple = tuples::tagged_tuple_from_typelist<
118 using MutableCacheTuple = tuples::tagged_tuple_from_typelist<
121 using mock_objects_tags =
122 tmpl::transform<
typename Metavariables::component_list,
123 tmpl::bind<MockDistributedObjectsTag, tmpl::_1>>;
124 using CollectionOfMockDistributedObjects =
125 tuples::tagged_tuple_from_typelist<mock_objects_tags>;
126 using Inboxes = tuples::tagged_tuple_from_typelist<
127 tmpl::transform<
typename Metavariables::component_list,
128 tmpl::bind<InboxesTag, tmpl::_1>>>;
133 MutableCacheTuple mutable_cache_contents = {})
140 tmpl::for_each<typename Metavariables::component_list>(
141 [
this](
auto component) {
142 using Component = tmpl::type_from<decltype(component)>;
143 Parallel::get_parallel_component<Component>(cache_).set_data(
144 &
tuples::get<MockDistributedObjectsTag<Component>>(
145 mock_distributed_objects_),
152 template <
typename... Tags>
155 tuples::reorder<CacheTuple>(std::move(cache_contents))) {}
159 template <
typename... CacheTags,
typename... MutableCacheTags>
164 tuples::reorder<CacheTuple>(std::move(cache_contents)),
165 tuples::reorder<MutableCacheTuple>(
166 std::move(mutable_cache_contents))) {}
169 template <
typename Component,
typename...
Options>
172 mock_distributed_objects<Component>().emplace(
175 array_index, &cache_,
177 std::forward<Options>(opts)...));
181 template <
typename Component,
typename...
Options,
182 typename Metavars = Metavariables,
185 const typename Component::array_index& array_index,
186 const typename detail::get_initialization<Component>::InitialValues&
189 detail::get_initialization<Component>::initialize_databox_action::
190 set_initial_values(initial_values);
191 auto iterator_bool = mock_distributed_objects<Component>().emplace(
194 array_index, &cache_,
196 std::forward<Options>(opts)...));
197 if (not iterator_bool.second) {
198 ERROR(
"Failed to insert parallel component '"
199 << pretty_type::get_name<Component>() <<
"' with index "
202 iterator_bool.first->second.set_phase(Metavariables::Phase::Initialization);
203 iterator_bool.first->second.next_action();
209 template <
typename Component,
typename Action,
typename Arg0,
212 Arg0&& arg0, Args&&... args) noexcept {
213 mock_distributed_objects<Component>()
215 .template simple_action<Action>(
216 std::make_tuple(std::forward<Arg0>(arg0),
217 std::forward<Args>(args)...),
221 template <
typename Component,
typename Action>
223 const typename Component::array_index& array_index) noexcept {
224 mock_distributed_objects<Component>()
226 .template simple_action<Action>(
true);
233 template <
typename Component,
typename Action,
typename Arg0,
236 Arg0&& arg0, Args&&... args) noexcept {
237 mock_distributed_objects<Component>()
239 .template threaded_action<Action>(
240 std::make_tuple(std::forward<Arg0>(arg0),
241 std::forward<Args>(args)...),
245 template <
typename Component,
typename Action>
247 const typename Component::array_index& array_index) noexcept {
248 mock_distributed_objects<Component>()
250 .template threaded_action<Action>(
true);
256 template <
typename Component>
258 const typename Component::array_index& array_index)
const noexcept {
259 return mock_distributed_objects<Component>()
261 .is_simple_action_queue_empty();
266 template <
typename Component>
268 const typename Component::array_index& array_index) noexcept {
269 mock_distributed_objects<Component>()
271 .invoke_queued_simple_action();
276 template <
typename Component>
278 const typename Component::array_index& array_index)
const noexcept {
279 return mock_distributed_objects<Component>()
281 .is_threaded_action_queue_empty();
286 template <
typename Component>
288 const typename Component::array_index& array_index) noexcept {
289 mock_distributed_objects<Component>()
291 .invoke_queued_threaded_action();
296 template <
typename Component,
typename Action>
298 const typename Component::array_index& array_index) noexcept {
300 tmpl::list_contains_v<
301 typename MockDistributedObject<Component>::all_actions_list,
303 "Cannot force a next action that is not in the action list of the "
304 "parallel component. See the first template parameter of "
305 "'force_next_action_to_be' for the component and the second template "
306 "parameter for the action.");
307 bool found_matching_phase =
false;
308 const auto invoke_for_phase =
309 [
this, &array_index, &found_matching_phase](
auto phase_dep_v) noexcept {
310 using PhaseDep = decltype(phase_dep_v);
311 constexpr
typename Metavariables::Phase phase = PhaseDep::type::phase;
312 using actions_list =
typename PhaseDep::type::action_list;
313 auto& distributed_object =
314 this->mock_distributed_objects<Component>().at(array_index);
315 if (distributed_object.get_phase() == phase) {
316 found_matching_phase =
true;
317 distributed_object.force_next_action_to_be(
320 tmpl::index_of<actions_list, Action>>::value,
322 tmpl::index_of<actions_list, Action>>::value);
326 Component>::phase_dependent_action_lists>(invoke_for_phase);
327 if (not found_matching_phase) {
329 "Could not find any actions in the current phase for the component '"
330 << pretty_type::short_name<Component>()
331 <<
"'. Maybe you are not in the phase you expected to be in? The "
332 "integer value corresponding to the current phase is "
333 <<
static_cast<int>(this->mock_distributed_objects<Component>()
340 template <
typename Component>
342 const typename Component::array_index& array_index)
const noexcept {
343 return mock_distributed_objects<Component>()
345 .get_next_action_index();
350 template <
typename Component>
352 const typename Component::array_index& array_index) noexcept {
353 mock_distributed_objects<Component>().at(array_index).next_action();
358 template <
typename Component>
359 bool is_ready(
const typename Component::array_index& array_index) noexcept {
360 return mock_distributed_objects<Component>().at(array_index).is_ready();
365 template <
typename Component>
366 auto inboxes() noexcept -> std::unordered_map<
367 typename Component::array_index,
368 tuples::tagged_tuple_from_typelist<
370 return tuples::get<InboxesTag<Component>>(inboxes_);
373 template <
typename Component>
374 auto inboxes() const noexcept -> const std::unordered_map<
375 typename Component::array_index,
376 tuples::tagged_tuple_from_typelist<
378 return tuples::get<InboxesTag<Component>>(inboxes_);
384 template <
typename Component,
typename InboxTag>
386 -> std::unordered_set<typename Component::array_index> {
388 for (
const auto& element_box : inboxes<Component>()) {
389 if (not tuples::get<InboxTag>(element_box.second).empty()) {
390 result.insert(element_box.first);
398 template <
typename Component>
400 return tuples::get<MockDistributedObjectsTag<Component>>(
401 mock_distributed_objects_);
404 template <
typename Component>
406 return tuples::get<MockDistributedObjectsTag<Component>>(
407 mock_distributed_objects_);
410 GlobalCache& cache() noexcept {
return cache_; }
413 void set_phase(
const typename Metavariables::Phase next_phase) noexcept {
414 tmpl::for_each<mock_objects_tags>(
415 [
this, &next_phase](
auto component_v) noexcept {
416 for (
auto&
object :
tuples::get<
typename decltype(component_v)::type>(
417 mock_distributed_objects_)) {
418 object.second.set_phase(next_phase);
425 GlobalCache cache_{};
427 CollectionOfMockDistributedObjects mock_distributed_objects_{};