U  ge@sddlZddlZddlZddlZddlZddlZddlmZm Z ej j dddZ e dZdddZd d Zd d Zd dZddZdddZdddZdS)N)MPIMixedCMDFGenmpiexecF) raise_missingcCs@|dkr t}tjdg}tjj|d|d}|}|}dS)z%!Runs the "sync" command as an exe().Nz /bin/syncT)capturelogger) module_loggerprodutilprogRunnerpipelinePipeline to_stringpoll)rsyncpversionstatusrF/lfs/h1/ops/prod/packages/hmon.v3.2.7/ush/produtil/mpi_impl/mpiexec.pyrunsyncs rc Cs|dkrXz&tjdd}t|}|dkr,|}Wn(tttfk rV}zW5d}~XYnX|dkrtjdd}t|}td|d}|dkstt|}t |dr|j ||dd }||_ |S) z!Adds OpenMP support to the provided object @param arg An produtil.prog.Runner or produtil.mpiprog.MPIRanksBase object tree @param threads the number of threads, or threads per rank, an integerNOMP_NUM_THREADSrZPRODUTIL_RUN_NODESIZEZ24renvrKMP_NUM_THREADSZMKL_NUM_THREADS) osenvirongetintKeyError TypeError ValueErrormaxAssertionErrorhasattrrthreads)argr'ZonteZnodesizerrropenmp#s*  r*cCstdk S)zk!Detects whether the MPICH mpi implementation is available by looking for the mpiexec program in $PATH.N) mpiexec_pathrrrrdetectAsr,cCsdS)z@!Does this module represent an MPI implementation? Returns True.Trrrrr can_run_mpiFsr-cKstjjt|gf|S)z!Returns an ImmutableRunner that will run the specified program. @returns an empty list @param exe The executable to run on compute nodes. @param kwargs Ignored.)r r ImmutableRunnerstr)exekwargsrrr make_bigexeJsr2cKs@|dkr t}t|f||d|}|dt|t|f|S)N)allranksrzmpirunner: %s => %s)r mpirunner2inforepr)r(r3rr1mrrr mpirunnerQs r8c Kszt|tjjst|\}}|r.|r.tdg}|ddrH|dd}| dkr|rdd|j t g|d t j d gd gd D}tj|}n|rtd n|rtj|}dd|j dddD}tjddkrtdtjjt g|d d| dgtd|f|d}n2dd|j t g|d dgd gd D}tj|}|j} | dk rv| dkrv|j| | dd}|S)a!Turns a produtil.mpiprog.MPIRanksBase tree into a produtil.prog.Runner @param arg a tree of produtil.mpiprog.MPIRanksBase objects @param allranks if True, and only one rank is requested by arg, then all MPI ranks will be used @param kwargs passed to produtil.mpi_impl.mpi_impl_base.CMDFGen when mpiserial is in use. @returns a produtil.prog.Runner that will run the selected MPI program @warning Assumes the TOTAL_TASKS environment variable is set if allranks=TruezACannot mix serial and parallel MPI ranks in the same MPI program.label_ioFz -prepend-rankNrcSsg|]}|qSrr.0arrr oszmpirunner2..z-np TOTAL_TASKS:)prebeforebetweenzWhen using allranks=True, you must provide an mpi program specification with only one MPI rank (to be duplicated across all ranks).cSsg|]}|qSrrr:rrrr={sT)to_shellexpand mpiserialz^Attempting to run a serial program via mpiexec but the mpiserial program is not in your $PATH.z%s serialcmdf)preruncSsg|]}|qSrrr:rrrr=sz%(n)dr) isinstancer mpiprog MPIRanksBaser% check_serialrrappendnranks to_arglistr+rrr r MPIAllRanksErrorcollapsefileopfind_exeMPISerialMissingrr'r) r(r3r1serialparallel extra_argsrunnerarglistlinesr'rrrr4XsV            r4)N)FN)F)rloggingprodutil.fileopr produtil.progprodutil.mpiprogprodutil.pipeline mpi_impl_baserrrQrRr+ getLoggerr rr*r,r-r2r8r4rrrrs