MaCh3  2.4.2
Reference Guide
Functions
MaCh3Utils Namespace Reference

Functions

void MaCh3Welcome ()
 KS: Prints welcome message with MaCh3 logo. More...
 
std::string GetMaCh3Version ()
 KS: Get version of MaCh3. More...
 
void GetOSInfo ()
 KS: Find out more about operational system. More...
 
void GetCPUInfo ()
 KS: Check what CPU you are using. More...
 
void NThreadsSanity ()
 KS: Check if user is not using huge number of threads and throw error. More...
 
void GetGPUInfo ()
 KS: Check what GPU you are using. More...
 
void GetDiskUsage ()
 KS: Find out about Disk usage. More...
 
std::string TerminalToString (std::string cmd)
 KS: Convoluted code to grab output from terminal to string. More...
 
void EstimateDataTransferRate (TChain *chain, const Long64_t entry)
 KS: Check what CPU you are using. More...
 
void PrintProgressBar (const Long64_t Done, const Long64_t All)
 KS: Simply print progress bar. More...
 
int getValue (const std::string &Type)
 CW: Get info like RAM. More...
 
int parseLine (const std::string &line)
 CW: Get memory, which is probably silly. More...
 
void PrintConfig (const YAML::Node &node)
 KS: Print Yaml config using logger. More...
 
void Print (const TTree *tree)
 
void MaCh3Usage (int argc, char **argv)
 KS: Almost all MaCh3 executables have the same usage, prepare simple printer. More...
 
double GetMassFromPDG (const int PDG)
 Return mass for given PDG. More...
 
int PDGToNuOscillatorFlavour (const int NuPdg)
 Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscillator type simply gets multiplied by -1. More...
 
std::string FormatDouble (const double value, const int precision)
 Convert double into string for precision, useful for playing with yaml if you don't want to have in config floating point precision... More...
 

Function Documentation

◆ EstimateDataTransferRate()

void MaCh3Utils::EstimateDataTransferRate ( TChain *  chain,
const Long64_t  entry 
)

KS: Check what CPU you are using.

Definition at line 211 of file Monitor.cpp.

