parsl 2024.6.17__py3-none-any.whl → 2024.7.1__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 (42) hide show
  1. parsl/app/bash.py +2 -3
  2. parsl/channels/local/local.py +7 -2
  3. parsl/configs/ASPIRE1.py +3 -1
  4. parsl/configs/Azure.py +3 -1
  5. parsl/configs/ad_hoc.py +2 -0
  6. parsl/configs/bridges.py +3 -1
  7. parsl/configs/cc_in2p3.py +2 -0
  8. parsl/configs/ec2.py +2 -0
  9. parsl/configs/expanse.py +3 -1
  10. parsl/configs/frontera.py +2 -0
  11. parsl/configs/htex_local.py +2 -0
  12. parsl/configs/illinoiscluster.py +2 -0
  13. parsl/configs/kubernetes.py +3 -1
  14. parsl/configs/local_threads.py +5 -1
  15. parsl/configs/midway.py +2 -0
  16. parsl/configs/osg.py +3 -1
  17. parsl/configs/polaris.py +3 -1
  18. parsl/configs/stampede2.py +2 -0
  19. parsl/configs/summit.py +2 -0
  20. parsl/configs/toss3_llnl.py +3 -1
  21. parsl/configs/vineex_local.py +3 -1
  22. parsl/configs/wqex_local.py +3 -1
  23. parsl/executors/high_throughput/errors.py +33 -0
  24. parsl/executors/high_throughput/executor.py +1 -0
  25. parsl/executors/high_throughput/interchange.py +1 -26
  26. parsl/executors/workqueue/executor.py +25 -5
  27. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +7 -15
  28. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +6 -11
  29. parsl/tests/test_error_handling/test_retries.py +4 -15
  30. parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
  31. parsl/tests/test_staging/test_file.py +6 -6
  32. parsl/version.py +1 -1
  33. {parsl-2024.6.17.data → parsl-2024.7.1.data}/scripts/interchange.py +1 -26
  34. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/METADATA +2 -2
  35. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/RECORD +42 -41
  36. {parsl-2024.6.17.data → parsl-2024.7.1.data}/scripts/exec_parsl_function.py +0 -0
  37. {parsl-2024.6.17.data → parsl-2024.7.1.data}/scripts/parsl_coprocess.py +0 -0
  38. {parsl-2024.6.17.data → parsl-2024.7.1.data}/scripts/process_worker_pool.py +0 -0
  39. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/LICENSE +0 -0
  40. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/WHEEL +0 -0
  41. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/entry_points.txt +0 -0
  42. {parsl-2024.6.17.dist-info → parsl-2024.7.1.dist-info}/top_level.txt +0 -0
parsl/app/bash.py CHANGED
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from functools import partial, update_wrapper
2
+ from functools import partial
3
3
  from inspect import Parameter, signature
4
4
 
5
5
  from parsl.app.app import AppBase
@@ -123,11 +123,10 @@ class BashApp(AppBase):
123
123
  if sig.parameters[s].default is not Parameter.empty:
124
124
  self.kwargs[s] = sig.parameters[s].default
125
125
 
126
- # update_wrapper allows remote_side_bash_executor to masquerade as self.func
127
126
  # partial is used to attach the first arg the "func" to the remote_side_bash_executor
128
127
  # this is done to avoid passing a function type in the args which parsl.serializer
129
128
  # doesn't support
130
- remote_fn = partial(update_wrapper(remote_side_bash_executor, self.func), self.func)
129
+ remote_fn = partial(remote_side_bash_executor, self.func)
131
130
  remote_fn.__name__ = self.func.__name__
132
131
  self.wrapped_remote_function = wrap_error(remote_fn)
133
132
 
@@ -55,6 +55,7 @@ class LocalChannel(Channel, RepresentationMixin):
55
55
  current_env.update(envs)
56
56
 
57
57
  try:
58
+ logger.debug("Creating process with command '%s'", cmd)
58
59
  proc = subprocess.Popen(
59
60
  cmd,
60
61
  stdout=subprocess.PIPE,
@@ -64,12 +65,16 @@ class LocalChannel(Channel, RepresentationMixin):
64
65
  shell=True,
65
66
  preexec_fn=os.setpgrp
66
67
  )
68
+ logger.debug("Created process with pid %s. Performing communicate", proc.pid)
67
69
  (stdout, stderr) = proc.communicate(timeout=walltime)
68
70
  retcode = proc.returncode
71
+ logger.debug("Process %s returned %s", proc.pid, proc.returncode)
69
72
 
70
- except Exception as e:
71
- logger.warning("Execution of command '{}' failed due to \n{}".format(cmd, e))
73
+ except Exception:
74
+ logger.exception(f"Execution of command failed:\n{cmd}")
72
75
  raise
76
+ else:
77
+ logger.debug("Execution of command in process %s completed normally", proc.pid)
73
78
 
74
79
  return (retcode, stdout.decode("utf-8"), stderr.decode("utf-8"))
75
80
 
parsl/configs/ASPIRE1.py CHANGED
@@ -4,6 +4,7 @@ from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import MpiRunLauncher
5
5
  from parsl.monitoring.monitoring import MonitoringHub
6
6
  from parsl.providers import PBSProProvider
7
+ from parsl.usage_tracking.levels import LEVEL_1
7
8
 
8
9
  config = Config(
9
10
  executors=[
@@ -39,5 +40,6 @@ config = Config(
39
40
  strategy='simple',
40
41
  retries=3,
41
42
  app_cache=True,
42
- checkpoint_mode='task_exit'
43
+ checkpoint_mode='task_exit',
44
+ usage_tracking=LEVEL_1,
43
45
  )
parsl/configs/Azure.py CHANGED
@@ -8,6 +8,7 @@ from parsl.data_provider.http import HTTPInTaskStaging
8
8
  from parsl.data_provider.rsync import RSyncStaging
9
9
  from parsl.executors import HighThroughputExecutor
10
10
  from parsl.providers import AzureProvider
11
+ from parsl.usage_tracking.levels import LEVEL_1
11
12
 
12
13
  vm_reference = {
13
14
  # All fields below are required
@@ -33,5 +34,6 @@ config = Config(
33
34
  FTPInTaskStaging(),
34
35
  RSyncStaging(getpass.getuser() + "@" + address_by_query())],
35
36
  )
36
- ]
37
+ ],
38
+ usage_tracking=LEVEL_1,
37
39
  )
parsl/configs/ad_hoc.py CHANGED
@@ -4,6 +4,7 @@ from parsl.channels import SSHChannel
4
4
  from parsl.config import Config
5
5
  from parsl.executors import HighThroughputExecutor
6
6
  from parsl.providers import AdHocProvider
7
+ from parsl.usage_tracking.levels import LEVEL_1
7
8
 
8
9
  user_opts: Dict[str, Dict[str, Any]]
9
10
  user_opts = {'adhoc':
@@ -33,4 +34,5 @@ config = Config(
33
34
  ],
34
35
  # AdHoc Clusters should not be setup with scaling strategy.
35
36
  strategy='none',
37
+ usage_tracking=LEVEL_1,
36
38
  )
