/[escript]/trunk/ripley/generators/lamebuilder.py
ViewVC logotype

Contents of /trunk/ripley/generators/lamebuilder.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6939 - (show annotations)
Mon Jan 20 03:37:18 2020 UTC (4 months, 1 week ago) by uqaeller
File MIME type: text/x-python
File size: 13359 byte(s)
Updated the copyright header.


1
2 ##############################################################################
3 #
4 # Copyright (c) 2003-2020 by The University of Queensland
5 # http://www.uq.edu.au
6 #
7 # Primary Business: Queensland, Australia
8 # Licensed under the Apache License, version 2.0
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Development until 2012 by Earth Systems Science Computational Center (ESSCC)
12 # Development 2012-2013 by School of Earth Sciences
13 # Development from 2014 by Centre for Geoscience Computing (GeoComp)
14 # Development from 2019 by School of Earth and Environmental Sciences
15 #
16 ##############################################################################
17
18 from __future__ import print_function, division
19
20 import lamesource
21 import sys
22
23 def buildTempAndSummation(dim, ids, temps, summations, forced_substitutions = []):
24 declarations = {}
25 sumStatements = {}
26 for k in range(dim):
27 for m in range(dim):
28 declarations[(k,m)] = []
29 sumStatements[(k,m)] = []
30 zeroes = [] #tracks tmpvars that will always be zero
31 nonzeroes = [] #tracks tmpvars that will possibly be non-zero
32 use_counts = {} #tmp var usage counts, used later for culling
33 #temp declarations
34 #hold on to the building expression for every identifier
35 var_expressions = {}
36 for line in temps:
37 newline = line.format(k,m)
38 insert = False
39 for index in ids.iterkeys():
40 if index in newline:
41 insert = True
42 break
43 if not insert:
44 value = newline.split("=")[1]
45 for tmp in nonzeroes:
46 if tmp in value:
47 x = use_counts.get(tmp, 0)
48 use_counts[tmp] = x+1
49 insert = True
50 i = newline.index("tmp")
51 identifier = newline[i:].split()[0]
52 expression = newline.split("= ")[1][:-1]
53 if insert:
54 nonzeroes.append(identifier)
55 var_expressions[identifier] = expression
56 else:
57 zeroes.append(identifier)
58 #summations
59 with_nonzero = [] #only those with some non-zero temp var
60 for line in summations:
61 newline = replaceZeroes(line.format(k,m),zeroes)
62 for nz in nonzeroes:
63 if nz in newline:
64 with_nonzero.append(newline)
65 components = newline[:-1].split("+=")[1].lstrip().replace(" + ", "|").replace(" - ", "|")
66 if components[0] == "-":
67 components = components[1:]
68 components = components.split("|")
69 for var in components:
70 x = use_counts.get(var, 0)
71 use_counts[var] = x+1
72 break
73 for fs in forced_substitutions:
74 if fs in nonzeroes:
75 use_counts[fs] = 1
76 for z in zeroes:
77 use_counts[z] = 0
78 #only interested in keeping variables declarations with 2 or more uses
79 for var in nonzeroes:
80 #0 we don't care and 1 we substitute the expression
81 if use_counts.get(var, 0) > 1:
82 declarations[(k,m)].append(" const double %s = %s;"%(var, var_expressions[var]))
83 #remove zeroes and replace single use tmpvars with their expression
84 for line in with_nonzero:
85 for key in use_counts.iterkeys():
86 if use_counts[key] == 0:
87 line = line.replace("%s;"%key, ";")
88 line = line.replace("%s "%key, " ")
89 elif use_counts[key] < 2:
90 s = var_expressions[key]
91 line = line.replace("%s;"%key, s+";")
92 line = line.replace("%s "%key, s+" ")
93 #print only if there's a right-hand-side of the expression
94 if "+=;" not in line and "+=;" not in line:
95 sumStatements[(k,m)].append(" "+line)
96 return declarations, sumStatements
97
98 def replaceZeroes(line, zeroes):
99 for zero in zeroes:
100 if zero+"|" in line:
101 line = line.replace(" + %s|"%zero, "")
102 line = line.replace("%s| + "%zero, "0 + ") #there's a better solution
103 line = line.replace(" - %s|"%zero, "") #it's just to stop
104 line = line.replace("%s| - "%zero, "0 - ") # a - b -> b instead of -b
105 line = line.replace("=%s|;"%zero,"=;")
106 if line:
107 return line.replace("|","").replace(" - 0", "").replace(" + 0", "").replace("+= 0 +", "+=").replace("+= 0 - ", "+=-")
108 return line
109
110 def print2DAExpanded():
111 dim = 2
112 quads = 2**dim
113 ids = {}
114 for i in range(dim):
115 for j in range(dim):
116 ids["{0}{0}{1}{1}".format(i,j)] = None
117 ids["{0}{1}{1}{0}".format(i,j)] = None
118 ids["{0}{1}{0}{1}".format(i,j)] = None
119
120 for name in sorted(ids.iterkeys()):
121 print("double A_{0}[{1}] =".format(name,quads), "{0};")
122 # ijji += mu
123 # ijij += mu
124 # iijj += lambda
125 print("if (!mu.isEmpty()) {\n const double *mu_p = mu.getSampleDataRO(e);")
126 completed = {}
127 for i in range(dim):
128 for j in range(dim):
129 for q in range(quads):
130 if i == j:
131 print(" A_{0}{0}{0}{0}[{1}] += 2*mu_p[{1}];".format(i,q))
132 else:
133 print(" A_{0}{1}{1}{0}[{2}] += mu_p[{2}];".format(i,j,q))
134 print(" A_{0}{1}{0}{1}[{2}] += mu_p[{2}];".format(i,j,q))
135 print("}\nif (!lambda.isEmpty()) {\n const double *lambda_p = lambda.getSampleDataRO(e);")
136 for i in range(dim):
137 for j in range(dim):
138 for q in range(quads):
139 print(" A_{0}{0}{1}{1}[{2}] += lambda_p[{2}];".format(i,j,q))
140 print("}")
141
142 decl, sums = buildTempAndSummation(dim, ids, lamesource.expanded2Dtemps, lamesource.expanded2Dsummations)
143 for k in range(dim):
144 for m in range(dim):
145 print("{")
146 print("\n".join(decl[(k,m)]))
147 print("\n".join(sums[(k,m)]))
148 print("}")
149
150 def print2DAReduced():
151 dim = 2
152 quads = 2**dim
153 ids = {}
154 for i in range(dim):
155 for j in range(dim):
156 ids["{0}{0}{1}{1}".format(i,j)] = None
157 ids["{0}{1}{1}{0}".format(i,j)] = None
158 ids["{0}{1}{0}{1}".format(i,j)] = None
159
160 for name in sorted(ids.iterkeys()):
161 print("double A_{0} =".format(name,quads), "0;")
162 # ijji += mu
163 # ijij += mu
164 # iijj += lambda
165
166 print("if (!mu.isEmpty()) {\n const double *mu_p = mu.getSampleDataRO(e);")
167
168 for i in range(dim):
169 for j in range(dim):
170 if i == j:
171 print(" A_{0}{0}{0}{0} += 2*mu_p[0];".format(i))
172 else:
173 print(" A_{0}{1}{1}{0} += mu_p[0];".format(i,j))
174 print(" A_{0}{1}{0}{1} += mu_p[0];".format(i,j))
175 print("}")
176 print("if (!lambda.isEmpty()) {\n const double *lambda_p = lambda.getSampleDataRO(e);")
177 for i in range(dim):
178 for j in range(dim):
179 print(" A_{0}{0}{1}{1} += lambda_p[0];".format(i,j))
180 print("}")
181
182 lines = [
183 "const double tmp_0 = 6*w1*(A_{0}0{1}1 - A_{0}1{1}0);",
184 "const double tmp_1 = 6*w1*(A_{0}0{1}1 + A_{0}1{1}0);",
185 "const double tmp_2 = 6*w1*(-A_{0}0{1}1 - A_{0}1{1}0);",
186 "const double tmp_3 = 6*w1*(-A_{0}0{1}1 + A_{0}1{1}0);"
187 ]
188
189 zeroes = []
190 nonzeroes = []
191 for k in range(dim):
192 for m in range(dim):
193 if k == m:
194 for q in range(quads):
195 zeroes.append("tmp{0}{0}_{1}".format(m, q))
196 continue
197 for line in lines:
198 newline = line.format(k,m)
199 insert = False
200 for index in ids.iterkeys():
201 if index in newline:
202 insert = True
203 break
204 i = newline.index("tmp")
205 if insert:
206 print(newline)
207 nonzeroes.append(newline[i:].split()[0].rstrip())
208 else:
209 zeroes.append(newline[i:].split()[0].rstrip())
210
211 for k in range(dim):
212 for m in range(dim):
213 for line in lamesource.reduced2Dsummations:
214 newline = replaceZeroes(line.format(k,m),zeroes)
215 if not newline:
216 continue
217 if k != m:
218 st = "A_{0}0{1}0".format(k,m)
219 if st in newline:
220 i = newline.index(st)
221 newline = newline[:i-3] + newline[i+12:]
222 st = "A_{0}1{1}1".format(k,m)
223 if st in newline:
224 i = newline.index(st)
225 newline = newline[:i-2] + newline[i+11:]
226 print(newline)
227
228 def print3DAExpanded():
229 dim = 3
230 quads = 2**dim
231 ids = {}
232 for i in range(dim):
233 for j in range(dim):
234 ids["{0}{0}{1}{1}".format(i,j)] = None
235 ids["{0}{1}{1}{0}".format(i,j)] = None
236 ids["{0}{1}{0}{1}".format(i,j)] = None
237
238 for name in sorted(ids.iterkeys()):
239 print("double A_{0}[{1}] =".format(name,quads), "{0};")
240 # ijji += mu
241 # ijij += mu
242 # iijj += lambda
243 print("if (!mu.isEmpty()) {\n const double *mu_p = mu.getSampleDataRO(e);")
244 for i in range(dim):
245 for j in range(dim):
246 for q in range(quads):
247 if i == j:
248 print(" A_{0}{0}{0}{0}[{1}] += 2*mu_p[{1}];".format(i,q))
249 else:
250 print(" A_{0}{1}{1}{0}[{2}] += mu_p[{2}];".format(i,j,q))
251 print(" A_{0}{1}{0}{1}[{2}] += mu_p[{2}];".format(i,j,q))
252 print("}")
253 print("if (!lambda.isEmpty()) {\n const double *lambda_p = lambda.getSampleDataRO(e);")
254 for i in range(dim):
255 for j in range(dim):
256 for q in range(quads):
257 print(" A_{0}{0}{1}{1}[{2}] += lambda_p[{2}];".format(i,j,q))
258 print("}")
259
260 decl, sums = buildTempAndSummation(dim, ids, lamesource.expanded3Dtemps, lamesource.expanded3Dsummations)
261 for k in range(dim):
262 for m in range(dim):
263 print("{")
264 print("\n".join(decl[(k,m)]))
265 print("\n".join(sums[(k,m)]))
266 print("}")
267
268 def print3DAReduced():
269 dim = 3
270 ids = {}
271 for i in range(dim):
272 for j in range(dim):
273 ids["{0}{0}{1}{1}".format(i,j)] = None
274 ids["{0}{1}{1}{0}".format(i,j)] = None
275 ids["{0}{1}{0}{1}".format(i,j)] = None
276
277 for i in sorted(ids.iterkeys()):
278 print("double Aw%s = 0;"%i)
279
280 print("if (!mu.isEmpty()) {\n const double *mu_p = mu.getSampleDataRO(e);")
281 for i in range(dim):
282 for j in range(dim):
283 if i == j:
284 print(" Aw{0}{0}{0}{0} += 2*mu_p[0];".format(i))
285 else:
286 print(" Aw{0}{1}{1}{0} += mu_p[0];".format(i,j))
287 print(" Aw{0}{1}{0}{1} += mu_p[0];".format(i,j))
288
289 print("}\nif (!lambda.isEmpty()) {\n const double *lambda_p = lambda.getSampleDataRO(e);")
290 for i in range(dim):
291 for j in range(dim):
292 print(" Aw{0}{0}{1}{1} += lambda_p[0];".format(i,j))
293 print("}")
294
295 for k in range(dim):
296 for m in range(dim):
297 for line in ["Aw{0}0{1}0 *= 8*w27;","Aw{0}0{1}1 *= 12*w8;","Aw{0}0{1}2 *= 12*w11;",
298 "Aw{0}1{1}0 *= 12*w8;","Aw{0}1{1}1 *= 8*w22;","Aw{0}1{1}2 *= 12*w10;",
299 "Aw{0}2{1}0 *= 12*w11;","Aw{0}2{1}1 *= 12*w10;","Aw{0}2{1}2 *= 8*w13;"]:
300 newline = line.format(k,m)
301 found = False
302 for ident in ids.iterkeys():
303 if ident in newline:
304 found = True
305 break
306 if found:
307 print(newline)
308
309 decs, sums = buildTempAndSummation(dim, ids, lamesource.reduced3Dtemps,
310 lamesource.reduced3Dsummations,
311 forced_substitutions = ["tmp12","tmp13","tmp14","tmp21","tmp22","tmp23"])
312 for k in range(dim):
313 for m in range(dim):
314 print("{")
315 print("\n".join(decs[(k,m)]))
316 print("\n".join(sums[(k,m)]))
317 print("}")
318
319
320
321 def printAReduced(dim):
322 if dim == 2:
323 return print2DAReduced()
324 elif dim == 3:
325 return print3DAReduced()
326 else:
327 raise
328
329 def printAExpanded(dim):
330 if dim == 2:
331 return print2DAExpanded()
332 elif dim == 3:
333 return print3DAExpanded()
334 else:
335 raise
336
337 if __name__ == "__main__":
338 if len(sys.argv) < 3 or sys.argv[1] not in ["R", "E"] or sys.argv[2] not in ["2","3"]:
339 print("Usage: {0} [R]educed/[E]xpanded dimensions\nE.g. {0} R 3")
340 exit(1)
341 dim = int(sys.argv[2])
342 if sys.argv[1] == "R":
343 printAReduced(dim)
344 else:
345 printAExpanded(dim)
346

  ViewVC Help
Powered by ViewVC 1.1.26