1111import aiofiles
1212
1313if TYPE_CHECKING :
14+ from xtl .jobs .config2 import BatchJobConfig
1415 from xtl .config .settings import DependencySettings
1516from xtl .common .compatibility import PY310_OR_LESS , XTL_COMPUTE_SITE
1617from xtl .jobs .batchfiles import BatchFile , BatchFileStatus
@@ -191,6 +192,12 @@ def execute_command(command: Sequence[str], timeout: int = 20) \
191192 async def execute_batch (self , batch : BatchFile , ** kwargs ):
192193 ...
193194
195+ @staticmethod
196+ def _prepare_shebang (shell : ShellType ) -> str :
197+ if shell .shebang :
198+ return f'{ shell .shebang } { shell .new_line_char } '
199+ return ''
200+
194201
195202class LocalSite (BaseComputeSite ):
196203 """
@@ -202,7 +209,8 @@ def prepare_preamble(self, dependencies: Iterable[DependencySettings | str]
202209 | DependencySettings | str
203210 | None ,
204211 shell : ShellType ) -> str :
205- return self .policy .intercept_preamble ('' ) if self .policy else ''
212+ preamble = self ._prepare_shebang (shell )
213+ return self .policy .intercept_preamble (preamble ) if self .policy else preamble
206214
207215 def prepare_command (self , command : str ) -> str :
208216 return self .policy .intercept_command (command ) if self .policy else command
@@ -361,7 +369,6 @@ async def _log_stream_to_file(stream: asyncio.StreamReader,
361369 await f .close ()
362370
363371
364-
365372class ModulesSite (LocalSite ):
366373 """
367374 A compute site that uses
@@ -400,6 +407,16 @@ def _load_modules(modules: str | Iterable[str], shell: ShellType) -> str:
400407 cmd = f'call { cmd } '
401408 return cmd
402409
410+ def _prepare_modules_preamble (self , dependencies : Iterable [DependencySettings | str ]
411+ | DependencySettings | str
412+ | None ,
413+ shell : ShellType ) -> str :
414+ preamble = self ._purge_modules (shell = shell )
415+ for dep in self .resolve_dependencies (dependencies ):
416+ if dep .modules :
417+ preamble += self ._load_modules (modules = dep .modules , shell = shell )
418+ return preamble
419+
403420 def prepare_preamble (self , dependencies : Iterable [DependencySettings | str ]
404421 | DependencySettings | str
405422 | None ,
@@ -417,10 +434,9 @@ def prepare_preamble(self, dependencies: Iterable[DependencySettings | str]
417434 :param shell: The shell type to generate the commands for.
418435 :return: The preamble string.
419436 """
420- preamble = self ._purge_modules (shell = shell )
421- for dep in self .resolve_dependencies (dependencies ):
422- if dep .modules :
423- preamble += self ._load_modules (modules = dep .modules , shell = shell )
437+ preamble = self ._prepare_shebang (shell )
438+ preamble += self ._prepare_modules_preamble (dependencies = dependencies ,
439+ shell = shell )
424440 return self .policy .intercept_preamble (preamble ) if self .policy else preamble
425441
426442 def check_dependencies (self , dependencies : Iterable [DependencySettings | str ]
@@ -506,12 +522,28 @@ class SlurmSite(SchedulerSite, ABC):
506522 Abstract base class for compute sites that utilize the
507523 `SLURM <https://slurm.schedmd.com/>`_ job scheduler.
508524 """
525+ _default_shell = Shell .BASH
526+ _supported_shells = frozenset ([Shell .BASH ])
509527
510- def prepare_preamble (self , dependencies : Iterable [DependencySettings | str ]
511- | DependencySettings | str
512- | None ,
513- shell : ShellType ) -> str :
514- # SBATCH preamble
528+ @staticmethod
529+ def _prepare_slurm_preamble (shell : ShellType ,
530+ config : BatchJobConfig | dict = None ) -> str :
531+ from xtl .jobs .config2 import BatchJobConfig
532+
533+ args = []
534+ if config :
535+ if not isinstance (config , BatchJobConfig ):
536+ config = BatchJobConfig (** config )
537+ args .extend (config .to_slurm ())
538+
539+ if args :
540+ nl = shell .new_line_char
541+ return nl .join (f'#SBATCH { arg } ' for arg in args ) + nl
542+ return ''
543+
544+ async def validate_submission (self , batch : BatchFile , ** kwargs ) -> bool :
545+ # Run `sbatch --test-only <batchfile>` to check if allocation is possible
546+ # and check the exit code
515547 raise NotImplementedError ()
516548
517549 async def schedule_batch (self , batch : BatchFile , ** kwargs ) -> str :
@@ -536,12 +568,14 @@ class SlurmLocalSite(SlurmSite, LocalSite):
536568 def prepare_preamble (self , dependencies : Iterable [DependencySettings | str ]
537569 | DependencySettings | str
538570 | None ,
539- shell : ShellType ) -> str :
540- slurm_preamble = SlurmSite .prepare_preamble (self , dependencies = dependencies ,
541- shell = shell )
542- local_preamble = LocalSite .prepare_preamble (self , dependencies = dependencies ,
543- shell = shell )
544- raise NotImplementedError ()
571+ shell : ShellType ,
572+ config : BatchJobConfig | dict = None ,
573+ ** kwargs ) -> str :
574+ preamble = self ._prepare_shebang (shell = shell )
575+ # SBATCH preamble
576+ if config :
577+ preamble += self ._prepare_slurm_preamble (shell = shell , config = config )
578+ return self .policy .intercept_preamble (preamble ) if self .policy else preamble
545579
546580
547581class SlurmModulesSite (SlurmSite , ModulesSite ):
@@ -554,12 +588,17 @@ class SlurmModulesSite(SlurmSite, ModulesSite):
554588 def prepare_preamble (self , dependencies : Iterable [DependencySettings | str ]
555589 | DependencySettings | str
556590 | None ,
557- shell : ShellType ) -> str :
558- slurm_preamble = SlurmSite .prepare_preamble (self , dependencies = dependencies ,
559- shell = shell )
560- modules_preamble = ModulesSite .prepare_preamble (self , dependencies = dependencies ,
561- shell = shell )
562- raise NotImplementedError ()
591+ shell : ShellType ,
592+ config : BatchJobConfig | dict = None ,
593+ ** kwargs ) -> str :
594+ preamble = self ._prepare_shebang (shell = shell )
595+ # SBATCH preamble
596+ if config :
597+ preamble += self ._prepare_slurm_preamble (shell = shell , config = config )
598+ # Modules preamble
599+ preamble += self ._prepare_modules_preamble (dependencies = dependencies ,
600+ shell = shell )
601+ return self .policy .intercept_preamble (preamble ) if self .policy else preamble
563602
564603
565604class VirtualizationSite (BaseComputeSite , ABC ): ...
0 commit comments