From 42bdeed93c38d534589823100f39373fa538de62 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 19 Dec 2019 15:45:06 +0100 Subject: [PATCH 1/2] .hdf5 files are now forcibly closed (if necessary) upon restarting an ARMC procedure --- FOX/classes/armc.py | 14 +++++++++++++- FOX/io/hdf5_utils.py | 17 ++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/FOX/classes/armc.py b/FOX/classes/armc.py index 54cc900b..84ceee27 100644 --- a/FOX/classes/armc.py +++ b/FOX/classes/armc.py @@ -32,7 +32,9 @@ from .monte_carlo import MonteCarlo from ..logger import Plams2Logger, get_logger -from ..io.hdf5_utils import create_hdf5, to_hdf5, create_xyz_hdf5, _get_filename_xyz +from ..io.hdf5_utils import ( + create_hdf5, to_hdf5, create_xyz_hdf5, _get_filename_xyz, hdf5_clear_status +) from ..io.file_container import NullContext from ..functions.utils import get_template from ..armc_functions.sanitization import init_armc_sanitization @@ -520,6 +522,16 @@ def restart(self) -> None: if not os.path.isfile(xyz): create_xyz_hdf5(self.hdf5_file, self.molecule, iter_len=self.sub_iter_len) + # Check that both .hdf5 files can be opened; clear their status if not + closed = hdf5_clear_status(xyz) + if not closed: + self.logger.warning(f"Unable to open ...{os.sep}{os.path.basename(xyz)}, " + "file status was forcibly reset") + closed = hdf5_clear_status(self.hdf5_file) + if not closed: + self.logger.warning(f"Unable to open ...{os.sep}{os.path.basename(self.hdf5_file)}, " + "file status was forcibly reset") + # Finish the current set of sub-iterations j += 1 for omega in range(j, self.sub_iter_len): diff --git a/FOX/io/hdf5_utils.py b/FOX/io/hdf5_utils.py index 078655b1..5afd79ab 100644 --- a/FOX/io/hdf5_utils.py +++ b/FOX/io/hdf5_utils.py @@ -42,6 +42,7 @@ """ +import subprocess from os import remove from time import sleep from typing import Dict, Iterable, Optional, Union, Hashable, List, Tuple @@ -300,6 +301,17 @@ def _get_kwarg_dict(armc: 'FOX.ARMC') -> Settings: """################################### Updating .hdf5 files ####################################""" +@assert_error(H5PY_ERROR) +def hdf5_clear_status(filename: str) -> bool: + """Run the :code:`h5clear filename` command if **filename** refuses to open.""" + try: + with h5py.File(filename, 'r+', libver='latest'): + return True + except OSError: + subprocess.run(['h5clear', '-s', 'repr(filename)']) + return False + + @assert_error(H5PY_ERROR) def hdf5_availability(filename: str, timeout: float = 5.0, max_attempts: Optional[int] = 10) -> None: @@ -334,7 +346,7 @@ def hdf5_availability(filename: str, timeout: float = 5.0, while i: try: - with h5py.File(filename, 'r+', libver='latest') as _: + with h5py.File(filename, 'r+', libver='latest'): return # the .hdf5 file can safely be opened except OSError as ex: # the .hdf5 file cannot be safely opened yet print((warning).format(filename, timeout)) @@ -405,6 +417,9 @@ def _xyz_to_hdf5(filename: str, omega: int, All to-be exported :class:`MultiMolecule` instance(s) or float (*e.g.* ``np.nan``). """ + # Check if the hdf5 file is already opened. If opened: wait for 5 sec and try again. + hdf5_availability(filename) + with h5py.File(filename, 'r+', libver='latest') as f: if not isinstance(mol_list, abc.Iterable): # Check if mol_list is a scalar (np.nan) i = 0 From 1d0f0bb1f11022eadd937bfdeaae972e71eada99 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 19 Dec 2019 15:46:16 +0100 Subject: [PATCH 2/2] Update hdf5_utils.py --- FOX/io/hdf5_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FOX/io/hdf5_utils.py b/FOX/io/hdf5_utils.py index 5afd79ab..b6621281 100644 --- a/FOX/io/hdf5_utils.py +++ b/FOX/io/hdf5_utils.py @@ -341,7 +341,7 @@ def hdf5_availability(filename: str, timeout: float = 5.0, Raised if **max_attempts** is exceded. """ - warning = "OSWarning: '{}' is currently unavailable; repeating attempt in {:.0f} seconds" + warning = "WARNING: '{}' is currently unavailable; repeating attempt in {:.0f} seconds" i = max_attempts or np.inf while i: