Branch data Line data Source code
1 : : #include "Communicate/CommunicatorLogging.hpp"
2 : :
3 : : #include <fstream>
4 : : #include <iomanip>
5 : :
6 : : #include "Utility/Inform.h"
7 : :
8 : : #include "Communicate/Communicator.h"
9 : : #include "Communicate/LogEntry.h"
10 : :
11 : : namespace ippl {
12 : : namespace mpi {
13 : 0 : void Communicator::printLogs(const std::string& filename) {
14 [ # # ]: 0 : std::vector<LogEntry> localLogs = gatherLocalLogs();
15 : :
16 : 0 : std::vector<LogEntry> allLogs;
17 [ # # ]: 0 : if (rank() == 0) {
18 [ # # ]: 0 : allLogs = gatherLogsFromAllRanks(localLogs);
19 : : } else {
20 [ # # ]: 0 : sendLogsToRank0(localLogs);
21 : : }
22 : :
23 [ # # ]: 0 : if (rank() == 0) {
24 [ # # ]: 0 : writeLogsToFile(allLogs, filename);
25 : : }
26 : 0 : }
27 : :
28 : 0 : std::vector<LogEntry> Communicator::gatherLocalLogs() {
29 : 0 : std::vector<LogEntry> localLogs;
30 : :
31 [ # # ]: 0 : buffer_handlers_m.forAll([&](auto& loggingHandler) {
32 : 0 : const auto& logs = loggingHandler.getLogs();
33 [ # # ]: 0 : localLogs.insert(localLogs.end(), logs.begin(), logs.end());
34 : 0 : });
35 : :
36 : 0 : return localLogs;
37 : 0 : }
38 : :
39 : 0 : void Communicator::sendLogsToRank0(const std::vector<LogEntry>& localLogs) {
40 [ # # ]: 0 : std::vector<char> buffer = serializeLogs(localLogs);
41 : :
42 : 0 : int logSize = buffer.size();
43 : :
44 [ # # ]: 0 : this->send(logSize, 1, 0, 0);
45 [ # # ]: 0 : this->send<char>(buffer.data(), logSize, 0, 0);
46 : 0 : }
47 : :
48 : 0 : std::vector<LogEntry> Communicator::gatherLogsFromAllRanks(
49 : : const std::vector<LogEntry>& localLogs) {
50 : 0 : std::vector<LogEntry> allLogs = localLogs;
51 : :
52 [ # # ]: 0 : for (int rank = 1; rank < size_m; ++rank) {
53 : : int logSize;
54 : 0 : Status status;
55 : :
56 [ # # ]: 0 : this->recv(logSize, 1, rank, 0, status);
57 : :
58 [ # # ]: 0 : std::vector<char> buffer(logSize);
59 [ # # ]: 0 : this->recv<char>(buffer.data(), logSize, rank, 0, status);
60 : :
61 [ # # ]: 0 : std::vector<LogEntry> deserializedLogs = deserializeLogs(buffer);
62 [ # # ]: 0 : allLogs.insert(allLogs.end(), deserializedLogs.begin(), deserializedLogs.end());
63 : 0 : }
64 : :
65 : 0 : return allLogs;
66 : 0 : }
67 : :
68 : 0 : std::vector<char> serializeLogs(const std::vector<LogEntry>& logs) {
69 : 0 : std::vector<char> buffer;
70 : :
71 [ # # ]: 0 : for (const auto& logEntry : logs) {
72 [ # # ]: 0 : std::vector<char> serializedEntry = logEntry.serialize();
73 [ # # ]: 0 : buffer.insert(buffer.end(), serializedEntry.begin(), serializedEntry.end());
74 : 0 : }
75 : :
76 : 0 : return buffer;
77 : 0 : }
78 : :
79 : 0 : std::vector<LogEntry> deserializeLogs(const std::vector<char>& buffer) {
80 : 0 : std::vector<LogEntry> logs;
81 : 0 : size_t offset = 0;
82 : :
83 [ # # ]: 0 : while (offset < buffer.size()) {
84 [ # # ]: 0 : LogEntry logEntry = LogEntry::deserialize(buffer, offset);
85 : :
86 [ # # ]: 0 : logs.push_back(logEntry);
87 : :
88 [ # # ]: 0 : offset += logEntry.serialize().size();
89 : 0 : }
90 : 0 : return logs;
91 : 0 : }
92 : :
93 : 0 : void Communicator::writeLogsToFile(const std::vector<LogEntry>& allLogs,
94 : : const std::string& filename) {
95 [ # # ]: 0 : Inform logFile(0, filename.c_str(), Inform::OVERWRITE, 0);
96 [ # # ]: 0 : logFile.setOutputLevel(1);
97 : :
98 [ # # # # ]: 0 : logFile << "Timestamp,Method,Rank,MemorySpace,usedSize,FreeSize,Parameters" << endl;
99 : :
100 [ # # ]: 0 : for (const auto& log : allLogs) {
101 [ # # ]: 0 : auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(
102 : 0 : log.timestamp.time_since_epoch())
103 : 0 : .count();
104 : :
105 : 0 : logFile << timestamp << "," << log.methodName << "," << log.rank << ","
106 [ # # # # : 0 : << log.memorySpace << "," << log.usedSize << "," << log.freeSize;
# # # # #
# # # # #
# # # # #
# # # ]
107 : :
108 [ # # ]: 0 : logFile << ",\"";
109 : 0 : bool first = true;
110 [ # # ]: 0 : for (const auto& [key, value] : log.parameters) {
111 [ # # ]: 0 : if (!first) {
112 [ # # ]: 0 : logFile << "; ";
113 : : }
114 [ # # # # : 0 : logFile << key << ": " << value;
# # ]
115 : 0 : first = false;
116 : : }
117 [ # # # # ]: 0 : logFile << "\"" << endl;
118 : : }
119 : :
120 [ # # ]: 0 : logFile.flush();
121 : 0 : }
122 : :
123 : : } // namespace mpi
124 : : } // namespace ippl
|