parsl/configs/bridges.py CHANGED
@@ -3,6 +3,7 @@ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import SrunLauncher
5
5
  from parsl.providers import SlurmProvider
6
+ from parsl.usage_tracking.levels import LEVEL_1
6
7
 
7
8
  """ This config assumes that it is used to launch parsl tasks from the login nodes
8
9
  of Bridges at PSC. Each job submitted to the scheduler will request 2 nodes for 10 minutes.
@@ -34,5 +35,6 @@ config = Config(
34
35
  cmd_timeout=120,
35
36
  ),
36
37
  )
37
- ]
38
+ ],
39
+ usage_tracking=LEVEL_1,
38
40
  )
parsl/configs/cc_in2p3.py CHANGED
@@ -2,6 +2,7 @@ from parsl.channels import LocalChannel
2
2
  from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.providers import GridEngineProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -19,4 +20,5 @@ config = Config(
19
20
  ),
20
21
  )
21
22
  ],
23
+ usage_tracking=LEVEL_1,
22
24
  )
parsl/configs/ec2.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from parsl.config import Config
2
2
  from parsl.executors import HighThroughputExecutor
3
3
  from parsl.providers import AWSProvider
4
+ from parsl.usage_tracking.levels import LEVEL_1
4
5
 
5
6
  config = Config(
6
7
  executors=[
@@ -25,4 +26,5 @@ config = Config(
25
26
  ),
26
27
  )
27
28
  ],
29
+ usage_tracking=LEVEL_1,
28
30
  )
parsl/configs/expanse.py CHANGED
@@ -2,6 +2,7 @@ from parsl.config import Config
2
2
  from parsl.executors import HighThroughputExecutor
3
3
  from parsl.launchers import SrunLauncher
4
4
  from parsl.providers import SlurmProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -24,5 +25,6 @@ config = Config(
24
25
  nodes_per_block=2,
25
26
  ),
26
27
  )
27
- ]
28
+ ],
29
+ usage_tracking=LEVEL_1,
28
30
  )
parsl/configs/frontera.py CHANGED
@@ -3,6 +3,7 @@ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import SrunLauncher
5
5
  from parsl.providers import SlurmProvider
6
+ from parsl.usage_tracking.levels import LEVEL_1
6
7
 
7
8
  """ This config assumes that it is used to launch parsl tasks from the login nodes
8
9
  of Frontera at TACC. Each job submitted to the scheduler will request 2 nodes for 10 minutes.
@@ -32,4 +33,5 @@ config = Config(
32
33
  ),
33
34
  )
34
35
  ],
36
+ usage_tracking=LEVEL_1,
35
37
  )
@@ -2,6 +2,7 @@ from parsl.channels import LocalChannel
2
2
  from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.providers import LocalProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -15,4 +16,5 @@ config = Config(
15
16
  ),
16
17
  )
17
18
  ],
19
+ usage_tracking=LEVEL_1,
18
20
  )
@@ -2,6 +2,7 @@ from parsl.config import Config
2
2
  from parsl.executors import HighThroughputExecutor
3
3
  from parsl.launchers import SrunLauncher
4
4
  from parsl.providers import SlurmProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  """ This config assumes that it is used to launch parsl tasks from the login nodes
7
8
  of the Campus Cluster at UIUC. Each job submitted to the scheduler will request 2 nodes for 10 minutes.
@@ -25,4 +26,5 @@ config = Config(
25
26
  ),
26
27
  )
27
28
  ],
29
+ usage_tracking=LEVEL_1,
28
30
  )
@@ -2,6 +2,7 @@ from parsl.addresses import address_by_route
2
2
  from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.providers import KubernetesProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -36,5 +37,6 @@ config = Config(
36
37
  max_blocks=10,
37
38
  ),
38
39
  ),
39
- ]
40
+ ],
41
+ usage_tracking=LEVEL_1,
40
42
  )
@@ -1,4 +1,8 @@
1
1
  from parsl.config import Config
2
2
  from parsl.executors.threads import ThreadPoolExecutor
3
+ from parsl.usage_tracking.levels import LEVEL_1
3
4
 
4
- config = Config(executors=[ThreadPoolExecutor()])
5
+ config = Config(
6
+ executors=[ThreadPoolExecutor()],
7
+ usage_tracking=LEVEL_1,
8
+ )
parsl/configs/midway.py CHANGED
@@ -3,6 +3,7 @@ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import SrunLauncher
5
5
  from parsl.providers import SlurmProvider
6
+ from parsl.usage_tracking.levels import LEVEL_1
6
7
 
7
8
  config = Config(
8
9
  executors=[
@@ -28,4 +29,5 @@ config = Config(
28
29
  ),
29
30
  )
30
31
  ],
32
+ usage_tracking=LEVEL_1,
31
33
  )
parsl/configs/osg.py CHANGED
@@ -1,6 +1,7 @@
1
1
  from parsl.config import Config
2
2
  from parsl.executors import HighThroughputExecutor
3
3
  from parsl.providers import CondorProvider
4
+ from parsl.usage_tracking.levels import LEVEL_1
4
5
 
5
6
  config = Config(
6
7
  executors=[
@@ -26,5 +27,6 @@ python3 -m venv parsl_env; source parsl_env/bin/activate; python3 -m pip install
26
27
  worker_logdir_root='$OSG_WN_TMP',
27
28
  worker_ports=(31000, 31001)
28
29
  )
29
- ]
30
+ ],
31
+ usage_tracking=LEVEL_1,
30
32
  )
parsl/configs/polaris.py CHANGED
@@ -3,6 +3,7 @@ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import MpiExecLauncher
5
5
  from parsl.providers import PBSProProvider
6
+ from parsl.usage_tracking.levels import LEVEL_1
6
7
 
7
8
  # There are three user parameters to change for the PBSProProvider:
8
9
  # YOUR_ACCOUNT: Account to charge usage
@@ -34,5 +35,6 @@ config = Config(
34
35
  cpus_per_node=64,
35
36
  ),
36
37
  ),
37
- ]
38
+ ],
39
+ usage_tracking=LEVEL_1,
38
40
  )
@@ -4,6 +4,7 @@ from parsl.data_provider.globus import GlobusStaging
4
4
  from parsl.executors import HighThroughputExecutor
5
5
  from parsl.launchers import SrunLauncher
6
6
  from parsl.providers import SlurmProvider
7
+ from parsl.usage_tracking.levels import LEVEL_1
7
8
 
8
9
  config = Config(
9
10
  executors=[
@@ -34,4 +35,5 @@ config = Config(
34
35
  )
35
36
 
36
37
  ],
38
+ usage_tracking=LEVEL_1,
37
39
  )
parsl/configs/summit.py CHANGED
@@ -3,6 +3,7 @@ from parsl.config import Config
3
3
  from parsl.executors import HighThroughputExecutor
4
4
  from parsl.launchers import JsrunLauncher
5
5
  from parsl.providers import LSFProvider
6
+ from parsl.usage_tracking.levels import LEVEL_1
6
7
 
7
8
  config = Config(
8
9
  executors=[
@@ -26,4 +27,5 @@ config = Config(
26
27
  )
27
28
 
28
29
  ],
30
+ usage_tracking=LEVEL_1,
29
31
  )
@@ -2,6 +2,7 @@ from parsl.config import Config
2
2
  from parsl.executors import FluxExecutor
3
3
  from parsl.launchers import SrunLauncher
4
4
  from parsl.providers import SlurmProvider
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -24,5 +25,6 @@ config = Config(
24
25
  cmd_timeout=120,
25
26
  ),
26
27
  )
27
- ]
28
+ ],
29
+ usage_tracking=LEVEL_1,
28
30
  )
@@ -2,6 +2,7 @@ import uuid
2
2
 
3
3
  from parsl.config import Config
4
4
  from parsl.executors.taskvine import TaskVineExecutor, TaskVineManagerConfig
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -15,5 +16,6 @@ config = Config(
15
16
  # To disable status reporting, comment out the project_name.
16
17
  manager_config=TaskVineManagerConfig(project_name="parsl-vine-" + str(uuid.uuid4())),
17
18
  )
18
- ]
19
+ ],
20
+ usage_tracking=LEVEL_1,
19
21
  )
@@ -2,6 +2,7 @@ import uuid
2
2
 
3
3
  from parsl.config import Config
4
4
  from parsl.executors import WorkQueueExecutor
5
+ from parsl.usage_tracking.levels import LEVEL_1
5
6
 
6
7
  config = Config(
7
8
  executors=[
@@ -21,5 +22,6 @@ config = Config(
21
22
  # A shared filesystem is not needed when using Work Queue.
22
23
  shared_fs=False
23
24
  )
24
- ]
25
+ ],
26
+ usage_tracking=LEVEL_1,
25
27
  )
@@ -1,3 +1,36 @@
1
+ import time
2
+
3
+
4
+ class ManagerLost(Exception):
5
+ """
6
+ Task lost due to manager loss. Manager is considered lost when multiple heartbeats
7
+ have been missed.
8
+ """
9
+ def __init__(self, manager_id: bytes, hostname: str) -> None:
10
+ self.manager_id = manager_id
11
+ self.tstamp = time.time()
12
+ self.hostname = hostname
13
+
14
+ def __str__(self) -> str:
15
+ return (
16
+ f"Task failure due to loss of manager {self.manager_id.decode()} on"
17
+ f" host {self.hostname}"
18
+ )
19
+
20
+
21
+ class VersionMismatch(Exception):
22
+ """Manager and Interchange versions do not match"""
23
+ def __init__(self, interchange_version: str, manager_version: str):
24
+ self.interchange_version = interchange_version
25
+ self.manager_version = manager_version
26
+
27
+ def __str__(self) -> str:
28
+ return (
29
+ f"Manager version info {self.manager_version} does not match interchange"
30
+ f" version info {self.interchange_version}, causing a critical failure"
31
+ )
32
+
33
+
1
34
  class WorkerLost(Exception):
2
35
  """Exception raised when a worker is lost
