aiida_cp2k.workchains package

Submodules

aiida_cp2k.workchains.aiida_base_restart module

Base implementation of WorkChain class that implements a simple automated restart mechanism for calculations.

class aiida_cp2k.workchains.aiida_base_restart.BaseRestartWorkChain(*args, **kwargs)[source]

Bases: aiida.engine.processes.workchains.workchain.WorkChain

Base restart work chain

This work chain serves as the starting point for more complex work chains that will be designed to run a calculation that might need multiple restarts to come to a successful end. These restarts may be necessary because a single calculation run is not sufficient to achieve a fully converged result, or certain errors maybe encountered which are recoverable.

This work chain implements the most basic functionality to achieve this goal. It will launch calculations, restarting until it is completed successfully or the maximum number of iterations is reached. It can recover from errors through error handlers that can be attached dynamically through the register_error_handler decorator.

The idea is to sub class this work chain and leverage the generic error handling that is implemented in the few outline methods. The minimally required outline would look something like the following:

cls.setup
while_(cls.should_run_calculation)(
    cls.run_calculation,
    cls.inspect_calculation,
)

Each of these methods can of course be overriden but they should be general enough to fit most calculation cycles. The run_calculation method will take the inputs for the calculation process from the context under the key inputs. The user should therefore make sure that before the run_calculation method is called, that the to be used inputs are stored under self.ctx.inputs. One can update the inputs based on the results from a prior calculation by calling an outline method just before the run_calculation step, for example:

cls.setup
while_(cls.should_run_calculation)(
    cls.prepare_calculation,
    cls.run_calculation,
    cls.inspect_calculation,
)

Where in the prepare_calculation method, the inputs dictionary at self.ctx.inputs is updated before the next calculation will be run with those inputs.

The _calculation_class attribute should be set to the CalcJob class that should be run in the loop.

__abstractmethods__ = frozenset({})
__init__(*args, **kwargs)[source]

Construct a WorkChain instance.

Construct the instance only if it is a sub class of WorkChain, otherwise raise InvalidOperation.

Parameters
  • inputs (dict) – work chain inputs

  • logger (logging.Logger) – aiida logger

  • runner – work chain runner

  • enable_persistence (bool) – whether to persist this work chain

Type

aiida.engine.runners.Runner

__module__ = 'aiida_cp2k.workchains.aiida_base_restart'
_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 108
_abc_registry = <_weakrefset.WeakSet object>
_calculation_class = None
_error_handler_entry_point = None
_handle_calculation_failure(calculation)[source]

Call the attached error handlers if any to attempt to correct the cause of the calculation failure.

The registered error handlers will be called in order based on their priority until a handler returns a report that instructs to break. If the last executed error handler defines an exit code, that will be returned to instruct the work chain to abort. Otherwise the work chain will continue the cycle.

Parameters

calculation – the calculation that finished with a non-zero exit status

Returns

ExitCode if the work chain is to be aborted

Raises

UnexpectedCalculationFailure – if no error handlers were registered or no errors were handled.

_handle_calculation_sanity_checks(calculation)[source]

Perform a sanity check of a calculation that finished ok.

Calculations that were marked as successful by the parser may still have produced outputs that do not make sense but were not detected by the code and so were not highlighted as warnings or errors. The consistency of the outputs can be checked here. If an unrecoverable problem is found, the function should return the appropriate exit code to abort the work chain. If the probem can be fixed with a restart calculation, this function should adapt the inputs as an error handler would and return False. This will signal to the work chain that a new calculation should be started. If None is returned, the work chain assumes that the outputs produced by the calculation are good and nothing will be done.

Parameters

calculation – the calculation whose outputs should be checked for consistency

Returns

ErrorHandlerReport if a new calculation should be launched or abort if it includes an exit code

_handle_unexpected_failure(calculation, exception=None)[source]

Handle an unexpected failure.

This occurs when a calculation excepted, was killed or finished with a non-zero exit status but no errors were handled. If this is the second consecutive unexpected failure the work chain is aborted.

Parameters
  • calculation – the calculation that failed in an unexpected way

  • exception – optional exception or error message to log to the report

Returns

ExitCode if this is the second consecutive unexpected failure

_load_error_handlers()[source]

If an error handler entry point is defined, load them. If the plugin cannot be loaded log it and pass.

_verbose = False
classmethod define(spec)[source]
inspect_calculation()[source]

Analyse the results of the previous calculation and call the error handlers when necessary.

load_instance_state(saved_state, load_context)[source]

Load instance state.

Parameters
  • saved_state – saved instance state

  • load_context (plumpy.persistence.LoadSaveContext) –

on_terminated()[source]

Clean the working directories of all child calculations if clean_workdir=True in the inputs.

results()[source]

Attach the outputs specified in the output specification from the last completed calculation.

run_calculation()[source]

Run the next calculation, taking the input dictionary from the context at self.ctx.inputs.

setup()[source]

Initialize context variables that are used during the logical flow of the BaseRestartWorkChain.

should_run_calculation()[source]

Return whether a new calculation should be run.

This is the case as long as the last calculation has not finished successfully and the maximum number of restarts has not yet been exceeded.

class aiida_cp2k.workchains.aiida_base_restart.ErrorHandlerReport(is_handled, do_break, exit_code)

