Espere a que se complete el conjunto de trabajos qsub
(7)
Tengo un script por lotes que comienza con un par de trabajos qsub, y quiero interceptarlos cuando todos se hayan completado.
No quiero usar la opción -sync, porque quiero que se ejecuten simultáneamente. Cada trabajo tiene un conjunto diferente de parámetros de línea de comando.
Quiero que mi script espere hasta que todos los trabajos se hayan completado, y haga algo después de eso. No quiero usar la función de suspensión, por ejemplo, para verificar si ciertos archivos se han generado después de cada 30 s, porque esto es un drenaje de recursos.
Creo que Torque puede tener algunas opciones, pero estoy ejecutando SGE.
¿Alguna idea sobre cómo podría implementar esto por favor?
Gracias Ps encontré otro hilo Link
que tuvo una respuesta
Puede usar esperar para detener la ejecución hasta que todos sus trabajos hayan terminado. Incluso puede recopilar todos los estados de salida y otras estadísticas de ejecución (tiempo que tomó, cantidad de trabajos realizados en ese momento, lo que sea) si realiza un ciclo de espera para identificaciones específicas.
pero no estoy seguro de cómo usarlo sin sondear en algún valor. ¿Se puede usar bash trap, pero cómo lo haría con qsub?
En caso de que tenga 150 archivos que quiera procesar y pueda ejecutar solo 15 cada vez, mientras que los otros están en espera en la cola, puede configurar algo como esto.
# split my list files in a junk of small list having 10 file each
awk ''NR%10==1 {x="F"++i;}{ print > "list_part"x".txt" }'' list.txt
Guarde todos los trabajos de forma que el primero de cada list_part * .txt mantenga el segundo ... el segundo mantenga el tercero ... y así sucesivamente.
for list in $( ls list_part*.txt ) ; do
PREV_JOB=$(qsub start.sh) # create a dummy script start.sh just for starting
for file in $(cat $list ) ; do
NEXT_JOB=$(qsub -v file=$file -W depend=afterany:$PREV_JOB myscript.sh )
PREV_JOB=$NEXT_JOB
done
done
Esto es útil si tiene en myscript.sh un procedimiento que requiere mover o descargar muchos archivos o crear un tráfico intenso en el cluster-lan
Esto funciona en bash, pero las ideas deben ser portátiles. Use -terse
para facilitar la construcción de una cadena con identificadores de trabajo para esperar; luego envíe un trabajo ficticio que use -hold_jid
para esperar en los trabajos anteriores y -sync y
para que qsub no regrese hasta que (y por lo tanto todos los requisitos previos) haya terminado:
# example where each of three jobs just sleeps for some time:
job_ids=$(qsub -terse -b y sleep 10)
job_ids=job_ids,$(qsub -terse -b y sleep 20)
job_ids=job_ids,$(qsub -terse -b y sleep 30)
qsub -hold_jid ${job_ids} -sync y -b y echo "DONE"
-
-terse
opción-terse
hace que la salida de qsub sea la id del trabajo -
-hold_jid
opción-hold_jid
(como se menciona en otras respuestas) hace que un trabajo espere en los ID de trabajo especificados -
-sync y
opción de-sync y
(a la que hace referencia el OP) le pide a qsub que no regrese hasta que finalice el trabajo enviado -
-by
especifica que el comando no es una ruta de acceso a un archivo de script (por ejemplo, estoy usando lasleep 30
como el comando)
Inicie sus trabajos qsub, usando la opción -N para darles nombres arbitrarios (trabajo1, trabajo2, etc.):
qsub -N job1 -cwd ./job1_script
qsub -N job2 -cwd ./job2_script
qsub -N job3 -cwd ./job3_script
Inicie su secuencia de comandos y dígale que espere hasta que los trabajos llamados job1, job2 y job3 se terminen antes de que comience:
qsub -hold_jid job1,job2,job3 -cwd ./results_script
Necesitaba más flexibilidad, así que construí un módulo de Python para este y otros propósitos here . Puede ejecutar el módulo directamente como un script ( python qsub.py
) para una demostración.
Uso:
$ git clone https://github.com/stevekm/util.git
$ cd util
$ python
Python 2.7.3 (default, Mar 29 2013, 16:50:34)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import qsub
>>> job = qsub.submit(command = ''echo foo; sleep 60'', print_verbose = True)
qsub command is:
qsub -j y -N "python" -o :"/home/util/" -e :"/home/util/" <<E0F
set -x
echo foo; sleep 60
set +x
E0F
>>> qsub.monitor_jobs(jobs = [job], print_verbose = True)
Monitoring jobs for completion. Number of jobs in queue: 1
Number of jobs in queue: 0
No jobs remaining in the job queue
([Job(id = 4112505, name = python, log_dir = None)], [])
Diseñado con Python 2.7 y SGE ya que eso es lo que nuestro sistema ejecuta. Las únicas bibliotecas Python no estándar requeridas son los módulos tools.py
y log.py
incluidos, y sh.py (también incluido)
Obviamente, no es tan útil si desea permanecer puramente en bash
, pero si necesita esperar en los trabajos qsub
, me imagino que su flujo de trabajo está avanzando hacia una complejidad que se beneficiaría del uso de Python.
Otra alternativa (desde here ) es la siguiente:
FIRST=$(qsub job1.pbs)
echo $FIRST
SECOND=$(qsub -W depend=afterany:$FIRST job2.pbs)
echo $SECOND
THIRD=$(qsub -W depend=afterany:$SECOND job3.pbs)
echo $THIRD
La idea es que qsub devuelve el ID de trabajo y esto normalmente se descarga a la salida estándar. En su lugar, capture en una variable ( $FIRST
, $SECOND
, $THIRD
) y use el -W depend=afterany:[JOBIDs]
cuando -W depend=afterany:[JOBIDs]
en cola sus trabajos para controlar la estructura de dependencia de cuando se eliminan de la cola.
Si todos los trabajos tienen un patrón común en el nombre, puede proporcionar ese patrón cuando envíe los trabajos. https://linux.die.net/man/1/sge_types muestra qué patrones puede usar. ejemplo:
-hold_jid "job_name_pattern*"
qsub -hold_jid job1,job2,job3 -cwd ./myscript