Skip to content

Commit 68aa254

Browse files
First commit of AllScale testing framework
1 parent 02e9ccb commit 68aa254

8 files changed

Lines changed: 385 additions & 65 deletions

python/ObservationsGenerator.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,17 @@ def Amdados2D(config_file, demo):
4646
subprocess.run("sync", check=True)
4747
print("")
4848
print("")
49+
# amend sensor location to ensure information in vicinity
50+
# of point release
51+
cx = round(float(conf.spot_x) / conf.dx)
52+
cy = round(float(conf.spot_y) / conf.dy)
53+
x1 = int(cx) + 3 # insure that there are at least
54+
y1 = int(cy) + 3 # one sensor location close to source
55+
4956
sensor_idx = LoadSensorLocations(conf)
57+
sensor_idx[0,0] = x1
58+
sensor_idx[0,1] = y1
59+
np.savetxt(MakeFileName(conf, "sensors"), dtype=int, sensor_idx)
5060

5161
# Run forward simulation and record the "true" solutions into a file.
5262
with open(MakeFileName(conf, "true_field"), "wb") as fid:
@@ -117,9 +127,6 @@ def LoadSensorLocations(conf):
117127
Np = round(math.ceil(Nx * Ny * conf.sensor_fraction))
118128
data = np.loadtxt(MakeFileName(conf, "sensors"), dtype=int)
119129
assert (data is not None) and (data.size > 0), "empty file of sensors"
120-
if data.ndim == 1:
121-
assert data.size == 2 # single sensor point (x,y)
122-
data = np.reshape(data, (-1,data.size))
123130
assert len(data.shape) == 2 and data.shape[1] == 2, "wrong layout"
124131
assert data.shape[0] <= Nx * Ny, "too many records"
125132
assert data.dtype == int, "type mismatch"
@@ -254,7 +261,7 @@ def ForwardSolver(conf, glo_idx, sensor_idx, solution_fid, demo):
254261
# Write the field entries at sensors into the file of observations.
255262
writer.WriteField(field, sensor_idx, k)
256263
# Write a number of full fields for comparison against C++ simulation.
257-
if k == 0 or ((Nw-1)*(k-1))//(Nt-1) != ((Nw-1)*k)//(Nt-1):
264+
if ((Nw-1)*(k-1))//(Nt-1) != ((Nw-1)*k)//(Nt-1):
258265
WriteEntireField(solution_fid, field, k)
259266

260267
# Visualization, if needed.

python/RandObservationsGenerator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
AMDADOS_EXE = "build/app/amdados"
1414

1515

