Fenix @develop
 
Loading...
Searching...
No Matches
collective_log_holder.h
1#ifndef FENIX_LOGGING_COLLECTIVE_LOG_HOLDER_H
2#define FENIX_LOGGING_COLLECTIVE_LOG_HOLDER_H
3
4#include <type_traits>
5#include <variant>
6#include <memory>
7
8#include "fenix/logging/op_log.h"
9#include "fenix/logging/serialize.h"
10#include "fenix/logging/ops/barrier_log.h"
11#include "fenix/logging/ops/bcast_log.h"
12#include "fenix/logging/ops/reduce_log.h"
13#include "fenix/logging/ops/allreduce_log.h"
14
15namespace fenix::logging {
16
17using CollectiveLogVariant =
18 std::variant<BarrierLog*, BcastLog*, ReduceLog*, AllreduceLog*>;
19
20// Type-erasing helper that can be serialized/deserialized directly.
21// Treat as a unique_ptr
23 public:
24 CollectiveLogHolder() = default;
25 CollectiveLogHolder(CollectiveLogHolder&& o) { *this = std::move(o); }
27 log = std::move(o.log);
28 variant = std::move(o.variant);
29 return *this;
30 }
31
32 // Create based on underlying log type
33 template <typename LogT, typename... Args>
34 static CollectiveLogHolder create(Args... args) {
35 auto l = std::make_unique<LogT>(args...);
36 return CollectiveLogHolder(std::move(l), static_cast<LogT*>(l.get()));
37 }
38
39 CollectiveLogHolder(std::istream& i) {
40 read_log(
41 i, serialize::read<size_t>(i),
42 std::make_index_sequence<std::variant_size_v<CollectiveLogVariant>>{}
43 );
44 }
45
46 void serialize(std::ostream& o) const {
47 fenix_assert(log);
48 serialize::write<size_t>(o, variant.index());
49 serialize::write(o, *log);
50 }
51
52 operator bool() const { return !!log; }
53 CollectiveLog* operator->() { return log.get(); }
54 const CollectiveLog* operator->() const { return log.get(); }
55
56 // Support placing in a sorted set
57 auto operator<=>(const CollectiveLogHolder& o) const {
58 fenix_assert(log);
59 return log->idx() <=> o->idx();
60 }
61 auto operator<=>(const int& i) const {
62 fenix_assert(log);
63 return log->idx() <=> i;
64 }
65 auto operator==(const int& i) const {
66 fenix_assert(log);
67 return log->idx() == i;
68 }
69
70 // Helper to try reading log as each possible type
71 template <size_t... I>
72 void read_log(std::istream& input, size_t type, std::index_sequence<I...>) {
73 ((read_log<I>(input, type)), ...);
74 fenix_assert(log);
75 }
76
77 // Helper to try reading log as type with index I, no-op if type mismatch
78 template <size_t I>
79 void read_log(std::istream& input, size_t type) {
80 if (type != I) return;
81 using LogT = std::remove_pointer_t<
82 std::variant_alternative_t<I, CollectiveLogVariant>>;
83 log = std::make_unique<LogT>(input);
84 variant.emplace<I>(static_cast<LogT*>(log.get()));
85 }
86
87 std::unique_ptr<CollectiveLog> log;
88 CollectiveLogVariant variant;
89
90 private:
92 std::unique_ptr<CollectiveLog>&& m_log, CollectiveLogVariant&& m_variant
93 )
94 : log(std::move(m_log)), variant(std::move(m_variant)) {}
95};
96
97} //namespace fenix::logging
98
99#endif
Definition collective_log_holder.h:22
Definition op_log.h:76