Skip to content

Honour the computer's default_mpiprocs_per_machine in HyperQueueJobResource - #49

Merged
khsrali merged 4 commits into
aiidateam:mainfrom
elinscott:honour-default-mpiprocs
Aug 18, 2026
Merged

Honour the computer's default_mpiprocs_per_machine in HyperQueueJobResource#49
khsrali merged 4 commits into
aiidateam:mainfrom
elinscott:honour-default-mpiprocs

Conversation

@elinscott

Copy link
Copy Markdown
Contributor

Problem

HyperQueueJobResource.accepts_default_mpiprocs_per_machine() returns False, so aiida-core's Scheduler.preprocess_resources never injects the computer's default_mpiprocs_per_machine into the resources. The backward-compatibility path then computes num_cpus = num_machines * num_mpiprocs_per_machine with a hard-coded fallback of 1 — so every builder-driven CalcJob (e.g. anything built through aiida-quantumespresso's get_builder_from_protocol, which seeds resources = {'num_machines': 1}) silently runs on a single CPU, regardless of the "Default #procs/machine" configured on the computer.

See the existing TODO comment in validate_resources, which already describes this hole.

Change

accepts_default_mpiprocs_per_machine() now returns True, so aiida-core injects the computer's default as num_mpiprocs_per_machine whenever the user did not set it explicitly. The backward-compatibility product picks it up unchanged.

  • When the computer defines no default, aiida-core injects None — the fallback to 1 is kept for that case
  • Explicitly passed resources always win.
  • The modern num_cpus path is untouched.

Testing

New tests in tests/test_scheduler.py

elinscott and others added 2 commits July 8, 2026 17:53
…source

accepts_default_mpiprocs_per_machine() returned False, so aiida-core's
Scheduler.preprocess_resources never injected the computer's
default_mpiprocs_per_machine, and the backward-compatibility path
num_machines * num_mpiprocs_per_machine fell back to a hard-coded 1: every
builder-driven CalcJob on a HyperQueue computer silently ran on a single
CPU regardless of the computer's configured default.

Return True and handle the None that aiida-core injects when the computer
defines no default (falling back to 1 as before). Also join the two halves
of the deprecation warning, the second of which was a dead string statement
that never reached the message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@elinscott

Copy link
Copy Markdown
Contributor Author

@khsrali

@khsrali khsrali self-assigned this Aug 17, 2026
@khsrali

khsrali commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

I should be able to have a look at this, soon

@khsrali khsrali left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @elinscott ,
Sorry I had a lot other responsibilities, took some time to get into this.

The changes are sound.
Tests require a fix, see below.
And, the changes are technically backward incompatible, let's put them it in the changelog on this PR, before it gets forgotten. You can add them in a section like:

## Unpublished:
balah blah

Or, if you don't mind, make a new release and put them there.

Comment thread tests/test_scheduler.py Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from aiida_hyperqueue.scheduler import (
AiiDAHypereQueueDeprecationWarning,
HyperQueueJobResource,
HyperQueueScheduler,
)

@elinscott elinscott Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. (Aside: Hyper-e-QueueDepecationWarning??!)

Comment thread tests/test_scheduler.py Outdated
Comment on lines +68 to +98
def test_resource_validation_backward_compatibility():
"""Tests for the deprecated `num_machines` / `num_mpiprocs_per_machine` path."""
# num_cpus is the product of the two legacy keys
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=2, num_mpiprocs_per_machine=8)
assert resource.num_cpus == 16

# the computer's default_mpiprocs_per_machine, which aiida-core's
# `Scheduler.preprocess_resources` injects as `num_mpiprocs_per_machine`,
# must be honoured (this is what `accepts_default_mpiprocs_per_machine`
# returning True enables)
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1, num_mpiprocs_per_machine=8)
assert resource.num_cpus == 8

# a computer without a default leads aiida-core to inject `None`; fall back to 1
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1, num_mpiprocs_per_machine=None)
assert resource.num_cpus == 1

# `num_mpiprocs_per_machine` omitted entirely also falls back to 1
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1)
assert resource.num_cpus == 1


