diff --git a/lmn/cli/_config_loader.py b/lmn/cli/_config_loader.py index b15bf99..1fe138b 100644 --- a/lmn/cli/_config_loader.py +++ b/lmn/cli/_config_loader.py @@ -124,6 +124,7 @@ def load_config(machine_name: str): # Parse special config params preset_conf = { 'slurm-configs': config.get('slurm-configs', {}), + 'pbs-configs': config.get('pbs-configs', {}), 'docker-images': config.get('docker-images', {}), } diff --git a/lmn/cli/_utils.py b/lmn/cli/_utils.py index aee1883..711ebc3 100644 --- a/lmn/cli/_utils.py +++ b/lmn/cli/_utils.py @@ -42,7 +42,6 @@ def rsync(source_dir: Union[Path, str], target_dir: Union[Path, str], remote_con cmd = f"rsync {options_str} {remote_conf.base_uri}:{source_dir} {target_dir}" else: cmd = f"rsync {options_str} {source_dir} {remote_conf.base_uri}:{target_dir}" - logger.debug(f'running command: {cmd}') if not dry_run: run_cmd(cmd, shell=True) diff --git a/lmn/cli/run.py b/lmn/cli/run.py index 5032df8..a6d477f 100644 --- a/lmn/cli/run.py +++ b/lmn/cli/run.py @@ -370,7 +370,7 @@ def handler_scheduler( logger.error(f'Slurm config preset: "{parsed.sconf}" cannot be found in "slurm-configs" or is empty.') import sys; sys.exit(1) scheduler_conf = SlurmConfig(**_sconf) - logger.debug(f'Using preset: {parsed.sconf}') + logger.info(f'Using Slurm preset: [{parsed.sconf}]') runner = SlurmRunner(ssh_client, lmndirs) @@ -381,24 +381,25 @@ def handler_scheduler( raise ValueError('Configuration must have an entry for "pbs" to use PBS mode.') # Create PBSConfig object - if parsed.sconf is None: + if parsed.pbsconf is None: scheduler_conf = machine.parsed_conf.pbs else: # Try to load from the slurm conf presets logger.debug('parsed.sconf is specified. Loading custom preset conf.') - _pconf = preset.get('pbs-configs', {}).get(parsed.pconf, {}) + _pconf = preset.get('pbs-configs', {}).get(parsed.pbsconf, {}) if not _pconf: - logger.error(f'PBS config preset: "{parsed.pconf}" cannot be found in "pbs-configs" or is empty.') + logger.error(f'PBS config preset: "{parsed.pbsconf}" cannot be found in "pbs-configs" or is empty.') import sys; sys.exit(1) scheduler_conf = PBSConfig(**_pconf) - logger.debug(f'Using preset: {parsed.pconf}') + logger.info(f'Using PBS preset: [{parsed.pbsconf}]') runner = PBSRunner(ssh_client, lmndirs) else: - raise ValueError(f'Unrecognized mode: {mode}') + logger.error(f'Unrecognized mode: {mode}') + import sys; sys.exit(1) - # NOTE: Slurm seems to be fine with duplicated name. (How about PBS?) + # NOTE: Slurm / PBS seem to be fine with duplicated name. proj_name_maxlen = 15 rand_num = random.randint(0, 100) job_name = f'lmn-{project.name[:proj_name_maxlen]}-{randomname.get_name()}-{rand_num}' @@ -407,7 +408,7 @@ def handler_scheduler( scheduler_conf.job_name = job_name if run_opt.force: - logger.warn("`-f / --force` option has no effect in slurm mode") + logger.warn("`-f / --force` option has no effect in Slurm / PBS mode") # Specify job name name = f'{machine.user}-lmn-{project.name}' diff --git a/lmn/runner.py b/lmn/runner.py index 394256d..cf2e039 100644 --- a/lmn/runner.py +++ b/lmn/runner.py @@ -371,7 +371,7 @@ def exec(self, cmd: str, relative_workdir, conf: PBSConfig, env: Optional[dict] # NOTE: without `-S` option, `bash -i` will be considered a single command and will end up in command not found. # Reference: https://unix.stackexchange.com/a/657774/556831 # '#!/usr/bin/env -S bash -i' if interactive else '#!/usr/bin/env bash', - f'#!/bin/{s.shell} -i', # ^ This only works with a recent version of coreutils (8.30) and that cannot be taken for granted. + f'#!/bin/{conf.shell} -i', # ^ This only works with a recent version of coreutils (8.30) and that cannot be taken for granted. *slurm_options, *exports, cmd diff --git a/lmn/scheduler/pbs.py b/lmn/scheduler/pbs.py index 9ff20e0..5979fff 100644 --- a/lmn/scheduler/pbs.py +++ b/lmn/scheduler/pbs.py @@ -8,7 +8,7 @@ class PBSConfig(BaseModel): job_name: str = 'default-job-name' # To be filled account: str = 'SuperBERT' # Account string queue: str = 'debug' # debug, small, medium, large, etc. (Check `qstat -q`) - shell: str = '/usr/bin/env bash' + shell: str = 'bash' # It will be fed to `/bin/{shell}` template filesystems: str = 'home:grand' # Request access to /home and /grand directories select: int = 1 # Request 1 node place: str = 'free' # scatter, pack (default): specify how to distribute allocations (I believe it only matters for multi-node allocation ?)