Commit 5f8b5e71 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Merge branch 'master' into macro-vectorisation

parents e0177f4e 9e88fc31
......@@ -466,6 +466,12 @@ AM_CONDITIONAL([HAVE_DOXYGEN], [test "$ac_cv_path_ac_pt_DX_DOXYGEN" != ""])
# Handle .in files.
AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile doc/Makefile doc/Doxyfile tests/Makefile])
AC_CONFIG_FILES([tests/testReading.sh], [chmod +x tests/testReading.sh])
AC_CONFIG_FILES([tests/testPair.sh], [chmod +x tests/testPair.sh])
AC_CONFIG_FILES([tests/testPairPerturbed.sh], [chmod +x tests/testPairPerturbed.sh])
AC_CONFIG_FILES([tests/test27cells.sh], [chmod +x tests/test27cells.sh])
AC_CONFIG_FILES([tests/test27cellsPerturbed.sh], [chmod +x tests/test27cellsPerturbed.sh])
AC_CONFIG_FILES([tests/testParser.sh], [chmod +x tests/testParser.sh])
# Report general configuration.
AC_MSG_RESULT([
......
......@@ -19,7 +19,7 @@
MYFLAGS = -DTIMER
# Add the source directory and debug to CFLAGS
AM_CFLAGS = -I../src $(HDF5_CPPFLAGS)
AM_CFLAGS = -I$(top_srcdir)/src $(HDF5_CPPFLAGS)
AM_LDFLAGS = $(HDF5_LDFLAGS)
......
......@@ -34,6 +34,8 @@ Snapshots:
# Parameters governing the conserved quantities statistics
Statistics:
delta_time: 1e-2 # Time between statistics output
energy_file_name: energy # (Optional) File name for energy output
timestep_file_name: timesteps # (Optional) File name for timing information output. Note: No underscores "_" allowed in file name
# Parameters for the hydrodynamics scheme
SPH:
......
#!/usr/bin/env python
#
# Usage:
# python plot_scaling_results.py input-file1-ext input-file2-ext ...
#
# Description:
# Plots speed up, parallel efficiency and time to solution given a "timesteps" output file generated by SWIFT.
#
# Example:
# python plot_scaling_results.py _hreads_cosma_stdout.txt _threads_knl_stdout.txt
#
# The working directory should contain files 1_threads_cosma_stdout.txt - 64_threads_cosma_stdout.txt and 1_threads_knl_stdout.txt - 64_threads_knl_stdout.txt, i.e wall clock time for each run using a given number of threads
import sys
import glob
import re
import numpy as np
import matplotlib.pyplot as plt
version = []
branch = []
revision = []
hydro_scheme = []
hydro_kernel = []
hydro_neighbours = []
hydro_eta = []
threadList = []
linestyle = ('ro-','bo-','go-','yo-','mo-')
#cmdLine = './swift_fixdt -s -t 16 cosmoVolume.yml'
#platform = 'KNL'
# Work out how many data series there are
if len(sys.argv) == 2:
inputFileNames = (sys.argv[1],"")
numOfSeries = 1
elif len(sys.argv) == 3:
inputFileNames = (sys.argv[1],sys.argv[2])
numOfSeries = 2
elif len(sys.argv) == 4:
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
# Get the names of the branch, Git revision, hydro scheme and hydro kernel
def parse_header(inputFile):
with open(inputFile, 'r') as f:
found_end = False
for line in f:
if 'Branch:' in line:
s = line.split()
branch.append(s[2])
elif 'Revision:' in line:
s = line.split()
revision.append(s[2])
elif 'Hydrodynamic scheme:' in line:
line = line[2:-1]
s = line.split()
line = s[2:]
hydro_scheme.append(" ".join(line))
elif 'Hydrodynamic kernel:' in line:
line = line[2:-1]
s = line.split()
line = s[2:5]
hydro_kernel.append(" ".join(line))
elif 'neighbours:' in line:
s = line.split()
hydro_neighbours.append(s[4])
elif 'Eta:' in line:
s = line.split()
hydro_eta.append(s[2])
return
# Parse file and return total time taken, speed up and parallel efficiency
def parse_files():
times = []
totalTime = []
serialTime = []
speedUp = []
parallelEff = []
for i in range(0,numOfSeries): # Loop over each data series
# Get each file that starts with the cmd line arg
file_list = glob.glob(inputFileNames[i] + "*")
threadList.append([])
# Create a list of threads using the list of files
for fileName in file_list:
s = re.split(r'[_.]+',fileName)
threadList[i].append(int(s[1]))
# Sort the thread list in ascending order and save the indices
sorted_indices = np.argsort(threadList[i])
threadList[i].sort()
# Sort the file list in ascending order acording to the thread number
file_list = [ file_list[j] for j in sorted_indices]
parse_header(file_list[0])
version.append(branch[i] + " " + revision[i] + "\n" + hydro_scheme[i] +
"\n" + hydro_kernel[i] + r", $N_{neigh}$=" + hydro_neighbours[i] +
r", $\eta$=" + hydro_eta[i] + "\n")
times.append([])
totalTime.append([])
speedUp.append([])
parallelEff.append([])
# Loop over all files for a given series and load the times
for j in range(0,len(file_list)):
times[i].append([])
times[i][j].append(np.loadtxt(file_list[j],usecols=(5,)))
totalTime[i].append(np.sum(times[i][j]))
serialTime.append(totalTime[i][0])
# Loop over all files for a given series and calculate speed up and parallel efficiency
for j in range(0,len(file_list)):
speedUp[i].append(serialTime[i] / totalTime[i][j])
parallelEff[i].append(speedUp[i][j] / threadList[i][j])
return (times,totalTime,speedUp,parallelEff)
def print_results(times,totalTime,parallelEff,version):
for i in range(0,numOfSeries):
print " "
print "------------------------------------"
print version[i]
print "------------------------------------"
print "Wall clock time for: {} time steps".format(len(times[0][0][0]))
print "------------------------------------"
for j in range(0,len(threadList[i])):
print str(threadList[i][j]) + " threads: {}".format(totalTime[i][j])
print " "
print "------------------------------------"
print "Parallel Efficiency for: {} time steps".format(len(times[0][0][0]))
print "------------------------------------"
for j in range(0,len(threadList[i])):
print str(threadList[i][j]) + " threads: {}".format(parallelEff[i][j])
return
def plot_results(times,totalTime,speedUp,parallelEff):
fig, axarr = plt.subplots(2, 2,figsize=(15,15))
speedUpPlot = axarr[0, 0]
parallelEffPlot = axarr[0, 1]
totalTimePlot = axarr[1, 0]
emptyPlot = axarr[1, 1]
# Plot speed up
for i in range(0,numOfSeries):
speedUpPlot.plot(threadList[i],speedUp[i],linestyle[i],label=version[i])
speedUpPlot.plot(threadList[i],threadList[i],color='k',linestyle='--')
speedUpPlot.set_ylabel("Speed Up")
speedUpPlot.set_xlabel("No. of Threads")
# Plot parallel efficiency
for i in range(0,numOfSeries):
parallelEffPlot.plot(threadList[i],parallelEff[i],linestyle[i])
parallelEffPlot.set_xscale('log')
parallelEffPlot.set_ylabel("Parallel Efficiency")
parallelEffPlot.set_xlabel("No. of Threads")
parallelEffPlot.set_ylim([0,1.1])
# Plot time to solution
for i in range(0,numOfSeries):
totalTimePlot.loglog(threadList[i],totalTime[i],linestyle[i],label=version[i])
totalTimePlot.set_xscale('log')
totalTimePlot.set_xlabel("No. of Threads")
totalTimePlot.set_ylabel("Time to Solution (ms)")
totalTimePlot.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,prop={'size':14})
emptyPlot.axis('off')
for i, txt in enumerate(threadList[0]):
speedUpPlot.annotate(txt, (threadList[0][i],speedUp[0][i]))
parallelEffPlot.annotate(txt, (threadList[0][i],parallelEff[0][i]))
totalTimePlot.annotate(txt, (threadList[0][i],totalTime[0][i]))
#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".format(len(times[0][0][0])))
return
# Calculate results
(times,totalTime,speedUp,parallelEff) = parse_files()
plot_results(times,totalTime,speedUp,parallelEff)
print_results(times,totalTime,parallelEff,version)
plt.show()
......@@ -92,12 +92,12 @@ version_string.h: version_string.h.in $(AM_SOURCES) $(include_HEADERS) $(noinst_
GIT_BRANCH=`$(GIT_CMD) branch | sed -n 's/^\* \(.*\)/\1/p'`; \
sed -e "s,@PACKAGE_VERSION\@,$(PACKAGE_VERSION)," \
-e "s,@GIT_REVISION\@,$${GIT_REVISION}," \
-e "s|@GIT_BRANCH\@|$${GIT_BRANCH}|" version_string.h.in > version_string.h; \
-e "s|@GIT_BRANCH\@|$${GIT_BRANCH}|" $< > version_string.h; \
else \
if test ! -f version_string.h; then \
sed -e "s,@PACKAGE_VERSION\@,$(PACKAGE_VERSION)," \
-e "s,@GIT_REVISION\@,unknown," \
-e "s,@GIT_BRANCH\@,unknown," version_string.h.in > version_string.h; \
-e "s,@GIT_BRANCH\@,unknown," $< > version_string.h; \
fi; \
fi
......
......@@ -65,6 +65,7 @@
#include "single_io.h"
#include "timers.h"
#include "units.h"
#include "version.h"
const char *engine_policy_names[13] = {"none",
"rand",
......@@ -2392,6 +2393,10 @@ void engine_step(struct engine *e) {
printf(" %6d %14e %14e %10zd %10zd %21.3f\n", e->step, e->time,
e->timeStep, e->updates, e->g_updates, e->wallclock_time);
fflush(stdout);
fprintf(e->file_timesteps, " %6d %14e %14e %10zd %10zd %21.3f\n", e->step,
e->time, e->timeStep, e->updates, e->g_updates, e->wallclock_time);
fflush(e->file_timesteps);
}
/* Save some statistics */
......@@ -2801,6 +2806,7 @@ void engine_init(struct engine *e, struct space *s,
e->dt_min = parser_get_param_double(params, "TimeIntegration:dt_min");
e->dt_max = parser_get_param_double(params, "TimeIntegration:dt_max");
e->file_stats = NULL;
e->file_timesteps = NULL;
e->deltaTimeStatistics =
parser_get_param_double(params, "Statistics:delta_time");
e->timeLastStatistics = e->timeBegin - e->deltaTimeStatistics;
......@@ -2952,12 +2958,41 @@ void engine_init(struct engine *e, struct space *s,
/* Open some files */
if (e->nodeID == 0) {
e->file_stats = fopen("energy.txt", "w");
char energyfileName[200] = "";
parser_get_opt_param_string(params, "Statistics:energy_file_name",
energyfileName,
engine_default_energy_file_name);
sprintf(energyfileName + strlen(energyfileName), ".txt");
e->file_stats = fopen(energyfileName, "w");
fprintf(e->file_stats,
"# %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s\n",
"Time", "Mass", "E_tot", "E_kin", "E_int", "E_pot", "p_x", "p_y",
"p_z", "ang_x", "ang_y", "ang_z");
fflush(e->file_stats);
char timestepsfileName[200] = "";
parser_get_opt_param_string(params, "Statistics:timestep_file_name",
timestepsfileName,
engine_default_timesteps_file_name);
sprintf(timestepsfileName + strlen(timestepsfileName), "_%d.txt",
nr_nodes * nr_threads);
e->file_timesteps = fopen(timestepsfileName, "w");
fprintf(e->file_timesteps,
"# Branch: %s\n# Revision: %s\n# Compiler: %s, Version: %s \n# "
"Number of threads: %d\n# Number of MPI ranks: %d\n# Hydrodynamic "
"scheme: %s\n# Hydrodynamic kernel: %s\n# No. of neighbours: %.2f "
"+/- %.2f\n# Eta: %f\n",
git_branch(), git_revision(), compiler_name(), compiler_version(),
e->nr_threads, e->nr_nodes, SPH_IMPLEMENTATION, kernel_name,
e->hydro_properties->target_neighbours,
e->hydro_properties->delta_neighbours,
e->hydro_properties->eta_neighbours);
fprintf(e->file_timesteps, "# %6s %14s %14s %10s %10s %16s [%s]\n", "Step",
"Time", "Time-step", "Updates", "g-Updates", "Wall-clock time",
clocks_getunit());
fflush(e->file_timesteps);
}
/* Print policy */
......
......@@ -72,6 +72,8 @@ extern const char *engine_policy_names[];
#define engine_tasksreweight 10
#define engine_parts_size_grow 1.05
#define engine_redistribute_alloc_margin 1.2
#define engine_default_energy_file_name "energy"
#define engine_default_timesteps_file_name "timesteps"
/* The rank of the engine as a global variable (for messages). */
extern int engine_rank;
......@@ -149,6 +151,9 @@ struct engine {
double timeLastStatistics;
double deltaTimeStatistics;
/* Timesteps information */
FILE *file_timesteps;
/* The current step number. */
int step;
......
......@@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Add the source directory and debug to CFLAGS
AM_CFLAGS = -I../src $(HDF5_CPPFLAGS) -DTIMER
AM_CFLAGS = -I$(top_srcdir)/src $(HDF5_CPPFLAGS) -DTIMER
AM_LDFLAGS = ../src/.libs/libswiftsim.a $(HDF5_LDFLAGS) $(HDF5_LIBS)
......
......@@ -3,6 +3,6 @@ rm brute_force_27_standard.dat swift_dopair_27_standard.dat
./test27cells -p 6 -r 1 -d 0 -f standard
python difffloat.py brute_force_27_standard.dat swift_dopair_27_standard.dat tolerance.dat 6
python @srcdir@/difffloat.py brute_force_27_standard.dat swift_dopair_27_standard.dat @srcdir@/tolerance.dat 6
exit $?
......@@ -3,6 +3,6 @@ rm brute_force_27_perturbed.dat swift_dopair_27_perturbed.dat
./test27cells -p 6 -r 1 -d 0.1 -f perturbed
python difffloat.py brute_force_27_perturbed.dat swift_dopair_27_perturbed.dat tolerance.dat 6
python @srcdir@/difffloat.py brute_force_27_perturbed.dat swift_dopair_27_perturbed.dat @srcdir@/tolerance.dat 6
exit $?
......@@ -3,6 +3,6 @@ rm brute_force_standard.dat swift_dopair_standard.dat
./testPair -p 6 -r 1 -d 0 -f standard
python difffloat.py brute_force_standard.dat swift_dopair_standard.dat tolerance.dat
python @srcdir@/difffloat.py brute_force_standard.dat swift_dopair_standard.dat @srcdir@/tolerance.dat
exit $?
......@@ -3,6 +3,6 @@ rm brute_force_perturbed.dat swift_dopair_perturbed.dat
./testPair -p 6 -r 1 -d 0.1 -f perturbed
python difffloat.py brute_force_perturbed.dat swift_dopair_perturbed.dat tolerance.dat
python @srcdir@/difffloat.py brute_force_perturbed.dat swift_dopair_perturbed.dat @srcdir@/tolerance.dat
exit $?
#!/bin/bash
rm parser_output.yml
./testParser testParserInput.yaml
./testParser @srcdir@/testParserInput.yaml
......@@ -27,6 +27,7 @@ int main() {
size_t Ngas = 0, Ngpart = 0;
int periodic = -1;
int flag_entropy_ICs = -1;
int i, j, k, n;
double dim[3];
struct part *parts = NULL;
......@@ -39,7 +40,7 @@ int main() {
/* Read data */
read_ic_single("input.hdf5", dim, &parts, &gparts, &Ngas, &Ngpart, &periodic,
0);
&flag_entropy_ICs, 0);
/* Check global properties read are correct */
assert(dim[0] == boxSize);
......
#!/bin/bash
python makeInput.py
python @srcdir@/makeInput.py
./testReading
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment