o
    QpÆeÉ ã                   @   s0  d Z ddlZddlZddlZddlZddlZddlZddlZddlZ	ddl
Z
ddlZddlmZ ddlmZmZ ddlZddlm  mZ ddlmZ ddlZejded dd	„ Zd
d„ ZG dd„ dƒZdd„ Zdd„ Zdd„ Ze dkr”eej!dd… ƒZ"ee"ƒZ#e#j$e"j%d e"j&du r–e# '¡ Z(dS dS dS )a‡  
Functions related to batch job submission.
Should be run with a file containing jobs to submit as a batch.
Optional parameters for job submission are, --memory, --walltime, and --queuename.
Generates job scripts, runs them, and waits for output files to be written before exiting.


This script has functions to support submitting two different job types: a script as a job or a batch file consisting of
multiple parallel tasks. submitting a script as a job is done calling the function: submit_script
However submitting a batch file (calling submit_batch_jobs) can be done in 5 different ways with or without launcher.
Two environmental variables have to be set: JOB_SUBMISSION_SCHEME and QUEUENAME  (set in '~/accounts/platforms_defaults.bash')
QUEUENAME has defaults based on platforms. comment/uncomment or introduce a new one
JOB_SUBMISSION_SCHEME: it can have one of these options:

singleTask                     ---> submit each task of a batch file separately in a job
multiTask_singleNode           ---> distribute tasks of a batch file into jobs with one node
multiTask_multiNode            ---> submit tasks of a batch file in one job with required number of nodes
launcher_multiTask_singleNode  ---> distribute tasks of a batch file into jobs with one node, submit with launcher
launcher_multiTask_multiNode   ---> submit tasks of a batch file in one job with required number of nodes using launcher

é    N)Úmessage_rsmas)Úqueue_config_fileÚsupported_platforms)ÚdatetimeÚignore)Úcategoryc                  C   s  t jt jd} |  dd¡}|jdtdd |jddtd	d
d |jddddd |jddddd |jddddd |jdddddd |jdd td!d"d |jd#d$td%d&d'd( |jd)d*td+d,d-d. |jd/d0d1d2d3 |jd4d5d1d6d3 |jd7d8d1d9d3 | S ):a  
    Creates an argument parser for parsing parameters for batch job submission.
    Required parameter: file to batch create
    Optional parameters: template file, memory, walltime, and queue name
    :return: ArgumentParser object for parsing command line batch job submission
    )Úformatter_classz
Input FilezFile/Dataset to displayÚfilezThe file to batch create)ÚtypeÚhelpz
--templateÚcustom_template_fileztemplate filez&custom template with option settings.
)Údestr
   Úmetavarr   z--memoryÚmemoryzMEMORY (KB)z4Amount of memory to allocate, specified in kilobytes)r   r   r   z
--walltimeÚ	wall_timezWALLTIME (HH:MM)z+Amount of wall time to use, in HH:MM formatz--queueÚqueueÚQUEUEzName of queue to submit job toz--outdirÚout_dirÚ	run_filesZOUTDIRzoutput directory for run files)r   Údefaultr   r   z--numMemoryUnitsÚnum_memory_unitsznumber of memory unitszxnumber of memory units to calculate walltime, for ISCE workflow:number of bursts, for Miaplpy workflow:number of patchesz	--numDataÚnum_dataé   znumber of dataz;number of data (interferogram or slc) to calculate walltime)r   r
   r   r   r   z--distributeÚ
distributeú+NzFiles to be copied to /tmp)r   r
   Únargsr   r   z--writeonlyÚ	writeonlyÚ
store_truez"Write job files without submitting)r   Úactionr   z--remoraÚremoraz!use remora to get job informationz--tmpÚcopy_to_tmpz!write to run_files_tmp/ directory)ÚargparseÚArgumentParserÚRawTextHelpFormatterÚadd_argument_groupÚadd_argumentÚstrÚint)ÚparserÚgroup© r*   ú=/home/exouser/operations/rsmas_insar/minsar/job_submission.pyÚcreate_argument_parser.   s:   
ÿ
ÿ
ÿÿÿÿÿr,   c                 C   s   t ƒ }| | ¡}zt d¡}W n   t ¡ }Y tj |j¡|_tj ||j 	tj 
|¡¡d  d¡d ¡|_d|jv rFtj |j|j¡|_|S )z·
    Parses command line arguments into namespace.
    :param args: Arguments to parse
    :return: Namespace with submission parameters (from command line arguments or defaults)
    ZSCRATCHr   ú/r   )r,   Ú
parse_argsÚosÚgetenvÚgetcwdÚpathÚabspathr	   ÚjoinÚrsplitÚbasenameÚsplitÚwork_dirr   )Úargsr(   Z
job_paramsZscratch_dirr*   r*   r+   Úparse_argumentsO   s   

 ÿ
r:   c                   @   sŽ   e Zd ZdZdd„ Zd!dd„Zd"dd	„Zd#d
d„Zdd„ Zd$dd„Z	d%dd„Z
d&dd„Zd'dd„Zd(dd„Zd)dd„Zd'dd„Zd$dd „ZdS )*Ú
JOB_SUBMITz<
        A class representing the job submission object
    c              
   C   s®  |j  ¡ D ]}t| ||j | ƒ qd|v r)|jdkr)tj t d¡d¡| _d| _ntj t d¡d¡| _d| _t	|ƒ\	| _
| _| _| _| _| _| _| _| _d| _d|vsW|jsZd | _d	|vsa|jsdd | _d
|vsk|jsnd | _d|vsu|jsy| j| _d|vr€d| _d|vr‡d | _d|vrŽd | _|j| _d | _d | _d | _d|vs¢|js¥d| _d| _ g | _!zt" "| j#d ¡d }tj $|¡|j%|jd < W n   t&d '| j#d ¡ƒ Y || _(d S )NÚprefixÚstripmapÚ
ISCE_STACKÚstripmapStackÚ	topsStackÚtopsr   r   r   r   r   r   Ú.r   r    Úreserve_nodeTz/DEM/*.wgs84r   zStack.demDirzDEM does not exist in {}z/DEM))Ú__dict__ÚkeysÚsetattrr<   r/   r2   r4   r0   Ú
stack_pathÚset_job_queue_valuesÚsubmission_schemeÚplatform_nameÚ	schedulerÚ
queue_nameÚnumber_of_cores_per_nodeÚnumber_of_threads_per_coreÚmax_jobs_per_workflowÚmax_memory_per_nodeÚwall_time_factorÚ!number_of_parallel_tasks_per_noder   r   r   r   r   r   r    r   Údefault_memoryÚdefault_wall_timeÚdefault_num_threadsrC   Úemail_notifÚ	job_filesÚglobr8   ÚdirnameÚtemplateÚprintÚformatÚinps)Úselfr]   ÚkZdem_filer*   r*   r+   Ú__init__o   sP   þ
zJOB_SUBMIT.__init__NÚFalsec                 C   s¾   t j | j¡st j | j¡rt  | j¡ t  | j¡ |dur!|| _d dd„ |dd… D ƒ¡}| j	|dd t j | jd 
|¡¡g| _| j|||| j| jd	 |d
kr]| j| j| jdd dS )aŸ  
        Submits a single script as a job. (compare to submit_batch_jobs for several tasks given in run_file)
        :param job_name: Name of job.
        :param job_file_name: Name of job file.
        :param argv: Command line arguments for running job.
        :param email_notif: If email notifications should be on or not. Defaults to true.
        :return job number of the script that was submitted
        Nú c                 s   s    | ]	}|d kr|V  qdS )z--submitNr*   )Ú.0Úflagr*   r*   r+   Ú	<genexpr>²   s   € z+JOB_SUBMIT.submit_script.<locals>.<genexpr>r   Úscript©Újob_typeú{0}.job©r8   Únumber_of_nodesra   F)r8   Ú	wait_flag)r/   r2   Úisdirr8   ÚisfileÚremoveÚmakedirsrV   r4   Úget_memory_walltimer\   rW   Úwrite_single_job_filerC   Úsubmit_and_check_job_status)r^   Újob_nameÚjob_file_nameÚargvrV   Z	writeOnlyÚcommand_liner*   r*   r+   Úsubmit_script    s   	ÿzJOB_SUBMIT.submit_scriptc              	   C   sÒ  |du r| j }|dur|| _g | _| jtv rç| jdkrd| _| j|dd dj| j	|| j
| jd}| jr8|d7 }|durY|d	7 }t|tƒrR|D ]	}|d
 |¡7 }qGn|d
 |¡7 }t | j|¡ t|dƒ}| ¡ }t|ƒ}	W d  ƒ n1 sxw   Y  tt |	t| jƒ | j| j  ¡ƒ}
|dur| j| | _|
|7 }
d| jv r¬| j||
|d dS d| jv rØ|d }tj  |¡}| j!||t|ƒ|
| j
d}| j "| j#||||
|d¡ dS d| jv rç| j$|||
||d dS )zã
        creates jobs based on scheduler
        :param batch_file: batch job name
        :param email_notif: If email notifications should be on or not. Defaults to true.
        :return: True if running on a cluster
        Nr=   é   Úbatchrg   zRjob_submission.py --template {t} {a} --outdir {b} --numMemoryUnits {c} --writeonly)ÚtÚaÚbÚcz --tmpz --distributeú {}ÚrZ
singleTask©r   ZmultiTask_multiNodeZ_0©Únumber_of_tasksrk   r8   ©Ú
batch_filerk   r   ZmultiTask_singleNode)r   Únum_cores_per_task)%r	   rV   rW   rJ   r   r<   r   rq   r\   r   r   r    Ú
isinstanceÚlistr   Úlogr8   ÚopenÚ	readlinesÚlenr'   ÚnpÚceilÚfloatrU   rM   rN   rR   rI   Úwrite_batch_singletask_jobsr/   r2   r6   Úget_job_file_linesÚappendÚadd_tasks_to_job_file_linesÚ
split_jobs)r^   r…   rV   r   r†   Zlog_argsÚitemÚfÚtasksrƒ   rk   Úbatch_file_namert   Újob_file_linesr*   r*   r+   Úwrite_batch_jobs¿   sl   

ý
ÿ
þ
ÿ

ïÿý

ûÿzJOB_SUBMIT.write_batch_jobsc                 C   s¤   t | jƒdkr| j| j| jd dS tdƒ t d¡}t|dƒ(}| ¡ }| j	dkr-d}nd	}|D ]}t 
|| ¡ |tjd< q1W d
  ƒ dS 1 sKw   Y  dS )zâ
        submit jobs based on scheduler
        :param batch_file: batch job name
        :param email_notif: If email notifications should be on or not. Defaults to true.
        :return: True if running on a cluster
        r   ©r8   Tz!
Working on a single machine ...
ÚPATHr€   r=   z-export PATH=$ISCE_STACK/stripmapStack:$PATH; z)export PATH=$ISCE_STACK/topsStack:$PATH; NF)rŒ   rW   rs   r   r[   r/   r0   rŠ   r‹   r<   ÚsystemÚenviron)r^   r…   Úsystem_pathr–   Zcommand_linesÚcmdrw   r*   r*   r+   Úsubmit_batch_jobs  s$   

þ
ú
ö
zJOB_SUBMIT.submit_batch_jobsc                 C   s  d}| j dkrdtj ||¡ }nM| j dkr dtj ||¡ }n>| j dkrVtjddtjdj ¡  	d	¡}| 
d
¡s>| 
d¡rId tj ||¡¡}nd tj ||¡¡}d}ntd | j ¡ƒ‚tj|tjdd}|rt d| 	d	¡¡}ttdd„ |D ƒƒƒ}|S d}|S )zí
        Submit a single job (to bsub or qsub). Used by submit_jobs_individually and submit_job_with_launcher and submit_script.
        :param job_file_name: Name of job file to submit.
        :return: Job number of submission
        TÚLSFzbsub < ÚPBSzqsub < ÚSLURMÚhostname©ÚshellÚstdoutúutf-8ÚloginÚcometz	sbatch {}z{}Fú"ERROR: scheduler {0} not supported)Ústderrr§   z\d+c                 S   s   g | ]}t |ƒ‘qS r*   )r'   ©rc   Úxr*   r*   r+   Ú
<listcomp>C  ó    z0JOB_SUBMIT.submit_single_job.<locals>.<listcomp>ÚNone)rK   r/   r2   r4   Ú
subprocessÚPopenÚPIPEr¨   ÚreadÚdecodeÚ
startswithr\   Ú	ExceptionÚcheck_outputÚSTDOUTÚreÚfindallr&   Úmax)r^   ru   r8   Zjob_num_existsÚcommandr¥   Z
output_jobÚ
job_numberr*   r*   r+   Úsubmit_single_job(  s&   


þzJOB_SUBMIT.submit_single_jobr   c           
      C   sÚ   t jddt jdj ¡  d¡}| j||||d}| d¡ | jdkr+| j	||||d}| j
r=| d	¡ | d
| d ¡ n	| d| d ¡ d |¡}ttj ||¡dƒ}	|	 |¡ W d  ƒ dS 1 sfw   Y  dS )a  
        Writes a job file for a single job.
        :param job_name: Name of job.
        :param job_file_name: Name of job file.
        :param command_line: Command line containing process to run.
        :param work_dir: working or output directory
        r¥   Tr¦   r©   rj   z
free
r¤   r   z
module load remoraz
remora Ú
ri   úw+N)r³   r´   rµ   r¨   r¶   r·   r‘   r’   rK   Úadd_slurm_commandsr   r\   rŠ   r/   r2   r4   Ú
writelines)
r^   rt   ru   rw   r8   rk   r   r¥   r™   Újob_filer*   r*   r+   rr   I  s$   	
ÿ




ÿýz JOB_SUBMIT.write_single_job_filec           
   	   C   s    t |ƒ}| ¡ }W d  ƒ n1 sw   Y  t|ƒD ]1\}}tj |¡ tj¡d d t|ƒ }| j	|||tj 
|¡||d tj 
|¡d | d }	qdS )ab  
        Iterates through jobs in input file and writes a job file for each job using the specified scheduler. This function
        is used for batch jobs in pegasus (LSF) to split the tasks into multiple jobs
        :param batch_file: File containing batch of jobs for which we are creating job files.
        :return: List of job file names.
        NéÿÿÿÿÚ_)r8   rk   r   r-   z.job)rŠ   r‹   Ú	enumerater/   r2   r3   r7   Úsepr&   rr   rY   )
r^   r…   rk   r   Ú
input_fileZjob_listÚirw   ru   rÆ   r*   r*   r+   r   j  s   

ÿ$ÿz&JOB_SUBMIT.write_batch_singletask_jobsTc              	   C   s’  g }g }g }|D ]D}t  d t j ||¡¡¡ |  ||¡}t j |d | d¡d |¡¡}	t j |d | d¡d |¡¡}
| |¡ | |	¡ | |
¡ q|rÇd}d}d}t 	d¡ | j
dkr]g }t j |d	¡}t||ƒD ]\}}|d
ksüd}|dkrüt  d ||¡¡ t 	d¡ t|dƒ}| ¡ }t|ƒdk r£	 W d  ƒ qyW d  ƒ n1 s­w   Y  d|d v s¾d|d v rØtd ||¡ƒ ||d 7 }t 	|d ¡ |d7 }n d|d v rád}nd|d v rïd}| |¡ n	d}td |¡ƒ‚|dks}qot|ƒdkr\|D ]M}t |¡}tj|dd}t ||¡ t t ¡ d¡}|d t j |¡ d | d | }t| jd  d!ƒ}| |¡ W d  ƒ n	1 sMw   Y  q| j|| jd" n1t||ƒD ]+\}	}d
|	vrŒt j |	¡sŒtd ||¡ƒ ||d 7 }t 	|¡ t j |	¡rrqb|D ]6}t | d¡d d# ¡}|D ]$}t|d$ƒt|d%ƒt|d&ƒt|d'ƒg}t  !|¡ "¡ rÃtd( |¡ƒ‚q qdS ))aƒ  
        Writes a single job file for launcher to submit as array. This is used to submit jobs in slurm or sge where launcher
        is available (compare to submit_jobs_individually used on pegasus with LSF)
        :return:
        :param batch_file: File containing tasks that we are submitting.
        :param work_dir: the directory to check outputs and error files of job
        zchmod +x {}z{}_{}.orB   r   z{}_{}.eé<   é   r¤   Z
job_statusr²   Úwaitz!sacct --format="State" -j {} > {}r€   é   NZPENDINGZRUNNINGz/Waiting for job {} output file after {} minutesr   Z	COMPLETEDÚcompleteZTIMEOUTÚtimeoutÚfailedz'Error: {} job was terminated with Errorg333333ó?)Úfactorz%Y%m%d:%H-%Mz: re-running: z: z --> z
/rerun.logr|   r›   z*.ezSegmentation faultZAbortedÚERRORÚErrorzError terminating job: {})#r/   r   r\   r2   r4   rÁ   r7   r’   ÚtimeÚsleeprK   ÚziprŠ   r‹   rŒ   r[   ÚRuntimeErrorÚputilsÚextract_walltime_from_job_fileÚmultiply_walltimeÚreplace_walltime_in_job_filer   ÚstrftimeÚnowr6   r   rÅ   rs   r8   ÚexistsrX   Úcheck_words_in_filer   ÚarrayÚany)r^   rW   r8   rl   Zjob_numbersZjobs_outZjobs_errru   Zjob_numÚoutÚerrrÌ   Zwait_time_secZtotal_wait_time_minZrerun_job_filesZjob_status_filerÀ   Zjob_statZ	stat_fileÚstatusr   Únew_wall_timeÚdateStrÚstringZrerunÚerror_filesÚerrfileZjob_exitr*   r*   r+   rs   }  s¤   	  



ýþÿ
ì€
$ÿ€€

ý€ýÿûz&JOB_SUBMIT.submit_and_check_job_statusc                    sâ  |}d}| j }d|v sd|v rd}d| jv rd}|t|ƒkr/|d }t || ¡}|t|ƒkstt t|ƒ| ¡ƒ‰ t| j| | j ƒ}	|	ˆ k rc|t|ƒk r^|d7 }tt t|ƒ| ¡ƒ‰ nn|	ˆ k sH|	ˆ k ry|d }t| j| | j ƒ}	|	ˆ k sg|dkr„td 	|¡ƒ tj
dt|ƒˆ …  ¡ }
‡ fd	d
„|
D ƒ}t|ƒ|d< |durª| j| | _nt ˆ | ¡| _t|
|ƒD ]7\}}|
 |¡}|d 	|¡ }tj |¡}| j|||| || jd}| j||||… |||d}| j |¡ q·dS )zÝ
        splits the batch file tasks into multiple jobs with one node
        :param batch_file:
        :param tasks:
        :param number_of_nodes: Total number of nodes required for all tasks
        :return:
        r   Zgenerate_burst_igramZmerge_burst_igraméd   Z
singleNodeiè  z|Note: Number of jobs exceed the numbers allowed per queue for jobs with 1 node...
Number of Nodes per job are adjusted to {}r   c                    s   g | ]}|ˆ  ‘qS r*   r*   r®   ©Znumber_of_parallel_tasksr*   r+   r°     r±   z)JOB_SUBMIT.split_jobs.<locals>.<listcomp>rÇ   Nz_{}r‚   r„   )rO   rI   r'   r   rŽ   rŒ   rP   rS   r[   r\   ÚogridÚtolistrM   rR   ÚmathrÙ   Úindexr/   r2   r6   r‘   r   r“   rW   r’   )r^   r…   r—   rk   r   r†   Znumber_of_jobsZnumber_of_nodes_per_jobrO   Znumber_of_limited_memory_tasksZstart_linesZ	end_linesZ
start_lineZend_lineZ	job_countr˜   rt   r™   ru   r*   rî   r+   r”   Ø  s^   	
þúþÿ
ÿýzJOB_SUBMIT.split_jobsrz   c                 C   sÒ  t jdd}|dkrd}| | d¡d  d¡dd… ¡}n|}| jd	kr5|dkr5| jdu r5t  | j¡| _| jr<| j}nd
}| jdv ri||v rT|| d }|| d }n|d d }|d d }t  	|||¡| _
n| j| _
| jdv r¬||v rŽ|| d }|| d }	t|| d ƒ| j }
n|d d }|d d }	t|d d ƒ| j }
|
dkr«d
}
n| j}d}	d
}
t  || j||	|
| j¡| _||v rÌ|| d | _n|d d | _||v rà|| d | _dS |d d | _dS )z¶
        get memory, walltime and number of threads for the job from job_defaults.cfg
        :param job_name: the job file name
        :param job_type: 'batch' or 'script'
        zjob_defaults.cfg)Úconfig_filerz   rÈ   r-   rÇ   rÎ   NrA   r   )Nr²   Úc_memoryÚs_memoryr   Ú
c_walltimeÚ
s_walltimeÚseconds_factorr   Ú0Únum_threadsr    )rÛ   Úget_config_defaultsr4   r7   r<   r   Úget_number_of_burstsr]   r   Úscale_memoryrS   r   r   r   Úscale_walltimerQ   rK   rT   rU   Úcopy_to_tmp_flag)r^   rt   rh   ÚconfigÚ	step_nameÚnumber_of_memory_unitsrô   rõ   rö   r÷   Úextra_secondsr*   r*   r+   rq     sX   $


€

ÿþzJOB_SUBMIT.get_memory_walltimec                 C   sä  | j dkr"|}d}d}d}d}	d| d }
d}d	}d
}d}d}d}nQ| j dkrBd}d}d}d}	d}
d}d}d
}d}d}d| d }n1| j dkrk|| j }d}d}d}d}	d| d }
d}d	}d}d| d }d}d }ntd! | j ¡ƒ‚| jd"kr||d#9 }d$| || tj |¡¡ ||	 t d%¡¡ g}| j	r¤| 
|| t d&¡¡ ¡ | ||
 t|ƒt|ƒ¡ || tj ||¡¡ || tj ||¡¡ || | j¡ || | j¡ g¡ | j dkrä| 
|d' ¡ | jd(krð| 
|d) ¡ |S )*aÇ  
        Generates the lines of a job submission file that are based on the specified scheduler.
        :param job_name: Name of job.
        :param job_file_name: Name of job file.
        :param number_of_tasks: Number of lines in batch file to be supposed as number of tasks
        :param number_of_nodes: Number of nodes based on number of tasks (each node is able to perform 68 tasks)
        :return: List of lines for job submission file
        r¢   z
#BSUB z	/bin/bashz-J {0}z-P {0}z-n {0}z-R span[hosts={1}]z-o {0}_%J.oz-e {0}_%J.ez-q {0}z-W {0}z-M {}z	-B -u {0}r£   z
#PBS z-N {0}z-A {0}z-l nodes={0}:ppn={1}z-o {0}_$PBS_JOBID.oz-e {0}_$PBS_JOBID.ez-l walltime={0}z
-l mem={0}z-m az-M {0}r¤   z	
#SBATCH z-n {1}z-p {0}z--mail-user={}z--mail-type=failz-t {0}Fr¬   Úparallelé   z#! ZJOBSHEDULER_PROJECTNAMEZNOTIFICATIONEMAILz-VZgpuz--gres=gpu:4)rK   rM   r¹   r\   r   r/   r2   r6   r0   rV   r’   Úextendr'   r4   rT   )r^   rt   ru   rƒ   rk   r8   r<   r§   Zname_optionZproject_optionZprocess_optionZstdout_optionZstderr_optionZqueue_optionZwalltime_limit_optionZmemory_optionZemail_optionr™   r*   r*   r+   r‘   d  sv   




ýû

zJOB_SUBMIT.get_job_file_linesc                 C   s  | j r| jdkr
|S | d¡ | d¡ | d¡ | d¡ | d || j¡¡ |d urWd ||| j¡}t|tƒrF|D ]	}|d |¡7 }q;n|d |¡7 }|d7 }| |¡ n| d ||| j¡¡ | d	¡ | d
¡ | d¡ | d¡ | jdkr‚| d¡ |S | d¡ |S )NÚnorÂ   ú1################################################
z1#   install code on /tmp                       #
z(install_code_on_tmp.bash {} --prefix {}
zcopy_data_to_tmp.bash {} {} {}r   zcopy_data_to_tmp.bash {} {} {}
z# set environment    
zexport PATH=/bin
zunset PYTHONPATH
z(export RSMASINSAR_HOME=/tmp/rsmas_insar
r=   z’cd $RSMASINSAR_HOME; source ~/accounts/platforms_defaults.bash; source setup/environment.bash; export PATH=$ISCE_STACK/stripmapStack:$PATH; cd -;
zŽcd $RSMASINSAR_HOME; source ~/accounts/platforms_defaults.bash; source setup/environment.bash; export PATH=$ISCE_STACK/topsStack:$PATH; cd -;
)r    rÿ   r’   r\   r<   r   r‡   rˆ   )r^   r™   ru   r¥   r…   r   Zjob_cmdr•   r*   r*   r+   rÄ   À  sF   



$
ÿ





   6   
Ì   4zJOB_SUBMIT.add_slurm_commandsc                 C   s8  d}| j dkr"tjddtjdj ¡  d¡}| d¡r | d¡s"d}d	 |¡}g }	d
| j	v s1|r|D ]/}
t
 |
¡}t
 |¡}|	 d |
 d¡d tj |¡d | d tj |¡d | d ¡¡ q3tj |¡rnt |¡ t|dƒ}| |	¡ W d  ƒ n1 sƒw   Y  | j dkr—| j|||||d}| d¡ | d¡ | d¡ | d | j¡¡ | d | j¡¡ | d |¡¡ | d |¡¡ | d¡ | d¡ | jrí| d¡ | d¡ | dtj |¡ d  ¡ n| d!¡ | d"¡ ttj | j|¡dƒ}| |¡ W d  ƒ |S 1 sw   Y  |S t|ƒD ]&\}}
|	 d# |
 d¡d tj |¡d$ |¡ tj |¡d% |¡ ¡¡ q| j dkrQ| d&¡ | d' | j¡¡ | d( | j¡¡ | d¡ |	D ]}
| |
¡ qj| d)¡ ttj | j|¡dƒ}| |¡ W d  ƒ |S 1 s•w   Y  |S )*a^  
        complete job file lines based on job submission scheme. if it uses launcher, add launcher specific lines
        :param job_file_lines: raw job file lines from function 'get_job_file_lines'
        :param tasks:number of tasks to be include in this job
        :param batch_file: name of batch file containing tasks
        :return:
        Fr¤   r¥   Tr¦   r©   rª   r«   ri   Zlauncherz{} > {} 2>{}
rÂ   r   rÈ   z_$LAUNCHER_JID.oz_$LAUNCHER_JID.erÃ   N)r…   r   z2
################################################
z# execute tasks with launcher
r  zexport OMP_NUM_THREADS={0}
zexport LAUNCHER_PPN={0}
zexport LAUNCHER_NHOSTS={0}
zexport LAUNCHER_JOB_FILE={0}
z!export LAUNCHER_WORKDIR=/dev/shm
zcd /dev/shm
z

module load remoraz
remora $LAUNCHER_DIR/paramrun
z 
mv remora_$SLURM_JOB_ID remora_z_$SLURM_JOB_ID
z$LAUNCHER_DIR/paramrun
zrm -rf /tmp/rsmas_insar 
z{} > {} 2>{} &
z_{}.oz_{}.ezC
export LD_PRELOAD=/home1/apps/tacc-patches/python_cacher/myopen.soz

export OMP_NUM_THREADS={0}z
export PATH={0}:$PATHz
wait)rK   r³   r´   rµ   r¨   r¶   r·   r¸   r\   rI   rÛ   Ú$extract_config_file_from_task_stringÚ)extract_date_string_from_config_file_namer’   r7   r/   r2   r3   rá   ro   rŠ   rÅ   rÄ   rU   rR   r   r6   r4   r   rÉ   rG   )r^   r™   r—   r…   rk   r   Zdo_launcherr¥   ru   Ztasks_with_outputÚlineró   Údate_stringZbatch_fZjob_fÚcountr*   r*   r+   r“   ¶  s€   



þ
ÿ

ÿ










ÿäê
þ



ÿýz&JOB_SUBMIT.add_tasks_to_job_file_lines)Nra   )NNNN)N)Nr   N)r   N)NT)NN)rz   )r   r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r`   rx   rš   r¡   rÁ   rr   r   rs   r”   rq   r‘   rÄ   r“   r*   r*   r*   r+   r;   j   s$    
1

M
!
!

[
G
E
\   yr;   c                    s^   t | dƒ}| ¡ }W d  ƒ n1 sw   Y  ‡ fdd„|D ƒ}t d| ¡dkr-dS dS )	zÈ
    Checks for existence of a specific word in a file
    :param errfile: The file to be checked
    :param eword: The word to search for in the file
    :return: True if the word is in the file
    r€   Nc                    s   g | ]}ˆ |v ‘qS r*   r*   )rc   r•   ©Úewordr*   r+   r°      r±   z'check_words_in_file.<locals>.<listcomp>r   r   TF)rŠ   r‹   r   Úsum)rì   r  r–   ÚlinesZcheck_ewordr*   r  r+   râ     s   
ÿrâ   c              
   C   sP  t | ƒ}|d }|dkrt d¡rt d¡}nd}tjddtjdj ¡  d¡}t	D ]}||v r4|} nd }q*| j
r@| j
|d	< nt d	¡rLt d	¡|d	< |d	 |d
 |d |d |d |d |d dœ}| ¡ D ]!}|| dks‰|dkr}t|| ƒ||< qh|dks‰t|| ƒ||< qh|t	v rTttdƒ}| ¡ }	W d   ƒ n1 s£w   Y  |	D ]}
|
 d¡r¹|	d  ¡ } nqª|	D ]—}
|
 d¡sS|
 |¡rS|
 ¡ }|| d	¡ }|d dv rß||d< ||d krS|d dkr÷t|| d
¡ ƒ|d< |d dkr	t|| d¡ ƒ|d< |d dkrt|| d¡ ƒ|d< |d dkr-t|| d¡ ƒ|d< |d dkr?t|| d¡ ƒ|d< |d dkrQt|| d¡ ƒ|d<  nq¼|dv r\d}n|dv rdd }n
|d!v rld"}nd }g d#¢}d}| ¡ D ]\}}|| dkr|| ||< |d$7 }qx||||d |d |d |d |d |d f	}|S )%NÚjob_submission_schemeÚautoZJOB_SUBMISSION_SCHEMEZlauncher_multiTask_singleNodezhostname -fTr¦   r©   Ú	QUEUENAMEÚCPUS_PER_NODEÚTHREADS_PER_COREÚMAX_JOBS_PER_WORKFLOWÚMAX_JOBS_PER_QUEUEÚWALLTIME_FACTORÚMEM_PER_NODE)rL   rM   rN   rO   Úmax_jobs_per_queuerQ   rP   rQ   rL   r€   ZPLATFORM_NAMEr   ú#)r  ÚNONEr²   rM   rN   r  rO   rP   )Ú	stampede3Úfronterar«   r¤   )Úpegasusr¢   )Úeos_sanghoonÚbeijing_serverÚdeqing_serverÚeosÚdqcentos7insarr£   )Nr  r   r   i€>  r   r   )Ú"auto_template_not_existing_optionsr/   r0   r³   r´   rµ   r¨   r¶   r·   r   r   rE   r   r'   rŠ   r   r‹   r¸   r7   rò   Úitems)r9   rZ   rI   r¥   ÚplatformrJ   Z
check_autoÚkeyr–   r  r  Zqueue_headerZsplit_valuesZdefault_queuerK   Zdef_autorÌ   ÚvalueZout_putsr*   r*   r+   rH   (  s    

ú€

ÿ
þ€


€þrH   c                 C   sb   g d¢}t | dƒr$ddlm} || jƒj}|D ]
}||vr!d||< q|S i }|D ]}d||< q(|S )N)r  r  r  r  r  r  r  r  r   r   )ÚTemplater  )ÚhasattrÚminsar.objects.dataset_templater/  r   Úoptions)r9   Zjob_optionsr/  rZ   Úoptionr*   r*   r+   r*  ‰  s   
€ü
r*  Ú__main__r   r   F))r  r/   ÚsysÚstatr³   r!   r×   rX   Únumpyr   rñ   ÚtextwrapÚminsar.objectsr   Úminsar.objects.auto_defaultsr   r   ÚwarningsÚminsar.utils.process_utilitiesÚutilsÚprocess_utilitiesrÛ   r   r¼   ÚfilterwarningsÚFutureWarningr,   r:   r;   râ   rH   r*  r  rv   ZPARAMSÚjob_objrš   r   r   r¡   rç   r*   r*   r*   r+   Ú<module>   sR   !         4a
ú