2010-07-22 21 views
10

Ich habe eine Funktion (neuronales Netzwerkmodell), die Zahlen produziert. Ich möchte mehrere Parameter, Methoden und verschiedene Eingaben (dh Hunderte von Läufen der Funktion) von Python mit PBS auf einem Standard-Cluster mit Torque testen."peinlich parallele" Programmierung mit Python und PBS auf einem Cluster

Hinweis: Ich habe versucht, parallelpython, ipython und so und war nie vollständig zufrieden, da ich etwas einfacheres wollen. Der Cluster befindet sich in einer bestimmten Konfiguration, die ich nicht ändern kann und eine solche Lösung, die python + qsub integriert, wird sicherlich der Community nutzen.

Dinge zu vereinfachen, Ich habe eine einfache Funktion wie:

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') 

wo input ein, die das Eingabeobjekt ist, input.name ein String ist, und do_lots_number_crunching Stunden dauern können.

Meine Frage ist: Gibt es eine richtige Art und Weise so etwas wie ein Scan von Parametern wie

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

in „etwas“ zu verwandeln, die einen PBS-Skript für jeden Aufruf der Funktion model starten würden?

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

Ich war einer Funktion zu denken, dass die PBS-Vorlage enthalten würde und aus dem Python-Skript aufrufen, aber es noch nicht herausfinden konnte (Dekorateur?).

Antwort

4

pbs_python [1] könnte dafür arbeiten. Wenn experiment_model.py 'a' als Argument könnten Sie tun

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

Sie diese leicht jug mit tun kann (was ich für eine ähnliche Einrichtung entwickelt).

Sie in Datei schreiben würde (zum Beispiel 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) 

Und das ist es!

Jetzt können Sie "Krug Jobs" in Ihrer Warteschlange starten: jug execute model.py und dies wird automatisch parallelisieren. Was passiert, ist, dass jeder Job in wird, eine Schleife, so etwas wie:

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

(Es ist eigentlich viel komplizierter als das, aber Sie erhalten den Punkt).

Es verwendet das Dateisystem zum Sperren (wenn Sie auf einem NFS-System sind) oder einen Redis-Server, wenn Sie bevorzugen. Es kann auch Abhängigkeiten zwischen Aufgaben verwalten.

Das ist nicht genau das, wonach Sie gefragt haben, aber ich glaube, es ist eine sauberere Architektur, um dies vom Job-Queuing-System zu trennen.

2

Es sieht so aus als wäre ich ein bisschen spät zur Party, aber ich hatte auch die gleiche Frage, wie man vor ein paar Jahren peinlich parallele Probleme auf einen Cluster in Python abbildet und meine eigene Lösung geschrieben hat.Ich lud sie vor kurzem auf GitHub hier: https://github.com/plediii/pbs_util

Um Ihr Programm mit pbs_util zu schreiben, würde ich zuerst eine pbs_util.ini im Arbeitsverzeichnis erstellen enthält

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

Dann wird ein Python-Skript wie folgt

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)) 

Und das würde es tun.

0

Ich habe gerade angefangen mit Clustern und EP-Anwendungen zu arbeiten. Mein Ziel (ich bin bei der Bibliothek) ist es, genug zu lernen, um anderen Forschern auf dem Campus den Zugang zu HPC mit EP-Anwendungen zu erleichtern ... besonders Forschern außerhalb von STEM. Ich bin immer noch sehr neu, aber dachte, es könnte helfen, diese Frage auf die Verwendung von GNU Parallel in einem PBS-Skript zu verweisen, um grundlegende Python-Skripte mit unterschiedlichen Argumenten zu starten. In der .pbs Datei gibt es zwei Linien darauf hinweisen:

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. 

Als newby EP Supercomputer, obwohl ich alle anderen Optionen auf „parallel“ noch nicht verstehen, dieser Befehl erlaubt mir Starten Sie Python-Skripts parallel mit verschiedenen Parametern. Dies würde gut funktionieren, wenn Sie im Vorfeld eine Reihe von Parameterdateien generieren können, die Ihr Problem parallelisieren. Beispielsweise Simulationen über einen Parameterraum hinweg ausführen. Oder viele Dateien mit demselben Code verarbeiten.