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