Coverage for melissa/launcher/parser.py: 22%
80 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-10 22:25 +0100
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-10 22:25 +0100
2import logging
3import os
4from melissa.utility import networking
5import socket
6from melissa.scheduler.slurm import SlurmScheduler
7from melissa.scheduler.slurm_global import SlurmGlobalScheduler
8from melissa.scheduler.slurm_semiglobal import SlurmSemiGlobalScheduler
9from melissa.scheduler.slurm_openmpi import OpenmpiSlurmScheduler
10from melissa.scheduler.oar import OarScheduler
11from melissa.scheduler.oar_hybrid import OarHybridScheduler
12from melissa.scheduler.openmpi import OpenMpiScheduler
13from typing import Tuple
14import shutil
16logger = logging.getLogger(__name__)
19def homogenize_arguments(config_path: str) -> Tuple[str, str]:
21 head_tail = os.path.split(config_path)
22 conf_name = head_tail[1]
23 if config_path is not None and config_path.startswith("/"):
24 project_dir = head_tail[0]
25 logger.info(f"Using absolute path for project_dir {project_dir}")
26 else:
27 project_dir = f"{os.getcwd()}/{head_tail[0]}"
28 logger.info(f"Found relative path, new project_dir {project_dir}")
30 if ".json" in conf_name:
31 conf_name = os.path.splitext(conf_name)[0]
33 return conf_name, project_dir
36def check_protocol_choice(lconfig: dict):
37 # check protocol choice
38 protocols = networking.get_available_protocols()
39 if protocols == []:
40 return "no supported communication protocols available"
41 if lconfig['protocol'] == "sctp":
42 if socket.IPPROTO_SCTP not in protocols:
43 return "SCTP unavailable"
44 protocol = socket.IPPROTO_SCTP
45 elif lconfig['protocol'] == "tcp":
46 if socket.IPPROTO_TCP not in protocols:
47 return "TCP unavailable"
48 protocol = socket.IPPROTO_TCP
49 elif lconfig['protocol'] == "auto":
50 protocol = protocols[0]
51 del protocols
53 logger.info(
54 f"using protocol {networking.protocol2str(protocol)} "
55 "for server/launcher communication"
56 )
58 return protocol
61def setup_scheduler(lconfig: dict):
62 # FIXME: the architecture here is quite difficult to debug for mypy (see type: ignore).
63 if lconfig['scheduler'] == "oar":
64 scheduler_impl = OarScheduler
65 sched_client_cmd = "mpirun"
66 sched_server_cmd = "mpirun"
67 elif lconfig['scheduler'] == "oar-hybrid":
68 scheduler_impl = OarHybridScheduler # type: ignore
69 sched_client_cmd = "mpirun"
70 sched_server_cmd = "mpirun"
71 elif lconfig['scheduler'] == "openmpi":
72 scheduler_impl = OpenMpiScheduler # type: ignore
73 sched_client_cmd = "mpirun"
74 sched_server_cmd = "mpirun"
75 elif lconfig['scheduler'] == "slurm":
76 scheduler_impl = SlurmScheduler # type: ignore
77 sched_client_cmd = "srun"
78 sched_server_cmd = "srun"
79 elif lconfig['scheduler'] == "slurm-global":
80 scheduler_impl = SlurmGlobalScheduler # type: ignore
81 sched_client_cmd = "srun"
82 sched_server_cmd = "srun"
83 elif lconfig['scheduler'] == "slurm-semiglobal":
84 scheduler_impl = SlurmSemiGlobalScheduler # type: ignore
85 sched_client_cmd = "srun"
86 sched_server_cmd = "srun"
87 elif lconfig['scheduler'] == "slurm-openmpi":
88 scheduler_impl = OpenmpiSlurmScheduler # type: ignore
89 sched_client_cmd = "mpirun"
90 sched_server_cmd = "mpirun"
91 else:
92 raise RuntimeError("BUG unknown scheduler {:s}".format(lconfig['scheduler']))
94 # set up the scheduler command (e.g. mpirun, srun)
95 sched_client_cmd = lconfig.get("scheduler_client_command", sched_client_cmd)
96 sched_server_cmd = lconfig.get("scheduler_server_command", sched_server_cmd)
98 return scheduler_impl, sched_client_cmd, sched_server_cmd
101def locate_executable(path_raw: str) -> str:
102 maybe_path = shutil.which(path_raw)
103 if maybe_path is None:
104 raise RuntimeError(f"executable {path_raw} not found")
105 return os.path.abspath(maybe_path)