fractal-server 2.14.0a24__tar.gz → 2.14.0a25__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.
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/PKG-INFO +1 -1
- fractal_server-2.14.0a25/fractal_server/__init__.py +1 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/history.py +1 -1
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/history.py +4 -2
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/base_runner.py +20 -36
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/local/get_local_config.py +5 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/local/runner.py +4 -47
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/_slurm_config.py +4 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/base_slurm_runner.py +26 -63
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/get_slurm_config.py +38 -1
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/task_files.py +29 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/db_tools.py +0 -15
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/runner.py +4 -8
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/runner_functions.py +97 -40
- fractal_server-2.14.0a25/fractal_server/migrations/versions/f37aceb45062_make_historyunit_logfile_required.py +39 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/pyproject.toml +2 -2
- fractal_server-2.14.0a24/fractal_server/__init__.py +0 -1
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/LICENSE +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/README.md +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/__main__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/alembic.ini +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/db/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/history/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/linkusergroup.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/linkuserproject.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/security.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/user_settings.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/accounting.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/dataset.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/job.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/project.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/task.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/task_group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/workflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/models/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/accounting.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/impersonate.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/job.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/project.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/task.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/task_group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/admin/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/_aux_functions.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/_aux_functions_history.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/_aux_functions_task_lifecycle.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/_aux_functions_tasks.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/dataset.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/images.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/job.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/project.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/status_legacy.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/submit.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/task.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/task_collection.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/task_collection_custom.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/task_group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/task_group_lifecycle.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/verify_image_types.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/workflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/workflow_import.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/_aux_auth.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/current_user.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/login.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/oauth.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/register.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/router.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/auth/users.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/aux/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/aux/_job.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/aux/_runner.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/aux/validate_user_settings.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/pagination.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/components.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/compress_folder.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/exceptions.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/local/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/_batching.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/_job_states.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/remote.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/slurm_job_task_models.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_common/utils_executors.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_ssh/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_ssh/runner.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_sudo/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_sudo/_subprocess_run_as_user.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/executors/slurm_sudo/runner.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/extract_archive.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/filenames.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/run_subprocess.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/set_start_and_last_task_index.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/shutdown.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/_local.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/_slurm_ssh.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/_slurm_sudo.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/deduplicate_list.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/merge_outputs.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/runner_functions_low_level.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/submit_workflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/task_interface.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/versions.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/_filter_validators.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/_validators.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/user.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/user_group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/user_settings.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/accounting.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/dataset.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/dumps.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/history.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/job.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/manifest.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/project.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/status_legacy.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/task.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/task_collection.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/task_group.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/workflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/schemas/v2/workflowtask.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/security/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/security/signup_email.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/user_settings.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/config.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/data_migrations/README.md +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/data_migrations/tools.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/gunicorn_fractal.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/images/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/images/models.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/images/tools.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/logger.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/main.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/env.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/naming_convention.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/034a469ec2eb_task_groups.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/091b01f51f88_add_usergroup_and_linkusergroup_table.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/19eca0dd47a9_user_settings_project_dir.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/1eac13a26c83_drop_v1_tables.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/316140ff7ee1_remove_usersettings_cache_dir.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/47351f8c7ebc_drop_dataset_filters.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/4c308bcaea2b_add_task_args_schema_and_task_args_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/4cedeb448a53_workflowtask_foreign_keys_not_nullables.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/501961cfcd85_remove_link_between_v1_and_v2_tasks_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/50a13d6138fd_initial_schema.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/5bf02391cfef_v2.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/70e77f1c38b0_add_applyworkflow_first_task_index_and_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/71eefd1dd202_add_slurm_accounts.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/84bf0fffde30_add_dumps_to_applyworkflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/8e8f227a3e36_update_taskv2_post_2_7_0.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/8f79bd162e35_add_docs_info_and_docs_link_to_task_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/94a47ea2d3ff_remove_cache_dir_slurm_user_and_slurm_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/97f444d47249_add_applyworkflow_project_dump.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/99ea79d9e5d2_add_dataset_history.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/9c5ae74c9b98_add_user_settings_table.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/9db60297b8b2_set_ondelete.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/9fd26a2b0de4_add_workflow_timestamp_created.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/a7f4d6137b53_add_workflow_dump_to_applyworkflow.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/af1ef1c83c9b_add_accounting_tables.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/af8673379a5c_drop_old_filter_columns.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/d256a7379ab8_taskgroup_activity_and_venv_info_to_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/d4fe3708d309_make_applyworkflow_workflow_dump_non_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/da2cb2ac4255_user_group_viewer_paths.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/db09233ad13a_split_filters_and_keep_old_columns.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/e75cac726012_make_applyworkflow_start_timestamp_not_.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/e81103413827_add_job_type_filters.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/efa89c30e0a4_add_project_timestamp_created.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/f384e1c0cf5d_drop_task_default_args_columns.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/migrations/versions/fbce16ff4e47_new_history_items.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/py.typed +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/ssh/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/ssh/_fabric.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/string_tools.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/syringe.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/utils.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/local/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/local/_utils.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/local/collect.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/local/deactivate.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/local/reactivate.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/ssh/__init__.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/ssh/_utils.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/ssh/collect.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/ssh/deactivate.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/ssh/reactivate.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/1_create_venv.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/2_pip_install.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/3_pip_freeze.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/4_pip_show.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/5_get_venv_size_and_file_number.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/templates/6_pip_install_from_freeze.sh +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/utils_background.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/utils_database.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/utils_package_names.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/utils_python_interpreter.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/tasks/v2/utils_templates.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/urls.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/utils.py +0 -0
- {fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/zip_tools.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "2.14.0a25"
|
{fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/routes/api/v2/history.py
RENAMED
@@ -249,8 +249,10 @@ async def get_history_run_units(
|
|
249
249
|
page_size = pagination.page_size or total_count
|
250
250
|
|
251
251
|
# Query `HistoryUnit`s
|
252
|
-
stmt =
|
253
|
-
HistoryUnit
|
252
|
+
stmt = (
|
253
|
+
select(HistoryUnit)
|
254
|
+
.where(HistoryUnit.history_run_id == history_run_id)
|
255
|
+
.order_by(HistoryUnit.id)
|
254
256
|
)
|
255
257
|
if unit_status:
|
256
258
|
stmt = stmt.where(HistoryUnit.status == unit_status)
|
@@ -4,7 +4,6 @@ from fractal_server.app.runner.task_files import TaskFiles
|
|
4
4
|
from fractal_server.app.schemas.v2.task import TaskTypeType
|
5
5
|
from fractal_server.logger import set_logger
|
6
6
|
|
7
|
-
|
8
7
|
TASK_TYPES_SUBMIT: list[TaskTypeType] = [
|
9
8
|
"compound",
|
10
9
|
"converter_compound",
|
@@ -103,29 +102,44 @@ class BaseRunner(object):
|
|
103
102
|
|
104
103
|
def validate_multisubmit_parameters(
|
105
104
|
self,
|
106
|
-
|
105
|
+
*,
|
107
106
|
task_type: TaskTypeType,
|
107
|
+
list_parameters: list[dict[str, Any]],
|
108
108
|
list_task_files: list[TaskFiles],
|
109
|
+
history_unit_ids: list[int],
|
109
110
|
) -> None:
|
110
111
|
"""
|
111
112
|
Validate parameters for `multisubmit` method
|
112
113
|
|
113
114
|
Args:
|
114
|
-
list_parameters: List of parameters dictionaries.
|
115
115
|
task_type: Task type.
|
116
|
+
list_parameters: List of parameters dictionaries.
|
117
|
+
list_task_files:
|
118
|
+
history_unit_ids:
|
116
119
|
"""
|
117
120
|
if task_type not in TASK_TYPES_MULTISUBMIT:
|
118
121
|
raise ValueError(f"Invalid {task_type=} for `multisubmit`.")
|
119
122
|
|
123
|
+
if not isinstance(list_parameters, list):
|
124
|
+
raise ValueError("`parameters` must be a list.")
|
125
|
+
|
126
|
+
if len(list_parameters) != len(list_task_files):
|
127
|
+
raise ValueError(
|
128
|
+
f"{len(list_task_files)=} differs from "
|
129
|
+
f"{len(list_parameters)=}."
|
130
|
+
)
|
131
|
+
if len(history_unit_ids) != len(list_parameters):
|
132
|
+
raise ValueError(
|
133
|
+
f"{len(history_unit_ids)=} differs from "
|
134
|
+
f"{len(list_parameters)=}."
|
135
|
+
)
|
136
|
+
|
120
137
|
subfolders = set(
|
121
138
|
task_file.wftask_subfolder_local for task_file in list_task_files
|
122
139
|
)
|
123
140
|
if len(subfolders) != 1:
|
124
141
|
raise ValueError(f"More than one subfolders: {subfolders}.")
|
125
142
|
|
126
|
-
if not isinstance(list_parameters, list):
|
127
|
-
raise ValueError("`parameters` must be a list.")
|
128
|
-
|
129
143
|
for single_kwargs in list_parameters:
|
130
144
|
if not isinstance(single_kwargs, dict):
|
131
145
|
raise ValueError("kwargs itemt must be a dictionary.")
|
@@ -137,33 +151,3 @@ class BaseRunner(object):
|
|
137
151
|
zarr_urls = [kwargs["zarr_url"] for kwargs in list_parameters]
|
138
152
|
if len(zarr_urls) != len(set(zarr_urls)):
|
139
153
|
raise ValueError("Non-unique zarr_urls")
|
140
|
-
|
141
|
-
def validate_multisubmit_history_unit_ids(
|
142
|
-
self,
|
143
|
-
*,
|
144
|
-
history_unit_ids: list[int],
|
145
|
-
task_type: TaskTypeType,
|
146
|
-
list_parameters: list[dict[str, Any]],
|
147
|
-
) -> None:
|
148
|
-
"""
|
149
|
-
Run preliminary check for multisubmit inputs.
|
150
|
-
|
151
|
-
Args:
|
152
|
-
history_unit_ids:
|
153
|
-
task_type:
|
154
|
-
list_parameters:
|
155
|
-
"""
|
156
|
-
if task_type in ["compound", "converter_compound"]:
|
157
|
-
if len(history_unit_ids) != 1:
|
158
|
-
raise NotImplementedError(
|
159
|
-
"We are breaking the assumption that compound/multisubmit "
|
160
|
-
"is associated to a single HistoryUnit. This is not "
|
161
|
-
"supported."
|
162
|
-
)
|
163
|
-
elif task_type == "parallel" and len(history_unit_ids) != len(
|
164
|
-
list_parameters
|
165
|
-
):
|
166
|
-
raise ValueError(
|
167
|
-
f"{len(history_unit_ids)=} differs from "
|
168
|
-
f"{len(list_parameters)=}."
|
169
|
-
)
|
@@ -47,11 +47,16 @@ class LocalBackendConfig(BaseModel):
|
|
47
47
|
model_config = ConfigDict(extra="forbid")
|
48
48
|
parallel_tasks_per_job: Optional[int] = None
|
49
49
|
|
50
|
+
@property
|
51
|
+
def batch_size(self) -> int:
|
52
|
+
return self.parallel_tasks_per_job or 1
|
53
|
+
|
50
54
|
|
51
55
|
def get_local_backend_config(
|
52
56
|
wftask: WorkflowTaskV2,
|
53
57
|
which_type: Literal["non_parallel", "parallel"],
|
54
58
|
config_path: Optional[Path] = None,
|
59
|
+
tot_tasks: int = 1,
|
55
60
|
) -> LocalBackendConfig:
|
56
61
|
"""
|
57
62
|
Prepare a `LocalBackendConfig` configuration object
|
@@ -8,12 +8,7 @@ from .get_local_config import LocalBackendConfig
|
|
8
8
|
from fractal_server.app.db import get_sync_db
|
9
9
|
from fractal_server.app.runner.exceptions import TaskExecutionError
|
10
10
|
from fractal_server.app.runner.executors.base_runner import BaseRunner
|
11
|
-
from fractal_server.app.runner.task_files import MULTISUBMIT_PREFIX
|
12
|
-
from fractal_server.app.runner.task_files import SUBMIT_PREFIX
|
13
11
|
from fractal_server.app.runner.task_files import TaskFiles
|
14
|
-
from fractal_server.app.runner.v2.db_tools import (
|
15
|
-
update_logfile_of_history_unit,
|
16
|
-
)
|
17
12
|
from fractal_server.app.runner.v2.db_tools import update_status_of_history_unit
|
18
13
|
from fractal_server.app.schemas.v2 import HistoryUnitStatus
|
19
14
|
from fractal_server.logger import set_logger
|
@@ -68,13 +63,6 @@ class LocalRunner(BaseRunner):
|
|
68
63
|
workdir_local = task_files.wftask_subfolder_local
|
69
64
|
workdir_local.mkdir()
|
70
65
|
|
71
|
-
# Add prefix to task_files object
|
72
|
-
task_files.prefix = SUBMIT_PREFIX
|
73
|
-
update_logfile_of_history_unit(
|
74
|
-
history_unit_id=history_unit_id,
|
75
|
-
logfile=task_files.log_file_local,
|
76
|
-
)
|
77
|
-
|
78
66
|
# SUBMISSION PHASE
|
79
67
|
future = self.executor.submit(
|
80
68
|
func,
|
@@ -111,29 +99,18 @@ class LocalRunner(BaseRunner):
|
|
111
99
|
list_task_files: list[TaskFiles],
|
112
100
|
task_type: Literal["parallel", "compound", "converter_compound"],
|
113
101
|
config: LocalBackendConfig,
|
114
|
-
):
|
102
|
+
) -> tuple[dict[int, Any], dict[int, BaseException]]:
|
115
103
|
"""
|
116
|
-
Note:
|
117
|
-
|
118
|
-
|
119
|
-
2. The number of `HistoryUnit`s is equal to `len(history_unit_ids)`.
|
120
|
-
3. For compound tasks, these two numbers are not the same.
|
121
|
-
|
122
|
-
For this reason, we defer database updates to the caller function,
|
123
|
-
when we are in one of the "compound" cases
|
124
|
-
|
104
|
+
Note: `list_parameters`, `list_task_files` and `history_unit_ids`
|
105
|
+
have the same size. For parallel tasks, this is also the number of
|
106
|
+
input images, while for compound tasks these can differ.
|
125
107
|
"""
|
126
108
|
|
127
109
|
self.validate_multisubmit_parameters(
|
128
110
|
list_parameters=list_parameters,
|
129
111
|
task_type=task_type,
|
130
112
|
list_task_files=list_task_files,
|
131
|
-
)
|
132
|
-
|
133
|
-
self.validate_multisubmit_history_unit_ids(
|
134
113
|
history_unit_ids=history_unit_ids,
|
135
|
-
task_type=task_type,
|
136
|
-
list_parameters=list_parameters,
|
137
114
|
)
|
138
115
|
|
139
116
|
logger.debug(f"[multisubmit] START, {len(list_parameters)=}")
|
@@ -159,9 +136,6 @@ class LocalRunner(BaseRunner):
|
|
159
136
|
active_futures: dict[int, Future] = {}
|
160
137
|
for ind_within_chunk, kwargs in enumerate(list_parameters_chunk):
|
161
138
|
positional_index = ind_chunk + ind_within_chunk
|
162
|
-
list_task_files[
|
163
|
-
positional_index
|
164
|
-
].prefix = f"{MULTISUBMIT_PREFIX}-{positional_index:06d}"
|
165
139
|
future = self.executor.submit(
|
166
140
|
func,
|
167
141
|
parameters=kwargs,
|
@@ -171,23 +145,6 @@ class LocalRunner(BaseRunner):
|
|
171
145
|
)
|
172
146
|
active_futures[positional_index] = future
|
173
147
|
|
174
|
-
if task_type == "parallel":
|
175
|
-
# FIXME: replace loop with a `bulk_update_history_unit`
|
176
|
-
# function
|
177
|
-
update_logfile_of_history_unit(
|
178
|
-
history_unit_id=history_unit_ids[positional_index],
|
179
|
-
logfile=list_task_files[
|
180
|
-
positional_index
|
181
|
-
].log_file_local,
|
182
|
-
)
|
183
|
-
else:
|
184
|
-
logger.debug(
|
185
|
-
f"Unclear what logfile to associate to {task_type=} "
|
186
|
-
"within multisubmit (see issue #2382)."
|
187
|
-
)
|
188
|
-
# FIXME: Improve definition for compound tasks
|
189
|
-
pass
|
190
|
-
|
191
148
|
while active_futures:
|
192
149
|
finished_futures = [
|
193
150
|
index_and_future
|
@@ -12,7 +12,6 @@ import cloudpickle
|
|
12
12
|
from ..slurm_common._slurm_config import SlurmConfig
|
13
13
|
from ..slurm_common.slurm_job_task_models import SlurmJob
|
14
14
|
from ..slurm_common.slurm_job_task_models import SlurmTask
|
15
|
-
from ._batching import heuristics
|
16
15
|
from ._job_states import STATES_FINISHED
|
17
16
|
from fractal_server import __VERSION__
|
18
17
|
from fractal_server.app.db import get_sync_db
|
@@ -20,15 +19,10 @@ from fractal_server.app.runner.exceptions import JobExecutionError
|
|
20
19
|
from fractal_server.app.runner.exceptions import TaskExecutionError
|
21
20
|
from fractal_server.app.runner.executors.base_runner import BaseRunner
|
22
21
|
from fractal_server.app.runner.filenames import SHUTDOWN_FILENAME
|
23
|
-
from fractal_server.app.runner.task_files import MULTISUBMIT_PREFIX
|
24
|
-
from fractal_server.app.runner.task_files import SUBMIT_PREFIX
|
25
22
|
from fractal_server.app.runner.task_files import TaskFiles
|
26
23
|
from fractal_server.app.runner.v2.db_tools import (
|
27
24
|
bulk_update_status_of_history_unit,
|
28
25
|
)
|
29
|
-
from fractal_server.app.runner.v2.db_tools import (
|
30
|
-
update_logfile_of_history_unit,
|
31
|
-
)
|
32
26
|
from fractal_server.app.runner.v2.db_tools import update_status_of_history_unit
|
33
27
|
from fractal_server.app.schemas.v2 import HistoryUnitStatus
|
34
28
|
from fractal_server.config import get_settings
|
@@ -84,9 +78,18 @@ class BaseSlurmRunner(BaseRunner):
|
|
84
78
|
|
85
79
|
# Create job folders. Note that the local one may or may not exist
|
86
80
|
# depending on whether it is a test or an actual run
|
87
|
-
|
88
|
-
self.
|
89
|
-
|
81
|
+
try:
|
82
|
+
if not self.root_dir_local.is_dir():
|
83
|
+
self._mkdir_local_folder(self.root_dir_local.as_posix())
|
84
|
+
self._mkdir_remote_folder(self.root_dir_remote.as_posix())
|
85
|
+
except Exception as e:
|
86
|
+
error_msg = (
|
87
|
+
f"Could not mkdir {self.root_dir_local.as_posix()} or "
|
88
|
+
f"{self.root_dir_remote.as_posix()}. "
|
89
|
+
f"Original error: {str(e)}."
|
90
|
+
)
|
91
|
+
logger.error(error_msg)
|
92
|
+
raise RuntimeError(error_msg)
|
90
93
|
|
91
94
|
self.shutdown_file = self.root_dir_local / SHUTDOWN_FILENAME
|
92
95
|
self.jobs = {}
|
@@ -178,7 +181,7 @@ class BaseSlurmRunner(BaseRunner):
|
|
178
181
|
fractal_server=__VERSION__,
|
179
182
|
)
|
180
183
|
for task in slurm_job.tasks:
|
181
|
-
#
|
184
|
+
# Write input pickle
|
182
185
|
_args = []
|
183
186
|
_kwargs = dict(
|
184
187
|
parameters=task.parameters,
|
@@ -485,21 +488,14 @@ class BaseSlurmRunner(BaseRunner):
|
|
485
488
|
self._mkdir_remote_folder(folder=workdir_remote.as_posix())
|
486
489
|
logger.info("[submit] Create local/remote folders - END")
|
487
490
|
|
488
|
-
# Add prefix to task_files object
|
489
|
-
task_files.prefix = SUBMIT_PREFIX
|
490
|
-
update_logfile_of_history_unit(
|
491
|
-
history_unit_id=history_unit_id,
|
492
|
-
logfile=task_files.log_file_local,
|
493
|
-
)
|
494
|
-
|
495
491
|
# Submission phase
|
496
492
|
slurm_job = SlurmJob(
|
497
|
-
prefix=
|
493
|
+
prefix=task_files.prefix,
|
498
494
|
workdir_local=workdir_local,
|
499
495
|
workdir_remote=workdir_remote,
|
500
496
|
tasks=[
|
501
497
|
SlurmTask(
|
502
|
-
prefix=
|
498
|
+
prefix=task_files.prefix,
|
503
499
|
index=0,
|
504
500
|
component=task_files.component,
|
505
501
|
parameters=parameters,
|
@@ -575,6 +571,11 @@ class BaseSlurmRunner(BaseRunner):
|
|
575
571
|
task_type: Literal["parallel", "compound", "converter_compound"],
|
576
572
|
config: SlurmConfig,
|
577
573
|
) -> tuple[dict[int, Any], dict[int, BaseException]]:
|
574
|
+
"""
|
575
|
+
Note: `list_parameters`, `list_task_files` and `history_unit_ids`
|
576
|
+
have the same size. For parallel tasks, this is also the number of
|
577
|
+
input images, while for compound tasks these can differ.
|
578
|
+
"""
|
578
579
|
|
579
580
|
if len(self.jobs) > 0:
|
580
581
|
raise RuntimeError(
|
@@ -599,11 +600,7 @@ class BaseSlurmRunner(BaseRunner):
|
|
599
600
|
list_parameters=list_parameters,
|
600
601
|
task_type=task_type,
|
601
602
|
list_task_files=list_task_files,
|
602
|
-
)
|
603
|
-
self.validate_multisubmit_history_unit_ids(
|
604
603
|
history_unit_ids=history_unit_ids,
|
605
|
-
task_type=task_type,
|
606
|
-
list_parameters=list_parameters,
|
607
604
|
)
|
608
605
|
|
609
606
|
logger.info(f"[multisubmit] START, {len(list_parameters)=}")
|
@@ -624,46 +621,28 @@ class BaseSlurmRunner(BaseRunner):
|
|
624
621
|
|
625
622
|
tot_tasks = len(list_parameters)
|
626
623
|
|
627
|
-
#
|
628
|
-
tasks_per_job
|
629
|
-
# Number of parallel components (always known)
|
630
|
-
tot_tasks=tot_tasks,
|
631
|
-
# Optional WorkflowTask attributes:
|
632
|
-
tasks_per_job=config.tasks_per_job,
|
633
|
-
parallel_tasks_per_job=config.parallel_tasks_per_job, # noqa
|
634
|
-
# Task requirements (multiple possible sources):
|
635
|
-
cpus_per_task=config.cpus_per_task,
|
636
|
-
mem_per_task=config.mem_per_task_MB,
|
637
|
-
# Fractal configuration variables (soft/hard limits):
|
638
|
-
target_cpus_per_job=config.target_cpus_per_job,
|
639
|
-
target_mem_per_job=config.target_mem_per_job,
|
640
|
-
target_num_jobs=config.target_num_jobs,
|
641
|
-
max_cpus_per_job=config.max_cpus_per_job,
|
642
|
-
max_mem_per_job=config.max_mem_per_job,
|
643
|
-
max_num_jobs=config.max_num_jobs,
|
644
|
-
)
|
645
|
-
config.parallel_tasks_per_job = parallel_tasks_per_job
|
646
|
-
config.tasks_per_job = tasks_per_job
|
624
|
+
# NOTE: chunking has already taken place in `get_slurm_config`,
|
625
|
+
# so that `config.tasks_per_job` is now set.
|
647
626
|
|
648
627
|
# Divide arguments in batches of `tasks_per_job` tasks each
|
649
628
|
args_batches = []
|
650
|
-
batch_size = tasks_per_job
|
629
|
+
batch_size = config.tasks_per_job
|
651
630
|
for ind_chunk in range(0, tot_tasks, batch_size):
|
652
631
|
args_batches.append(
|
653
632
|
list_parameters[ind_chunk : ind_chunk + batch_size] # noqa
|
654
633
|
)
|
655
|
-
if len(args_batches) != math.ceil(tot_tasks / tasks_per_job):
|
634
|
+
if len(args_batches) != math.ceil(tot_tasks / config.tasks_per_job):
|
656
635
|
raise RuntimeError("Something wrong here while batching tasks")
|
657
636
|
|
658
637
|
# Part 1/3: Iterate over chunks, prepare SlurmJob objects
|
659
638
|
logger.info("[multisubmit] Prepare `SlurmJob`s.")
|
660
639
|
jobs_to_submit = []
|
661
640
|
for ind_batch, chunk in enumerate(args_batches):
|
662
|
-
prefix
|
641
|
+
# Read prefix based on the first task of this batch
|
642
|
+
prefix = list_task_files[ind_batch * batch_size].prefix
|
663
643
|
tasks = []
|
664
644
|
for ind_chunk, parameters in enumerate(chunk):
|
665
645
|
index = (ind_batch * batch_size) + ind_chunk
|
666
|
-
list_task_files[index].prefix = prefix
|
667
646
|
tasks.append(
|
668
647
|
SlurmTask(
|
669
648
|
prefix=prefix,
|
@@ -676,7 +655,6 @@ class BaseSlurmRunner(BaseRunner):
|
|
676
655
|
task_files=list_task_files[index],
|
677
656
|
),
|
678
657
|
)
|
679
|
-
|
680
658
|
jobs_to_submit.append(
|
681
659
|
SlurmJob(
|
682
660
|
prefix=prefix,
|
@@ -697,21 +675,6 @@ class BaseSlurmRunner(BaseRunner):
|
|
697
675
|
slurm_config=config,
|
698
676
|
)
|
699
677
|
|
700
|
-
if task_type == "parallel":
|
701
|
-
# FIXME: replace loop with a `bulk_update_history_unit` function
|
702
|
-
for ind, task_files in enumerate(list_task_files):
|
703
|
-
update_logfile_of_history_unit(
|
704
|
-
history_unit_id=history_unit_ids[ind],
|
705
|
-
logfile=task_files.log_file_local,
|
706
|
-
)
|
707
|
-
else:
|
708
|
-
logger.debug(
|
709
|
-
f"Unclear what logfile to associate to {task_type=} "
|
710
|
-
"within multisubmit (see issue #2382)."
|
711
|
-
)
|
712
|
-
# FIXME: Improve definition for compound tasks
|
713
|
-
pass
|
714
|
-
|
715
678
|
logger.info(f"END submission phase, {self.job_ids=}")
|
716
679
|
|
717
680
|
# FIXME: replace this sleep with a more precise check
|
@@ -2,6 +2,7 @@ from pathlib import Path
|
|
2
2
|
from typing import Literal
|
3
3
|
from typing import Optional
|
4
4
|
|
5
|
+
from ._batching import heuristics
|
5
6
|
from ._slurm_config import _parse_mem_value
|
6
7
|
from ._slurm_config import load_slurm_config_file
|
7
8
|
from ._slurm_config import logger
|
@@ -10,7 +11,7 @@ from ._slurm_config import SlurmConfigError
|
|
10
11
|
from fractal_server.app.models.v2 import WorkflowTaskV2
|
11
12
|
|
12
13
|
|
13
|
-
def
|
14
|
+
def get_slurm_config_internal(
|
14
15
|
wftask: WorkflowTaskV2,
|
15
16
|
which_type: Literal["non_parallel", "parallel"],
|
16
17
|
config_path: Optional[Path] = None,
|
@@ -162,3 +163,39 @@ def get_slurm_config(
|
|
162
163
|
slurm_config = SlurmConfig(**slurm_dict)
|
163
164
|
|
164
165
|
return slurm_config
|
166
|
+
|
167
|
+
|
168
|
+
def get_slurm_config(
|
169
|
+
wftask: WorkflowTaskV2,
|
170
|
+
which_type: Literal["non_parallel", "parallel"],
|
171
|
+
config_path: Optional[Path] = None,
|
172
|
+
tot_tasks: int = 1,
|
173
|
+
) -> SlurmConfig:
|
174
|
+
config = get_slurm_config_internal(
|
175
|
+
wftask,
|
176
|
+
which_type,
|
177
|
+
config_path,
|
178
|
+
)
|
179
|
+
|
180
|
+
# Set/validate parameters for task batching
|
181
|
+
tasks_per_job, parallel_tasks_per_job = heuristics(
|
182
|
+
# Number of parallel components (always known)
|
183
|
+
tot_tasks=tot_tasks,
|
184
|
+
# Optional WorkflowTask attributes:
|
185
|
+
tasks_per_job=config.tasks_per_job,
|
186
|
+
parallel_tasks_per_job=config.parallel_tasks_per_job, # noqa
|
187
|
+
# Task requirements (multiple possible sources):
|
188
|
+
cpus_per_task=config.cpus_per_task,
|
189
|
+
mem_per_task=config.mem_per_task_MB,
|
190
|
+
# Fractal configuration variables (soft/hard limits):
|
191
|
+
target_cpus_per_job=config.target_cpus_per_job,
|
192
|
+
target_mem_per_job=config.target_mem_per_job,
|
193
|
+
target_num_jobs=config.target_num_jobs,
|
194
|
+
max_cpus_per_job=config.max_cpus_per_job,
|
195
|
+
max_mem_per_job=config.max_mem_per_job,
|
196
|
+
max_num_jobs=config.max_num_jobs,
|
197
|
+
)
|
198
|
+
config.parallel_tasks_per_job = parallel_tasks_per_job
|
199
|
+
config.tasks_per_job = tasks_per_job
|
200
|
+
|
201
|
+
return config
|
{fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/task_files.py
RENAMED
@@ -4,6 +4,7 @@ from typing import Union
|
|
4
4
|
|
5
5
|
from pydantic import BaseModel
|
6
6
|
|
7
|
+
from fractal_server.app.runner.components import _index_to_component
|
7
8
|
from fractal_server.string_tools import sanitize_string
|
8
9
|
|
9
10
|
SUBMIT_PREFIX = "non_par"
|
@@ -140,3 +141,31 @@ class TaskFiles(BaseModel):
|
|
140
141
|
metadiff_file_remote=self.metadiff_file_remote,
|
141
142
|
log_file_remote=self.log_file_remote,
|
142
143
|
)
|
144
|
+
|
145
|
+
|
146
|
+
def enrich_task_files_multisubmit(
|
147
|
+
*,
|
148
|
+
tot_tasks: int,
|
149
|
+
batch_size: int,
|
150
|
+
base_task_files: TaskFiles,
|
151
|
+
) -> list[TaskFiles]:
|
152
|
+
"""
|
153
|
+
Expand `TaskFiles` objects with `component` and `prefix`.
|
154
|
+
"""
|
155
|
+
|
156
|
+
new_list_task_files: list[TaskFiles] = []
|
157
|
+
for absolute_index in range(tot_tasks):
|
158
|
+
ind_batch = absolute_index // batch_size
|
159
|
+
new_list_task_files.append(
|
160
|
+
TaskFiles(
|
161
|
+
**base_task_files.model_dump(
|
162
|
+
exclude={
|
163
|
+
"component",
|
164
|
+
"prefix",
|
165
|
+
}
|
166
|
+
),
|
167
|
+
prefix=f"{MULTISUBMIT_PREFIX}-{ind_batch:06d}",
|
168
|
+
component=_index_to_component(absolute_index),
|
169
|
+
)
|
170
|
+
)
|
171
|
+
return new_list_task_files
|
{fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/db_tools.py
RENAMED
@@ -4,7 +4,6 @@ from sqlalchemy.dialects.postgresql import insert as pg_insert
|
|
4
4
|
from sqlalchemy.orm import Session
|
5
5
|
from sqlmodel import update
|
6
6
|
|
7
|
-
from fractal_server.app.db import get_sync_db
|
8
7
|
from fractal_server.app.models.v2 import HistoryImageCache
|
9
8
|
from fractal_server.app.models.v2 import HistoryRun
|
10
9
|
from fractal_server.app.models.v2 import HistoryUnit
|
@@ -59,20 +58,6 @@ def bulk_update_status_of_history_unit(
|
|
59
58
|
db_sync.commit()
|
60
59
|
|
61
60
|
|
62
|
-
def update_logfile_of_history_unit(
|
63
|
-
*,
|
64
|
-
history_unit_id: int,
|
65
|
-
logfile: str,
|
66
|
-
) -> None:
|
67
|
-
with next(get_sync_db()) as db_sync:
|
68
|
-
unit = db_sync.get(HistoryUnit, history_unit_id)
|
69
|
-
if unit is None:
|
70
|
-
raise ValueError(f"HistoryUnit {history_unit_id} not found.")
|
71
|
-
unit.logfile = logfile
|
72
|
-
db_sync.merge(unit)
|
73
|
-
db_sync.commit()
|
74
|
-
|
75
|
-
|
76
61
|
def bulk_upsert_image_cache_fast(
|
77
62
|
*,
|
78
63
|
list_upsert_objects: list[dict[str, Any]],
|
{fractal_server-2.14.0a24 → fractal_server-2.14.0a25}/fractal_server/app/runner/v2/runner.py
RENAMED
@@ -128,10 +128,6 @@ def execute_tasks_v2(
|
|
128
128
|
db.commit()
|
129
129
|
db.refresh(history_run)
|
130
130
|
history_run_id = history_run.id
|
131
|
-
logger.debug(
|
132
|
-
f"Created {history_run_id=}, for "
|
133
|
-
f"{wftask.id=} and {dataset.id=}"
|
134
|
-
)
|
135
131
|
|
136
132
|
# TASK EXECUTION (V2)
|
137
133
|
if task.type in ["non_parallel", "converter_non_parallel"]:
|
@@ -205,9 +201,9 @@ def execute_tasks_v2(
|
|
205
201
|
# Update image list
|
206
202
|
num_new_images = 0
|
207
203
|
current_task_output.check_zarr_urls_are_unique()
|
208
|
-
#
|
209
|
-
#
|
210
|
-
#
|
204
|
+
# NOTE: In principle we could make the task-output processing more
|
205
|
+
# granular, and also associate output-processing failures to history
|
206
|
+
# status.
|
211
207
|
for image_obj in current_task_output.image_list_updates:
|
212
208
|
image = image_obj.model_dump()
|
213
209
|
# Edit existing image
|
@@ -346,7 +342,7 @@ def execute_tasks_v2(
|
|
346
342
|
)
|
347
343
|
|
348
344
|
db.commit()
|
349
|
-
db.close() #
|
345
|
+
db.close() # NOTE: this is needed, but the reason is unclear
|
350
346
|
|
351
347
|
# Create accounting record
|
352
348
|
record = AccountingRecord(
|