1 | /* |
2 | * Vcluster_log.hpp |
3 | * |
4 | * Created on: Jul 11, 2015 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | #ifndef VCLUSTER_LOG_HPP_ |
9 | #define VCLUSTER_LOG_HPP_ |
10 | |
11 | #include <fstream> |
12 | #include "timer.hpp" |
13 | |
14 | #ifdef VERBOSE_TEST |
15 | |
16 | /*! \brief Vcluster log |
17 | * |
18 | * It basically produce a report of the communication status |
19 | * |
20 | */ |
21 | class Vcluster_log |
22 | { |
23 | timer t; |
24 | |
25 | // delay of the log |
26 | size_t log_delay; |
27 | |
28 | size_t rank; |
29 | |
30 | // Receive status vector |
31 | openfpm::vector<MPI_Status> r_log; |
32 | |
33 | // Send processors vector |
34 | openfpm::vector<size_t> s_log; |
35 | |
36 | // log file |
37 | std::ofstream f; |
38 | |
39 | public: |
40 | |
41 | /*! \brief Start to count the seconds |
42 | * |
43 | * The log report is generated only after "log_delay" seconds |
44 | * |
45 | * \param log_delay |
46 | * |
47 | */ |
48 | void start(size_t log_delay) |
49 | { |
50 | this->log_delay = log_delay; |
51 | t.start(); |
52 | } |
53 | |
54 | /*! \brief Create the log file |
55 | * |
56 | * \param rank processor id |
57 | * |
58 | */ |
59 | void openLog(size_t rank) |
60 | { |
61 | int result; |
62 | char p_name[MPI_MAX_PROCESSOR_NAME]; |
63 | MPI_Get_processor_name(p_name, &result ); |
64 | |
65 | std::stringstream str; |
66 | str << "vcluster_log_" << p_name << "_" << rank; |
67 | f.open(str.str()); |
68 | } |
69 | |
70 | /*! \brief Allocate and MPI_Status |
71 | * |
72 | * \return a valid MPI_Status |
73 | * |
74 | */ |
75 | void logRecv(MPI_Status & stat) |
76 | { |
77 | r_log.add(stat); |
78 | } |
79 | |
80 | /*! \brief |
81 | * |
82 | * \param prc processor |
83 | * |
84 | */ |
85 | void logSend(size_t prc) |
86 | { |
87 | s_log.add(prc); |
88 | } |
89 | |
90 | /*! \brief This function write a report for the NBX communication strategy |
91 | * |
92 | * \param nbx |
93 | * \param send request |
94 | */ |
95 | void NBXreport(size_t nbx, openfpm::vector<MPI_Request> & req, bool reach_b, MPI_Status bar_stat) |
96 | { |
97 | // req and s_log must match |
98 | |
99 | if (req.size() != s_log.size()) |
100 | std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " req.size() != s_log.size() " << req.size() << "!=" << s_log.size() << "\n" ; |
101 | |
102 | // if it is waiting more than 20 seconds |
103 | // Write a deadlock status report |
104 | if (t.getwct() >= log_delay) |
105 | { |
106 | f << "=============================== NBX ==================================\n" ; |
107 | |
108 | int flag; |
109 | |
110 | f << "NBX counter: " << nbx << "\n" ; |
111 | f << "\n" ; |
112 | |
113 | // Print the send requests and their status |
114 | for (size_t i = 0 ; i < req.size() ; i++) |
115 | { |
116 | MPI_Status stat; |
117 | MPI_SAFE_CALL(MPI_Request_get_status(req.get(i),&flag,&stat)); |
118 | if (flag == true) |
119 | f << "Send to: " << s_log.get(i) << " with tag " << stat.MPI_TAG << " completed" << "\n" ; |
120 | else |
121 | f << "Send to: " << s_log.get(i) << " with tag " << stat.MPI_TAG << " pending" << "\n" ; |
122 | } |
123 | |
124 | f << "\n" ; |
125 | |
126 | // Print the receive request and their status |
127 | |
128 | for (size_t j = 0 ; j < r_log.size() ; j++) |
129 | { |
130 | f << "Received from: " << r_log.get(j).MPI_SOURCE << " with tag " << r_log.get(j).MPI_TAG << "\n" ; |
131 | } |
132 | |
133 | // Barrier status |
134 | |
135 | if (reach_b == true) |
136 | f << "Barrier status: active\n" ; |
137 | else |
138 | f << "Barrier status: inactive\n" ; |
139 | |
140 | |
141 | |
142 | f << "======================================================================\n" ; |
143 | f.flush(); |
144 | |
145 | t.reset(); |
146 | } |
147 | } |
148 | |
149 | /*! \brief Clear all the logged status |
150 | * |
151 | * |
152 | */ |
153 | void clear() |
154 | { |
155 | r_log.clear(); |
156 | s_log.clear(); |
157 | } |
158 | }; |
159 | |
160 | #else |
161 | |
162 | /*! \brief Vcluster log |
163 | * |
164 | * Stub object, it does nothing |
165 | * |
166 | */ |
167 | class Vcluster_log |
168 | { |
169 | public: |
170 | inline void start(size_t log_delay) {} |
171 | inline void openLog(size_t rank) {} |
172 | inline void logRecv(MPI_Status & stat) {} |
173 | inline void logSend(size_t prc) {} |
174 | inline void NBXreport(size_t nbx, openfpm::vector<MPI_Request> & req, bool reach_b, MPI_Status bar_stat) {} |
175 | inline void clear() {}; |
176 | }; |
177 | |
178 | #endif |
179 | |
180 | |
181 | |
182 | #endif /* VCLUSTER_LOG_HPP_ */ |
183 | |