3
36
  """
@@ -551,6 +551,7 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin, UsageIn
551
551
  logger.debug("Popened interchange process. Writing config object")
552
552
  stdin.write(config_pickle)
553
553
  stdin.flush()
554
+ stdin.close()
554
555
  logger.debug("Sent config object. Requesting worker ports")
555
556
  try:
556
557
  (self.worker_task_port, self.worker_result_port) = self.command_client.run("WORKER_PORTS", timeout_s=120)
@@ -17,6 +17,7 @@ import zmq
17
17
 
18
18
  from parsl import curvezmq
19
19
  from parsl.app.errors import RemoteExceptionWrapper
20
+ from parsl.executors.high_throughput.errors import ManagerLost, VersionMismatch
20
21
  from parsl.executors.high_throughput.manager_record import ManagerRecord
21
22
  from parsl.monitoring.message_type import MessageType
22
23
  from parsl.process_loggers import wrap_with_logs
@@ -31,32 +32,6 @@ LOGGER_NAME = "interchange"
31
32
  logger = logging.getLogger(LOGGER_NAME)
32
33
 
33
34
 
34
- class ManagerLost(Exception):
35
- ''' Task lost due to manager loss. Manager is considered lost when multiple heartbeats
36
- have been missed.
37
- '''
38
- def __init__(self, manager_id: bytes, hostname: str) -> None:
39
- self.manager_id = manager_id
40
- self.tstamp = time.time()
41
- self.hostname = hostname
42
-
43
- def __str__(self) -> str:
44
- return "Task failure due to loss of manager {} on host {}".format(self.manager_id.decode(), self.hostname)
45
-
46
-
47
- class VersionMismatch(Exception):
48
- ''' Manager and Interchange versions do not match
49
- '''
50
- def __init__(self, interchange_version: str, manager_version: str):
51
- self.interchange_version = interchange_version
52
- self.manager_version = manager_version
53
-
54
- def __str__(self) -> str:
55
- return "Manager version info {} does not match interchange version info {}, causing a critical failure".format(
56
- self.manager_version,
57
- self.interchange_version)
58
-
59
-
60
35
  class Interchange:
61
36
  """ Interchange is a task orchestrator for distributed systems.
62
37
 
@@ -215,6 +215,13 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
215
215
  This requires a version of Work Queue / cctools after commit
216
216
  874df524516441da531b694afc9d591e8b134b73 (release 7.5.0 is too early).
217
217
  Default is False.
218
+
219
+ scaling_cores_per_worker: int
220
+ When using Parsl scaling, this specifies the number of cores that a
221
+ worker is expected to have available for computation. Default 1. This
222
+ parameter can be ignored when using a fixed number of blocks, or when
223
+ using one task per worker (by omitting a ``cores`` resource
224
+ specifiation for each task).
218
225
  """
219
226
 
220
227
  radio_mode = "filesystem"
@@ -244,12 +251,14 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
244
251
  full_debug: bool = True,
245
252
  worker_executable: str = 'work_queue_worker',
246
253
  function_dir: Optional[str] = None,
247
- coprocess: bool = False):
254
+ coprocess: bool = False,
255
+ scaling_cores_per_worker: int = 1):
248
256
  BlockProviderExecutor.__init__(self, provider=provider,
249
257
  block_error_handler=True)
250
258
  if not _work_queue_enabled:
251
259
  raise OptionalModuleMissing(['work_queue'], "WorkQueueExecutor requires the work_queue module.")
252
260
 
261
+ self.scaling_cores_per_worker = scaling_cores_per_worker
253
262
  self.label = label
254
263
  self.task_queue = multiprocessing.Queue() # type: multiprocessing.Queue
255
264
  self.collector_queue = multiprocessing.Queue() # type: multiprocessing.Queue
@@ -469,6 +478,8 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
469
478
  # Create a Future object and have it be mapped from the task ID in the tasks dictionary
470
479
  fu = Future()
471
480
  fu.parsl_executor_task_id = executor_task_id
481
+ assert isinstance(resource_specification, dict)
482
+ fu.resource_specification = resource_specification
472
483
  logger.debug("Getting tasks_lock to set WQ-level task entry")
473
484
  with self.tasks_lock:
474
485
  logger.debug("Got tasks_lock to set WQ-level task entry")
@@ -654,20 +665,29 @@ class WorkQueueExecutor(BlockProviderExecutor, putils.RepresentationMixin):
654
665
 
655
666
  @property
656
667
  def outstanding(self) -> int:
657
- """Count the number of outstanding tasks. This is inefficiently
668
+ """Count the number of outstanding slots required. This is inefficiently
658
669
  implemented and probably could be replaced with a counter.
659
670
  """
