Skip to content
Snippets Groups Projects
Commit c0c1d00f authored by James Willis's avatar James Willis Committed by Matthieu Schaller
Browse files

Updated scaling script.

parent 58834a7e
No related branches found
No related tags found
No related merge requests found
...@@ -16,6 +16,8 @@ import glob ...@@ -16,6 +16,8 @@ import glob
import re import re
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import scipy.stats
import ntpath
params = {'axes.labelsize': 14, params = {'axes.labelsize': 14,
'axes.titlesize': 18, 'axes.titlesize': 18,
...@@ -48,29 +50,20 @@ threadList = [] ...@@ -48,29 +50,20 @@ threadList = []
hexcols = ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77', hexcols = ['#332288', '#88CCEE', '#44AA99', '#117733', '#999933', '#DDCC77',
'#CC6677', '#882255', '#AA4499', '#661100', '#6699CC', '#AA4466', '#CC6677', '#882255', '#AA4499', '#661100', '#6699CC', '#AA4466',
'#4477AA'] '#4477AA']
linestyle = (hexcols[0],hexcols[1],hexcols[3],hexcols[5],hexcols[6],hexcols[8]) linestyle = (hexcols[0],hexcols[1],hexcols[3],hexcols[5],hexcols[6],hexcols[8],hexcols[2],hexcols[4],hexcols[7],hexcols[9])
#cmdLine = './swift -s -t 16 cosmoVolume.yml' numTimesteps = 0
#platform = 'KNL' legendTitle = ' '
inputFileNames = []
# Work out how many data series there are # Work out how many data series there are
if len(sys.argv) == 2: if len(sys.argv) == 1:
inputFileNames = (sys.argv[1],"") print "Please specify an input file in the arguments."
numOfSeries = 1 sys.exit()
elif len(sys.argv) == 3: else:
inputFileNames = (sys.argv[1],sys.argv[2]) for fileName in sys.argv[1:]:
numOfSeries = 2 inputFileNames.append(fileName)
elif len(sys.argv) == 4: numOfSeries = int(len(sys.argv) - 1)
inputFileNames = (sys.argv[1],sys.argv[2],sys.argv[3])
numOfSeries = 3
elif len(sys.argv) == 5:
inputFileNames = (sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4])
numOfSeries = 4
elif len(sys.argv) == 6:
inputFileNames = (sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5])
numOfSeries = 5
elif len(sys.argv) == 7:
inputFileNames = (sys.argv[1],sys.argv[2],sys.argv[3],sys.argv[4],sys.argv[5],sys.argv[6])
numOfSeries = 6
# Get the names of the branch, Git revision, hydro scheme and hydro kernel # Get the names of the branch, Git revision, hydro scheme and hydro kernel
def parse_header(inputFile): def parse_header(inputFile):
...@@ -105,23 +98,35 @@ def parse_header(inputFile): ...@@ -105,23 +98,35 @@ def parse_header(inputFile):
# Parse file and return total time taken, speed up and parallel efficiency # Parse file and return total time taken, speed up and parallel efficiency
def parse_files(): def parse_files():
times = []
totalTime = [] totalTime = []
serialTime = [] sumTotal = []
speedUp = [] speedUp = []
parallelEff = [] parallelEff = []
for i in range(0,numOfSeries): # Loop over each data series
for i in range(0,numOfSeries): # Loop over each data series
# Get path to set of files
path, name = ntpath.split(inputFileNames[i])
# Get each file that starts with the cmd line arg # Get each file that starts with the cmd line arg
file_list = glob.glob(inputFileNames[i] + "*") file_list = glob.glob(inputFileNames[i] + "*")
threadList.append([]) threadList.append([])
# Remove path from file names
for j in range(0,len(file_list)):
p, filename = ntpath.split(file_list[j])
file_list[j] = filename
# Create a list of threads using the list of files # Create a list of threads using the list of files
for fileName in file_list: for fileName in file_list:
s = re.split(r'[_.]+',fileName) s = re.split(r'[_.]+',fileName)
threadList[i].append(int(s[1])) threadList[i].append(int(s[1]))
# Re-add path once each file has been found
if len(path) != 0:
for j in range(0,len(file_list)):
file_list[j] = path + '/' + file_list[j]
# Sort the thread list in ascending order and save the indices # Sort the thread list in ascending order and save the indices
sorted_indices = np.argsort(threadList[i]) sorted_indices = np.argsort(threadList[i])
...@@ -133,38 +138,50 @@ def parse_files(): ...@@ -133,38 +138,50 @@ def parse_files():
parse_header(file_list[0]) parse_header(file_list[0])
branch[i] = branch[i].replace("_", "\\_") branch[i] = branch[i].replace("_", "\\_")
version.append("$\\textrm{%s}$"%str(branch[i]) + " " + revision[i] + "\n" + hydro_scheme[i] + #version.append("$\\textrm{%s}$"%str(branch[i]))# + " " + revision[i])# + "\n" + hydro_scheme[i] +
"\n" + hydro_kernel[i] + r", $N_{ngb}=%d$"%float(hydro_neighbours[i]) + # "\n" + hydro_kernel[i] + r", $N_{ngb}=%d$"%float(hydro_neighbours[i]) +
r", $\eta=%.3f$"%float(hydro_eta[i])) # r", $\eta=%.3f$"%float(hydro_eta[i]))
times.append([])
totalTime.append([]) totalTime.append([])
speedUp.append([]) speedUp.append([])
parallelEff.append([]) parallelEff.append([])
# Loop over all files for a given series and load the times # Loop over all files for a given series and load the times
for j in range(0,len(file_list)): for j in range(0,len(file_list)):
times[i].append([]) times = np.loadtxt(file_list[j],usecols=(6,))
times[i][j].append(np.loadtxt(file_list[j],usecols=(5,), skiprows=11)) updates = np.loadtxt(file_list[j],usecols=(3,))
totalTime[i].append(np.sum(times[i][j])) totalTime[i].append(np.sum(times))
sumTotal.append(np.sum(totalTime[i]))
serialTime.append(totalTime[i][0]) # Sort the total times in descending order
sorted_indices = np.argsort(sumTotal)[::-1]
# Loop over all files for a given series and calculate speed up and parallel efficiency
totalTime = [ totalTime[j] for j in sorted_indices]
branchNew = [ branch[j] for j in sorted_indices]
for i in range(0,numOfSeries):
version.append("$\\textrm{%s}$"%str(branchNew[i]))
global numTimesteps
numTimesteps = len(times)
# Find speed-up and parallel efficiency
for i in range(0,numOfSeries):
for j in range(0,len(file_list)): for j in range(0,len(file_list)):
speedUp[i].append(serialTime[i] / totalTime[i][j]) speedUp[i].append(totalTime[i][0] / totalTime[i][j])
parallelEff[i].append(speedUp[i][j] / threadList[i][j]) parallelEff[i].append(speedUp[i][j] / threadList[i][j])
return (times,totalTime,speedUp,parallelEff) return (totalTime,speedUp,parallelEff)
def print_results(times,totalTime,parallelEff,version): def print_results(totalTime,parallelEff,version):
for i in range(0,numOfSeries): for i in range(0,numOfSeries):
print " " print " "
print "------------------------------------" print "------------------------------------"
print version[i] print version[i]
print "------------------------------------" print "------------------------------------"
print "Wall clock time for: {} time steps".format(len(times[0][0][0])) print "Wall clock time for: {} time steps".format(numTimesteps)
print "------------------------------------" print "------------------------------------"
for j in range(0,len(threadList[i])): for j in range(0,len(threadList[i])):
...@@ -172,7 +189,7 @@ def print_results(times,totalTime,parallelEff,version): ...@@ -172,7 +189,7 @@ def print_results(times,totalTime,parallelEff,version):
print " " print " "
print "------------------------------------" print "------------------------------------"
print "Parallel Efficiency for: {} time steps".format(len(times[0][0][0])) print "Parallel Efficiency for: {} time steps".format(numTimesteps)
print "------------------------------------" print "------------------------------------"
for j in range(0,len(threadList[i])): for j in range(0,len(threadList[i])):
...@@ -180,8 +197,18 @@ def print_results(times,totalTime,parallelEff,version): ...@@ -180,8 +197,18 @@ def print_results(times,totalTime,parallelEff,version):
return return
def plot_results(times,totalTime,speedUp,parallelEff): # Returns a lighter/darker version of the colour
def color_variant(hex_color, brightness_offset=1):
rgb_hex = [hex_color[x:x+2] for x in [1, 3, 5]]
new_rgb_int = [int(hex_value, 16) + brightness_offset for hex_value in rgb_hex]
new_rgb_int = [min([255, max([0, i])]) for i in new_rgb_int] # make sure new values are between 0 and 255
# hex() produces "0x88", we want just "88"
return "#" + "".join([hex(i)[2:] for i in new_rgb_int])
def plot_results(totalTime,speedUp,parallelEff,numSeries):
fig, axarr = plt.subplots(2, 2, figsize=(10,10), frameon=True) fig, axarr = plt.subplots(2, 2, figsize=(10,10), frameon=True)
speedUpPlot = axarr[0, 0] speedUpPlot = axarr[0, 0]
parallelEffPlot = axarr[0, 1] parallelEffPlot = axarr[0, 1]
...@@ -190,27 +217,27 @@ def plot_results(times,totalTime,speedUp,parallelEff): ...@@ -190,27 +217,27 @@ def plot_results(times,totalTime,speedUp,parallelEff):
# Plot speed up # Plot speed up
speedUpPlot.plot(threadList[0],threadList[0], linestyle='--', lw=1.5, color='0.2') speedUpPlot.plot(threadList[0],threadList[0], linestyle='--', lw=1.5, color='0.2')
for i in range(0,numOfSeries): for i in range(0,numSeries):
speedUpPlot.plot(threadList[i],speedUp[i],linestyle[i],label=version[i]) speedUpPlot.plot(threadList[0],speedUp[i],linestyle[i],label=version[i])
speedUpPlot.set_ylabel("${\\rm Speed\\textendash up}$", labelpad=0.) speedUpPlot.set_ylabel("${\\rm Speed\\textendash up}$", labelpad=0.)
speedUpPlot.set_xlabel("${\\rm Threads}$", labelpad=0.) speedUpPlot.set_xlabel("${\\rm Threads}$", labelpad=0.)
speedUpPlot.set_xlim([0.7,threadList[i][-1]+1]) speedUpPlot.set_xlim([0.7,threadList[0][-1]+1])
speedUpPlot.set_ylim([0.7,threadList[i][-1]+1]) speedUpPlot.set_ylim([0.7,threadList[0][-1]+1])
# Plot parallel efficiency # Plot parallel efficiency
parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [1,1], 'k--', lw=1.5, color='0.2') parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [1,1], 'k--', lw=1.5, color='0.2')
parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.9,0.9], 'k--', lw=1.5, color='0.2') parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.9,0.9], 'k--', lw=1.5, color='0.2')
parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.75,0.75], 'k--', lw=1.5, color='0.2') parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.75,0.75], 'k--', lw=1.5, color='0.2')
parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.5,0.5], 'k--', lw=1.5, color='0.2') parallelEffPlot.plot([threadList[0][0], 10**np.floor(np.log10(threadList[0][-1])+1)], [0.5,0.5], 'k--', lw=1.5, color='0.2')
for i in range(0,numOfSeries): for i in range(0,numSeries):
parallelEffPlot.plot(threadList[i],parallelEff[i],linestyle[i]) parallelEffPlot.plot(threadList[0],parallelEff[i],linestyle[i])
parallelEffPlot.set_xscale('log') parallelEffPlot.set_xscale('log')
parallelEffPlot.set_ylabel("${\\rm Parallel~efficiency}$", labelpad=0.) parallelEffPlot.set_ylabel("${\\rm Parallel~efficiency}$", labelpad=0.)
parallelEffPlot.set_xlabel("${\\rm Threads}$", labelpad=0.) parallelEffPlot.set_xlabel("${\\rm Threads}$", labelpad=0.)
parallelEffPlot.set_ylim([0,1.1]) parallelEffPlot.set_ylim([0,1.1])
parallelEffPlot.set_xlim([0.9,10**(np.floor(np.log10(threadList[i][-1]))+0.5)]) parallelEffPlot.set_xlim([0.9,10**(np.floor(np.log10(threadList[0][-1]))+0.5)])
# Plot time to solution # Plot time to solution
for i in range(0,numOfSeries): for i in range(0,numOfSeries):
...@@ -218,20 +245,15 @@ def plot_results(times,totalTime,speedUp,parallelEff): ...@@ -218,20 +245,15 @@ def plot_results(times,totalTime,speedUp,parallelEff):
totalTimePlot.loglog(pts,totalTime[i][0]/pts, 'k--', lw=1., color='0.2') totalTimePlot.loglog(pts,totalTime[i][0]/pts, 'k--', lw=1., color='0.2')
totalTimePlot.loglog(threadList[i],totalTime[i],linestyle[i],label=version[i]) totalTimePlot.loglog(threadList[i],totalTime[i],linestyle[i],label=version[i])
y_min = 10**np.floor(np.log10(np.min(totalTime[:][-1])*0.6)) y_min = 10**np.floor(np.log10(np.min(totalTime[:][0])*0.6))
y_max = 1.2*10**np.floor(np.log10(np.max(totalTime[:][0]) * 1.5)+1) y_max = 1.0*10**np.floor(np.log10(np.max(totalTime[:][0]) * 1.5)+1)
totalTimePlot.set_xscale('log') totalTimePlot.set_xscale('log')
totalTimePlot.set_xlabel("${\\rm Threads}$", labelpad=0.) totalTimePlot.set_xlabel("${\\rm Threads}$", labelpad=0.)
totalTimePlot.set_ylabel("${\\rm Time~to~solution}~[{\\rm ms}]$", labelpad=0.) totalTimePlot.set_ylabel("${\\rm Time~to~solution}~[{\\rm ms}]$", labelpad=0.)
totalTimePlot.set_xlim([0.9, 10**(np.floor(np.log10(threadList[i][-1]))+0.5)]) totalTimePlot.set_xlim([0.9, 10**(np.floor(np.log10(threadList[0][-1]))+0.5)])
totalTimePlot.set_ylim(y_min, y_max) totalTimePlot.set_ylim(y_min, y_max)
ax2 = totalTimePlot.twinx() totalTimePlot.legend(bbox_to_anchor=(1.21, 0.97), loc=2, borderaxespad=0.,prop={'size':12}, frameon=False,title=legendTitle)
ax2.set_yscale('log')
ax2.set_ylabel("${\\rm Time~to~solution}~[{\\rm hr}]$", labelpad=0.)
ax2.set_ylim(y_min / 3.6e6, y_max / 3.6e6)
totalTimePlot.legend(bbox_to_anchor=(1.21, 0.97), loc=2, borderaxespad=0.,prop={'size':12}, frameon=False)
emptyPlot.axis('off') emptyPlot.axis('off')
for i, txt in enumerate(threadList[0]): for i, txt in enumerate(threadList[0]):
...@@ -240,17 +262,19 @@ def plot_results(times,totalTime,speedUp,parallelEff): ...@@ -240,17 +262,19 @@ def plot_results(times,totalTime,speedUp,parallelEff):
parallelEffPlot.annotate("$%s$"%txt, (threadList[0][i],parallelEff[0][i]), (threadList[0][i], parallelEff[0][i]+0.02), color=hexcols[0]) parallelEffPlot.annotate("$%s$"%txt, (threadList[0][i],parallelEff[0][i]), (threadList[0][i], parallelEff[0][i]+0.02), color=hexcols[0])
totalTimePlot.annotate("$%s$"%txt, (threadList[0][i],totalTime[0][i]), (threadList[0][i], totalTime[0][i]*1.1), color=hexcols[0]) totalTimePlot.annotate("$%s$"%txt, (threadList[0][i],totalTime[0][i]), (threadList[0][i], totalTime[0][i]*1.1), color=hexcols[0])
#fig.suptitle("Thread Speed Up, Parallel Efficiency and Time To Solution for {} Time Steps of Cosmo Volume\n Cmd Line: {}, Platform: {}".format(len(times[0][0][0]),cmdLine,platform)) #fig.suptitle("Thread Speed Up, Parallel Efficiency and Time To Solution for {} Time Steps of Cosmo Volume\n Cmd Line: {}, Platform: {}".format(numTimesteps),cmdLine,platform))
fig.suptitle("${\\rm Speed\\textendash up,~parallel~efficiency~and~time~to~solution~for}~%d~{\\rm time\\textendash steps}$"%len(times[0][0][0]), fontsize=16) fig.suptitle("${\\rm Speed\\textendash up,~parallel~efficiency~and~time~to~solution~for}~%d~{\\rm time\\textendash steps}$"%numTimesteps, fontsize=16)
return return
# Calculate results # Calculate results
(times,totalTime,speedUp,parallelEff) = parse_files() (totalTime,speedUp,parallelEff) = parse_files()
legendTitle = version[0]
plot_results(times,totalTime,speedUp,parallelEff) plot_results(totalTime,speedUp,parallelEff,numOfSeries)
print_results(times,totalTime,parallelEff,version) print_results(totalTime,parallelEff,version)
# And plot # And plot
plt.show() plt.show()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment