Salome HOME
Update copyrights
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Parser.cxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D, 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 : type(single_machine),
136   Protocol(ssh),
137   ClusterInternalProtocol(ssh),
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 ostream & operator<<(ostream &os, const ParserResourcesType &prt)
199 {
200   os << "Name: " << prt.Name << endl <<
201         "HostName: " << prt.HostName << endl <<
202         "Type: " << prt.getResourceTypeStr() << endl <<
203         "NbOfNodes: " << prt.DataForSort._nbOfNodes << endl <<
204         "NbOfProcPerNode: " << prt.DataForSort._nbOfProcPerNode << endl <<
205         "CPUFreqMHz: " << prt.DataForSort._CPUFreqMHz << endl <<
206         "MemInMB: " << prt.DataForSort._memInMB << endl <<
207         "Protocol: " << prt.getAccessProtocolTypeStr() << endl <<
208         "ClusterInternalProtocol: " << prt.getClusterInternalProtocolStr() << endl <<
209         "Batch: " << prt.getBatchTypeStr() << endl <<
210         "mpi: " << prt.getMpiImplTypeStr() << endl <<
211         "UserName: " << prt.UserName << endl <<
212         "AppliPath: " << prt.AppliPath << endl <<
213         "OS: " << prt.OS << endl <<
214         "batchQueue: " << prt.batchQueue << endl <<
215         "userCommands: " << prt.userCommands << endl <<
216         "use: " << prt.use << endl <<
217         "NbOfProc: " << prt.nbOfProc << endl <<
218         "Can Launch Batch Jobs: " << prt.can_launch_batch_jobs << endl <<
219         "Can Run Containers: " << prt.can_run_containers << endl <<
220         "Working Directory: " << prt.working_directory << endl;
221
222   for(unsigned int i=0 ; i<prt.ComponentsList.size() ; i++)
223     os << "Component " << i+1 << " called: " << prt.ComponentsList[i] << endl;
224
225   list<ParserResourcesType>::const_iterator it;
226   for(it = prt.ClusterMembersList.begin() ; it != prt.ClusterMembersList.end() ; it++)
227   {
228     os << "Cluster member called: " << (*it).HostName << endl;
229   }
230   return os;
231 }
232
233 std::string
234 ParserResourcesType::getAccessProtocolTypeStr() const
235 {
236   return protocolToString(Protocol);
237 }
238
239 std::string
240 ParserResourcesType::getClusterInternalProtocolStr() const
241 {
242   return protocolToString(ClusterInternalProtocol);
243 }
244
245 std::string 
246 ParserResourcesType::getResourceTypeStr() const
247 {
248   switch (type)
249   {
250   case cluster:
251     return "cluster";
252   case single_machine:
253     return "single_machine";
254   default:
255     throw ResourcesException("Unknown resource type");
256   }
257 }
258
259 std::string 
260 ParserResourcesType::getBatchTypeStr() const
261 {
262   switch (Batch)
263   {
264   case none:
265     return "none";
266   case pbs:
267     return "pbs";
268   case lsf:
269     return "lsf";
270   case sge:
271     return "sge";
272   case ccc:
273     return "ccc";
274   case slurm:
275     return "slurm";
276   case ll:
277     return "ll";
278   case vishnu:
279     return "vishnu";
280   case oar:
281     return "oar";
282   case coorm:
283     return "coorm";
284   default:
285     throw ResourcesException("Unknown batch type");
286   }
287 }
288
289 std::string 
290 ParserResourcesType::getMpiImplTypeStr() const
291 {
292   switch (mpi)
293   {
294   case nompi:
295     return "no mpi";
296   case lam:
297     return "lam";
298   case mpich1:
299     return "mpich1";
300   case mpich2:
301     return "mpich2";
302   case openmpi:
303     return "openmpi";
304   case ompi:
305     return "ompi";
306   case slurmmpi:
307     return "slurmmpi";
308   case prun:
309     return "prun";
310   default:
311     throw ResourcesException("Unknown MPI implementation type");
312   }
313 }
314
315 string ParserResourcesType::getCanLaunchBatchJobsStr() const
316 {
317   return can_launch_batch_jobs ? "true" : "false";
318 }
319
320 string ParserResourcesType::getCanRunContainersStr() const
321 {
322   return can_run_containers ? "true" : "false";
323 }
324
325 void ParserResourcesType::setAccessProtocolTypeStr(const string & protocolTypeStr)
326 {
327   Protocol = stringToProtocol(protocolTypeStr);
328 }
329
330 void ParserResourcesType::setResourceTypeStr(const string & resourceTypeStr)
331 {
332   if (resourceTypeStr == "cluster")
333     type = cluster;
334   else if (resourceTypeStr == "single_machine")
335     type = single_machine;
336   else
337     throw ResourcesException((string("Unknown resource type ") + resourceTypeStr).c_str());
338 }
339
340 void ParserResourcesType::setBatchTypeStr(const string & batchTypeStr)
341 {
342   if (batchTypeStr == "pbs")
343     Batch = pbs;
344   else if (batchTypeStr == "lsf")
345     Batch = lsf;
346   else if (batchTypeStr == "sge")
347     Batch = sge;
348   else if (batchTypeStr == "slurm")
349     Batch = slurm;
350   else if (batchTypeStr == "ccc")
351     Batch = ccc;
352   else if (batchTypeStr == "ll")
353     Batch = ll;
354   else if (batchTypeStr == "vishnu")
355     Batch = vishnu;
356   else if (batchTypeStr == "oar")
357     Batch = oar;
358   else if (batchTypeStr == "coorm")
359     Batch = coorm;
360   else if (batchTypeStr == "" || batchTypeStr == "none" || batchTypeStr == "ssh_batch")
361     Batch = none;
362   else
363     throw ResourcesException((string("Unknown batch type ") + batchTypeStr).c_str());
364 }
365
366 void ParserResourcesType::setMpiImplTypeStr(const string & mpiImplTypeStr)
367 {
368   if (mpiImplTypeStr == "lam")
369     mpi = lam;
370   else if (mpiImplTypeStr == "mpich1")
371     mpi = mpich1;
372   else if (mpiImplTypeStr == "mpich2")
373     mpi = mpich2;
374   else if (mpiImplTypeStr == "openmpi")
375     mpi = openmpi;
376   else if (mpiImplTypeStr == "ompi")
377     mpi = ompi;
378   else if (mpiImplTypeStr == "slurmmpi")
379     mpi = slurmmpi;
380   else if (mpiImplTypeStr == "prun")
381     mpi = prun;
382   else if (mpiImplTypeStr == "" || mpiImplTypeStr == "no mpi")
383     mpi = nompi;
384   else
385     throw ResourcesException((string("Unknown MPI implementation type ") + mpiImplTypeStr).c_str());
386 }
387
388 void ParserResourcesType::setClusterInternalProtocolStr(const string & internalProtocolTypeStr)
389 {
390   ClusterInternalProtocol = stringToProtocol(internalProtocolTypeStr);
391 }
392
393 void ParserResourcesType::setCanLaunchBatchJobsStr(const string & canLaunchBatchJobsStr)
394 {
395   if (canLaunchBatchJobsStr == "true")
396     can_launch_batch_jobs = true;
397   else if (canLaunchBatchJobsStr == "false")
398     can_launch_batch_jobs = false;
399   else
400     throw ResourcesException((string("Invalid boolean value for can_launch_batch_jobs: ") +
401                             canLaunchBatchJobsStr).c_str());
402 }
403
404 void ParserResourcesType::setCanRunContainersStr(const string & canRunContainersStr)
405 {
406   if (canRunContainersStr == "true")
407     can_run_containers = true;
408   else if (canRunContainersStr == "false")
409     can_run_containers = false;
410   else
411     throw ResourcesException((string("Invalid boolean value for can_run_containers: ") +
412                             canRunContainersStr).c_str());
413 }