671
+ logger.debug("Calculating outstanding task slot load")
660
672
  outstanding = 0
673
+ tasks = 0 # only for log message...
661
674
  with self.tasks_lock:
662
675
  for fut in self.tasks.values():
663
676
  if not fut.done():
664
- outstanding += 1
665
- logger.debug(f"Counted {outstanding} outstanding tasks")
677
+ # if a task does not specify a core count, Work Queue will allocate an entire
678
+ # worker node to that task. That's approximated here by saying that it uses
679
+ # scaling_cores_per_worker.
680
+ resource_spec = getattr(fut, 'resource_specification', {})
681
+ cores = resource_spec.get('cores', self.scaling_cores_per_worker)
682
+
683
+ outstanding += cores
684
+ tasks += 1
685
+ logger.debug(f"Counted {tasks} outstanding tasks with {outstanding} outstanding slots")
666
686
  return outstanding
667
687
 
668
688
  @property
669
689
  def workers_per_node(self) -> Union[int, float]:
670
- return 1
690
+ return self.scaling_cores_per_worker
671
691
 
672
692
  def scale_in(self, count: int) -> List[str]:
673
693
  """Scale in method.
@@ -1,7 +1,5 @@
1
1
  import os
2
2
 
3
- import pytest
4
-
5
3
  import parsl
6
4
  from parsl.app.app import bash_app
7
5
 
@@ -23,24 +21,18 @@ def no_checkpoint_stdout_app_ignore_args(stdout=None):
23
21
  return "echo X"
24
22
 
25
23
 
26
- def test_memo_stdout():
24
+ def test_memo_stdout(tmpd_cwd):
25
+ path_x = tmpd_cwd / "test.memo.stdout.x"
27
26
 
28
27
  # this should run and create a file named after path_x
29
- path_x = "test.memo.stdout.x"
30
- if os.path.exists(path_x):
31
- os.remove(path_x)
32
-
33
- no_checkpoint_stdout_app_ignore_args(stdout=path_x).result()
34
- assert os.path.exists(path_x)
35
-
36
- # this should be memoized, so not create benc.test.y
37
- path_y = "test.memo.stdout.y"
28
+ no_checkpoint_stdout_app_ignore_args(stdout=str(path_x)).result()
29
+ assert path_x.exists()
38
30
 
39
- if os.path.exists(path_y):
40
- os.remove(path_y)
31
+ # this should be memoized, so should not get created
32
+ path_y = tmpd_cwd / "test.memo.stdout.y"
41
33
 
42
34
  no_checkpoint_stdout_app_ignore_args(stdout=path_y).result()
43
- assert not os.path.exists(path_y)
35
+ assert not path_y.exists(), "For memoization, expected NO file written"
44
36
 
45
37
  # this should also be memoized, so not create an arbitrary name
46
38
  z_fut = no_checkpoint_stdout_app_ignore_args(stdout=parsl.AUTO_LOGNAME)
@@ -1,5 +1,4 @@
1
1
  import copy
2
- import os
3
2
  from typing import List
4
3
 
5
4
  import pytest
@@ -30,21 +29,17 @@ def no_checkpoint_stdout_app(stdout=None):
30
29
  return "echo X"
31
30
 
32
31
 
33
- def test_memo_stdout():
34
-
32
+ def test_memo_stdout(tmpd_cwd):
35
33
  assert const_list_x == const_list_x_arg
36
34
 
37
- path_x = "test.memo.stdout.x"
38
- if os.path.exists(path_x):
39
- os.remove(path_x)
35
+ path_x = tmpd_cwd / "test.memo.stdout.x"
40
36
 
41
37
  # this should run and create a file named after path_x
42
- no_checkpoint_stdout_app(stdout=path_x).result()
43
- assert os.path.exists(path_x)
38
+ no_checkpoint_stdout_app(stdout=str(path_x)).result()
39
+ path_x.unlink(missing_ok=False)
44
40
 
45
- os.remove(path_x)
46
- no_checkpoint_stdout_app(stdout=path_x).result()
47
- assert not os.path.exists(path_x)
41
+ no_checkpoint_stdout_app(stdout=str(path_x)).result()
42
+ assert not path_x.exists(), "For memoization, expected NO file written"
48
43
 
49
44
  # this should also be memoized, so not create an arbitrary name
50
45
  z_fut = no_checkpoint_stdout_app(stdout=parsl.AUTO_LOGNAME)
@@ -1,9 +1,7 @@
1
- import argparse
2
1
  import os
3
2
 
4
3
  import pytest
5
4
 
6
- import parsl
7
5
  from parsl import bash_app, python_app
8
6
  from parsl.tests.configs.local_threads import fresh_config
9
7
 
@@ -68,8 +66,6 @@ def test_fail_nowait(numtasks=10):
68
66
  assert isinstance(
69
67
  e, TypeError), "Expected a TypeError, got {}".format(e)
70
68
 
71
- print("Done")
72
-
73
69
 
74
70
  @pytest.mark.local
75
71
  def test_fail_delayed(numtasks=10):
@@ -94,19 +90,12 @@ def test_fail_delayed(numtasks=10):
94
90
  assert isinstance(
95
91
  e, TypeError), "Expected a TypeError, got {}".format(e)
96
92
 
97
- print("Done")
98
-
99
93
 
100
94
  @pytest.mark.local
101
- def test_retry():
95
+ def test_retry(tmpd_cwd):
102
96
  """Test retries via app that succeeds on the Nth retry.
