forked from crp/ecp-benchmarks
85 lines
3 KiB
Python
85 lines
3 KiB
Python
"""A parametric study over MPI procs and OMP threads for a benchmark."""
|
|
|
|
import os
|
|
import glob
|
|
import numpy as np
|
|
import openmc
|
|
|
|
# Query user for benchmark to profile (i.e., '2x2-periodic')
|
|
benchmark = input('Benchmark: ')
|
|
os.chdir(benchmark)
|
|
|
|
# Query user for hardware platform to consider
|
|
platform = os.environ['HOSTNAME']
|
|
|
|
# Default MPI+OMP runtime parameters for Phi/Haswell
|
|
if 'thing' in platform:
|
|
platform = 'haswell'
|
|
mpi_procs = [1, 2, 4, 8, 36, 72]
|
|
omp_threads = [72, 36, 18, 9, 2, 1]
|
|
else:
|
|
platform = 'phi'
|
|
mpi_procs = [4, 4, 4, 64, 64, 64]
|
|
omp_threads = [16, 32, 64, 1, 2, 4]
|
|
|
|
# Allocate arrays for timing data for inactive and active cycles
|
|
times = np.zeros((len(mpi_procs),2), dtype=np.int)
|
|
|
|
# Instantiate a Summary object to retrieve the geometry
|
|
su = openmc.Summary('summary.h5')
|
|
|
|
for i, xs in enumerate(['ace', 'multipole']):
|
|
|
|
# Construct uniform initial source distribution over fissionable zones
|
|
lower_left = su.opencg_geometry.bounds[:2] + [-10.]
|
|
upper_right = su.opencg_geometry.bounds[3:5] + [10.]
|
|
source = openmc.source.Source(space=openmc.stats.Box(lower_left, upper_right))
|
|
source.space.only_fissionable = True
|
|
|
|
settings_file = openmc.Settings()
|
|
settings_file.batches = 10
|
|
settings_file.inactive = 5
|
|
settings_file.particles = 10000
|
|
settings_file.ptables = True
|
|
settings_file.output = {'tallies': False}
|
|
settings_file.source = source
|
|
settings_file.sourcepoint_write = False
|
|
|
|
if xs == 'multipole':
|
|
settings_file.temperature = {'multipole': True, 'tolerance': 1000}
|
|
|
|
settings_file.export_to_xml()
|
|
|
|
for j, (procs, threads) in enumerate(zip(mpi_procs, omp_threads)):
|
|
|
|
# Run OpenMC - works for both flat and cache memory modes
|
|
#openmc.run(threads=threads, mpi_procs=procs,
|
|
# mpi_exec='HYDRA_TOPO_DEBUG=1 mpiexec -bind-to numa')
|
|
|
|
# Run OpenMC - works for both flat mode with MCDRAM only
|
|
#openmc.run(threads=threads, mpi_procs=procs,
|
|
# mpi_exec='HYDRA_TOPO_DEBUG=1 mpiexec -bind-to core:16 numactl --preferred 4,5,6,7')
|
|
|
|
# Run OpenMC - works for both flat and cache memory modes
|
|
openmc.run(threads=threads, mpi_procs=procs,
|
|
mpi_exec='HYDRA_TOPO_DEBUG=1 mpiexec -bind-to core:16')
|
|
|
|
# Glob the names of all statepoints in the directory
|
|
sp_filenames = glob.glob('statepoint.*.h5')
|
|
|
|
# Load the final statepoint
|
|
sp = openmc.StatePoint(sp_filenames[0])
|
|
|
|
# Extract cumulative time spent in (in)active cycles in seconds
|
|
inactive = sp.runtime['inactive batches']
|
|
active = sp.runtime['active batches']
|
|
|
|
# Convert times to neutrons / second
|
|
times[j,0] = int((sp.n_inactive * sp.n_particles) / inactive)
|
|
times[j,1] = int((sp.n_realizations * sp.n_particles) / active)
|
|
|
|
print('inactive time (n / sec): {}'.format(times[j,0]))
|
|
print('active time (n / sec): {}'.format(times[j,1]))
|
|
|
|
# Save timing data to CSV files
|
|
np.savetxt('{}-{}.csv'.format(platform, xs), times, delimiter=',', fmt='%d')
|