parsl 2024.5.20__py3-none-any.whl → 2024.6.3__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 (291) hide show
  1. parsl/__init__.py +9 -10
  2. parsl/addresses.py +6 -4
  3. parsl/app/app.py +3 -6
  4. parsl/app/bash.py +4 -4
  5. parsl/app/errors.py +5 -3
  6. parsl/app/futures.py +3 -3
  7. parsl/app/python.py +2 -1
  8. parsl/benchmark/perf.py +2 -1
  9. parsl/channels/__init__.py +2 -2
  10. parsl/channels/base.py +0 -1
  11. parsl/channels/errors.py +2 -1
  12. parsl/channels/oauth_ssh/oauth_ssh.py +4 -3
  13. parsl/channels/ssh/ssh.py +9 -1
  14. parsl/channels/ssh_il/ssh_il.py +1 -0
  15. parsl/concurrent/__init__.py +2 -2
  16. parsl/config.py +12 -6
  17. parsl/configs/ASPIRE1.py +3 -3
  18. parsl/configs/Azure.py +6 -7
  19. parsl/configs/ad_hoc.py +4 -3
  20. parsl/configs/bridges.py +3 -3
  21. parsl/configs/cc_in2p3.py +2 -2
  22. parsl/configs/ec2.py +1 -1
  23. parsl/configs/expanse.py +1 -2
  24. parsl/configs/frontera.py +2 -3
  25. parsl/configs/htex_local.py +1 -2
  26. parsl/configs/illinoiscluster.py +1 -1
  27. parsl/configs/kubernetes.py +1 -2
  28. parsl/configs/midway.py +3 -3
  29. parsl/configs/osg.py +1 -1
  30. parsl/configs/polaris.py +1 -1
  31. parsl/configs/stampede2.py +4 -5
  32. parsl/configs/summit.py +1 -3
  33. parsl/configs/toss3_llnl.py +1 -2
  34. parsl/configs/vineex_local.py +3 -3
  35. parsl/configs/wqex_local.py +2 -2
  36. parsl/data_provider/data_manager.py +3 -3
  37. parsl/data_provider/file_noop.py +1 -2
  38. parsl/data_provider/files.py +3 -3
  39. parsl/data_provider/ftp.py +1 -3
  40. parsl/data_provider/globus.py +7 -6
  41. parsl/data_provider/http.py +2 -2
  42. parsl/data_provider/rsync.py +1 -1
  43. parsl/data_provider/staging.py +2 -2
  44. parsl/data_provider/zip.py +4 -5
  45. parsl/dataflow/dependency_resolvers.py +115 -0
  46. parsl/dataflow/dflow.py +65 -54
  47. parsl/dataflow/errors.py +2 -1
  48. parsl/dataflow/futures.py +1 -2
  49. parsl/dataflow/memoization.py +5 -5
  50. parsl/dataflow/rundirs.py +1 -1
  51. parsl/dataflow/taskrecord.py +4 -5
  52. parsl/executors/__init__.py +3 -3
  53. parsl/executors/base.py +1 -0
  54. parsl/executors/flux/execute_parsl_task.py +2 -2
  55. parsl/executors/flux/executor.py +11 -12
  56. parsl/executors/flux/flux_instance_manager.py +3 -3
  57. parsl/executors/high_throughput/errors.py +10 -0
  58. parsl/executors/high_throughput/executor.py +31 -36
  59. parsl/executors/high_throughput/interchange.py +16 -18
  60. parsl/executors/high_throughput/manager_record.py +1 -0
  61. parsl/executors/high_throughput/monitoring_info.py +2 -1
  62. parsl/executors/high_throughput/mpi_executor.py +6 -3
  63. parsl/executors/high_throughput/mpi_prefix_composer.py +19 -3
  64. parsl/executors/high_throughput/mpi_resource_management.py +1 -2
  65. parsl/executors/high_throughput/probe.py +6 -4
  66. parsl/executors/high_throughput/process_worker_pool.py +31 -20
  67. parsl/executors/high_throughput/zmq_pipes.py +63 -15
  68. parsl/executors/radical/executor.py +15 -15
  69. parsl/executors/radical/rpex_master.py +1 -2
  70. parsl/executors/radical/rpex_resources.py +4 -9
  71. parsl/executors/radical/rpex_worker.py +2 -1
  72. parsl/executors/status_handling.py +5 -4
  73. parsl/executors/taskvine/__init__.py +1 -1
  74. parsl/executors/taskvine/errors.py +1 -1
  75. parsl/executors/taskvine/exec_parsl_function.py +2 -2
  76. parsl/executors/taskvine/executor.py +23 -24
  77. parsl/executors/taskvine/factory.py +1 -1
  78. parsl/executors/taskvine/manager.py +11 -13
  79. parsl/executors/threads.py +4 -5
  80. parsl/executors/workqueue/errors.py +1 -1
  81. parsl/executors/workqueue/exec_parsl_function.py +5 -4
  82. parsl/executors/workqueue/executor.py +26 -27
  83. parsl/executors/workqueue/parsl_coprocess.py +1 -1
  84. parsl/jobs/error_handlers.py +1 -1
  85. parsl/jobs/job_status_poller.py +2 -5
  86. parsl/jobs/states.py +1 -1
  87. parsl/jobs/strategy.py +2 -2
  88. parsl/launchers/__init__.py +12 -3
  89. parsl/launchers/errors.py +1 -1
  90. parsl/log_utils.py +1 -2
  91. parsl/monitoring/db_manager.py +16 -10
  92. parsl/monitoring/monitoring.py +11 -15
  93. parsl/monitoring/queries/pandas.py +1 -2
  94. parsl/monitoring/radios.py +2 -4
  95. parsl/monitoring/remote.py +13 -8
  96. parsl/monitoring/router.py +8 -11
  97. parsl/monitoring/types.py +2 -0
  98. parsl/monitoring/visualization/app.py +4 -2
  99. parsl/monitoring/visualization/models.py +0 -1
  100. parsl/monitoring/visualization/plots/default/workflow_plots.py +8 -4
  101. parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
  102. parsl/monitoring/visualization/utils.py +0 -1
  103. parsl/monitoring/visualization/views.py +16 -9
  104. parsl/multiprocessing.py +0 -1
  105. parsl/process_loggers.py +1 -2
  106. parsl/providers/__init__.py +9 -12
  107. parsl/providers/ad_hoc/ad_hoc.py +1 -1
  108. parsl/providers/aws/aws.py +2 -3
  109. parsl/providers/azure/azure.py +4 -5
  110. parsl/providers/base.py +1 -1
  111. parsl/providers/cluster_provider.py +1 -1
  112. parsl/providers/cobalt/cobalt.py +3 -3
  113. parsl/providers/condor/condor.py +4 -2
  114. parsl/providers/errors.py +2 -2
  115. parsl/providers/googlecloud/googlecloud.py +2 -1
  116. parsl/providers/grid_engine/grid_engine.py +2 -2
  117. parsl/providers/kubernetes/kube.py +5 -3
  118. parsl/providers/local/local.py +5 -1
  119. parsl/providers/lsf/lsf.py +2 -2
  120. parsl/providers/pbspro/pbspro.py +1 -1
  121. parsl/providers/slurm/slurm.py +5 -5
  122. parsl/providers/torque/torque.py +1 -1
  123. parsl/serialize/__init__.py +8 -3
  124. parsl/serialize/base.py +1 -2
  125. parsl/serialize/concretes.py +5 -4
  126. parsl/serialize/proxystore.py +3 -2
  127. parsl/tests/__init__.py +1 -1
  128. parsl/tests/configs/ad_hoc_cluster_htex.py +4 -4
  129. parsl/tests/configs/azure_single_node.py +4 -5
  130. parsl/tests/configs/bridges.py +3 -2
  131. parsl/tests/configs/cc_in2p3.py +2 -2
  132. parsl/tests/configs/comet.py +2 -1
  133. parsl/tests/configs/ec2_single_node.py +1 -2
  134. parsl/tests/configs/ec2_spot.py +1 -2
  135. parsl/tests/configs/frontera.py +3 -2
  136. parsl/tests/configs/htex_ad_hoc_cluster.py +2 -4
  137. parsl/tests/configs/htex_local.py +2 -3
  138. parsl/tests/configs/htex_local_alternate.py +8 -11
  139. parsl/tests/configs/htex_local_intask_staging.py +5 -7
  140. parsl/tests/configs/htex_local_rsync_staging.py +4 -6
  141. parsl/tests/configs/local_adhoc.py +1 -1
  142. parsl/tests/configs/local_radical.py +1 -3
  143. parsl/tests/configs/local_radical_mpi.py +2 -2
  144. parsl/tests/configs/midway.py +2 -2
  145. parsl/tests/configs/nscc_singapore.py +3 -3
  146. parsl/tests/configs/osg_htex.py +1 -1
  147. parsl/tests/configs/petrelkube.py +3 -2
  148. parsl/tests/configs/summit.py +1 -0
  149. parsl/tests/configs/swan_htex.py +2 -2
  150. parsl/tests/configs/taskvine_ex.py +3 -5
  151. parsl/tests/configs/theta.py +2 -2
  152. parsl/tests/configs/workqueue_ex.py +3 -4
  153. parsl/tests/conftest.py +6 -6
  154. parsl/tests/integration/test_channels/test_ssh_errors.py +1 -1
  155. parsl/tests/integration/test_stress/test_python_simple.py +3 -4
  156. parsl/tests/integration/test_stress/test_python_threads.py +3 -5
  157. parsl/tests/manual_tests/htex_local.py +4 -4
  158. parsl/tests/manual_tests/test_ad_hoc_htex.py +2 -1
  159. parsl/tests/manual_tests/test_basic.py +1 -0
  160. parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +4 -4
  161. parsl/tests/manual_tests/test_log_filter.py +3 -1
  162. parsl/tests/manual_tests/test_memory_limits.py +6 -6
  163. parsl/tests/manual_tests/test_regression_220.py +2 -1
  164. parsl/tests/manual_tests/test_udp_simple.py +4 -3
  165. parsl/tests/manual_tests/test_worker_count.py +3 -2
  166. parsl/tests/scaling_tests/htex_local.py +2 -2
  167. parsl/tests/scaling_tests/test_scale.py +0 -9
  168. parsl/tests/scaling_tests/vineex_condor.py +1 -2
  169. parsl/tests/scaling_tests/vineex_local.py +1 -2
  170. parsl/tests/site_tests/test_provider.py +3 -1
  171. parsl/tests/site_tests/test_site.py +2 -0
  172. parsl/tests/sites/test_affinity.py +7 -5
  173. parsl/tests/sites/test_dynamic_executor.py +3 -4
  174. parsl/tests/sites/test_ec2.py +3 -2
  175. parsl/tests/sites/test_local_adhoc.py +2 -1
  176. parsl/tests/sites/test_worker_info.py +4 -3
  177. parsl/tests/test_aalst_patterns.py +0 -1
  178. parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
  179. parsl/tests/test_bash_apps/test_error_codes.py +1 -4
  180. parsl/tests/test_bash_apps/test_memoize_ignore_args.py +1 -0
  181. parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +2 -2
  182. parsl/tests/test_bash_apps/test_pipeline.py +1 -1
  183. parsl/tests/test_bash_apps/test_std_uri.py +4 -9
  184. parsl/tests/test_callables.py +2 -2
  185. parsl/tests/test_checkpointing/test_periodic.py +2 -7
  186. parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
  187. parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
  188. parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
  189. parsl/tests/test_checkpointing/test_regression_239.py +1 -1
  190. parsl/tests/test_checkpointing/test_task_exit.py +1 -2
  191. parsl/tests/test_docs/test_from_slides.py +2 -2
  192. parsl/tests/test_docs/test_kwargs.py +1 -1
  193. parsl/tests/test_docs/test_tutorial_1.py +1 -2
  194. parsl/tests/test_docs/test_workflow1.py +2 -2
  195. parsl/tests/test_docs/test_workflow2.py +0 -1
  196. parsl/tests/test_error_handling/test_rand_fail.py +2 -2
  197. parsl/tests/test_error_handling/test_resource_spec.py +4 -2
  198. parsl/tests/test_error_handling/test_retries.py +2 -1
  199. parsl/tests/test_error_handling/test_retry_handler.py +1 -0
  200. parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
  201. parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
  202. parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
  203. parsl/tests/test_flux.py +1 -1
  204. parsl/tests/test_htex/test_basic.py +0 -1
  205. parsl/tests/test_htex/test_command_client_timeout.py +66 -0
  206. parsl/tests/test_htex/test_connected_blocks.py +3 -2
  207. parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
  208. parsl/tests/test_htex/test_disconnected_blocks.py +6 -4
  209. parsl/tests/test_htex/test_drain.py +5 -5
  210. parsl/tests/test_htex/test_htex.py +1 -2
  211. parsl/tests/test_htex/test_manager_failure.py +0 -1
  212. parsl/tests/test_htex/test_managers_command.py +5 -9
  213. parsl/tests/test_htex/test_missing_worker.py +2 -8
  214. parsl/tests/test_htex/test_multiple_disconnected_blocks.py +6 -4
  215. parsl/tests/test_monitoring/test_app_names.py +3 -3
  216. parsl/tests/test_monitoring/test_basic.py +4 -6
  217. parsl/tests/test_monitoring/test_db_locks.py +6 -4
  218. parsl/tests/test_monitoring/test_fuzz_zmq.py +6 -4
  219. parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +5 -7
  220. parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
  221. parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
  222. parsl/tests/test_monitoring/test_stdouterr.py +4 -6
  223. parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
  224. parsl/tests/test_mpi_apps/test_bad_mpi_config.py +1 -1
  225. parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +4 -7
  226. parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +15 -4
  227. parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
  228. parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
  229. parsl/tests/test_mpi_apps/test_mpiex.py +4 -3
  230. parsl/tests/test_mpi_apps/test_resource_spec.py +21 -17
  231. parsl/tests/test_providers/test_cobalt_deprecation_warning.py +2 -0
  232. parsl/tests/test_providers/test_local_provider.py +2 -1
  233. parsl/tests/test_providers/test_pbspro_template.py +1 -1
  234. parsl/tests/test_providers/test_slurm_template.py +1 -1
  235. parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
  236. parsl/tests/test_python_apps/test_context_manager.py +5 -12
  237. parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
  238. parsl/tests/test_python_apps/test_futures.py +2 -1
  239. parsl/tests/test_python_apps/test_join.py +0 -1
  240. parsl/tests/test_python_apps/test_lifted.py +11 -7
  241. parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
  242. parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
  243. parsl/tests/test_radical/test_mpi_funcs.py +1 -1
  244. parsl/tests/test_regression/test_1480.py +2 -1
  245. parsl/tests/test_regression/test_1653.py +2 -1
  246. parsl/tests/test_regression/test_2652.py +1 -0
  247. parsl/tests/test_regression/test_69a.py +0 -1
  248. parsl/tests/test_regression/test_854.py +4 -2
  249. parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
  250. parsl/tests/test_regression/test_98.py +0 -1
  251. parsl/tests/test_scaling/test_block_error_handler.py +9 -4
  252. parsl/tests/test_scaling/test_regression_1621.py +0 -2
  253. parsl/tests/test_scaling/test_scale_down.py +2 -3
  254. parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +4 -5
  255. parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +3 -4
  256. parsl/tests/test_scaling/test_shutdown_scalein.py +1 -4
  257. parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
  258. parsl/tests/test_serialization/test_basic.py +2 -1
  259. parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
  260. parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
  261. parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
  262. parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
  263. parsl/tests/test_shutdown/test_kill_monitoring.py +3 -4
  264. parsl/tests/test_staging/staging_provider.py +2 -2
  265. parsl/tests/test_staging/test_1316.py +3 -4
  266. parsl/tests/test_staging/test_docs_1.py +1 -1
  267. parsl/tests/test_staging/test_docs_2.py +2 -1
  268. parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
  269. parsl/tests/test_staging/test_staging_https.py +2 -2
  270. parsl/tests/test_staging/test_staging_stdout.py +4 -3
  271. parsl/tests/test_staging/test_zip_in.py +6 -8
  272. parsl/tests/test_staging/test_zip_out.py +7 -9
  273. parsl/tests/test_staging/test_zip_to_zip.py +6 -8
  274. parsl/tests/test_summary.py +2 -2
  275. parsl/tests/test_thread_parallelism.py +0 -1
  276. parsl/tests/test_threads/test_configs.py +1 -2
  277. parsl/tests/test_threads/test_lazy_errors.py +2 -2
  278. parsl/usage_tracking/api.py +2 -3
  279. parsl/usage_tracking/usage.py +8 -18
  280. parsl/utils.py +13 -2
  281. parsl/version.py +1 -1
  282. {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/exec_parsl_function.py +5 -4
  283. {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/process_worker_pool.py +31 -20
  284. {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/METADATA +6 -6
  285. parsl-2024.6.3.dist-info/RECORD +471 -0
  286. parsl-2024.5.20.dist-info/RECORD +0 -468
  287. {parsl-2024.5.20.data → parsl-2024.6.3.data}/scripts/parsl_coprocess.py +1 -1
  288. {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/LICENSE +0 -0
  289. {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/WHEEL +0 -0
  290. {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/entry_points.txt +0 -0
  291. {parsl-2024.5.20.dist-info → parsl-2024.6.3.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,7 @@ import pytest
2
2
 
3
3
  from parsl import Config
4
4
  from parsl.executors import HighThroughputExecutor
5
- from parsl.launchers import SrunLauncher, AprunLauncher, SimpleLauncher
5
+ from parsl.launchers import AprunLauncher, SimpleLauncher, SrunLauncher
6
6
  from parsl.providers import SlurmProvider
7
7
 
8
8
 
@@ -1,5 +1,7 @@
1
1
  from typing import Dict
2
+
2
3
  import pytest
4
+
3
5
  import parsl
4
6
  from parsl import python_app
5
7
  from parsl.tests.configs.htex_local import fresh_config
@@ -7,17 +9,12 @@ from parsl.tests.configs.htex_local import fresh_config
7
9
  EXECUTOR_LABEL = "MPI_TEST"
8
10
 
9
11
 
10
- def local_setup():
12
+ def local_config():
11
13
  config = fresh_config()
12
14
  config.executors[0].label = EXECUTOR_LABEL
13
15
  config.executors[0].max_workers_per_node = 1
14
16
  config.executors[0].enable_mpi_mode = False
15
- parsl.load(config)
16
-
17
-
18
- def local_teardown():
19
- parsl.dfk().cleanup()
20
- parsl.clear()
17
+ return config
21
18
 
22
19
 
23
20
  @python_app
@@ -1,13 +1,17 @@
1
1
  import logging
2
+ import os
2
3
  import random
3
4
  from typing import Dict
5
+
4
6
  import pytest
7
+
5
8
  import parsl
6
- from parsl import python_app, bash_app
9
+ from parsl import bash_app, python_app
10
+ from parsl.executors.high_throughput.mpi_prefix_composer import (
11
+ MissingResourceSpecification,
12
+ )
7
13
  from parsl.tests.configs.htex_local import fresh_config
8
14
 
9
- import os
10
-
11
15
  EXECUTOR_LABEL = "MPI_TEST"
12
16
 
13
17
 
@@ -28,7 +32,6 @@ def local_setup():
28
32
 
29
33
  def local_teardown():
30
34
  parsl.dfk().cleanup()
31
- parsl.clear()
32
35
 
33
36
 
34
37
  @python_app
@@ -169,3 +172,11 @@ def test_simulated_load(rounds: int = 100):
169
172
  total_ranks, nodes = future.result(timeout=10)
170
173
  assert len(nodes) == futures[future]["num_nodes"]
171
174
  assert total_ranks == futures[future]["num_nodes"] * futures[future]["ranks_per_node"]
175
+
176
+
177
+ @pytest.mark.local
178
+ def test_missing_resource_spec():
179
+
180
+ with pytest.raises(MissingResourceSpecification):
181
+ future = mock_app(sleep_dur=0.4)
182
+ future.result(timeout=10)
@@ -1,14 +1,14 @@
1
1
  import logging
2
+
2
3
  import pytest
3
4
 
4
- from parsl.executors.high_throughput.mpi_resource_management import Scheduler
5
5
  from parsl.executors.high_throughput.mpi_prefix_composer import (
6
- compose_srun_launch_cmd,
6
+ compose_all,
7
7
  compose_aprun_launch_cmd,
8
8
  compose_mpiexec_launch_cmd,
9
- compose_all,
9
+ compose_srun_launch_cmd,
10
10
  )
11
-
11
+ from parsl.executors.high_throughput.mpi_resource_management import Scheduler
12
12
 
13
13
  resource_spec = {"num_nodes": 2,
14
14
  "num_ranks": 8,
@@ -1,9 +1,14 @@
1
1
  import logging
2
2
  import os
3
+ import pickle
3
4
  from unittest import mock
5
+
4
6
  import pytest
5
- import pickle
6
- from parsl.executors.high_throughput.mpi_resource_management import TaskScheduler, MPITaskScheduler
7
+
8
+ from parsl.executors.high_throughput.mpi_resource_management import (
9
+ MPITaskScheduler,
10
+ TaskScheduler,
11
+ )
7
12
  from parsl.multiprocessing import SpawnContext
8
13
  from parsl.serialize import pack_res_spec_apply_message, unpack_res_spec_apply_message
9
14
 
@@ -5,11 +5,12 @@ from pathlib import Path
5
5
  import pytest
6
6
 
7
7
  import parsl
8
- from .test_mpi_mode_enabled import get_env_vars
9
- from parsl import HighThroughputExecutor, Config
8
+ from parsl import Config, HighThroughputExecutor
9
+ from parsl.executors.high_throughput.mpi_executor import MPIExecutor
10
10
  from parsl.launchers import SimpleLauncher
11
11
  from parsl.providers import LocalProvider
12
- from parsl.executors.high_throughput.mpi_executor import MPIExecutor
12
+
13
+ from .test_mpi_mode_enabled import get_env_vars
13
14
 
14
15
  cwd = Path(__file__).parent.absolute()
15
16
  pbs_nodefile = cwd.joinpath("mocks", "pbs_nodefile")
@@ -2,25 +2,25 @@ import contextlib
2
2
  import logging
3
3
  import os
4
4
  import typing
5
-
5
+ import unittest
6
+ from typing import Dict
6
7
 
7
8
  import pytest
8
- import unittest
9
9
 
10
10
  import parsl
11
11
  from parsl.app.app import python_app
12
- from parsl.tests.configs.htex_local import fresh_config
13
- from typing import Dict
12
+ from parsl.executors.high_throughput.mpi_prefix_composer import (
13
+ InvalidResourceSpecification,
14
+ MissingResourceSpecification,
15
+ validate_resource_spec,
16
+ )
14
17
  from parsl.executors.high_throughput.mpi_resource_management import (
18
+ get_nodes_in_batchjob,
15
19
  get_pbs_hosts_list,
16
20
  get_slurm_hosts_list,
17
- get_nodes_in_batchjob,
18
21
  identify_scheduler,
19
22
  )
20
- from parsl.executors.high_throughput.mpi_prefix_composer import (
21
- validate_resource_spec,
22
- InvalidResourceSpecification
23
- )
23
+ from parsl.tests.configs.htex_local import fresh_config
24
24
 
25
25
  EXECUTOR_LABEL = "MPI_TEST"
26
26
 
@@ -122,18 +122,22 @@ def test_top_level():
122
122
 
123
123
  @pytest.mark.local
124
124
  @pytest.mark.parametrize(
125
- "resource_spec, exception",
125
+ "resource_spec, is_mpi_enabled, exception",
126
126
  (
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),
127
+ ({"num_nodes": 2, "ranks_per_node": 1}, False, None),
128
+ ({"launcher_options": "--debug_foo"}, False, None),
129
+ ({"num_nodes": 2, "BAD_OPT": 1}, False, InvalidResourceSpecification),
130
+ ({}, False, None),
131
+ ({"num_nodes": 2, "ranks_per_node": 1}, True, None),
132
+ ({"launcher_options": "--debug_foo"}, True, None),
133
+ ({"num_nodes": 2, "BAD_OPT": 1}, True, InvalidResourceSpecification),
134
+ ({}, True, MissingResourceSpecification),
131
135
  )
132
136
  )
133
- def test_resource_spec(resource_spec: Dict, exception):
137
+ def test_resource_spec(resource_spec: Dict, is_mpi_enabled: bool, exception):
134
138
  if exception:
135
139
  with pytest.raises(exception):
136
- validate_resource_spec(resource_spec)
140
+ validate_resource_spec(resource_spec, is_mpi_enabled)
137
141
  else:
138
- result = validate_resource_spec(resource_spec)
142
+ result = validate_resource_spec(resource_spec, is_mpi_enabled)
139
143
  assert result is None
@@ -1,5 +1,7 @@
1
1
  import warnings
2
+
2
3
  import pytest
4
+
3
5
  from parsl.providers import CobaltProvider
4
6
 
5
7
 
@@ -1,7 +1,6 @@
1
1
  import logging
2
2
  import os
3
3
  import pathlib
4
- import pytest
5
4
  import random
6
5
  import shutil
7
6
  import socket
@@ -10,6 +9,8 @@ import tempfile
10
9
  import threading
11
10
  import time
12
11
 
12
+ import pytest
13
+
13
14
  from parsl.channels import LocalChannel, SSHChannel
14
15
  from parsl.jobs.states import JobState
15
16
  from parsl.launchers import SingleNodeLauncher
@@ -1,6 +1,6 @@
1
1
  import random
2
-
3
2
  from unittest import mock
3
+
4
4
  import pytest
5
5
 
6
6
  from parsl.channels import LocalChannel
@@ -1,7 +1,7 @@
1
1
  import logging
2
2
  import random
3
-
4
3
  from unittest import mock
4
+
5
5
  import pytest
6
6
 
7
7
  from parsl.channels import LocalChannel
@@ -1,7 +1,8 @@
1
- import pytest
2
1
  import random
3
2
  import string
4
3
 
4
+ import pytest
5
+
5
6
  from parsl.providers.errors import SubmitException
6
7
 
7
8
 
@@ -1,8 +1,9 @@
1
- import parsl
2
- from parsl.tests.configs.local_threads import fresh_config
3
1
  import pytest
4
- from parsl.errors import NoDataFlowKernelError
2
+
3
+ import parsl
5
4
  from parsl.dataflow.dflow import DataFlowKernel
5
+ from parsl.errors import NoDataFlowKernelError
6
+ from parsl.tests.configs.local_threads import fresh_config
6
7
 
7
8
 
8
9
  @parsl.python_app
@@ -15,14 +16,6 @@ def foo(x, stdout='foo.stdout'):
15
16
  return f"echo {x + 1}"
16
17
 
17
18
 
18
- def local_setup():
19
- pass
20
-
21
-
22
- def local_teardown():
23
- parsl.clear()
24
-
25
-
26
19
  @pytest.mark.local
27
20
  def test_within_context_manger(tmpd_cwd):
28
21
  config = fresh_config()
@@ -37,4 +30,4 @@ def test_within_context_manger(tmpd_cwd):
37
30
 
38
31
  with pytest.raises(NoDataFlowKernelError) as excinfo:
39
32
  square(2).result()
40
- assert str(excinfo.value) == "Cannot submit to a DFK that has been cleaned up"
33
+ assert str(excinfo.value) == "Must first load config"
@@ -1,6 +1,7 @@
1
+ from concurrent.futures import Future
2
+
1
3
  import parsl
2
4
  from parsl.dataflow.errors import DependencyError
3
- from concurrent.futures import Future
4
5
 
5
6
 
6
7
  @parsl.python_app
@@ -11,9 +11,10 @@ Same applies to datafutures, and we need to know the behavior wrt.
11
11
  2. done() called on 1, vs 2
12
12
 
13
13
  """
14
- import pytest
15
14
  from os.path import basename
16
15
 
16
+ import pytest
17
+
17
18
  from parsl.app.app import python_app
18
19
  from parsl.data_provider.files import File
19
20
 
@@ -3,7 +3,6 @@ import pytest
3
3
  from parsl import join_app, python_app
4
4
  from parsl.dataflow.errors import JoinError
5
5
 
6
-
7
6
  RESULT_CONSTANT = 3
8
7
 
9
8
 
@@ -1,26 +1,30 @@
1
+ from concurrent.futures import Future
2
+ from typing import TypeVar
3
+
1
4
  import pytest
2
5
 
3
- from concurrent.futures import Future
4
6
  from parsl import python_app
5
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
 
@@ -1,4 +1,5 @@
1
1
  import pytest
2
+
2
3
  from parsl import python_app
3
4
  from parsl.dataflow.memoization import id_for_memo
4
5
 
@@ -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.dependency_resolvers import DEEP_DEPENDENCY_RESOLVER
11
+ from parsl.dataflow.errors import DependencyError
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
@@ -1,6 +1,6 @@
1
- import parsl
2
1
  import pytest
3
2
 
3
+ import parsl
4
4
  from parsl.tests.configs.local_radical_mpi import fresh_config as local_config
5
5
 
6
6
 
@@ -1,5 +1,6 @@
1
- from parsl import python_app
2
1
  import pytest
2
+
3
+ from parsl import python_app
3
4
  from parsl.tests.configs.htex_local import fresh_config as local_config
4
5
 
5
6
 
@@ -1,5 +1,6 @@
1
- from parsl import python_app
2
1
  import pytest
2
+
3
+ from parsl import python_app
3
4
  from parsl.tests.configs.htex_local import fresh_config as local_config
4
5
 
5
6
 
@@ -1,4 +1,5 @@
1
1
  import pytest
2
+
2
3
  from parsl.jobs.states import JobState
3
4
 
4
5
 
@@ -6,7 +6,6 @@ import pytest
6
6
  from parsl.app.app import bash_app, python_app
7
7
  from parsl.tests.configs.local_threads import config
8
8
 
9
-
10
9
  local_config = config
11
10
 
12
11
 
@@ -1,8 +1,10 @@
1
- import time
2
1
  import multiprocessing
2
+ import random
3
+ import time
4
+
3
5
  import pytest
6
+
4
7
  from parsl.multiprocessing import MacSafeQueue
5
- import random
6
8
 
7
9
 
8
10
  def consumer(in_q, out_q, delay=0):
@@ -1,11 +1,10 @@
1
1
  import pytest
2
2
 
3
3
  import parsl
4
-
5
4
  from parsl.config import Config
6
5
  from parsl.executors import HighThroughputExecutor
7
- from parsl.providers import LocalProvider
8
6
  from parsl.launchers import SimpleLauncher
7
+ from parsl.providers import LocalProvider
9
8
 
10
9
 
11
10
  def local_config() -> Config:
@@ -6,7 +6,6 @@ import argparse
6
6
  import pytest
7
7
 
8
8
  import parsl
9
-
10
9
  from parsl.dataflow.dflow import DataFlowKernel
11
10
  from parsl.tests.configs.local_threads import config
12
11
 
@@ -1,11 +1,16 @@
1
+ from functools import partial
2
+ from unittest.mock import Mock
3
+
1
4
  import pytest
2
5
 
3
6
  from parsl.executors import HighThroughputExecutor
7
+ from parsl.jobs.error_handlers import (
8
+ noop_error_handler,
9
+ simple_error_handler,
10
+ windowed_error_handler,
11
+ )
12
+ from parsl.jobs.states import JobState, JobStatus
4
13
  from parsl.providers import LocalProvider
5
- from unittest.mock import Mock
6
- from parsl.jobs.states import JobStatus, JobState
7
- from parsl.jobs.error_handlers import simple_error_handler, windowed_error_handler, noop_error_handler
8
- from functools import partial
9
14
 
10
15
 
11
16
  @pytest.mark.local
@@ -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
@@ -4,13 +4,12 @@ import time
4
4
  import pytest
5
5
 
6
6
  import parsl
7
-
8
7
  from parsl import File, python_app
9
- from parsl.providers import LocalProvider
10
8
  from parsl.channels import LocalChannel
11
- from parsl.launchers import SingleNodeLauncher
12
9
  from parsl.config import Config
13
10
  from parsl.executors import HighThroughputExecutor
11
+ from parsl.launchers import SingleNodeLauncher
12
+ from parsl.providers import LocalProvider
14
13
 
15
14
  logger = logging.getLogger(__name__)
16
15