Skip to content

Commit

Permalink
examples added MPI capabilities natively to base example, allow user …
Browse files Browse the repository at this point in the history
…to flag '--with_mpi' when running example, removed example 4 since we can just run example 3 with MPI which is the same thing
  • Loading branch information
bch0w committed Sep 10, 2022
1 parent 4ff549c commit 8d29f65
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 158 deletions.
153 changes: 0 additions & 153 deletions seisflows/examples/ex4_multicore_fwd.py

This file was deleted.

52 changes: 47 additions & 5 deletions seisflows/examples/sfexample2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class SFExample2D:
multiple example runs can benefit from the code written here
"""
def __init__(self, ntask=None, event_id=None, niter=None, nsta=None,
nproc=None, method="run", specfem2d_repo=None, **kwargs):
nproc=None, method="run", specfem2d_repo=None, with_mpi=False,
mpiexec="mpirun", **kwargs):
"""
Set path structure which is used to navigate around SPECFEM repositories
and the example working directory
Expand All @@ -70,6 +71,13 @@ def __init__(self, ntask=None, event_id=None, niter=None, nsta=None,
:param specfem2d_repo: path to the SPECFEM2D directory which should
contain binary executables. If not given, SPECFEM2D will be
downloaded configured and compiled automatically.
:type with_mpi: bool
:param with_mpi: run the example problem with MPI. That is, runs the
Solver with an MPI executable. All other tasks are run in serial.
:type mpiexec: str
:param mpiexec: MPI executable used to run MPI tasks. Defaults to
'mpiexec' but User is allowed to choose incase their system has
different MPI run call.
"""
self.cwd = os.getcwd()
self.sem2d_paths, self.workdir_paths = self.define_dir_structures(
Expand All @@ -96,6 +104,7 @@ def __init__(self, ntask=None, event_id=None, niter=None, nsta=None,
# -1 because it represents index but we need to talk in terms of count
assert(1 <= self.nsta <= 132), \
f"number of stations must be between 1 and 131, not {self.nsta}"

self.nproc = nproc or 1 # must be 1 for Examples 1-3

# This bool information is provided by the User running 'setup' or 'run'
Expand Down Expand Up @@ -132,8 +141,16 @@ def __init__(self, ntask=None, event_id=None, niter=None, nsta=None,
"path_model_true": self.workdir_paths.model_true,
}

# Used to configure SPECFEM2D binaries
self._configure_cmd = "./configure"
# Determine if we are running serial or parallel solver tasks
if with_mpi:
self.mpiexec = mpiexec
self._parameters["mpiexec"] = self.mpiexec # Pass on to workflow
self.check_mpi_executable()
self._configure_cmd = \
"./configure FC=gfortran CC=gcc MPIF90=mpif90 --with-mpi"
else:
self.mpixec = None
self._configure_cmd = "./configure"

def print_dialogue(self):
"""
Expand All @@ -157,6 +174,26 @@ def print_dialogue(self):
border="=")
)

def check_mpi_executable(self):
"""
If User wants to run examples with MPI, checks that MPI executable is
available and can be used to run solver. Sometimes if we don't
'$ module load mpi', we will get 'mpirun: command not found'
"""
try:
subprocess.run(f"which {self.mpiexec}", check=True, shell=True,
stdout=subprocess.DEVNULL)
except subprocess.CalledProcessError:
print(
msg.cli(f"MPI executable '{self.mpiexec}' not found on "
f"system. Please check that you have MPI "
f"installed/loaded. If '{self.mpiexec}' is not how you "
f"invoke MPI, use the flag `--mpiexec $MPIFLAG` when "
f"running the example to change the default exectable",
header="missing mpi", border="=")
)
sys.exit(-1)

@staticmethod
def define_dir_structures(cwd, specfem2d_repo, ex="Tape2007"):
"""
Expand Down Expand Up @@ -335,8 +372,13 @@ def run_xspecfem2d_binaries(self):
"""
cd(self.workdir_paths.workdir)

cmd_mesh = f"./bin/xmeshfem2D > OUTPUT_FILES/mesher.log.txt"
cmd_spec = f"./bin/xspecfem2D > OUTPUT_FILES/solver.log.txt"
if self.mpiexec:
mpicmd = f"{self.mpiexec} -n {self.nproc}"
cmd_mesh = f"{mpicmd} bin/xmeshfem2D > OUTPUT_FILES/mesher.log.txt"
cmd_spec = f"{mpicmd} bin/xspecfem2D > OUTPUT_FILES/solver.log.txt"
else:
cmd_mesh = f"./bin/xmeshfem2D > OUTPUT_FILES/mesher.log.txt"
cmd_spec = f"./bin/xspecfem2D > OUTPUT_FILES/solver.log.txt"

for cmd in [cmd_mesh, cmd_spec]:
print(f"Running SPECFEM2D with command: {cmd}")
Expand Down
5 changes: 5 additions & 0 deletions seisflows/seisflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ def _format_action(self, action):
"the Tape 2007 example (1 <= EVENT_ID <= 25). "
"If not used, example will default to choosing "
"sequential from 1 to NTASK")
examples.add_argument("--with_mpi", action="store_true", default=False,
help="Run Solver with MPI using MPI exectuable "
"`mpiexec` (defaults to 'mpirun'). Defaults to "
"False, in which case executables are run "
"in serial")
examples.add_argument("--mpiexec", type=str, nargs="?", default="mpirun",
help="Only for Example(s) 4. MPI executable to use "
"when running SPECFEM2D with MPI. Defaults to "
Expand Down

0 comments on commit 8d29f65

Please sign in to comment.