parsl 2024.4.8__tar.gz → 2024.4.22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {parsl-2024.4.8/parsl.egg-info → parsl-2024.4.22}/PKG-INFO +2 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/addresses.py +2 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/bash.py +10 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/errors.py +3 -5
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/data_manager.py +2 -1
- parsl-2024.4.22/parsl/data_provider/zip.py +104 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/dflow.py +92 -43
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/futures.py +26 -12
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/base.py +28 -9
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/executor.py +14 -19
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/process_worker_pool.py +3 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/status_handling.py +81 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/executor.py +13 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/executor.py +14 -3
- parsl-2024.4.22/parsl/jobs/job_status_poller.py +58 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/strategy.py +22 -27
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/monitoring.py +29 -23
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/radios.py +15 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/router.py +7 -6
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/local/local.py +1 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_alternate.py +2 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/taskvine_ex.py +1 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/workqueue_ex.py +1 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/conftest.py +6 -7
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_basic.py +7 -4
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_error_codes.py +0 -3
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_kwarg_storage.py +0 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize.py +0 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize_ignore_args.py +0 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +0 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_multiline.py +0 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_stdout.py +11 -6
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_task_exit.py +1 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_zmq_binding.py +1 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_basic.py +46 -21
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_fuzz_zmq.py +10 -1
- parsl-2024.4.22/parsl/tests/test_monitoring/test_stdouterr.py +137 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_context_manager.py +3 -3
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_outputs.py +0 -1
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_regression_1621.py +11 -11
- parsl-2024.4.22/parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +74 -0
- parsl-2024.4.22/parsl/tests/test_staging/test_staging_stdout.py +61 -0
- parsl-2024.4.22/parsl/tests/test_staging/test_zip_out.py +113 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/utils.py +11 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/version.py +1 -1
- {parsl-2024.4.8 → parsl-2024.4.22/parsl.egg-info}/PKG-INFO +2 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/SOURCES.txt +5 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/requires.txt +3 -2
- {parsl-2024.4.8 → parsl-2024.4.22}/requirements.txt +1 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/setup.py +1 -1
- parsl-2024.4.8/parsl/jobs/job_status_poller.py +0 -152
- {parsl-2024.4.8 → parsl-2024.4.22}/LICENSE +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/MANIFEST.in +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/README.rst +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/app.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/futures.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/app/python.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/benchmark/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/benchmark/perf.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/base.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/local/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/local/local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/oauth_ssh/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/oauth_ssh/oauth_ssh.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh/ssh.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh_il/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/channels/ssh_il/ssh_il.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/concurrent/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/config.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ASPIRE1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/Azure.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ad_hoc.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/bridges.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/cc_in2p3.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/ec2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/expanse.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/frontera.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/htex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/illinoiscluster.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/kubernetes.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/local_threads.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/midway.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/osg.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/polaris.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/stampede2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/summit.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/toss3_llnl.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/vineex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/configs/wqex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/curvezmq.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/file_noop.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/files.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/ftp.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/globus.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/http.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/rsync.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/data_provider/staging.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/memoization.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/rundirs.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/states.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/dataflow/taskrecord.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/execute_parsl_task.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/executor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/flux/flux_instance_manager.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/interchange.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/manager_record.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/monitoring_info.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/mpi_prefix_composer.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/mpi_resource_management.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/probe.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/high_throughput/zmq_pipes.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/executor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_master.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_resources.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/radical/rpex_worker.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/exec_parsl_function.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/factory.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/factory_config.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/manager.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/manager_config.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/taskvine/utils.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/threads.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/exec_parsl_function.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/parsl_coprocess.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/executors/workqueue/parsl_coprocess_stub.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/error_handlers.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/jobs/states.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/base.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/launchers/launchers.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/log_utils.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/db_manager.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/message_type.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/queries/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/queries/pandas.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/remote.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/types.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/app.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/models.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/task_plots.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/workflow_plots.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/static/parsl-logo-white.png +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/static/parsl-monitor.css +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/app.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/dag.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/error.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/layout.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/resource_usage.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/task.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/workflow.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/templates/workflows_summary.html +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/utils.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/version.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/monitoring/visualization/views.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/multiprocessing.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/process_loggers.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/ad_hoc/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/ad_hoc/ad_hoc.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/aws.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/aws/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/azure.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/azure/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/base.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cluster_provider.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/cobalt.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/cobalt/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/condor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/condor/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/googlecloud/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/googlecloud/googlecloud.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/grid_engine.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/grid_engine/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/kube.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/kubernetes/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/local/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/lsf.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/lsf/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/pbspro.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/pbspro/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/slurm.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/slurm/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/providers/torque/torque.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/py.typed +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/base.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/concretes.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/facade.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/serialize/proxystore.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/callables_helper.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ad_hoc_cluster_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/azure_single_node.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/bluewaters.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/bridges.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/cc_in2p3.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/comet.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/cooley_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ec2_single_node.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/ec2_spot.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/frontera.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_ad_hoc_cluster.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_intask_staging.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/htex_local_rsync_staging.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_adhoc.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_radical.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_radical_mpi.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_dfk_exit.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_periodic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_checkpoint_task_exit.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_ftp_in_task.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_globus.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_http_in_task.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_monitoring.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/local_threads_no_cache.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/midway.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/nscc_singapore.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/osg_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/petrelkube.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/summit.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/swan_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/theta.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/configs/user_opts.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/latency.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_apps/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_channels.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_local_channel.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_scp_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_parsl_load_default_config.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/test_python_simple.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/integration/test_stress/test_python_threads.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/htex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_basic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_log_filter.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_memory_limits.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_oauth_ssh.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_regression_220.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_udp_simple.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/manual_tests/test_worker_count.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/htex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/local_threads.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/test_scale.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/vineex_condor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/vineex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/wqex_condor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/scaling_tests/wqex_local.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/site_config_selector.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/test_provider.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/site_tests/test_site.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_affinity.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_concurrent.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_dynamic_executor.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_ec2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_launchers.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_local_adhoc.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_mpi/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/sites/test_worker_info.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_aalst_patterns.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_apptimeout.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_keyword_overlaps.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_bash_apps/test_pipeline.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_callables.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_channels/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_channels/test_large_output.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_periodic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_232.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_233.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_checkpointing/test_regression_239.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_curvezmq.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_from_slides.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_kwargs.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_tutorial_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_docs/test_workflow4.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_fail.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_python_walltime.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_rand_fail.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_resource_spec.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retries.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retry_handler.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_retry_handler_failure.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_serialization_fail.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_error_handling/test_wrap_with_logs.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_flowcontrol/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_flux.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_basic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_connected_blocks.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_cpu_affinity_explicit.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_disconnected_blocks.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_drain.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_htex.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_manager_failure.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_missing_worker.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_multiple_disconnected_blocks.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_htex/test_worker_failure.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_app_names.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_db_locks.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_incomplete_futures.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_memoization_representation.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_monitoring/test_viz_colouring.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_bad_mpi_config.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_prefix.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_mpi_scheduler.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_mpi_apps/test_resource_spec.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_local_provider.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_pbspro_template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_slurm_instantiate.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_slurm_template.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_providers/test_submiterror_deprecation.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_arg_input_types.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_basic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_dep_standard_futures.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_dependencies.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_depfail_propagation.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fail.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fibonacci_iterative.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_fibonacci_recursive.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_futures.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_garbage_collect.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_import_fail.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_join.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_lifted.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_mapred.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_4.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_ignore_args.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_memoize_joinapp.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_overview.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_pipeline.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_simple.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_timeout.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_python_apps/test_type5.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_radical/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_radical/test_mpi_funcs.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1480.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1606_wait_for_current_tasks.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_1653.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_221.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_226.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_2652.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_69a.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_854.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_97_parallelism_0.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_regression/test_98.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_block_error_handler.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_scale_down.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_scaling/test_shutdown_scalein.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_2555_caching_deserializer.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_basic.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_htex_code_cache.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_pack_resource_spec.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_proxystore_configured.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_serialization/test_proxystore_impl.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_shutdown/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_shutdown/test_kill_monitoring.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/staging_provider.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_1316.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_docs_1.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_docs_2.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_elaborate_noop_file.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file_apps.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_file_staging.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_output_chain_filenames.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_ftp.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_ftp_in_task.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_globus.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_staging/test_staging_https.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_summary.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_thread_parallelism.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/test_configs.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_threads/test_lazy_errors.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_utils/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/test_utils/test_representation_mixin.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/tests/utils.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/usage_tracking/__init__.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl/usage_tracking/usage.py +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/dependency_links.txt +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/entry_points.txt +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/parsl.egg-info/top_level.txt +0 -0
- {parsl-2024.4.8 → parsl-2024.4.22}/setup.cfg +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.4.
|
3
|
+
Version: 2024.4.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/2024.04.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2024.04.22.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|
@@ -113,7 +113,7 @@ def get_all_addresses() -> Set[str]:
|
|
113
113
|
try:
|
114
114
|
s_addresses.add(address_by_interface(interface))
|
115
115
|
except Exception:
|
116
|
-
logger.
|
116
|
+
logger.debug("Ignoring failure to fetch address from interface {}".format(interface))
|
117
117
|
|
118
118
|
resolution_functions: List[Callable[[], str]]
|
119
119
|
resolution_functions = [address_by_hostname, address_by_route, address_by_query]
|
@@ -121,7 +121,7 @@ def get_all_addresses() -> Set[str]:
|
|
121
121
|
try:
|
122
122
|
s_addresses.add(f())
|
123
123
|
except Exception:
|
124
|
-
logger.
|
124
|
+
logger.debug("Ignoring an address finder exception")
|
125
125
|
|
126
126
|
return s_addresses
|
127
127
|
|
@@ -5,6 +5,7 @@ import logging
|
|
5
5
|
|
6
6
|
from parsl.app.errors import wrap_error
|
7
7
|
from parsl.app.app import AppBase
|
8
|
+
from parsl.data_provider.files import File
|
8
9
|
from parsl.dataflow.dflow import DataFlowKernelLoader
|
9
10
|
|
10
11
|
logger = logging.getLogger(__name__)
|
@@ -54,13 +55,20 @@ def remote_side_bash_executor(func, *args, **kwargs):
|
|
54
55
|
if stdfspec is None:
|
55
56
|
return None
|
56
57
|
|
57
|
-
|
58
|
+
if isinstance(stdfspec, File):
|
59
|
+
# a File is an os.PathLike and so we can use it directly for
|
60
|
+
# the subsequent file operations
|
61
|
+
fname = stdfspec
|
62
|
+
mode = "w"
|
63
|
+
else:
|
64
|
+
fname, mode = get_std_fname_mode(fdname, stdfspec)
|
65
|
+
|
58
66
|
try:
|
59
67
|
if os.path.dirname(fname):
|
60
68
|
os.makedirs(os.path.dirname(fname), exist_ok=True)
|
61
69
|
fd = open(fname, mode)
|
62
70
|
except Exception as e:
|
63
|
-
raise pe.BadStdStreamFile(fname
|
71
|
+
raise pe.BadStdStreamFile(str(fname)) from e
|
64
72
|
return fd
|
65
73
|
|
66
74
|
std_out = open_std_fd('stdout')
|
@@ -78,16 +78,14 @@ class BadStdStreamFile(ParslError):
|
|
78
78
|
|
79
79
|
Contains:
|
80
80
|
reason(string)
|
81
|
-
exception object
|
82
81
|
"""
|
83
82
|
|
84
|
-
def __init__(self, reason: str
|
85
|
-
super().__init__(reason
|
83
|
+
def __init__(self, reason: str) -> None:
|
84
|
+
super().__init__(reason)
|
86
85
|
self._reason = reason
|
87
|
-
self._exception = exception
|
88
86
|
|
89
87
|
def __repr__(self) -> str:
|
90
|
-
return "Bad Stream File: {}
|
88
|
+
return "Bad Stream File: {}".format(self._reason)
|
91
89
|
|
92
90
|
def __str__(self) -> str:
|
93
91
|
return self.__repr__()
|
@@ -7,6 +7,7 @@ from parsl.data_provider.files import File
|
|
7
7
|
from parsl.data_provider.file_noop import NoOpFileStaging
|
8
8
|
from parsl.data_provider.ftp import FTPSeparateTaskStaging
|
9
9
|
from parsl.data_provider.http import HTTPSeparateTaskStaging
|
10
|
+
from parsl.data_provider.zip import ZipFileStaging
|
10
11
|
from parsl.data_provider.staging import Staging
|
11
12
|
|
12
13
|
if TYPE_CHECKING:
|
@@ -17,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|
17
18
|
# these will be shared between all executors that do not explicitly
|
18
19
|
# override, so should not contain executor-specific state
|
19
20
|
default_staging: List[Staging]
|
20
|
-
default_staging = [NoOpFileStaging(), FTPSeparateTaskStaging(), HTTPSeparateTaskStaging()]
|
21
|
+
default_staging = [NoOpFileStaging(), FTPSeparateTaskStaging(), HTTPSeparateTaskStaging(), ZipFileStaging()]
|
21
22
|
|
22
23
|
|
23
24
|
class DataManager:
|
@@ -0,0 +1,104 @@
|
|
1
|
+
import filelock
|
2
|
+
import logging
|
3
|
+
import os
|
4
|
+
import parsl
|
5
|
+
import zipfile
|
6
|
+
|
7
|
+
from typing import Tuple
|
8
|
+
|
9
|
+
from parsl.data_provider.staging import Staging
|
10
|
+
from parsl.data_provider.files import File
|
11
|
+
from parsl.errors import ParslError
|
12
|
+
|
13
|
+
|
14
|
+
logger = logging.getLogger(__name__)
|
15
|
+
|
16
|
+
|
17
|
+
class ZipAuthorityError(ParslError):
|
18
|
+
def __init__(self, file):
|
19
|
+
self.file = file
|
20
|
+
|
21
|
+
def __str__(self):
|
22
|
+
return f"ZipFileStaging cannot stage Files with an authority (netloc) section ({self.file.netloc}), for {self.file.url}"
|
23
|
+
|
24
|
+
|
25
|
+
class ZipFileStaging(Staging):
|
26
|
+
"""A stage-out provider for zip files.
|
27
|
+
|
28
|
+
This provider will stage out files by writing them into the specified zip
|
29
|
+
file.
|
30
|
+
|
31
|
+
The filename of both the zip file and the file contained in that zip are
|
32
|
+
specified using a zip: URL, like this:
|
33
|
+
|
34
|
+
zip:/tmp/foo/this.zip/inside/here.txt
|
35
|
+
|
36
|
+
This URL names a zip file ``/tmp/foo/this.zip`` containing a file
|
37
|
+
``inside/here.txt``.
|
38
|
+
|
39
|
+
The provider will use the Python filelock package to lock the zip file so
|
40
|
+
that it does not conflict with other instances of itself. This lock will
|
41
|
+
not protect against other modifications to the zip file.
|
42
|
+
"""
|
43
|
+
|
44
|
+
def can_stage_out(self, file: File) -> bool:
|
45
|
+
logger.debug("archive provider checking File {}".format(repr(file)))
|
46
|
+
|
47
|
+
# First check if this is the scheme we care about
|
48
|
+
if file.scheme != "zip":
|
49
|
+
return False
|
50
|
+
|
51
|
+
# This is some basic validation to check that the user isn't specifying
|
52
|
+
# an authority section and expecting it to mean something.
|
53
|
+
if file.netloc != "":
|
54
|
+
raise ZipAuthorityError(file)
|
55
|
+
|
56
|
+
# If we got this far, we can stage this file
|
57
|
+
return True
|
58
|
+
|
59
|
+
def stage_out(self, dm, executor, file, parent_fut):
|
60
|
+
assert file.scheme == 'zip'
|
61
|
+
|
62
|
+
zip_path, inside_path = zip_path_split(file.path)
|
63
|
+
|
64
|
+
working_dir = dm.dfk.executors[executor].working_dir
|
65
|
+
|
66
|
+
if working_dir:
|
67
|
+
file.local_path = os.path.join(working_dir, inside_path)
|
68
|
+
|
69
|
+
# TODO: I think its the right behaviour that a staging out provider should create the directory structure
|
70
|
+
# for the file to be placed in?
|
71
|
+
os.makedirs(os.path.dirname(file.local_path), exist_ok=True)
|
72
|
+
else:
|
73
|
+
raise RuntimeError("zip file staging requires a working_dir to be specified")
|
74
|
+
|
75
|
+
stage_out_app = _zip_stage_out_app(dm)
|
76
|
+
app_fut = stage_out_app(zip_path, inside_path, working_dir, inputs=[file], _parsl_staging_inhibit=True, parent_fut=parent_fut)
|
77
|
+
return app_fut
|
78
|
+
|
79
|
+
|
80
|
+
def _zip_stage_out(zip_file, inside_path, working_dir, parent_fut=None, inputs=[], _parsl_staging_inhibit=True):
|
81
|
+
file = inputs[0]
|
82
|
+
|
83
|
+
os.makedirs(os.path.dirname(zip_file), exist_ok=True)
|
84
|
+
|
85
|
+
with filelock.FileLock(zip_file + ".lock"):
|
86
|
+
with zipfile.ZipFile(zip_file, mode='a', compression=zipfile.ZIP_DEFLATED) as z:
|
87
|
+
z.write(file, arcname=inside_path)
|
88
|
+
|
89
|
+
os.remove(file)
|
90
|
+
|
91
|
+
|
92
|
+
def _zip_stage_out_app(dm):
|
93
|
+
return parsl.python_app(executors=['_parsl_internal'], data_flow_kernel=dm.dfk)(_zip_stage_out)
|
94
|
+
|
95
|
+
|
96
|
+
def zip_path_split(path: str) -> Tuple[str, str]:
|
97
|
+
"""Split zip: path into a zipfile name and a contained-file name.
|
98
|
+
"""
|
99
|
+
index = path.find(".zip/")
|
100
|
+
|
101
|
+
zip_path = path[:index + 4]
|
102
|
+
inside_path = path[index + 5:]
|
103
|
+
|
104
|
+
return (zip_path, inside_path)
|
@@ -177,10 +177,11 @@ class DataFlowKernel:
|
|
177
177
|
|
178
178
|
# this must be set before executors are added since add_executors calls
|
179
179
|
# job_status_poller.add_executors.
|
180
|
+
radio = self.monitoring.radio if self.monitoring else None
|
180
181
|
self.job_status_poller = JobStatusPoller(strategy=self.config.strategy,
|
181
182
|
strategy_period=self.config.strategy_period,
|
182
183
|
max_idletime=self.config.max_idletime,
|
183
|
-
|
184
|
+
monitoring=radio)
|
184
185
|
|
185
186
|
self.executors: Dict[str, ParslExecutor] = {}
|
186
187
|
|
@@ -218,14 +219,18 @@ class DataFlowKernel:
|
|
218
219
|
task_log_info = self._create_task_log_info(task_record)
|
219
220
|
self.monitoring.send(MessageType.TASK_INFO, task_log_info)
|
220
221
|
|
221
|
-
def _create_task_log_info(self, task_record):
|
222
|
+
def _create_task_log_info(self, task_record: TaskRecord) -> Dict[str, Any]:
|
222
223
|
"""
|
223
224
|
Create the dictionary that will be included in the log.
|
224
225
|
"""
|
225
226
|
info_to_monitor = ['func_name', 'memoize', 'hashsum', 'fail_count', 'fail_cost', 'status',
|
226
227
|
'id', 'time_invoked', 'try_time_launched', 'time_returned', 'try_time_returned', 'executor']
|
227
228
|
|
228
|
-
|
229
|
+
# mypy cannot verify that these task_record[k] references are valid:
|
230
|
+
# They are valid if all entries in info_to_monitor are declared in the definition of TaskRecord
|
231
|
+
# This type: ignore[literal-required] asserts that fact.
|
232
|
+
task_log_info = {"task_" + k: task_record[k] for k in info_to_monitor} # type: ignore[literal-required]
|
233
|
+
|
229
234
|
task_log_info['run_id'] = self.run_id
|
230
235
|
task_log_info['try_id'] = task_record['try_id']
|
231
236
|
task_log_info['timestamp'] = datetime.datetime.now()
|
@@ -237,20 +242,28 @@ class DataFlowKernel:
|
|
237
242
|
task_log_info['task_inputs'] = str(task_record['kwargs'].get('inputs', None))
|
238
243
|
task_log_info['task_outputs'] = str(task_record['kwargs'].get('outputs', None))
|
239
244
|
task_log_info['task_stdin'] = task_record['kwargs'].get('stdin', None)
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
245
|
+
|
246
|
+
def std_spec_to_name(name, spec):
|
247
|
+
if spec is None:
|
248
|
+
name = ""
|
249
|
+
elif isinstance(spec, File):
|
250
|
+
name = spec.url
|
251
|
+
else:
|
252
|
+
# fallthrough case is various str, os.PathLike, tuple modes that
|
253
|
+
# can be interpreted by get_std_fname_mode.
|
254
|
+
try:
|
255
|
+
name, _ = get_std_fname_mode(name, spec)
|
256
|
+
except Exception:
|
257
|
+
logger.exception(f"Could not parse {name} specification {spec} for task {task_record['id']}")
|
258
|
+
name = ""
|
259
|
+
return name
|
260
|
+
|
261
|
+
stdout_spec = task_record['kwargs'].get('stdout')
|
262
|
+
task_log_info['task_stdout'] = std_spec_to_name('stdout', stdout_spec)
|
263
|
+
|
264
|
+
stderr_spec = task_record['kwargs'].get('stderr')
|
265
|
+
task_log_info['task_stderr'] = std_spec_to_name('stderr', stderr_spec)
|
266
|
+
|
254
267
|
task_log_info['task_fail_history'] = ",".join(task_record['fail_history'])
|
255
268
|
task_log_info['task_depends'] = None
|
256
269
|
if task_record['depends'] is not None:
|
@@ -674,14 +687,6 @@ class DataFlowKernel:
|
|
674
687
|
def launch_task(self, task_record: TaskRecord) -> Future:
|
675
688
|
"""Handle the actual submission of the task to the executor layer.
|
676
689
|
|
677
|
-
If the app task has the executors attributes not set (default=='all')
|
678
|
-
the task is launched on a randomly selected executor from the
|
679
|
-
list of executors. This behavior could later be updated to support
|
680
|
-
binding to executors based on user specified criteria.
|
681
|
-
|
682
|
-
If the app task specifies a particular set of executors, it will be
|
683
|
-
targeted at those specific executors.
|
684
|
-
|
685
690
|
Args:
|
686
691
|
task_record : The task record
|
687
692
|
|
@@ -768,6 +773,10 @@ class DataFlowKernel:
|
|
768
773
|
(inputs[idx], func) = self.data_manager.optionally_stage_in(f, func, executor)
|
769
774
|
|
770
775
|
for kwarg, f in kwargs.items():
|
776
|
+
# stdout and stderr files should not be staging in (they will be staged *out*
|
777
|
+
# in _add_output_deps)
|
778
|
+
if kwarg in ['stdout', 'stderr']:
|
779
|
+
continue
|
771
780
|
(kwargs[kwarg], func) = self.data_manager.optionally_stage_in(f, func, executor)
|
772
781
|
|
773
782
|
newargs = list(args)
|
@@ -780,33 +789,56 @@ class DataFlowKernel:
|
|
780
789
|
logger.debug("Adding output dependencies")
|
781
790
|
outputs = kwargs.get('outputs', [])
|
782
791
|
app_fut._outputs = []
|
783
|
-
|
784
|
-
|
792
|
+
|
793
|
+
# Pass over all possible outputs: the outputs kwarg, stdout and stderr
|
794
|
+
# and for each of those, perform possible stage-out. This can result in:
|
795
|
+
# a DataFuture to be exposed in app_fut to represent the completion of
|
796
|
+
# that stageout (sometimes backed by a new sub-workflow for separate-task
|
797
|
+
# stageout), a replacement for the function to be executed (intended to
|
798
|
+
# be the original function wrapped with an in-task stageout wrapper), a
|
799
|
+
# rewritten File object to be passed to task to be executed
|
800
|
+
|
801
|
+
@typechecked
|
802
|
+
def stageout_one_file(file: File, rewritable_func: Callable):
|
803
|
+
if not self.check_staging_inhibited(kwargs):
|
785
804
|
# replace a File with a DataFuture - either completing when the stageout
|
786
805
|
# future completes, or if no stage out future is returned, then when the
|
787
806
|
# app itself completes.
|
788
807
|
|
789
808
|
# The staging code will get a clean copy which it is allowed to mutate,
|
790
809
|
# while the DataFuture-contained original will not be modified by any staging.
|
791
|
-
f_copy =
|
792
|
-
outputs[idx] = f_copy
|
810
|
+
f_copy = file.cleancopy()
|
793
811
|
|
794
|
-
logger.debug("Submitting stage out for output file {}".format(repr(
|
812
|
+
logger.debug("Submitting stage out for output file {}".format(repr(file)))
|
795
813
|
stageout_fut = self.data_manager.stage_out(f_copy, executor, app_fut)
|
796
814
|
if stageout_fut:
|
797
|
-
logger.debug("Adding a dependency on stageout future for {}".format(repr(
|
798
|
-
|
815
|
+
logger.debug("Adding a dependency on stageout future for {}".format(repr(file)))
|
816
|
+
df = DataFuture(stageout_fut, file, tid=app_fut.tid)
|
799
817
|
else:
|
800
|
-
logger.debug("No stageout dependency for {}".format(repr(
|
801
|
-
|
818
|
+
logger.debug("No stageout dependency for {}".format(repr(file)))
|
819
|
+
df = DataFuture(app_fut, file, tid=app_fut.tid)
|
802
820
|
|
803
821
|
# this is a hook for post-task stageout
|
804
822
|
# note that nothing depends on the output - which is maybe a bug
|
805
823
|
# in the not-very-tested stageout system?
|
806
|
-
|
824
|
+
rewritable_func = self.data_manager.replace_task_stage_out(f_copy, rewritable_func, executor)
|
825
|
+
return rewritable_func, f_copy, df
|
807
826
|
else:
|
808
|
-
logger.debug("Not performing output staging for: {}".format(repr(
|
809
|
-
|
827
|
+
logger.debug("Not performing output staging for: {}".format(repr(file)))
|
828
|
+
return rewritable_func, file, DataFuture(app_fut, file, tid=app_fut.tid)
|
829
|
+
|
830
|
+
for idx, file in enumerate(outputs):
|
831
|
+
func, outputs[idx], o = stageout_one_file(file, func)
|
832
|
+
app_fut._outputs.append(o)
|
833
|
+
|
834
|
+
file = kwargs.get('stdout')
|
835
|
+
if isinstance(file, File):
|
836
|
+
func, kwargs['stdout'], app_fut._stdout_future = stageout_one_file(file, func)
|
837
|
+
|
838
|
+
file = kwargs.get('stderr')
|
839
|
+
if isinstance(file, File):
|
840
|
+
func, kwargs['stderr'], app_fut._stderr_future = stageout_one_file(file, func)
|
841
|
+
|
810
842
|
return func
|
811
843
|
|
812
844
|
def _gather_all_deps(self, args: Sequence[Any], kwargs: Dict[str, Any]) -> List[Future]:
|
@@ -1132,6 +1164,8 @@ class DataFlowKernel:
|
|
1132
1164
|
executor.run_dir = self.run_dir
|
1133
1165
|
executor.hub_address = self.hub_address
|
1134
1166
|
executor.hub_port = self.hub_zmq_port
|
1167
|
+
if self.monitoring:
|
1168
|
+
executor.monitoring_radio = self.monitoring.radio
|
1135
1169
|
if hasattr(executor, 'provider'):
|
1136
1170
|
if hasattr(executor.provider, 'script_dir'):
|
1137
1171
|
executor.provider.script_dir = os.path.join(self.run_dir, 'submit_scripts')
|
@@ -1235,8 +1269,7 @@ class DataFlowKernel:
|
|
1235
1269
|
'tasks_completed_count': self.task_state_counts[States.exec_done],
|
1236
1270
|
"time_began": self.time_began,
|
1237
1271
|
'time_completed': self.time_completed,
|
1238
|
-
'run_id': self.run_id, 'rundir': self.run_dir
|
1239
|
-
'exit_now': True})
|
1272
|
+
'run_id': self.run_id, 'rundir': self.run_dir})
|
1240
1273
|
|
1241
1274
|
logger.info("Terminating monitoring")
|
1242
1275
|
self.monitoring.close()
|
@@ -1386,10 +1419,26 @@ class DataFlowKernel:
|
|
1386
1419
|
|
1387
1420
|
@staticmethod
|
1388
1421
|
def _log_std_streams(task_record: TaskRecord) -> None:
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1422
|
+
tid = task_record['id']
|
1423
|
+
|
1424
|
+
def log_std_stream(name: str, target) -> None:
|
1425
|
+
if target is None:
|
1426
|
+
logger.info(f"{name} for task {tid} will not be redirected.")
|
1427
|
+
elif isinstance(target, str):
|
1428
|
+
logger.info(f"{name} for task {tid} will be redirected to {target}")
|
1429
|
+
elif isinstance(target, os.PathLike):
|
1430
|
+
logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target)}")
|
1431
|
+
elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], str):
|
1432
|
+
logger.info(f"{name} for task {tid} will be redirected to {target[0]} with mode {target[1]}")
|
1433
|
+
elif isinstance(target, tuple) and len(target) == 2 and isinstance(target[0], os.PathLike):
|
1434
|
+
logger.info(f"{name} for task {tid} will be redirected to {os.fspath(target[0])} with mode {target[1]}")
|
1435
|
+
elif isinstance(target, DataFuture):
|
1436
|
+
logger.info(f"{name} for task {tid} will staged to {target.file_obj.url}")
|
1437
|
+
else:
|
1438
|
+
logger.error(f"{name} for task {tid} has unknown specification: {target!r}")
|
1439
|
+
|
1440
|
+
log_std_stream("Standard out", task_record['app_fu'].stdout)
|
1441
|
+
log_std_stream("Standard error", task_record['app_fu'].stderr)
|
1393
1442
|
|
1394
1443
|
|
1395
1444
|
class DataFlowKernelLoader:
|
@@ -1,16 +1,9 @@
|
|
1
|
-
"""This module implements the AppFutures.
|
2
|
-
|
3
|
-
We have two basic types of futures:
|
4
|
-
1. DataFutures which represent data objects
|
5
|
-
2. AppFutures which represent the futures on App/Leaf tasks.
|
6
|
-
|
7
|
-
"""
|
8
1
|
from __future__ import annotations
|
9
2
|
|
10
3
|
from concurrent.futures import Future
|
11
4
|
import logging
|
12
5
|
import threading
|
13
|
-
from typing import Any, Optional, Sequence
|
6
|
+
from typing import Any, Optional, Sequence, Union
|
14
7
|
|
15
8
|
import parsl.app.app as app
|
16
9
|
|
@@ -77,13 +70,34 @@ class AppFuture(Future):
|
|
77
70
|
self._outputs = []
|
78
71
|
self.task_record = task_record
|
79
72
|
|
73
|
+
self._stdout_future: Optional[DataFuture] = None
|
74
|
+
self._stderr_future: Optional[DataFuture] = None
|
75
|
+
|
80
76
|
@property
|
81
|
-
def stdout(self) ->
|
82
|
-
|
77
|
+
def stdout(self) -> Union[None, str, DataFuture]:
|
78
|
+
"""Return app stdout. If stdout was specified as a string, then this
|
79
|
+
property will return that string. If stdout was specified as a File,
|
80
|
+
then this property will return a DataFuture representing that file
|
81
|
+
stageout.
|
82
|
+
TODO: this can be a tuple too I think?"""
|
83
|
+
if self._stdout_future:
|
84
|
+
return self._stdout_future
|
85
|
+
else:
|
86
|
+
# this covers the str and None cases
|
87
|
+
return self.task_record['kwargs'].get('stdout')
|
83
88
|
|
84
89
|
@property
|
85
|
-
def stderr(self) ->
|
86
|
-
|
90
|
+
def stderr(self) -> Union[None, str, DataFuture]:
|
91
|
+
"""Return app stderr. If stdout was specified as a string, then this
|
92
|
+
property will return that string. If stdout was specified as a File,
|
93
|
+
then this property will return a DataFuture representing that file
|
94
|
+
stageout.
|
95
|
+
TODO: this can be a tuple too I think?"""
|
96
|
+
if self._stderr_future:
|
97
|
+
return self._stderr_future
|
98
|
+
else:
|
99
|
+
# this covers the str and None cases
|
100
|
+
return self.task_record['kwargs'].get('stderr')
|
87
101
|
|
88
102
|
@property
|
89
103
|
def tid(self) -> int:
|
@@ -1,9 +1,10 @@
|
|
1
|
+
import os
|
1
2
|
from abc import ABCMeta, abstractmethod
|
2
3
|
from concurrent.futures import Future
|
3
|
-
from typing import Any, Callable, Dict, Optional
|
4
|
+
from typing import Any, Callable, Dict, Optional
|
4
5
|
from typing_extensions import Literal, Self
|
5
6
|
|
6
|
-
from parsl.
|
7
|
+
from parsl.monitoring.radios import MonitoringRadio
|
7
8
|
|
8
9
|
|
9
10
|
class ParslExecutor(metaclass=ABCMeta):
|
@@ -45,6 +46,21 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
45
46
|
label: str = "undefined"
|
46
47
|
radio_mode: str = "udp"
|
47
48
|
|
49
|
+
def __init__(
|
50
|
+
self,
|
51
|
+
*,
|
52
|
+
hub_address: Optional[str] = None,
|
53
|
+
hub_port: Optional[int] = None,
|
54
|
+
monitoring_radio: Optional[MonitoringRadio] = None,
|
55
|
+
run_dir: str = ".",
|
56
|
+
run_id: Optional[str] = None,
|
57
|
+
):
|
58
|
+
self.hub_address = hub_address
|
59
|
+
self.hub_port = hub_port
|
60
|
+
self.monitoring_radio = monitoring_radio
|
61
|
+
self.run_dir = os.path.abspath(run_dir)
|
62
|
+
self.run_id = run_id
|
63
|
+
|
48
64
|
def __enter__(self) -> Self:
|
49
65
|
return self
|
50
66
|
|
@@ -79,13 +95,6 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
79
95
|
"""
|
80
96
|
pass
|
81
97
|
|
82
|
-
def create_monitoring_info(self, status: Dict[str, JobStatus]) -> List[object]:
|
83
|
-
"""Create a monitoring message for each block based on the poll status.
|
84
|
-
|
85
|
-
:return: a list of dictionaries mapping to the info of each block
|
86
|
-
"""
|
87
|
-
return []
|
88
|
-
|
89
98
|
def monitor_resources(self) -> bool:
|
90
99
|
"""Should resource monitoring happen for tasks on running on this executor?
|
91
100
|
|
@@ -135,3 +144,13 @@ class ParslExecutor(metaclass=ABCMeta):
|
|
135
144
|
@hub_port.setter
|
136
145
|
def hub_port(self, value: Optional[int]) -> None:
|
137
146
|
self._hub_port = value
|
147
|
+
|
148
|
+
@property
|
149
|
+
def monitoring_radio(self) -> Optional[MonitoringRadio]:
|
150
|
+
"""Local radio for sending monitoring messages
|
151
|
+
"""
|
152
|
+
return self._monitoring_radio
|
153
|
+
|
154
|
+
@monitoring_radio.setter
|
155
|
+
def monitoring_radio(self, value: Optional[MonitoringRadio]) -> None:
|
156
|
+
self._monitoring_radio = value
|
@@ -5,7 +5,6 @@ import typeguard
|
|
5
5
|
import logging
|
6
6
|
import threading
|
7
7
|
import queue
|
8
|
-
import datetime
|
9
8
|
import pickle
|
10
9
|
from dataclasses import dataclass
|
11
10
|
from multiprocessing import Process, Queue
|
@@ -18,7 +17,7 @@ import parsl.launchers
|
|
18
17
|
from parsl.serialize import pack_res_spec_apply_message, deserialize
|
19
18
|
from parsl.serialize.errors import SerializationError, DeserializationError
|
20
19
|
from parsl.app.errors import RemoteExceptionWrapper
|
21
|
-
from parsl.jobs.states import JobStatus, JobState
|
20
|
+
from parsl.jobs.states import JobStatus, JobState, TERMINAL_STATES
|
22
21
|
from parsl.executors.high_throughput import zmq_pipes
|
23
22
|
from parsl.executors.high_throughput import interchange
|
24
23
|
from parsl.executors.errors import (
|
@@ -677,22 +676,6 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
677
676
|
# Return the future
|
678
677
|
return fut
|
679
678
|
|
680
|
-
def create_monitoring_info(self, status):
|
681
|
-
""" Create a msg for monitoring based on the poll status
|
682
|
-
|
683
|
-
"""
|
684
|
-
msg = []
|
685
|
-
for bid, s in status.items():
|
686
|
-
d = {}
|
687
|
-
d['run_id'] = self.run_id
|
688
|
-
d['status'] = s.status_name
|
689
|
-
d['timestamp'] = datetime.datetime.now()
|
690
|
-
d['executor_label'] = self.label
|
691
|
-
d['job_id'] = self.blocks_to_job_id.get(bid, None)
|
692
|
-
d['block_id'] = bid
|
693
|
-
msg.append(d)
|
694
|
-
return msg
|
695
|
-
|
696
679
|
@property
|
697
680
|
def workers_per_node(self) -> Union[int, float]:
|
698
681
|
return self._workers_per_node
|
@@ -730,8 +713,20 @@ class HighThroughputExecutor(BlockProviderExecutor, RepresentationMixin):
|
|
730
713
|
tasks: int # sum of tasks in this block
|
731
714
|
idle: float # shortest idle time of any manager in this block
|
732
715
|
|
716
|
+
# block_info will be populated from two sources:
|
717
|
+
# the Job Status Poller mutable block list, and the list of blocks
|
718
|
+
# which have connected to the interchange.
|
719
|
+
|
720
|
+
def new_block_info():
|
721
|
+
return BlockInfo(tasks=0, idle=float('inf'))
|
722
|
+
|
723
|
+
block_info: Dict[str, BlockInfo] = defaultdict(new_block_info)
|
724
|
+
|
725
|
+
for block_id, job_status in self._status.items():
|
726
|
+
if job_status.state not in TERMINAL_STATES:
|
727
|
+
block_info[block_id] = new_block_info()
|
728
|
+
|
733
729
|
managers = self.connected_managers()
|
734
|
-
block_info: Dict[str, BlockInfo] = defaultdict(lambda: BlockInfo(tasks=0, idle=float('inf')))
|
735
730
|
for manager in managers:
|
736
731
|
if not manager['active']:
|
737
732
|
continue
|
@@ -361,7 +361,9 @@ class Manager:
|
|
361
361
|
kill_event.set()
|
362
362
|
else:
|
363
363
|
task_recv_counter += len(tasks)
|
364
|
-
logger.debug("Got executor tasks: {}, cumulative count of tasks: {}".format(
|
364
|
+
logger.debug("Got executor tasks: {}, cumulative count of tasks: {}".format(
|
365
|
+
[t['task_id'] for t in tasks], task_recv_counter
|
366
|
+
))
|
365
367
|
|
366
368
|
for task in tasks:
|
367
369
|
self.task_scheduler.put_task(task)
|