#!/usr/bin/python -u
# @file get_data.py
-# @purpose Extract statistics from repeated runs of N-Body simulators
+# @purpose Extract statistics from repeated runs of N-Body simulators and graph them
# @author Sam Moore (20503628) - 2012
+# Not documented very well, because it's not part of the task requirements
+# Mostly to get a different graph I just comment out a lot of lines and uncomment others. Well designed.
import sys
import os
import subprocess
+import odict
import Gnuplot, Gnuplot.funcutils
plot = Gnuplot.Gnuplot(persist=0)
-programs = {
- "single-thread" : "./single-thread/nbody -g -v 5"
-}
-for n in range(1, 5):
- programs.update({"mthread"+str(n) : "./mthread/nbody -g -v 5 -n "+str(n)})
+programs = odict.odict([("single-thread" , "./single-thread/nbody -g")])
+
+for n in range(4, 5, 1):
+ programs.update({"mthread"+str(n) : "./mthread/nbody -g -n "+str(n)})
+ programs.update({"openmp"+str(n) : "./openmp/nbody -g -n " +str(n)})
+ for theta in [0.1, 1.0, 10.0]:
+ programs.update({"nbody-bh"+str(n)+":theta"+str(theta) : "./nbody-bh/nbody -g -n "+str(n)+" --theta " + str(theta)})
+
+
def RunForSteps(program, field, steps):
results = []
- #print(str(program) + " -s "+str(steps) + " " + str(field))
- results.append(RunProgram(str(program) + " -s "+str(steps) + " " + str(field)))
+ print(str(program) + " -s "+str(steps) + " -v 5 " + str(field))
+ results = RunProgram(str(program) + " -s "+str(steps) + " -v 5 " + str(field))
return results
def VaryField(program, steps, fields):
data = {}
data.update(programs)
+ Plot_PerformanceN(data, 10, 1, 3000, 100)
+
+ """
fields = map(int, os.listdir("fields"))
fields.sort(key = lambda e : e)
+ ignore = [10, 100]
for n in fields:
+ if n in ignore:
+ continue
for p in data.keys():
- data[p] = [RunForSteps(programs[p], "fields/"+str(n), 200), n]
+ #Plot_MeanErrors(programs["single-thread"], programs[p], "fields/"+str(n), 0, 100)
+ data[p] = RunForSteps(programs[p], "fields/"+str(n), 200)
#print(str(data[p]))
- if (len(data[p]) > 0):
- plot.replot(Gnuplot.Data(data[p][0], title=str(p)+":"+str(n), with_="lp linecolor "+str(fields.index(n))))
+
+ #print(str(data.items()));
+ for d in sorted(data.items(), key = lambda e : e[1][len(e[1])-1][1]):
+ if (len(d[1]) > 0):
+ plot.replot(Gnuplot.Data(d[1], title=str(d[0])+":"+str(n), with_="lp")) #linecolor "+str(fields.index(n))))
#print(str(data.items()))
# Score the programs
#for p in sorted(data.items(), key = lambda e : e[1][0][len(e[1][0])-1][1]):
# print(str(p[0])+":"+str(n)+"\t"+str(p[1][0][len(p[1][0])-1][1]))
-
+ """
sys.stdin.readline()
return 0
+def Plot_MeanErrors(control, program, field, sMin, sMax):
+ plot("set xlabel \"steps\"")
+ plot("set ylabel \"Error\"")
+ plot("set title \"Mean Position Error .vs. Steps\\n(Mean Error = Mean absolute error of all position components)\\nField: "+str(field)+"\"")
+ plot("set key outside right")
+ plot("set log y")
+ if (control == program):
+ return
+ d = []
+ for s in range(sMin, sMax, (sMax - sMin) / 20):
+ d.append([s, MeanError(control, program, field, s)])
+
+ plot.replot(Gnuplot.Data(d, title=str(program), with_="lp")) #linecolor "+str(fields.index(n))))
+
+def Plot_PerformanceN(d, steps, nMin, nMax, nStep):
+
+ plot("set xlabel \"N bodies\"")
+ plot("set ylabel \"Real Time (s)\"")
+ plot("set title \"Time taken to simulate N randomly generated bodies for 1000 steps\"")
+ plot("set key outside right")
+ for p in d.items():
+ data = []
+ for n in range(nMin, nMax, nStep):
+ print("Run for " + str(n) + " bodies; " + str(p[1]))
+ r = RunProgram(str(p[1]) + " -r " + str(n) + " -s " + str(steps))
+ data.append([n, r[len(r)-1][1]])
+ plot.replot(Gnuplot.Data(data, title=str(p[0]), with_="lp"))
+
+def MeanError(programA, programB, field, steps):
+ print("Calculate error for "+str(steps) + " steps: " + str(programB) + " .vs. " + str(programA))
+ RunProgram(str(programA) + " -s "+str(steps) + " " + str(field) + " " + "A.tmp")
+ RunProgram(str(programB) + " -s "+str(steps) + " " + str(field) + " " + "B.tmp")
+
+ A = open("A.tmp", "r", 0)
+ B = open("B.tmp", "r", 0)
+
+ nA = int(A.readline().strip("\r\n\t "))
+ nB = int(B.readline().strip("\r\n\t "))
+ if (nA != nB):
+ sys.stderr.write("Body number error; A: " + str(nA) + " vs B: " + str(nB) + "\n")
+ sys.exit(1)
+
+ total_error = 0.0
+ values = 0
+ for i in range(0, nA):
+ dataA = A.readline().strip("\r\n\t ").split(" ")
+ dataB = B.readline().strip("\r\n\t ").split(" ")
+ #print("A: "+str(dataA))
+ #print("B: "+str(dataB))
+ dataA = map(float, dataA)[1:4] # Only count positions
+ dataB = map(float, dataB)[1:4]
+ #print("Length " + str(len(dataA)))
+ if (len(dataB) != len(dataA)):
+ sys.stderr.write("Number of values in line are different\n")
+ sys.exit(1)
+
+
+
+ values += len(dataA)
+ for j in range(0, len(dataA)-1):
+ total_error += abs(dataB[j] - dataA[j])
+ os.system("rm A.tmp; rm B.tmp;")
+ return total_error / values
+
if __name__ == "__main__":
sys.exit(main(sys.argv))