From 579c739ae9d422cc37bb0d0a825170be13ce8496 Mon Sep 17 00:00:00 2001 From: Tim Jenness Date: Tue, 7 Jan 2025 15:43:51 -0700 Subject: [PATCH] Work around change to SlurmProvider API in parsl v2024.12.02 The two alternate SlurmProvider calls are needed to help mypy which can't handle kwargs with and without move_files. --- pyproject.toml | 1 + python/lsst/ctrl/bps/parsl/parsl_features.py | 38 +++++++++++++++++ python/lsst/ctrl/bps/parsl/sites/ccin2p3.py | 43 ++++++++++++++++++-- requirements.txt | 1 + 4 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 python/lsst/ctrl/bps/parsl/parsl_features.py diff --git a/pyproject.toml b/pyproject.toml index 838db6b..7e58050 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ keywords = ["lsst"] dependencies = [ "lsst-ctrl-bps", "parsl >= 2024.03.04", + "packaging", ] dynamic = ["version"] diff --git a/python/lsst/ctrl/bps/parsl/parsl_features.py b/python/lsst/ctrl/bps/parsl/parsl_features.py new file mode 100644 index 0000000..ac99d51 --- /dev/null +++ b/python/lsst/ctrl/bps/parsl/parsl_features.py @@ -0,0 +1,38 @@ +# This file is part of ctrl_bps_parsl. +# +# Developed for the LSST Data Management System. +# This product includes software developed by the LSST Project +# (https://www.lsst.org). +# See the COPYRIGHT file at the top-level directory of this distribution +# for details of code ownership. +# +# This software is dual licensed under the GNU General Public License and also +# under a 3-clause BSD license. Recipients may choose which of these licenses +# to use; please see the files gpl-3.0.txt and/or bsd_license.txt, +# respectively. If you choose the GPL option then the following text applies +# (but note that there is still no warranty even if you opt for BSD instead): +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +__all__ = [ + "SLURM_PROVIDER_HAS_MOVE_FILES", +] + +import importlib.metadata + +from packaging.version import Version + +_PARSL_VERSION = Version(importlib.metadata.version("parsl")) + +SLURM_PROVIDER_HAS_MOVE_FILES = _PARSL_VERSION < Version("2024.12.02") diff --git a/python/lsst/ctrl/bps/parsl/sites/ccin2p3.py b/python/lsst/ctrl/bps/parsl/sites/ccin2p3.py index 0b9cc64..815567a 100644 --- a/python/lsst/ctrl/bps/parsl/sites/ccin2p3.py +++ b/python/lsst/ctrl/bps/parsl/sites/ccin2p3.py @@ -7,6 +7,7 @@ from parsl.providers import SlurmProvider from ..configuration import get_bps_config_value +from ..parsl_features import SLURM_PROVIDER_HAS_MOVE_FILES from ..site import SiteConfig if TYPE_CHECKING: @@ -186,9 +187,39 @@ def get_executors(self) -> list[ParslExecutor]: options = f"#SBATCH {' '.join(opt for opt in scheduler_options)}" if scheduler_options else "" - executor = HighThroughputExecutor( - label, - provider=SlurmProvider( + if not SLURM_PROVIDER_HAS_MOVE_FILES: + provider = SlurmProvider( + # Slurm partition to request blocks from. + partition=slot["partition"], + # Slurm account to which to charge resources used by the + # job. + account=self._account, + # Nodes to provision per block (1 block = 1 CPU core). + nodes_per_block=1, + # Number of CPU cores to provision per node. + cores_per_node=1, + # Memory per node (GB) for each Slurm job. + mem_per_node=slot["memory"], + # Initial number of blocks. + init_blocks=0, + # Minimum number of blocks to maintain. + min_blocks=0, + # Maximum number of blocks to maintain. + max_blocks=slot["max_blocks"], + # Time limit for each Slurm job. + walltime=slot["walltime"], + # '#SBATCH' directives to prepend to the Slurm submission + # script. + scheduler_options=options, + # Set the number of file descriptors and processes to + # the maximum allowed. + worker_init="ulimit -n hard && ulimit -u hard", + # Requests nodes which are not shared with other running + # jobs. + exclusive=False, + ) + else: + provider = SlurmProvider( # Slurm partition to request blocks from. partition=slot["partition"], # Slurm account to which to charge resources used by the @@ -219,7 +250,11 @@ def get_executors(self) -> list[ParslExecutor]: exclusive=False, # Should files be moved by Parsl? move_files=False, - ), + ) + + executor = HighThroughputExecutor( + label, + provider, # Address to connect to the main Parsl process. address=self.get_address(), # GB of memory required per worker. If specified the node diff --git a/requirements.txt b/requirements.txt index a0da108..5809999 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ parsl >= 2024.03.04 lsst-ctrl-bps @ git+https://github.com/lsst/ctrl_bps@main +packaging