From 2f276a8f93c83869bb4e1cda485eb2588828c3f1 Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:59:01 +0000 Subject: [PATCH 1/7] Raise error if tracking not set up --- janus_core/helpers/log.py | 6 ++++++ tests/test_log.py | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/janus_core/helpers/log.py b/janus_core/helpers/log.py index 870b4446..5a78205d 100644 --- a/janus_core/helpers/log.py +++ b/janus_core/helpers/log.py @@ -200,6 +200,12 @@ def config_tracker( while carbon_logger.hasHandlers(): carbon_logger.removeHandler(carbon_logger.handlers[0]) + if not hasattr(tracker, "_emissions"): + raise ValueError( + "Carbon tracker has not been configured correctly. Please try " + "reconfiguring, or disable the tracker." + ) + else: tracker = None diff --git a/tests/test_log.py b/tests/test_log.py index 63a9593c..5fce17cf 100644 --- a/tests/test_log.py +++ b/tests/test_log.py @@ -2,9 +2,11 @@ from __future__ import annotations +from codecarbon import OfflineEmissionsTracker +import pytest import yaml -from janus_core.helpers.log import config_logger +from janus_core.helpers.log import config_logger, config_tracker from tests.utils import assert_log_contains @@ -30,3 +32,24 @@ def test_multiline_log(tmp_path): assert len(log_dicts[0]["message"]) == 3 assert_log_contains(log_path, includes=["Line 1", "Line 4"]) + + +def test_tracker(tmp_path): + """Test tracker can be correctly set up.""" + from pathlib import Path + + tmp_path = Path(".") + log_path = tmp_path / "test.log" + + logger = config_logger(name=__name__, filename=log_path) + tracker = config_tracker(janus_logger=logger) + assert isinstance(tracker, OfflineEmissionsTracker) + + +def test_tracker_error(tmp_path): + """Test tracker raises error if not set up correctly.""" + log_path = tmp_path / "test.log" + + logger = config_logger(name=__name__, filename=log_path) + with pytest.raises(ValueError): + config_tracker(janus_logger=logger, country_iso_code="TEST") From 219c318799fd056e014c5dfcc9e819914849744b Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:23:57 +0000 Subject: [PATCH 2/7] Add troubleshooting for carbon tracking --- docs/source/user_guide/index.rst | 1 + docs/source/user_guide/troubleshooting.rst | 56 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 docs/source/user_guide/troubleshooting.rst diff --git a/docs/source/user_guide/index.rst b/docs/source/user_guide/index.rst index 2926d959..172ea8f3 100644 --- a/docs/source/user_guide/index.rst +++ b/docs/source/user_guide/index.rst @@ -7,3 +7,4 @@ User guide command_line python + troubleshooting diff --git a/docs/source/user_guide/troubleshooting.rst b/docs/source/user_guide/troubleshooting.rst new file mode 100644 index 00000000..3abf419d --- /dev/null +++ b/docs/source/user_guide/troubleshooting.rst @@ -0,0 +1,56 @@ +=============== +Troubleshooting +=============== + +Carbon tracking +--------------- + +Enabling tracking (Python) +++++++++++++++++++++++++++ + +Carbon tracking can be enabled through the ``track_carbon`` option. +By default, this is ``True`` if logging is enabled, but requires setting ``attach_logger``, as this defaults to ``False``. + +For example, to track the carbon emissions during a single point calculation: + +.. code-block:: python + + from janus_core.calculations.single_point import SinglePoint + + sp = SinglePoint( + struct_path="tests/data/NaCl.cif", + attach_logger=True, + track_carbon=True, + ) + +This generates a log file, ``NaCl-singlepoint-log.yml``, which stores the emissions for the calculation. + + +In the case of multiple calculations, such as geometry optimisation triggered during molecular dynamics, +the emissions for each component of the calculation will be separate items in the log. + + +Disabling tracking (CLI) +++++++++++++++++++++++++ + +Currently, carbon tracking is enabled by default when using the command line interface, +saving the total calculating emissions to the generated summary file, as well as additional details and +per-calculation emissions to the log file. + +This can be disabled by passing the ``--no-tracker`` flag to any command. For example: + +.. code-block:: bash + + janus singlepoint --struct tests/data/NaCl.cif --no-tracker + + +Sudo access ++++++++++++ + +On some systems, such as MacOS, the carbon tracker may prompt for your password, if you have sudo access. +To avoid this, you can: + +1. Disable carbon tracking, as described in `Disabling tracking (CLI)`_. +3. Modify your sudoers file, as described `here `_, to provide sudo rights for all future calculations. +2. Provide your password. This may be saved for a period of time, but will need to be entered again in future. +4. Fail authentication, for example by entering an invalid or no password three times, which triggers the tracking to default to a constant power. From dd8e76a6cbf2749622951bd5875167719d07ef59 Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:47:46 +0000 Subject: [PATCH 3/7] Ensure track_carbon flag set correctly --- janus_core/calculations/base.py | 16 ++++++++++++---- janus_core/calculations/descriptors.py | 8 +++++--- janus_core/calculations/eos.py | 8 +++++--- janus_core/calculations/geom_opt.py | 8 +++++--- janus_core/calculations/md.py | 8 +++++--- janus_core/calculations/phonons.py | 8 +++++--- janus_core/calculations/single_point.py | 8 +++++--- janus_core/training/preprocess.py | 12 ++++++++++-- janus_core/training/train.py | 12 ++++++++++-- 9 files changed, 62 insertions(+), 26 deletions(-) diff --git a/janus_core/calculations/base.py b/janus_core/calculations/base.py index eb8b3756..f6b240e3 100644 --- a/janus_core/calculations/base.py +++ b/janus_core/calculations/base.py @@ -52,7 +52,8 @@ class BaseCalculation(FileNameMixin): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. file_prefix : PathLike | None @@ -85,7 +86,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, file_prefix: PathLike | None = None, additional_prefix: str | None = None, @@ -123,7 +124,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. file_prefix : PathLike | None @@ -146,12 +148,18 @@ def __init__( self.read_kwargs = read_kwargs self.calc_kwargs = calc_kwargs self.log_kwargs = log_kwargs - self.track_carbon = track_carbon self.tracker_kwargs = tracker_kwargs if not self.model_path and "model_path" in self.calc_kwargs: raise ValueError("`model_path` must be passed explicitly") + if not attach_logger: + if track_carbon: + raise ValueError("Carbon tracking requires logging to be enabled") + self.track_carbon = False + else: + self.track_carbon = track_carbon if track_carbon is not None else True + # Read structures and/or attach calculators # Note: logger not set up so yet so not passed here self.struct = input_structs( diff --git a/janus_core/calculations/descriptors.py b/janus_core/calculations/descriptors.py index 6b71a56e..e0494897 100644 --- a/janus_core/calculations/descriptors.py +++ b/janus_core/calculations/descriptors.py @@ -52,7 +52,8 @@ class Descriptors(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Default is True if + attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. invariants_only : bool @@ -85,7 +86,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, invariants_only: bool = True, calc_per_element: bool = False, @@ -122,7 +123,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. invariants_only : bool diff --git a/janus_core/calculations/eos.py b/janus_core/calculations/eos.py index bd7bc863..1c781b63 100644 --- a/janus_core/calculations/eos.py +++ b/janus_core/calculations/eos.py @@ -55,7 +55,8 @@ class EoS(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Default is True if + attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. min_volume : float @@ -117,7 +118,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, min_volume: float = 0.95, max_volume: float = 1.05, @@ -162,7 +163,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. min_volume : float diff --git a/janus_core/calculations/geom_opt.py b/janus_core/calculations/geom_opt.py index 6077fddd..856947cb 100644 --- a/janus_core/calculations/geom_opt.py +++ b/janus_core/calculations/geom_opt.py @@ -55,7 +55,8 @@ class GeomOpt(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. fmax : float @@ -109,7 +110,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, fmax: float = 0.1, steps: int = 1000, @@ -153,7 +154,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. fmax : float diff --git a/janus_core/calculations/md.py b/janus_core/calculations/md.py index 4a1119e0..cc25874f 100644 --- a/janus_core/calculations/md.py +++ b/janus_core/calculations/md.py @@ -75,7 +75,8 @@ class MolecularDynamics(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. struct : Atoms @@ -187,7 +188,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, ensemble: Ensembles | None = None, steps: int = 0, @@ -252,7 +253,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. ensemble : Ensembles diff --git a/janus_core/calculations/phonons.py b/janus_core/calculations/phonons.py index fd936fb6..dd1d41ef 100644 --- a/janus_core/calculations/phonons.py +++ b/janus_core/calculations/phonons.py @@ -60,7 +60,8 @@ class Phonons(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. calcs : MaybeSequence[PhononCalcs] | None @@ -165,7 +166,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, calcs: MaybeSequence[PhononCalcs] = (), supercell: MaybeList[int] = 2, @@ -218,7 +219,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. calcs : MaybeSequence[PhononCalcs] | None diff --git a/janus_core/calculations/single_point.py b/janus_core/calculations/single_point.py index 953f0070..c9bf27b9 100644 --- a/janus_core/calculations/single_point.py +++ b/janus_core/calculations/single_point.py @@ -56,7 +56,8 @@ class SinglePoint(BaseCalculation): log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. properties : MaybeSequence[Properties] @@ -92,7 +93,7 @@ def __init__( set_calc: bool | None = None, attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, properties: MaybeSequence[Properties] = (), write_results: bool = False, @@ -128,7 +129,8 @@ def __init__( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. properties : MaybeSequence[Properties] diff --git a/janus_core/training/preprocess.py b/janus_core/training/preprocess.py index 49b74a6f..869c0b74 100644 --- a/janus_core/training/preprocess.py +++ b/janus_core/training/preprocess.py @@ -19,7 +19,7 @@ def preprocess( req_file_keys: Sequence[PathLike] = ("train_file", "test_file", "valid_file"), attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, ) -> None: """ @@ -40,7 +40,8 @@ def preprocess( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. """ @@ -51,6 +52,13 @@ def preprocess( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) + if not attach_logger: + if track_carbon: + raise ValueError("Carbon tracking requires logging to be enabled") + track_carbon = False + else: + track_carbon = track_carbon if track_carbon is not None else True + # Configure logging if attach_logger: log_kwargs.setdefault("filename", "preprocess-log.yml") diff --git a/janus_core/training/train.py b/janus_core/training/train.py index 85ccefe4..0b785bcd 100644 --- a/janus_core/training/train.py +++ b/janus_core/training/train.py @@ -24,7 +24,7 @@ def train( ), attach_logger: bool = False, log_kwargs: dict[str, Any] | None = None, - track_carbon: bool = True, + track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, ) -> None: """ @@ -45,7 +45,8 @@ def train( log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. track_carbon : bool - Whether to track carbon emissions of calculation. Default is True. + Whether to track carbon emissions of calculation. Requires attach_logger. + Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_tracker`. Default is {}. """ @@ -56,6 +57,13 @@ def train( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) + if not attach_logger: + if track_carbon: + raise ValueError("Carbon tracking requires logging to be enabled") + track_carbon = False + else: + track_carbon = track_carbon if track_carbon is not None else True + # Configure logging if attach_logger: log_kwargs.setdefault("filename", "train-log.yml") From 4977e94d6c9c323e7db6718499a006efeab74246 Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:58:29 +0000 Subject: [PATCH 4/7] Pass tracking flag to sub-calculations --- janus_core/calculations/eos.py | 1 + janus_core/calculations/md.py | 1 + janus_core/calculations/phonons.py | 1 + 3 files changed, 3 insertions(+) diff --git a/janus_core/calculations/eos.py b/janus_core/calculations/eos.py index 1c781b63..3ca40a6f 100644 --- a/janus_core/calculations/eos.py +++ b/janus_core/calculations/eos.py @@ -265,6 +265,7 @@ def __init__( "name": self.logger.name, "filemode": "a", } + self.minimize_kwargs["track_carbon"] = self.track_carbon # Set output files self.write_kwargs.setdefault("filename", None) diff --git a/janus_core/calculations/md.py b/janus_core/calculations/md.py index cc25874f..dfa9f1d9 100644 --- a/janus_core/calculations/md.py +++ b/janus_core/calculations/md.py @@ -499,6 +499,7 @@ def __init__( "name": self.logger.name, "filemode": "a", } + self.minimize_kwargs["track_carbon"] = self.track_carbon self.dyn: Langevin | VelocityVerlet | ASE_NPT self.n_atoms = len(self.struct) diff --git a/janus_core/calculations/phonons.py b/janus_core/calculations/phonons.py index dd1d41ef..25938bef 100644 --- a/janus_core/calculations/phonons.py +++ b/janus_core/calculations/phonons.py @@ -353,6 +353,7 @@ def __init__( "name": self.logger.name, "filemode": "a", } + self.minimize_kwargs["track_carbon"] = self.track_carbon # Write out file by default self.minimize_kwargs.setdefault("write_results", True) From 25d8b31d3431be3c92a2e84c66625bec48c3f1c6 Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Thu, 12 Dec 2024 10:58:52 +0000 Subject: [PATCH 5/7] Allow extra kwargs to be passed to carbon tracker --- janus_core/helpers/log.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/janus_core/helpers/log.py b/janus_core/helpers/log.py index 5a78205d..0c19d19d 100644 --- a/janus_core/helpers/log.py +++ b/janus_core/helpers/log.py @@ -161,6 +161,7 @@ def config_tracker( country_iso_code: str = "GBR", save_to_file: bool = False, log_level: Literal["debug", "info", "warning", "error", "critical"] = "critical", + **kwargs, ) -> OfflineEmissionsTracker | None: """ Configure codecarbon tracker to log outputs. @@ -177,6 +178,8 @@ def config_tracker( Whether to also output results to a csv file. Default is False. log_level : Literal["debug", "info", "warning", "error", "critical"] Log level of internal carbon tracker log. Default is "critical". + **kwargs + Additional keyword arguments to pass to OfflineEmissionsTracker. Returns ------- @@ -193,6 +196,7 @@ def config_tracker( project_name="janus-core", log_level=log_level, allow_multiple_runs=True, + **kwargs, ) # Suppress further logging from codecarbon From 452a64b2db134a2ee603edf58e5e3d6149c98105 Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:19:08 +0000 Subject: [PATCH 6/7] Set attach_logger correctly --- janus_core/calculations/base.py | 21 ++++++++++++++------- janus_core/calculations/descriptors.py | 16 +++++++++------- janus_core/calculations/eos.py | 16 +++++++++------- janus_core/calculations/geom_opt.py | 12 +++++++----- janus_core/calculations/md.py | 16 +++++++++------- janus_core/calculations/phonons.py | 16 +++++++++------- janus_core/calculations/single_point.py | 16 +++++++++------- janus_core/training/preprocess.py | 12 +++++++++--- janus_core/training/train.py | 12 +++++++++--- 9 files changed, 84 insertions(+), 53 deletions(-) diff --git a/janus_core/calculations/base.py b/janus_core/calculations/base.py index f6b240e3..461cac7d 100644 --- a/janus_core/calculations/base.py +++ b/janus_core/calculations/base.py @@ -47,11 +47,12 @@ class BaseCalculation(FileNameMixin): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -84,7 +85,7 @@ def __init__( sequence_allowed: bool = True, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -119,11 +120,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -153,6 +155,11 @@ def __init__( if not self.model_path and "model_path" in self.calc_kwargs: raise ValueError("`model_path` must be passed explicitly") + if "filename" in log_kwargs: + attach_logger = True + else: + attach_logger = attach_logger if attach_logger else False + if not attach_logger: if track_carbon: raise ValueError("Carbon tracking requires logging to be enabled") diff --git a/janus_core/calculations/descriptors.py b/janus_core/calculations/descriptors.py index e0494897..f3a42eb7 100644 --- a/janus_core/calculations/descriptors.py +++ b/janus_core/calculations/descriptors.py @@ -47,11 +47,12 @@ class Descriptors(BaseCalculation): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -84,7 +85,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -118,11 +119,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/calculations/eos.py b/janus_core/calculations/eos.py index 3ca40a6f..236e3fa9 100644 --- a/janus_core/calculations/eos.py +++ b/janus_core/calculations/eos.py @@ -50,11 +50,12 @@ class EoS(BaseCalculation): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -116,7 +117,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -158,11 +159,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/calculations/geom_opt.py b/janus_core/calculations/geom_opt.py index 856947cb..cb26e227 100644 --- a/janus_core/calculations/geom_opt.py +++ b/janus_core/calculations/geom_opt.py @@ -51,10 +51,11 @@ class GeomOpt(BaseCalculation): set_calc : bool | None Whether to set (new) calculators for structures. Default is None. attach_logger : bool - Whether to attach a logger. Default is False. + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -108,7 +109,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -150,10 +151,11 @@ def __init__( set_calc : bool | None Whether to set (new) calculators for structures. Default is None. attach_logger : bool - Whether to attach a logger. Default is False. + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/calculations/md.py b/janus_core/calculations/md.py index dfa9f1d9..3a0a65f1 100644 --- a/janus_core/calculations/md.py +++ b/janus_core/calculations/md.py @@ -70,11 +70,12 @@ class MolecularDynamics(BaseCalculation): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -186,7 +187,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -248,11 +249,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/calculations/phonons.py b/janus_core/calculations/phonons.py index 25938bef..64b9047f 100644 --- a/janus_core/calculations/phonons.py +++ b/janus_core/calculations/phonons.py @@ -55,11 +55,12 @@ class Phonons(BaseCalculation): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -164,7 +165,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -214,11 +215,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/calculations/single_point.py b/janus_core/calculations/single_point.py index c9bf27b9..07db9d4a 100644 --- a/janus_core/calculations/single_point.py +++ b/janus_core/calculations/single_point.py @@ -51,11 +51,12 @@ class SinglePoint(BaseCalculation): Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -91,7 +92,7 @@ def __init__( read_kwargs: ASEReadArgs | None = None, calc_kwargs: dict[str, Any] | None = None, set_calc: bool | None = None, - attach_logger: bool = False, + attach_logger: bool | None = None, log_kwargs: dict[str, Any] | None = None, track_carbon: bool | None = None, tracker_kwargs: dict[str, Any] | None = None, @@ -124,11 +125,12 @@ def __init__( Keyword arguments to pass to the selected calculator. Default is {}. set_calc : bool | None Whether to set (new) calculators for structures. Default is None. - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None diff --git a/janus_core/training/preprocess.py b/janus_core/training/preprocess.py index 869c0b74..392d2b4b 100644 --- a/janus_core/training/preprocess.py +++ b/janus_core/training/preprocess.py @@ -35,11 +35,12 @@ def preprocess( req_file_keys : Sequence[PathLike] List of files that must exist if defined in the configuration file. Default is ("train_file", "test_file", "valid_file"). - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -52,6 +53,11 @@ def preprocess( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) + if "filename" in log_kwargs: + attach_logger = True + else: + attach_logger = attach_logger if attach_logger else False + if not attach_logger: if track_carbon: raise ValueError("Carbon tracking requires logging to be enabled") diff --git a/janus_core/training/train.py b/janus_core/training/train.py index 0b785bcd..70fbdd92 100644 --- a/janus_core/training/train.py +++ b/janus_core/training/train.py @@ -40,11 +40,12 @@ def train( req_file_keys : Sequence[PathLike] List of files that must exist if defined in the configuration file. Default is ("train_file", "test_file", "valid_file", "statistics_file"). - attach_logger : bool - Whether to attach a logger. Default is False. + attach_logger : bool | None + Whether to attach a logger. Default is True if "filename" is passed in + log_kwargs, else False. log_kwargs : dict[str, Any] | None Keyword arguments to pass to `config_logger`. Default is {}. - track_carbon : bool + track_carbon : bool | None Whether to track carbon emissions of calculation. Requires attach_logger. Default is True if attach_logger is True, else False. tracker_kwargs : dict[str, Any] | None @@ -57,6 +58,11 @@ def train( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) + if "filename" in log_kwargs: + attach_logger = True + else: + attach_logger = attach_logger if attach_logger else False + if not attach_logger: if track_carbon: raise ValueError("Carbon tracking requires logging to be enabled") From 81f8b9dae9d0d282eda43310e3fcdd565cc2054d Mon Sep 17 00:00:00 2001 From: ElliottKasoar <45317199+ElliottKasoar@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:32:46 +0000 Subject: [PATCH 7/7] Refactor setting log and tracker defaults --- janus_core/calculations/base.py | 16 ++++---------- janus_core/helpers/utils.py | 35 +++++++++++++++++++++++++++++++ janus_core/training/preprocess.py | 16 ++++---------- janus_core/training/train.py | 16 ++++---------- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/janus_core/calculations/base.py b/janus_core/calculations/base.py index 461cac7d..22b5a9e6 100644 --- a/janus_core/calculations/base.py +++ b/janus_core/calculations/base.py @@ -16,7 +16,7 @@ ) from janus_core.helpers.log import config_logger, config_tracker from janus_core.helpers.struct_io import input_structs -from janus_core.helpers.utils import FileNameMixin, none_to_dict +from janus_core.helpers.utils import FileNameMixin, none_to_dict, set_log_tracker class BaseCalculation(FileNameMixin): @@ -155,17 +155,9 @@ def __init__( if not self.model_path and "model_path" in self.calc_kwargs: raise ValueError("`model_path` must be passed explicitly") - if "filename" in log_kwargs: - attach_logger = True - else: - attach_logger = attach_logger if attach_logger else False - - if not attach_logger: - if track_carbon: - raise ValueError("Carbon tracking requires logging to be enabled") - self.track_carbon = False - else: - self.track_carbon = track_carbon if track_carbon is not None else True + attach_logger, self.track_carbon = set_log_tracker( + attach_logger, log_kwargs, track_carbon + ) # Read structures and/or attach calculators # Note: logger not set up so yet so not passed here diff --git a/janus_core/helpers/utils.py b/janus_core/helpers/utils.py index 32ed6043..b1976c32 100644 --- a/janus_core/helpers/utils.py +++ b/janus_core/helpers/utils.py @@ -517,3 +517,38 @@ def selector_len(slc: SliceLike | list, selectable_length: int) -> int: if stop is None: stop = selectable_length return len(range(start, stop, step)) + + +def set_log_tracker( + attach_logger: bool, log_kwargs: dict, track_carbon: bool +) -> tuple[bool, bool]: + """ + Set attach_logger and track_carbon default values. + + Parameters + ---------- + attach_logger : bool + Whether to attach a logger. + log_kwargs : dict[str, Any] + Keyword arguments to pass to `config_logger`. + track_carbon : bool + Whether to track carbon emissions of calculation. + + Returns + ------- + tuple[bool, bool] + Default values for attach_logger and track_carbon. + """ + if "filename" in log_kwargs: + attach_logger = True + else: + attach_logger = attach_logger if attach_logger else False + + if not attach_logger: + if track_carbon: + raise ValueError("Carbon tracking requires logging to be enabled") + track_carbon = False + else: + track_carbon = track_carbon if track_carbon is not None else True + + return attach_logger, track_carbon diff --git a/janus_core/training/preprocess.py b/janus_core/training/preprocess.py index 392d2b4b..dd02536f 100644 --- a/janus_core/training/preprocess.py +++ b/janus_core/training/preprocess.py @@ -11,7 +11,7 @@ from janus_core.helpers.janus_types import PathLike from janus_core.helpers.log import config_logger, config_tracker -from janus_core.helpers.utils import check_files_exist, none_to_dict +from janus_core.helpers.utils import check_files_exist, none_to_dict, set_log_tracker def preprocess( @@ -53,17 +53,9 @@ def preprocess( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) - if "filename" in log_kwargs: - attach_logger = True - else: - attach_logger = attach_logger if attach_logger else False - - if not attach_logger: - if track_carbon: - raise ValueError("Carbon tracking requires logging to be enabled") - track_carbon = False - else: - track_carbon = track_carbon if track_carbon is not None else True + attach_logger, track_carbon = set_log_tracker( + attach_logger, log_kwargs, track_carbon + ) # Configure logging if attach_logger: diff --git a/janus_core/training/train.py b/janus_core/training/train.py index 70fbdd92..8abc33f7 100644 --- a/janus_core/training/train.py +++ b/janus_core/training/train.py @@ -11,7 +11,7 @@ from janus_core.helpers.janus_types import PathLike from janus_core.helpers.log import config_logger, config_tracker -from janus_core.helpers.utils import check_files_exist, none_to_dict +from janus_core.helpers.utils import check_files_exist, none_to_dict, set_log_tracker def train( @@ -58,17 +58,9 @@ def train( options = yaml.safe_load(file) check_files_exist(options, req_file_keys) - if "filename" in log_kwargs: - attach_logger = True - else: - attach_logger = attach_logger if attach_logger else False - - if not attach_logger: - if track_carbon: - raise ValueError("Carbon tracking requires logging to be enabled") - track_carbon = False - else: - track_carbon = track_carbon if track_carbon is not None else True + attach_logger, track_carbon = set_log_tracker( + attach_logger, log_kwargs, track_carbon + ) # Configure logging if attach_logger: