aiida-hyperqueue 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiida_hyperqueue-0.2.0/.github/workflows/cd.yml +52 -0
- aiida_hyperqueue-0.2.0/.github/workflows/ci.yml +30 -0
- aiida_hyperqueue-0.2.0/.github/workflows/validate_release_tag.py +45 -0
- aiida_hyperqueue-0.2.0/.pre-commit-config.yaml +17 -0
- aiida_hyperqueue-0.2.0/.readthedocs.yml +26 -0
- aiida_hyperqueue-0.2.0/CHANGELOG.md +21 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/LICENSE +1 -1
- aiida_hyperqueue-0.2.0/PKG-INFO +64 -0
- aiida_hyperqueue-0.2.0/README.md +31 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/aiida_hyperqueue/__init__.py +1 -1
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/__init__.py +5 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/alloc.py +99 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/install.py +120 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/params/__init__.py +0 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/params/arguments.py +4 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/params/options.py +33 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/root.py +37 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/cli/server.py +121 -0
- aiida_hyperqueue-0.2.0/aiida_hyperqueue/scheduler.py +312 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/source/conf.py +41 -37
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/source/get_started.md +25 -27
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/source/index.md +1 -1
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/pyproject.toml +12 -27
- aiida_hyperqueue-0.2.0/tests/README.md +5 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/tests/__init__.py +2 -1
- aiida_hyperqueue-0.2.0/tests/conftest.py +387 -0
- aiida_hyperqueue-0.2.0/tests/target/hq +0 -0
- aiida_hyperqueue-0.2.0/tests/test_cli_alloc.py +16 -0
- aiida_hyperqueue-0.2.0/tests/test_cli_install.py +30 -0
- aiida_hyperqueue-0.2.0/tests/test_cli_server.py +152 -0
- aiida_hyperqueue-0.2.0/tests/test_scheduler.py +215 -0
- aiida_hyperqueue-0.2.0/tests/utils/__init__.py +11 -0
- aiida_hyperqueue-0.2.0/tests/utils/cmd.py +16 -0
- aiida_hyperqueue-0.2.0/tests/utils/io.py +28 -0
- aiida_hyperqueue-0.2.0/tests/utils/job.py +24 -0
- aiida_hyperqueue-0.2.0/tests/utils/mock.py +43 -0
- aiida_hyperqueue-0.2.0/tests/utils/table.py +151 -0
- aiida_hyperqueue-0.2.0/tests/utils/wait.py +85 -0
- aiida-hyperqueue-0.1.0/.github/workflows/ci.yml +0 -86
- aiida-hyperqueue-0.1.0/.pre-commit-config.yaml +0 -33
- aiida-hyperqueue-0.1.0/.readthedocs.yml +0 -9
- aiida-hyperqueue-0.1.0/PKG-INFO +0 -48
- aiida-hyperqueue-0.1.0/README.md +0 -15
- aiida-hyperqueue-0.1.0/aiida_hyperqueue/cli.py +0 -149
- aiida-hyperqueue-0.1.0/aiida_hyperqueue/scheduler.py +0 -289
- aiida-hyperqueue-0.1.0/tests/conftest.py +0 -11
- aiida-hyperqueue-0.1.0/tests/test_scheduler.py +0 -18
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/.gitignore +0 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/.gitignore +0 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/Makefile +0 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/source/developer_guide/index.md +0 -0
- {aiida-hyperqueue-0.1.0 → aiida_hyperqueue-0.2.0}/docs/source/img/AiiDA_transparent_logo.png +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: cd
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v[0-9]+.[0-9]+.[0-9]+*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
|
|
10
|
+
validate-release-tag:
|
|
11
|
+
|
|
12
|
+
if: github.repository == 'aiidateam/aiida-hyperqueue'
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout source
|
|
17
|
+
uses: actions/checkout@v3
|
|
18
|
+
|
|
19
|
+
- name: Set up Python 3.10
|
|
20
|
+
uses: actions/setup-python@v4
|
|
21
|
+
with:
|
|
22
|
+
python-version: '3.10'
|
|
23
|
+
|
|
24
|
+
- name: Validate the tag version against the package version
|
|
25
|
+
run: python .github/workflows/validate_release_tag.py $GITHUB_REF
|
|
26
|
+
|
|
27
|
+
publish:
|
|
28
|
+
|
|
29
|
+
name: Publish to PyPI
|
|
30
|
+
needs: [validate-release-tag]
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
environment: deployment
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout source
|
|
38
|
+
uses: actions/checkout@v3
|
|
39
|
+
|
|
40
|
+
- name: Set up Python 3.10
|
|
41
|
+
uses: actions/setup-python@v4
|
|
42
|
+
with:
|
|
43
|
+
python-version: '3.10'
|
|
44
|
+
|
|
45
|
+
- name: Install flit
|
|
46
|
+
run: pip install flit~=3.8
|
|
47
|
+
|
|
48
|
+
- name: Build with flit
|
|
49
|
+
run: flit build
|
|
50
|
+
|
|
51
|
+
- name: Publish to PyPI using Trusted Publishing
|
|
52
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
|
|
7
|
+
tests:
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
timeout-minutes: 30
|
|
10
|
+
strategy:
|
|
11
|
+
matrix:
|
|
12
|
+
python-version: ["3.10"]
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v3
|
|
16
|
+
|
|
17
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
18
|
+
uses: actions/setup-python@v4
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
|
|
22
|
+
- name: Install python dependencies
|
|
23
|
+
run: |
|
|
24
|
+
pip install --upgrade pip
|
|
25
|
+
pip install .[tests]
|
|
26
|
+
|
|
27
|
+
- name: Run test suite
|
|
28
|
+
run: |
|
|
29
|
+
chmod og-rw ~
|
|
30
|
+
pytest --cov aiida_hyperqueue --cov-append .
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Validate that the version in the tag label matches the version of the package."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import ast
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_version_from_module(content: str) -> str:
|
|
10
|
+
"""Get the ``__version__`` attribute from a module.
|
|
11
|
+
|
|
12
|
+
.. note:: This has been adapted from :mod:`setuptools.config`.
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
module = ast.parse(content)
|
|
16
|
+
except SyntaxError as exception:
|
|
17
|
+
raise OSError("Unable to parse module.") from exception
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
return next(
|
|
21
|
+
ast.literal_eval(statement.value)
|
|
22
|
+
for statement in module.body
|
|
23
|
+
if isinstance(statement, ast.Assign)
|
|
24
|
+
for target in statement.targets
|
|
25
|
+
if isinstance(target, ast.Name) and target.id == "__version__"
|
|
26
|
+
)
|
|
27
|
+
except StopIteration as exception:
|
|
28
|
+
raise OSError(
|
|
29
|
+
"Unable to find the `__version__` attribute in the module."
|
|
30
|
+
) from exception
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if __name__ == "__main__":
|
|
34
|
+
parser = argparse.ArgumentParser()
|
|
35
|
+
parser.add_argument("GITHUB_REF", help="The GITHUB_REF environmental variable")
|
|
36
|
+
args = parser.parse_args()
|
|
37
|
+
assert args.GITHUB_REF.startswith(
|
|
38
|
+
"refs/tags/v"
|
|
39
|
+
), f'GITHUB_REF should start with "refs/tags/v": {args.GITHUB_REF}'
|
|
40
|
+
tag_version = args.GITHUB_REF[11:]
|
|
41
|
+
package_version = get_version_from_module(
|
|
42
|
+
Path("aiida_hyperqueue/__init__.py").read_text(encoding="utf-8")
|
|
43
|
+
)
|
|
44
|
+
error_message = f"The tag version `{tag_version}` is different from the package version `{package_version}`"
|
|
45
|
+
assert tag_version == package_version, error_message
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Install pre-commit hooks via:
|
|
2
|
+
# pre-commit install
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v4.6.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: end-of-file-fixer
|
|
8
|
+
- id: fix-encoding-pragma
|
|
9
|
+
- id: mixed-line-ending
|
|
10
|
+
- id: trailing-whitespace
|
|
11
|
+
- id: check-json
|
|
12
|
+
|
|
13
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
14
|
+
rev: v0.6.5
|
|
15
|
+
hooks:
|
|
16
|
+
- id: ruff-format
|
|
17
|
+
- id: ruff
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
# YAML adapted from aiida-core .readthedocs.yml
|
|
4
|
+
|
|
5
|
+
# Disable all unneeded formats
|
|
6
|
+
formats: []
|
|
7
|
+
|
|
8
|
+
build:
|
|
9
|
+
os: ubuntu-22.04
|
|
10
|
+
tools:
|
|
11
|
+
python: '3.11'
|
|
12
|
+
jobs:
|
|
13
|
+
# Use uv to speed up the build
|
|
14
|
+
# https://docs.readthedocs.io/en/stable/build-customization.html#install-dependencies-with-uv
|
|
15
|
+
post_create_environment:
|
|
16
|
+
- asdf plugin add uv
|
|
17
|
+
- asdf install uv 0.2.9
|
|
18
|
+
- asdf global uv 0.2.9
|
|
19
|
+
post_install:
|
|
20
|
+
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH uv pip install .[docs]
|
|
21
|
+
|
|
22
|
+
# Let the build fail if there are any warnings
|
|
23
|
+
sphinx:
|
|
24
|
+
builder: html
|
|
25
|
+
configuration: docs/source/conf.py
|
|
26
|
+
fail_on_warning: true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## v0.2.0
|
|
2
|
+
|
|
3
|
+
- [#18](https://github.com/aiidateam/aiida-hyperqueue/pull/18) A large refactoring with following changes:
|
|
4
|
+
|
|
5
|
+
- correctly support memory setup for resources.
|
|
6
|
+
- support turn on hyperthreading with latest version of hyperqueue.
|
|
7
|
+
- Support install hq to remote computer over CLI.
|
|
8
|
+
- adding unit tests with submit to real hq using the fixture from hyperqueue repo.
|
|
9
|
+
- Fix the submit bug for hq > 0.12 that resources are configured twice in job script and submit command.
|
|
10
|
+
|
|
11
|
+
- [#26](https://github.com/aiidateam/aiida-hyperqueue/pull/26) Change alloc add worker name (name appear in slurm queue) `aiida` -> `ahq`
|
|
12
|
+
- [#24](https://github.com/aiidateam/aiida-hyperqueue/pull/24) Use JSON format as output for hq job list and hq submit
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## v0.1.1
|
|
16
|
+
|
|
17
|
+
Only a small fix to the `README.md` was added here, this release is mainly to test the automated deployment to PyPI.
|
|
18
|
+
|
|
19
|
+
## v0.1.0
|
|
20
|
+
|
|
21
|
+
First release on PyPI, tested with HyperQueue v0.15.0.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aiida-hyperqueue
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: AiiDA plugin for the HyperQueue metascheduler
|
|
5
|
+
Author: Marnik Bercx, Jusong Yu
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Framework :: AiiDA
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
12
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: aiida-core~=2.0
|
|
17
|
+
Requires-Dist: sphinx ; extra == "docs"
|
|
18
|
+
Requires-Dist: myst-parser ; extra == "docs"
|
|
19
|
+
Requires-Dist: sphinx-design ; extra == "docs"
|
|
20
|
+
Requires-Dist: sphinx-book-theme ; extra == "docs"
|
|
21
|
+
Requires-Dist: sphinxcontrib-details-directive~=0.1.0 ; extra == "docs"
|
|
22
|
+
Requires-Dist: pre-commit~=3.5 ; extra == "pre-commit"
|
|
23
|
+
Requires-Dist: mypy~=1.10.0 ; extra == "pre-commit"
|
|
24
|
+
Requires-Dist: pgtest~=1.3.1 ; extra == "tests"
|
|
25
|
+
Requires-Dist: coverage~=7.0 ; extra == "tests"
|
|
26
|
+
Requires-Dist: pytest~=7.0 ; extra == "tests"
|
|
27
|
+
Requires-Dist: pytest-cov~=4.1 ; extra == "tests"
|
|
28
|
+
Project-URL: Source, https://github.com/aiidateam/aiida-hyperqueue
|
|
29
|
+
Provides-Extra: docs
|
|
30
|
+
Provides-Extra: pre-commit
|
|
31
|
+
Provides-Extra: tests
|
|
32
|
+
|
|
33
|
+
[](https://github.com/aiidateam/aiida-hyperqueue/actions)
|
|
34
|
+
[](http://aiida-hyperqueue.readthedocs.io/)
|
|
35
|
+
[](https://badge.fury.io/py/aiida-hyperqueue)
|
|
36
|
+
|
|
37
|
+
# AiiDA HyperQueue plugin
|
|
38
|
+
|
|
39
|
+
AiiDA plugin for the [HyperQueue](https://it4innovations.github.io/hyperqueue/stable/) metascheduler.
|
|
40
|
+
|
|
41
|
+
| ❗️ This package is still in the early stages of development and we will most likely break the API regularly in new 0.X versions. Be sure to pin the version when installing this package in scripts.|
|
|
42
|
+
|---|
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
Allows task farming on Slurm machines through the submission of AiiDA calculations to the [HyperQueue](https://github.com/It4innovations/hyperqueue) metascheduler.
|
|
47
|
+
See the [Documentation](http://aiida-hyperqueue.readthedocs.io/) for more information on how to install and use the plugin.
|
|
48
|
+
|
|
49
|
+
## For developers
|
|
50
|
+
|
|
51
|
+
To control the loglevel of command, since we use the `echo` module from aiida, the CLI loglever can be set through `logging.verdi_loglevel`.
|
|
52
|
+
|
|
53
|
+
## Acknowledgenement
|
|
54
|
+
If you use this plugin for your research, please cite the following work:
|
|
55
|
+
|
|
56
|
+
#### HyperQueue
|
|
57
|
+
|
|
58
|
+
* J. Beránek *et al.*, *HyperQueue: Efficient and ergonomic task graphs on HPC clusters*, SoftwareX **27**, 101814 (2024); DOI: [10.1016/j.softx.2024.101814](https://doi.org/10.1016/j.softx.2024.101814)
|
|
59
|
+
|
|
60
|
+
#### AiiDA
|
|
61
|
+
|
|
62
|
+
* S. P. Huber *et al.*, *AiiDA 1.0, a scalable computational infrastructure for automated reproducible workflows and data provenance*, Scientific Data **7**, 300 (2020); DOI: [10.1038/s41597-020-00638-4](https://doi.org/10.1038/s41597-020-00638-4)
|
|
63
|
+
* M. Uhrin *et al.*, *Workflows in AiiDA: Engineering a high-throughput, event-based engine for robust and modular computational workflows*, Computational Materials Science **187**, 110086 (2021); DOI: [10.1016/j.commatsci.2020.110086](https://doi.org/10.1016/j.commatsci.2020.110086)
|
|
64
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[](https://github.com/aiidateam/aiida-hyperqueue/actions)
|
|
2
|
+
[](http://aiida-hyperqueue.readthedocs.io/)
|
|
3
|
+
[](https://badge.fury.io/py/aiida-hyperqueue)
|
|
4
|
+
|
|
5
|
+
# AiiDA HyperQueue plugin
|
|
6
|
+
|
|
7
|
+
AiiDA plugin for the [HyperQueue](https://it4innovations.github.io/hyperqueue/stable/) metascheduler.
|
|
8
|
+
|
|
9
|
+
| ❗️ This package is still in the early stages of development and we will most likely break the API regularly in new 0.X versions. Be sure to pin the version when installing this package in scripts.|
|
|
10
|
+
|---|
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
Allows task farming on Slurm machines through the submission of AiiDA calculations to the [HyperQueue](https://github.com/It4innovations/hyperqueue) metascheduler.
|
|
15
|
+
See the [Documentation](http://aiida-hyperqueue.readthedocs.io/) for more information on how to install and use the plugin.
|
|
16
|
+
|
|
17
|
+
## For developers
|
|
18
|
+
|
|
19
|
+
To control the loglevel of command, since we use the `echo` module from aiida, the CLI loglever can be set through `logging.verdi_loglevel`.
|
|
20
|
+
|
|
21
|
+
## Acknowledgenement
|
|
22
|
+
If you use this plugin for your research, please cite the following work:
|
|
23
|
+
|
|
24
|
+
#### HyperQueue
|
|
25
|
+
|
|
26
|
+
* J. Beránek *et al.*, *HyperQueue: Efficient and ergonomic task graphs on HPC clusters*, SoftwareX **27**, 101814 (2024); DOI: [10.1016/j.softx.2024.101814](https://doi.org/10.1016/j.softx.2024.101814)
|
|
27
|
+
|
|
28
|
+
#### AiiDA
|
|
29
|
+
|
|
30
|
+
* S. P. Huber *et al.*, *AiiDA 1.0, a scalable computational infrastructure for automated reproducible workflows and data provenance*, Scientific Data **7**, 300 (2020); DOI: [10.1038/s41597-020-00638-4](https://doi.org/10.1038/s41597-020-00638-4)
|
|
31
|
+
* M. Uhrin *et al.*, *Workflows in AiiDA: Engineering a high-throughput, event-based engine for robust and modular computational workflows*, Computational Materials Science **187**, 110086 (2021); DOI: [10.1016/j.commatsci.2020.110086](https://doi.org/10.1016/j.commatsci.2020.110086)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import click
|
|
3
|
+
|
|
4
|
+
from aiida.cmdline.params import options, arguments
|
|
5
|
+
from aiida.cmdline.utils import echo
|
|
6
|
+
|
|
7
|
+
from .root import cmd_root
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@cmd_root.group("alloc")
|
|
11
|
+
def alloc_group():
|
|
12
|
+
"""Commands to configure HQ allocations."""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@alloc_group.command("add")
|
|
16
|
+
@click.argument("slurm-options", nargs=-1)
|
|
17
|
+
@options.COMPUTER(required=True)
|
|
18
|
+
@click.option(
|
|
19
|
+
"-t",
|
|
20
|
+
"--time-limit",
|
|
21
|
+
type=str,
|
|
22
|
+
required=True,
|
|
23
|
+
help=(
|
|
24
|
+
"Time limit for each job run by the allocation. The duration can be expressed using various shortcuts "
|
|
25
|
+
"recognised by HyperQueue, e.g. 30m, 2h, ... For the full list, see https://tinyurl.com/hq-duration."
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
@click.option(
|
|
29
|
+
"--hyper-threading/--no-hyper-threading",
|
|
30
|
+
default=True,
|
|
31
|
+
type=click.BOOL,
|
|
32
|
+
help=("Allow HyperQueue to consider hyperthreads when assigning resources."),
|
|
33
|
+
)
|
|
34
|
+
@click.option(
|
|
35
|
+
"-b",
|
|
36
|
+
"--backlog",
|
|
37
|
+
type=click.INT,
|
|
38
|
+
required=False,
|
|
39
|
+
default=1,
|
|
40
|
+
help=(
|
|
41
|
+
"Set the backlog for the allocator. This is the number of allocations HyperQueue will make sure is waiting with"
|
|
42
|
+
" the job manager."
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
@click.option(
|
|
46
|
+
"-w",
|
|
47
|
+
"--workers-per-alloc",
|
|
48
|
+
type=click.INT,
|
|
49
|
+
required=False,
|
|
50
|
+
default=1,
|
|
51
|
+
help=("Option to allow pooled jobs to launch on multiple nodes."),
|
|
52
|
+
)
|
|
53
|
+
def cmd_add(
|
|
54
|
+
slurm_options, computer, time_limit, hyper_threading, backlog, workers_per_alloc
|
|
55
|
+
):
|
|
56
|
+
"""Add a new allocation to the HQ server."""
|
|
57
|
+
|
|
58
|
+
# from hq==0.13.0: ``--cpus=no-ht`` is now changed to a flag ``--no-hyper-threading``
|
|
59
|
+
hyper = "" if hyper_threading else "--no-hyper-threading"
|
|
60
|
+
|
|
61
|
+
with computer.get_transport() as transport:
|
|
62
|
+
retval, _, stderr = transport.exec_command_wait(
|
|
63
|
+
f'hq alloc add slurm --backlog {backlog} --time-limit {time_limit} --name ahq {hyper} '
|
|
64
|
+
f'--workers-per-alloc {workers_per_alloc} -- {" ".join(slurm_options)}'
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if retval != 0:
|
|
68
|
+
echo.echo_critical(f"failed to create new allocation: {stderr}\n")
|
|
69
|
+
|
|
70
|
+
echo.echo_success(f"{stderr}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@alloc_group.command("list")
|
|
74
|
+
@arguments.COMPUTER()
|
|
75
|
+
def cmd_list(computer):
|
|
76
|
+
"""List the allocations on the HQ server."""
|
|
77
|
+
|
|
78
|
+
with computer.get_transport() as transport:
|
|
79
|
+
retval, stdout, stderr = transport.exec_command_wait("hq alloc list")
|
|
80
|
+
|
|
81
|
+
if retval != 0:
|
|
82
|
+
echo.echo_critical(f"failed to list allocations: {stderr}\n")
|
|
83
|
+
|
|
84
|
+
echo.echo(stdout)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@alloc_group.command("remove")
|
|
88
|
+
@click.argument("alloc_id")
|
|
89
|
+
@options.COMPUTER(required=True)
|
|
90
|
+
def cmd_remove(alloc_id, computer):
|
|
91
|
+
"""Remove an allocation from the HQ server."""
|
|
92
|
+
|
|
93
|
+
with computer.get_transport() as transport:
|
|
94
|
+
retval, _, stderr = transport.exec_command_wait(f"hq alloc remove {alloc_id}")
|
|
95
|
+
|
|
96
|
+
if retval != 0:
|
|
97
|
+
echo.echo_critical(f"failed to remove allocation: {stderr}\n")
|
|
98
|
+
|
|
99
|
+
echo.echo_success(f"{stderr}")
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import click
|
|
3
|
+
import tempfile
|
|
4
|
+
import requests
|
|
5
|
+
import tarfile
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from aiida import orm
|
|
9
|
+
from aiida.cmdline.utils import echo
|
|
10
|
+
|
|
11
|
+
from .params import arguments
|
|
12
|
+
from .root import cmd_root
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@cmd_root.command("install")
|
|
16
|
+
@arguments.COMPUTER()
|
|
17
|
+
@click.option(
|
|
18
|
+
"-p",
|
|
19
|
+
"--remote-bin-dir",
|
|
20
|
+
type=click.Path(),
|
|
21
|
+
default=Path("$HOME/bin/"),
|
|
22
|
+
help="remote bin path hq will stored.",
|
|
23
|
+
)
|
|
24
|
+
@click.option(
|
|
25
|
+
"--write-bashrc/--no-write-bashrc",
|
|
26
|
+
default=True,
|
|
27
|
+
help="write the bin path to bashrc.",
|
|
28
|
+
)
|
|
29
|
+
@click.option(
|
|
30
|
+
"--hq-version", type=str, default="0.19.0", help="the hq version will be installed."
|
|
31
|
+
)
|
|
32
|
+
# TODO: should also support different arch binary??
|
|
33
|
+
def cmd_install(
|
|
34
|
+
computer: orm.Computer, remote_bin_dir: Path, hq_version: str, write_bashrc: bool
|
|
35
|
+
):
|
|
36
|
+
"""Install the hq binary to the computer through the transport"""
|
|
37
|
+
|
|
38
|
+
# The minimal hq version we support is 0.13.0, check the minor version
|
|
39
|
+
try:
|
|
40
|
+
_, minor, _ = hq_version.split(".")
|
|
41
|
+
except ValueError as e:
|
|
42
|
+
echo.echo_critical(f"Cannot parse the version {hq_version}: {e}")
|
|
43
|
+
else:
|
|
44
|
+
if int(minor) < 13:
|
|
45
|
+
# `--no-hyper-threading` replace `--cpus=no-ht` from 0.13.0
|
|
46
|
+
# If older version installed, try to not use `--no-hyper-threading` for `aiida-hq alloc add`.
|
|
47
|
+
echo.echo_warning(
|
|
48
|
+
f"You are installing hq version {hq_version}, please do not use `--no-hyper-threading` for `aiida-hq alloc add`."
|
|
49
|
+
" Or install version >= 0.13.0"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Download the hq binary with specific version to local temp folder
|
|
53
|
+
# raise if the version not found
|
|
54
|
+
# Then upload to the remote using opened transport of computer
|
|
55
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
56
|
+
url = f"https://github.com/It4innovations/hyperqueue/releases/download/v{hq_version}/hq-v{hq_version}-linux-x64.tar.gz"
|
|
57
|
+
response = requests.get(url, stream=True)
|
|
58
|
+
rcode = response.status_code
|
|
59
|
+
|
|
60
|
+
if rcode != 200:
|
|
61
|
+
echo.echo_error(
|
|
62
|
+
"Cannot download the hq, please check the version is exist."
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
temp_dir = Path(temp_dir)
|
|
66
|
+
tar_path = temp_dir / "hq.tar.gz"
|
|
67
|
+
|
|
68
|
+
with open(tar_path, "wb") as f:
|
|
69
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
70
|
+
f.write(chunk)
|
|
71
|
+
|
|
72
|
+
with tarfile.open(tar_path, "r") as tar:
|
|
73
|
+
tar.extractall(path=temp_dir)
|
|
74
|
+
|
|
75
|
+
echo.echo_success(f"The hq version {hq_version} binary downloaded.")
|
|
76
|
+
|
|
77
|
+
bin_path = temp_dir / "hq"
|
|
78
|
+
|
|
79
|
+
# upload the binary to remote
|
|
80
|
+
# TODO: try not override if the binary exist, put has overwrite=True as default
|
|
81
|
+
with computer.get_transport() as transport:
|
|
82
|
+
# Get the abs path of remote bin dir
|
|
83
|
+
retval, stdout, stderr = transport.exec_command_wait(
|
|
84
|
+
f"echo {str(remote_bin_dir)}"
|
|
85
|
+
)
|
|
86
|
+
if retval != 0:
|
|
87
|
+
echo.echo_critical(
|
|
88
|
+
f"Not able to parse remote bin dir {remote_bin_dir}, exit_code={retval}"
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
remote_bin_dir = Path(stdout.strip())
|
|
92
|
+
|
|
93
|
+
# first check if the hq exist in the target folder
|
|
94
|
+
if transport.isfile(str(remote_bin_dir / "hq")):
|
|
95
|
+
echo.echo_info(
|
|
96
|
+
f"hq exist in the {remote_bin_dir} on remote, will override it."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
transport.makedirs(path=remote_bin_dir, ignore_existing=True)
|
|
100
|
+
transport.put(
|
|
101
|
+
localpath=str(bin_path.resolve()), remotepath=str(remote_bin_dir)
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
# XXX: should transport.put take care of this already??
|
|
105
|
+
transport.exec_command_wait(f"chmod +x {str(remote_bin_dir / 'hq')}")
|
|
106
|
+
|
|
107
|
+
# write to bashrc
|
|
108
|
+
if write_bashrc:
|
|
109
|
+
identity_str = "by aiida-hq"
|
|
110
|
+
retval, _, stderr = transport.exec_command_wait(
|
|
111
|
+
f"grep -q '# {identity_str}' ~/.bashrc || echo '# {identity_str}\nexport PATH=$HOME/bin:$PATH' >> ~/.bashrc"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if retval != 0:
|
|
115
|
+
echo.echo_critical(
|
|
116
|
+
f"Not able to set set the path $HOME/bin to your remote bashrc, try to do it manually.\n"
|
|
117
|
+
f"Info: {stderr}"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
echo.echo_success(f"The hq binary installed into remote {remote_bin_dir}")
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Reusable options for CLI commands."""
|
|
3
|
+
|
|
4
|
+
import functools
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from aiida.cmdline.params import options as core_options
|
|
8
|
+
from aiida.cmdline.params import types as core_types
|
|
9
|
+
|
|
10
|
+
__all__ = (
|
|
11
|
+
"PROFILE",
|
|
12
|
+
"VERBOSITY",
|
|
13
|
+
"VERSION",
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
PROFILE = functools.partial(
|
|
17
|
+
core_options.PROFILE,
|
|
18
|
+
type=core_types.ProfileParamType(load_profile=True),
|
|
19
|
+
expose_value=False,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Clone the ``VERBOSITY`` option from ``aiida-core`` so the ``-v`` short flag can be removed, since that overlaps with
|
|
23
|
+
# the flag of the ``VERSION`` option of this CLI.
|
|
24
|
+
VERBOSITY = core_options.VERBOSITY.clone()
|
|
25
|
+
VERBOSITY.args = ("--verbosity",)
|
|
26
|
+
|
|
27
|
+
VERSION = core_options.OverridableOption(
|
|
28
|
+
"-v",
|
|
29
|
+
"--version",
|
|
30
|
+
type=click.STRING,
|
|
31
|
+
required=False,
|
|
32
|
+
help="Select the version of the installed configuration.",
|
|
33
|
+
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Command line interface `aiida-hq` for aiida-hyperqueue.
|
|
3
|
+
The CLI implementation prototype from `aiida-pseudo`.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from aiida.cmdline.groups.verdi import VerdiCommandGroup
|
|
9
|
+
|
|
10
|
+
from .params import options
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CustomVerdiCommandGroup(VerdiCommandGroup):
|
|
14
|
+
"""Subclass of :class:`aiida.cmdline.groups.verdi.VerdiCommandGroup` for the CLI.
|
|
15
|
+
|
|
16
|
+
This subclass overrides the verbosity option to use a custom one that removes the ``-v`` short version of the option
|
|
17
|
+
since that is used by other options in this CLI and so would clash.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
@staticmethod
|
|
21
|
+
def add_verbosity_option(cmd):
|
|
22
|
+
"""Apply the ``verbosity`` option to the command, which is common to all subcommands."""
|
|
23
|
+
if cmd is not None and "verbosity" not in [param.name for param in cmd.params]:
|
|
24
|
+
cmd = options.VERBOSITY()(cmd)
|
|
25
|
+
|
|
26
|
+
return cmd
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@click.group(
|
|
30
|
+
"aiida-hq",
|
|
31
|
+
cls=CustomVerdiCommandGroup,
|
|
32
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
33
|
+
)
|
|
34
|
+
@options.VERBOSITY()
|
|
35
|
+
@options.PROFILE()
|
|
36
|
+
def cmd_root():
|
|
37
|
+
"""CLI for the ``aiida-hyperqueue`` plugin."""
|