103
97
  """
104
98
 
105
- fname = "retry.out"
106
- try:
107
- os.remove(fname)
108
- except OSError:
109
- pass
110
- fu = succeed_on_retry(fname)
111
-
112
- fu.result()
99
+ fpath = tmpd_cwd / "retry.out"
100
+ sout = str(tmpd_cwd / "stdout")
101
+ succeed_on_retry(str(fpath), stdout=sout).result()
@@ -0,0 +1,47 @@
1
+ import os
2
+ import signal
3
+
4
+ import pytest
5
+
6
+ import parsl
7
+ from parsl import Config, HighThroughputExecutor
8
+ from parsl.executors.high_throughput.errors import ManagerLost
9
+
10
+
11
+ @parsl.python_app
12
+ def get_manager_pgid():
13
+ import os
14
+ return os.getpgid(os.getpid())
15
+
16
+
17
+ @parsl.python_app
18
+ def lose_manager():
19
+ import os
20
+ import signal
21
+
22
+ manager_pid = os.getppid()
23
+ os.kill(manager_pid, signal.SIGSTOP)
24
+
25
+
26
+ @pytest.mark.local
27
+ def test_manager_lost_system_failure(tmpd_cwd):
28
+ hte = HighThroughputExecutor(
29
+ label="htex_local",
30
+ address="127.0.0.1",
31
+ max_workers_per_node=2,
32
+ cores_per_worker=1,
33
+ worker_logdir_root=str(tmpd_cwd),
34
+ heartbeat_period=1,
35
+ heartbeat_threshold=1,
36
+ )
37
+ c = Config(executors=[hte], strategy='simple', strategy_period=0.1)
38
+
39
+ with parsl.load(c):
40
+ manager_pgid = get_manager_pgid().result()
41
+ try:
42
+ with pytest.raises(ManagerLost):
43
+ lose_manager().result()
44
+ finally:
45
+ # Allow process to clean itself up
46
+ os.killpg(manager_pgid, signal.SIGCONT)
47
+ os.killpg(manager_pgid, signal.SIGTERM)
@@ -22,11 +22,11 @@ def test_files():
22
22
 
23
23
 
24
24
  @pytest.mark.local
25
- def test_open():
26
- with open('test-open.txt', 'w') as tfile:
27
- tfile.write('Hello')
25
+ def test_open(tmpd_cwd):
26
+ fpath = tmpd_cwd / 'test-open.txt'
27
+ fpath.write_text('Hello')
28
28
 
29
- pfile = File('test-open.txt')
29
+ pfile = File(fpath)
30
30
 
31
- with open(str(pfile), 'r') as opfile:
32
- assert (opfile.readlines()[0] == 'Hello')
31
+ with open(pfile) as opfile:
32
+ assert (opfile.read() == 'Hello')
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.06.17'
6
+ VERSION = '2024.07.01'
@@ -17,6 +17,7 @@ import zmq
17
17
 
18
18
  from parsl import curvezmq
19
19
  from parsl.app.errors import RemoteExceptionWrapper
20
+ from parsl.executors.high_throughput.errors import ManagerLost, VersionMismatch
20
21
  from parsl.executors.high_throughput.manager_record import ManagerRecord
21
22
  from parsl.monitoring.message_type import MessageType
22
23
  from parsl.process_loggers import wrap_with_logs
@@ -31,32 +32,6 @@ LOGGER_NAME = "interchange"
31
32
  logger = logging.getLogger(LOGGER_NAME)
32
33
 
33
34
 
34
- class ManagerLost(Exception):
35
- ''' Task lost due to manager loss. Manager is considered lost when multiple heartbeats
36
- have been missed.
37
- '''
38
- def __init__(self, manager_id: bytes, hostname: str) -> None:
39
- self.manager_id = manager_id
40
- self.tstamp = time.time()
41
- self.hostname = hostname
42
-
43
- def __str__(self) -> str:
44
- return "Task failure due to loss of manager {} on host {}".format(self.manager_id.decode(), self.hostname)
45
-
46
-
47
- class VersionMismatch(Exception):
48
- ''' Manager and Interchange versions do not match
49
- '''
50
- def __init__(self, interchange_version: str, manager_version: str):
51
- self.interchange_version = interchange_version
52
- self.manager_version = manager_version
53
-
54
- def __str__(self) -> str:
55
- return "Manager version info {} does not match interchange version info {}, causing a critical failure".format(
56
- self.manager_version,
57
- self.interchange_version)
58
-
59
-
60
35
  class Interchange:
61
36
  """ Interchange is a task orchestrator for distributed systems.
62
37
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: parsl
3
- Version: 2024.6.17
3
+ Version: 2024.7.1
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.06.17.tar.gz
6
+ Download-URL: https://github.com/Parsl/parsl/archive/2024.07.01.tar.gz
7
7
  Author: The Parsl Team
8
8
  Author-email: parsl@googlegroups.com
9
9
  License: Apache 2.0
@@ -8,10 +8,10 @@ parsl/multiprocessing.py,sha256=MyaEcEq-Qf860u7V98u-PZrPNdtzOZL_NW6EhIJnmfQ,1937
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=91FjQiTUY383ueAjkBAgE21My9nba6SP2a2SrbB1r1Q,11250
11
- parsl/version.py,sha256=bW2OSs-fGwn8vVUB6s290nY4Qe21tYD0iIBDkqvY198,131
11
+ parsl/version.py,sha256=rymKA_7RPC0NJoPK5DYnRc2K1WmH8LD0xsv3iQyTwDA,131
12
12
  parsl/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  parsl/app/app.py,sha256=D5Ok_gt99mlclM_QfZbquHUBkibyG4tYdUN9ijRwUnQ,8345
14
- parsl/app/bash.py,sha256=iTpWH1K5E0e60nH23bwl97zNgg5BssFIqfp-182wkjA,5656
14
+ parsl/app/bash.py,sha256=jm2AvePlCT9DZR7H_4ANDWxatp5dN_22FUlT_gWhZ-g,5528
15
15
  parsl/app/errors.py,sha256=nJmOEPglAISfD3R1UsTZH-avqiSOJgx_DkpdL9B591w,3917
16
16
  parsl/app/futures.py,sha256=XU1NwkoNVsxy3KF5y0Ihsla5hPbhhuSikZInfS7h7Uo,2910
17
17
  parsl/app/python.py,sha256=0hrz2BppVOwwNfh5hnoP70Yv56gSRkIoT-fP9XNb4v4,2331
@@ -21,7 +21,7 @@ parsl/channels/__init__.py,sha256=DNFoy_e_vhNTABHVzo4nWilvBYe9W4Na6jj4vYf9El4,37
21
21
  parsl/channels/base.py,sha256=bS43-Qv4VSxa83V6fJ54lNBL_eHCu-Ce7-aoy1C9vCc,4193
22
22
  parsl/channels/errors.py,sha256=Dp0FhtHpygn0IjX8nGurx-WrTJm9aw-Jjz3SSUT-jCc,3283
23
23
  parsl/channels/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- parsl/channels/local/local.py,sha256=YWJdsLBTG6Ri01pd_28Ha1ZkgdbrPpxCEOdRLOmnavs,4995
24
+ parsl/channels/local/local.py,sha256=xqH4HnipUN95NgvyB1r33SiqgQKkARgRKmg0_HnumUk,5311
25
25
  parsl/channels/oauth_ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
26
  parsl/channels/oauth_ssh/oauth_ssh.py,sha256=GrVOpJ6M6BwtGG4zOU4zakyphzuGY5M3suQ8PyjwyOA,3509
27
27
  parsl/channels/ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -29,27 +29,27 @@ parsl/channels/ssh/ssh.py,sha256=pwbekDM55dwQHrWwNk5wXcQUAf7cGmRahAwZQ89lxDw,950
29
29
  parsl/channels/ssh_il/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  parsl/channels/ssh_il/ssh_il.py,sha256=5XjotlA83UM4zGfnVriC9pE2NzaCT5hqvXZ9v4GG3pg,2410
