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.
Files changed (67) hide show
  1. parsl/channels/base.py +2 -9
  2. parsl/channels/local/local.py +3 -6
  3. parsl/channels/oauth_ssh/oauth_ssh.py +2 -2
  4. parsl/channels/ssh/ssh.py +2 -2
  5. parsl/config.py +7 -1
  6. parsl/dataflow/dependency_resolvers.py +115 -0
  7. parsl/dataflow/dflow.py +45 -39
  8. parsl/executors/__init__.py +2 -0
  9. parsl/executors/base.py +7 -7
  10. parsl/executors/high_throughput/errors.py +10 -0
  11. parsl/executors/high_throughput/executor.py +85 -84
  12. parsl/executors/high_throughput/interchange.py +6 -5
  13. parsl/executors/high_throughput/mpi_executor.py +85 -0
  14. parsl/executors/high_throughput/mpi_prefix_composer.py +18 -2
  15. parsl/executors/high_throughput/mpi_resource_management.py +3 -0
  16. parsl/executors/high_throughput/zmq_pipes.py +36 -2
  17. parsl/executors/radical/rpex_resources.py +3 -7
  18. parsl/monitoring/remote.py +18 -24
  19. parsl/providers/local/local.py +1 -1
  20. parsl/tests/conftest.py +2 -2
  21. parsl/tests/sites/test_dynamic_executor.py +0 -1
  22. parsl/tests/test_bash_apps/test_std_uri.py +0 -6
  23. parsl/tests/test_checkpointing/test_periodic.py +2 -7
  24. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -1
  25. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
  26. parsl/tests/test_checkpointing/test_task_exit.py +0 -1
  27. parsl/tests/test_htex/test_basic.py +0 -1
  28. parsl/tests/test_htex/test_command_client_timeout.py +69 -0
  29. parsl/tests/test_htex/test_cpu_affinity_explicit.py +1 -8
  30. parsl/tests/test_htex/test_manager_failure.py +0 -1
  31. parsl/tests/test_htex/test_managers_command.py +2 -7
  32. parsl/tests/test_htex/test_missing_worker.py +2 -8
  33. parsl/tests/test_monitoring/test_app_names.py +0 -1
  34. parsl/tests/test_monitoring/test_basic.py +0 -2
  35. parsl/tests/test_monitoring/test_db_locks.py +0 -1
  36. parsl/tests/test_monitoring/test_fuzz_zmq.py +0 -1
  37. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -2
  38. parsl/tests/test_monitoring/test_incomplete_futures.py +0 -1
  39. parsl/tests/test_monitoring/test_memoization_representation.py +0 -1
  40. parsl/tests/test_monitoring/test_stdouterr.py +0 -2
  41. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +6 -14
  42. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +2 -8
  43. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +10 -1
  44. parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
  45. parsl/tests/test_mpi_apps/test_resource_spec.py +14 -9
  46. parsl/tests/test_python_apps/test_context_manager.py +1 -9
  47. parsl/tests/test_python_apps/test_lifted.py +10 -6
  48. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
  49. parsl/tests/test_scaling/test_regression_1621.py +0 -2
  50. parsl/tests/test_scaling/test_shutdown_scalein.py +0 -2
  51. parsl/tests/test_serialization/test_proxystore_configured.py +0 -1
  52. parsl/tests/test_shutdown/test_kill_monitoring.py +0 -2
  53. parsl/tests/test_staging/test_1316.py +0 -2
  54. parsl/tests/test_staging/test_elaborate_noop_file.py +0 -1
  55. parsl/tests/test_summary.py +0 -1
  56. parsl/tests/test_threads/test_configs.py +0 -1
  57. parsl/tests/test_threads/test_lazy_errors.py +0 -1
  58. parsl/version.py +1 -1
  59. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/METADATA +6 -4
  60. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/RECORD +67 -62
  61. {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/exec_parsl_function.py +0 -0
  62. {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/parsl_coprocess.py +0 -0
  63. {parsl-2024.5.13.data → parsl-2024.5.27.data}/scripts/process_worker_pool.py +0 -0
  64. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/LICENSE +0 -0
  65. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/WHEEL +0 -0
  66. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/entry_points.txt +0 -0
  67. {parsl-2024.5.13.dist-info → parsl-2024.5.27.dist-info}/top_level.txt +0 -0
@@ -47,7 +47,6 @@ def test_hashsum():
47
47
 
48
48
  logger.info("cleaning up parsl")
49
49
  parsl.dfk().cleanup()
50
- parsl.clear()
51
50
 
52
51
  # at this point, we should find one row in the monitoring database.
53
52
 
@@ -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, SingleNodeLauncher, SimpleLauncher, AprunLauncher
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 SingleNodeLauncher is supplied"""
11
+ """AssertionError if a launcher other than SimpleLauncher is supplied"""
12
12
 
13
- for launcher in [SrunLauncher(), SimpleLauncher(), AprunLauncher()]:
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 SingleNodeLauncer works with mpi_mode"""
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=SingleNodeLauncher()),
30
+ provider=SlurmProvider(launcher=SimpleLauncher()),
31
31
  )
32
32
  ])
33
- assert isinstance(config.executors[0].provider.launcher, SingleNodeLauncher)
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 local_setup():
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
- parsl.load(config)
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) == "Cannot submit to a DFK that has been cleaned up"
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
@@ -69,6 +69,4 @@ def test_one_block(tmpd_cwd):
69
69
  with parsl.load(config):
70
70
  app().result()
71
71
 
72
- parsl.clear()
73
-
74
72
  assert oneshot_provider.recorded_submits == 1
@@ -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"
@@ -38,7 +38,6 @@ def local_setup():
38
38
 
39
39
  def local_teardown():
40
40
  parsl.dfk().cleanup()
41
- parsl.clear()
42
41
 
43
42
  methods_for_data.clear()
44
43
  methods_for_data.update(previous_methods)
@@ -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()
@@ -44,7 +44,6 @@ def storage_access_parsl():
44
44
  yield _setup_config
45
45
 
46
46
  parsl.dfk().cleanup()
47
- parsl.clear()
48
47
 
49
48
 
50
49
  @pytest.mark.local
@@ -22,7 +22,6 @@ def test_summary(caplog):
22
22
  fail().exception()
23
23
 
24
24
  parsl.dfk().cleanup()
25
- parsl.clear()
26
25
 
27
26
  assert "Summary of tasks in DFK:" in caplog.text
28
27
  assert "Tasks in state States.exec_done: 1" in caplog.text
@@ -30,5 +30,4 @@ def test_parallel_for():
30
30
  assert thread_count <= config.executors[0].max_threads, "More threads than allowed"
31
31
  assert process_count == 1, "More processes than allowed"
32
32
  dfk.cleanup()
33
- parsl.clear()
34
33
  return d
@@ -24,5 +24,4 @@ def test_lazy_behavior():
24
24
  assert f.done()
25
25
 
26
26
  parsl.dfk().cleanup()
27
- parsl.clear()
28
27
  return
parsl/version.py CHANGED
@@ -3,4 +3,4 @@
3
3
  Year.Month.Day[alpha/beta/..]
4
4
  Alphas will be numbered like this -> 2024.12.10a0
5
5
  """
6
- VERSION = '2024.05.13'
6
+ VERSION = '2024.05.27'
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.5.13
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.13.tar.gz
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.52.1 ; extra == 'all'
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.52.1 ; extra == 'radical-pilot'
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'