211  {
212 // ************************
213  TStopwatch timer;
214 
215  timer.Start();
216  Int_t bytesProcessed{ chain->GetEntry(entry) };
217 
218  timer.Stop();
219 
220  Double_t timeInSeconds = timer.RealTime();
221  Double_t dataRateMBps = (double(bytesProcessed) / (1024.0 * 1024.0)) / timeInSeconds;
222 
223  MACH3LOG_INFO("Data transfer: {} B, rate: {:.2f} MB/s", bytesProcessed, dataRateMBps);
224 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35

◆ FormatDouble()

std::string MaCh3Utils::FormatDouble ( const double  value,
const int  precision 
)
inline

Convert double into string for precision, useful for playing with yaml if you don't want to have in config floating point precision...

Definition at line 811 of file SampleStructs.h.

811  {
812  // ***************************
813  std::ostringstream oss;
814  oss << std::fixed << std::setprecision(precision) << value;
815  return oss.str();
816  }

◆ GetCPUInfo()

void MaCh3Utils::GetCPUInfo ( )

KS: Check what CPU you are using.

Definition at line 99 of file Monitor.cpp.

99  {
100 // ************************
101  //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
102  MACH3LOG_INFO("Using following CPU:");
103 
104  MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 name"));
105  MACH3LOG_INFO("{}", TerminalToString("cat /proc/cpuinfo | grep -m 1 MHz"));
106  //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
107  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -i Archit"));
108  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1d |L1d:'"));
109  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L1i |L1i:'"));
110  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L2 |L2:'"));
111  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'L3 |L3:'"));
112  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E 'Thread.* per core:|Wątków na rdzeń:'"));
113  MACH3LOG_INFO("{}", TerminalToString("lscpu | grep -m 1 -E '^CPU(:|\\(s\\)):?\\s+[0-9]+'"));
114  MACH3LOG_INFO("With available threads {}", M3::GetNThreads());
115 
116  NThreadsSanity();
117  //KS: /proc/cpuinfo and lscpu holds much more info I have limited it but one can expand it if needed
118 }
int GetNThreads()
number of threads which we need for example for TRandom3
Definition: Monitor.cpp:372
std::string TerminalToString(std::string cmd)
KS: Convoluted code to grab output from terminal to string.
Definition: Monitor.cpp:186
void NThreadsSanity()
KS: Check if user is not using huge number of threads and throw error.
Definition: Monitor.cpp:122

◆ GetDiskUsage()

void MaCh3Utils::GetDiskUsage ( )

KS: Find out about Disk usage.

Definition at line 176 of file Monitor.cpp.

176  {
177 // ************************
178  MACH3LOG_INFO("Disk Usage:");
179 
180  // Get disk usage
181  MACH3LOG_INFO("{}", TerminalToString("df -h --total | grep total"));
182 }

◆ GetGPUInfo()

void MaCh3Utils::GetGPUInfo ( )

KS: Check what GPU you are using.

Definition at line 143 of file Monitor.cpp.

143  {
144 // ************************
145 #ifdef MaCh3_CUDA
146  int nDevices;
147  cudaGetDeviceCount(&nDevices);
148  if (nDevices == 0) {
149  MACH3LOG_CRITICAL("MaCh3 compiled with CUDA support (for GPU acceleration) but could not find GPU");
150  MACH3LOG_CRITICAL("Either allocate GPU for your job or recompile MaCh3 without GPU support");
151  throw MaCh3Exception(__FILE__, __LINE__);
152  }
153 
154  MACH3LOG_INFO("Using following GPU:");
155  // Print GPU name
156  MACH3LOG_INFO("GPU Name: {}", TerminalToString("nvidia-smi --query-gpu=name --format=csv,noheader"));
157  // Print number of GPUs
158  MACH3LOG_INFO("Number of GPUs: {}", TerminalToString("nvidia-smi --query-gpu=count --format=csv,noheader"));
159  // Print total VRAM
160  MACH3LOG_INFO("Total VRAM: {} MB", TerminalToString("nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits"));
161  // Print Driver Version
162  MACH3LOG_INFO("Driver Version: {}", TerminalToString("nvidia-smi --query-gpu=driver_version --format=csv,noheader"));
163  // Print N GPU thread
164  MACH3LOG_INFO("Currently used GPU has: {} threads", GetNumGPUThreads());
165  // Print L2 cache
166  MACH3LOG_INFO("Currently used GPU has: {} KB L2 cache", GetL2CacheSize() / 1024);
167  // Shared memory info
168  MACH3LOG_INFO("Max shared memory per block: {} KB", GetSharedMemoryPerBlock() / 1024);
169  // Print 1D texture size
170  MACH3LOG_INFO("Max 1D texture size: {}", GetMaxTexture1DSize());
171 #endif
172 }
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
Custom exception class used throughout MaCh3.
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

◆ GetMaCh3Version()

std::string MaCh3Utils::GetMaCh3Version ( )

KS: Get version of MaCh3.

Returns
The current MaCh3 version as a string.

This function fetches and returns the version of the MaCh3 software being used.

Definition at line 46 of file Monitor.cpp.

46  {
47 // ************************
48  //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
49  std::string MaCh3_VERSION = "";
50 
51  if(std::getenv("MaCh3_ROOT") == nullptr){
52  throw MaCh3Exception(__FILE__, __LINE__, "Error: you haven't sourced setup.MaCh3.sh in core!");
53  }
54 
55  std::string file = std::string(std::getenv("MaCh3_ROOT")) + "/version.h";
56  // Open the version.h file
57  std::ifstream versionFile(file);
58 
59  // Check if the file is opened successfully
60  if (!versionFile.is_open()) {
61  MACH3LOG_ERROR("Error: Couldn't open version.h {}", file);
62  throw MaCh3Exception(__FILE__, __LINE__);
63  }
64 
65  std::string line;
66  const std::string searchKey = "MaCh3_VERSION=";
67 
68  // Read each line from the file
69  while (std::getline(versionFile, line)) {
70  // Search for the line containing MaCh3_VERSION
71  auto pos = line.find(searchKey);
72  if (pos != std::string::npos) {
73  // Extract the version string
74  MaCh3_VERSION = line.substr(pos + searchKey.length());
75  MaCh3_VERSION.erase(0, MaCh3_VERSION.find_first_not_of("\"")); // Remove leading quote
76  MaCh3_VERSION.erase(MaCh3_VERSION.find_last_not_of("\";") + 1); // Remove trailing quote and semicolon
77  break; // Stop searching once found
78  }
79  }
80  // Close the file
81  versionFile.close();
82 
83  return MaCh3_VERSION;
84 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37

◆ GetMassFromPDG()

double MaCh3Utils::GetMassFromPDG ( const int  PDG)
inline

Return mass for given PDG.

Note
Get the mass of a particle from the PDG In GeV, not MeV!
Todo:
this could be constexpr in c++17 [24] (particle masses) [34] (nuclear masses)

Definition at line 727 of file SampleStructs.h.

727  {
728  // *****************************
729  switch (abs(PDG)) {
730  // Leptons
731  case 11: return 0.00051099895; // e
732  case 13: return 0.1056583755; // mu
733  case 15: return 1.77693; // tau
734  // Neutrinos
735  case 12:
736  case 14:
737  case 16:
738  return 0.;
739  // Photon
740  case 22: return 0.;
741  // Mesons
742  case 211: return 0.13957039; // pi_+/-
743  case 111: return 0.1349768; // pi_0
744  case 221: return 0.547862; // eta
745  case 311: // K_0
746  case 130: // K_0_L
747  case 310: // K_0_S
748  return 0.497611;
749  case 321: return 0.493677; // K_+/-
750  // Baryons
751  case 2112: return 0.939565; // n
752  case 2212: return 0.938272; // p
753  case 3122: return 1.115683; // lambda
754  case 3222: return 1.118937; // sig_+
755  case 3112: return 1.197449; // sig_-
756  case 3212: return 1.192642; // sig_0
757  // Nuclei
758  case 1000050110: return 10.255103; // Boron-11
759  case 1000060120: return 11.177929; // Carbon-12
760  case 1000070140: return 13.043781; // Nitrogen-14
761  case 1000080160: return 14.899169; // Oxygen-16
762  case 1000090190: return 17.696901; // Fluorine-19
763  case 1000110230: return 21.414835; // Sodium-23
764  case 1000130270: return 25.133144; // Aluminum-27
765  case 1000140280: return 26.060342; // Silicon-28
766  case 1000190390: return 36.294463; // Potassium-39
767  case 1000180400: return 37.224724; // Argon-40
768  case 1000220480: return 44.663224; // Titanium-48
769  case 1000300640: return 59.549619; // Zinc-64
770  default:
771  MACH3LOG_ERROR("Haven't got a saved mass for PDG: {}", PDG);
772  MACH3LOG_ERROR("Please implement me!");
773  throw MaCh3Exception(__FILE__, __LINE__);
774  } // End switch
775  return 0;
776  }

◆ GetOSInfo()

void MaCh3Utils::GetOSInfo ( )

KS: Find out more about operational system.

Definition at line 88 of file Monitor.cpp.

88  {
89 // ************************
90  MACH3LOG_INFO("Operating System Information:");
91 
92  // Distribution and version
93  MACH3LOG_INFO("Distribution: {}", TerminalToString("lsb_release -d | awk -F':' '{print $2}'"));
94  MACH3LOG_INFO("Kernel Version: {}", TerminalToString("uname -r"));
95 }

◆ getValue()

int MaCh3Utils::getValue ( const std::string &  Type)

CW: Get info like RAM.

Parameters
TypeThe type of system information to retrieve (e.g., RAM, CPU usage).
Returns
The requested system information as an integer.

This function fetches system information like RAM usage or other hardware details based on the specified type.

Definition at line 251 of file Monitor.cpp.

251  { //Note: this value is in KB!
252 // ***************************************************************************
253  std::ifstream file("/proc/self/status");
254  int result = -1;
255  std::string line;
256 
257  if (Type == "VmSize")
258  {
259  while (std::getline(file, line))
260  {
261  if (line.compare(0, 7, "VmSize:") == 0)
262  {
263  result = parseLine(line.substr(7));
264  break;
265  }
266  }
267  }
268  else if (Type == "VmRSS")
269  {
270  while (std::getline(file, line))
271  {
272  if (line.compare(0, 6, "VmRSS:") == 0)
273  {
274  result = parseLine(line.substr(6));
275  break;
276  }
277  }
278  }
279  else if (Type == "MemTotal")
280  {
281  std::ifstream meminfo("/proc/meminfo");
282  while (std::getline(meminfo, line))
283  {
284  if (line.find("MemTotal:") != std::string::npos) {
285  result = parseLine(line.substr(9));
286  break;
287  }
288  }
289  }
290  else
291  {
292  MACH3LOG_ERROR("Not supported getValue: {}", Type);
293  throw MaCh3Exception(__FILE__, __LINE__);
294  }
295  return result;
296 }
int parseLine(const std::string &line)
CW: Get memory, which is probably silly.
Definition: Monitor.cpp:300

◆ MaCh3Usage()

void MaCh3Utils::MaCh3Usage ( int  argc,
char **  argv 
)

KS: Almost all MaCh3 executables have the same usage, prepare simple printer.

Parameters
argcThe number of command-line arguments.
argvThe array of command-line arguments.

This function prints a simple usage guide for MaCh3 executables, typically called when incorrect arguments are passed.

Definition at line 359 of file Monitor.cpp.

359  {
360 // ***************************************************************************
361  if (argc != 2) {
362  MACH3LOG_ERROR("Wrong usage of MaCh3 executable!");
363  MACH3LOG_ERROR("Syntax is $: {} config.yaml", argv[0]);
364  MACH3LOG_ERROR("Where config.yaml is a valid config file, compatible with the manager class (manager/manager.cpp/h)");
365  throw MaCh3Exception(__FILE__, __LINE__);
366  }
367 }

◆ MaCh3Welcome()

void MaCh3Utils::MaCh3Welcome ( )

KS: Prints welcome message with MaCh3 logo.

Definition at line 12 of file Monitor.cpp.

12  {
13 // *************************
14  // KS: Just make sure we only call it once
15  static bool MaCh3WelcomeInitialised = false;
16 
17  if(MaCh3WelcomeInitialised) return;
18 
19  std::string MaCh3_VERSION = GetMaCh3Version();
20 
21  MACH3LOG_INFO("##################################");
22  MACH3LOG_INFO("Welcome to: ");
23  MACH3LOG_INFO(" __ __ _____ _ ____ ");
24  MACH3LOG_INFO(" | \\/ | / ____| | |___ \\ ");
25  MACH3LOG_INFO(" | \\ / | __ _| | | |__ __) |");
26  MACH3LOG_INFO(" | |\\/| |/ _` | | | '_ \\ |__ < ");
27  MACH3LOG_INFO(" | | | | (_| | |____| | | |___) |");
28  MACH3LOG_INFO(" |_| |_|\\__,_|\\_____|_| |_|____/ ");
29  MACH3LOG_INFO("Version: {}", MaCh3_VERSION);
30  MACH3LOG_INFO("##################################");
31 
32  GetCPUInfo();
33 
34  GetGPUInfo();
35 
36  #ifdef DEBUG
37  GetOSInfo();
38  GetDiskUsage();
39  #endif
40 
41  MaCh3WelcomeInitialised = true;
42 }
void GetOSInfo()
KS: Find out more about operational system.
Definition: Monitor.cpp:88
std::string GetMaCh3Version()
KS: Get version of MaCh3.
Definition: Monitor.cpp:46
void GetDiskUsage()
KS: Find out about Disk usage.
Definition: Monitor.cpp:176
void GetCPUInfo()
KS: Check what CPU you are using.
Definition: Monitor.cpp:99
void GetGPUInfo()
KS: Check what GPU you are using.
Definition: Monitor.cpp:143

◆ NThreadsSanity()

void MaCh3Utils::NThreadsSanity ( )

KS: Check if user is not using huge number of threads and throw error.

Definition at line 122 of file Monitor.cpp.

122  {
123 // ************************
124  //KS: If OMP_NUM_THREADS is exported, assume user did this on purpose
125  if (std::getenv("OMP_NUM_THREADS") != nullptr) return;
126 
127  const int nThreads = M3::GetNThreads();
128  constexpr int MaxAllowedThreads = 16;
129  constexpr int RecommendedThreads = 8;
130 
131  if (nThreads > MaxAllowedThreads) {
132  MACH3LOG_CRITICAL("You specified more than {} threads ({})", MaxAllowedThreads, nThreads);
133  MACH3LOG_CRITICAL("With so many threads code will be slower, please use:");
134  MACH3LOG_CRITICAL("export OMP_NUM_THREADS={}", RecommendedThreads);
135  MACH3LOG_CRITICAL("To use different number of threads");
136  throw MaCh3Exception(__FILE__, __LINE__, "Too many threads");
137  }
138 }

◆ parseLine()

int MaCh3Utils::parseLine ( const std::string &  line)

CW: Get memory, which is probably silly.

Parameters
lineThe line of text to parse.
Returns
The extracted memory value as an integer.

This function is used to parse a line of text and extract memory-related information.

Definition at line 300 of file Monitor.cpp.

300  {
301 // ***************************************************************************
302  std::istringstream iss(line);
303  int value;
304  iss >> value;
305  return value;
306 }

◆ PDGToNuOscillatorFlavour()

int MaCh3Utils::PDGToNuOscillatorFlavour ( const int  NuPdg)
inline

Convert from PDG flavour to NuOscillator type beware that in the case of anti-neutrinos the NuOscillator type simply gets multiplied by -1.

Definition at line 783 of file SampleStructs.h.

783  {
784  int NuOscillatorFlavour = M3::_BAD_INT_;
785  switch(std::abs(NuPdg)){
786  case NuPDG::kNue:
787  NuOscillatorFlavour = NuOscillator::kElectron;
788  break;
789  case NuPDG::kNumu:
790  NuOscillatorFlavour = NuOscillator::kMuon;
791  break;
792  case NuPDG::kNutau:
793  NuOscillatorFlavour = NuOscillator::kTau;
794  break;
795  default:
796  MACH3LOG_ERROR("Unknown Neutrino PDG {}, cannot convert to NuOscillator type", NuPdg);
797  break;
798  }
799 
800  //This is very cheeky but if the PDG is negative then multiply the PDG by -1
801  // This is consistent with the treatment that NuOscillator expects as enums only
802  // exist for the generic matter flavour and not the anti-matter version
803  if(NuPdg < 0){NuOscillatorFlavour *= -1;}
804 
805  return NuOscillatorFlavour;
806  }
@ kNutau
Tau neutrino.
Definition: SampleStructs.h:98
@ kNue
Electron neutrino.
Definition: SampleStructs.h:96
@ kNumu
Muon neutrino.
Definition: SampleStructs.h:97
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55

◆ Print()

void MaCh3Utils::Print ( const TTree *  tree)
Parameters
treecontent of TTree using logger

Definition at line 325 of file Monitor.cpp.

325  {
326 // ***************************************************************************
327  if (!tree) return;
328 
329  // Create a temporary file to capture stdout
330  FILE* tmpFile = tmpfile();
331  if (!tmpFile) return;
332 
333  // Save old stdout
334  int oldStdout = dup(fileno(stdout));
335  // Redirect stdout to tmpFile
336  dup2(fileno(tmpFile), fileno(stdout));
337 
338  tree->Print(); // ROOT writes to stdout
339 
340  fflush(stdout);
341  // Restore old stdout
342  dup2(oldStdout, fileno(stdout));
343  close(oldStdout);
344 
345  // Read tmpFile content
346  fseek(tmpFile, 0, SEEK_SET);
347  char buffer[1024];
348  while (fgets(buffer, sizeof(buffer), tmpFile)) {
349  std::string line(buffer);
350  if (!line.empty() && line.back() == '\n') line.pop_back();
351  MACH3LOG_INFO("{}", line);
352  }
353 
354  fclose(tmpFile);
355 }

◆ PrintConfig()

void MaCh3Utils::PrintConfig ( const YAML::Node &  node)

KS: Print Yaml config using logger.

Parameters
nodeyaml config node

Definition at line 310 of file Monitor.cpp.

310  {
311 // ***************************************************************************
312  std::stringstream ss;
313  ss << node;
314  std::string yamlString = ss.str();
315 
316  std::istringstream iss(yamlString);
317  std::string line;
318  while (std::getline(iss, line)) {
319  MACH3LOG_INFO("{}", line);
320  }
321 }

◆ PrintProgressBar()

void MaCh3Utils::PrintProgressBar ( const Long64_t  Done,
const Long64_t  All 
)

KS: Simply print progress bar.

Parameters
DoneThe number of tasks completed.
AllThe total number of tasks.

This function prints a progress bar to the terminal, indicating the percentage of tasks completed.

Definition at line 228 of file Monitor.cpp.

228  {
229 // ************************
230  double progress = double(Done)/double(All);
231  const int barWidth = 20;
232  std::ostringstream progressBar;
233 
234  progressBar << "[";
235  int pos = int(barWidth * progress);
236  for (int i = 0; i < barWidth; ++i) {
237  if (i < pos)
238  progressBar << "=";
239  else if (i == pos)
240  progressBar << ">";
241  else
242  progressBar << " ";
243  }
244 
245  progressBar << "] " << std::setw(3) << Done <<"/"<< All<<" ("<<static_cast<int>(progress * 100.0)<<"%)\r";
246  MACH3LOG_INFO("{}", progressBar.str());
247 }

◆ TerminalToString()

std::string MaCh3Utils::TerminalToString ( std::string  cmd)

KS: Convoluted code to grab output from terminal to string.

Parameters
cmdThe terminal command to execute.
Returns
The output of the terminal command as a string.

Definition at line 186 of file Monitor.cpp.

186  {
187 // ************************
188  std::array<char, 128> buffer;
189  std::string result;
190 
191  struct PCloseDeleter {
192  void operator()(FILE* f) const {
193  if (f) pclose(f);
194  }
195  };
196  std::unique_ptr<FILE, PCloseDeleter> pipe(popen(cmd.c_str(), "r"));
197 
198  if (!pipe) {
199  throw MaCh3Exception(__FILE__, __LINE__, "popen() failed!");
200  }
201  while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
202  result += buffer.data();
203  }
204  // Remove trailing newline characters
205  result.erase(std::remove(result.begin(), result.end(), '\n'), result.end());
206  return result;
207 }