Bases: tuple

__getnewargs__()

Return self as a plain tuple. Used by copy and pickle.

__module__ = 'aiida_cp2k.workchains.aiida_base_restart'
static __new__(_cls, is_handled=False, do_break=False, exit_code=ExitCode(status=0, message=None))

Create new instance of ErrorHandlerReport(is_handled, do_break, exit_code)

__repr__()

Return a nicely formatted representation string

__slots__ = ()
_asdict()

Return a new OrderedDict which maps field names to their values.

_fields = ('is_handled', 'do_break', 'exit_code')
classmethod _make(iterable, new=<built-in method __new__ of type object>, len=<built-in function len>)

Make a new ErrorHandlerReport object from a sequence or iterable

_replace(**kwds)

Return a new ErrorHandlerReport object replacing specified fields with new values

_source = "from builtins import property as _property, tuple as _tuple\nfrom operator import itemgetter as _itemgetter\nfrom collections import OrderedDict\n\nclass ErrorHandlerReport(tuple):\n 'ErrorHandlerReport(is_handled, do_break, exit_code)'\n\n __slots__ = ()\n\n _fields = ('is_handled', 'do_break', 'exit_code')\n\n def __new__(_cls, is_handled, do_break, exit_code):\n 'Create new instance of ErrorHandlerReport(is_handled, do_break, exit_code)'\n return _tuple.__new__(_cls, (is_handled, do_break, exit_code))\n\n @classmethod\n def _make(cls, iterable, new=tuple.__new__, len=len):\n 'Make a new ErrorHandlerReport object from a sequence or iterable'\n result = new(cls, iterable)\n if len(result) != 3:\n raise TypeError('Expected 3 arguments, got %d' % len(result))\n return result\n\n def _replace(_self, **kwds):\n 'Return a new ErrorHandlerReport object replacing specified fields with new values'\n result = _self._make(map(kwds.pop, ('is_handled', 'do_break', 'exit_code'), _self))\n if kwds:\n raise ValueError('Got unexpected field names: %r' % list(kwds))\n return result\n\n def __repr__(self):\n 'Return a nicely formatted representation string'\n return self.__class__.__name__ + '(is_handled=%r, do_break=%r, exit_code=%r)' % self\n\n def _asdict(self):\n 'Return a new OrderedDict which maps field names to their values.'\n return OrderedDict(zip(self._fields, self))\n\n def __getnewargs__(self):\n 'Return self as a plain tuple. Used by copy and pickle.'\n return tuple(self)\n\n is_handled = _property(_itemgetter(0), doc='Alias for field number 0')\n\n do_break = _property(_itemgetter(1), doc='Alias for field number 1')\n\n exit_code = _property(_itemgetter(2), doc='Alias for field number 2')\n\n"
property do_break

Alias for field number 1

property exit_code

Alias for field number 2

property is_handled

Alias for field number 0

exception aiida_cp2k.workchains.aiida_base_restart.UnexpectedCalculationFailure[source]

Bases: aiida.common.exceptions.AiidaException

Raised when a calculation job has failed for an unexpected or unrecognized reason.

__module__ = 'aiida_cp2k.workchains.aiida_base_restart'
aiida_cp2k.workchains.aiida_base_restart.prepare_process_inputs(process, inputs)[source]

Prepare the inputs for submission for the given process, according to its spec.

That is to say that when an input is found in the inputs that corresponds to an input port in the spec of the process that expects a Dict, yet the value in the inputs is a plain dictionary, the value will be wrapped in by the Dict class to create a valid input.

Parameters
  • process – sub class of Process for which to prepare the inputs dictionary

  • inputs – a dictionary of inputs intended for submission of the process

Returns

a dictionary with all bare dictionaries wrapped in Dict if dictated by the process spec

aiida_cp2k.workchains.aiida_base_restart.wrap_bare_dict_inputs(port_namespace, inputs)[source]

Wrap bare dictionaries in inputs in a Dict node if dictated by the corresponding port in given namespace.

Parameters
  • port_namespace – a PortNamespace

  • inputs – a dictionary of inputs intended for submission of the process

Returns

a dictionary with all bare dictionaries wrapped in Dict if dictated by the port namespace

aiida_cp2k.workchains.base module

Base workchain to run a CP2K calculation

class aiida_cp2k.workchains.base.Cp2kBaseWorkChain(*args, **kwargs)[source]

Bases: aiida_cp2k.workchains.aiida_base_restart.BaseRestartWorkChain

Workchain to run a CP2K calculation with automated error handling and restarts.

__abstractmethods__ = frozenset({})
__module__ = 'aiida_cp2k.workchains.base'
_abc_cache = <_weakrefset.WeakSet object>
_abc_negative_cache = <_weakrefset.WeakSet object>
_abc_negative_cache_version = 108
_abc_registry = <_weakrefset.WeakSet object>
_calculation_class

alias of aiida_cp2k.calculations.Cp2kCalculation

classmethod define(spec)[source]
setup()[source]

Call the setup of the BaseRestartWorkChain and then create the inputs dictionary in self.ctx.inputs.

This self.ctx.inputs dictionary will be used by the BaseRestartWorkChain to submit the calculations in the internal loop.

Module contents

AiiDA-CP2K workchains