27#include "timemory/backends/dmp.hpp"
28#include "timemory/backends/process.hpp"
34#include "timemory/tpls/cereal/archives.hpp"
69 template <
typename Archive>
77 sfinae(ar, ver, 0, 0);
82 sfinae(ar, ver, 0, 0);
85 template <
typename Archive>
88 sfinae(ar, ver, 0, 0);
92 template <
typename Archive,
typename Up = Tp>
93 auto sfinae(Archive& ar,
unsigned int ver,
int,
int)
const
94 ->
decltype(Up::extra_serialization(ar, ver), void())
96 Up::extra_serialization(ar, ver);
99 template <
typename Archive,
typename Up = Tp>
100 auto sfinae(Archive& ar,
unsigned int,
int,
long)
const
101 ->
decltype(Up::extra_serialization(ar), void())
103 Up::extra_serialization(ar);
106 template <
typename Archive,
typename Up = Tp>
107 auto sfinae(Archive&,
unsigned int,
long,
long)
const
114template <
typename Tp>
115struct serialization_base
128 TIMEMORY_DEFAULT_OBJECT(serialization_base)
133 for(
auto& itr : _inp)
134 itr = std::tolower(itr);
138 static std::string get_identifier(
const type& _obj = type{})
144 idstr = get_identifier_sfinae(_obj, 0);
146 idstr = demangle<type>();
150 static auto get_label(
const type& _obj = type{})
152 return get_label_sfinae(_obj, 0, 0);
155 static auto get_description(
const type& _obj = type{})
157 return get_description_sfinae(_obj, 0, 0);
160 static auto get_unit(
const type& _obj = type{})
162 return get_unit_sfinae(_obj, 0, 0);
165 static auto get_display_unit(
const type& _obj = type{})
167 return get_display_unit_sfinae(_obj, 0, 0);
171 template <
typename Up>
172 static auto get_identifier_sfinae(
const Up& _data,
int) ->
decltype(_data.label())
174 return _data.label();
177 template <
typename Up>
178 static auto get_identifier_sfinae(
const Up&,
long)
184 template <
typename Up>
185 static auto get_label_sfinae(
const Up& _data,
int,
int)
186 ->
decltype(_data.label_array())
188 return _data.label_array();
191 template <
typename Up>
192 static auto get_label_sfinae(
const Up& _data,
int,
long) ->
decltype(_data.label())
194 return _data.label();
197 template <
typename Up>
198 static auto get_label_sfinae(
const Up&,
long,
long)
204 template <
typename Up>
205 static auto get_description_sfinae(
const Up& _data,
int,
int)
206 ->
decltype(_data.description_array())
208 return _data.description_array();
211 template <
typename Up>
212 static auto get_description_sfinae(
const Up& _data,
int,
long)
213 ->
decltype(_data.description())
215 return _data.description();
218 template <
typename Up>
219 static auto get_description_sfinae(
const Up&,
long,
long)
225 template <
typename Up>
226 static auto get_unit_sfinae(
const Up& _data,
int,
int) ->
decltype(_data.unit_array())
228 return _data.unit_array();
231 template <
typename Up>
232 static auto get_unit_sfinae(
const Up& _data,
int,
long) ->
decltype(_data.unit())
238 template <
typename Up>
239 static auto get_unit_sfinae(
const Up&,
long,
long) -> int64_t
245 template <
typename Up>
246 static auto get_display_unit_sfinae(
const Up& _data,
int,
int)
247 ->
decltype(_data.display_unit_array())
249 return _data.display_unit_array();
252 template <
typename Up>
253 static auto get_display_unit_sfinae(
const Up& _data,
int,
long)
254 ->
decltype(_data.display_unit())
257 return _data.display_unit();
260 template <
typename Up>
261 static auto get_display_unit_sfinae(
const Up&,
long,
long)
269template <typename Tp, bool AvailV = is_enabled<Tp>::value>
274template <
typename Tp>
275struct serialization<Tp,
false> :
public serialization_base<Tp>
278 using base_type = serialization_base<Tp>;
279 using metadata =
typename base_type::metadata;
281 TIMEMORY_DEFAULT_OBJECT(serialization)
283 template <
typename... Args>
284 serialization(Args&&...)
287 template <
typename... Args>
288 auto operator()(Args&&...)
const
294template <
typename Tp>
295struct serialization<Tp,
true> :
public serialization_base<Tp>
297 static constexpr bool value =
true;
299 using base_type = serialization_base<Tp>;
300 using tree_type = node::tree<type>;
301 using graph_node = node::graph<type>;
302 using result_node = node::result<type>;
303 using result_type = std::vector<result_node>;
304 using distrib_type = std::vector<result_type>;
305 using storage_type = impl::storage<type, value>;
306 using graph_type = graph<graph_node>;
307 using hierarchy_type = std::vector<uint64_t>;
308 using basic_tree_type = basic_tree<node::tree<type>>;
309 using basic_tree_vector_type = std::vector<basic_tree_type>;
310 using metadata =
typename base_type::metadata;
311 using mpi_data =
typename base_type::mpi_data;
312 using basic_tree_map_type =
313 std::map<std::string, std::vector<basic_tree_vector_type>>;
315 using base_type::get_description;
316 using base_type::get_display_unit;
317 using base_type::get_identifier;
318 using base_type::get_label;
319 using base_type::get_unit;
321 TIMEMORY_DEFAULT_OBJECT(serialization)
324 static constexpr bool component_is_specialized()
329 template <
typename Archive>
330 static constexpr bool is_specialized()
334 type_list<cereal::JSONInputArchive, cereal::MinimalJSONOutputArchive,
335 cereal::PrettyJSONOutputArchive>>::value;
338 template <
typename DataT>
339 static constexpr bool is_supported_dtype()
343 type_list<basic_tree_vector_type, std::vector<basic_tree_vector_type>,
344 result_type, distrib_type, basic_tree_map_type>>::value;
349 template <
typename Archive>
350 TIMEMORY_COLD serialization(
const Tp& obj, Archive& ar,
const unsigned int version,
353 static_assert(!is_specialized<Archive>(),
354 "Error! Calling template function instead of specialized function");
355 impl(obj, ar, version);
358 template <
typename Archive>
359 TIMEMORY_COLD
void operator()(
const Tp& obj, Archive& ar,
const unsigned int version,
360 enable_if_t<!is_specialized<Archive>(),
int> = 0)
const
362 static_assert(!is_specialized<Archive>(),
363 "Error! Calling template function instead of specialized function");
364 impl(obj, ar, version);
367 template <
typename Archive>
368 TIMEMORY_COLD
void operator()(Archive& ar, metadata data,
369 enable_if_t<!is_specialized<Archive>(),
int> = 0)
const
371 static_assert(!is_specialized<Archive>(),
372 "Error! Calling template function instead of specialized function");
376 template <
typename Archive,
typename DataT>
377 TIMEMORY_COLD
void operator()(
378 Archive& ar,
const DataT& data,
379 enable_if_t<!is_specialized<Archive>() && is_supported_dtype<DataT>(),
int> =
382 static_assert(!is_specialized<Archive>(),
383 "Error! Calling template function instead of specialized function");
387 template <
typename Archive,
typename DataT>
388 TIMEMORY_COLD
void operator()(
389 Archive& ar, DataT& data,
390 enable_if_t<!is_specialized<Archive>() && is_supported_dtype<DataT>(),
int> =
393 static_assert(!is_specialized<Archive>(),
394 "Error! Calling template function instead of specialized function");
395 static_assert(!(std::is_same<decay_t<DataT>, basic_tree_map_type>::value &&
396 concepts::is_input_archive<decay_t<Archive>>::value),
397 "Error! basic_tree_map_type does not support input serialization");
403 TIMEMORY_COLD serialization(
const Tp& obj, cereal::MinimalJSONOutputArchive& ar,
404 const unsigned int version, ...);
406 TIMEMORY_COLD
void operator()(
const Tp& obj, cereal::MinimalJSONOutputArchive& ar,
407 const unsigned int version, ...)
const;
409 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar, metadata,
412 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar,
413 const basic_tree_vector_type& data, ...)
const;
415 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar,
416 const std::vector<basic_tree_vector_type>& data,
419 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar,
420 const basic_tree_map_type& data, ...)
const;
422 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar,
423 const result_type& data, ...)
const;
425 TIMEMORY_COLD
void operator()(cereal::MinimalJSONOutputArchive& ar,
426 const distrib_type& data, ...)
const;
430 TIMEMORY_COLD serialization(
const Tp& obj, cereal::PrettyJSONOutputArchive& ar,
431 const unsigned int version, ...);
433 TIMEMORY_COLD
void operator()(
const Tp& obj, cereal::PrettyJSONOutputArchive& ar,
434 const unsigned int version, ...)
const;
436 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar, metadata,
439 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar,
440 const basic_tree_vector_type& data, ...)
const;
442 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar,
443 const std::vector<basic_tree_vector_type>& data,
446 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar,
447 const basic_tree_map_type& data, ...)
const;
449 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar,
450 const result_type& data, ...)
const;
452 TIMEMORY_COLD
void operator()(cereal::PrettyJSONOutputArchive& ar,
453 const distrib_type& data, ...)
const;
457 TIMEMORY_COLD
void operator()(cereal::JSONInputArchive& ar,
458 basic_tree_vector_type& data, ...)
const;
460 TIMEMORY_COLD
void operator()(cereal::JSONInputArchive& ar,
461 std::vector<basic_tree_vector_type>& data, ...)
const;
463 TIMEMORY_COLD
void operator()(cereal::JSONInputArchive& ar, result_type& data,
466 TIMEMORY_COLD
void operator()(cereal::JSONInputArchive& ar, distrib_type& data,
470 template <
typename ValueT>
471 std::vector<decay_t<ValueT>> operator()(mpi_data, mpi::comm_t comm,
473 int32_t comm_target = 0)
const;
476 template <
typename Archive>
477 TIMEMORY_COLD
void impl(
const Tp& obj, Archive& ar,
const unsigned int)
const;
479 template <
typename Archive>
480 TIMEMORY_COLD
void impl(Archive& ar, metadata)
const;
482 template <
typename Archive>
483 TIMEMORY_COLD
void impl(
484 Archive& ar,
const basic_tree_vector_type& data,
487 template <
typename Archive>
488 TIMEMORY_COLD
void impl(
489 Archive& ar,
const std::vector<basic_tree_vector_type>& data,
492 template <
typename Archive>
493 TIMEMORY_COLD
void impl(
494 Archive& ar,
const basic_tree_map_type& data,
497 template <
typename Archive>
498 TIMEMORY_COLD
void impl(
499 Archive& ar,
const result_type& data,
502 template <
typename Archive>
503 TIMEMORY_COLD
void impl(
504 Archive& ar,
const distrib_type& data,
508 template <
typename Archive>
509 TIMEMORY_COLD
void impl(
510 Archive& ar, basic_tree_vector_type& data,
513 template <
typename Archive>
514 TIMEMORY_COLD
void impl(
515 Archive& ar, std::vector<basic_tree_vector_type>& data,
518 template <
typename Archive>
519 TIMEMORY_COLD
void impl(
520 Archive& ar, result_type& data,
523 template <
typename Archive>
524 TIMEMORY_COLD
void impl(
525 Archive& ar, distrib_type& data,
529template <
typename Tp>
530template <
typename Archive>
532serialization<Tp, true>::impl(
const Tp& obj, Archive& ar,
const unsigned int)
const
534 auto try_catch = [&ar](
const char* key,
const auto& val) {
537 ar(cereal::make_nvp(key, val));
538 }
catch(cereal::Exception& e)
540 fprintf(stderr,
"Warning! '%s' threw exception: %s\n", key, e.what());
544 try_catch(
"laps", obj.get_laps());
545 try_catch(
"value", obj.get_value());
548 try_catch(
"accum", obj.get_accum());
550 IF_CONSTEXPR(trait::base_has_last<Tp>::value) { try_catch(
"last", obj.get_last()); }
551 try_catch(
"repr_data", obj.get());
552 try_catch(
"repr_display", obj.get_display());
555template <
typename Tp>
556template <
typename Archive>
558serialization<Tp, true>::impl(Archive& ar, metadata)
const
560 bool _thread_scope_only = trait::thread_scope_only<type>::value;
562 auto _num_pid_count = dmp::size();
564 ar(cereal::make_nvp(
"properties", component::properties<type>{}));
565 ar(cereal::make_nvp(
"type", get_label()));
566 ar(cereal::make_nvp(
"description", get_description()));
567 ar(cereal::make_nvp(
"unit_value", get_unit()));
568 ar(cereal::make_nvp(
"unit_repr", get_display_unit()));
569 ar(cereal::make_nvp(
"thread_scope_only", _thread_scope_only));
570 ar(cereal::make_nvp(
"thread_count", _num_thr_count));
571 ar(cereal::make_nvp(
"mpi_size", mpi::size()));
572 ar(cereal::make_nvp(
"upcxx_size", upc::size()));
573 ar(cereal::make_nvp(
"process_count", _num_pid_count));
574 ar(cereal::make_nvp(
"num_ranks", dmp::size()));
575 ar(cereal::make_nvp(
"concurrency", _num_thr_count));
578template <
typename Tp>
579template <
typename Archive>
581serialization<Tp, true>::impl(
582 Archive& ar,
const basic_tree_vector_type& data,
585 auto idstr = get_identifier();
586 ar.setNextName(idstr.c_str());
588 impl(ar, metadata{});
589 extra_serialization<Tp>{ ar };
590 ar(cereal::make_nvp(
"graph", data));
594template <
typename Tp>
595template <
typename Archive>
597serialization<Tp, true>::impl(
598 Archive& ar,
const std::vector<basic_tree_vector_type>& data,
601 auto idstr = get_identifier();
602 ar.setNextName(idstr.c_str());
604 impl(ar, metadata{});
605 extra_serialization<Tp>{ ar };
606 ar(cereal::make_nvp(
"graph", data));
610template <
typename Tp>
611template <
typename Archive>
613serialization<Tp, true>::impl(
614 Archive& ar,
const basic_tree_map_type& data,
617 auto idstr = get_identifier();
618 ar.setNextName(idstr.c_str());
620 impl(ar, metadata{});
621 extra_serialization<Tp>{ ar };
622 auto pitr = data.find(
"process");
623 if(pitr != data.end())
625 ar(cereal::make_nvp(
"graph", pitr->second));
629 for(
const auto& itr : data)
630 ar(cereal::make_nvp(itr.first, itr.second));
635template <
typename Tp>
636template <
typename Archive>
638serialization<Tp, true>::impl(
639 Archive& ar,
const result_type& data,
644 ar.setNextName(_name.c_str());
646 impl(ar, metadata{});
647 extra_serialization<Tp>{ ar };
653template <
typename Tp>
654template <
typename Archive>
656serialization<Tp, true>::impl(
657 Archive& ar,
const distrib_type& data,
662 ar.setNextName(_name.c_str());
664 impl(ar, metadata{});
665 extra_serialization<Tp>{ ar };
666 ar.setNextName(
"ranks");
669 for(uint64_t i = 0; i < data.size(); ++i)
671 if(data.at(i).empty())
676 ar(cereal::make_nvp(
"rank", i));
685template <
typename Tp>
686template <
typename Archive>
688serialization<Tp, true>::impl(
689 Archive& ar, basic_tree_vector_type& data,
692 auto idstr = get_identifier();
693 ar.setNextName(idstr.c_str());
695 ar(cereal::make_nvp(
"graph", data));
699template <
typename Tp>
700template <
typename Archive>
702serialization<Tp, true>::impl(
703 Archive& ar, std::vector<basic_tree_vector_type>& data,
706 auto idstr = get_identifier();
707 ar.setNextName(idstr.c_str());
709 std::stringstream _msg;
710 for(
const auto* name : {
"graph",
"mpi",
"upcxx" })
714 std::vector<basic_tree_vector_type> _data{};
715 ar(tim::cereal::make_nvp(name, _data));
716 data.reserve(data.size() + _data.size());
717 for(
auto&& itr : _data)
718 data.emplace_back(itr);
719 }
catch(tim::cereal::Exception& e)
721 _msg << e.what() <<
'\n';
726 throw std::runtime_error(_msg.str());
729template <
typename Tp>
730template <
typename Archive>
732serialization<Tp, true>::impl(
733 Archive& ar, result_type& data,
738 ar.setNextName(_name.c_str());
745template <
typename Tp>
746template <
typename Archive>
748serialization<Tp, true>::impl(
749 Archive& ar, distrib_type& data,
754 ar.setNextName(_name.c_str());
758 cereal::size_type _nranks = 0;
759 ar.setNextName(
"ranks");
761 ar.loadSize(_nranks);
764 data.resize(_nranks);
765 for(uint64_t i = 0; i < data.size(); ++i)
768 ar(cereal::make_nvp(
"rank", i));
772 }
catch(std::exception& e)
774 fprintf(stderr,
"%s\n", e.what());
783template <
typename Tp>
784template <
typename ValueT>
785std::vector<decay_t<ValueT>>
786serialization<Tp, true>::operator()(mpi_data, mpi::comm_t comm,
const ValueT&
entry,
787 int32_t comm_target)
const
789 using data_type = std::vector<decay_t<ValueT>>;
791#if !defined(TIMEMORY_USE_MPI)
795 using value_type = ValueT;
802 int comm_rank = mpi::rank(comm);
803 int comm_size = mpi::size(comm);
808 auto send_serialize = [&](
const value_type& src) {
809 std::stringstream ss;
811 auto oa = policy::output_archive<cereal::MinimalJSONOutputArchive,
813 (*oa)(cereal::make_nvp(
"data", src));
821 auto recv_serialize = [&](
const std::string& src) {
823 std::stringstream ss;
828 (*ia)(cereal::make_nvp(
"data", ret));
833 if(comm_rank == comm_target)
839 for(
int i = 1; i < comm_size; ++i)
842 mpi::recv(str, i, 0, comm);
843 _data[i] = recv_serialize(str);
845 _data[comm_rank] =
entry;
850 auto str_ret = send_serialize(
entry);
855 mpi::send(str_ret, 0, 0, comm);
865template <
typename Tp>
866struct serialization :
public internal::serialization<Tp, is_enabled<Tp>::value>
869 using base_type = internal::serialization<Tp, is_enabled<Tp>::value>;
874 template <
typename... Args>
879 using base_type::operator();
880 using base_type::get_description;
881 using base_type::get_display_unit;
882 using base_type::get_identifier;
883 using base_type::get_label;
884 using base_type::get_unit;
892#define TIMEMORY_OPERATIONS_TYPES_SERIALIZATION_HPP_
894#undef TIMEMORY_OPERATIONS_TYPES_SERIALIZATION_HPP_
static int32_t get_thread_count()
This effectively provides the total number of threads which collected data. It is only "decremented" ...
#define IF_CONSTEXPR(...)
void load(Archive &ar, tim::node::graph< Tp > &d)
void save(Archive &ar, std::shared_ptr< tim::tsettings< Tp, Tp & > > obj)
std::bitset< scope_count > data_type
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
tim::mpl::apply< std::string > string
typename impl::is_one_of< Tp, Types > is_one_of
check if type is in expansion
auto get(const auto_bundle< Tag, Types... > &_obj)
void consume_parameters(ArgsT &&...)
The declaration for the types for operations without definitions.
Include the macros for operations.
Declare the operations types.
static constexpr const char * enum_string()
static constexpr bool specialized()
static constexpr bool value
serialization(Args &&... args)
typename base_type::metadata metadata
internal::serialization< Tp, is_enabled< Tp >::value > base_type