Salome HOME
Integrate developments from N. Toukourou at INRIA (OAR and CooRM support)
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Parser.cxx
1 // Copyright (C) 2007-2013  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.
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 "Utils_SALOME_Exception.hxx"
25 #include <iostream>
26 #include <sstream>
27
28 using namespace std;
29
30 #define NULL_VALUE 0
31
32 unsigned int ResourceDataToSort::_nbOfProcWanted = NULL_VALUE;
33 unsigned int ResourceDataToSort::_nbOfNodesWanted = NULL_VALUE;
34 unsigned int ResourceDataToSort::_nbOfProcPerNodeWanted = NULL_VALUE;
35 unsigned int ResourceDataToSort::_CPUFreqMHzWanted = NULL_VALUE;
36 unsigned int ResourceDataToSort::_memInMBWanted = NULL_VALUE;
37
38 ResourceDataToSort::ResourceDataToSort()
39 {}
40
41 ResourceDataToSort::ResourceDataToSort(const std::string& name,
42                                        unsigned int nbOfNodes,
43                                        unsigned int nbOfProcPerNode,
44                                        unsigned int CPUFreqMHz,
45                                        unsigned int memInMB):
46     _Name(name),
47     _nbOfNodes(nbOfNodes),
48     _nbOfProcPerNode(nbOfProcPerNode),
49     _CPUFreqMHz(CPUFreqMHz),
50     _memInMB(memInMB)
51 {}
52
53 //! Method used by list::sort to sort the resources used in SALOME_ResourcesManager::GetResourcesFitting
54 bool ResourceDataToSort::operator< (const ResourceDataToSort& other) const
55   {
56     unsigned int nbPts = GetNumberOfPoints();
57     return nbPts < other.GetNumberOfPoints();
58   }
59
60 unsigned int ResourceDataToSort::GetNumberOfPoints() const
61   {
62     unsigned int ret = 0;
63     //priority 0 : Nb of proc
64
65     if (_nbOfProcWanted != NULL_VALUE)
66       {
67         unsigned int nb_proc = _nbOfNodes * _nbOfProcPerNode;
68         if (nb_proc == _nbOfProcWanted)
69           ret += 30000;
70         else if (nb_proc > _nbOfProcWanted)
71           ret += 20000;
72         else
73           ret += 10000;
74       }
75
76     //priority 1 : Nb of nodes
77
78     if (_nbOfNodesWanted != NULL_VALUE)
79       {
80         if (_nbOfNodes == _nbOfNodesWanted)
81           ret += 3000;
82         else if (_nbOfNodes > _nbOfNodesWanted)
83           ret += 2000;
84         else
85           ret += 1000;
86       }
87
88     //priority 2 : Nb of proc by node
89     if (_nbOfProcPerNodeWanted != NULL_VALUE)
90       {
91         if (_nbOfProcPerNode == _nbOfProcPerNodeWanted)
92           ret += 300;
93         else if (_nbOfProcPerNode > _nbOfProcPerNodeWanted)
94           ret += 200;
95         else
96           ret += 100;
97       }
98
99     //priority 3 : Cpu freq
100     if (_CPUFreqMHzWanted != NULL_VALUE)
101       {
102         if (_CPUFreqMHz == _CPUFreqMHzWanted)
103           ret += 30;
104         else if (_CPUFreqMHz > _CPUFreqMHzWanted)
105           ret += 20;
106         else
107           ret += 10;
108       }
109
110     //priority 4 : memory
111     if (_memInMBWanted != NULL_VALUE)
112       {
113         if (_memInMB == _memInMBWanted)
114           ret += 3;
115         else if (_memInMB > _memInMBWanted)
116           ret += 2;
117         else
118           ret += 1;
119       }
120
121     //RES_MESSAGE("[GetNumberOfPoints] points number for resource: " << _Name << " " << ret);
122     return ret;
123   }
124
125 //! Method used for debug
126 void ResourceDataToSort::Print() const
127   {
128     std::cout << _nbOfNodes << std::endl;
129     std::cout << _nbOfProcPerNode << std::endl;
130     std::cout << _CPUFreqMHz << std::endl;
131     std::cout << _memInMB << std::endl;
132   }
133
134
135 ParserResourcesType::ParserResourcesType()
136 : type(single_machine),
137   Protocol(ssh),
138   ClusterInternalProtocol(ssh),
139   Batch(none),
140   mpi(nompi),
141   nbOfProc(1),
142   can_launch_batch_jobs(false),
143   can_run_containers(false)
144 {
145   DataForSort._Name = "";
146   DataForSort._nbOfNodes = 1;
147   DataForSort._nbOfProcPerNode = 1;
148   DataForSort._CPUFreqMHz = 0;
149   DataForSort._memInMB = 0;
150 }
151
152 ParserResourcesType::~ParserResourcesType()
153 {
154 }
155
156 std::string ParserResourcesType::protocolToString(AccessProtocolType protocol)
157 {
158   switch (protocol)
159   {
160   case sh:
161     return "sh";
162   case rsh:
163     return "rsh";
164   case ssh:
165     return "ssh";
166   case srun:
167     return "srun";
168   case pbsdsh:
169     return "pbsdsh";
170   case blaunch:
171     return "blaunch";
172   default:
173     throw SALOME_Exception("Unknown protocol");
174   }
175 }
176
177 AccessProtocolType ParserResourcesType::stringToProtocol(const std::string & protocolStr)
178 {
179   if (protocolStr == "sh")
180     return sh;
181   else if (protocolStr == "rsh")
182     return rsh;
183   else if (protocolStr == "ssh")
184     return ssh;
185   else if (protocolStr == "srun")
186     return srun;
187   else if (protocolStr == "pbsdsh")
188     return pbsdsh;
189   else if (protocolStr == "blaunch")
190     return blaunch;
191   else
192     throw SALOME_Exception((string("Unknown protocol ") + protocolStr).c_str());
193 }
194
195 ostream & operator<<(ostream &os, const ParserResourcesType &prt)
196 {
197   os << "Name: " << prt.Name << endl <<
198         "HostName: " << prt.HostName << endl <<
199         "Type: " << prt.getResourceTypeStr() << endl <<
200         "NbOfNodes: " << prt.DataForSort._nbOfNodes << endl <<
201         "NbOfProcPerNode: " << prt.DataForSort._nbOfProcPerNode << endl <<
202         "CPUFreqMHz: " << prt.DataForSort._CPUFreqMHz << endl <<
203         "MemInMB: " << prt.DataForSort._memInMB << endl <<
204         "Protocol: " << prt.getAccessProtocolTypeStr() << endl <<
205         "ClusterInternalProtocol: " << prt.getClusterInternalProtocolStr() << endl <<
206         "Batch: " << prt.getBatchTypeStr() << endl <<
207         "mpi: " << prt.getMpiImplTypeStr() << endl <<
208         "UserName: " << prt.UserName << endl <<
209         "AppliPath: " << prt.AppliPath << endl <<
210         "OS: " << prt.OS << endl <<
211         "batchQueue: " << prt.batchQueue << endl <<
212         "userCommands: " << prt.userCommands << endl <<
213         "use: " << prt.use << endl <<
214         "NbOfProc: " << prt.nbOfProc << endl <<
215         "Can Launch Batch Jobs: " << prt.can_launch_batch_jobs << endl <<
216         "Can Run Containers: " << prt.can_run_containers << endl <<
217         "Working Directory: " << prt.working_directory << endl;
218
219   for(unsigned int i=0 ; i<prt.ComponentsList.size() ; i++)
220     os << "Component " << i+1 << " called: " << prt.ComponentsList[i] << endl;
221
222   list<ParserResourcesType>::const_iterator it;
223   for(it = prt.ClusterMembersList.begin() ; it != prt.ClusterMembersList.end() ; it++)
224   {
225     os << "Cluster member called: " << (*it).HostName << endl;
226   }
227   return os;
228 }
229
230 std::string
231 ParserResourcesType::getAccessProtocolTypeStr() const
232 {
233   return protocolToString(Protocol);
234 }
235
236 std::string
237 ParserResourcesType::getClusterInternalProtocolStr() const
238 {
239   return protocolToString(ClusterInternalProtocol);
240 }
241
242 std::string 
243 ParserResourcesType::getResourceTypeStr() const
244 {
245   switch (type)
246   {
247   case cluster:
248     return "cluster";
249   case single_machine:
250     return "single_machine";
251   default:
252     throw SALOME_Exception("Unknown resource type");
253   }
254 }
255
256 std::string 
257 ParserResourcesType::getBatchTypeStr() const
258 {
259   switch (Batch)
260   {
261   case none:
262     return "none";
263   case pbs:
264     return "pbs";
265   case lsf:
266     return "lsf";
267   case sge:
268     return "sge";
269   case ccc:
270     return "ccc";
271   case slurm:
272     return "slurm";
273   case ll:
274     return "ll";
275   case vishnu:
276     return "vishnu";
277   case oar:
278     return "oar";
279   case coorm:
280     return "coorm";
281   case ssh_batch:
282     return "ssh_batch";
283   default:
284     throw SALOME_Exception("Unknown batch type");
285   }
286 }
287
288 std::string 
289 ParserResourcesType::getMpiImplTypeStr() const
290 {
291   switch (mpi)
292   {
293   case nompi:
294     return "no mpi";
295   case lam:
296     return "lam";
297   case mpich1:
298     return "mpich1";
299   case mpich2:
300     return "mpich2";
301   case openmpi:
302     return "openmpi";
303   case ompi:
304     return "ompi";
305   case slurmmpi:
306     return "slurmmpi";
307   case prun:
308     return "prun";
309   default:
310     throw SALOME_Exception("Unknown MPI implementation type");
311   }
312 }
313
314 string ParserResourcesType::getCanLaunchBatchJobsStr() const
315 {
316   return can_launch_batch_jobs ? "true" : "false";
317 }
318
319 string ParserResourcesType::getCanRunContainersStr() const
320 {
321   return can_run_containers ? "true" : "false";
322 }
323
324 void ParserResourcesType::setAccessProtocolTypeStr(const string & protocolTypeStr)
325 {
326   Protocol = stringToProtocol(protocolTypeStr);
327 }
328
329 void ParserResourcesType::setResourceTypeStr(const string & resourceTypeStr)
330 {
331   if (resourceTypeStr == "cluster")
332     type = cluster;
333   else if (resourceTypeStr == "single_machine")
334     type = single_machine;
335   else
336     throw SALOME_Exception((string("Unknown resource type ") + resourceTypeStr).c_str());
337 }
338
339 void ParserResourcesType::setBatchTypeStr(const string & batchTypeStr)
340 {
341   if (batchTypeStr == "pbs")
342     Batch = pbs;
343   else if (batchTypeStr == "lsf")
344     Batch = lsf;
345   else if (batchTypeStr == "sge")
346     Batch = sge;
347   else if (batchTypeStr == "slurm")
348     Batch = slurm;
349   else if (batchTypeStr == "ccc")
350     Batch = ccc;
351   else if (batchTypeStr == "ssh_batch")
352     Batch = ssh_batch;
353   else if (batchTypeStr == "ll")
354     Batch = ll;
355   else if (batchTypeStr == "vishnu")
356     Batch = vishnu;
357   else if (batchTypeStr == "oar")
358     Batch = oar;
359   else if (batchTypeStr == "coorm")
360     Batch = coorm;
361   else if (batchTypeStr == "")
362     Batch = none;
363   else
364     throw SALOME_Exception((string("Unknown batch type ") + batchTypeStr).c_str());
365 }
366
367 void ParserResourcesType::setMpiImplTypeStr(const string & mpiImplTypeStr)
368 {
369   if (mpiImplTypeStr == "lam")
370     mpi = lam;
371   else if (mpiImplTypeStr == "mpich1")
372     mpi = mpich1;
373   else if (mpiImplTypeStr == "mpich2")
374     mpi = mpich2;
375   else if (mpiImplTypeStr == "openmpi")
376     mpi = openmpi;
377   else if (mpiImplTypeStr == "ompi")
378     mpi = ompi;
379   else if (mpiImplTypeStr == "slurmmpi")
380     mpi = slurmmpi;
381   else if (mpiImplTypeStr == "prun")
382     mpi = prun;
383   else if (mpiImplTypeStr == "" || mpiImplTypeStr == "no mpi")
384     mpi = nompi;
385   else
386     throw SALOME_Exception((string("Unknown MPI implementation type ") + mpiImplTypeStr).c_str());
387 }
388
389 void ParserResourcesType::setClusterInternalProtocolStr(const string & internalProtocolTypeStr)
390 {
391   ClusterInternalProtocol = stringToProtocol(internalProtocolTypeStr);
392 }
393
394 void ParserResourcesType::setCanLaunchBatchJobsStr(const string & canLaunchBatchJobsStr)
395 {
396   if (canLaunchBatchJobsStr == "true")
397     can_launch_batch_jobs = true;
398   else if (canLaunchBatchJobsStr == "false")
399     can_launch_batch_jobs = false;
400   else
401     throw SALOME_Exception((string("Invalid boolean value for can_launch_batch_jobs: ") +
402                             canLaunchBatchJobsStr).c_str());
403 }
404
405 void ParserResourcesType::setCanRunContainersStr(const string & canRunContainersStr)
406 {
407   if (canRunContainersStr == "true")
408     can_run_containers = true;
409   else if (canRunContainersStr == "false")
410     can_run_containers = false;
411   else
412     throw SALOME_Exception((string("Invalid boolean value for can_run_containers: ") +
413                             canRunContainersStr).c_str());
414 }