Skip to content

containerized code: setting and running containerized code (docker, sarus, singularity, conda) #5507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/config/add-docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
label: add-docker
description: add docker
default_calc_job_plugin: core.arithmetic.add
on_computer: true
computer: localhost
filepath_executable: /bin/bash
image: ubuntu
engine_command: docker run -v $PWD:/workdir:rw -w /workdir {image} sh -c
escape_exec_line: true
prepend_text: ' '
append_text: ' '
4 changes: 2 additions & 2 deletions .github/config/add.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
label: add
description: add
default_calc_job_plugin: core.arithmetic.add
input_plugin: core.arithmetic.add
on_computer: true
computer: localhost
filepath_executable: /bin/bash
remote_abs_path: /bin/bash
prepend_text: ' '
append_text: ' '
4 changes: 2 additions & 2 deletions .github/config/doubler.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
label: doubler
description: doubler
default_calc_job_plugin: core.templatereplacer
input_plugin: core.templatereplacer
on_computer: true
computer: localhost
filepath_executable: PLACEHOLDER_REMOTE_ABS_PATH_DOUBLER
remote_abs_path: PLACEHOLDER_REMOTE_ABS_PATH_DOUBLER
prepend_text: ' '
append_text: ' '
1 change: 1 addition & 0 deletions .github/config/localhost.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ transport: core.local
scheduler: core.direct
shebang: '#!/usr/bin/env bash'
work_dir: PLACEHOLDER_WORK_DIR
use_double_quotes: true
mpirun_command: ' '
mpiprocs_per_machine: 1
prepend_text: ' '
Expand Down
35 changes: 35 additions & 0 deletions .github/system_tests/test_containerized_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
###########################################################################
# Copyright (c), The AiiDA team. All rights reserved. #
# This file is part of the AiiDA code. #
# #
# The code is hosted on GitHub at https://github.com/aiidateam/aiida-core #
# For further information on the license, see the LICENSE.txt file #
# For further information please visit http://www.aiida.net #
###########################################################################
"""Test run on containrized code."""
from aiida import orm
from aiida.engine import run_get_node
from aiida.plugins import CalculationFactory

ArithmeticAddCalculation = CalculationFactory('core.arithmetic.add')

inputs = {
'code': orm.load_code('add-docker@localhost'),
'x': orm.Int(4),
'y': orm.Int(6),
'metadata': {
'options': {
'resources': {
'num_machines': 1,
'num_mpiprocs_per_machine': 1
}
}
}
}

res, node = run_get_node(ArithmeticAddCalculation, **inputs)
assert 'sum' in res
assert 'remote_folder' in res
assert 'retrieved' in res
assert res['sum'].value == 10
1 change: 1 addition & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: nightly

on:
workflow_dispatch: # To manually trigger nightly
schedule:
- cron: '0 0 * * *' # Run every day at midnight
pull_request:
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ verdi setup --non-interactive --config "${CONFIG}/profile.yaml"
verdi computer setup --non-interactive --config "${CONFIG}/localhost.yaml"
verdi computer configure core.local localhost --config "${CONFIG}/localhost-config.yaml"
verdi computer test localhost
verdi code create core.code.installed --non-interactive --config "${CONFIG}/doubler.yaml"
verdi code create core.code.installed --non-interactive --config "${CONFIG}/add.yaml"
verdi code setup --non-interactive --config "${CONFIG}/doubler.yaml"
verdi code setup --non-interactive --config "${CONFIG}/add.yaml"
verdi code create core.code.installed.containerized --non-interactive --config "${CONFIG}/add-docker.yaml"

# set up slurm-ssh computer
verdi computer setup --non-interactive --config "${CONFIG}/slurm-ssh.yaml"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests_nightly.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export PYTHONPATH="${PYTHONPATH}:${SYSTEM_TESTS}:${MODULE_POLISH}"

verdi daemon start 4
verdi -p test_aiida run ${SYSTEM_TESTS}/test_daemon.py
verdi -p test_aiida run ${SYSTEM_TESTS}/test_containerized_code.py
bash ${SYSTEM_TESTS}/test_polish_workchains.sh
verdi daemon stop

Expand Down
29 changes: 27 additions & 2 deletions aiida/engine/processes/calcjobs/calcjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from aiida.common.folders import Folder
from aiida.common.lang import classproperty, override
from aiida.common.links import LinkType
from aiida.orm.nodes.data.code.containerized import Containerized

