Skip to content

Commit

Permalink
Add --allow-changes for resume (#374)
Browse files Browse the repository at this point in the history
  • Loading branch information
cmbant authored Aug 9, 2024
1 parent 0bbb34d commit dede10b
Show file tree
Hide file tree
Showing 9 changed files with 2,137 additions and 1,836 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 3.5.3

- added --allow-changes option to cobaya-run to allow changes in the input file
- Updates for deprecation warnings
- Minor optimization refactor and doc update

## 3.5.2

- Updates for numpy 2 and other compatibility fixes
Expand Down
2 changes: 1 addition & 1 deletion cobaya/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@


__author__ = "Jesus Torrado and Antony Lewis"
__version__ = "3.5.2"
__version__ = "3.5.3"
__obsolete__ = False
__year__ = "2024"
__url__ = "https://cobaya.readthedocs.io"
22 changes: 7 additions & 15 deletions cobaya/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,15 +463,15 @@ def check_and_dump_info(self, input_info, updated_info, check_compatible=True,
- idem, populated with the components' defaults.
If resuming a sample, checks first that old and new infos and versions are
consistent.
consistent unless allow_changes is True.
"""
# trim known params of each likelihood: for internal use only
self.check_lock()
updated_info_trimmed = deepcopy_where_possible(updated_info)
updated_info_trimmed["version"] = get_version()
for like_info in updated_info_trimmed.get("likelihood", {}).values():
(like_info or {}).pop("params", None)
if check_compatible:
if check_compatible or cache_old:
# We will test the old info against the dumped+loaded new info.
# This is because we can't actually check if python objects do change
try:
Expand All @@ -481,21 +481,16 @@ def check_and_dump_info(self, input_info, updated_info, check_compatible=True,
# for example, when there's a dynamically generated class that cannot
# be found by the yaml loader (could use yaml loader that ignores them)
old_info = None
if old_info:
# use consistent yaml read-in types
# TODO: could probably just compare full infos here, with externals?
# for the moment cautiously keeping old behaviour
old_info = yaml_load(yaml_dump(old_info)) # type: ignore
if old_info.get("test"):
old_info = None
if old_info:
if check_compatible and old_info and not old_info.get("test"):
old_info = yaml_load(yaml_dump(old_info))
new_info = yaml_load(yaml_dump(updated_info_trimmed))
if not is_equal_info(old_info, new_info, strict=False,
ignore_blocks=list(ignore_blocks) + [
"output"]):
raise LoggedError(
self.log, "Old and new run information not compatible! "
"Resuming not possible!")
"Resuming not possible!\n"
"Use --allow-changes to proceed anyway.")
# Deal with version comparison separately:
# - If not specified now, take the one used in resume info
# - If specified both now and before, check new older than old one
Expand Down Expand Up @@ -540,11 +535,8 @@ def check_and_dump_info(self, input_info, updated_info, check_compatible=True,
for f, info in [(self.file_input, input_info),
(self.file_updated, updated_info_trimmed)]:
if info:
for k in ignore_blocks:
for k in tuple(ignore_blocks) + ("debug", "force", "resume"):
info.pop(k, None)
info.pop("debug", None)
info.pop("force", None)
info.pop("resume", None)
# make sure the dumped output prefix does only contain the file prefix,
# not the folder, since it's already been placed inside it
info["output"] = self.updated_prefix()
Expand Down
7 changes: 7 additions & 0 deletions cobaya/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def run(info_or_yaml_or_file: Union[InputDict, str, os.PathLike],
minimize: Optional[bool] = None,
no_mpi: bool = False, test: Optional[bool] = None,
override: Optional[InputDict] = None,
allow_changes: bool = False
) -> Tuple[InputDict, Union[Sampler, PostResult]]:
"""
Run from an input dictionary, file name or yaml string, with optional arguments
Expand All @@ -51,6 +52,7 @@ def run(info_or_yaml_or_file: Union[InputDict, str, os.PathLike],
:param test: only test initialization rather than actually running
:param override: option dictionary to merge into the input one, overriding settings
(but with lower precedence than the explicit keyword arguments)
:param allow_changes: if true, allow input option changes when resuming or minimizing
:return: (updated_info, sampler) tuple of options dictionary and Sampler instance,
or (updated_info, post_results) if using "post" post-processing
"""
Expand Down Expand Up @@ -103,6 +105,7 @@ def run(info_or_yaml_or_file: Union[InputDict, str, os.PathLike],
# 3. If output requested, check compatibility if existing one, and dump.
# 3.1 First: model only
out.check_and_dump_info(info, updated_info, cache_old=True,
check_compatible=not allow_changes,
ignore_blocks=["sampler"])
# 3.2 Then sampler -- 1st get the first sampler mentioned in the updated.yaml
if not (info_sampler := updated_info.get("sampler")):
Expand Down Expand Up @@ -177,6 +180,10 @@ def run_script(args=None):
help=("Replaces the sampler in the input and runs a minimization "
"process (incompatible with post-processing)."),
**trueNone_kwargs)
parser.add_argument("--allow-changes",
help="Allow changing input parameters when resuming "
"or minimizing, skipping consistency checks",
**trueNone_kwargs)
parser.add_argument("--version", action="version", version=get_version())
parser.add_argument("--no-mpi",
help=("disable MPI when mpi4py installed but MPI does "
Expand Down
Loading

0 comments on commit dede10b

Please sign in to comment.