parsl 2024.5.13__py3-none-any.whl → 2024.5.27__py3-none-any.whl
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.
- parsl/channels/base.py +2 -9
- parsl/channels/local/local.py +3 -6
- parsl/channels/oauth_ssh/oauth_ssh.py +2 -2
- parsl/channels/ssh/ssh.py +2 -2
- parsl/config.py +7 -1
- parsl/dataflow/dependency_resolvers.py +115 -0
- parsl/dataflow/dflow.py +45 -39
- parsl/executors/__init__.py +2 -0
- parsl/executors/base.py +7 -7
- parsl/executors/high_throughput/errors.py +10 -0
- parsl/executors/high_throughput/executor.py +85 -84
- parsl/executors/high_throughput/interchange.py +6 -5
- parsl/executors/high_throughput/mpi_executor.py +85 -0
- parsl/executors/high_throughput/mpi_prefix_composer.py +18 -2
- parsl/executors/high_throughput/mpi_resource_management.py +3 -0
- parsl/executors/high_throughput/zmq_pipes.py +36 -2
- parsl/executors/radical/rpex_resources.py +3 -7
- parsl/monitoring/remote.py +18 -24
- parsl/providers/local/local.py +1 -1
- parsl/tests/conftest.py +2 -2
- parsl/tests/sites/test_dynamic_executor.py +0 -1
- parsl/tests/test_bash_apps/test_std_uri.py +0 -6
- parsl/tests/test_checkpointing/test_periodic.py +2 -7
- parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -1
- parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
- parsl/tests/test_checkpointing/test_task_exit.py +0 -1
- parsl/tests/test_htex/test_basic.py +0 -1
- parsl/tests/test_htex/test_command_client_timeout.py +69 -0
- parsl/tests/test_htex/test_cpu_affinity_explicit.py +1 -8
- parsl/tests/test_htex/test_manager_failure.py +0 -1
- parsl/tests/test_htex/test_managers_command.py +2 -7
- parsl/tests/test_htex/test_missing_worker.py +2 -8
- parsl/tests/test_monitoring/test_app_names.py +0 -1
- parsl/tests/test_monitoring/test_basic.py +0 -2
- parsl/tests/test_monitoring/test_db_locks.py +0 -1
- parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -1
- parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -2
- parsl/tests/test_monitoring/test_incomplete_futures.py +0 -1
- parsl/tests/test_monitoring/test_memoization_representation.py +0 -1
- parsl/tests/test_monitoring/test_stdouterr.py +0 -2
- parsl/tests/test_mpi_apps/test_bad_mpi_config.py +6 -14
- parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +2 -8
- parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +10 -1
- parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
- parsl/tests/test_mpi_apps/test_resource_spec.py +14 -9
- parsl/tests/test_python_apps/test_context_manager.py +1 -9
- parsl/tests/test_python_apps/test_lifted.py +10 -6
- parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
- parsl/tests/test_scaling/test_regression_1621.py +0 -2
- parsl/tests/test_scaling/test_shutdown_scalein.py +0 -2
- parsl/tests/test_serialization/test_proxystore_configured.py +0 -1
- parsl/tests/test_shutdown/test_kill_monitoring.py +0 -2
- parsl/tests/test_staging/test_1316.py +0 -2
- parsl/tests/test_staging/test_elaborate_noop_file.py +0 -1
- parsl/tests/test_summary.py +0 -1
- parsl/tests/test_threads/test_configs.py +0 -1
- parsl/tests/test_threads/test_lazy_errors.py +0 -1
- parsl/version.py +1 -1
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/METADATA +6 -4
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/RECORD +67 -62
- {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/exec_parsl_function.py +0 -0
- {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/parsl_coprocess.py +0 -0
- {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/process_worker_pool.py +0 -0
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/LICENSE +0 -0
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/WHEEL +0 -0
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/entry_points.txt +0 -0
- {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/top_level.txt +0 -0
@@ -103,8 +103,6 @@ def test_stdstream_to_monitoring(stdx, expected_stdx, stream, tmpd_cwd, caplog):
|
|
103
103
|
kwargs = {stream: stdx}
|
104
104
|
stdapp(**kwargs).result()
|
105
105
|
|
106
|
-
parsl.clear()
|
107
|
-
|
108
106
|
engine = sqlalchemy.create_engine(c.monitoring.logging_endpoint)
|
109
107
|
with engine.begin() as connection:
|
110
108
|
|
@@ -2,15 +2,15 @@ import pytest
|
|
2
2
|
|
3
3
|
from parsl import Config
|
4
4
|
from parsl.executors import HighThroughputExecutor
|
5
|
-
from parsl.launchers import SrunLauncher,
|
5
|
+
from parsl.launchers import SrunLauncher, AprunLauncher, SimpleLauncher
|
6
6
|
from parsl.providers import SlurmProvider
|
7
7
|
|
8
8
|
|
9
9
|
@pytest.mark.local
|
10
10
|
def test_bad_launcher_with_mpi_mode():
|
11
|
-
"""AssertionError if a launcher other than
|
11
|
+
"""AssertionError if a launcher other than SimpleLauncher is supplied"""
|
12
12
|
|
13
|
-
for launcher in [SrunLauncher(),
|
13
|
+
for launcher in [SrunLauncher(), AprunLauncher()]:
|
14
14
|
with pytest.raises(AssertionError):
|
15
15
|
Config(executors=[
|
16
16
|
HighThroughputExecutor(
|
@@ -22,20 +22,12 @@ def test_bad_launcher_with_mpi_mode():
|
|
22
22
|
|
23
23
|
@pytest.mark.local
|
24
24
|
def test_correct_launcher_with_mpi_mode():
|
25
|
-
"""Confirm that
|
25
|
+
"""Confirm that SimpleLauncher works with mpi_mode"""
|
26
26
|
|
27
27
|
config = Config(executors=[
|
28
28
|
HighThroughputExecutor(
|
29
29
|
enable_mpi_mode=True,
|
30
|
-
provider=SlurmProvider(launcher=
|
30
|
+
provider=SlurmProvider(launcher=SimpleLauncher()),
|
31
31
|
)
|
32
32
|
])
|
33
|
-
assert isinstance(config.executors[0].provider.launcher,
|
34
|
-
|
35
|
-
config = Config(executors=[
|
36
|
-
HighThroughputExecutor(
|
37
|
-
enable_mpi_mode=True,
|
38
|
-
provider=SlurmProvider(),
|
39
|
-
)
|
40
|
-
])
|
41
|
-
assert isinstance(config.executors[0].provider.launcher, SingleNodeLauncher)
|
33
|
+
assert isinstance(config.executors[0].provider.launcher, SimpleLauncher)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import logging
|
2
1
|
from typing import Dict
|
3
2
|
import pytest
|
4
3
|
import parsl
|
@@ -8,17 +7,12 @@ from parsl.tests.configs.htex_local import fresh_config
|
|
8
7
|
EXECUTOR_LABEL = "MPI_TEST"
|
9
8
|
|
10
9
|
|
11
|
-
def
|
10
|
+
def local_config():
|
12
11
|
config = fresh_config()
|
13
12
|
config.executors[0].label = EXECUTOR_LABEL
|
14
13
|
config.executors[0].max_workers_per_node = 1
|
15
14
|
config.executors[0].enable_mpi_mode = False
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def local_teardown():
|
20
|
-
parsl.dfk().cleanup()
|
21
|
-
parsl.clear()
|
15
|
+
return config
|
22
16
|
|
23
17
|
|
24
18
|
@python_app
|
@@ -6,6 +6,8 @@ import parsl
|
|
6
6
|
from parsl import python_app, bash_app
|
7
7
|
from parsl.tests.configs.htex_local import fresh_config
|
8
8
|
|
9
|
+
from parsl.executors.high_throughput.mpi_prefix_composer import MissingResourceSpecification
|
10
|
+
|
9
11
|
import os
|
10
12
|
|
11
13
|
EXECUTOR_LABEL = "MPI_TEST"
|
@@ -28,7 +30,6 @@ def local_setup():
|
|
28
30
|
|
29
31
|
def local_teardown():
|
30
32
|
parsl.dfk().cleanup()
|
31
|
-
parsl.clear()
|
32
33
|
|
33
34
|
|
34
35
|
@python_app
|
@@ -169,3 +170,11 @@ def test_simulated_load(rounds: int = 100):
|
|
169
170
|
total_ranks, nodes = future.result(timeout=10)
|
170
171
|
assert len(nodes) == futures[future]["num_nodes"]
|
171
172
|
assert total_ranks == futures[future]["num_nodes"] * futures[future]["ranks_per_node"]
|
173
|
+
|
174
|
+
|
175
|
+
@pytest.mark.local
|
176
|
+
def test_missing_resource_spec():
|
177
|
+
|
178
|
+
with pytest.raises(MissingResourceSpecification):
|
179
|
+
future = mock_app(sleep_dur=0.4)
|
180
|
+
future.result(timeout=10)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
"""Tests for the wrapper class"""
|
2
|
+
from inspect import signature
|
3
|
+
from pathlib import Path
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
import parsl
|
8
|
+
from .test_mpi_mode_enabled import get_env_vars
|
9
|
+
from parsl import HighThroughputExecutor, Config
|
10
|
+
from parsl.launchers import SimpleLauncher
|
11
|
+
from parsl.providers import LocalProvider
|
12
|
+
from parsl.executors.high_throughput.mpi_executor import MPIExecutor
|
13
|
+
|
14
|
+
cwd = Path(__file__).parent.absolute()
|
15
|
+
pbs_nodefile = cwd.joinpath("mocks", "pbs_nodefile")
|
16
|
+
|
17
|
+
|
18
|
+
def local_config():
|
19
|
+
return Config(
|
20
|
+
executors=[
|
21
|
+
MPIExecutor(
|
22
|
+
max_workers_per_block=1,
|
23
|
+
provider=LocalProvider(
|
24
|
+
worker_init=f"export PBS_NODEFILE={pbs_nodefile}",
|
25
|
+
launcher=SimpleLauncher()
|
26
|
+
)
|
27
|
+
)
|
28
|
+
]
|
29
|
+
)
|
30
|
+
|
31
|
+
|
32
|
+
@pytest.mark.local
|
33
|
+
def test_docstring():
|
34
|
+
"""Ensure the old kwargs are copied over into the new class"""
|
35
|
+
assert 'label' in MPIExecutor.__doc__
|
36
|
+
assert 'max_workers_per_block' in MPIExecutor.__doc__
|
37
|
+
assert 'available_accelerators' not in MPIExecutor.__doc__
|
38
|
+
|
39
|
+
|
40
|
+
@pytest.mark.local
|
41
|
+
def test_init():
|
42
|
+
"""Ensure all relevant kwargs are copied over from HTEx"""
|
43
|
+
|
44
|
+
new_kwargs = {'max_workers_per_block'}
|
45
|
+
excluded_kwargs = {'available_accelerators', 'enable_mpi_mode', 'cores_per_worker', 'max_workers_per_node',
|
46
|
+
'mem_per_worker', 'cpu_affinity', 'max_workers'}
|
47
|
+
|
48
|
+
# Get the kwargs from both HTEx and MPIEx
|
49
|
+
htex_kwargs = set(signature(HighThroughputExecutor.__init__).parameters)
|
50
|
+
mpix_kwargs = set(signature(MPIExecutor.__init__).parameters)
|
51
|
+
|
52
|
+
assert mpix_kwargs.difference(htex_kwargs) == new_kwargs
|
53
|
+
assert len(mpix_kwargs.intersection(excluded_kwargs)) == 0
|
54
|
+
assert mpix_kwargs.union(excluded_kwargs).difference(new_kwargs) == htex_kwargs
|
55
|
+
|
56
|
+
|
57
|
+
@pytest.mark.local
|
58
|
+
def test_get_env():
|
59
|
+
future = get_env_vars(parsl_resource_specification={
|
60
|
+
"num_nodes": 3,
|
61
|
+
"ranks_per_node": 5,
|
62
|
+
})
|
63
|
+
env_vars = future.result()
|
64
|
+
assert env_vars['PARSL_NUM_RANKS'] == '15'
|
@@ -19,7 +19,8 @@ from parsl.executors.high_throughput.mpi_resource_management import (
|
|
19
19
|
)
|
20
20
|
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
21
21
|
validate_resource_spec,
|
22
|
-
InvalidResourceSpecification
|
22
|
+
InvalidResourceSpecification,
|
23
|
+
MissingResourceSpecification
|
23
24
|
)
|
24
25
|
|
25
26
|
EXECUTOR_LABEL = "MPI_TEST"
|
@@ -122,18 +123,22 @@ def test_top_level():
|
|
122
123
|
|
123
124
|
@pytest.mark.local
|
124
125
|
@pytest.mark.parametrize(
|
125
|
-
"resource_spec, exception",
|
126
|
+
"resource_spec, is_mpi_enabled, exception",
|
126
127
|
(
|
127
|
-
({"num_nodes": 2, "ranks_per_node": 1}, None),
|
128
|
-
({"launcher_options": "--debug_foo"}, None),
|
129
|
-
({"num_nodes": 2, "BAD_OPT": 1}, InvalidResourceSpecification),
|
130
|
-
({}, None),
|
128
|
+
({"num_nodes": 2, "ranks_per_node": 1}, False, None),
|
129
|
+
({"launcher_options": "--debug_foo"}, False, None),
|
130
|
+
({"num_nodes": 2, "BAD_OPT": 1}, False, InvalidResourceSpecification),
|
131
|
+
({}, False, None),
|
132
|
+
({"num_nodes": 2, "ranks_per_node": 1}, True, None),
|
133
|
+
({"launcher_options": "--debug_foo"}, True, None),
|
134
|
+
({"num_nodes": 2, "BAD_OPT": 1}, True, InvalidResourceSpecification),
|
135
|
+
({}, True, MissingResourceSpecification),
|
131
136
|
)
|
132
137
|
)
|
133
|
-
def test_resource_spec(resource_spec: Dict, exception):
|
138
|
+
def test_resource_spec(resource_spec: Dict, is_mpi_enabled: bool, exception):
|
134
139
|
if exception:
|
135
140
|
with pytest.raises(exception):
|
136
|
-
validate_resource_spec(resource_spec)
|
141
|
+
validate_resource_spec(resource_spec, is_mpi_enabled)
|
137
142
|
else:
|
138
|
-
result = validate_resource_spec(resource_spec)
|
143
|
+
result = validate_resource_spec(resource_spec, is_mpi_enabled)
|
139
144
|
assert result is None
|
@@ -15,14 +15,6 @@ def foo(x, stdout='foo.stdout'):
|
|
15
15
|
return f"echo {x + 1}"
|
16
16
|
|
17
17
|
|
18
|
-
def local_setup():
|
19
|
-
pass
|
20
|
-
|
21
|
-
|
22
|
-
def local_teardown():
|
23
|
-
parsl.clear()
|
24
|
-
|
25
|
-
|
26
18
|
@pytest.mark.local
|
27
19
|
def test_within_context_manger(tmpd_cwd):
|
28
20
|
config = fresh_config()
|
@@ -37,4 +29,4 @@ def test_within_context_manger(tmpd_cwd):
|
|
37
29
|
|
38
30
|
with pytest.raises(NoDataFlowKernelError) as excinfo:
|
39
31
|
square(2).result()
|
40
|
-
assert str(excinfo.value) == "
|
32
|
+
assert str(excinfo.value) == "Must first load config"
|
@@ -3,24 +3,28 @@ import pytest
|
|
3
3
|
from concurrent.futures import Future
|
4
4
|
from parsl import python_app
|
5
5
|
|
6
|
+
from typing import TypeVar
|
7
|
+
|
8
|
+
T = TypeVar('T')
|
9
|
+
|
6
10
|
|
7
11
|
@python_app
|
8
|
-
def returns_a_dict():
|
12
|
+
def returns_a_dict() -> dict:
|
9
13
|
return {"a": "X", "b": "Y"}
|
10
14
|
|
11
15
|
|
12
16
|
@python_app
|
13
|
-
def returns_a_list():
|
17
|
+
def returns_a_list() -> list:
|
14
18
|
return ["X", "Y"]
|
15
19
|
|
16
20
|
|
17
21
|
@python_app
|
18
|
-
def returns_a_tuple():
|
22
|
+
def returns_a_tuple() -> tuple:
|
19
23
|
return ("X", "Y")
|
20
24
|
|
21
25
|
|
22
26
|
@python_app
|
23
|
-
def returns_a_class():
|
27
|
+
def returns_a_class() -> type:
|
24
28
|
from dataclasses import dataclass
|
25
29
|
|
26
30
|
@dataclass
|
@@ -38,7 +42,7 @@ class MyOuterClass():
|
|
38
42
|
|
39
43
|
|
40
44
|
@python_app
|
41
|
-
def returns_a_class_instance():
|
45
|
+
def returns_a_class_instance() -> object:
|
42
46
|
return MyOuterClass()
|
43
47
|
|
44
48
|
|
@@ -110,7 +114,7 @@ def test_returns_a_class():
|
|
110
114
|
|
111
115
|
|
112
116
|
@python_app
|
113
|
-
def passthrough(v):
|
117
|
+
def passthrough(v: T) -> T:
|
114
118
|
return v
|
115
119
|
|
116
120
|
|
@@ -0,0 +1,161 @@
|
|
1
|
+
from concurrent.futures import Future
|
2
|
+
from pathlib import Path
|
3
|
+
from threading import Event
|
4
|
+
from typing import Sequence
|
5
|
+
|
6
|
+
import pytest
|
7
|
+
|
8
|
+
import parsl
|
9
|
+
from parsl.config import Config
|
10
|
+
from parsl.dataflow.errors import DependencyError
|
11
|
+
from parsl.dataflow.dependency_resolvers import DEEP_DEPENDENCY_RESOLVER
|
12
|
+
|
13
|
+
|
14
|
+
def local_config():
|
15
|
+
return Config(dependency_resolver=DEEP_DEPENDENCY_RESOLVER)
|
16
|
+
|
17
|
+
|
18
|
+
@parsl.python_app
|
19
|
+
def a(event):
|
20
|
+
event.wait()
|
21
|
+
return 7
|
22
|
+
|
23
|
+
|
24
|
+
@parsl.python_app
|
25
|
+
def b(x: int):
|
26
|
+
return x + 1
|
27
|
+
|
28
|
+
|
29
|
+
@pytest.mark.local
|
30
|
+
def test_simple_pos_arg():
|
31
|
+
e = Event()
|
32
|
+
s = a(e)
|
33
|
+
f_b = b(s)
|
34
|
+
e.set()
|
35
|
+
|
36
|
+
assert f_b.result() == 8
|
37
|
+
|
38
|
+
|
39
|
+
@parsl.python_app
|
40
|
+
def b_first(x: Sequence[int]):
|
41
|
+
return x[0] + 1
|
42
|
+
|
43
|
+
|
44
|
+
@pytest.mark.local
|
45
|
+
def test_tuple_pos_arg():
|
46
|
+
e = Event()
|
47
|
+
s = (a(e),)
|
48
|
+
f_b = b_first(s)
|
49
|
+
e.set()
|
50
|
+
assert f_b.result() == 8
|
51
|
+
|
52
|
+
|
53
|
+
@pytest.mark.local
|
54
|
+
def test_list_exception():
|
55
|
+
a = Future()
|
56
|
+
a.set_exception(RuntimeError("artificial error"))
|
57
|
+
f_b = b([a])
|
58
|
+
assert isinstance(f_b.exception(), DependencyError)
|
59
|
+
|
60
|
+
|
61
|
+
@parsl.python_app
|
62
|
+
def make_path(s: str):
|
63
|
+
return Path(s)
|
64
|
+
|
65
|
+
|
66
|
+
@parsl.python_app
|
67
|
+
def append_paths(iterable, end_str: str = "end"):
|
68
|
+
type_ = type(iterable)
|
69
|
+
return type_([Path(s, end_str) for s in iterable])
|
70
|
+
|
71
|
+
|
72
|
+
@pytest.mark.local
|
73
|
+
@pytest.mark.parametrize(
|
74
|
+
"type_",
|
75
|
+
[
|
76
|
+
tuple,
|
77
|
+
list,
|
78
|
+
set,
|
79
|
+
],
|
80
|
+
)
|
81
|
+
def test_resolving_iterables(type_):
|
82
|
+
output1 = make_path("test1")
|
83
|
+
output2 = make_path("test2")
|
84
|
+
output3 = append_paths(type_([output1, output2]), end_str="end")
|
85
|
+
assert output3.result() == type_([Path("test1", "end"), Path("test2", "end")])
|
86
|
+
|
87
|
+
|
88
|
+
@parsl.python_app
|
89
|
+
def append_paths_dict(iterable: dict, end_str: str = "end"):
|
90
|
+
return {Path(k, end_str): Path(v, end_str) for k, v in iterable.items()}
|
91
|
+
|
92
|
+
|
93
|
+
@pytest.mark.local
|
94
|
+
def test_resolving_dict():
|
95
|
+
output1 = make_path("test1")
|
96
|
+
output2 = make_path("test2")
|
97
|
+
output3 = append_paths_dict({output1: output2}, end_str="end")
|
98
|
+
assert output3.result() == {Path("test1", "end"): Path("test2", "end")}
|
99
|
+
|
100
|
+
|
101
|
+
@parsl.python_app
|
102
|
+
def extract_deep(struct: list):
|
103
|
+
return struct[0][0][0][0][0]
|
104
|
+
|
105
|
+
|
106
|
+
@pytest.mark.local
|
107
|
+
def test_deeper_list():
|
108
|
+
f = Future()
|
109
|
+
f.set_result(7)
|
110
|
+
f_b = extract_deep([[[[[f]]]]])
|
111
|
+
|
112
|
+
assert f_b.result() == 7
|
113
|
+
|
114
|
+
|
115
|
+
@pytest.mark.local
|
116
|
+
def test_deeper_list_and_tuple():
|
117
|
+
f = Future()
|
118
|
+
f.set_result(7)
|
119
|
+
f_b = extract_deep([([([f],)],)])
|
120
|
+
|
121
|
+
assert f_b.result() == 7
|
122
|
+
|
123
|
+
|
124
|
+
@parsl.python_app
|
125
|
+
def dictionary_checker(d):
|
126
|
+
assert d["a"] == [30, 10]
|
127
|
+
assert d["b"] == 20
|
128
|
+
|
129
|
+
|
130
|
+
@pytest.mark.local
|
131
|
+
def test_dictionary():
|
132
|
+
k1 = Future()
|
133
|
+
k1.set_result("a")
|
134
|
+
k2 = Future()
|
135
|
+
k2.set_result("b")
|
136
|
+
v1 = Future()
|
137
|
+
v1.set_result(10)
|
138
|
+
|
139
|
+
# this .result() will fail if the asserts fail
|
140
|
+
dictionary_checker({k1: [30, v1], k2: 20}).result()
|
141
|
+
|
142
|
+
|
143
|
+
@pytest.mark.local
|
144
|
+
def test_dictionary_later():
|
145
|
+
k1 = Future()
|
146
|
+
k2 = Future()
|
147
|
+
v1 = Future()
|
148
|
+
|
149
|
+
f1 = dictionary_checker({k1: [30, v1], k2: 20})
|
150
|
+
|
151
|
+
assert not f1.done()
|
152
|
+
k1.set_result("a")
|
153
|
+
k2.set_result("b")
|
154
|
+
v1.set_result(10)
|
155
|
+
|
156
|
+
# having set the results, f1 should fairly rapidly complete (but not
|
157
|
+
# instantly) so we can't assert on done() here... but we can
|
158
|
+
# check that f1 does "eventually" complete... meaning that
|
159
|
+
# none of the assertions inside test_dictionary have failed
|
160
|
+
|
161
|
+
assert f1.result() is None
|
@@ -72,7 +72,5 @@ def test_shutdown_scalein_blocks(tmpd_cwd, try_assert):
|
|
72
72
|
# this will wait for everything to be scaled out fully
|
73
73
|
try_assert(lambda: len(htex.connected_managers()) == BLOCK_COUNT)
|
74
74
|
|
75
|
-
parsl.clear()
|
76
|
-
|
77
75
|
assert len(accumulating_provider.submit_job_ids) == BLOCK_COUNT, f"Exactly {BLOCK_COUNT} blocks should have been launched"
|
78
76
|
assert len(accumulating_provider.cancel_job_ids) == BLOCK_COUNT, f"Exactly {BLOCK_COUNT} blocks should have been scaled in"
|
@@ -25,7 +25,6 @@ def test_no_kills():
|
|
25
25
|
assert parsl.dfk().monitoring is not None, "This test requires monitoring"
|
26
26
|
|
27
27
|
parsl.dfk().cleanup()
|
28
|
-
parsl.clear()
|
29
28
|
|
30
29
|
|
31
30
|
@pytest.mark.local
|
@@ -62,4 +61,3 @@ def test_kill_monitoring_helper_process(sig, process_attr, try_assert):
|
|
62
61
|
simple_app().result()
|
63
62
|
|
64
63
|
parsl.dfk().cleanup()
|
65
|
-
parsl.clear()
|
@@ -60,7 +60,6 @@ def test_1316_local_path_on_execution_side_sp2():
|
|
60
60
|
assert not file.local_path, "The local_path on the submit side should not be set"
|
61
61
|
|
62
62
|
parsl.dfk().cleanup()
|
63
|
-
parsl.clear()
|
64
63
|
|
65
64
|
|
66
65
|
@pytest.mark.local
|
@@ -83,4 +82,3 @@ def test_1316_local_path_setting_preserves_dependency_sp2():
|
|
83
82
|
assert not file.local_path, "The local_path on the submit side should not be set"
|
84
83
|
|
85
84
|
parsl.dfk().cleanup()
|
86
|
-
parsl.clear()
|
parsl/tests/test_summary.py
CHANGED
parsl/version.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.5.
|
3
|
+
Version: 2024.5.27
|
4
4
|
Summary: Simple data dependent workflows in Python
|
5
5
|
Home-page: https://github.com/Parsl/parsl
|
6
|
-
Download-URL: https://github.com/Parsl/parsl/archive/2024.05.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2024.05.27.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -55,7 +55,8 @@ Requires-Dist: pyyaml ; extra == 'all'
|
|
55
55
|
Requires-Dist: cffi ; extra == 'all'
|
56
56
|
Requires-Dist: jsonschema ; extra == 'all'
|
57
57
|
Requires-Dist: proxystore ; extra == 'all'
|
58
|
-
Requires-Dist: radical.pilot ==1.
|
58
|
+
Requires-Dist: radical.pilot ==1.60 ; extra == 'all'
|
59
|
+
Requires-Dist: radical.utils ==1.60 ; extra == 'all'
|
59
60
|
Provides-Extra: aws
|
60
61
|
Requires-Dist: boto3 ; extra == 'aws'
|
61
62
|
Provides-Extra: azure
|
@@ -84,7 +85,8 @@ Requires-Dist: oauth-ssh >=0.9 ; extra == 'oauth_ssh'
|
|
84
85
|
Provides-Extra: proxystore
|
85
86
|
Requires-Dist: proxystore ; extra == 'proxystore'
|
86
87
|
Provides-Extra: radical-pilot
|
87
|
-
Requires-Dist: radical.pilot ==1.
|
88
|
+
Requires-Dist: radical.pilot ==1.60 ; extra == 'radical-pilot'
|
89
|
+
Requires-Dist: radical.utils ==1.60 ; extra == 'radical-pilot'
|
88
90
|
Provides-Extra: visualization
|
89
91
|
Requires-Dist: pydot ; extra == 'visualization'
|
90
92
|
Requires-Dist: networkx <2.6,>=2.5 ; extra == 'visualization'
|