MaCh3 2.2.1
Reference Guide
Loading...
Searching...
No Matches
Monitor.cpp
Go to the documentation of this file.
1#include "Manager/Monitor.h"
2
3//Only if GPU is enabled
4#ifdef MaCh3_CUDA
6#endif
7
8namespace MaCh3Utils {
9
10// *************************
12// *************************
13 // KS: Just make sure we only call it once
14 static bool MaCh3WelcomeInitialised = false;
15
16 if(MaCh3WelcomeInitialised) return;
17
18 std::string MaCh3_VERSION = GetMaCh3Version();
19
20 MACH3LOG_INFO("##################################");
21 MACH3LOG_INFO("Welcome to: ");
22 MACH3LOG_INFO(" __ __ _____ _ ____ ");
23 MACH3LOG_INFO(" | \\/ | / ____| | |___ \\ ");
24 MACH3LOG_INFO(" | \\ / | __ _| | | |__ __) |");
25 MACH3LOG_INFO(" | |\\/| |/ _` | | | '_ \\ |__ < ");
26 MACH3LOG_INFO(" | | | | (_| | |____| | | |___) |");
27 MACH3LOG_INFO(" |_| |_|\\__,_|\\_____|_| |_|____/ ");
28 MACH3LOG_INFO("Version: {}", MaCh3_VERSION);
29 MACH3LOG_INFO("##################################");
30
31 GetCPUInfo();
32
33 GetGPUInfo();
34
35 #ifdef DEBUG
36 GetOSInfo();
38 #endif
39
40 MaCh3WelcomeInitialised = true;
41}
42
43// ************************
44// KS: Get version of MaCh3
45std::string GetMaCh3Version() {
46// ************************
47 //KS: Find MaCh3 version based on header file. There could be better way to just include version.h but as long as we don't have to hardcode version I am content
48 std::string MaCh3_VERSION = "";
49
50 if(std::getenv("MaCh3_ROOT") == nullptr){
51 throw MaCh3Exception(__FILE__, __LINE__, "Error: you haven't sourced setup.MaCh3.sh in core!");
52 }
53
54 std::string file = std::string(std::getenv("MaCh3_ROOT")) + "/version.h";
55 // Open the version.h file
56 std::ifstream versionFile(file);
57
58 // Check if the file is opened successfully
59 if (!versionFile.is_open()) {
60 MACH3LOG_ERROR("Error: Couldn't open version.h {}", file);
61 throw MaCh3Exception(__FILE__, __LINE__);
62 }
63
64 std::string line;
65 const std::string searchKey = "MaCh3_VERSION=";
66
67 // Read each line from the file
68 while (std::getline(versionFile, line)) {
69 // Search for the line containing MaCh3_VERSION
70 auto pos = line.find(searchKey);
71 if (pos != std::string::npos) {
72 // Extract the version string
73 MaCh3_VERSION = line.substr(pos + searchKey.length());
74 MaCh3_VERSION.erase(0, MaCh3_VERSION.find_first_not_of("\"")); // Remove leading quote
75 MaCh3_VERSION.erase(MaCh3_VERSION.find_last_not_of("\";") + 1); // Remove trailing quote and semicolon
76 break; // Stop searching once found
77 }
78 }
79 // Close the file
80 versionFile.close();
81
82 return MaCh3_VERSION;
83}
84
85// ************************
86// KS: Find out more about operational system
87void GetOSInfo() {
88// ************************
89 MACH3LOG_INFO("Operating System Information:");
90
91 // Distribution and version
92 MACH3LOG_INFO("Distribution: {}", TerminalToString("lsb_release -d | awk -F':' '{print $2}'"));
93 MACH3LOG_INFO("Kernel Version: {}", TerminalToString("uname -r"));
94}
95
96// ************************
97//KS: Simple function retrieving CPU info
98void GetCPUInfo() {
99// ************************
100 //KS: Use -m 1 to limit to only one grep because in one computing node there is a lot of CPU which are the same
101 MACH3LOG_INFO("Using following CPU:");
102
103 MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 name"));
104 MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 MHz"));
105 //KS: Below code is convoluted because I mostly work on English based Linux but sometimes on Polish based Linux, this ensures it works on both. We can add support for other languages if needed
106 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -i Archit"));
107 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1d |L1d:'"));
108 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1i |L1i:'"));
109 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L2 |L2:'"));
110 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L3 |L3:'"));
111 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'Thread.* per core:|Wątków na rdzeń:'"));
112 MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E '^CPU(:|\\(s\\)):?\\s+[0-9]+'"));
113 MACH3LOG_INFO("With available threads {}", M3::GetNThreads());
114
116 //KS: /proc/cpuinfo and lscpu holds much more info I have limited it but one can expand it if needed
117}
118
119
120// ************************
122// ************************
123 //KS: If OMP_NUM_THREADS is exported, assume user did this on purpose
124 if (std::getenv("OMP_NUM_THREADS") != nullptr) return;
125
126 const int nThreads = M3::GetNThreads();
127 constexpr int MaxAllowedThreads = 16;
128 constexpr int RecommendedThreads = 8;
129
130 if (nThreads > MaxAllowedThreads) {
131 MACH3LOG_CRITICAL("You specified more than {} threads ({})", MaxAllowedThreads, nThreads);
132 MACH3LOG_CRITICAL("With so many threads code will be slower, please use:");
133 MACH3LOG_CRITICAL("export OMP_NUM_THREADS={}", RecommendedThreads);
134 MACH3LOG_CRITICAL("To use different number of threads");
135 throw MaCh3Exception(__FILE__, __LINE__, "Too many threads");
136 }
137}
138
139
140// ************************
141//KS: Simple function retrieving GPU info
143// ************************
144#ifdef MaCh3_CUDA
145 MACH3LOG_INFO("Using following GPU:");
146 // Print GPU name
147 MACH3LOG_INFO("GPU Name: {}", TerminalToString("nvidia-smi --query-gpu=name --format=csv,noheader"));
148 // Print number of GPUs
149 MACH3LOG_INFO("Number of GPUs: {}", TerminalToString("nvidia-smi --query-gpu=count --format=csv,noheader"));
150 // Print total VRAM
151 MACH3LOG_INFO("Total VRAM: {} MB", TerminalToString("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits"));
152 // Print Driver Version
153 MACH3LOG_INFO("Driver Version: {}", TerminalToString("nvidia-smi --query-gpu=driver_version --format=csv,noheader"));
154 // Print N GPU thread
155 MACH3LOG_INFO("Currently used GPU has: {} threads", GetNumGPUThreads());
156 // Print L2 cache
157 MACH3LOG_INFO("Currently used GPU has: {} KB L2 cache", GetL2CacheSize() / 1024);
158 // Shared memory info
159 MACH3LOG_INFO("Max shared memory per block: {} KB", GetSharedMemoryPerBlock() / 1024);
160 // Print 1D texture size
161 MACH3LOG_INFO("Max 1D texture size: {}", GetMaxTexture1DSize());
162#endif
163}
164
165// ************************
166// KS: Find out about Disk usage
168// ************************
169 MACH3LOG_INFO("Disk Usage:");
170
171 // Get disk usage
172 MACH3LOG_INFO("{}", TerminalToString("df -h --total | grep total"));
173}
174
175// ************************
176// KS: Convoluted code to grab output from terminal to string
177std::string TerminalToString(std::string cmd) {
178// ************************
179 std::array<char, 128> buffer;
180 std::string result;
181 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(), "r"), pclose);
182 if (!pipe) {
183 throw MaCh3Exception(__FILE__, __LINE__, "popen() failed!");
184 }
185 while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
186 result += buffer.data();
187 }
188 // Remove trailing newline characters
189 result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
190 return result;
191}
192
193// ************************
194//KS: Simple to retrieve speed of get entry inspired by
195void EstimateDataTransferRate(TChain* chain, const Long64_t entry){
196// ************************
197 TStopwatch timer;
198
199 timer.Start();
200 Int_t bytesProcessed{ chain->GetEntry(entry) };
201
202 timer.Stop();
203
204 Double_t timeInSeconds = timer.RealTime();
205 Double_t dataRateMBps = (double(bytesProcessed) / (1024.0 * 1024.0)) / timeInSeconds;
206
207 MACH3LOG_INFO("Data transfer: {} B, rate: {:.2f} MB/s", bytesProcessed, dataRateMBps);
208}
209
210// ************************
211//KS: Simply print progress bar
212void PrintProgressBar(const Long64_t Done, const Long64_t All) {
213// ************************
214 double progress = double(Done)/double(All);
215 const int barWidth = 20;
216 std::ostringstream progressBar;
217
218 progressBar << "[";
219 int pos = int(barWidth * progress);
220 for (int i = 0; i < barWidth; ++i) {
221 if (i < pos)
222 progressBar << "=";
223 else if (i == pos)
224 progressBar << ">";
225 else
226 progressBar << " ";
227 }
228
229 progressBar << "] " << std::setw(3) << Done <<"/"<< All<<" ("<<static_cast<int>(progress * 100.0)<<"%)\r";
230 MACH3LOG_INFO("{}", progressBar.str());
231}
232
233// ***************************************************************************
234//CW: Get memory, which is probably silly
235int getValue(const std::string& Type) { //Note: this value is in KB!
236// ***************************************************************************
237 std::ifstream file("/proc/self/status");
238 int result = -1;
239 std::string line;
240
241 if (Type == "VmSize")
242 {
243 while (std::getline(file, line))
244 {
245 if (line.compare(0, 7, "VmSize:") == 0)
246 {
247 result = parseLine(line.substr(7));
248 break;
249 }
250 }
251 }
252 else if (Type == "VmRSS")
253 {
254 while (std::getline(file, line))
255 {
256 if (line.compare(0, 6, "VmRSS:") == 0)
257 {
258 result = parseLine(line.substr(6));
259 break;
260 }
261 }
262 }
263 else if (Type == "MemTotal")
264 {
265 std::ifstream meminfo("/proc/meminfo");
266 while (std::getline(meminfo, line))
267 {
268 if (line.find("MemTotal:") != std::string::npos) {
269 result = parseLine(line.substr(9));
270 break;
271 }
272 }
273 }
274 else
275 {
276 MACH3LOG_ERROR("Not supported getValue: {}", Type);
277 throw MaCh3Exception(__FILE__, __LINE__);
278 }
279 return result;
280}
281
282// ***************************************************************************
283//CW: Get memory, which is probably silly
284int parseLine(const std::string& line){
285// ***************************************************************************
286 std::istringstream iss(line);
287 int value;
288 iss >> value;
289 return value;
290}
291
292// ***************************************************************************
293//KS: Print Yaml config using logger
294void PrintConfig(const YAML::Node& node){
295// ***************************************************************************
296 std::stringstream ss;
297 ss << node;
298 std::string yamlString = ss.str();
299
300 std::istringstream iss(yamlString);
301 std::string line;
302 while (std::getline(iss, line)) {
303 MACH3LOG_INFO("{}", line);
304 }
305}
306
307// ***************************************************************************
308//KS: Almost all MaCh3 executables have the same usage, prepare simple printer
309void MaCh3Usage(int argc, char **argv) {
310// ***************************************************************************
311 if (argc != 2) {
312 MACH3LOG_ERROR("Wrong usage of MaCh3 executable!");
313 MACH3LOG_ERROR("Syntax is $: {} config.yaml", argv[0]);
314 MACH3LOG_ERROR("Where config.yaml is a valid config file, compatible with the manager class (manager/manager.cpp/h)");
315 throw MaCh3Exception(__FILE__, __LINE__);
316 }
317}
318} //end namespace
319
320namespace M3 {
321// ***************************************************************************
323// ***************************************************************************
324 #ifdef MULTITHREAD
325 return omp_get_max_threads();
326 #else
327 return 1;
328 #endif
329}
330
331} //end namespace
332
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:26
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:25
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:23
System and monitoring utilities for printing system information and status updates.
Custom exception class for MaCh3 errors.
size_t GetMaxTexture1DSize(const int device)
KS: Get the maximum size for 1D textures on the specified GPU device.
Definition: gpuUtils.cu:134
int GetNumGPUThreads(const int Device)
KS: Get number of GPU threads for currently used GPU.
Definition: gpuUtils.cu:102
size_t GetL2CacheSize(const int device)
KS: Get L2 cache size (in bytes) for the specified GPU device.
Definition: gpuUtils.cu:122
size_t GetSharedMemoryPerBlock(const int device)
KS: Returns the maximum shared memory per block for a given GPU device.
Definition: gpuUtils.cu:146
Common CUDA utilities and definitions for shared GPU functionality.
Definition: Core.h:19
int GetNThreads()
number of threads which we need for example for TRandom3
Definition: Monitor.cpp:322
void GetOSInfo()
KS: Find out more about operational system.
Definition: Monitor.cpp:87
std::string TerminalToString(std::string cmd)
KS: Convoluted code to grab output from terminal to string.
Definition: Monitor.cpp:177
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
Definition: Monitor.cpp:212
std::string GetMaCh3Version()
KS: Get version of MaCh3.
Definition: Monitor.cpp:45
void GetDiskUsage()
KS: Find out about Disk usage.
Definition: Monitor.cpp:167
void NThreadsSanity()
KS: Check if user is not using huge number of threads and throw error.
Definition: Monitor.cpp:121
void GetCPUInfo()
KS: Check what CPU you are using.
Definition: Monitor.cpp:98
void GetGPUInfo()
KS: Check what GPU you are using.
Definition: Monitor.cpp:142
int getValue(const std::string &Type)
CW: Get info like RAM.
Definition: Monitor.cpp:235
void PrintConfig(const YAML::Node &node)
KS: Print Yaml config using logger.
Definition: Monitor.cpp:294
void MaCh3Usage(int argc, char **argv)
KS: Almost all MaCh3 executables have the same usage, prepare simple printer.
Definition: Monitor.cpp:309
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
Definition: Monitor.cpp:11
int parseLine(const std::string &line)
CW: Get memory, which is probably silly.
Definition: Monitor.cpp:284
void EstimateDataTransferRate(TChain *chain, const Long64_t entry)
KS: Check what CPU you are using.
Definition: Monitor.cpp:195