b7535906317b8c825d2b9e85ff2eb8a6b642f75d
[matches/honours.git] / course / semester2 / pprog / assignment1 / get_data.py
1 #!/usr/bin/python -u
2
3 # @file get_data.py
4 # @purpose Extract statistics from repeated runs of N-Body simulators and graph them
5 # @author Sam Moore (20503628) - 2012
6 # Not documented very well, because it's not part of the task requirements
7 # Mostly to get a different graph I just comment out a lot of lines and uncomment others. Well designed.
8
9 import sys
10 import os
11 import subprocess
12 import odict
13
14 import Gnuplot, Gnuplot.funcutils
15 plot = Gnuplot.Gnuplot(persist=0)
16
17 programs = odict.odict([("single-thread" , "./single-thread/nbody -g")])
18
19 for n in range(4, 5, 1):
20         programs.update({"mthread"+str(n) : "./mthread/nbody -g -n "+str(n)})
21         programs.update({"openmp"+str(n) : "./openmp/nbody -g -n " +str(n)})
22         for theta in [0.1, 1.0, 10.0]:
23                 programs.update({"nbody-bh"+str(n)+":theta"+str(theta) : "./nbody-bh/nbody -g -n "+str(n)+" --theta " + str(theta)})
24
25
26
27
28
29 def RunProgram(string):
30         p = subprocess.Popen(string.split(" "), stdout=subprocess.PIPE)
31         results = []
32         for line in p.stdout:
33                 results.append(map(float, line.strip(" \r\n\t").split("\t")))
34         results.sort(key = lambda e : e[0])
35         return results
36
37 def RunForSteps(program, field, steps):
38         results = []
39         print(str(program) + " -s "+str(steps) + " -v 5 " + str(field))
40         results = RunProgram(str(program) + " -s "+str(steps) + " -v 5 " + str(field))
41         return results
42
43 def VaryField(program, steps, fields):
44         results = []
45         for f in fields:
46                 results.append(RunProgram(program + " -s " +str(steps) + " " + str(field)))
47         return results
48
49 def VaryTime(program, field, time_min, time_max, time_inc=10):
50         results = []
51         for t in range(time_min, time_max, time_inc):
52                 results.append(RunProgram(program + " -t "+str(t) + " " + str(field)))
53         return results
54
55 def main(argv):
56         plot("set xlabel \"steps\"")
57         plot("set ylabel \"real time (s)\"")
58         plot("set title \"Time .vs. Steps Computed\"")
59         plot("set key outside right")
60         data = {}
61         data.update(programs)
62
63         Plot_PerformanceN(data, 10, 1, 3000, 100)
64         
65         """
66         fields = map(int, os.listdir("fields"))
67         fields.sort(key = lambda e : e)
68         
69         ignore = [10, 100]
70         for n in fields:
71                 if n in ignore:
72                         continue
73                 for p in data.keys():
74                         #Plot_MeanErrors(programs["single-thread"], programs[p], "fields/"+str(n), 0, 100)
75                         data[p] = RunForSteps(programs[p], "fields/"+str(n), 200)
76                         #print(str(data[p]))
77
78                 #print(str(data.items()));
79                 for d in sorted(data.items(), key = lambda e : e[1][len(e[1])-1][1]):
80                         if (len(d[1]) > 0):
81                                 plot.replot(Gnuplot.Data(d[1], title=str(d[0])+":"+str(n), with_="lp")) #linecolor "+str(fields.index(n))))
82
83         #print(str(data.items()))
84         # Score the programs
85         
86         #for p in sorted(data.items(), key = lambda e : e[1][0][len(e[1][0])-1][1]):
87         #       print(str(p[0])+":"+str(n)+"\t"+str(p[1][0][len(p[1][0])-1][1]))
88         """
89         sys.stdin.readline()
90         return 0
91
92 def Plot_MeanErrors(control, program, field, sMin, sMax):
93         plot("set xlabel \"steps\"")
94         plot("set ylabel \"Error\"")
95         plot("set title \"Mean Position Error .vs. Steps\\n(Mean Error = Mean absolute error of all position components)\\nField: "+str(field)+"\"")
96         plot("set key outside right")
97         plot("set log y")
98         if (control == program):
99                 return
100         d = []
101         for s in range(sMin, sMax, (sMax - sMin) / 20):
102                 d.append([s, MeanError(control, program, field, s)])
103
104         plot.replot(Gnuplot.Data(d, title=str(program), with_="lp")) #linecolor "+str(fields.index(n))))
105         
106 def Plot_PerformanceN(d, steps, nMin, nMax, nStep):
107
108         plot("set xlabel \"N bodies\"")
109         plot("set ylabel \"Real Time (s)\"")
110         plot("set title \"Time taken to simulate N randomly generated bodies for 1000 steps\"")
111         plot("set key outside right")
112         for p in d.items():
113                 data = []
114                 for n in range(nMin, nMax, nStep):
115                         print("Run for " + str(n) + " bodies; " + str(p[1]))
116                         r = RunProgram(str(p[1]) + " -r " + str(n) + " -s " + str(steps))
117                         data.append([n, r[len(r)-1][1]])
118                 plot.replot(Gnuplot.Data(data, title=str(p[0]), with_="lp"))
119
120 def MeanError(programA, programB, field, steps):
121         print("Calculate error for "+str(steps) + " steps: " + str(programB) + " .vs. " + str(programA))
122         RunProgram(str(programA) + " -s "+str(steps) + " " + str(field) + " " + "A.tmp")
123         RunProgram(str(programB) + " -s "+str(steps) + " " + str(field) + " " + "B.tmp")
124
125         A = open("A.tmp", "r", 0)
126         B = open("B.tmp", "r", 0)
127         
128         nA = int(A.readline().strip("\r\n\t "))
129         nB = int(B.readline().strip("\r\n\t "))
130         if (nA != nB):
131                 sys.stderr.write("Body number error; A: " + str(nA) + " vs B: " + str(nB) + "\n")
132                 sys.exit(1)
133
134         total_error = 0.0
135         values = 0
136         for i in range(0, nA):
137                 dataA = A.readline().strip("\r\n\t ").split(" ")
138                 dataB = B.readline().strip("\r\n\t ").split(" ")
139                 #print("A: "+str(dataA))
140                 #print("B: "+str(dataB))
141                 dataA = map(float, dataA)[1:4] # Only count positions
142                 dataB = map(float, dataB)[1:4]
143                 #print("Length " + str(len(dataA)))
144                 if (len(dataB) != len(dataA)):
145                         sys.stderr.write("Number of values in line are different\n")
146                         sys.exit(1)
147         
148                 
149
150                 values += len(dataA)
151                 for j in range(0, len(dataA)-1):
152                         total_error += abs(dataB[j] - dataA[j])
153         os.system("rm A.tmp; rm B.tmp;")
154         return total_error / values     
155
156 if __name__ == "__main__":
157         sys.exit(main(sys.argv))

UCC git Repository :: git.ucc.asn.au