Skip to content

Commit

Permalink
Refactor set_counter() and some bug fixes
Browse files Browse the repository at this point in the history
- Fix to payu crashing with empty restart files/dirs
- Add default values of LD_LIBRARY_PATHS
- Raise exceptions for missing model executables
  • Loading branch information
Jo Basevi committed Sep 22, 2023
1 parent 2d16f18 commit b476d21
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 36 deletions.
73 changes: 37 additions & 36 deletions payu/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import errno
import getpass
import os
import re
import resource
import sys
import shlex
Expand Down Expand Up @@ -172,41 +173,40 @@ def set_counters(self):

# Initialize counter if unset
if self.counter is None:
# TODO: this logic can probably be streamlined
try:
restart_dirs = [d for d in os.listdir(self.archive_path)
if d.startswith('restart')]
except EnvironmentError as exc:
if exc.errno == errno.ENOENT:
restart_dirs = None
else:
raise

# First test for restarts
if restart_dirs:
self.counter = 1 + max([int(d.lstrip('restart'))
for d in restart_dirs
if d.startswith('restart')])
# Check for restart index
max_restart_index = self.max_output_index(output_type="restart")
if max_restart_index:
self.counter = 1 + max_restart_index
else:
# repeat runs do not generate restart files, so check outputs
try:
output_dirs = [d for d in os.listdir(self.archive_path)
if d.startswith('output')]
except EnvironmentError as exc:
if exc.errno == errno.ENOENT:
output_dirs = None
else:
raise

# First test for restarts
# Now look for output directories
if output_dirs:
self.counter = 1 + max([int(d.lstrip('output'))
for d in output_dirs
if d.startswith('output')])
# Now look for output directories,
# as repeat runs do not generate restart files.
max_output_index = self.max_output_index()
if max_output_index:
self.counter = 1 + max_output_index
else:
self.counter = 0

def max_output_index(self, output_type="output"):
"""Given a output directory type (output or restart),
return the maximum index of output directories found"""
try:
output_dirs = self.list_output_dirs(output_type)
except EnvironmentError as exc:
if exc.errno == errno.ENOENT:
output_dirs = None
else:
raise

if output_dirs and len(output_dirs):
return max([int(d.lstrip(output_type))
for d in output_dirs])

def list_output_dirs(self, output_type="output"):
"""Return a list of restart or output directories in archive"""
naming_pattern = re.compile(fr"^{output_type}[0-9][0-9][0-9]$")
return [d for d in os.listdir(self.archive_path)
if naming_pattern.match(d)]

def set_stacksize(self, stacksize):

if stacksize == 'unlimited':
Expand Down Expand Up @@ -749,8 +749,7 @@ def archive(self):
default_restart_history)

# Remove any outdated restart files
prior_restart_dirs = [d for d in os.listdir(self.archive_path)
if d.startswith('restart')]
prior_restart_dirs = self.list_output_dirs(output_type="restart")

for res_dir in prior_restart_dirs:

Expand All @@ -766,10 +765,12 @@ def archive(self):
shutil.rmtree(res_path)

# Ensure dynamic library support for subsequent python calls
ld_libpaths = os.environ['LD_LIBRARY_PATH']
ld_libpaths = os.environ.get('LD_LIBRARY_PATH', None)
py_libpath = sysconfig.get_config_var('LIBDIR')
if py_libpath not in ld_libpaths.split(':'):
os.environ['LD_LIBRARY_PATH'] = ':'.join([py_libpath, ld_libpaths])
if ld_libpaths is None:
os.environ['LD_LIBRARY_PATH'] = py_libpath
elif py_libpath not in ld_libpaths.split(':'):
os.environ['LD_LIBRARY_PATH'] = f'{py_libpath}:{ld_libpaths}'

collate_config = self.config.get('collate', {})
collating = collate_config.get('enable', True)
Expand Down
4 changes: 4 additions & 0 deletions payu/models/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ def setup(self):

# Make symlink to executable in work directory
if self.exec_path:
# Check whether executable path exists
if not os.path.isfile(self.exec_path):
raise FileNotFoundError(f'Executable not found on path: {self.exec_path}')

# If have exe manifest this implies exe reproduce is True. Do not
# want to overwrite exe manifest in this case
if not self.expt.manifest.have_manifest['exe']:
Expand Down

0 comments on commit b476d21

Please sign in to comment.