16-
def Amdados2D(config_file, demo):
16+
def Amdados2D_quick(config_file, demo):
1717
""" Advection-diffusion PDE forward solver.
1818
"""
1919
# Initialize parameters, global indices and output directory.
@@ -34,9 +34,9 @@ def Amdados2D(config_file, demo):
3434
print("generating a new one ...")
3535
assert os.path.exists(AMDADOS_EXE), (
3636
"Application 'amdados' must be built before running this script")
37-
subprocess.Popen([AMDADOS_EXE, "--scenario", "sensors",
37+
amdados = subprocess.Popen([AMDADOS_EXE, "--scenario", "sensors",
3838
"--config", config_file])
39-
os.sync()
39+
amdados.wait()
4040
print("")
4141
print("")
4242
sensor_idx = LoadSensorLocations(conf)

python/RunMultipleConfigForExperiment.py

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,24 @@
3232
from RandObservationsGenerator import InitDependentParams, Amdados2D
3333
from Utility import *
3434

35-
GridSizes = [(2,2),(4,4), (8,8), (12,12), (16,16), (20,20), (24,24), (28,28), (32,32)]
35+
# Get subdomain sizes as multiplier factors
36+
37+
38+
nthreads = np.arange(0,46,2)
39+
GridSizes = np.zeros([len(nthreads), 2])
40+
nthreads[0] = 1
41+
nthreads[1] = 3
42+
GridSizes[0:13, :] = ([4,2], [6,4], [8,4], [8,6],[8,8], [10,8],[12, 8],[16,7],
43+
[16,8], [12,12], [20,8], [16,11], [16,12])
44+
for i in range(13, len(GridSizes)):
45+
GridSizes[i, :] = [(i)*2, 8]
46+
problem_size= GridSizes[:,0]*GridSizes[:,1]
47+
48+
execute_time = np.zeros([len(nthreads), 4])
3649
# Integration period in seconds.
37-
IntegrationPeriod = 100
50+
IntegrationPeriod = 25
51+
IntegrationNsteps = 50
52+
# Path to the C++ executable.
3853

3954
# Path to the C++ executable.
4055
AMDADOS_EXE = "build/app/amdados"
@@ -52,8 +67,9 @@
5267

5368
# For all the grid sizes in the list ...
5469
exe_time_profile = np.zeros((len(GridSizes),2))
55-
for grid_no, grid in enumerate(GridSizes):
56-
assert grid[0] >= 2 and grid[1] >= 2, "the minimum grid size is 2x2"
70+
for i in range(0, len(nthreads)):
71+
grid = GridSizes[i, :]
72+
Nproc = nthreads[i]
5773
# Modify parameters given the current grid size.
5874
setattr(conf, "num_subdomains_x", int(grid[0]))
5975
setattr(conf, "num_subdomains_y", int(grid[1]))
@@ -70,22 +86,33 @@
7086

7187
# Run C++ data assimilation application.
7288
print("##################################################")
73-
print("Simulation by 'amdados' application ...")
74-
print("silent if debugging & messaging were disabled")
89+
print("Simulation by 'amdados' application for series of hpx threads")
90+
print("Initial simulations for Oceans paper")
7591
print("##################################################")
7692
print(AMDADOS_EXE, config_file)
77-
subprocess.call([AMDADOS_EXE, "--scenario", "simulation",
78-
"--config", config_file])
93+
output = subprocess.Popen([AMDADOS_EXE, "--scenario", "simulation",
94+
"--config", config_file, "--hpx:threads=" + str(Nproc)], stdout=subprocess.PIPE)
7995
os.sync()
8096

97+
# Strip the execution time from stdout, both total simulation time
98+
# and throughput (subdomain/s)
99+
strip_output = str(output.communicate()[0]).split('\\n')
100+
for line in strip_output:
101+
if re.search("Simulation", line):
102+
simtime_string = line
103+
if re.search("Throughput", line):
104+
throughput_string = line
105+
simtime_secs = float(simtime_string.split(' ')[2][:-1])
106+
throughput_secs = float(throughput_string.split(' ')[1])
107+
108+
81109
# Get the execution time and corresponding (global) problem size
82110
# and save the current scalability profile into the file.
83111
problem_size = ( conf.num_subdomains_x * conf.subdomain_x *
84112
conf.num_subdomains_y * conf.subdomain_y )
85-
exe_time_profile[grid_no,0] = problem_size
86-
exe_time_profile[grid_no,1] = timer() - start_time
113+
execute_time[i, :] = [problem_size, Nproc, simtime_secs, throughput_secs]
87114
np.savetxt(os.path.join(conf.output_dir, "scalability_performance.txt"),
88-
exe_time_profile)
115+
execute_time)
89116

90117
except subprocess.CalledProcessError as error:
91118
traceback.print_exc()
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# -----------------------------------------------------------------------------
2+
# Author : Albert Akhriev, albert_akhriev@ie.ibm.com
3+
# Copyright : IBM Research Ireland, 2017-2018
4+
# -----------------------------------------------------------------------------
5+
6+
""" This script runs several simulations with increasing problem size
7+
utilizing all available CPUs. It saves the execution time of each
8+
simulation in a file that can be used to plot the scalability profile.
9+
Essential parameters, listed in the first lines, include the set of
10+
problem sizes and integration period.
11+
Each simulation is twofold. First, we run the Python forward solver that
12+
generates the ground-truth and observations ("ObservationsGenerator.py").
13+
The Python code itself uses the C++ code running in the special mode for
14+
generating sensor locations (scenario "sensors"). Second, the C++ data
15+
assimilation application is launched (scenario "simulation") with
16+
observations generated by "ObservationsGenerator.py".
17+
The results of all the simulations are accumulated in the output
18+
directory and can be visualized later on by the script "Visualize.py".
19+
The configuration file "amdados.conf" is used in all the simulations with
20+
modification of three parameters: grid sizes (number of subdomains) in both
21+
dimensions and integration time. Other parameters remain intact. It is not
22+
recommended to tweak parameters unless their meaning is absolutely clear.
23+
If you had modified the parameters, please, consider to rerun this script
24+
because the results in the output directory a not valid any longer.
25+
The script was designed to fulfil the formal requirements of the
26+
Allscale project.
27+
"""
28+
print(__doc__)
29+
30+
from timeit import default_timer as timer
31+
import os, cmd
32+
from RandObservationsGenerator import InitDependentParams, Amdados2D
33+
from Utility import *
34+
35+
36+
nthreads = np.arange(0,46,2)
37+
GridSizes = np.zeros([len(nthreads), 2])
38+
nthreads[0] = 1
39+
nthreads[1] = 3
40+
GridSizes[0:13, :] = ([4,2], [6,4], [8,4], [8,6],[8,8], [10,8],[12, 8],[16,7],
41+
[16,8], [12,12], [20,8], [16,11], [16,12])
42+
for i in range(13, len(GridSizes)):
43+
GridSizes[i, :] = [(i)*2, 8]
44+
problem_size= GridSizes[:,0]*GridSizes[:,1]
45+
46+
execute_time = np.zeros([len(nthreads), 4])
47+
# Integration period in seconds.
48+
IntegrationPeriod = 25
49+
IntegrationNsteps = 50
50+
# Path to the C++ executable.
51+
AMDADOS_EXE = "build/mpi_amdados"
52+
53+
54+
if __name__ == "__main__":
55+
try:
56+
# Read configuration file.
57+
conf = Configuration("amdados.conf")
58+
# Create the output directory, if it does not exist.
59+
if not os.path.isdir(conf.output_dir):
60+
os.mkdir(conf.output_dir)
61+
# Check existence of "amdados" application executable.
62+
assert os.path.isfile(AMDADOS_EXE), "amdados executable was not found"
63+
64+
# For all the grid sizes in the list ...
65+
exe_time_profile = np.zeros((len(GridSizes),2))
66+
for i in range(0, len(nthreads)):
67+
grid = GridSizes[i]
68+
Nproc = nthreads[i]
69+
# Modify parameters given the current grid size.
70+
setattr(conf, "num_subdomains_x", int(grid[0]))
71+
setattr(conf, "num_subdomains_y", int(grid[1]))
72+
setattr(conf, "integration_period", int(IntegrationPeriod))
73+
setattr(conf, "integration_nsteps", int(IntegrationNsteps))
74+
InitDependentParams(conf)
75+
conf.PrintParameters()
76+
config_file = conf.WriteParameterFile("scalability_test.conf")
77+
os.sync()
78+
# Python simulator generates the ground-truth and observations.
79+
Amdados2D(config_file, False)
80+
81+
# Get the starting time.
82+
start_time = timer()
83+
84+
# Run C++ data assimilation application.
85+
print("##################################################")
86+
print("Simulation by 'amdados' application for series of hpx threads")
87+
print("Initial simulations for Oceans paper")
88+
print("##################################################")
89+
print(AMDADOS_EXE, config_file)
90+
print("NPROC =", str(Nproc))
91+
output = subprocess.Popen(["mpirun", "--allow-run-as-root", "-np", str(Nproc),
92+
"./build/mpi_amdados", "--scenario", "simulation", "--config", config_file], stdout=subprocess.PIPE)
93+
output.wait()
94+
assert output.returncode == 0, "amdados returned non-zero status"
95+
96+
# Strip the execution time from stdout, both total simulation time
97+
# and throughput (subdomain/s)
98+
strip_output = str(output.communicate()[0]).split('\\n')
99+
for line in strip_output:
100+
if re.search("Simulation took", line):
101+
simtime_string = line
102+
if re.search("Throughput", line):
103+
throughput_string = line
104+
print('simtime read =', simtime_string)
105+
print('simtime string =', simtime_string.split(' ')[2][:-1])
106+
print('throughput string =', throughput_string.split(' ')[1])
107+
108+
simtime_secs = float(simtime_string.split(' ')[2][:-1])
109+
throughput_secs = float(throughput_string.split(' ')[1])
110+
111+
112+
# Get the execution time and corresponding (global) problem size
113+
# and save the current scalability profile into the file.
114+
problem_size = ( conf.num_subdomains_x * conf.num_subdomains_y )
115+
execute_time[i, :] = [problem_size, Nproc, simtime_secs, throughput_secs]
116+
np.savetxt(os.path.join(conf.output_dir, "scalability_performance_MPI.txt"),
117+
execute_time)
118+
119+
except subprocess.CalledProcessError as error:
120+
traceback.print_exc()
121+
if error.output is not None:
122+
print("ERROR: " + str(error.output))
123+
else:
124+
print("CalledProcessError")
125+
except AssertionError as error:
126+
traceback.print_exc()
127+
print("ERROR: " + str(error.args))
128+
except ValueError as error:
129+
traceback.print_exc()
130+
print("ERROR: " + str(error.args))
131+
except Exception as error:
132+
traceback.print_exc()
133+
print("ERROR: " + str(error.args))
134+

python/ScalabilityTestMT.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@
5757
# Read configuration file.
5858
conf = Configuration("amdados.conf")
5959
# Create the output directory, if it does not exist.
60-
if not os.path.isdir(conf.output_dir):
61-
if not os.path.islink(conf.output_dir):
62-
os.mkdir(conf.output_dir)
60+
if not os.path.isdir(conf.output_dir): os.mkdir(conf.output_dir)
6361
# Check existence of "amdados" application executable.
6462
assert os.path.isfile(AMDADOS_EXE), "amdados executable was not found"
6563

@@ -90,7 +88,6 @@
9088
print("##################################################")
9189
print("Simulation by 'amdados' application ...")
9290
print("silent if debugging & messaging were disabled")
93-
print("Number of workers: " + str(n))
9491
print("##################################################")
9592
proc = subprocess.Popen([AMDADOS_EXE,
9693
"--scenario", "simulation",

python/ScalabilityTestSize.py

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,36 +49,27 @@
4949
# This is a reasonable set of problems, be patient for days to come ...
5050
#GridSizes = [(11,11), (19,17), (23,25), (37,31), (43,41), (83,89)]
5151
# Small problems for a relatively brief testing.
52-
GridSizes = [(13,11), (17,13), (19,15), (23,21), (25,23), (27,25)]
52+
#GridSizes = [(13,11), (17,13), (19,15), (23,21), (25,23), (27,25)]
5353
#GridSizes = [(13,11), (18,16), (23,21), (29,27), (34,32), (39,37)]
54-
#GridSizes = [(2,2),(4,4),(8,8),(12,12),(16,16),(20,20),(24,24),(28,28),(32,32)]
54+
GridSizes = [(2,2),(4,4),(8,8),(12,12),(16,16),(20,20),(24,24),(28,28),(32,32)]
5555

5656
# Integration period in seconds.
57-
IntegrationPeriod = 9000
57+
IntegrationPeriod = 100
5858

59-
# Path to the C++ executable(s).
59+
# Path to the C++ executable.
6060
AMDADOS_EXE = "build/app/amdados"
61-
MPI_AMDADOS_EXE = "build/mpi_amdados"
61+
6262

6363
if __name__ == "__main__":
6464
try:
6565
CheckPythonVersion()
66-
parser = argparse.ArgumentParser()
67-
parser.add_argument("--mpi", type=bool, default=False,
68-
help="use MPI implementation instead of Allscale one")
69-
param = parser.parse_args()
7066
# Read configuration file.
7167
conf = Configuration("amdados.conf")
7268
# Create the output directory, if it does not exist.
7369
if not os.path.isdir(conf.output_dir):
7470
os.mkdir(conf.output_dir)
75-
# Check existence of "amdados" application executable(s).
76-
assert os.path.isfile(AMDADOS_EXE), (
77-
"Allscale amdados executable was not found")
78-
if param.mpi:
79-
assert os.path.isfile(MPI_AMDADOS_EXE), (
80-
"MPI amdados executable was not found")
81-
print("Running MPI implementation")
71+
# Check existence of "amdados" application executable.
72+
assert os.path.isfile(AMDADOS_EXE), "amdados executable was not found"
8273

8374
# For all the grid sizes in the list ...
8475
exe_time_profile = np.zeros((len(GridSizes),2))
@@ -100,21 +91,11 @@
10091
start_time = timer()
10192

10293
# Run C++ data assimilation application.
103-
if param.mpi:
104-
print("##################################################")
105-
print("Simulation with pure MPI Amdados application ...")
106-
print("silent if debugging & messaging were disabled")
107-
print("##################################################")
108-
subprocess.run(["mpirun", "-np", str(os.cpu_count()),
109-
"-f", "host_file", MPI_AMDADOS_EXE,
110-
"--scenario", "simulation",
111-
"--config", config_file], check=True)
112-
else:
113-
print("##################################################")
114-
print("Simulation with Allscale Amdados application ...")
115-
print("silent if debugging & messaging were disabled")
116-
print("##################################################")
117-
subprocess.run([AMDADOS_EXE, "--scenario", "simulation",
94+
print("##################################################")
95+
print("Simulation by 'amdados' application ...")
96+
print("silent if debugging & messaging were disabled")
97+
print("##################################################")
98+
subprocess.run([AMDADOS_EXE, "--scenario", "simulation",
11899
"--config", config_file], check=True)
119100

120101
# Get the execution time and corresponding (global) problem size

0 commit comments

Comments
 (0)