parsl 2024.3.18__py3-none-any.whl → 2025.1.13__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.
- parsl/__init__.py +9 -10
- parsl/addresses.py +26 -6
- parsl/app/app.py +7 -8
- parsl/app/bash.py +15 -8
- parsl/app/errors.py +10 -13
- parsl/app/futures.py +8 -10
- parsl/app/python.py +2 -1
- parsl/benchmark/perf.py +2 -1
- parsl/concurrent/__init__.py +2 -2
- parsl/config.py +53 -10
- parsl/configs/ASPIRE1.py +6 -5
- parsl/configs/Azure.py +9 -8
- parsl/configs/bridges.py +6 -4
- parsl/configs/cc_in2p3.py +3 -3
- parsl/configs/ec2.py +3 -1
- parsl/configs/expanse.py +4 -3
- parsl/configs/frontera.py +3 -4
- parsl/configs/htex_local.py +3 -4
- parsl/configs/illinoiscluster.py +3 -1
- parsl/configs/improv.py +34 -0
- parsl/configs/kubernetes.py +4 -3
- parsl/configs/local_threads.py +5 -1
- parsl/configs/midway.py +5 -3
- parsl/configs/osg.py +4 -2
- parsl/configs/polaris.py +4 -2
- parsl/configs/stampede2.py +6 -5
- parsl/configs/summit.py +3 -3
- parsl/configs/toss3_llnl.py +4 -3
- parsl/configs/vineex_local.py +6 -4
- parsl/configs/wqex_local.py +5 -3
- parsl/curvezmq.py +4 -0
- parsl/data_provider/data_manager.py +4 -3
- parsl/data_provider/file_noop.py +1 -2
- parsl/data_provider/files.py +3 -3
- parsl/data_provider/ftp.py +1 -3
- parsl/data_provider/globus.py +7 -6
- parsl/data_provider/http.py +2 -2
- parsl/data_provider/rsync.py +1 -1
- parsl/data_provider/staging.py +2 -2
- parsl/data_provider/zip.py +135 -0
- parsl/dataflow/dependency_resolvers.py +115 -0
- parsl/dataflow/dflow.py +259 -223
- parsl/dataflow/errors.py +3 -5
- parsl/dataflow/futures.py +27 -14
- parsl/dataflow/memoization.py +5 -5
- parsl/dataflow/rundirs.py +5 -6
- parsl/dataflow/taskrecord.py +4 -5
- parsl/executors/__init__.py +4 -2
- parsl/executors/base.py +45 -15
- parsl/executors/errors.py +13 -0
- parsl/executors/execute_task.py +37 -0
- parsl/executors/flux/execute_parsl_task.py +3 -3
- parsl/executors/flux/executor.py +18 -19
- parsl/executors/flux/flux_instance_manager.py +26 -27
- parsl/executors/high_throughput/errors.py +43 -3
- parsl/executors/high_throughput/executor.py +307 -285
- parsl/executors/high_throughput/interchange.py +137 -168
- parsl/executors/high_throughput/manager_record.py +4 -0
- parsl/executors/high_throughput/manager_selector.py +55 -0
- parsl/executors/high_throughput/monitoring_info.py +2 -1
- parsl/executors/high_throughput/mpi_executor.py +113 -0
- parsl/executors/high_throughput/mpi_prefix_composer.py +10 -11
- parsl/executors/high_throughput/mpi_resource_management.py +6 -17
- parsl/executors/high_throughput/probe.py +9 -7
- parsl/executors/high_throughput/process_worker_pool.py +77 -75
- parsl/executors/high_throughput/zmq_pipes.py +81 -23
- parsl/executors/radical/executor.py +130 -79
- parsl/executors/radical/rpex_resources.py +17 -15
- parsl/executors/radical/rpex_worker.py +4 -3
- parsl/executors/status_handling.py +157 -51
- parsl/executors/taskvine/__init__.py +1 -1
- parsl/executors/taskvine/errors.py +1 -1
- parsl/executors/taskvine/exec_parsl_function.py +2 -2
- parsl/executors/taskvine/executor.py +38 -55
- parsl/executors/taskvine/factory.py +1 -1
- parsl/executors/taskvine/factory_config.py +1 -1
- parsl/executors/taskvine/manager.py +17 -13
- parsl/executors/taskvine/manager_config.py +7 -2
- parsl/executors/threads.py +6 -6
- parsl/executors/workqueue/errors.py +1 -1
- parsl/executors/workqueue/exec_parsl_function.py +6 -5
- parsl/executors/workqueue/executor.py +64 -63
- parsl/executors/workqueue/parsl_coprocess.py +1 -1
- parsl/jobs/error_handlers.py +2 -2
- parsl/jobs/job_status_poller.py +28 -112
- parsl/jobs/states.py +7 -2
- parsl/jobs/strategy.py +43 -31
- parsl/launchers/__init__.py +12 -3
- parsl/launchers/errors.py +1 -1
- parsl/launchers/launchers.py +0 -6
- parsl/log_utils.py +1 -2
- parsl/monitoring/db_manager.py +55 -93
- parsl/monitoring/errors.py +6 -0
- parsl/monitoring/monitoring.py +85 -311
- parsl/monitoring/queries/pandas.py +1 -2
- parsl/monitoring/radios/base.py +13 -0
- parsl/monitoring/radios/filesystem.py +52 -0
- parsl/monitoring/radios/htex.py +57 -0
- parsl/monitoring/radios/multiprocessing.py +17 -0
- parsl/monitoring/radios/udp.py +56 -0
- parsl/monitoring/radios/zmq.py +17 -0
- parsl/monitoring/remote.py +33 -37
- parsl/monitoring/router.py +212 -0
- parsl/monitoring/types.py +5 -6
- parsl/monitoring/visualization/app.py +4 -2
- parsl/monitoring/visualization/models.py +0 -1
- parsl/monitoring/visualization/plots/default/workflow_plots.py +8 -4
- parsl/monitoring/visualization/plots/default/workflow_resource_plots.py +1 -0
- parsl/monitoring/visualization/utils.py +0 -1
- parsl/monitoring/visualization/views.py +16 -9
- parsl/multiprocessing.py +0 -1
- parsl/process_loggers.py +1 -2
- parsl/providers/__init__.py +8 -17
- parsl/providers/aws/aws.py +2 -3
- parsl/providers/azure/azure.py +4 -5
- parsl/providers/base.py +2 -18
- parsl/providers/cluster_provider.py +3 -9
- parsl/providers/condor/condor.py +7 -17
- parsl/providers/errors.py +2 -2
- parsl/providers/googlecloud/googlecloud.py +2 -1
- parsl/providers/grid_engine/grid_engine.py +5 -14
- parsl/providers/kubernetes/kube.py +80 -40
- parsl/providers/local/local.py +13 -26
- parsl/providers/lsf/lsf.py +5 -23
- parsl/providers/pbspro/pbspro.py +5 -17
- parsl/providers/slurm/slurm.py +81 -39
- parsl/providers/torque/torque.py +3 -14
- parsl/serialize/__init__.py +8 -3
- parsl/serialize/base.py +1 -2
- parsl/serialize/concretes.py +5 -4
- parsl/serialize/facade.py +3 -3
- parsl/serialize/proxystore.py +3 -2
- parsl/tests/__init__.py +1 -1
- parsl/tests/configs/azure_single_node.py +4 -5
- parsl/tests/configs/bridges.py +3 -2
- parsl/tests/configs/cc_in2p3.py +1 -3
- parsl/tests/configs/comet.py +2 -1
- parsl/tests/configs/ec2_single_node.py +1 -2
- parsl/tests/configs/ec2_spot.py +1 -2
- parsl/tests/configs/flux_local.py +11 -0
- parsl/tests/configs/frontera.py +2 -3
- parsl/tests/configs/htex_local.py +3 -5
- parsl/tests/configs/htex_local_alternate.py +11 -15
- parsl/tests/configs/htex_local_intask_staging.py +5 -9
- parsl/tests/configs/htex_local_rsync_staging.py +4 -8
- parsl/tests/configs/local_radical.py +1 -3
- parsl/tests/configs/local_radical_mpi.py +2 -2
- parsl/tests/configs/local_threads_checkpoint_periodic.py +8 -10
- parsl/tests/configs/local_threads_monitoring.py +0 -1
- parsl/tests/configs/midway.py +2 -2
- parsl/tests/configs/nscc_singapore.py +3 -3
- parsl/tests/configs/osg_htex.py +1 -1
- parsl/tests/configs/petrelkube.py +3 -2
- parsl/tests/configs/slurm_local.py +24 -0
- parsl/tests/configs/summit.py +1 -0
- parsl/tests/configs/taskvine_ex.py +4 -7
- parsl/tests/configs/user_opts.py +0 -7
- parsl/tests/configs/workqueue_ex.py +4 -6
- parsl/tests/conftest.py +27 -13
- parsl/tests/integration/test_stress/test_python_simple.py +3 -4
- parsl/tests/integration/test_stress/test_python_threads.py +3 -5
- parsl/tests/manual_tests/htex_local.py +4 -6
- parsl/tests/manual_tests/test_basic.py +1 -0
- parsl/tests/manual_tests/test_log_filter.py +3 -1
- parsl/tests/manual_tests/test_memory_limits.py +6 -8
- parsl/tests/manual_tests/test_regression_220.py +2 -1
- parsl/tests/manual_tests/test_udp_simple.py +4 -4
- parsl/tests/manual_tests/test_worker_count.py +3 -2
- parsl/tests/scaling_tests/htex_local.py +2 -4
- parsl/tests/scaling_tests/test_scale.py +0 -9
- parsl/tests/scaling_tests/vineex_condor.py +1 -2
- parsl/tests/scaling_tests/vineex_local.py +1 -2
- parsl/tests/site_tests/site_config_selector.py +1 -6
- parsl/tests/site_tests/test_provider.py +4 -2
- parsl/tests/site_tests/test_site.py +2 -0
- parsl/tests/sites/test_affinity.py +7 -7
- parsl/tests/sites/test_dynamic_executor.py +3 -4
- parsl/tests/sites/test_ec2.py +3 -2
- parsl/tests/sites/test_worker_info.py +4 -5
- parsl/tests/test_aalst_patterns.py +0 -1
- parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
- parsl/tests/test_bash_apps/test_basic.py +10 -4
- parsl/tests/test_bash_apps/test_error_codes.py +5 -7
- parsl/tests/test_bash_apps/test_inputs_default.py +25 -0
- parsl/tests/test_bash_apps/test_kwarg_storage.py +1 -1
- parsl/tests/test_bash_apps/test_memoize.py +2 -8
- parsl/tests/test_bash_apps/test_memoize_ignore_args.py +9 -14
- parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +9 -14
- parsl/tests/test_bash_apps/test_multiline.py +1 -1
- parsl/tests/test_bash_apps/test_pipeline.py +1 -1
- parsl/tests/test_bash_apps/test_std_uri.py +123 -0
- parsl/tests/test_bash_apps/test_stdout.py +33 -8
- parsl/tests/test_callables.py +2 -2
- parsl/tests/test_checkpointing/test_periodic.py +21 -39
- parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
- parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -2
- parsl/tests/test_checkpointing/test_python_checkpoint_3.py +0 -1
- parsl/tests/test_checkpointing/test_regression_239.py +1 -1
- parsl/tests/test_checkpointing/test_task_exit.py +2 -3
- parsl/tests/test_docs/test_from_slides.py +5 -2
- parsl/tests/test_docs/test_kwargs.py +4 -1
- parsl/tests/test_docs/test_tutorial_1.py +1 -2
- parsl/tests/test_docs/test_workflow1.py +2 -2
- parsl/tests/test_docs/test_workflow2.py +0 -1
- parsl/tests/test_error_handling/test_rand_fail.py +2 -2
- parsl/tests/test_error_handling/test_resource_spec.py +10 -12
- parsl/tests/test_error_handling/test_retries.py +6 -16
- parsl/tests/test_error_handling/test_retry_handler.py +1 -0
- parsl/tests/test_error_handling/test_retry_handler_failure.py +2 -1
- parsl/tests/test_error_handling/test_serialization_fail.py +1 -1
- parsl/tests/test_error_handling/test_wrap_with_logs.py +1 -0
- parsl/tests/test_execute_task.py +29 -0
- parsl/tests/test_flux.py +1 -1
- parsl/tests/test_htex/test_basic.py +2 -3
- parsl/tests/test_htex/test_block_manager_selector_unit.py +20 -0
- parsl/tests/test_htex/test_command_client_timeout.py +66 -0
- parsl/tests/test_htex/test_connected_blocks.py +3 -2
- parsl/tests/test_htex/test_cpu_affinity_explicit.py +6 -10
- parsl/tests/test_htex/test_disconnected_blocks.py +6 -5
- parsl/tests/test_htex/test_disconnected_blocks_failing_provider.py +71 -0
- parsl/tests/test_htex/test_drain.py +11 -10
- parsl/tests/test_htex/test_htex.py +51 -25
- parsl/tests/test_htex/test_manager_failure.py +0 -1
- parsl/tests/test_htex/test_manager_selector_by_block.py +51 -0
- parsl/tests/test_htex/test_managers_command.py +36 -0
- parsl/tests/test_htex/test_missing_worker.py +2 -12
- parsl/tests/test_htex/test_multiple_disconnected_blocks.py +9 -9
- parsl/tests/test_htex/test_resource_spec_validation.py +45 -0
- parsl/tests/test_htex/test_zmq_binding.py +29 -8
- parsl/tests/test_monitoring/test_app_names.py +5 -5
- parsl/tests/test_monitoring/test_basic.py +73 -25
- parsl/tests/test_monitoring/test_db_locks.py +6 -4
- parsl/tests/test_monitoring/test_fuzz_zmq.py +19 -8
- parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +80 -0
- parsl/tests/test_monitoring/test_incomplete_futures.py +5 -4
- parsl/tests/test_monitoring/test_memoization_representation.py +4 -2
- parsl/tests/test_monitoring/test_stdouterr.py +134 -0
- parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
- parsl/tests/test_mpi_apps/test_bad_mpi_config.py +33 -26
- parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +28 -11
- parsl/tests/test_mpi_apps/test_mpi_prefix.py +4 -4
- parsl/tests/test_mpi_apps/test_mpi_scheduler.py +7 -2
- parsl/tests/test_mpi_apps/test_mpiex.py +64 -0
- parsl/tests/test_mpi_apps/test_resource_spec.py +42 -49
- parsl/tests/test_providers/test_kubernetes_provider.py +102 -0
- parsl/tests/test_providers/test_local_provider.py +3 -132
- parsl/tests/test_providers/test_pbspro_template.py +2 -3
- parsl/tests/test_providers/test_slurm_template.py +2 -3
- parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
- parsl/tests/test_python_apps/test_context_manager.py +128 -0
- parsl/tests/test_python_apps/test_dep_standard_futures.py +2 -1
- parsl/tests/test_python_apps/test_dependencies_deep.py +59 -0
- parsl/tests/test_python_apps/test_fail.py +0 -25
- parsl/tests/test_python_apps/test_futures.py +2 -1
- parsl/tests/test_python_apps/test_inputs_default.py +22 -0
- parsl/tests/test_python_apps/test_join.py +0 -1
- parsl/tests/test_python_apps/test_lifted.py +11 -7
- parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
- parsl/tests/test_python_apps/test_outputs.py +1 -1
- parsl/tests/test_python_apps/test_pluggable_future_resolution.py +161 -0
- parsl/tests/test_radical/test_mpi_funcs.py +1 -2
- parsl/tests/test_regression/test_1480.py +2 -1
- parsl/tests/test_regression/test_1653.py +2 -1
- parsl/tests/test_regression/test_226.py +1 -0
- parsl/tests/test_regression/test_2652.py +1 -0
- parsl/tests/test_regression/test_69a.py +0 -1
- parsl/tests/test_regression/test_854.py +4 -2
- parsl/tests/test_regression/test_97_parallelism_0.py +1 -2
- parsl/tests/test_regression/test_98.py +0 -1
- parsl/tests/test_scaling/test_block_error_handler.py +9 -4
- parsl/tests/test_scaling/test_regression_1621.py +11 -15
- parsl/tests/test_scaling/test_regression_3568_scaledown_vs_MISSING.py +84 -0
- parsl/tests/test_scaling/test_regression_3696_oscillation.py +103 -0
- parsl/tests/test_scaling/test_scale_down.py +2 -5
- parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +5 -8
- parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +71 -0
- parsl/tests/test_scaling/test_shutdown_scalein.py +73 -0
- parsl/tests/test_scaling/test_worker_interchange_bad_messages_3262.py +90 -0
- parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
- parsl/tests/test_serialization/test_3495_deserialize_managerlost.py +47 -0
- parsl/tests/test_serialization/test_basic.py +2 -1
- parsl/tests/test_serialization/test_htex_code_cache.py +3 -4
- parsl/tests/test_serialization/test_pack_resource_spec.py +2 -1
- parsl/tests/test_serialization/test_proxystore_configured.py +10 -6
- parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
- parsl/tests/test_shutdown/test_kill_monitoring.py +64 -0
- parsl/tests/test_staging/staging_provider.py +2 -2
- parsl/tests/test_staging/test_1316.py +3 -4
- parsl/tests/test_staging/test_docs_1.py +2 -1
- parsl/tests/test_staging/test_docs_2.py +2 -1
- parsl/tests/test_staging/test_elaborate_noop_file.py +2 -3
- parsl/tests/{test_data → test_staging}/test_file.py +6 -6
- parsl/tests/{test_data → test_staging}/test_output_chain_filenames.py +3 -0
- parsl/tests/test_staging/test_staging_ftp.py +1 -0
- parsl/tests/test_staging/test_staging_https.py +5 -2
- parsl/tests/test_staging/test_staging_stdout.py +64 -0
- parsl/tests/test_staging/test_zip_in.py +39 -0
- parsl/tests/test_staging/test_zip_out.py +110 -0
- parsl/tests/test_staging/test_zip_to_zip.py +41 -0
- parsl/tests/test_summary.py +2 -2
- parsl/tests/test_thread_parallelism.py +0 -1
- parsl/tests/test_threads/test_configs.py +1 -2
- parsl/tests/test_threads/test_lazy_errors.py +2 -2
- parsl/tests/test_utils/test_execute_wait.py +35 -0
- parsl/tests/test_utils/test_sanitize_dns.py +76 -0
- parsl/tests/unit/test_address.py +20 -0
- parsl/tests/unit/test_file.py +99 -0
- parsl/tests/unit/test_usage_tracking.py +66 -0
- parsl/usage_tracking/api.py +65 -0
- parsl/usage_tracking/levels.py +6 -0
- parsl/usage_tracking/usage.py +104 -62
- parsl/utils.py +137 -4
- parsl/version.py +1 -1
- {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/exec_parsl_function.py +6 -5
- parsl-2025.1.13.data/scripts/interchange.py +649 -0
- {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/process_worker_pool.py +77 -75
- parsl-2025.1.13.dist-info/METADATA +96 -0
- parsl-2025.1.13.dist-info/RECORD +462 -0
- {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/WHEEL +1 -1
- parsl/channels/__init__.py +0 -7
- parsl/channels/base.py +0 -141
- parsl/channels/errors.py +0 -113
- parsl/channels/local/local.py +0 -164
- parsl/channels/oauth_ssh/oauth_ssh.py +0 -110
- parsl/channels/ssh/ssh.py +0 -276
- parsl/channels/ssh_il/__init__.py +0 -0
- parsl/channels/ssh_il/ssh_il.py +0 -74
- parsl/configs/ad_hoc.py +0 -35
- parsl/executors/radical/rpex_master.py +0 -42
- parsl/monitoring/radios.py +0 -175
- parsl/providers/ad_hoc/__init__.py +0 -0
- parsl/providers/ad_hoc/ad_hoc.py +0 -248
- parsl/providers/cobalt/__init__.py +0 -0
- parsl/providers/cobalt/cobalt.py +0 -236
- parsl/providers/cobalt/template.py +0 -17
- parsl/tests/configs/ad_hoc_cluster_htex.py +0 -35
- parsl/tests/configs/cooley_htex.py +0 -37
- parsl/tests/configs/htex_ad_hoc_cluster.py +0 -28
- parsl/tests/configs/local_adhoc.py +0 -18
- parsl/tests/configs/swan_htex.py +0 -43
- parsl/tests/configs/theta.py +0 -37
- parsl/tests/integration/test_channels/__init__.py +0 -0
- parsl/tests/integration/test_channels/test_channels.py +0 -17
- parsl/tests/integration/test_channels/test_local_channel.py +0 -42
- parsl/tests/integration/test_channels/test_scp_1.py +0 -45
- parsl/tests/integration/test_channels/test_ssh_1.py +0 -40
- parsl/tests/integration/test_channels/test_ssh_errors.py +0 -46
- parsl/tests/integration/test_channels/test_ssh_file_transport.py +0 -41
- parsl/tests/integration/test_channels/test_ssh_interactive.py +0 -24
- parsl/tests/manual_tests/test_ad_hoc_htex.py +0 -48
- parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +0 -88
- parsl/tests/manual_tests/test_oauth_ssh.py +0 -13
- parsl/tests/sites/test_local_adhoc.py +0 -61
- parsl/tests/test_channels/__init__.py +0 -0
- parsl/tests/test_channels/test_large_output.py +0 -22
- parsl/tests/test_data/__init__.py +0 -0
- parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +0 -51
- parsl/tests/test_providers/test_cobalt_deprecation_warning.py +0 -16
- parsl-2024.3.18.dist-info/METADATA +0 -98
- parsl-2024.3.18.dist-info/RECORD +0 -449
- parsl/{channels/local → monitoring/radios}/__init__.py +0 -0
- parsl/{channels/oauth_ssh → tests/test_shutdown}/__init__.py +0 -0
- parsl/tests/{test_data → test_staging}/test_file_apps.py +0 -0
- parsl/tests/{test_data → test_staging}/test_file_staging.py +0 -0
- parsl/{channels/ssh → tests/unit}/__init__.py +0 -0
- {parsl-2024.3.18.data → parsl-2025.1.13.data}/scripts/parsl_coprocess.py +1 -1
- {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/LICENSE +0 -0
- {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/entry_points.txt +0 -0
- {parsl-2024.3.18.dist-info → parsl-2025.1.13.dist-info}/top_level.txt +0 -0
@@ -1,22 +1,12 @@
|
|
1
|
-
import argparse
|
2
|
-
import time
|
3
|
-
|
4
1
|
import pytest
|
5
2
|
|
6
3
|
import parsl
|
7
4
|
from parsl.app.app import python_app
|
8
|
-
from parsl.tests.configs.local_threads_checkpoint_periodic import
|
5
|
+
from parsl.tests.configs.local_threads_checkpoint_periodic import fresh_config
|
9
6
|
|
10
7
|
|
11
8
|
def local_setup():
|
12
|
-
|
13
|
-
dfk = parsl.load(config)
|
14
|
-
|
15
|
-
|
16
|
-
def local_teardown():
|
17
|
-
# explicit clear without dfk.cleanup here, because the
|
18
|
-
# test does that already
|
19
|
-
parsl.clear()
|
9
|
+
parsl.load(fresh_config())
|
20
10
|
|
21
11
|
|
22
12
|
@python_app(cache=True)
|
@@ -27,40 +17,32 @@ def slow_double(x, sleep_dur=1):
|
|
27
17
|
|
28
18
|
|
29
19
|
def tstamp_to_seconds(line):
|
30
|
-
print("Parsing line: ", line)
|
31
20
|
f = line.partition(" ")[0]
|
32
21
|
return float(f)
|
33
22
|
|
34
23
|
|
35
24
|
@pytest.mark.local
|
36
|
-
def test_periodic(
|
25
|
+
def test_periodic():
|
37
26
|
"""Test checkpointing with task_periodic behavior
|
38
27
|
"""
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
d[i].result()
|
49
|
-
print("Done sleeping")
|
50
|
-
|
51
|
-
time.sleep(16)
|
52
|
-
dfk.cleanup()
|
28
|
+
h, m, s = map(int, parsl.dfk().config.checkpoint_period.split(":"))
|
29
|
+
assert h == 0, "Verify test setup"
|
30
|
+
assert m == 0, "Verify test setup"
|
31
|
+
assert s > 0, "Verify test setup"
|
32
|
+
sleep_for = s + 1
|
33
|
+
with parsl.dfk():
|
34
|
+
futs = [slow_double(sleep_for) for _ in range(4)]
|
35
|
+
[f.result() for f in futs]
|
36
|
+
run_dir = parsl.dfk().run_dir
|
53
37
|
|
54
38
|
# Here we will check if the loglines came back with 5 seconds deltas
|
55
|
-
|
56
|
-
|
57
|
-
with open("{}/parsl.log".format(dfk.run_dir), 'r') as f:
|
39
|
+
with open("{}/parsl.log".format(run_dir)) as f:
|
58
40
|
log_lines = f.readlines()
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
41
|
+
expected_msg = " Done checkpointing"
|
42
|
+
expected_msg2 = " No tasks checkpointed in this pass"
|
43
|
+
|
44
|
+
lines = [line for line in log_lines if expected_msg in line or expected_msg2 in line]
|
45
|
+
assert len(lines) >= 3, "Insufficient checkpoint lines in logfile"
|
46
|
+
deltas = [tstamp_to_seconds(line) for line in lines]
|
47
|
+
assert deltas[1] - deltas[0] < 5.5, "Delta between checkpoints exceeded period"
|
48
|
+
assert deltas[2] - deltas[1] < 5.5, "Delta between checkpoints exceeded period"
|
@@ -1,9 +1,10 @@
|
|
1
1
|
import contextlib
|
2
2
|
import os
|
3
|
+
|
3
4
|
import pytest
|
5
|
+
|
4
6
|
import parsl
|
5
7
|
from parsl import python_app
|
6
|
-
|
7
8
|
from parsl.tests.configs.local_threads_checkpoint import fresh_config
|
8
9
|
|
9
10
|
|
@@ -19,7 +20,6 @@ def parsl_configured(run_dir, **kw):
|
|
19
20
|
yield dfk
|
20
21
|
|
21
22
|
parsl.dfk().cleanup()
|
22
|
-
parsl.clear()
|
23
23
|
|
24
24
|
|
25
25
|
@python_app(cache=True)
|
@@ -5,8 +5,8 @@ import pytest
|
|
5
5
|
|
6
6
|
import parsl
|
7
7
|
from parsl.app.app import python_app
|
8
|
-
from parsl.utils import time_limited_open
|
9
8
|
from parsl.tests.configs.local_threads_checkpoint_task_exit import config
|
9
|
+
from parsl.utils import time_limited_open
|
10
10
|
|
11
11
|
|
12
12
|
def local_setup():
|
@@ -15,8 +15,7 @@ def local_setup():
|
|
15
15
|
|
16
16
|
|
17
17
|
def local_teardown():
|
18
|
-
parsl.dfk().cleanup
|
19
|
-
parsl.clear()
|
18
|
+
parsl.dfk().cleanup()
|
20
19
|
|
21
20
|
|
22
21
|
@python_app(cache=True)
|
@@ -1,8 +1,10 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
1
5
|
from parsl.app.app import bash_app, python_app
|
2
6
|
from parsl.data_provider.files import File
|
3
7
|
|
4
|
-
import os
|
5
|
-
|
6
8
|
|
7
9
|
@bash_app
|
8
10
|
def echo(message, outputs=[]):
|
@@ -15,6 +17,7 @@ def cat(inputs=[]):
|
|
15
17
|
return f.readlines()
|
16
18
|
|
17
19
|
|
20
|
+
@pytest.mark.staging_required
|
18
21
|
def test_slides():
|
19
22
|
"""Testing code snippet from slides """
|
20
23
|
|
@@ -1,7 +1,9 @@
|
|
1
1
|
"""Functions used to explain kwargs"""
|
2
2
|
from pathlib import Path
|
3
3
|
|
4
|
-
|
4
|
+
import pytest
|
5
|
+
|
6
|
+
from parsl import File, python_app
|
5
7
|
|
6
8
|
|
7
9
|
def test_inputs():
|
@@ -19,6 +21,7 @@ def test_inputs():
|
|
19
21
|
assert reduce_future.result() == 6
|
20
22
|
|
21
23
|
|
24
|
+
@pytest.mark.shared_fs
|
22
25
|
def test_outputs(tmpd_cwd):
|
23
26
|
@python_app()
|
24
27
|
def write_app(message, outputs=()):
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import os
|
2
|
+
|
2
3
|
import pytest
|
3
|
-
import parsl
|
4
4
|
|
5
|
+
import parsl
|
5
6
|
from parsl.app.app import bash_app, python_app
|
6
7
|
from parsl.data_provider.files import File
|
7
8
|
from parsl.tests.configs.local_threads import config
|
8
9
|
|
9
|
-
|
10
10
|
# parsl.set_stream_logger()
|
11
11
|
|
12
12
|
|
@@ -15,8 +15,8 @@ def local_config():
|
|
15
15
|
|
16
16
|
@python_app
|
17
17
|
def sleep_fail(sleep_dur, sleep_rand_max, fail_prob, inputs=[]):
|
18
|
-
import time
|
19
18
|
import random
|
19
|
+
import time
|
20
20
|
|
21
21
|
s = sleep_dur + random.randint(-sleep_rand_max, sleep_rand_max)
|
22
22
|
|
@@ -144,8 +144,8 @@ def test_deps(numtasks=10):
|
|
144
144
|
|
145
145
|
@python_app
|
146
146
|
def sleep_then_fail(sleep_dur=0.1):
|
147
|
-
import time
|
148
147
|
import math
|
148
|
+
import time
|
149
149
|
time.sleep(sleep_dur)
|
150
150
|
math.ceil("Trigger TypeError")
|
151
151
|
return 0
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import parsl
|
2
2
|
from parsl.app.app import python_app
|
3
|
-
from parsl.executors.errors import UnsupportedFeatureError, ExecutorError
|
4
3
|
from parsl.executors import WorkQueueExecutor
|
5
|
-
from parsl.executors.
|
4
|
+
from parsl.executors.errors import InvalidResourceSpecification
|
6
5
|
from parsl.executors.high_throughput.executor import HighThroughputExecutor
|
6
|
+
from parsl.executors.threads import ThreadPoolExecutor
|
7
7
|
|
8
8
|
|
9
9
|
@python_app
|
@@ -25,11 +25,10 @@ def test_resource(n=2):
|
|
25
25
|
try:
|
26
26
|
fut.result()
|
27
27
|
except InvalidResourceSpecification:
|
28
|
-
assert
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
assert isinstance(e, ExecutorError)
|
28
|
+
assert (
|
29
|
+
isinstance(executor, HighThroughputExecutor) or
|
30
|
+
isinstance(executor, WorkQueueExecutor) or
|
31
|
+
isinstance(executor, ThreadPoolExecutor))
|
33
32
|
|
34
33
|
# Specify resources with wrong types
|
35
34
|
# 'cpus' is incorrect, should be 'cores'
|
@@ -38,8 +37,7 @@ def test_resource(n=2):
|
|
38
37
|
try:
|
39
38
|
fut.result()
|
40
39
|
except InvalidResourceSpecification:
|
41
|
-
assert
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
assert isinstance(e, ExecutorError)
|
40
|
+
assert (
|
41
|
+
isinstance(executor, HighThroughputExecutor) or
|
42
|
+
isinstance(executor, WorkQueueExecutor) or
|
43
|
+
isinstance(executor, ThreadPoolExecutor))
|
@@ -1,8 +1,7 @@
|
|
1
|
-
import argparse
|
2
1
|
import os
|
2
|
+
|
3
3
|
import pytest
|
4
4
|
|
5
|
-
import parsl
|
6
5
|
from parsl import bash_app, python_app
|
7
6
|
from parsl.tests.configs.local_threads import fresh_config
|
8
7
|
|
@@ -15,8 +14,8 @@ def local_config():
|
|
15
14
|
|
16
15
|
@python_app
|
17
16
|
def sleep_then_fail(inputs=[], sleep_dur=0.1):
|
18
|
-
import time
|
19
17
|
import math
|
18
|
+
import time
|
20
19
|
time.sleep(sleep_dur)
|
21
20
|
math.ceil("Trigger TypeError")
|
22
21
|
return 0
|
@@ -67,8 +66,6 @@ def test_fail_nowait(numtasks=10):
|
|
67
66
|
assert isinstance(
|
68
67
|
e, TypeError), "Expected a TypeError, got {}".format(e)
|
69
68
|
|
70
|
-
print("Done")
|
71
|
-
|
72
69
|
|
73
70
|
@pytest.mark.local
|
74
71
|
def test_fail_delayed(numtasks=10):
|
@@ -93,19 +90,12 @@ def test_fail_delayed(numtasks=10):
|
|
93
90
|
assert isinstance(
|
94
91
|
e, TypeError), "Expected a TypeError, got {}".format(e)
|
95
92
|
|
96
|
-
print("Done")
|
97
|
-
|
98
93
|
|
99
94
|
@pytest.mark.local
|
100
|
-
def test_retry():
|
95
|
+
def test_retry(tmpd_cwd):
|
101
96
|
"""Test retries via app that succeeds on the Nth retry.
|
102
97
|
"""
|
103
98
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
except OSError:
|
108
|
-
pass
|
109
|
-
fu = succeed_on_retry(fname)
|
110
|
-
|
111
|
-
fu.result()
|
99
|
+
fpath = tmpd_cwd / "retry.out"
|
100
|
+
sout = str(tmpd_cwd / "stdout")
|
101
|
+
succeed_on_retry(str(fpath), stdout=sout).result()
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from parsl.executors.execute_task import execute_task
|
6
|
+
from parsl.serialize.facade import pack_res_spec_apply_message
|
7
|
+
|
8
|
+
|
9
|
+
def addemup(*args: int, name: str = "apples"):
|
10
|
+
total = sum(args)
|
11
|
+
return f"{total} {name}"
|
12
|
+
|
13
|
+
|
14
|
+
@pytest.mark.local
|
15
|
+
def test_execute_task():
|
16
|
+
args = (1, 2, 3)
|
17
|
+
kwargs = {"name": "boots"}
|
18
|
+
buff = pack_res_spec_apply_message(addemup, args, kwargs, {})
|
19
|
+
res = execute_task(buff)
|
20
|
+
assert res == addemup(*args, **kwargs)
|
21
|
+
|
22
|
+
|
23
|
+
@pytest.mark.local
|
24
|
+
def test_execute_task_resource_spec():
|
25
|
+
resource_spec = {"num_nodes": 2, "ranks_per_node": 2, "num_ranks": 4}
|
26
|
+
buff = pack_res_spec_apply_message(addemup, (1, 2), {}, resource_spec)
|
27
|
+
execute_task(buff)
|
28
|
+
for key, val in resource_spec.items():
|
29
|
+
assert os.environ[f"PARSL_{key.upper()}"] == str(val)
|
parsl/tests/test_flux.py
CHANGED
@@ -14,7 +14,6 @@ def local_setup():
|
|
14
14
|
|
15
15
|
def local_teardown():
|
16
16
|
parsl.dfk().cleanup()
|
17
|
-
parsl.clear()
|
18
17
|
|
19
18
|
|
20
19
|
@python_app
|
@@ -23,6 +22,6 @@ def dummy():
|
|
23
22
|
|
24
23
|
|
25
24
|
@pytest.mark.local
|
26
|
-
def
|
25
|
+
def test_app():
|
27
26
|
x = dummy()
|
28
|
-
x.result()
|
27
|
+
assert x.result() is None
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from parsl.executors.high_throughput.manager_record import ManagerRecord
|
4
|
+
from parsl.executors.high_throughput.manager_selector import BlockIdManagerSelector
|
5
|
+
|
6
|
+
|
7
|
+
@pytest.mark.local
|
8
|
+
def test_sort_managers():
|
9
|
+
ready_managers = {
|
10
|
+
b'manager1': {'block_id': 1},
|
11
|
+
b'manager2': {'block_id': None},
|
12
|
+
b'manager3': {'block_id': 3},
|
13
|
+
b'manager4': {'block_id': 2}
|
14
|
+
}
|
15
|
+
|
16
|
+
manager_list = {b'manager1', b'manager2', b'manager3', b'manager4'}
|
17
|
+
expected_sorted_list = [b'manager2', b'manager1', b'manager4', b'manager3']
|
18
|
+
manager_selector = BlockIdManagerSelector()
|
19
|
+
sorted_managers = manager_selector.sort_managers(ready_managers, manager_list)
|
20
|
+
assert sorted_managers == expected_sorted_list
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import threading
|
2
|
+
import time
|
3
|
+
|
4
|
+
import pytest
|
5
|
+
import zmq
|
6
|
+
|
7
|
+
from parsl import curvezmq
|
8
|
+
from parsl.executors.high_throughput.errors import (
|
9
|
+
CommandClientBadError,
|
10
|
+
CommandClientTimeoutError,
|
11
|
+
)
|
12
|
+
from parsl.executors.high_throughput.zmq_pipes import CommandClient
|
13
|
+
|
14
|
+
# Time constant used for timeout tests: various delays and
|
15
|
+
# timeouts will be appropriate multiples of this, but the
|
16
|
+
# value of T itself should not matter too much as long as
|
17
|
+
# it is big enough for zmq connections to happen successfully.
|
18
|
+
T = 0.25
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.mark.local
|
22
|
+
def test_command_not_sent() -> None:
|
23
|
+
"""Tests timeout on command send.
|
24
|
+
"""
|
25
|
+
# RFC6335 ephemeral port range
|
26
|
+
cc = CommandClient("127.0.0.1", (49152, 65535))
|
27
|
+
|
28
|
+
# cc will now wait for a connection, but we won't do anything to make the
|
29
|
+
# other side of the connection exist, so any command given to cc should
|
30
|
+
# timeout.
|
31
|
+
|
32
|
+
with pytest.raises(CommandClientTimeoutError):
|
33
|
+
cc.run("SOMECOMMAND", timeout_s=T)
|
34
|
+
|
35
|
+
cc.close()
|
36
|
+
|
37
|
+
|
38
|
+
@pytest.mark.local
|
39
|
+
def test_command_ignored() -> None:
|
40
|
+
"""Tests timeout on command response.
|
41
|
+
Tests that we timeout after a response and that the command client
|
42
|
+
sets itself into a bad state.
|
43
|
+
|
44
|
+
This only tests sequential access to the command client, even though
|
45
|
+
htex makes multithreaded use of the command client: see issue #3376 about
|
46
|
+
that lack of thread safety.
|
47
|
+
"""
|
48
|
+
# RFC6335 ephemeral port range
|
49
|
+
cc = CommandClient("127.0.0.1", (49152, 65535))
|
50
|
+
|
51
|
+
ic_ctx = curvezmq.ServerContext(None)
|
52
|
+
ic_channel = ic_ctx.socket(zmq.REP)
|
53
|
+
ic_channel.connect(f"tcp://127.0.0.1:{cc.port}")
|
54
|
+
|
55
|
+
with pytest.raises(CommandClientTimeoutError):
|
56
|
+
cc.run("SLOW_COMMAND", timeout_s=T)
|
57
|
+
|
58
|
+
req = ic_channel.recv_pyobj()
|
59
|
+
assert req == "SLOW_COMMAND", "Should have received command on interchange side"
|
60
|
+
assert not cc.ok, "CommandClient should have set itself to bad"
|
61
|
+
|
62
|
+
with pytest.raises(CommandClientBadError):
|
63
|
+
cc.run("ANOTHER_COMMAND")
|
64
|
+
|
65
|
+
cc.close()
|
66
|
+
ic_channel.close()
|
@@ -1,8 +1,10 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
-
import parsl
|
4
|
-
import pytest
|
5
3
|
import random
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
import parsl
|
6
8
|
from parsl.tests.configs.htex_local import fresh_config
|
7
9
|
|
8
10
|
logger = logging.getLogger(__name__)
|
@@ -18,6 +20,7 @@ def my_affinity():
|
|
18
20
|
|
19
21
|
@pytest.mark.local
|
20
22
|
@pytest.mark.multiple_cores_required
|
23
|
+
@pytest.mark.skipif('sched_getaffinity' not in dir(os), reason='System does not support sched_setaffinity')
|
21
24
|
def test_cpu_affinity_explicit():
|
22
25
|
available_cores = os.sched_getaffinity(0)
|
23
26
|
|
@@ -37,16 +40,9 @@ def test_cpu_affinity_explicit():
|
|
37
40
|
config.executors[0].max_workers_per_node = 1
|
38
41
|
|
39
42
|
logger.debug(f"config: {config}")
|
40
|
-
# TODO: is there a `with` style for this, to properly deal with exceptions?
|
41
|
-
|
42
|
-
parsl.load(config)
|
43
|
-
try:
|
44
43
|
|
44
|
+
with parsl.load(config):
|
45
45
|
worker_affinity = my_affinity().result()
|
46
46
|
logger.debug(f"worker reported this affinity: {worker_affinity}")
|
47
47
|
assert len(worker_affinity) == 1
|
48
48
|
assert worker_affinity == set((single_core,))
|
49
|
-
|
50
|
-
finally:
|
51
|
-
parsl.dfk().cleanup()
|
52
|
-
parsl.clear()
|
@@ -1,11 +1,13 @@
|
|
1
1
|
import logging
|
2
|
-
|
2
|
+
|
3
3
|
import pytest
|
4
|
-
|
4
|
+
|
5
|
+
import parsl
|
5
6
|
from parsl import Config
|
6
|
-
from parsl.
|
7
|
+
from parsl.executors import HighThroughputExecutor
|
7
8
|
from parsl.executors.errors import BadStateException
|
8
|
-
from parsl.jobs.states import
|
9
|
+
from parsl.jobs.states import JobState, JobStatus
|
10
|
+
from parsl.providers import LocalProvider
|
9
11
|
|
10
12
|
|
11
13
|
def local_config():
|
@@ -26,7 +28,6 @@ def local_config():
|
|
26
28
|
),
|
27
29
|
)
|
28
30
|
],
|
29
|
-
run_dir="/tmp/test_htex",
|
30
31
|
max_idletime=0.5,
|
31
32
|
strategy='htex_auto_scale',
|
32
33
|
)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import parsl
|
6
|
+
from parsl import Config
|
7
|
+
from parsl.executors import HighThroughputExecutor
|
8
|
+
from parsl.executors.errors import BadStateException
|
9
|
+
from parsl.jobs.states import JobState, JobStatus
|
10
|
+
from parsl.providers import LocalProvider
|
11
|
+
|
12
|
+
|
13
|
+
class FailingProvider(LocalProvider):
|
14
|
+
def submit(*args, **kwargs):
|
15
|
+
raise RuntimeError("Deliberate failure of provider.submit")
|
16
|
+
|
17
|
+
|
18
|
+
def local_config():
|
19
|
+
"""Config to simulate failing blocks without connecting"""
|
20
|
+
return Config(
|
21
|
+
executors=[
|
22
|
+
HighThroughputExecutor(
|
23
|
+
label="HTEX",
|
24
|
+
heartbeat_period=1,
|
25
|
+
heartbeat_threshold=2,
|
26
|
+
poll_period=100,
|
27
|
+
max_workers_per_node=1,
|
28
|
+
provider=FailingProvider(
|
29
|
+
init_blocks=0,
|
30
|
+
max_blocks=2,
|
31
|
+
min_blocks=0,
|
32
|
+
),
|
33
|
+
)
|
34
|
+
],
|
35
|
+
max_idletime=0.5,
|
36
|
+
strategy='htex_auto_scale',
|
37
|
+
strategy_period=0.1
|
38
|
+
# this strategy period needs to be a few times smaller than the
|
39
|
+
# status_polling_interval of FailingProvider, which is 5s at
|
40
|
+
# time of writing
|
41
|
+
)
|
42
|
+
|
43
|
+
|
44
|
+
@parsl.python_app
|
45
|
+
def double(x):
|
46
|
+
return x * 2
|
47
|
+
|
48
|
+
|
49
|
+
@pytest.mark.local
|
50
|
+
def test_disconnected_blocks():
|
51
|
+
"""Test reporting of blocks that fail to connect from HTEX"""
|
52
|
+
dfk = parsl.dfk()
|
53
|
+
executor = dfk.executors["HTEX"]
|
54
|
+
|
55
|
+
connected_blocks = executor.connected_blocks()
|
56
|
+
assert not connected_blocks, "Expected 0 blocks"
|
57
|
+
|
58
|
+
future = double(5)
|
59
|
+
with pytest.raises(BadStateException):
|
60
|
+
future.result()
|
61
|
+
|
62
|
+
assert isinstance(future.exception(), BadStateException)
|
63
|
+
|
64
|
+
status_dict = executor.status()
|
65
|
+
assert len(status_dict) == 1, "Expected exactly 1 block"
|
66
|
+
for status in status_dict.values():
|
67
|
+
assert isinstance(status, JobStatus)
|
68
|
+
assert status.state == JobState.MISSING
|
69
|
+
|
70
|
+
connected_blocks = executor.connected_blocks()
|
71
|
+
assert connected_blocks == [], "Expected exactly 0 connected blocks"
|