from ..exit_code import ExitCode
from ..ports import PortNamespace
Expand Down Expand Up @@ -615,7 +616,7 @@ def presubmit(self, folder: Folder) -> CalcInfo:
from aiida.common.datastructures import CodeInfo, CodeRunMode
from aiida.common.exceptions import InputValidationError, InvalidOperation, PluginInternalError, ValidationError
from aiida.common.utils import validate_list_of_string_tuples
from aiida.orm import AbstractCode, Code, Computer, InstalledCode, PortableCode, load_node
from aiida.orm import AbstractCode, Computer, PortableCode, load_code
from aiida.schedulers.datastructures import JobTemplate, JobTemplateCodeInfo

inputs = self.node.base.links.get_incoming(link_type=LinkType.INPUT_CALC)
Expand Down Expand Up @@ -719,7 +720,7 @@ def presubmit(self, folder: Folder) -> CalcInfo:

if code_info.code_uuid is None:
raise PluginInternalError('CalcInfo should have the information of the code to be launched')
this_code = load_node(code_info.code_uuid, sub_classes=(Code, InstalledCode, PortableCode))
this_code = load_code(code_info.code_uuid)

# To determine whether this code should be run with MPI enabled, we get the value that was set in the inputs
# of the entire process, which can then be overwritten by the value from the `CodeInfo`. This allows plugins
Expand All @@ -740,8 +741,32 @@ def presubmit(self, folder: Folder) -> CalcInfo:

cmdline_params = [str(this_code.get_executable())] + (code_info.cmdline_params or [])

escape_exec_line = False
if isinstance(this_code, Containerized):
prepend_cmdline_params += this_code.get_engine_command()
# escape exec line will put the all parameters after `prepend_cmdline_params`
# into the single quotes.
# It is only needed for docker type containerized code,
# therefore default set to False.
escape_exec_line = this_code.escape_exec_line

inner_mpi = this_code.inner_mpi
if inner_mpi:
# First always serials outside
prepend_cmdline_params = this_code.get_engine_command()

# Set mpi args for code if not exist use the computer one as default
if this_code.get_mpirun_command():
code_mpi_args = this_code.get_mpirun_command()
else:
code_mpi_args = mpi_args

# import ipdb; ipdb.set_trace()
cmdline_params = [arg.format(**subst_dict) for arg in code_mpi_args] + cmdline_params

tmpl_code_info = JobTemplateCodeInfo()
tmpl_code_info.prepend_cmdline_params = prepend_cmdline_params
tmpl_code_info.escape_exec_line = escape_exec_line
tmpl_code_info.cmdline_params = cmdline_params
tmpl_code_info.use_double_quotes = [computer.get_use_double_quotes(), this_code.use_double_quotes]
tmpl_code_info.stdin_name = code_info.stdin_name
Expand Down
2 changes: 2 additions & 0 deletions aiida/orm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
'GroupEntityLoader',
'ImportGroup',
'InstalledCode',
'InstalledContainerizedCode',
'Int',
'JsonableData',
'Kind',
Expand All @@ -81,6 +82,7 @@
'OrderSpecifier',
'OrmEntityLoader',
'PortableCode',
'PortableContainerizedCode',
'ProcessNode',
'ProjectionData',
'QueryBuilder',
Expand Down
2 changes: 2 additions & 0 deletions aiida/orm/nodes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
'Float',
'FolderData',
'InstalledCode',
'InstalledContainerizedCode',
'Int',
'JsonableData',
'Kind',
Expand All @@ -48,6 +49,7 @@
'NumericType',
'OrbitalData',
'PortableCode',
'PortableContainerizedCode',
'ProcessNode',
'ProjectionData',
'RemoteData',
Expand Down
2 changes: 2 additions & 0 deletions aiida/orm/nodes/data/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
'Float',
'FolderData',
'InstalledCode',
'InstalledContainerizedCode',
'Int',
'JsonableData',
'Kind',
Expand All @@ -57,6 +58,7 @@
'NumericType',
'OrbitalData',
'PortableCode',
'PortableContainerizedCode',
'ProjectionData',
'RemoteData',
'RemoteStashData',
Expand Down
3 changes: 3 additions & 0 deletions aiida/orm/nodes/data/code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# pylint: disable=wildcard-import

from .abstract import *
from .containerized import *
from .installed import *
from .legacy import *
from .portable import *
Expand All @@ -15,7 +16,9 @@
'AbstractCode',
'Code',
'InstalledCode',
'InstalledContainerizedCode',
'PortableCode',
'PortableContainerizedCode',
)

# yapf: enable
Loading