HWRF  trunk@4391
srun.py
1 ##@namespace produtil.mpi_impl.srun
2 # Adds SLURM srun support to produtil.run
3 #
4 # This module is part of the mpi_impl package -- see produtil.mpi_impl
5 # for details. This translates produtil.run directives to SLURM srun
6 # commands.
7 
8 import os, logging
10 
11 from .mpi_impl_base import MPIMixed,CMDFGen
12 
13 ##@var srun_path
14 # Path to the srun program
15 srun_path=produtil.fileop.find_exe('srun',raise_missing=False)
16 module_logger=logging.getLogger('lsf_cray_intel')
17 
18 def runsync(logger=None):
19  """!Runs the "sync" command as an exe()."""
20  if logger is None: logger=module_logger
21  sync=produtil.prog.Runner(['/bin/sync'])
22  p=produtil.pipeline.Pipeline(sync,capture=True,logger=logger)
23  version=p.to_string()
24  status=p.poll()
25 def openmp(arg,threads):
26  """!Adds OpenMP support to the provided object
27 
28  @param arg An produtil.prog.Runner or
29  produtil.mpiprog.MPIRanksBase object tree
30  @param threads the number of threads, or threads per rank, an
31  integer"""
32  assert(arg is not None)
33  if threads is not None:
34  arg.threads=threads
35  return arg.env(OMP_NUM_THREADS=threads,KMP_NUM_THREADS=threads,
36  KMP_AFFINITY='scatter')
37  else:
38  del arg.threads
39  return arg
40 
41 def detect():
42  """!Detects whether the SLURM srun command is available by looking
43  for it in the $PATH."""
44  return srun_path is not None
45 
47  """!Does this module represent an MPI implementation? Returns True."""
48  return True
49 
50 def make_bigexe(exe,**kwargs):
51  """!Returns an ImmutableRunner that will run the specified program.
52  @returns an empty list
53  @param exe The executable to run on compute nodes.
54  @param kwargs Ignored."""
55  return produtil.prog.ImmutableRunner([str(exe)],**kwargs)
56 
57 def mpirunner(arg,allranks=False,**kwargs):
58  """!Turns a produtil.mpiprog.MPIRanksBase tree into a produtil.prog.Runner
59  @param arg a tree of produtil.mpiprog.MPIRanksBase objects
60  @param allranks if True, and only one rank is requested by arg, then
61  all MPI ranks will be used
62  @param kwargs passed to produtil.mpi_impl.mpi_impl_base.CMDFGen
63  when mpiserial is in use.
64  @returns a produtil.prog.Runner that will run the selected MPI program"""
65  f=mpirunner_impl(arg,allranks=allranks,**kwargs)
66  logging.getLogger('srun').info("%s => %s"%(repr(arg),repr(f)))
67  return f
68 
69 def mpirunner_impl(arg,allranks=False,**kwargs):
70  """!This is the underlying implementation of mpirunner and should
71  not be called directly."""
72  assert(isinstance(arg,produtil.mpiprog.MPIRanksBase))
73  (serial,parallel)=arg.check_serial()
74  if serial and parallel:
75  raise MPIMixed('Cannot mix serial and parallel MPI ranks in the '
76  'same MPI program.')
77 
78  srun_args=[srun_path,'--export=ALL','--cpu_bind=core','--distribution=block:block']
79 
80  if arg.nranks()==1 and allranks:
81  arglist=[ str(a) for a in arg.to_arglist(
82  pre=srun_args,before=[],between=[])]
83  return produtil.prog.Runner(arglist)
84  elif allranks:
85  raise MPIAllRanksError(
86  "When using allranks=True, you must provide an mpi program "
87  "specification with only one MPI rank (to be duplicated across "
88  "all ranks).")
89  elif serial:
90  lines=[str(a) for a in arg.to_arglist(to_shell=True,expand=True)]
91  if produtil.fileop.find_exe('mpiserial') is None:
92  raise MPISerialMissing(
93  'Attempting to run a serial program via srun but the '
94  'mpiserial program is not in your $PATH.')
95  return produtil.prog.Runner(
96  [srun_path,'-n','%s'%(arg.nranks()),'mpiserial'],
97  prerun=CMDFGen('serialcmdf',lines,**kwargs))
98  else:
99  cmdfile=list()
100  irank=0
101  for rank,count in arg.expand_iter(expand=False):
102  cmdfile.append('%d-%d %s'%(irank,irank+count-1,rank.to_shell()))
103  irank+=count
104  return produtil.prog.Runner(
105  [srun_path,'-n',str(irank),'--multi-prog'],
106  prerun=CMDFGen('srun_cmdfile',cmdfile,filename_arg=True,**kwargs))
107 
This module provides a set of utility functions to do filesystem operations.
Definition: fileop.py:1
def mpirunner_impl(arg, allranks=False, kwargs)
This is the underlying implementation of mpirunner and should not be called directly.
Definition: srun.py:69
This class is a wrapper around launch and manage.
Definition: pipeline.py:564
def make_bigexe(exe, kwargs)
Returns an ImmutableRunner that will run the specified program.
Definition: srun.py:50
def mpirunner(arg, allranks=False, kwargs)
Turns a produtil.mpiprog.MPIRanksBase tree into a produtil.prog.Runner.
Definition: srun.py:57
def openmp(arg, threads)
Adds OpenMP support to the provided object.
Definition: srun.py:25
Implements the produtil.run: provides the object tree for representing shell commands.
Definition: prog.py:1
def runsync
Runs the "sync" command as an exe().
Definition: srun.py:18
def can_run_mpi()
Does this module represent an MPI implementation? Returns True.
Definition: srun.py:46
Object structure for describing MPI programs.
Definition: mpiprog.py:1
This is the abstract superclass of all classes that represent one or more MPI ranks, including MPI ranks that are actually serial programs.
Definition: mpiprog.py:68
Represents a single stage of a pipeline to execute.
Definition: prog.py:299
def find_exe
Searches the $PATH or a specified iterable of directory names to find an executable file with the giv...
Definition: fileop.py:573
Internal module that launches and monitors processes.
Definition: pipeline.py:1
An copy-on-write version of Runner.
Definition: prog.py:884
def detect()
Detects whether the SLURM srun command is available by looking for it in the $PATH.
Definition: srun.py:41