parsl 2025.9.15__py3-none-any.whl → 2025.9.22__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.
Potentially problematic release.
This version of parsl might be problematic. Click here for more details.
- parsl/executors/execute_task.py +2 -8
- parsl/executors/flux/executor.py +3 -5
- parsl/executors/high_throughput/executor.py +2 -4
- parsl/executors/high_throughput/interchange.py +4 -3
- parsl/executors/high_throughput/mpi_resource_management.py +1 -7
- parsl/executors/high_throughput/process_worker_pool.py +5 -1
- parsl/executors/radical/executor.py +2 -6
- parsl/executors/radical/rpex_worker.py +2 -2
- parsl/serialize/__init__.py +6 -9
- parsl/serialize/facade.py +0 -32
- parsl/tests/test_execute_task.py +2 -11
- parsl/tests/test_htex/test_priority_queue.py +7 -2
- parsl/tests/test_mpi_apps/test_mpi_scheduler.py +18 -43
- parsl/version.py +1 -1
- {parsl-2025.9.15.data → parsl-2025.9.22.data}/scripts/interchange.py +4 -3
- {parsl-2025.9.15.data → parsl-2025.9.22.data}/scripts/process_worker_pool.py +5 -1
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/METADATA +2 -2
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/RECORD +24 -25
- parsl/tests/test_serialization/test_pack_resource_spec.py +0 -23
- {parsl-2025.9.15.data → parsl-2025.9.22.data}/scripts/exec_parsl_function.py +0 -0
- {parsl-2025.9.15.data → parsl-2025.9.22.data}/scripts/parsl_coprocess.py +0 -0
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/LICENSE +0 -0
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/WHEEL +0 -0
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/entry_points.txt +0 -0
- {parsl-2025.9.15.dist-info → parsl-2025.9.22.dist-info}/top_level.txt +0 -0
parsl/executors/execute_task.py
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
from parsl.serialize import unpack_res_spec_apply_message
|
|
1
|
+
from parsl.serialize import unpack_apply_message
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
def execute_task(bufs: bytes):
|
|
7
5
|
"""Deserialize the buffer and execute the task.
|
|
8
6
|
Returns the result or throws exception.
|
|
9
7
|
"""
|
|
10
|
-
f, args, kwargs
|
|
11
|
-
|
|
12
|
-
for varname in resource_spec:
|
|
13
|
-
envname = "PARSL_" + str(varname).upper()
|
|
14
|
-
os.environ[envname] = str(resource_spec[varname])
|
|
8
|
+
f, args, kwargs = unpack_apply_message(bufs)
|
|
15
9
|
|
|
16
10
|
# We might need to look into callability of the function from itself
|
|
17
11
|
# since we change it's name in the new namespace
|
parsl/executors/flux/executor.py
CHANGED
|
@@ -24,7 +24,7 @@ from parsl.executors.flux.execute_parsl_task import __file__ as _WORKER_PATH
|
|
|
24
24
|
from parsl.executors.flux.flux_instance_manager import __file__ as _MANAGER_PATH
|
|
25
25
|
from parsl.providers import LocalProvider
|
|
26
26
|
from parsl.providers.base import ExecutionProvider
|
|
27
|
-
from parsl.serialize import deserialize,
|
|
27
|
+
from parsl.serialize import deserialize, pack_apply_message
|
|
28
28
|
from parsl.serialize.errors import SerializationError
|
|
29
29
|
from parsl.utils import RepresentationMixin
|
|
30
30
|
|
|
@@ -284,10 +284,8 @@ class FluxExecutor(ParslExecutor, RepresentationMixin):
|
|
|
284
284
|
infile = os.path.join(self.working_dir, f"{task_id}_in{os.extsep}pkl")
|
|
285
285
|
outfile = os.path.join(self.working_dir, f"{task_id}_out{os.extsep}pkl")
|
|
286
286
|
try:
|
|
287
|
-
fn_buf =
|
|
288
|
-
func, args, kwargs,
|
|
289
|
-
resource_specification={},
|
|
290
|
-
buffer_threshold=1024 * 1024
|
|
287
|
+
fn_buf = pack_apply_message(
|
|
288
|
+
func, args, kwargs, buffer_threshold=1 << 20,
|
|
291
289
|
)
|
|
292
290
|
except TypeError:
|
|
293
291
|
raise SerializationError(func.__name__)
|
|
@@ -35,7 +35,7 @@ from parsl.monitoring.radios.zmq_router import ZMQRadioReceiver, start_zmq_recei
|
|
|
35
35
|
from parsl.process_loggers import wrap_with_logs
|
|
36
36
|
from parsl.providers import LocalProvider
|
|
37
37
|
from parsl.providers.base import ExecutionProvider
|
|
38
|
-
from parsl.serialize import deserialize,
|
|
38
|
+
from parsl.serialize import deserialize, pack_apply_message
|
|
39
39
|
from parsl.serialize.errors import DeserializationError, SerializationError
|
|
40
40
|
from parsl.usage_tracking.api import UsageInformation
|
|
41
41
|
from parsl.utils import RepresentationMixin
|
|
@@ -708,9 +708,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
|
|
|
708
708
|
self.tasks[task_id] = fut
|
|
709
709
|
|
|
710
710
|
try:
|
|
711
|
-
fn_buf =
|
|
712
|
-
resource_specification=resource_specification,
|
|
713
|
-
buffer_threshold=1024 * 1024)
|
|
711
|
+
fn_buf = pack_apply_message(func, args, kwargs, buffer_threshold=1 << 20)
|
|
714
712
|
except TypeError:
|
|
715
713
|
raise SerializationError(func.__name__)
|
|
716
714
|
|
|
@@ -23,7 +23,6 @@ from parsl.monitoring.radios.base import MonitoringRadioSender
|
|
|
23
23
|
from parsl.monitoring.radios.zmq import ZMQRadioSender
|
|
24
24
|
from parsl.process_loggers import wrap_with_logs
|
|
25
25
|
from parsl.serialize import serialize as serialize_object
|
|
26
|
-
from parsl.utils import setproctitle
|
|
27
26
|
from parsl.version import VERSION as PARSL_VERSION
|
|
28
27
|
|
|
29
28
|
PKL_HEARTBEAT_CODE = pickle.dumps((2 ** 32) - 1)
|
|
@@ -220,7 +219,7 @@ class Interchange:
|
|
|
220
219
|
|
|
221
220
|
reply: Any # the type of reply depends on the command_req received (aka this needs dependent types...)
|
|
222
221
|
|
|
223
|
-
if self.
|
|
222
|
+
if self.socks.get(self.command_channel) == zmq.POLLIN:
|
|
224
223
|
logger.debug("entering command_server section")
|
|
225
224
|
|
|
226
225
|
command_req = self.command_channel.recv_pyobj()
|
|
@@ -328,7 +327,7 @@ class Interchange:
|
|
|
328
327
|
"""Process incoming task message(s).
|
|
329
328
|
"""
|
|
330
329
|
|
|
331
|
-
if self.
|
|
330
|
+
if self.socks.get(self.task_incoming) == zmq.POLLIN:
|
|
332
331
|
logger.debug("start task_incoming section")
|
|
333
332
|
msg = self.task_incoming.recv_pyobj()
|
|
334
333
|
|
|
@@ -627,6 +626,8 @@ def start_file_logger(filename: str, level: int = logging.DEBUG, format_string:
|
|
|
627
626
|
|
|
628
627
|
|
|
629
628
|
if __name__ == "__main__":
|
|
629
|
+
from parsl.utils import setproctitle
|
|
630
|
+
|
|
630
631
|
setproctitle("parsl: HTEX interchange")
|
|
631
632
|
|
|
632
633
|
config = pickle.load(sys.stdin.buffer)
|
|
@@ -9,7 +9,6 @@ from enum import Enum
|
|
|
9
9
|
from typing import Dict, List, Optional
|
|
10
10
|
|
|
11
11
|
from parsl.multiprocessing import SpawnContext
|
|
12
|
-
from parsl.serialize import pack_res_spec_apply_message, unpack_res_spec_apply_message
|
|
13
12
|
|
|
14
13
|
logger = logging.getLogger(__name__)
|
|
15
14
|
|
|
@@ -167,9 +166,7 @@ class MPITaskScheduler(TaskScheduler):
|
|
|
167
166
|
|
|
168
167
|
def put_task(self, task_package: dict):
|
|
169
168
|
"""Schedule task if resources are available otherwise backlog the task"""
|
|
170
|
-
|
|
171
|
-
user_ns.update({"__builtins__": __builtins__})
|
|
172
|
-
_f, _args, _kwargs, resource_spec = unpack_res_spec_apply_message(task_package["buffer"])
|
|
169
|
+
resource_spec = task_package.get("resource_spec", {})
|
|
173
170
|
|
|
174
171
|
nodes_needed = resource_spec.get("num_nodes")
|
|
175
172
|
tid = task_package["task_id"]
|
|
@@ -183,9 +180,6 @@ class MPITaskScheduler(TaskScheduler):
|
|
|
183
180
|
else:
|
|
184
181
|
resource_spec["MPI_NODELIST"] = ",".join(allocated_nodes)
|
|
185
182
|
self._map_tasks_to_nodes[tid] = allocated_nodes
|
|
186
|
-
buffer = pack_res_spec_apply_message(_f, _args, _kwargs, resource_spec)
|
|
187
|
-
task_package["buffer"] = buffer
|
|
188
|
-
task_package["resource_spec"] = resource_spec
|
|
189
183
|
|
|
190
184
|
self.pending_task_q.put(task_package)
|
|
191
185
|
|
|
@@ -603,6 +603,10 @@ def update_resource_spec_env_vars(mpi_launcher: str, resource_spec: Dict, node_i
|
|
|
603
603
|
|
|
604
604
|
|
|
605
605
|
def _init_mpi_env(mpi_launcher: str, resource_spec: Dict):
|
|
606
|
+
for varname in resource_spec:
|
|
607
|
+
envname = "PARSL_" + str(varname).upper()
|
|
608
|
+
os.environ[envname] = str(resource_spec[varname])
|
|
609
|
+
|
|
606
610
|
node_list = resource_spec.get("MPI_NODELIST")
|
|
607
611
|
if node_list is None:
|
|
608
612
|
return
|
|
@@ -753,8 +757,8 @@ def worker(
|
|
|
753
757
|
worker_enqueued = True
|
|
754
758
|
|
|
755
759
|
try:
|
|
756
|
-
# The worker will receive {'task_id':<tid>, 'buffer':<buf>}
|
|
757
760
|
req = task_queue.get(timeout=task_queue_timeout)
|
|
761
|
+
# req is {'task_id':<tid>, 'buffer':<buf>, 'resource_spec':<dict>}
|
|
758
762
|
except queue.Empty:
|
|
759
763
|
continue
|
|
760
764
|
|
|
@@ -20,7 +20,7 @@ from parsl.app.errors import BashExitFailure, RemoteExceptionWrapper
|
|
|
20
20
|
from parsl.app.python import timeout
|
|
21
21
|
from parsl.data_provider.files import File
|
|
22
22
|
from parsl.executors.base import ParslExecutor
|
|
23
|
-
from parsl.serialize import deserialize,
|
|
23
|
+
from parsl.serialize import deserialize, pack_apply_message
|
|
24
24
|
from parsl.serialize.errors import DeserializationError, SerializationError
|
|
25
25
|
from parsl.utils import RepresentationMixin
|
|
26
26
|
|
|
@@ -441,11 +441,7 @@ class RadicalPilotExecutor(ParslExecutor, RepresentationMixin):
|
|
|
441
441
|
|
|
442
442
|
def _pack_and_apply_message(self, func, args, kwargs):
|
|
443
443
|
try:
|
|
444
|
-
buffer =
|
|
445
|
-
args,
|
|
446
|
-
kwargs,
|
|
447
|
-
resource_specification={},
|
|
448
|
-
buffer_threshold=1024 * 1024)
|
|
444
|
+
buffer = pack_apply_message(func, args, kwargs, buffer_threshold=1 << 20)
|
|
449
445
|
task_func = rp.utils.serialize_bson(buffer)
|
|
450
446
|
except TypeError:
|
|
451
447
|
raise SerializationError(func.__name__)
|
|
@@ -5,7 +5,7 @@ import radical.pilot as rp
|
|
|
5
5
|
import parsl.app.errors as pe
|
|
6
6
|
from parsl.app.bash import remote_side_bash_executor
|
|
7
7
|
from parsl.executors.execute_task import execute_task
|
|
8
|
-
from parsl.serialize import serialize,
|
|
8
|
+
from parsl.serialize import serialize, unpack_apply_message
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class ParslWorker:
|
|
@@ -33,7 +33,7 @@ class ParslWorker:
|
|
|
33
33
|
|
|
34
34
|
try:
|
|
35
35
|
buffer = rp.utils.deserialize_bson(task['description']['executable'])
|
|
36
|
-
func, args, kwargs
|
|
36
|
+
func, args, kwargs = unpack_apply_message(buffer)
|
|
37
37
|
ret = remote_side_bash_executor(func, *args, **kwargs)
|
|
38
38
|
exc = (None, None)
|
|
39
39
|
val = None
|
parsl/serialize/__init__.py
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
from parsl.serialize.facade import (
|
|
2
2
|
deserialize,
|
|
3
3
|
pack_apply_message,
|
|
4
|
-
pack_res_spec_apply_message,
|
|
5
4
|
serialize,
|
|
6
5
|
unpack_apply_message,
|
|
7
|
-
unpack_res_spec_apply_message,
|
|
8
6
|
)
|
|
9
7
|
|
|
10
|
-
__all__ =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
]
|
|
8
|
+
__all__ = (
|
|
9
|
+
"serialize",
|
|
10
|
+
"deserialize",
|
|
11
|
+
"pack_apply_message",
|
|
12
|
+
"unpack_apply_message",
|
|
13
|
+
)
|
parsl/serialize/facade.py
CHANGED
|
@@ -62,44 +62,12 @@ def pack_apply_message(func: Any, args: Any, kwargs: Any, buffer_threshold: int
|
|
|
62
62
|
return packed_buffer
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def pack_res_spec_apply_message(func: Any, args: Any, kwargs: Any, resource_specification: Any, buffer_threshold: int = int(128 * 1e6)) -> bytes:
|
|
66
|
-
"""Serialize and pack function, parameters, and resource_specification
|
|
67
|
-
|
|
68
|
-
Parameters
|
|
69
|
-
----------
|
|
70
|
-
|
|
71
|
-
func: Function
|
|
72
|
-
A function to ship
|
|
73
|
-
|
|
74
|
-
args: Tuple/list of objects
|
|
75
|
-
positional parameters as a list
|
|
76
|
-
|
|
77
|
-
kwargs: Dict
|
|
78
|
-
Dict containing named parameters
|
|
79
|
-
|
|
80
|
-
resource_specification: Dict
|
|
81
|
-
Dict containing application resource specification
|
|
82
|
-
|
|
83
|
-
buffer_threshold: int
|
|
84
|
-
Limits buffer to specified size in bytes. Exceeding this limit would give you
|
|
85
|
-
a warning in the log. Default is 128MB.
|
|
86
|
-
"""
|
|
87
|
-
return pack_apply_message(func, args, (kwargs, resource_specification), buffer_threshold=buffer_threshold)
|
|
88
|
-
|
|
89
|
-
|
|
90
65
|
def unpack_apply_message(packed_buffer: bytes) -> List[Any]:
|
|
91
66
|
""" Unpack and deserialize function and parameters
|
|
92
67
|
"""
|
|
93
68
|
return [deserialize(buf) for buf in unpack_buffers(packed_buffer)]
|
|
94
69
|
|
|
95
70
|
|
|
96
|
-
def unpack_res_spec_apply_message(packed_buffer: bytes) -> List[Any]:
|
|
97
|
-
""" Unpack and deserialize function, parameters, and resource_specification
|
|
98
|
-
"""
|
|
99
|
-
func, args, (kwargs, resource_spec) = unpack_apply_message(packed_buffer)
|
|
100
|
-
return [func, args, kwargs, resource_spec]
|
|
101
|
-
|
|
102
|
-
|
|
103
71
|
def serialize(obj: Any, buffer_threshold: int = int(1e6)) -> bytes:
|
|
104
72
|
""" Try available serialization methods one at a time
|
|
105
73
|
|
parsl/tests/test_execute_task.py
CHANGED
|
@@ -3,7 +3,7 @@ import os
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
5
|
from parsl.executors.execute_task import execute_task
|
|
6
|
-
from parsl.serialize.facade import
|
|
6
|
+
from parsl.serialize.facade import pack_apply_message
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def addemup(*args: int, name: str = "apples"):
|
|
@@ -15,15 +15,6 @@ def addemup(*args: int, name: str = "apples"):
|
|
|
15
15
|
def test_execute_task():
|
|
16
16
|
args = (1, 2, 3)
|
|
17
17
|
kwargs = {"name": "boots"}
|
|
18
|
-
buff =
|
|
18
|
+
buff = pack_apply_message(addemup, args, kwargs)
|
|
19
19
|
res = execute_task(buff)
|
|
20
20
|
assert res == addemup(*args, **kwargs)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.local
|
|
24
|
-
def test_execute_task_resource_spec():
|
|
25
|
-
resource_spec = {"num_nodes": 2, "ranks_per_node": 2, "num_ranks": 4}
|
|
26
|
-
buff = pack_res_spec_apply_message(addemup, (1, 2), {}, resource_spec)
|
|
27
|
-
execute_task(buff)
|
|
28
|
-
for key, val in resource_spec.items():
|
|
29
|
-
assert os.environ[f"PARSL_{key.upper()}"] == str(val)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from random import randint
|
|
2
|
+
|
|
1
3
|
import pytest
|
|
2
4
|
|
|
3
5
|
import parsl
|
|
@@ -40,8 +42,11 @@ def test_priority_queue():
|
|
|
40
42
|
futures = {}
|
|
41
43
|
|
|
42
44
|
# Submit tasks with mixed priorities
|
|
43
|
-
#
|
|
44
|
-
|
|
45
|
+
# Test fallback behavior with a guaranteed-unsorted priorities
|
|
46
|
+
priorities = [randint(2, 9) for _ in range(randint(1, 10))]
|
|
47
|
+
priorities.insert(0, 10)
|
|
48
|
+
priorities.extend((1, 10, 1))
|
|
49
|
+
for i, priority in enumerate(priorities):
|
|
45
50
|
spec = {'priority': priority}
|
|
46
51
|
futures[(priority, i)] = fake_task(parsl_resource_specification=spec)
|
|
47
52
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import os
|
|
3
2
|
import pickle
|
|
4
3
|
from unittest import mock
|
|
@@ -10,7 +9,9 @@ from parsl.executors.high_throughput.mpi_resource_management import (
|
|
|
10
9
|
TaskScheduler,
|
|
11
10
|
)
|
|
12
11
|
from parsl.multiprocessing import SpawnContext
|
|
13
|
-
from parsl.serialize import
|
|
12
|
+
from parsl.serialize import pack_apply_message
|
|
13
|
+
|
|
14
|
+
mock_task_buffer = pack_apply_message("func", "args", "kwargs")
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
@pytest.fixture(autouse=True)
|
|
@@ -42,12 +43,8 @@ def test_MPISched_put_task():
|
|
|
42
43
|
assert len(scheduler.available_nodes) == 8
|
|
43
44
|
assert scheduler._free_node_counter.value == 8
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"kwargs",
|
|
48
|
-
resource_specification={"num_nodes": 2,
|
|
49
|
-
"ranks_per_node": 2})
|
|
50
|
-
task_package = {"task_id": 1, "buffer": mock_task_buffer}
|
|
46
|
+
res_spec = {"num_nodes": 2, "ranks_per_node": 2}
|
|
47
|
+
task_package = {"task_id": 1, "buffer": mock_task_buffer, "resource_spec": res_spec}
|
|
51
48
|
scheduler.put_task(task_package)
|
|
52
49
|
|
|
53
50
|
assert scheduler._free_node_counter.value == 6
|
|
@@ -82,21 +79,17 @@ def test_MPISched_roundtrip():
|
|
|
82
79
|
assert scheduler.available_nodes
|
|
83
80
|
assert len(scheduler.available_nodes) == 8
|
|
84
81
|
|
|
85
|
-
for
|
|
82
|
+
for trip in range(1, 9):
|
|
86
83
|
assert scheduler._free_node_counter.value == 8
|
|
87
84
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
"kwargs",
|
|
91
|
-
resource_specification={"num_nodes": round,
|
|
92
|
-
"ranks_per_node": 2})
|
|
93
|
-
task_package = {"task_id": round, "buffer": mock_task_buffer}
|
|
85
|
+
res_spec = {"num_nodes": trip, "ranks_per_node": 2}
|
|
86
|
+
task_package = {"task_id": trip, "buffer": mock_task_buffer, "resource_spec": res_spec}
|
|
94
87
|
scheduler.put_task(task_package)
|
|
95
88
|
|
|
96
|
-
assert scheduler._free_node_counter.value == 8 -
|
|
89
|
+
assert scheduler._free_node_counter.value == 8 - trip
|
|
97
90
|
|
|
98
91
|
# Pop in a mock result
|
|
99
|
-
result_pkl = pickle.dumps({"task_id":
|
|
92
|
+
result_pkl = pickle.dumps({"task_id": trip, "type": "result", "buffer": "RESULT BUF"})
|
|
100
93
|
result_q.put(result_pkl)
|
|
101
94
|
|
|
102
95
|
got_result = scheduler.get_result(True, 1)
|
|
@@ -114,27 +107,15 @@ def test_MPISched_contention():
|
|
|
114
107
|
|
|
115
108
|
assert scheduler._free_node_counter.value == 8
|
|
116
109
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"kwargs",
|
|
120
|
-
resource_specification={
|
|
121
|
-
"num_nodes": 8,
|
|
122
|
-
"ranks_per_node": 2
|
|
123
|
-
})
|
|
124
|
-
task_package = {"task_id": 1, "buffer": mock_task_buffer}
|
|
110
|
+
rspec_1 = {"num_nodes": 8, "ranks_per_node": 2}
|
|
111
|
+
task_package = {"task_id": 1, "buffer": mock_task_buffer, "resource_spec": rspec_1}
|
|
125
112
|
scheduler.put_task(task_package)
|
|
126
113
|
|
|
127
114
|
assert scheduler._free_node_counter.value == 0
|
|
128
115
|
assert scheduler._backlog_queue.empty()
|
|
129
116
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"kwargs",
|
|
133
|
-
resource_specification={
|
|
134
|
-
"num_nodes": 8,
|
|
135
|
-
"ranks_per_node": 2
|
|
136
|
-
})
|
|
137
|
-
task_package = {"task_id": 2, "buffer": mock_task_buffer}
|
|
117
|
+
rspec_2 = {"num_nodes": 8, "ranks_per_node": 2}
|
|
118
|
+
task_package = {"task_id": 2, "buffer": mock_task_buffer, "resource_spec": rspec_2}
|
|
138
119
|
scheduler.put_task(task_package)
|
|
139
120
|
|
|
140
121
|
# Second task should now be in the backlog_queue
|
|
@@ -143,8 +124,7 @@ def test_MPISched_contention():
|
|
|
143
124
|
# Confirm that the first task is available and has all 8 nodes provisioned
|
|
144
125
|
task_on_worker_side = task_q.get()
|
|
145
126
|
assert task_on_worker_side['task_id'] == 1
|
|
146
|
-
|
|
147
|
-
assert len(resource_spec['MPI_NODELIST'].split(',')) == 8
|
|
127
|
+
assert len(rspec_1["MPI_NODELIST"].split(",")) == 8
|
|
148
128
|
assert task_q.empty() # Confirm that task 2 is not yet scheduled
|
|
149
129
|
|
|
150
130
|
# Simulate worker returning result and the scheduler picking up result
|
|
@@ -159,8 +139,7 @@ def test_MPISched_contention():
|
|
|
159
139
|
# Pop in a mock result
|
|
160
140
|
task_on_worker_side = task_q.get()
|
|
161
141
|
assert task_on_worker_side['task_id'] == 2
|
|
162
|
-
|
|
163
|
-
assert len(resource_spec['MPI_NODELIST'].split(',')) == 8
|
|
142
|
+
assert len(rspec_2["MPI_NODELIST"].split(",")) == 8
|
|
164
143
|
|
|
165
144
|
|
|
166
145
|
@pytest.mark.local
|
|
@@ -178,11 +157,7 @@ def test_hashable_backlog_queue():
|
|
|
178
157
|
assert scheduler._free_node_counter.value == 8
|
|
179
158
|
|
|
180
159
|
for i in range(3):
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
"num_nodes": 8,
|
|
184
|
-
"ranks_per_node": 2
|
|
185
|
-
})
|
|
186
|
-
task_package = {"task_id": i, "buffer": mock_task_buffer}
|
|
160
|
+
res_spec = {"num_nodes": 8, "ranks_per_node": 2}
|
|
161
|
+
task_package = {"task_id": i, "buffer": mock_task_buffer, "resource_spec": res_spec}
|
|
187
162
|
scheduler.put_task(task_package)
|
|
188
163
|
assert scheduler._backlog_queue.qsize() == 2, "Expected 2 backlogged tasks"
|
parsl/version.py
CHANGED
|
@@ -23,7 +23,6 @@ from parsl.monitoring.radios.base import MonitoringRadioSender
|
|
|
23
23
|
from parsl.monitoring.radios.zmq import ZMQRadioSender
|
|
24
24
|
from parsl.process_loggers import wrap_with_logs
|
|
25
25
|
from parsl.serialize import serialize as serialize_object
|
|
26
|
-
from parsl.utils import setproctitle
|
|
27
26
|
from parsl.version import VERSION as PARSL_VERSION
|
|
28
27
|
|
|
29
28
|
PKL_HEARTBEAT_CODE = pickle.dumps((2 ** 32) - 1)
|
|
@@ -220,7 +219,7 @@ class Interchange:
|
|
|
220
219
|
|
|
221
220
|
reply: Any # the type of reply depends on the command_req received (aka this needs dependent types...)
|
|
222
221
|
|
|
223
|
-
if self.
|
|
222
|
+
if self.socks.get(self.command_channel) == zmq.POLLIN:
|
|
224
223
|
logger.debug("entering command_server section")
|
|
225
224
|
|
|
226
225
|
command_req = self.command_channel.recv_pyobj()
|
|
@@ -328,7 +327,7 @@ class Interchange:
|
|
|
328
327
|
"""Process incoming task message(s).
|
|
329
328
|
"""
|
|
330
329
|
|
|
331
|
-
if self.
|
|
330
|
+
if self.socks.get(self.task_incoming) == zmq.POLLIN:
|
|
332
331
|
logger.debug("start task_incoming section")
|
|
333
332
|
msg = self.task_incoming.recv_pyobj()
|
|
334
333
|
|
|
@@ -627,6 +626,8 @@ def start_file_logger(filename: str, level: int = logging.DEBUG, format_string:
|
|
|
627
626
|
|
|
628
627
|
|
|
629
628
|
if __name__ == "__main__":
|
|
629
|
+
from parsl.utils import setproctitle
|
|
630
|
+
|
|
630
631
|
setproctitle("parsl: HTEX interchange")
|
|
631
632
|
|
|
632
633
|
config = pickle.load(sys.stdin.buffer)
|
|
@@ -603,6 +603,10 @@ def update_resource_spec_env_vars(mpi_launcher: str, resource_spec: Dict, node_i
|
|
|
603
603
|
|
|
604
604
|
|
|
605
605
|
def _init_mpi_env(mpi_launcher: str, resource_spec: Dict):
|
|
606
|
+
for varname in resource_spec:
|
|
607
|
+
envname = "PARSL_" + str(varname).upper()
|
|
608
|
+
os.environ[envname] = str(resource_spec[varname])
|
|
609
|
+
|
|
606
610
|
node_list = resource_spec.get("MPI_NODELIST")
|
|
607
611
|
if node_list is None:
|
|
608
612
|
return
|
|
@@ -753,8 +757,8 @@ def worker(
|
|
|
753
757
|
worker_enqueued = True
|
|
754
758
|
|
|
755
759
|
try:
|
|
756
|
-
# The worker will receive {'task_id':<tid>, 'buffer':<buf>}
|
|
757
760
|
req = task_queue.get(timeout=task_queue_timeout)
|
|
761
|
+
# req is {'task_id':<tid>, 'buffer':<buf>, 'resource_spec':<dict>}
|
|
758
762
|
except queue.Empty:
|
|
759
763
|
continue
|
|
760
764
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: parsl
|
|
3
|
-
Version: 2025.9.
|
|
3
|
+
Version: 2025.9.22
|
|
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/2025.09.
|
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2025.09.22.tar.gz
|
|
7
7
|
Author: The Parsl Team
|
|
8
8
|
Author-email: parsl@googlegroups.com
|
|
9
9
|
License: Apache 2.0
|
|
@@ -8,7 +8,7 @@ parsl/multiprocessing.py,sha256=xqieTLko3DrHykCqqSHQszMwd8ORYllrgz6Qc_PsHCE,2112
|
|
|
8
8
|
parsl/process_loggers.py,sha256=uQ7Gd0W72Jz7rrcYlOMfLsAEhkRltxXJL2MgdduJjEw,1136
|
|
9
9
|
parsl/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
parsl/utils.py,sha256=smVYTusMoYUTD5N9OxTW5bh6o2iioh0NnfjrBAj8zYk,14452
|
|
11
|
-
parsl/version.py,sha256=
|
|
11
|
+
parsl/version.py,sha256=1FmTAxb_oLz19QvMrCDIghwk5d3IAI0plHgiPluzCgI,131
|
|
12
12
|
parsl/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
parsl/app/app.py,sha256=0gbM4AH2OtFOLsv07I5nglpElcwMSOi-FzdZZfrk7So,8532
|
|
14
14
|
parsl/app/bash.py,sha256=jm2AvePlCT9DZR7H_4ANDWxatp5dN_22FUlT_gWhZ-g,5528
|
|
@@ -65,31 +65,31 @@ parsl/dataflow/taskrecord.py,sha256=qIW7T6hn9dYTuNPdUura3HQwwUpUJACwPP5REm5COf4,
|
|
|
65
65
|
parsl/executors/__init__.py,sha256=PEuXYrnVqwlaz_nt82s9D_YNaVsX7ET29DeIZRUR8hw,577
|
|
66
66
|
parsl/executors/base.py,sha256=Qlc7Qa-jbfGpQcGB29JUFXCdhcSN63bjGubEcbDk270,4948
|
|
67
67
|
parsl/executors/errors.py,sha256=ZxL3nK5samPos8Xixo_jpRtPIiRJfZ5D397_qaXj2g0,2515
|
|
68
|
-
parsl/executors/execute_task.py,sha256=
|
|
68
|
+
parsl/executors/execute_task.py,sha256=Kx6V4Qe_Y2mtiKiUYAlGFseceKgzBdoXfuVsOouk2U4,892
|
|
69
69
|
parsl/executors/globus_compute.py,sha256=p59iBrv2BvYUAZ3YZSpOrm_Wpai592ueiJm3zFS7gvY,5304
|
|
70
70
|
parsl/executors/status_handling.py,sha256=aRlp0zNrkoaEQEcVoSsk6YNazzHtw0mPYy0GIaEh3qw,15744
|
|
71
71
|
parsl/executors/threads.py,sha256=lX9VuaMDBg_dqAObKfeaZlYCY4-ti33U-YMWOhWFGTY,4141
|
|
72
72
|
parsl/executors/flux/__init__.py,sha256=P9grTTeRPXfqXurFhlSS7XhmE6tTbnCnyQ1f9b-oYHE,136
|
|
73
73
|
parsl/executors/flux/execute_parsl_task.py,sha256=zHP5M7ILGiwnoalZ8WsfVVdZM7uP4iQo2ThVh4crxpM,1530
|
|
74
|
-
parsl/executors/flux/executor.py,sha256=
|
|
74
|
+
parsl/executors/flux/executor.py,sha256=UhW8R_QVYIuafrX4xOIokzl1z7p4KjFBUzser3bAxOg,16981
|
|
75
75
|
parsl/executors/flux/flux_instance_manager.py,sha256=5T3Rp7ZM-mlT0Pf0Gxgs5_YmnaPrSF9ec7zvRfLfYJw,2129
|
|
76
76
|
parsl/executors/high_throughput/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
77
|
parsl/executors/high_throughput/errors.py,sha256=k2XuvvFdUfNs2foHFnxmS-BToRMfdXpYEa4EF3ELKq4,1554
|
|
78
|
-
parsl/executors/high_throughput/executor.py,sha256=
|
|
79
|
-
parsl/executors/high_throughput/interchange.py,sha256=
|
|
78
|
+
parsl/executors/high_throughput/executor.py,sha256=fAjGPJM4_EQbIosIvNpXzKWTLqGVDNWB635l-6hkBow,40240
|
|
79
|
+
parsl/executors/high_throughput/interchange.py,sha256=PcalTRzNRVW5B5B6CVR4IoGqqrdhOSzzIcHoQawRH3A,26089
|
|
80
80
|
parsl/executors/high_throughput/manager_record.py,sha256=ZMsqFxvreGLRXAw3N-JnODDa9Qfizw2tMmcBhm4lco4,490
|
|
81
81
|
parsl/executors/high_throughput/manager_selector.py,sha256=UKcUE6v0tO7PDMTThpKSKxVpOpOUilxDL7UbNgpZCxo,2116
|
|
82
82
|
parsl/executors/high_throughput/monitoring_info.py,sha256=HC0drp6nlXQpAop5PTUKNjdXMgtZVvrBL0JzZJebPP4,298
|
|
83
83
|
parsl/executors/high_throughput/mpi_executor.py,sha256=P8n81Y9t5cw-YuNFgkrGtc4oG75ntBJDonUIfhkp_5I,5223
|
|
84
84
|
parsl/executors/high_throughput/mpi_prefix_composer.py,sha256=DmpKugANNa1bdYlqQBLHkrFc15fJpefPPhW9hkAlh1s,4308
|
|
85
|
-
parsl/executors/high_throughput/mpi_resource_management.py,sha256=
|
|
85
|
+
parsl/executors/high_throughput/mpi_resource_management.py,sha256=SeFtvvS-8asTGaukM5YW85m_8FdIGod0I5Vi0fNcXZg,7796
|
|
86
86
|
parsl/executors/high_throughput/probe.py,sha256=QlBFwSSxMmtH-Aa2JEvCzQLddsbWZluMUxq5ypLR51E,3831
|
|
87
|
-
parsl/executors/high_throughput/process_worker_pool.py,sha256=
|
|
87
|
+
parsl/executors/high_throughput/process_worker_pool.py,sha256=KLNE4kswtV0OzoHWCgg00Bs8zPtWixJGBqAbDPPfrWY,40688
|
|
88
88
|
parsl/executors/high_throughput/zmq_pipes.py,sha256=fANpmyvBetp0_b-qsI59yqBW8ank-PDNqThuQ3JeVl4,8183
|
|
89
89
|
parsl/executors/radical/__init__.py,sha256=CKbtV2numw5QvgIBq1htMUrt9TqDCIC2zifyf2svTNU,186
|
|
90
|
-
parsl/executors/radical/executor.py,sha256=
|
|
90
|
+
parsl/executors/radical/executor.py,sha256=eb7zgakpFBvGVlQ2NgxQlfjaql_mQQrYqqJJqbFxEno,22643
|
|
91
91
|
parsl/executors/radical/rpex_resources.py,sha256=Q7-0u3K447LBCe2y7mVcdw6jqWI7SdPXxCKhkr6FoRQ,5139
|
|
92
|
-
parsl/executors/radical/rpex_worker.py,sha256=
|
|
92
|
+
parsl/executors/radical/rpex_worker.py,sha256=vl807EucEH4YgKgQ-OAP1cZPDqRwKjte3WxH2CERbo8,1796
|
|
93
93
|
parsl/executors/taskvine/__init__.py,sha256=9rwp3M8B0YyEhZMLO0RHaNw7u1nc01WHbXLqnBTanu0,293
|
|
94
94
|
parsl/executors/taskvine/errors.py,sha256=euIYkSslrNSI85kyi2s0xzOaO9ik4c1fYHstMIeiBJk,652
|
|
95
95
|
parsl/executors/taskvine/exec_parsl_function.py,sha256=ftGdJU78lKPPkphSHlEi4rj164mhuMHJjghVqfgeXKk,7085
|
|
@@ -190,18 +190,18 @@ parsl/providers/slurm/template.py,sha256=KpgBEFMc1ps-38jdrk13xUGx9TCivu-iF90jgQD
|
|
|
190
190
|
parsl/providers/torque/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
191
191
|
parsl/providers/torque/template.py,sha256=4qfc2gmlEhRCAD7erFDOs4prJQ43I8s4E8DSUSVQx3A,358
|
|
192
192
|
parsl/providers/torque/torque.py,sha256=QMmhJtCfrF7HQW4rJWAZ6PaQ3WWFVWJS0QSkFH0wwdo,8918
|
|
193
|
-
parsl/serialize/__init__.py,sha256
|
|
193
|
+
parsl/serialize/__init__.py,sha256=mD67d2zn0VgOxyNR3xuPnq6Go8UZ_XPIsC1hu3qDfos,226
|
|
194
194
|
parsl/serialize/base.py,sha256=5GyJRr3PQohp5Zv9YQUEyes61mfUK7wTctTaXITYpSQ,1082
|
|
195
195
|
parsl/serialize/concretes.py,sha256=JPWmltkm-XH2S22ugXCYWYmxwukCUEXWYKzPkKXJO60,1911
|
|
196
196
|
parsl/serialize/errors.py,sha256=TmTjGI4jf8p2hH454jpp_CPbhxwPXcj5MdOMEmF6so4,1066
|
|
197
|
-
parsl/serialize/facade.py,sha256=
|
|
197
|
+
parsl/serialize/facade.py,sha256=D33Sia7rnJ2_ZdSBPsWBa0XDWVHOwqMe0DO4_sdXsoY,5596
|
|
198
198
|
parsl/serialize/proxystore.py,sha256=o-ha9QAvVhbN8y9S1itk3W0O75eyHYZw2AvB2xu5_Lg,1624
|
|
199
199
|
parsl/tests/__init__.py,sha256=VTtJzOzz_x6fWNh8IOnsgFqVbdiJShi2AZH21mcmID4,204
|
|
200
200
|
parsl/tests/callables_helper.py,sha256=ceP1YYsNtrZgKT6MAIvpgdccEjQ_CpFEOnZBGHKGOx0,30
|
|
201
201
|
parsl/tests/conftest.py,sha256=PqXpj1AxpPQrcKXJBQ83WIF8TIzZ4-YhAjKQPahE1Tw,15618
|
|
202
202
|
parsl/tests/test_callables.py,sha256=97vrIF1_hfDGd81FM1bhR6FemZMWFcALrH6pVHMTCt8,1974
|
|
203
203
|
parsl/tests/test_curvezmq.py,sha256=CmLQforq2WPYFC5OsOGh5a9ujiEFKygktZi1mpOn3XU,11239
|
|
204
|
-
parsl/tests/test_execute_task.py,sha256=
|
|
204
|
+
parsl/tests/test_execute_task.py,sha256=IzvuDLLckrRzghjvvcsUTNXFKskNsNQeKy1Bx-NWf2k,457
|
|
205
205
|
parsl/tests/test_flux.py,sha256=TxkVPjksl1usdE9Y6y2FYhdOOmYFTlbEv_V9WnvF41A,5098
|
|
206
206
|
parsl/tests/test_summary.py,sha256=x1RfWCFLzHjBw2ukwoRZPW1LFCKiwDmxx86ES-6yGRA,552
|
|
207
207
|
parsl/tests/test_thread_parallelism.py,sha256=TVNeQ1NkUhaf3YbbzUSH-ozFFdX_GbX-5ygommjVxvc,1653
|
|
@@ -320,7 +320,7 @@ parsl/tests/test_htex/test_manager_selector_by_block.py,sha256=VQqSE6MDhGpDSjShG
|
|
|
320
320
|
parsl/tests/test_htex/test_managers_command.py,sha256=SCwkfyGB-Udgu5L2yDMpR5bsaT-aNjNkiXxtuRb25DI,1622
|
|
321
321
|
parsl/tests/test_htex/test_missing_worker.py,sha256=gyp5i7_t-JHyJGtz_eXZKKBY5w8oqLOIxO6cJgGJMtQ,745
|
|
322
322
|
parsl/tests/test_htex/test_multiple_disconnected_blocks.py,sha256=2vXZoIx4NuAWYuiNoL5Gxr85w72qZ7Kdb3JGh0FufTg,1867
|
|
323
|
-
parsl/tests/test_htex/test_priority_queue.py,sha256=
|
|
323
|
+
parsl/tests/test_htex/test_priority_queue.py,sha256=sAs9W4I0LsmvPpuN9Q66yRY4zoSOEo0eMFh6DXlih0I,2336
|
|
324
324
|
parsl/tests/test_htex/test_resource_spec_validation.py,sha256=ZXW02jDd1rNxjBLh1jHyiz31zNoB9JzDw94aWllXFd4,1102
|
|
325
325
|
parsl/tests/test_htex/test_worker_failure.py,sha256=Uz-RHI-LK78FMjXUvrUFmo4iYfmpDVBUcBxxRb3UG9M,603
|
|
326
326
|
parsl/tests/test_htex/test_zmq_binding.py,sha256=SmX_63vvXKnzWISBr8HnJCrRqubx7K0blvgjq4Px2gc,4391
|
|
@@ -343,7 +343,7 @@ parsl/tests/test_mpi_apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
343
343
|
parsl/tests/test_mpi_apps/test_bad_mpi_config.py,sha256=QKvEUSrHIBrvqu2fRj1MAqxsYxDfcrdQ7dzWdOZejuU,1320
|
|
344
344
|
parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py,sha256=_fpiaDq9yEUuBxTiuxLFsBt5r1oX9S-3S-YL5yRB13E,5423
|
|
345
345
|
parsl/tests/test_mpi_apps/test_mpi_prefix.py,sha256=yJslZvYK3JeL9UgxMwF9DDPR9QD4zJLGVjubD0F-utc,1950
|
|
346
|
-
parsl/tests/test_mpi_apps/test_mpi_scheduler.py,sha256=
|
|
346
|
+
parsl/tests/test_mpi_apps/test_mpi_scheduler.py,sha256=3LEPPYzZEPCYFiqv1YJIRJwiVmZHIplu8P-czUJ6N5U,5550
|
|
347
347
|
parsl/tests/test_mpi_apps/test_mpiex.py,sha256=mlFdHK3A1B6NsEhxTQQX8lhs9qVza36FMG99vNrBRW4,2021
|
|
348
348
|
parsl/tests/test_mpi_apps/test_resource_spec.py,sha256=5k6HM2jtb6sa7jetpI-Tl1nPQiN33VLaM7YT10c307E,3756
|
|
349
349
|
parsl/tests/test_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -412,7 +412,6 @@ parsl/tests/test_serialization/test_2555_caching_deserializer.py,sha256=jEXJvbri
|
|
|
412
412
|
parsl/tests/test_serialization/test_3495_deserialize_managerlost.py,sha256=GoMtK6BmARicawzYR2eQj5jUSL9RZ_tHV3g19BdQuQ8,1144
|
|
413
413
|
parsl/tests/test_serialization/test_basic.py,sha256=4_1Rkq5tNl9EC0nfneF8kHTws7I0E6ovE_0DE97BEfU,544
|
|
414
414
|
parsl/tests/test_serialization/test_htex_code_cache.py,sha256=dd0XwlNDn6Lgj6-nHHjYWzl1FnhFLY_8Buxj77dyZ28,1840
|
|
415
|
-
parsl/tests/test_serialization/test_pack_resource_spec.py,sha256=-Vtyh8KyezZw8e7M2Z4m3LawY1Au4U-H3KRmVKXSut0,641
|
|
416
415
|
parsl/tests/test_serialization/test_proxystore_configured.py,sha256=lGWOSEWul16enDWhW-s7CK0d3eMDzm1324Fmj0cZMVU,2293
|
|
417
416
|
parsl/tests/test_serialization/test_proxystore_impl.py,sha256=uGd45sfPm9rJhzqKV0rI3lqdSOAUddQf-diEpcJAlcY,1228
|
|
418
417
|
parsl/tests/test_shutdown/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -452,13 +451,13 @@ parsl/usage_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
|
|
|
452
451
|
parsl/usage_tracking/api.py,sha256=iaCY58Dc5J4UM7_dJzEEs871P1p1HdxBMtNGyVdzc9g,1821
|
|
453
452
|
parsl/usage_tracking/levels.py,sha256=xbfzYEsd55KiZJ-mzNgPebvOH4rRHum04hROzEf41tU,291
|
|
454
453
|
parsl/usage_tracking/usage.py,sha256=hbMo5BYgIWqMcFWqN-HYP1TbwNrTonpv-usfwnCFJKY,9212
|
|
455
|
-
parsl-2025.9.
|
|
456
|
-
parsl-2025.9.
|
|
457
|
-
parsl-2025.9.
|
|
458
|
-
parsl-2025.9.
|
|
459
|
-
parsl-2025.9.
|
|
460
|
-
parsl-2025.9.
|
|
461
|
-
parsl-2025.9.
|
|
462
|
-
parsl-2025.9.
|
|
463
|
-
parsl-2025.9.
|
|
464
|
-
parsl-2025.9.
|
|
454
|
+
parsl-2025.9.22.data/scripts/exec_parsl_function.py,sha256=YXKVVIa4zXmOtz-0Ca4E_5nQfN_3S2bh2tB75uZZB4w,7774
|
|
455
|
+
parsl-2025.9.22.data/scripts/interchange.py,sha256=5hLSdQNG65v0iSx2FSeS6uyp7i3Ez2qWIzNSVblSixI,26076
|
|
456
|
+
parsl-2025.9.22.data/scripts/parsl_coprocess.py,sha256=zrVjEqQvFOHxsLufPi00xzMONagjVwLZbavPM7bbjK4,5722
|
|
457
|
+
parsl-2025.9.22.data/scripts/process_worker_pool.py,sha256=WGR9yr8EfBptQ6X-CvAPQEo1rlljD6peCc-za36-1xM,40674
|
|
458
|
+
parsl-2025.9.22.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
|
|
459
|
+
parsl-2025.9.22.dist-info/METADATA,sha256=IpHlJRMpOyOsgV7Ig9GQssk2IETO6cSZWaqEifE29c0,4055
|
|
460
|
+
parsl-2025.9.22.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
461
|
+
parsl-2025.9.22.dist-info/entry_points.txt,sha256=XqnsWDYoEcLbsMcpnYGKLEnSBmaIe1YoM5YsBdJG2tI,176
|
|
462
|
+
parsl-2025.9.22.dist-info/top_level.txt,sha256=PIheYoUFQtF2icLsgOykgU-Cjuwr2Oi6On2jo5RYgRM,6
|
|
463
|
+
parsl-2025.9.22.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import pytest
|
|
2
|
-
|
|
3
|
-
from parsl.serialize import pack_res_spec_apply_message, unpack_res_spec_apply_message
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def double(x: int, y: int = 2) -> int:
|
|
7
|
-
return x * y
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@pytest.mark.local
|
|
11
|
-
def test_pack_and_unpack():
|
|
12
|
-
args = (5,)
|
|
13
|
-
kwargs = {'y': 10}
|
|
14
|
-
resource_spec = {'num_nodes': 4}
|
|
15
|
-
packed = pack_res_spec_apply_message(double, args, kwargs, resource_specification=resource_spec)
|
|
16
|
-
|
|
17
|
-
unpacked = unpack_res_spec_apply_message(packed)
|
|
18
|
-
assert len(unpacked) == 4
|
|
19
|
-
u_fn, u_args, u_kwargs, u_res_spec = unpacked
|
|
20
|
-
assert u_fn == double
|
|
21
|
-
assert u_args == args
|
|
22
|
-
assert u_kwargs == kwargs
|
|
23
|
-
assert u_res_spec == resource_spec
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|