31
31
  parsl/concurrent/__init__.py,sha256=TvIVceJYaJAsxedNBF3Vdo9lEQNHH_j3uxJv0zUjP7w,3288
32
- parsl/configs/ASPIRE1.py,sha256=nQ8Sa-hHyT7Pr4pC15iBcM4rEXRAq_DhpiWoH7Htkug,1637
33
- parsl/configs/Azure.py,sha256=RTwyvzGY5F5yiTCCzQYy2Hs4PZk2J0PoYeJLDnuFu_M,1191
32
+ parsl/configs/ASPIRE1.py,sha256=eKnmz0QD3V522emtXMjS6Ppeooe5lzcBgCE6cxunbYY,1718
33
+ parsl/configs/Azure.py,sha256=CJms3xWmdb-S3CksbHrPF2TfMxJC5I0faqUKCOzVg0k,1268
34
34
  parsl/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- parsl/configs/ad_hoc.py,sha256=Ju7rvpJd55x1_hnsBoKBHb6vLemFnY5O9bzcT5ZyGII,1276
36
- parsl/configs/bridges.py,sha256=4-DUwDaiSvtwyxZLnMFwudNh2UJglTDYB1ZxyojYn8E,1446
37
- parsl/configs/cc_in2p3.py,sha256=Owa6d_kw0NeLYy12UD8JHWr64xuUTEgeiSraaFFGfNg,709
38
- parsl/configs/ec2.py,sha256=JVSe3p5DpV0wjBaZJknVzUX0lhpkWOsu8SzECfaZs3Y,868
39
- parsl/configs/expanse.py,sha256=HNdJdg52xC0GycX7nz7MiumqFPpNNyPVAwZreVZISmQ,956
40
- parsl/configs/frontera.py,sha256=1aExG0qoNwYlJPCQpwH9OwEsAnO8zkMMPesunvOxXdg,1419
41
- parsl/configs/htex_local.py,sha256=z0X_rMC4A8qUS6VgFXWZ4_iPPCUT8CkSaDORK0_fSn0,466
42
- parsl/configs/illinoiscluster.py,sha256=bxQ1bcWGk2EikAvE4s4Sz5FG8QOra3RSfiB2Z8l0oDI,1093
43
- parsl/configs/kubernetes.py,sha256=3WcoG_pq9FHcLvY2IbXYX7_vaiMlCuch7buQJKod75s,1248
44
- parsl/configs/local_threads.py,sha256=RbqOr2ELWBDFwmCCbvmyd4zEJDvonQGRbs7Apc6cy9g,138
45
- parsl/configs/midway.py,sha256=zZOV512IrKJllDXgZ5DkbLD3i8djicbkt1xFgW96ETE,1145
46
- parsl/configs/osg.py,sha256=5ikeEzc70797pjWT8C7m77XHyyTJ2DFfL4Njk0hN0Rs,1143
47
- parsl/configs/polaris.py,sha256=SZ-XJmPoFQKDl4p8hc-Nr5Zt2lg-XM82Bf7URxI9ZwY,1654
48
- parsl/configs/stampede2.py,sha256=dIfatCJPUwW68o1ud09fNM3uC5brqyuHGBkbrJcDeME,1329
49
- parsl/configs/summit.py,sha256=gXiBSt5QztvqGEm89WRhkTK0P1NThXsAi9EqxqYZMM0,1077
50
- parsl/configs/toss3_llnl.py,sha256=iaUbhWkywGObbIaNLsAihP560F185rrjpVfjkM6lBDQ,997
51
- parsl/configs/vineex_local.py,sha256=IyqD-VnUefJYhz0XE1Ik0DKgCgqGHKD3NRXXfayobz8,660
52
- parsl/configs/wqex_local.py,sha256=cjqaUHL9SfL45hgl1Gg6DjhGDbFMHeuTlzVeF367FZQ,794
35
+ parsl/configs/ad_hoc.py,sha256=Gwnehd5_K6IzUSPECHnNBljyO-LQ9fyaBClHiT_myp8,1352
36
+ parsl/configs/bridges.py,sha256=NsTvCiHZHbJj-BsOXOpgS4hCblCHW_lnMa_VMb3SIww,1523
37
+ parsl/configs/cc_in2p3.py,sha256=T9PjUt2OFFv3w2uXFeKfIDmE7j_nllD3jVouvCmPrCc,785
38
+ parsl/configs/ec2.py,sha256=5xtlZI4Fc558sYXdM4nQQvQDBNPdzhRRCO14F-8H7Y4,944
39
+ parsl/configs/expanse.py,sha256=ADUY3GZWSfVKmqFWbgdfC85kRxNPChqOGwly0XdcKSw,1033
40
+ parsl/configs/frontera.py,sha256=6n0TMvF2IFdJ3g5NdFcM-rg5Na_6dDroF0ZIozk3-LU,1495
41
+ parsl/configs/htex_local.py,sha256=v6VG9UoWoosy3ls66lToTyGahZFjoLb5ni0nVWKfKNY,542
42
+ parsl/configs/illinoiscluster.py,sha256=ZR22A8uwFb8tzSzmU1D0kR0qcr5Thr0j-7Nb5hiCgQ8,1170
43
+ parsl/configs/kubernetes.py,sha256=s6ABVRwHEKsIFi-w9gc5OK-P0UDmlAZsoHc6OZ3oOD4,1325
44
+ parsl/configs/local_threads.py,sha256=I1VFfGo2TMTrBL9g_rlG3TEqEWkhL-AHpkqJ3lvcTf8,221
45
+ parsl/configs/midway.py,sha256=An2Z-TbL3b6AP3uQwauxtUqZaYO2CtUiP8XH05hpWks,1221
46
+ parsl/configs/osg.py,sha256=OVpR2Q33EL6OYGRyj-VpfpbGDhRwGAu3_rT388n1UaY,1220
47
+ parsl/configs/polaris.py,sha256=rbUdeFC-R4YGcs3cShfs66IuZEKyBx_sFrVdjje_l_g,1731
48
+ parsl/configs/stampede2.py,sha256=2FTUZ6lQ-0_b0xtpDC6ZngFBhqc_vI45dHOSwrtzl3Y,1405
49
+ parsl/configs/summit.py,sha256=wCiYDwNomgVAy79Of1_gywtEO0oajlgm9mOvUTBaGSc,1153
50
+ parsl/configs/toss3_llnl.py,sha256=73ZckKIwTSd-DkAXtqg2U6l8ObPKMAJjs5CerUpJnsQ,1074
51
+ parsl/configs/vineex_local.py,sha256=6T7A5zYOoEedRQHjRW8GAXzXLCPmSlWOfLfbJl0jZGU,737
52
+ parsl/configs/wqex_local.py,sha256=XzjAvpHFaBSRVmSkbViTizKSkLR_2XXBP_zJ69KGBCg,871
53
53
  parsl/data_provider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
54
  parsl/data_provider/data_manager.py,sha256=2pbjNbf-WXAk2PRO_uGRGpH1dma5xfSw0YZpg1SdqHg,7319
55
55
  parsl/data_provider/file_noop.py,sha256=hxg6QNaBPsdTuio8jYJRkprXX9uuneMTXNCUe0YYP-E,498
