2010-07-22 14 views
10

Tengo una función (modelo de red neuronal) que produce figuras. Deseo probar varios parámetros, métodos y diferentes entradas (es decir, cientos de ejecuciones de la función) de python utilizando PBS en un clúster estándar con Torque.programación "embarazosamente paralela" usando python y PBS en un clúster

Nota: probé parallelpython, ipython y tal y nunca estaba completamente satisfecho, ya que quiero algo más simple. El clúster se encuentra en una configuración determinada que no puedo modificar y una solución de este tipo que integre python + qsub beneficiará a la comunidad.

Para simplificar las cosas, tengo una función simple, tales como:

import myModule 
def model(input, a= 1., N=100): 
    do_lots_number_crunching(input, a,N) 
    pylab.savefig('figure_' + input.name + '_' + str(a) + '_' + str(N) + '.png') 

donde input es un objeto que representa la entrada, input.name es una cadena, y do_lots_number_crunching puede durar horas.

Mi pregunta es: ¿hay una manera correcta para transformar algo así como un análisis de parámetros como

for a in pylab.linspace(0., 1., 100): 
    model(input, a) 

en "algo" que pondría en marcha una secuencia de comandos de PBS para cada llamada a la función model?

#PBS -l ncpus=1 
#PBS -l mem=i1000mb 
#PBS -l cput=24:00:00 
#PBS -V 
cd /data/work/ 
python experiment_model.py 

Estaba pensando en una función que incluiría la plantilla PBS y llamarlo desde el script en Python, pero aún no podía averiguarlo (decorador?).

Respuesta

4

pbs_python [1] podría funcionar para esto. Si experiment_model.py 'a' como un argumento que podría hacer

import pbs, os 

server_name = pbs.pbs_default() 
c = pbs.pbs_connect(server_name) 

attopl = pbs.new_attropl(4) 
attropl[0].name = pbs.ATTR_l 
attropl[0].resource = 'ncpus' 
attropl[0].value = '1' 

attropl[1].name = pbs.ATTR_l 
attropl[1].resource = 'mem' 
attropl[1].value = 'i1000mb' 

attropl[2].name = pbs.ATTR_l 
attropl[2].resource = 'cput' 
attropl[2].value = '24:00:00' 

attrop1[3].name = pbs.ATTR_V 

script=''' 
cd /data/work/ 
python experiment_model.py %f 
''' 

jobs = [] 

for a in pylab.linspace(0.,1.,100): 
    script_name = 'experiment_model.job' + str(a) 
    with open(script_name,'w') as scriptf: 
     scriptf.write(script % a) 
    job_id = pbs.pbs_submit(c, attropl, script_name, 'NULL', 'NULL') 
    jobs.append(job_id) 
    os.remove(script_name) 

print jobs 
[1]

: https://oss.trac.surfsara.nl/pbs_python/wiki/TorqueUsage pbs_python

3

Usted puede hacer esto fácilmente usando jug (que he desarrollado para una configuración similar).

Usted escribiría en el archivo (por ejemplo, model.py):

@TaskGenerator 
def model(param1, param2): 
    res = complex_computation(param1, param2) 
    pyplot.coolgraph(res) 


for param1 in np.linspace(0, 1.,100): 
    for param2 in xrange(2000): 
     model(param1, param2) 

Y eso es todo!

Ahora puede iniciar "jar jobs" en su cola: jug execute model.py y esto se paralelizará automáticamente. Lo que pasa es que cada trabajo será en un bucle, hacer algo como:

while not all_done(): 
    for t in tasks in tasks_that_i_can_run(): 
     if t.lock_for_me(): t.run() 

(En realidad es más complicado que eso, pero usted consigue el punto).

Utiliza el sistema de archivos para el bloqueo (si está en un sistema NFS) o un servidor redis si lo prefiere. También puede manejar dependencias entre tareas.

Esto no es exactamente lo que usted solicitó, pero creo que es una arquitectura más limpia separar esto del sistema de cola de trabajos.

2

Parece que llegué un poco tarde a la fiesta, pero también tuve la misma pregunta de cómo mapear problemas embarazosamente paralelos en un clúster en python hace unos años y escribí mi propia solución.Recientemente he subido a GitHub aquí: https://github.com/plediii/pbs_util

para escribir su programa con pbs_util, me gustaría crear primero una pbs_util.ini en el directorio de trabajo que contiene

[PBSUTIL] 
numnodes=1 
numprocs=1 
mem=i1000mb 
walltime=24:00:00 

A continuación, un script en Python como esto

import pbs_util.pbs_map as ppm 

import pylab 
import myModule 

class ModelWorker(ppm.Worker): 

    def __init__(self, input, N): 
     self.input = input 
     self.N = N 

    def __call__(self, a): 
     myModule.do_lots_number_crunching(self.input, a, self.N) 
     pylab.savefig('figure_' + self.input.name + '_' + str(a) + '_' + str(self.N) + '.png') 



# You need "main" protection like this since pbs_map will import this file on the  compute nodes 
if __name__ == "__main__": 
    input, N = something, picklable 
    # Use list to force the iterator 
    list(ppm.pbs_map(ModelWorker, pylab.linspace(0., 1., 100), 
        startup_args=(input, N), 
        num_clients=100)) 

Y eso lo haría.

0

Acabo de empezar a trabajar con clusters y aplicaciones EP. Mi objetivo (estoy con la Biblioteca) es aprender lo suficiente para ayudar a otros investigadores en el campus a acceder a HPC con aplicaciones EP ... especialmente investigadores fuera de STEM. Todavía soy muy nuevo, pero pensé que podría ayudar a esta pregunta señalar el uso de GNU Parallel en un script PBS para iniciar scripts básicos de Python con diferentes argumentos. En el archivo .pbs, hay dos líneas para señalar:

module load gnu-parallel # this is required on my environment 

parallel -j 4 --env PBS_O_WORKDIR --sshloginfile $PBS_NODEFILE \ 
--workdir $NODE_LOCAL_DIR --transfer --return 'output.{#}' --clean \ 
`pwd`/simple.py '{#}' '{}' ::: $INPUT_DIR/input.* 

# `-j 4` is the number of processors to use per node, will be cluster-specific 
# {#} will substitute the process number into the string 
# `pwd`/simple.py `{#}` `{}` this is the command that will be run multiple times 
# ::: $INPUT_DIR/input.* all of the files in $INPUT_DIR/ that start with 'input.' 
#  will be substituted into the python call as the second(3rd) argument where the 
#  `{}` resides. These can be simple text files that you use in your 'simple.py' 
#  script to pass the parameter sets, filenames, etc. 

Como Newby a la supercomputación EP, a pesar de que todavía no comprenden todas las otras opciones en "paralelo", este comando me permitió lanzar scripts de Python en paralelo con diferentes parámetros. Esto funcionaría bien si puede generar una gran cantidad de archivos de parámetros antes de tiempo que pondrán en paralelo su problema. Por ejemplo, ejecutar simulaciones en un espacio de parámetros. O procesando muchos archivos con el mismo código.

Cuestiones relacionadas