Fenix @develop
 
Loading...
Searching...
No Matches
comm_log.h
1#ifndef COMM_LOG_H
2#define COMM_LOG_H
3
4#include <map>
5#include <vector>
6#include <cassert>
7#include <istream>
8#include <ostream>
9#include <optional>
10
11#include <mpi.h>
12
13#include "fenix/logging/task.h"
14#include "fenix/logging/rank_log.h"
15#include "fenix/logging/collective_log_holder.h"
16
17namespace fenix::logging {
18struct CRegion {
19 int id = -1, first = -1, next = -1;
20 CRegion() = default;
21 CRegion(int m_id) : id(m_id) {};
22 CRegion(int m_id, int idx) : id(m_id), first(idx), next(idx) {}
23 auto operator<=>(const CRegion& o) const { return id <=> o.id; }
24 auto operator==(const CRegion& o) const { return id == o.id; }
25 auto operator<=>(const int& i) const { return id <=> i; }
26 auto operator==(const int& i) const { return id == i; }
27 bool valid() const { return id >= 0 && first >= 0 && next >= 0; }
28 bool empty() const { return valid() && first == next; }
29 bool fresh() const { return empty() && first == 0; }
30 std::string str() const {
31 return "Region " + std::to_string(id) + " [" + std::to_string(first) + "," +
32 std::to_string(next) + ")";
33 }
34};
35
36struct CommLog {
37 CommLog(MPI_Comm& c, int m_max_regions = 2);
38 CommLog(MPI_Comm& c, std::istream& i);
39 void serialize(std::ostream& o);
40
41 MPI_Comm& comm;
42 const int m_rank;
43 int max_regions;
44 int active_region = 0;
45
46 std::map<int, RankLog> rank_logs;
47 std::vector<TaskT> tasks;
48
49 std::vector<CRegion> regions;
50 std::set<CollectiveLogHolder, std::less<>> collectives;
51 CollectiveLogHolder active_op;
52 // Collective index every rank has successfully completed, as of last reset
53 int completed_collective_all = -1;
54 // As above, but index any rank has successfully completed
55 int completed_collective_any = -1;
56 TaskT task;
57
58 RankLog& logs(int r);
59 RankLog& operator[](int r) { return logs(r); }
60
61 // Attempt progress on each task
62 void progress();
63 // Progress pending tasks and this one until this task completes
64 void progress_through(TaskT t);
65 mpixx::Status progress_through(MPI_Request* r);
66
67 int send(const void* b, int n, MPI_Datatype d, int dst, int t) {
68 return logs(dst).send(b, n, d, t);
69 }
70 int irecv(void* b, int n, MPI_Datatype d, int src, int t, MPI_Request* r) {
71 return logs(src).irecv(b, n, d, t, r);
72 }
73
74 // Return from logged collective calls. MPI return code and the log
75 using CollectiveResult =
76 std::pair<int, std::reference_wrapper<const CollectiveLogHolder>>;
77
78 // Begin a logged collective MPI Function, return the log
79 template <auto MPIFunction, typename... Args>
80 int begin(Args... args) {
81 using LogT = mpi_log_t<MPIFunction>;
82
83 if (!region().valid()) append_region({active_region, 0});
84 return begin(
85 CollectiveLogHolder::template create<LogT>(args..., region().next++)
86 );
87 }
88
89 void fenix_pre_recovery();
90 void reset_consistency(int checkpoint_id);
91
92 void begin_region(int region);
93 CRegion& region() { return regions.back(); }
94 const CRegion& region() const { return regions.back(); }
95
96 std::string str(bool with_region = false) const {
97 return "Rank " + std::to_string(m_rank) +
98 " (active=" + std::to_string(active_region) + ")" +
99 (with_region ? " " + region().str() : "");
100 }
101
102 private:
103 // Iprobe MPI for any other rank trying to form consistency
104 void detect_incoming_consistency_request();
105 TaskT form_consistency();
106 void replay_collectives(int start_idx);
107 void append_region(const CRegion& r);
108 void erase_logs(const CRegion& r);
109 void erase_regions(
110 std::vector<CRegion>::iterator begin, std::vector<CRegion>::iterator end
111 );
112
113 // Returns reference to logged op in collectives set
114 int begin(CollectiveLogHolder&& collective_op);
115};
116
117extern std::optional<CommLog> comm_log;
118
119} //namespace fenix::logging
120
121#endif
Definition collective_log_holder.h:22
Definition task.h:6
Definition status.hpp:8
Definition comm_log.h:18
Definition comm_log.h:36
Definition rank_log.h:58