@@ -79,9 +79,9 @@ parsl/executors/flux/execute_parsl_task.py,sha256=gRN7F4HhdrKQ-bvn4wXrquBzFOp_9W
79
79
  parsl/executors/flux/executor.py,sha256=gPq49CQwtSZYZggLZ0dCXdpUlllKHJbvR8WRKeGh9xE,16977
80
80
  parsl/executors/flux/flux_instance_manager.py,sha256=2KVcphlybF-ALYD_3_YjMUi0f5LkjdoJOT_783CW4H0,2036
81
81
  parsl/executors/high_throughput/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- parsl/executors/high_throughput/errors.py,sha256=77ZGrw9suLh9tSWjyhCaIvnC9nRAOmrXsZmvHM6nT68,626
83
- parsl/executors/high_throughput/executor.py,sha256=iRmAdQpHpmC0UDC5jDZ0O-BlZe_RhfItlqL5RIiD7os,37039
84
- parsl/executors/high_throughput/interchange.py,sha256=6avQQ8Ljtmuzpa5yjClswqdVEBPDnNBeKb_yn0XbVW4,31462
82
+ parsl/executors/high_throughput/errors.py,sha256=Sak8e8UpiEcXefUjMHbhyXc4Rn7kJtOoh7L8wreBQdk,1638
83
+ parsl/executors/high_throughput/executor.py,sha256=XO0QkRdQIXYUOdabTTIJ6HIlMai0Tvu78bYHMFT-tNc,37061
84
+ parsl/executors/high_throughput/interchange.py,sha256=IRuiaBmks_R4cU-Sx0Q_Fjv4PdFtzU05GiPdeJstOoA,30578
85
85
  parsl/executors/high_throughput/manager_record.py,sha256=9XppKjDW0DJ7SMkPNxsiDs-HvXGPLrTg6Ceyh4b6gNs,433
86
86
  parsl/executors/high_throughput/monitoring_info.py,sha256=HC0drp6nlXQpAop5PTUKNjdXMgtZVvrBL0JzZJebPP4,298
87
87
  parsl/executors/high_throughput/mpi_executor.py,sha256=B2CR1pHaGQzIwTrQ-_i08NZG-NwS6yr8y7nxPaa_rkA,3760
@@ -107,7 +107,7 @@ parsl/executors/taskvine/utils.py,sha256=iSrIogeiauL3UNy_9tiZp1cBSNn6fIJkMYQRVi1
107
107
  parsl/executors/workqueue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  parsl/executors/workqueue/errors.py,sha256=XO2naYhAsHHyiOBH6hpObg3mPNDmvMoFqErsj0-v7jc,541
109
109
  parsl/executors/workqueue/exec_parsl_function.py,sha256=RUkJ4JSJAjr7YyRZ58zhMdg8cR5dVV9odUl3AuzNf3k,7802
110
- parsl/executors/workqueue/executor.py,sha256=X6mNMj-qP8uXZFJrNokIc2jJdq3tkGWdW4omtT79ATA,49272
110
+ parsl/executors/workqueue/executor.py,sha256=K5q-poZU37LVF4YhX34jKVMIBw5jpBfQ1rUadgPeQBU,50519
111
111
  parsl/executors/workqueue/parsl_coprocess.py,sha256=cF1UmTgVLoey6QzBcbYgEiEsRidSaFfuO54f1HFw_EM,5737
112
112
  parsl/executors/workqueue/parsl_coprocess_stub.py,sha256=_bJmpPIgL42qM6bVzeEKt1Mn1trSP41rtJguXxPGfHI,735
113
113
  parsl/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -301,8 +301,8 @@ parsl/tests/test_bash_apps/test_error_codes.py,sha256=jJ3BwhFpvTGKElKyuiCMWFeBaV
301
301
  parsl/tests/test_bash_apps/test_keyword_overlaps.py,sha256=8bfN2qw4uXJsYquppR1lZQrYW834AZc3zjYIIHTfDoE,209
302
302
  parsl/tests/test_bash_apps/test_kwarg_storage.py,sha256=OMMD3sKSngBSjVCHK9wju0hHzszOqbYuWtscyMuh5_8,720
303
303
  parsl/tests/test_bash_apps/test_memoize.py,sha256=gFhDNFxdRv8DNtErbwtdEvAph6SDFPaWY0tABZGS4I4,1383
304
- parsl/tests/test_bash_apps/test_memoize_ignore_args.py,sha256=ffABk6psbjGYatZiUicb-BYLmzqnxbUCNhMh0h4Ctus,1322
305
- parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py,sha256=8geUkrr09Oc4ZfPklf-sHl5WErVjlfhuQvV7KJ_cOhM,1362
304
+ parsl/tests/test_bash_apps/test_memoize_ignore_args.py,sha256=dCDvf_iVuU5aq5gLlOUwcCZTbWtNJ4Uj0Zjx1ZbBOhQ,1257
305
+ parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py,sha256=3cMYYNhSncDshWfbbyMld5z1ZrJHPpxz_0u8DMBgRdA,1341
306
306
  parsl/tests/test_bash_apps/test_multiline.py,sha256=stpMEv2eopGG-ietxjUtD5gYMOVpwPdLauDizjUfTdA,1082
307
307
  parsl/tests/test_bash_apps/test_pipeline.py,sha256=1kQDD8-Dh5H9SKFcKHzN_mSrdxAV_VYzk8ZnDyna3l8,2444
308
308
  parsl/tests/test_bash_apps/test_std_uri.py,sha256=CvAt8BUhNl2pA5chq9YyhkD6eo2IUH6PjWfe3SQ-YRU,3752
@@ -330,7 +330,7 @@ parsl/tests/test_error_handling/test_fail.py,sha256=xx4TGWfL7le4cQ9nvnUkrlmKQJks
330
330
  parsl/tests/test_error_handling/test_python_walltime.py,sha256=rdmGZHIkuann2Njt3i62odKJ0FaODGr7-L96rOXNVYg,950
331
331
  parsl/tests/test_error_handling/test_rand_fail.py,sha256=crFg4GmwdDpvx49_7w5Xt2P7H2R_V9f6i1Ar-QkASuU,3864
332
332
  parsl/tests/test_error_handling/test_resource_spec.py,sha256=bk0h2KRZ1lKga_dfhkqq4-tvUJimPtO6gJikUzXJJrU,1565
333
- parsl/tests/test_error_handling/test_retries.py,sha256=Hgy-1y9nx-unB4KE2-Em3OUvdWxoYzAWq-EY7ImEgIE,2446
333
+ parsl/tests/test_error_handling/test_retries.py,sha256=zJ9D2hrvXQURnK2OIf5LfQFcSDVZ8rhdpp6peGccY7s,2372
334
334
  parsl/tests/test_error_handling/test_retry_handler.py,sha256=8fMHffMBLhRyNreIqkrwamx9TYRZ498uVYNlkcbAoLU,1407
335
335
  parsl/tests/test_error_handling/test_retry_handler_failure.py,sha256=GaGtZZCB9Wb7ieShqTrxUFEUSKy07ZZWytCY4Qixk9Y,552