def test_accepts_default_mpiprocs_per_machine():
"""The resource class must accept the computer's default so it reaches validate_resources."""
assert HyperQueueJobResource.accepts_default_mpiprocs_per_machine()


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I understand, one cannot test fix this way. because HyperQueueJobResource bypasses preprocess_resources entirely. The way to go would be using HyperQueueScheduler().create_job_resource which returns the genuine resources considered.

Suggested change
def test_resource_validation_backward_compatibility():
"""Tests for the deprecated `num_machines` / `num_mpiprocs_per_machine` path."""
# num_cpus is the product of the two legacy keys
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=2, num_mpiprocs_per_machine=8)
assert resource.num_cpus == 16
# the computer's default_mpiprocs_per_machine, which aiida-core's
# `Scheduler.preprocess_resources` injects as `num_mpiprocs_per_machine`,
# must be honoured (this is what `accepts_default_mpiprocs_per_machine`
# returning True enables)
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1, num_mpiprocs_per_machine=8)
assert resource.num_cpus == 8
# a computer without a default leads aiida-core to inject `None`; fall back to 1
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1, num_mpiprocs_per_machine=None)
assert resource.num_cpus == 1
# `num_mpiprocs_per_machine` omitted entirely also falls back to 1
with pytest.warns(Warning, match="deprecated"):
resource = HyperQueueJobResource(num_machines=1)
assert resource.num_cpus == 1
def test_accepts_default_mpiprocs_per_machine():
"""The resource class must accept the computer's default so it reaches validate_resources."""
assert HyperQueueJobResource.accepts_default_mpiprocs_per_machine()
@pytest.mark.parametrize(
"resources, default_mpiprocs, expected_num_cpus",
(
({"num_machines": 1}, 8, 8), # the computer's default must be honoured
({"num_machines": 1}, None, 1), # no default on the computer -> fall back to 1
({"num_machines": 2, "num_mpiprocs_per_machine": 8}, 4, 16), # explicit wins
({"num_cpus": 4}, 8, 4), # the modern path ignores the default
),
)
@pytest.mark.filterwarnings("ignore:The `num_machines`")
def test_resource_preprocessing(resources, default_mpiprocs, expected_num_cpus):
"""The computer's `default_mpiprocs_per_machine` must reach the deprecated `num_machines` path.
Mirrors `CalcJob`, which calls `preprocess_resources` with the computer's default before the
resources are validated.
"""
HyperQueueScheduler.preprocess_resources(resources, default_mpiprocs)
resource = HyperQueueScheduler().create_job_resource(**resources)
assert resource.num_cpus == expected_num_cpus
def test_resource_deprecation():
"""The `num_machines` / `num_mpiprocs_per_machine` path is deprecated."""
with pytest.warns(AiiDAHypereQueueDeprecationWarning, match="deprecated"):
HyperQueueJobResource(num_machines=1, num_mpiprocs_per_machine=8)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adopted. But for the record, the original tests did detect the fix — I ran both versions against the pre-fix base commit (84d8083) and against this branch, and both fail on the base and pass here. But the newer tests are cleaner, thanks!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok interesting

elinscott and others added 2 commits August 18, 2026 11:58
- Replace the direct-construction resource tests with the reviewer's
  parametrized test that routes through preprocess_resources and
  create_job_resource, plus a dedicated deprecation-warning test
- Import AiiDAHypereQueueDeprecationWarning in tests
- Add an Unpublished changelog section noting the behavior change

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…into address-review-49

# Conflicts:
#	tests/test_scheduler.py
@elinscott

Copy link
Copy Markdown
Contributor Author

The changes are sound. Tests require a fix, see below. And, the changes are technically backward incompatible, let's put them it in the changelog on this PR, before it gets forgotten.

Done — added an Unpublished section to CHANGELOG.md. N.B. I don't have permissions to create releases; will leave that up to you if you think it's necessary.

@elinscott

Copy link
Copy Markdown
Contributor Author

Thanks @khsrali . Should be ready for another look from you

@elinscott
elinscott requested a review from khsrali August 18, 2026 10:25

@khsrali khsrali left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all good @elinscott
Thanks again!

@khsrali
khsrali merged commit 88a862f into aiidateam:main Aug 18, 2026
4 checks passed
This was referenced Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants