1
2 """Things that are needed for convenient parallel Execution"""
3
4 from PyFoam.Basics.Utilities import Utilities
5 from PyFoam.FoamInformation import foamMPI
6 from PyFoam.Error import error,warning,debug
7 from PyFoam import configuration as config
8
9 from os import path
10 from string import strip
11
13 """Wrapper class for starting an stopping a LAM-Machine"""
14 - def __init__(self,machines=None,nr=None):
15 """@param machines: Name of the file with the machine information
16 @param nr: Number of processes"""
17
18 Utilities.__init__(self)
19
20 self.stop()
21
22 if machines=="":
23 machines=None
24
25 if machines==None and foamMPI()=="LAM":
26 error("Machinefile must be specified for LAM")
27
28 if machines==None and nr==None:
29 error("Either machinefile or Nr of CPUs must be specified for MPI type",foamMPI())
30
31 self.mFile=machines
32 self.procNr=nr
33
34 self.boot()
35 if not self.machineOK():
36 error("Error: LAM was not started")
37
39 """Check whether the LAM machine was properly booted"""
40 if self.running:
41 if(foamMPI()=="LAM"):
42 if self.cpuNr()<=0:
43 self.running=False
44
45 return self.running
46
48 """Stops a LAM-machine (if one is running)"""
49 self.running=False
50 if(foamMPI()=="LAM"):
51 self.execute("lamhalt -v")
52
54 """Boots a LAM-machine using the machine-file"""
55 if(foamMPI()=="LAM"):
56 warning("LAM is untested. Any Feedback most welcome")
57 self.execute("lamboot -s -v "+self.mFile)
58 self.running=True
59 elif(foamMPI()=="OPENMPI"):
60 self.running=True
61 else:
62 error(" Unknown or missing MPI-Implementation: "+foamMPI())
63
65 if(foamMPI()=="LAM"):
66 if self.running:
67 lines=self.execute("lamnodes")
68 nr=0
69 for l in lines:
70 tmp=l.split(':')
71 if len(tmp)>1:
72 nr+=int(tmp[1])
73 return nr
74 else:
75 return -1
76 elif(foamMPI()=="OPENMPI"):
77 if self.mFile:
78 f=open(self.mFile)
79 l=map(strip,f.readlines())
80 f.close()
81 nr=0
82 for m in l:
83 tmp=m.split()
84 if len(tmp)==1:
85 nr+=1
86 elif len(tmp)==0:
87 pass
88 else:
89 error("Machinefile not valid (I think): more than one element in one line:"+str(tmp))
90
91 if self.procNr==None:
92 return nr
93 else:
94 return min(nr,self.procNr)
95
96 elif self.procNr:
97 return self.procNr
98 else:
99 error("Can't determine Nr of CPUs without machinefile")
100
102 """Builds a list with a working mpirun command (for that MPI-Implementation)
103 @param argv: the original arguments that are to be wrapped
104 @return: list with the correct mpirun-command"""
105
106 nr=str(self.cpuNr())
107 mpirun=[config().get("MPI","run_"+foamMPI(),default="mpirun")]
108
109 mpirun+=eval(config().get("MPI","options_"+foamMPI()+"_pre",default="[]"))
110
111 if(foamMPI()=="LAM"):
112 mpirun+=["-np",nr]
113 elif(foamMPI()=="OPENMPI"):
114 nr=[]
115 if self.procNr!=None:
116 nr=["-np",str(self.procNr)]
117 machine=[]
118 if self.mFile!=None:
119 machine=["-machinefile",self.mFile]
120 mpirun+=nr+machine
121 else:
122 error(" Unknown or missing MPI-Implementation for mpirun: "+foamMPI())
123
124 mpirun+=eval(config().get("MPI","options_"+foamMPI()+"_post",default="[]"))
125
126 mpirun+=argv[0:3]+["-parallel"]+argv[3:]
127
128 if config().getdebug("ParallelExecution"):
129 debug("Arguments:",mpirun)
130
131 return mpirun
132
134 """Write the parameter-File for a metis decomposition
135 @param sDir: Solution directory
136 @type sDir: PyFoam.RunDictionary.SolutionDirectory"""
137
138 params="method metis;\n"
139
140 self.writeDecomposition(sDir,params)
141
143 """Write the parameter-File for a metis decomposition
144 @param sDir: Solution directory
145 @type sDir: PyFoam.RunDictionary.SolutionDirectory
146 @param direction: direction in which to decompose (0=x, 1=y, 2=z)"""
147
148 params ="method simple;\n"
149 params+="\nsimpleCoeffs\n{\n\t n \t ("
150 if direction==0:
151 params+=str(self.cpuNr())+" "
152 else:
153 params+="1 "
154 if direction==1:
155 params+=str(self.cpuNr())+" "
156 else:
157 params+="1 "
158 if direction==2:
159 params+=str(self.cpuNr())
160 else:
161 params+="1"
162 params+=");\n\t delta \t 0.001;\n}\n"
163
164 self.writeDecomposition(sDir,params)
165
167 """Write parameter file for a decomposition
168 @param par:Parameters specific for that kind of decomposition
169 @type par:str
170 @param sDir: Solution directory
171 @type sDir: PyFoam.RunDictionary.SolutionDirectory"""
172
173 f=open(path.join(sDir.systemDir(),"decomposeParDict"),"w")
174 self.writeDictionaryHeader(f)
175 f.write("// * * * * * * * * * //\n\n")
176 f.write("numberOfSubdomains "+str(self.cpuNr())+";\n\n")
177 f.write(par)
178 f.write("\n\n// * * * * * * * * * //")
179 f.close()
180