336
336
  parsl/tests/test_error_handling/test_serialization_fail.py,sha256=5nnGyaOH0Quyjo3eTKkDfAvYcNYxL8OfMi1KccyncaM,647
@@ -427,6 +427,7 @@ parsl/tests/test_scaling/test_scale_down_htex_unregistered.py,sha256=4DYZB9BMDzy
427
427
  parsl/tests/test_scaling/test_shutdown_scalein.py,sha256=Jzi0OH7UE6qvQ4ZpsfHu8lySpkMDgorn2elAzMNE6wI,2397
428
428
  parsl/tests/test_serialization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
429
429
  parsl/tests/test_serialization/test_2555_caching_deserializer.py,sha256=jEXJvbriaLVI7frV5t-iJRKYyeQ7a9_-t3X9lhhBWQo,767
430
+ parsl/tests/test_serialization/test_3495_deserialize_managerlost.py,sha256=23phMEstEWWQUHxlyZh4Ta1DC94by8f_-OYCcykyNu8,1144
430
431
  parsl/tests/test_serialization/test_basic.py,sha256=4_1Rkq5tNl9EC0nfneF8kHTws7I0E6ovE_0DE97BEfU,544
431
432
  parsl/tests/test_serialization/test_htex_code_cache.py,sha256=dd0XwlNDn6Lgj6-nHHjYWzl1FnhFLY_8Buxj77dyZ28,1840
432
433
  parsl/tests/test_serialization/test_pack_resource_spec.py,sha256=-Vtyh8KyezZw8e7M2Z4m3LawY1Au4U-H3KRmVKXSut0,641
@@ -440,7 +441,7 @@ parsl/tests/test_staging/test_1316.py,sha256=eS0e2BDM2vmPNF60aDr35wcuGgDPfXjTjRV
440
441
  parsl/tests/test_staging/test_docs_1.py,sha256=HxFoBYRNkoJoCDIok9QEIDJLICmaF3RCklSWYtG8BEQ,628
441
442
  parsl/tests/test_staging/test_docs_2.py,sha256=DrxoUVowwzdQebewfyQ6v-IHVFJfs5qGzWVQ4UVSbkA,464
442
443
  parsl/tests/test_staging/test_elaborate_noop_file.py,sha256=8FHXraFrXDBB2wsKx15AQ6vOgpWwtDL6O6PejOkfdOM,2448
443
- parsl/tests/test_staging/test_file.py,sha256=Dqen1RJ-uLfzX8xIyJN2Qw3oVy4cFkQQVh6KC72xFDA,950
444
+ parsl/tests/test_staging/test_file.py,sha256=Jsmn-4jaIuMz6ocmACMJmylx-thKky7QGWISkl4Mxjs,924
444
445
  parsl/tests/test_staging/test_file_apps.py,sha256=zTwLAf4R-lFLoqeyz9ZfFeVTs9PL9dmpKjeZEVG7C2s,1540
445
446
  parsl/tests/test_staging/test_file_staging.py,sha256=PTBZhTQJsNtUi38uUZOdIb8yw18-qxMoY9GFodzPYuE,674
446
447
  parsl/tests/test_staging/test_output_chain_filenames.py,sha256=9Mxfl9oU_x1ZSP8JSxT_t4WFCfDTprLjSeFNMm4vVxA,894
@@ -464,13 +465,13 @@ parsl/usage_tracking/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
464
465
  parsl/usage_tracking/api.py,sha256=iaCY58Dc5J4UM7_dJzEEs871P1p1HdxBMtNGyVdzc9g,1821
465
466
  parsl/usage_tracking/levels.py,sha256=xbfzYEsd55KiZJ-mzNgPebvOH4rRHum04hROzEf41tU,291
466
467
  parsl/usage_tracking/usage.py,sha256=qNEJ7nPimqd3Y7OWFLdYmNwJ6XDKlyfV_fTzasxsQw8,8690
467
- parsl-2024.6.17.data/scripts/exec_parsl_function.py,sha256=RUkJ4JSJAjr7YyRZ58zhMdg8cR5dVV9odUl3AuzNf3k,7802
468
- parsl-2024.6.17.data/scripts/interchange.py,sha256=kI1fSF30txw_eEicPSsxbycuz6Sdxiiyy2xrrk7jlZU,31449
469
- parsl-2024.6.17.data/scripts/parsl_coprocess.py,sha256=zrVjEqQvFOHxsLufPi00xzMONagjVwLZbavPM7bbjK4,5722
470
- parsl-2024.6.17.data/scripts/process_worker_pool.py,sha256=weug6_LAMbqEKQhiI6ZMg8r3e-XBDw1-L5_COEt7caM,41879
471
- parsl-2024.6.17.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
472
- parsl-2024.6.17.dist-info/METADATA,sha256=IwP3sPUnicwrXXDVoYqbCuTzXAA1am762Xpw2RuKfso,4124
473
- parsl-2024.6.17.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
474
- parsl-2024.6.17.dist-info/entry_points.txt,sha256=XqnsWDYoEcLbsMcpnYGKLEnSBmaIe1YoM5YsBdJG2tI,176
475
- parsl-2024.6.17.dist-info/top_level.txt,sha256=PIheYoUFQtF2icLsgOykgU-Cjuwr2Oi6On2jo5RYgRM,6
476
- parsl-2024.6.17.dist-info/RECORD,,
468
+ parsl-2024.7.1.data/scripts/exec_parsl_function.py,sha256=RUkJ4JSJAjr7YyRZ58zhMdg8cR5dVV9odUl3AuzNf3k,7802
469
+ parsl-2024.7.1.data/scripts/interchange.py,sha256=n0aOHLX64DEWx-OA4vWrYRVZfmaz8Rc8haNtafbgh4k,30565
470
+ parsl-2024.7.1.data/scripts/parsl_coprocess.py,sha256=zrVjEqQvFOHxsLufPi00xzMONagjVwLZbavPM7bbjK4,5722
471
+ parsl-2024.7.1.data/scripts/process_worker_pool.py,sha256=weug6_LAMbqEKQhiI6ZMg8r3e-XBDw1-L5_COEt7caM,41879
472
+ parsl-2024.7.1.dist-info/LICENSE,sha256=tAkwu8-AdEyGxGoSvJ2gVmQdcicWw3j1ZZueVV74M-E,11357
473
+ parsl-2024.7.1.dist-info/METADATA,sha256=TQ_3YOcktX94s5XnASKWQNt2X2bp6pQHIG3ocx71qTY,4123
474
+ parsl-2024.7.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
475
+ parsl-2024.7.1.dist-info/entry_points.txt,sha256=XqnsWDYoEcLbsMcpnYGKLEnSBmaIe1YoM5YsBdJG2tI,176
476
+ parsl-2024.7.1.dist-info/top_level.txt,sha256=PIheYoUFQtF2icLsgOykgU-Cjuwr2Oi6On2jo5RYgRM,6
477
+ parsl-2024.7.1.dist-info/RECORD,,