Skip to content
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

Make HTEX reject empty resource specification in MPI mode #3442

Merged
merged 11 commits into from
May 27, 2024
3 changes: 2 additions & 1 deletion parsl/executors/high_throughput/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,8 @@ def submit(self, func, resource_specification, *args, **kwargs):
Returns:
Future
"""
validate_resource_spec(resource_specification)

validate_resource_spec(resource_specification, is_mpi_enabled=self.enable_mpi_mode)

if self.bad_state_is_set:
raise self.executor_exception
Expand Down
8 changes: 7 additions & 1 deletion parsl/executors/high_throughput/mpi_prefix_composer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ def __str__(self):
return f"Invalid resource specification options supplied: {self.invalid_keys}"


def validate_resource_spec(resource_spec: Dict[str, str]):
def validate_resource_spec(resource_spec: Dict[str, str], is_mpi_enabled: bool = False):
R1j1t marked this conversation as resolved.
Show resolved Hide resolved
"""Basic validation of keys in the resource_spec

Raises: InvalidResourceSpecification if the resource_spec
is invalid (e.g, contains invalid keys)
"""
user_keys = set(resource_spec.keys())

# empty resource_spec when mpi_mode is set causes parsl to hang
# ref issue #3427
if is_mpi_enabled and len(user_keys) == 0:
raise InvalidResourceSpecification({'mpi_mode requires parsl_resource_specification to be configured'})
R1j1t marked this conversation as resolved.
Show resolved Hide resolved

legal_keys = set(("ranks_per_node",
"num_nodes",
"num_ranks",
Expand Down
10 changes: 10 additions & 0 deletions parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from parsl import python_app, bash_app
from parsl.tests.configs.htex_local import fresh_config

from parsl.executors.high_throughput.mpi_prefix_composer import InvalidResourceSpecification

import os

EXECUTOR_LABEL = "MPI_TEST"
Expand Down Expand Up @@ -169,3 +171,11 @@ def test_simulated_load(rounds: int = 100):
total_ranks, nodes = future.result(timeout=10)
assert len(nodes) == futures[future]["num_nodes"]
assert total_ranks == futures[future]["num_nodes"] * futures[future]["ranks_per_node"]


@pytest.mark.local
def test_missing_resource_spec():

with pytest.raises(InvalidResourceSpecification):
future = mock_app(sleep_dur=0.4)
future.result(timeout=10)
20 changes: 12 additions & 8 deletions parsl/tests/test_mpi_apps/test_resource_spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,22 @@ def test_top_level():

@pytest.mark.local
@pytest.mark.parametrize(
"resource_spec, exception",
"resource_spec, is_mpi_enabled, exception",
(
({"num_nodes": 2, "ranks_per_node": 1}, None),
({"launcher_options": "--debug_foo"}, None),
({"num_nodes": 2, "BAD_OPT": 1}, InvalidResourceSpecification),
({}, None),
({"num_nodes": 2, "ranks_per_node": 1}, False, None),
({"launcher_options": "--debug_foo"}, False, None),
({"num_nodes": 2, "BAD_OPT": 1}, False, InvalidResourceSpecification),
({}, False, None),
({"num_nodes": 2, "ranks_per_node": 1}, True, None),
({"launcher_options": "--debug_foo"}, True, None),
({"num_nodes": 2, "BAD_OPT": 1}, True, InvalidResourceSpecification),
({}, True, InvalidResourceSpecification),
)
)
def test_resource_spec(resource_spec: Dict, exception):
def test_resource_spec(resource_spec: Dict, is_mpi_enabled: bool, exception):
if exception:
with pytest.raises(exception):
validate_resource_spec(resource_spec)
validate_resource_spec(resource_spec, is_mpi_enabled=is_mpi_enabled)
else:
result = validate_resource_spec(resource_spec)
result = validate_resource_spec(resource_spec, is_mpi_enabled=is_mpi_enabled)
assert result is None
Loading