Salome HOME
[EDF29150] : log performance of python scripts run inside SALOME container + verbosit...
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Parser.cxx
1 // Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "SALOME_ResourcesCatalog_Parser.hxx"
24 #include <iostream>
25 #include <sstream>
26
27 using namespace std;
28
29 #define NULL_VALUE 0
30
31 unsigned int ResourceDataToSort::_nbOfProcWanted = NULL_VALUE;
32 unsigned int ResourceDataToSort::_nbOfNodesWanted = NULL_VALUE;
33 unsigned int ResourceDataToSort::_nbOfProcPerNodeWanted = NULL_VALUE;
34 unsigned int ResourceDataToSort::_CPUFreqMHzWanted = NULL_VALUE;
35 unsigned int ResourceDataToSort::_memInMBWanted = NULL_VALUE;
36
37 ResourceDataToSort::ResourceDataToSort()
38 {}
39
40 ResourceDataToSort::ResourceDataToSort(const std::string& name,
41                                        unsigned int nbOfNodes,
42                                        unsigned int nbOfProcPerNode,
43                                        unsigned int CPUFreqMHz,
44                                        unsigned int memInMB):
45     _Name(name),
46     _nbOfNodes(nbOfNodes),
47     _nbOfProcPerNode(nbOfProcPerNode),
48     _CPUFreqMHz(CPUFreqMHz),
49     _memInMB(memInMB)
50 {}
51
52 //! Method used by list::sort to sort the resources used in SALOME_ResourcesManager::GetResourcesFitting
53 bool ResourceDataToSort::operator< (const ResourceDataToSort& other) const
54   {
55     unsigned int nbPts = GetNumberOfPoints();
56     return nbPts < other.GetNumberOfPoints();
57   }
58
59 unsigned int ResourceDataToSort::GetNumberOfPoints() const
60   {
61     unsigned int ret = 0;
62     //priority 0 : Nb of proc
63
64     if (_nbOfProcWanted != NULL_VALUE)
65       {
66         unsigned int nb_proc = _nbOfNodes * _nbOfProcPerNode;
67         if (nb_proc == _nbOfProcWanted)
68           ret += 30000;
69         else if (nb_proc > _nbOfProcWanted)
70           ret += 20000;
71         else
72           ret += 10000;
73       }
74
75     //priority 1 : Nb of nodes
76
77     if (_nbOfNodesWanted != NULL_VALUE)
78       {
79         if (_nbOfNodes == _nbOfNodesWanted)
80           ret += 3000;
81         else if (_nbOfNodes > _nbOfNodesWanted)
82           ret += 2000;
83         else
84           ret += 1000;
85       }
86
87     //priority 2 : Nb of proc by node
88     if (_nbOfProcPerNodeWanted != NULL_VALUE)
89       {
90         if (_nbOfProcPerNode == _nbOfProcPerNodeWanted)
91           ret += 300;
92         else if (_nbOfProcPerNode > _nbOfProcPerNodeWanted)
93           ret += 200;
94         else
95           ret += 100;
96       }
97
98     //priority 3 : Cpu freq
99     if (_CPUFreqMHzWanted != NULL_VALUE)
100       {
101         if (_CPUFreqMHz == _CPUFreqMHzWanted)
102           ret += 30;
103         else if (_CPUFreqMHz > _CPUFreqMHzWanted)
104           ret += 20;
105         else
106           ret += 10;
107       }
108
109     //priority 4 : memory
110     if (_memInMBWanted != NULL_VALUE)
111       {
112         if (_memInMB == _memInMBWanted)
113           ret += 3;
114         else if (_memInMB > _memInMBWanted)
115           ret += 2;
116         else
117           ret += 1;
118       }
119
120     //RES_MESSAGE("[GetNumberOfPoints] points number for resource: " << _Name << " " << ret);
121     return ret;
122   }
123
124 //! Method used for debug
125 void ResourceDataToSort::Print() const
126   {
127     std::cout << _nbOfNodes << std::endl;
128     std::cout << _nbOfProcPerNode << std::endl;
129     std::cout << _CPUFreqMHz << std::endl;
130     std::cout << _memInMB << std::endl;
131   }
132
133
134 ParserResourcesType::ParserResourcesType()
135 : Protocol(ssh),
136   ClusterInternalProtocol(ssh),
137   type(single_machine),
138   Batch(none),
139   mpi(nompi),
140   nbOfProc(1),
141   can_launch_batch_jobs(false),
142   can_run_containers(false)
143 {
144   DataForSort._Name = "";
145   DataForSort._nbOfNodes = 1;
146   DataForSort._nbOfProcPerNode = 1;
147   DataForSort._CPUFreqMHz = 0;
148   DataForSort._memInMB = 0;
149 }
150
151 ParserResourcesType::~ParserResourcesType()
152 {
153 }
154
155 std::string ParserResourcesType::protocolToString(AccessProtocolType protocol)
156 {
157   switch (protocol)
158   {
159   case sh:
160     return "sh";
161   case rsh:
162     return "rsh";
163   case ssh:
164     return "ssh";
165   case srun:
166     return "srun";
167   case pbsdsh:
168     return "pbsdsh";
169   case blaunch:
170     return "blaunch";
171   case rsync:
172     return "rsync";
173   default:
174     throw ResourcesException("Unknown protocol");
175   }
176 }
177
178 AccessProtocolType ParserResourcesType::stringToProtocol(const std::string & protocolStr)
179 {
180   if (protocolStr == "sh")
181     return sh;
182   else if (protocolStr == "rsh")
183     return rsh;
184   else if (protocolStr == "ssh")
185     return ssh;
186   else if (protocolStr == "srun")
187     return srun;
188   else if (protocolStr == "pbsdsh")
189     return pbsdsh;
190   else if (protocolStr == "blaunch")
191     return blaunch;
192   else if (protocolStr == "rsync")
193     return rsync;
194   else
195     throw ResourcesException((string("Unknown protocol ") + protocolStr).c_str());
196 }
197
198 std::string ParserResourcesType::dump(char sep) const
199 {
200   std::ostringstream oss;
201   oss << "Name: " << this->Name << sep <<
202         "HostName: " << this->HostName << sep <<
203         "Type: " << this->getResourceTypeStr() << sep <<
204         "NbOfNodes: " << this->DataForSort._nbOfNodes << sep <<
205         "NbOfProcPerNode: " << this->DataForSort._nbOfProcPerNode << sep <<
206         "CPUFreqMHz: " << this->DataForSort._CPUFreqMHz << sep <<
207         "MemInMB: " << this->DataForSort._memInMB << sep <<
208         "Protocol: " << this->getAccessProtocolTypeStr() << sep <<
209         "ClusterInternalProtocol: " << this->getClusterInternalProtocolStr() << sep <<
210         "Batch: " << this->getBatchTypeStr() << sep <<
211         "mpi: " << this->getMpiImplTypeStr() << sep <<
212         "UserName: " << this->UserName << sep <<
213         "AppliPath: " << this->AppliPath << sep <<
214         "OS: " << this->OS << sep <<
215         "batchQueue: " << this->batchQueue << sep <<
216         "userCommands: " << this->userCommands << sep <<
217         "use: " << this->use << sep <<
218         "NbOfProc: " << this->nbOfProc << sep <<
219         "Can Launch Batch Jobs: " << this->can_launch_batch_jobs << sep <<
220         "Can Run Containers: " << this->can_run_containers << sep <<
221         "Working Directory: " << this->working_directory << sep;
222
223   for(unsigned int i=0 ; i<this->ComponentsList.size() ; i++)
224     oss << "Component " << i+1 << " called: " << this->ComponentsList[i] << sep;
225
226   list<ParserResourcesType>::const_iterator it;
227   for(it = this->ClusterMembersList.cbegin() ; it != this->ClusterMembersList.cend() ; it++)
228   {
229     oss << "Cluster member called: " << (*it).HostName << sep;
230   }
231   return oss.str();
232 }
233
234 ostream & operator<<(ostream &os, const ParserResourcesType &prt)
235 {
236   os << prt.dump('\n');
237   return os;
238 }
239
240 std::string
241 ParserResourcesType::getAccessProtocolTypeStr() const
242 {
243   return protocolToString(Protocol);
244 }
245
246 std::string
247 ParserResourcesType::getClusterInternalProtocolStr() const
248 {
249   return protocolToString(ClusterInternalProtocol);
250 }
251
252 std::string 
253 ParserResourcesType::getResourceTypeStr() const
254 {
255   switch (type)
256   {
257   case cluster:
258     return "cluster";
259   case single_machine:
260     return "single_machine";
261   default:
262     throw ResourcesException("Unknown resource type");
263   }
264 }
265
266 std::string 
267 ParserResourcesType::getBatchTypeStr() const
268 {
269   switch (Batch)
270   {
271   case none:
272     return "none";
273   case pbs:
274     return "pbs";
275   case lsf:
276     return "lsf";
277   case sge:
278     return "sge";
279   case ccc:
280     return "ccc";
281   case slurm:
282     return "slurm";
283   case ll:
284     return "ll";
285   case vishnu:
286     return "vishnu";
287   case oar:
288     return "oar";
289   case coorm:
290     return "coorm";
291   default:
292     throw ResourcesException("Unknown batch type");
293   }
294 }
295
296 std::string 
297 ParserResourcesType::getMpiImplTypeStr() const
298 {
299   switch (mpi)
300   {
301   case nompi:
302     return "no mpi";
303   case lam:
304     return "lam";
305   case mpich1:
306     return "mpich1";
307   case mpich2:
308     return "mpich2";
309   case openmpi:
310     return "openmpi";
311   case ompi:
312     return "ompi";
313   case slurmmpi:
314     return "slurmmpi";
315   case prun:
316     return "prun";
317   default:
318     throw ResourcesException("Unknown MPI implementation type");
319   }
320 }
321
322 string ParserResourcesType::getCanLaunchBatchJobsStr() const
323 {
324   return can_launch_batch_jobs ? "true" : "false";
325 }
326
327 string ParserResourcesType::getCanRunContainersStr() const
328 {
329   return can_run_containers ? "true" : "false";
330 }
331
332 void ParserResourcesType::setAccessProtocolTypeStr(const string & protocolTypeStr)
333 {
334   Protocol = stringToProtocol(protocolTypeStr);
335 }
336
337 void ParserResourcesType::setResourceTypeStr(const string & resourceTypeStr)
338 {
339   if (resourceTypeStr == "cluster")
340     type = cluster;
341   else if (resourceTypeStr == "single_machine")
342     type = single_machine;
343   else
344     throw ResourcesException((string("Unknown resource type ") + resourceTypeStr).c_str());
345 }
346
347 void ParserResourcesType::setBatchTypeStr(const string & batchTypeStr)
348 {
349   if (batchTypeStr == "pbs")
350     Batch = pbs;
351   else if (batchTypeStr == "lsf")
352     Batch = lsf;
353   else if (batchTypeStr == "sge")
354     Batch = sge;
355   else if (batchTypeStr == "slurm")
356     Batch = slurm;
357   else if (batchTypeStr == "ccc")
358     Batch = ccc;
359   else if (batchTypeStr == "ll")
360     Batch = ll;
361   else if (batchTypeStr == "vishnu")
362     Batch = vishnu;
363   else if (batchTypeStr == "oar")
364     Batch = oar;
365   else if (batchTypeStr == "coorm")
366     Batch = coorm;
367   else if (batchTypeStr == "" || batchTypeStr == "none" || batchTypeStr == "ssh_batch")
368     Batch = none;
369   else
370     throw ResourcesException((string("Unknown batch type ") + batchTypeStr).c_str());
371 }
372
373 void ParserResourcesType::setMpiImplTypeStr(const string & mpiImplTypeStr)
374 {
375   if (mpiImplTypeStr == "lam")
376     mpi = lam;
377   else if (mpiImplTypeStr == "mpich1")
378     mpi = mpich1;
379   else if (mpiImplTypeStr == "mpich2")
380     mpi = mpich2;
381   else if (mpiImplTypeStr == "openmpi")
382     mpi = openmpi;
383   else if (mpiImplTypeStr == "ompi")
384     mpi = ompi;
385   else if (mpiImplTypeStr == "slurmmpi")
386     mpi = slurmmpi;
387   else if (mpiImplTypeStr == "prun")
388     mpi = prun;
389   else if (mpiImplTypeStr == "" || mpiImplTypeStr == "no mpi")
390     mpi = nompi;
391   else
392     throw ResourcesException((string("Unknown MPI implementation type ") + mpiImplTypeStr).c_str());
393 }
394
395 void ParserResourcesType::setClusterInternalProtocolStr(const string & internalProtocolTypeStr)
396 {
397   ClusterInternalProtocol = stringToProtocol(internalProtocolTypeStr);
398 }
399
400 void ParserResourcesType::setCanLaunchBatchJobsStr(const string & canLaunchBatchJobsStr)
401 {
402   if (canLaunchBatchJobsStr == "true")
403     can_launch_batch_jobs = true;
404   else if (canLaunchBatchJobsStr == "false")
405     can_launch_batch_jobs = false;
406   else
407     throw ResourcesException((string("Invalid boolean value for can_launch_batch_jobs: ") +
408                             canLaunchBatchJobsStr).c_str());
409 }
410
411 void ParserResourcesType::setCanRunContainersStr(const string & canRunContainersStr)
412 {
413   if (canRunContainersStr == "true")
414     can_run_containers = true;
415   else if (canRunContainersStr == "false")
416     can_run_containers = false;
417   else
418     throw ResourcesException((string("Invalid boolean value for can_run_containers: ") +
419                             canRunContainersStr).c_str());
420 }