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