parsl 2024.5.27__py3-none-any.whl → 2024.6.10__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 +6 -4
- parsl/app/app.py +3 -6
- parsl/app/bash.py +4 -4
- parsl/app/errors.py +5 -3
- parsl/app/futures.py +3 -3
- parsl/app/python.py +2 -1
- parsl/benchmark/perf.py +2 -1
- parsl/channels/__init__.py +2 -2
- parsl/channels/base.py +0 -1
- parsl/channels/errors.py +2 -1
- parsl/channels/oauth_ssh/oauth_ssh.py +4 -3
- parsl/channels/ssh/ssh.py +9 -1
- parsl/channels/ssh_il/ssh_il.py +1 -0
- parsl/concurrent/__init__.py +2 -2
- parsl/config.py +32 -9
- parsl/configs/ASPIRE1.py +3 -3
- parsl/configs/Azure.py +6 -7
- parsl/configs/ad_hoc.py +4 -3
- parsl/configs/bridges.py +3 -3
- parsl/configs/cc_in2p3.py +2 -2
- parsl/configs/ec2.py +1 -1
- parsl/configs/expanse.py +1 -2
- parsl/configs/frontera.py +2 -3
- parsl/configs/htex_local.py +1 -2
- parsl/configs/illinoiscluster.py +1 -1
- parsl/configs/kubernetes.py +1 -2
- parsl/configs/midway.py +3 -3
- parsl/configs/osg.py +1 -1
- parsl/configs/polaris.py +1 -1
- parsl/configs/stampede2.py +4 -5
- parsl/configs/summit.py +1 -3
- parsl/configs/toss3_llnl.py +1 -2
- parsl/configs/vineex_local.py +3 -3
- parsl/configs/wqex_local.py +2 -2
- parsl/data_provider/data_manager.py +3 -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 +4 -5
- parsl/dataflow/dflow.py +57 -26
- parsl/dataflow/errors.py +2 -1
- parsl/dataflow/futures.py +1 -2
- parsl/dataflow/memoization.py +5 -5
- parsl/dataflow/rundirs.py +1 -1
- parsl/dataflow/taskrecord.py +4 -5
- parsl/executors/__init__.py +3 -3
- parsl/executors/base.py +1 -0
- parsl/executors/flux/execute_parsl_task.py +2 -2
- parsl/executors/flux/executor.py +11 -12
- parsl/executors/flux/flux_instance_manager.py +3 -3
- parsl/executors/high_throughput/executor.py +31 -36
- parsl/executors/high_throughput/interchange.py +37 -38
- parsl/executors/high_throughput/manager_record.py +1 -0
- parsl/executors/high_throughput/monitoring_info.py +2 -1
- parsl/executors/high_throughput/mpi_executor.py +5 -2
- parsl/executors/high_throughput/mpi_prefix_composer.py +1 -1
- parsl/executors/high_throughput/mpi_resource_management.py +1 -2
- parsl/executors/high_throughput/probe.py +6 -4
- parsl/executors/high_throughput/process_worker_pool.py +31 -20
- parsl/executors/high_throughput/zmq_pipes.py +28 -14
- parsl/executors/radical/executor.py +15 -15
- parsl/executors/radical/rpex_master.py +1 -2
- parsl/executors/radical/rpex_resources.py +1 -2
- parsl/executors/radical/rpex_worker.py +2 -1
- parsl/executors/status_handling.py +5 -4
- 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 +23 -24
- parsl/executors/taskvine/factory.py +1 -1
- parsl/executors/taskvine/manager.py +11 -13
- parsl/executors/threads.py +4 -5
- parsl/executors/workqueue/errors.py +1 -1
- parsl/executors/workqueue/exec_parsl_function.py +5 -4
- parsl/executors/workqueue/executor.py +26 -27
- parsl/executors/workqueue/parsl_coprocess.py +1 -1
- parsl/jobs/error_handlers.py +1 -1
- parsl/jobs/job_status_poller.py +2 -5
- parsl/jobs/states.py +1 -1
- parsl/jobs/strategy.py +2 -2
- parsl/launchers/__init__.py +12 -3
- parsl/launchers/errors.py +1 -1
- parsl/log_utils.py +1 -2
- parsl/monitoring/db_manager.py +16 -10
- parsl/monitoring/monitoring.py +11 -15
- parsl/monitoring/queries/pandas.py +1 -2
- parsl/monitoring/radios.py +2 -4
- parsl/monitoring/remote.py +13 -8
- parsl/monitoring/router.py +8 -11
- parsl/monitoring/types.py +2 -0
- 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 +9 -12
- parsl/providers/ad_hoc/ad_hoc.py +1 -1
- parsl/providers/aws/aws.py +2 -3
- parsl/providers/azure/azure.py +4 -5
- parsl/providers/base.py +1 -1
- parsl/providers/cluster_provider.py +1 -1
- parsl/providers/cobalt/cobalt.py +3 -3
- parsl/providers/condor/condor.py +4 -2
- parsl/providers/errors.py +2 -2
- parsl/providers/googlecloud/googlecloud.py +2 -1
- parsl/providers/grid_engine/grid_engine.py +2 -2
- parsl/providers/kubernetes/kube.py +24 -9
- parsl/providers/local/local.py +5 -1
- parsl/providers/lsf/lsf.py +2 -2
- parsl/providers/pbspro/pbspro.py +1 -1
- parsl/providers/slurm/slurm.py +36 -27
- parsl/providers/torque/torque.py +1 -1
- parsl/serialize/__init__.py +8 -3
- parsl/serialize/base.py +1 -2
- parsl/serialize/concretes.py +5 -4
- parsl/serialize/proxystore.py +3 -2
- parsl/tests/__init__.py +1 -1
- parsl/tests/configs/ad_hoc_cluster_htex.py +4 -4
- parsl/tests/configs/azure_single_node.py +4 -5
- parsl/tests/configs/bridges.py +3 -2
- parsl/tests/configs/cc_in2p3.py +2 -2
- 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 +3 -2
- parsl/tests/configs/htex_ad_hoc_cluster.py +2 -4
- parsl/tests/configs/htex_local.py +2 -3
- parsl/tests/configs/htex_local_alternate.py +8 -11
- parsl/tests/configs/htex_local_intask_staging.py +5 -7
- parsl/tests/configs/htex_local_rsync_staging.py +4 -6
- parsl/tests/configs/local_adhoc.py +1 -1
- parsl/tests/configs/local_radical.py +1 -3
- parsl/tests/configs/local_radical_mpi.py +2 -2
- 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/summit.py +1 -0
- parsl/tests/configs/swan_htex.py +2 -2
- parsl/tests/configs/taskvine_ex.py +3 -5
- parsl/tests/configs/theta.py +2 -2
- parsl/tests/configs/workqueue_ex.py +3 -4
- parsl/tests/conftest.py +8 -4
- parsl/tests/integration/test_channels/test_ssh_errors.py +1 -1
- 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 -4
- parsl/tests/manual_tests/test_ad_hoc_htex.py +2 -1
- parsl/tests/manual_tests/test_basic.py +1 -0
- parsl/tests/manual_tests/test_fan_in_out_htex_remote.py +4 -4
- parsl/tests/manual_tests/test_log_filter.py +3 -1
- parsl/tests/manual_tests/test_memory_limits.py +6 -6
- parsl/tests/manual_tests/test_regression_220.py +2 -1
- parsl/tests/manual_tests/test_udp_simple.py +4 -3
- parsl/tests/manual_tests/test_worker_count.py +3 -2
- parsl/tests/scaling_tests/htex_local.py +2 -2
- 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/test_provider.py +3 -1
- parsl/tests/site_tests/test_site.py +2 -0
- parsl/tests/sites/test_affinity.py +7 -5
- parsl/tests/sites/test_dynamic_executor.py +3 -3
- parsl/tests/sites/test_ec2.py +3 -2
- parsl/tests/sites/test_local_adhoc.py +2 -1
- parsl/tests/sites/test_worker_info.py +4 -3
- parsl/tests/test_aalst_patterns.py +0 -1
- parsl/tests/test_bash_apps/test_apptimeout.py +2 -2
- parsl/tests/test_bash_apps/test_error_codes.py +1 -4
- parsl/tests/test_bash_apps/test_memoize_ignore_args.py +1 -0
- parsl/tests/test_bash_apps/test_memoize_ignore_args_regr.py +2 -2
- parsl/tests/test_bash_apps/test_pipeline.py +1 -1
- parsl/tests/test_bash_apps/test_std_uri.py +4 -3
- parsl/tests/test_bash_apps/test_stdout.py +20 -2
- parsl/tests/test_callables.py +2 -2
- parsl/tests/test_checkpointing/test_python_checkpoint_1.py +1 -0
- parsl/tests/test_checkpointing/test_python_checkpoint_2.py +2 -1
- parsl/tests/test_checkpointing/test_regression_239.py +1 -1
- parsl/tests/test_checkpointing/test_task_exit.py +1 -1
- parsl/tests/test_docs/test_from_slides.py +2 -2
- parsl/tests/test_docs/test_kwargs.py +1 -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 +4 -2
- parsl/tests/test_error_handling/test_retries.py +2 -1
- 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_flux.py +1 -1
- parsl/tests/test_htex/test_command_client_timeout.py +9 -12
- parsl/tests/test_htex/test_connected_blocks.py +3 -2
- parsl/tests/test_htex/test_cpu_affinity_explicit.py +5 -2
- parsl/tests/test_htex/test_disconnected_blocks.py +6 -4
- parsl/tests/test_htex/test_drain.py +5 -5
- parsl/tests/test_htex/test_htex.py +1 -2
- parsl/tests/test_htex/test_managers_command.py +3 -2
- parsl/tests/test_htex/test_multiple_disconnected_blocks.py +6 -4
- parsl/tests/test_htex/test_zmq_binding.py +22 -6
- parsl/tests/test_monitoring/test_app_names.py +3 -2
- parsl/tests/test_monitoring/test_basic.py +4 -4
- parsl/tests/test_monitoring/test_db_locks.py +6 -3
- parsl/tests/test_monitoring/test_fuzz_zmq.py +6 -3
- parsl/tests/test_monitoring/test_htex_init_blocks_vs_monitoring.py +5 -5
- parsl/tests/test_monitoring/test_incomplete_futures.py +5 -3
- parsl/tests/test_monitoring/test_memoization_representation.py +4 -1
- parsl/tests/test_monitoring/test_stdouterr.py +4 -4
- parsl/tests/test_monitoring/test_viz_colouring.py +1 -0
- parsl/tests/test_mpi_apps/test_bad_mpi_config.py +1 -1
- parsl/tests/test_mpi_apps/test_mpi_mode_disabled.py +2 -0
- parsl/tests/test_mpi_apps/test_mpi_mode_enabled.py +7 -5
- 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 +4 -3
- parsl/tests/test_mpi_apps/test_resource_spec.py +9 -10
- parsl/tests/test_providers/test_cobalt_deprecation_warning.py +2 -0
- parsl/tests/test_providers/test_local_provider.py +2 -1
- parsl/tests/test_providers/test_pbspro_template.py +1 -1
- parsl/tests/test_providers/test_slurm_template.py +1 -1
- parsl/tests/test_providers/test_submiterror_deprecation.py +2 -1
- parsl/tests/test_python_apps/test_context_manager.py +99 -3
- 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_futures.py +2 -1
- parsl/tests/test_python_apps/test_join.py +0 -1
- parsl/tests/test_python_apps/test_lifted.py +3 -3
- parsl/tests/test_python_apps/test_memoize_bad_id_for_memo.py +1 -0
- parsl/tests/test_python_apps/test_pluggable_future_resolution.py +1 -1
- 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_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_scale_down.py +2 -3
- parsl/tests/test_scaling/test_scale_down_htex_auto_scale.py +4 -5
- parsl/tests/test_scaling/test_scale_down_htex_unregistered.py +3 -4
- parsl/tests/test_scaling/test_shutdown_scalein.py +1 -2
- parsl/tests/test_serialization/test_2555_caching_deserializer.py +1 -1
- 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 -5
- parsl/tests/test_serialization/test_proxystore_impl.py +5 -3
- parsl/tests/test_shutdown/test_kill_monitoring.py +3 -2
- parsl/tests/test_staging/staging_provider.py +2 -2
- parsl/tests/test_staging/test_1316.py +3 -2
- parsl/tests/test_staging/test_docs_1.py +1 -1
- parsl/tests/test_staging/test_docs_2.py +2 -1
- parsl/tests/test_staging/test_elaborate_noop_file.py +2 -2
- parsl/tests/test_staging/test_staging_https.py +2 -2
- parsl/tests/test_staging/test_staging_stdout.py +4 -3
- parsl/tests/test_staging/test_zip_in.py +6 -8
- parsl/tests/test_staging/test_zip_out.py +7 -9
- parsl/tests/test_staging/test_zip_to_zip.py +6 -8
- parsl/tests/test_summary.py +2 -1
- parsl/tests/test_thread_parallelism.py +0 -1
- parsl/tests/test_threads/test_configs.py +1 -1
- parsl/tests/test_threads/test_lazy_errors.py +2 -1
- parsl/tests/unit/test_usage_tracking.py +45 -0
- parsl/usage_tracking/api.py +2 -3
- parsl/usage_tracking/levels.py +6 -0
- parsl/usage_tracking/usage.py +60 -39
- parsl/utils.py +13 -2
- parsl/version.py +1 -1
- {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/exec_parsl_function.py +5 -4
- {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/process_worker_pool.py +31 -20
- {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/METADATA +2 -2
- parsl-2024.6.10.dist-info/RECORD +475 -0
- parsl-2024.5.27.dist-info/RECORD +0 -471
- {parsl-2024.5.27.data → parsl-2024.6.10.data}/scripts/parsl_coprocess.py +1 -1
- {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/LICENSE +0 -0
- {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/WHEEL +0 -0
- {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/entry_points.txt +0 -0
- {parsl-2024.5.27.dist-info → parsl-2024.6.10.dist-info}/top_level.txt +0 -0
@@ -6,15 +6,15 @@
|
|
6
6
|
# of the globus staging provider
|
7
7
|
|
8
8
|
import logging
|
9
|
+
|
9
10
|
import pytest
|
10
11
|
|
11
12
|
import parsl
|
12
|
-
|
13
13
|
from parsl import bash_app, python_app
|
14
14
|
from parsl.config import Config
|
15
15
|
from parsl.data_provider.files import File
|
16
16
|
from parsl.executors.threads import ThreadPoolExecutor
|
17
|
-
from parsl.tests.test_staging.staging_provider import
|
17
|
+
from parsl.tests.test_staging.staging_provider import NoOpError, NoOpTestingFileStaging
|
18
18
|
|
19
19
|
logger = logging.getLogger(__name__)
|
20
20
|
|
@@ -1,9 +1,9 @@
|
|
1
|
+
import pytest
|
2
|
+
|
1
3
|
import parsl
|
2
4
|
from parsl.app.app import python_app
|
3
5
|
from parsl.data_provider.files import File
|
4
6
|
|
5
|
-
import pytest
|
6
|
-
|
7
7
|
# This config is for the local test which will adding an executor.
|
8
8
|
# Most tests in this file should be non-local and use the configuration
|
9
9
|
# specificed with --config, not this one.
|
@@ -1,12 +1,13 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
-
import parsl
|
4
|
-
import pytest
|
5
3
|
import zipfile
|
6
4
|
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
import parsl
|
7
8
|
from parsl.app.futures import DataFuture
|
8
|
-
from parsl.tests.configs.htex_local import fresh_config as local_config
|
9
9
|
from parsl.data_provider.files import File
|
10
|
+
from parsl.tests.configs.htex_local import fresh_config as local_config
|
10
11
|
|
11
12
|
|
12
13
|
@parsl.bash_app
|
@@ -1,18 +1,16 @@
|
|
1
|
-
import parsl
|
2
|
-
import pytest
|
3
1
|
import random
|
4
2
|
import zipfile
|
5
3
|
|
6
|
-
|
7
|
-
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
4
|
+
import pytest
|
8
5
|
|
9
|
-
|
6
|
+
import parsl
|
10
7
|
from parsl.channels import LocalChannel
|
11
|
-
from parsl.launchers import SimpleLauncher
|
12
|
-
|
13
8
|
from parsl.config import Config
|
9
|
+
from parsl.data_provider.files import File
|
10
|
+
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
14
11
|
from parsl.executors import HighThroughputExecutor
|
15
|
-
|
12
|
+
from parsl.launchers import SimpleLauncher
|
13
|
+
from parsl.providers import LocalProvider
|
16
14
|
from parsl.tests.configs.htex_local import fresh_config as local_config
|
17
15
|
|
18
16
|
|
@@ -1,18 +1,16 @@
|
|
1
|
-
import parsl
|
2
|
-
import pytest
|
3
1
|
import zipfile
|
4
2
|
|
5
|
-
|
6
|
-
from parsl.data_provider.data_manager import default_staging
|
7
|
-
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
3
|
+
import pytest
|
8
4
|
|
9
|
-
|
5
|
+
import parsl
|
10
6
|
from parsl.channels import LocalChannel
|
11
|
-
from parsl.launchers import SimpleLauncher
|
12
|
-
|
13
7
|
from parsl.config import Config
|
8
|
+
from parsl.data_provider.data_manager import default_staging
|
9
|
+
from parsl.data_provider.files import File
|
10
|
+
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
14
11
|
from parsl.executors import HighThroughputExecutor
|
15
|
-
|
12
|
+
from parsl.launchers import SimpleLauncher
|
13
|
+
from parsl.providers import LocalProvider
|
16
14
|
from parsl.tests.configs.htex_local import fresh_config as local_config
|
17
15
|
|
18
16
|
|
@@ -1,18 +1,16 @@
|
|
1
|
-
import parsl
|
2
|
-
import pytest
|
3
1
|
import random
|
4
2
|
import zipfile
|
5
3
|
|
6
|
-
|
7
|
-
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
4
|
+
import pytest
|
8
5
|
|
9
|
-
|
6
|
+
import parsl
|
10
7
|
from parsl.channels import LocalChannel
|
11
|
-
from parsl.launchers import SimpleLauncher
|
12
|
-
|
13
8
|
from parsl.config import Config
|
9
|
+
from parsl.data_provider.files import File
|
10
|
+
from parsl.data_provider.zip import ZipAuthorityError, ZipFileStaging
|
14
11
|
from parsl.executors import HighThroughputExecutor
|
15
|
-
|
12
|
+
from parsl.launchers import SimpleLauncher
|
13
|
+
from parsl.providers import LocalProvider
|
16
14
|
from parsl.tests.configs.htex_local import fresh_config as local_config
|
17
15
|
|
18
16
|
|
parsl/tests/test_summary.py
CHANGED
@@ -7,9 +7,9 @@ from parsl.tests.configs.local_threads import fresh_config
|
|
7
7
|
|
8
8
|
@python_app
|
9
9
|
def worker_identify(x, sleep_dur=0.2):
|
10
|
-
import time
|
11
10
|
import os
|
12
11
|
import threading
|
12
|
+
import time
|
13
13
|
time.sleep(sleep_dur)
|
14
14
|
return {"pid": os.getpid(),
|
15
15
|
"tid": threading.current_thread()}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"""Test usage_tracking values."""
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import parsl
|
6
|
+
from parsl.config import Config
|
7
|
+
from parsl.errors import ConfigurationError
|
8
|
+
|
9
|
+
|
10
|
+
@pytest.mark.local
|
11
|
+
def test_config_load():
|
12
|
+
"""Test loading a config with usage tracking."""
|
13
|
+
with parsl.load(Config(usage_tracking=3)):
|
14
|
+
pass
|
15
|
+
parsl.clear()
|
16
|
+
|
17
|
+
|
18
|
+
@pytest.mark.local
|
19
|
+
@pytest.mark.parametrize("level", (0, 1, 2, 3, False, True))
|
20
|
+
def test_valid(level):
|
21
|
+
"""Test valid usage_tracking values."""
|
22
|
+
Config(usage_tracking=level)
|
23
|
+
assert Config(usage_tracking=level).usage_tracking == level
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.mark.local
|
27
|
+
@pytest.mark.parametrize("level", (12, 1000, -1))
|
28
|
+
def test_invalid_values(level):
|
29
|
+
"""Test invalid usage_tracking values."""
|
30
|
+
with pytest.raises(ConfigurationError):
|
31
|
+
Config(usage_tracking=level)
|
32
|
+
|
33
|
+
|
34
|
+
@pytest.mark.local
|
35
|
+
@pytest.mark.parametrize("level", ("abcd", None, bytes(1), 1.0, 1j, object()))
|
36
|
+
def test_invalid_types(level):
|
37
|
+
"""Test invalid usage_tracking types."""
|
38
|
+
with pytest.raises(Exception) as ex:
|
39
|
+
Config(usage_tracking=level)
|
40
|
+
|
41
|
+
# with typeguard 4.x this is TypeCheckError,
|
42
|
+
# with typeguard 2.x this is TypeError
|
43
|
+
# we can't instantiate TypeCheckError if we're in typeguard 2.x environment
|
44
|
+
# because it does not exist... so check name using strings.
|
45
|
+
assert ex.type.__name__ in ["TypeCheckError", "TypeError"]
|
parsl/usage_tracking/api.py
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
import inspect
|
2
|
-
|
3
|
-
from parsl.utils import RepresentationMixin
|
4
|
-
|
5
2
|
from abc import abstractmethod
|
6
3
|
from functools import singledispatch
|
7
4
|
from typing import Any, List, Sequence
|
8
5
|
|
6
|
+
from parsl.utils import RepresentationMixin
|
9
7
|
|
10
8
|
# Traverse the configuration hierarchy, returning a JSON component
|
11
9
|
# for each one. Configuration components which implement
|
@@ -14,6 +12,7 @@ from typing import Any, List, Sequence
|
|
14
12
|
# are traversed in sequence. Other types default to reporting no
|
15
13
|
# usage information.
|
16
14
|
|
15
|
+
|
17
16
|
@singledispatch
|
18
17
|
def get_parsl_usage(obj) -> List[Any]:
|
19
18
|
return []
|
@@ -0,0 +1,6 @@
|
|
1
|
+
"""Module for defining the usage tracking levels."""
|
2
|
+
|
3
|
+
DISABLED = 0 # Tracking is disabled
|
4
|
+
LEVEL_1 = 1 # Share info about Parsl version, Python version, platform
|
5
|
+
LEVEL_2 = 2 # Share info about config + level 1
|
6
|
+
LEVEL_3 = 3 # Share info about app count, app fails, execution time + level 2
|
parsl/usage_tracking/usage.py
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
import uuid
|
2
|
-
import time
|
3
|
-
import os
|
4
1
|
import json
|
5
2
|
import logging
|
3
|
+
import platform
|
6
4
|
import socket
|
7
5
|
import sys
|
8
|
-
import
|
6
|
+
import time
|
7
|
+
import uuid
|
9
8
|
|
9
|
+
from parsl.dataflow.states import States
|
10
|
+
from parsl.errors import ConfigurationError
|
11
|
+
from parsl.multiprocessing import ForkProcess
|
10
12
|
from parsl.usage_tracking.api import get_parsl_usage
|
13
|
+
from parsl.usage_tracking.levels import DISABLED as USAGE_TRACKING_DISABLED
|
14
|
+
from parsl.usage_tracking.levels import LEVEL_3 as USAGE_TRACKING_LEVEL_3
|
11
15
|
from parsl.utils import setproctitle
|
12
|
-
from parsl.multiprocessing import ForkProcess
|
13
|
-
from parsl.dataflow.states import States
|
14
16
|
from parsl.version import VERSION as PARSL_VERSION
|
15
17
|
|
16
18
|
logger = logging.getLogger(__name__)
|
17
19
|
|
18
20
|
from typing import Callable
|
21
|
+
|
19
22
|
from typing_extensions import ParamSpec
|
20
23
|
|
21
24
|
# protocol version byte: when (for example) compression parameters are changed
|
@@ -110,28 +113,33 @@ class UsageTracker:
|
|
110
113
|
self.python_version = "{}.{}.{}".format(sys.version_info.major,
|
111
114
|
sys.version_info.minor,
|
112
115
|
sys.version_info.micro)
|
113
|
-
self.
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
116
|
+
self.tracking_level = self.check_tracking_level()
|
117
|
+
self.start_time = None
|
118
|
+
logger.debug("Tracking level: {}".format(self.tracking_level))
|
119
|
+
|
120
|
+
def check_tracking_level(self) -> int:
|
121
|
+
"""Check if tracking is enabled and return level.
|
122
|
+
|
123
|
+
Checks usage_tracking in Config
|
124
|
+
- Possible values: [True, False, 0, 1, 2, 3]
|
125
|
+
|
126
|
+
True/False values are treated as Level 1/Level 0 respectively.
|
127
|
+
|
128
|
+
Returns: int
|
129
|
+
- 0 : Tracking is disabled
|
130
|
+
- 1 : Tracking is enabled with level 1
|
131
|
+
Share info about Parsl version, Python version, platform
|
132
|
+
- 2 : Tracking is enabled with level 2
|
133
|
+
Share info about config + level 1
|
134
|
+
- 3 : Tracking is enabled with level 3
|
135
|
+
Share info about app count, app fails, execution time + level 2
|
124
136
|
"""
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
137
|
+
if not USAGE_TRACKING_DISABLED <= self.config.usage_tracking <= USAGE_TRACKING_LEVEL_3:
|
138
|
+
raise ConfigurationError(
|
139
|
+
f"Usage Tracking values must be 0, 1, 2, or 3 and not {self.config.usage_tracking}"
|
140
|
+
)
|
129
141
|
|
130
|
-
|
131
|
-
if envvar == "false":
|
132
|
-
track = False
|
133
|
-
|
134
|
-
return track
|
142
|
+
return self.config.usage_tracking
|
135
143
|
|
136
144
|
def construct_start_message(self) -> bytes:
|
137
145
|
"""Collect preliminary run info at the start of the DFK.
|
@@ -143,18 +151,28 @@ class UsageTracker:
|
|
143
151
|
'parsl_v': self.parsl_version,
|
144
152
|
'python_v': self.python_version,
|
145
153
|
'platform.system': platform.system(),
|
146
|
-
'
|
147
|
-
|
154
|
+
'tracking_level': int(self.tracking_level)}
|
155
|
+
|
156
|
+
if self.tracking_level >= 2:
|
157
|
+
message['components'] = get_parsl_usage(self.dfk._config)
|
158
|
+
|
159
|
+
if self.tracking_level == 3:
|
160
|
+
self.start_time = int(time.time())
|
161
|
+
message['start'] = self.start_time
|
162
|
+
|
148
163
|
logger.debug(f"Usage tracking start message: {message}")
|
149
164
|
|
150
165
|
return self.encode_message(message)
|
151
166
|
|
152
167
|
def construct_end_message(self) -> bytes:
|
153
168
|
"""Collect the final run information at the time of DFK cleanup.
|
169
|
+
This is only called if tracking level is 3.
|
154
170
|
|
155
171
|
Returns:
|
156
172
|
- Message dict dumped as json string, ready for UDP
|
157
173
|
"""
|
174
|
+
end_time = int(time.time())
|
175
|
+
|
158
176
|
app_count = self.dfk.task_count
|
159
177
|
|
160
178
|
app_fails = self.dfk.task_state_counts[States.failed] + self.dfk.task_state_counts[States.dep_fail]
|
@@ -167,7 +185,8 @@ class UsageTracker:
|
|
167
185
|
'app_fails': app_fails}
|
168
186
|
|
169
187
|
message = {'correlator': self.correlator_uuid,
|
170
|
-
'end':
|
188
|
+
'end': end_time,
|
189
|
+
'execution_time': end_time - self.start_time,
|
171
190
|
'components': [dfk_component] + get_parsl_usage(self.dfk._config)}
|
172
191
|
logger.debug(f"Usage tracking end message (unencoded): {message}")
|
173
192
|
|
@@ -178,20 +197,22 @@ class UsageTracker:
|
|
178
197
|
|
179
198
|
def send_UDP_message(self, message: bytes) -> None:
|
180
199
|
"""Send UDP message."""
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
logger.debug("Usage tracking failed: {}".format(e))
|
200
|
+
try:
|
201
|
+
proc = udp_messenger(self.domain_name, self.UDP_PORT, self.sock_timeout, message)
|
202
|
+
self.procs.append(proc)
|
203
|
+
except Exception as e:
|
204
|
+
logger.debug("Usage tracking failed: {}".format(e))
|
187
205
|
|
188
206
|
def send_start_message(self) -> None:
|
189
|
-
|
190
|
-
|
207
|
+
if self.tracking_level:
|
208
|
+
self.start_time = time.time()
|
209
|
+
message = self.construct_start_message()
|
210
|
+
self.send_UDP_message(message)
|
191
211
|
|
192
212
|
def send_end_message(self) -> None:
|
193
|
-
|
194
|
-
|
213
|
+
if self.tracking_level == 3:
|
214
|
+
message = self.construct_end_message()
|
215
|
+
self.send_UDP_message(message)
|
195
216
|
|
196
217
|
def close(self, timeout: float = 10.0) -> None:
|
197
218
|
"""First give each process one timeout period to finish what it is
|
parsl/utils.py
CHANGED
@@ -7,7 +7,19 @@ import threading
|
|
7
7
|
import time
|
8
8
|
from contextlib import contextmanager
|
9
9
|
from types import TracebackType
|
10
|
-
from typing import
|
10
|
+
from typing import (
|
11
|
+
IO,
|
12
|
+
Any,
|
13
|
+
AnyStr,
|
14
|
+
Callable,
|
15
|
+
Dict,
|
16
|
+
Generator,
|
17
|
+
List,
|
18
|
+
Optional,
|
19
|
+
Sequence,
|
20
|
+
Tuple,
|
21
|
+
Union,
|
22
|
+
)
|
11
23
|
|
12
24
|
import typeguard
|
13
25
|
from typing_extensions import Type
|
@@ -16,7 +28,6 @@ import parsl
|
|
16
28
|
from parsl.app.errors import BadStdStreamFile
|
17
29
|
from parsl.version import VERSION
|
18
30
|
|
19
|
-
|
20
31
|
try:
|
21
32
|
import setproctitle as setproctitle_module
|
22
33
|
except ImportError:
|
parsl/version.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
import pickle
|
2
|
+
import sys
|
3
|
+
import traceback
|
4
|
+
|
1
5
|
from parsl.app.errors import RemoteExceptionWrapper
|
2
6
|
from parsl.data_provider.files import File
|
3
|
-
from parsl.utils import get_std_fname_mode
|
4
|
-
import traceback
|
5
|
-
import sys
|
6
|
-
import pickle
|
7
7
|
from parsl.serialize import serialize
|
8
|
+
from parsl.utils import get_std_fname_mode
|
8
9
|
|
9
10
|
# This scripts executes a parsl function which is pickled in a file:
|
10
11
|
#
|
@@ -1,39 +1,41 @@
|
|
1
1
|
#!python
|
2
2
|
|
3
3
|
import argparse
|
4
|
+
import json
|
4
5
|
import logging
|
6
|
+
import math
|
7
|
+
import multiprocessing
|
5
8
|
import os
|
6
|
-
import
|
9
|
+
import pickle
|
7
10
|
import platform
|
11
|
+
import queue
|
12
|
+
import sys
|
8
13
|
import threading
|
9
|
-
import pickle
|
10
14
|
import time
|
11
|
-
import queue
|
12
15
|
import uuid
|
13
|
-
from typing import Sequence, Optional, Dict, List
|
14
|
-
|
15
|
-
import zmq
|
16
|
-
import math
|
17
|
-
import json
|
18
|
-
import psutil
|
19
|
-
import multiprocessing
|
20
16
|
from multiprocessing.managers import DictProxy
|
21
17
|
from multiprocessing.sharedctypes import Synchronized
|
18
|
+
from typing import Dict, List, Optional, Sequence
|
19
|
+
|
20
|
+
import psutil
|
21
|
+
import zmq
|
22
22
|
|
23
23
|
from parsl import curvezmq
|
24
|
-
from parsl.process_loggers import wrap_with_logs
|
25
|
-
from parsl.version import VERSION as PARSL_VERSION
|
26
24
|
from parsl.app.errors import RemoteExceptionWrapper
|
27
25
|
from parsl.executors.high_throughput.errors import WorkerLost
|
28
|
-
from parsl.executors.high_throughput.
|
29
|
-
|
30
|
-
|
26
|
+
from parsl.executors.high_throughput.mpi_prefix_composer import (
|
27
|
+
VALID_LAUNCHERS,
|
28
|
+
compose_all,
|
29
|
+
)
|
31
30
|
from parsl.executors.high_throughput.mpi_resource_management import (
|
31
|
+
MPITaskScheduler,
|
32
32
|
TaskScheduler,
|
33
|
-
MPITaskScheduler
|
34
33
|
)
|
35
|
-
|
36
|
-
from parsl.
|
34
|
+
from parsl.executors.high_throughput.probe import probe_addresses
|
35
|
+
from parsl.multiprocessing import SpawnContext
|
36
|
+
from parsl.process_loggers import wrap_with_logs
|
37
|
+
from parsl.serialize import serialize, unpack_res_spec_apply_message
|
38
|
+
from parsl.version import VERSION as PARSL_VERSION
|
37
39
|
|
38
40
|
HEARTBEAT_CODE = (2 ** 32) - 1
|
39
41
|
DRAINED_CODE = (2 ** 32) - 2
|
@@ -677,7 +679,8 @@ def worker(
|
|
677
679
|
# If desired, set process affinity
|
678
680
|
if cpu_affinity != "none":
|
679
681
|
# Count the number of cores per worker
|
680
|
-
|
682
|
+
# OSX does not implement os.sched_getaffinity
|
683
|
+
avail_cores = sorted(os.sched_getaffinity(0)) # type: ignore[attr-defined, unused-ignore]
|
681
684
|
cores_per_worker = len(avail_cores) // pool_size
|
682
685
|
assert cores_per_worker > 0, "Affinity does not work if there are more workers than cores"
|
683
686
|
|
@@ -717,7 +720,15 @@ def worker(
|
|
717
720
|
os.environ["KMP_AFFINITY"] = f"explicit,proclist=[{proc_list}]" # For Intel OpenMP
|
718
721
|
|
719
722
|
# Set the affinity for this worker
|
720
|
-
os.sched_setaffinity
|
723
|
+
# OSX does not implement os.sched_setaffinity so type checking
|
724
|
+
# is ignored here in two ways:
|
725
|
+
# On a platform without sched_setaffinity, that attribute will not
|
726
|
+
# be defined, so ignore[attr-defined] will tell mypy to ignore this
|
727
|
+
# incorrect-for-OS X attribute access.
|
728
|
+
# On a platform with sched_setaffinity, that type: ignore message
|
729
|
+
# will be redundant, and ignore[unused-ignore] tells mypy to ignore
|
730
|
+
# that this ignore is unneeded.
|
731
|
+
os.sched_setaffinity(0, my_cores) # type: ignore[attr-defined, unused-ignore]
|
721
732
|
logger.info("Set worker CPU affinity to {}".format(my_cores))
|
722
733
|
|
723
734
|
# If desired, pin to accelerator
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: parsl
|
3
|
-
Version: 2024.
|
3
|
+
Version: 2024.6.10
|
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.
|
6
|
+
Download-URL: https://github.com/Parsl/parsl/archive/2024.06.10.tar.gz
|
7
7
|
Author: The Parsl Team
|
8
8
|
Author-email: parsl@googlegroups.com
|
9
9
|
License: Apache 2.0
|