Skip to content

Commit

Permalink
CalcJob: Fully abstract interaction with AbstractCode in presubmit (
Browse files Browse the repository at this point in the history
#5666)

The `CalcJob.presubmit` has been refactored recently after the renaming
and refactoring of the `Code` class into the `AbstractCode` abstract
base class, and the concrete implementations `InstalledCode` and
`PortableCode`. The goal was to have `CalcJob.presubmit` only interact
with the official interface of `AbstractCode`. This would allow other
implementations to be made that continue to work.

There was one place remaining in `CalcJob.presubmit` that still had code
specific to the type of `AbstractCode` being used in the calculation.
For the `PortableCode` it was verifying that the files created by the
`CalcJob` plugin didn't create a file in the sandbox folder that over-
lapped with the relative filepath of the executable.

This check is now moved to the `validate_working_directory` method on
the `AbstractCode` class,  which is called by `CalcJob.presubmit` making
it fully independent of the code subclass being used.

Co-authored-by: Sebastiaan Huber <mail@sphuber.net>
  • Loading branch information
unkcpz and sphuber authored Sep 27, 2022
1 parent d666332 commit a7775f3
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
5 changes: 1 addition & 4 deletions aiida/engine/processes/calcjobs/calcjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,10 +634,7 @@ def presubmit(self, folder: Folder) -> CalcInfo:
)
)

if isinstance(code, PortableCode) and str(code.filepath_executable) in folder.get_content_list():
raise PluginInternalError(
f'The plugin created a file {code.filepath_executable} that is also the executable name!'
)
code.validate_working_directory(folder)

calc_info = self.prepare_for_submission(folder)
calc_info.uuid = str(self.node.uuid)
Expand Down
14 changes: 14 additions & 0 deletions aiida/orm/nodes/data/code/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from aiida.cmdline.params.options.interactive import TemplateInteractiveOption
from aiida.common import exceptions
from aiida.common.folders import Folder
from aiida.common.lang import type_check
from aiida.orm import Computer
from aiida.plugins import CalculationFactory
Expand Down Expand Up @@ -76,6 +77,19 @@ def get_executable(self) -> str:
:return: The executable to be called in the submission script.
"""

def validate_working_directory(self, folder: Folder):
"""Validate content of the working directory created by the :class:`~aiida.engine.CalcJob` plugin.
This method will be called by :meth:`~aiida.engine.processes.calcjobs.calcjob.CalcJob.presubmit` when a new
calculation job is launched, passing the :class:`~aiida.common.folders.Folder` that was used by the plugin used
for the calculation to create the input files for the working directory. This method can be overridden by
implementations of the ``AbstractCode`` class that need to validate the contents of that folder.
:param folder: A sandbox folder that the ``CalcJob`` plugin wrote input files to that will be copied to the
working directory for the corresponding calculation job instance.
:raises PluginInternalError: If the content of the sandbox folder is not valid.
"""

@property
@abc.abstractmethod
def full_label(self) -> str:
Expand Down
19 changes: 19 additions & 0 deletions aiida/orm/nodes/data/code/portable.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import click

from aiida.common import exceptions
from aiida.common.folders import Folder
from aiida.common.lang import type_check
from aiida.orm import Computer

Expand Down Expand Up @@ -92,6 +93,24 @@ def get_executable(self) -> str:
"""
return self.filepath_executable

def validate_working_directory(self, folder: Folder):
"""Validate content of the working directory created by the :class:`~aiida.engine.CalcJob` plugin.
This method will be called by :meth:`~aiida.engine.processes.calcjobs.calcjob.CalcJob.presubmit` when a new
calculation job is launched, passing the :class:`~aiida.common.folders.Folder` that was used by the plugin used
for the calculation to create the input files for the working directory. This method can be overridden by
implementations of the ``AbstractCode`` class that need to validate the contents of that folder.
:param folder: A sandbox folder that the ``CalcJob`` plugin wrote input files to that will be copied to the
working directory for the corresponding calculation job instance.
:raises PluginInternalError: The ``CalcJob`` plugin created a file that has the same relative filepath as the
executable for this portable code.
"""
if str(self.filepath_executable) in folder.get_content_list():
raise exceptions.PluginInternalError(
f'The plugin created a file {self.filepath_executable} that is also the executable name!'
)

@property
def full_label(self) -> str:
"""Return the full label of this code.
Expand Down

0 comments on commit a7775f3

Please sign in to comment.