2010-11-19 11 views
4

Ich versuche, ein Stück Code auf einem großen Computer-Cluster zu laufen, um verschiedene Teile der Daten zu analysieren.Matlab Charge Parallelisierung in Bash

Ich habe 2 Schleifen erstellt, um die Jobs verschiedenen Knoten und den CPUs zuzuordnen, die die Knoten enthalten. Die Analysefunktion, die ich geschrieben habe, 'chnJob()', braucht nur einen Index, um zu wissen, welchen Teil der Daten es analysieren muss (es ist die Shell-Variable, die in diesem Fall 'chn' genannt wird).

die Schleife wie folgt aus:

for NODE in $NODES; do # Loop through nodes 
    for job_idx in {1..$PROCS_PER_NODE}; do # Loop through jobs per node (8 per node) 
     echo "this is the channel $chn" 
     ssh $NODE "matlab -nodisplay -nodesktop -nojvm -nosplash -r 'cd $WORK_DIR; chnJob($chn); quit'" & 
     let chn++ 
     sleep 2 
    done 
done 

Auch wenn ich sehe, dass chn Variable ordnungsgemäß erhöht wird, wird der Wert von chn, die der Matlab-Funktion übergeben wird, ist immer der letzte Wert des chn.

Dies ist wahrscheinlich, weil Matlab eine Menge Zeit braucht, um auf jedem Knoten zu öffnen und bash beendet die Schleifen bis dahin. Der Wert, der an jede Matlab-Instanz übergeben wird, ist also nur der letzte Wert.

Gibt es eine Möglichkeit, das zu umgehen? Kann ich den Wert dieser Variablen "backen", wenn ich die Funktion aufruft?

Oder ist das Problem ganz anders?

Antwort

2

Bash kann Variablen in Klammernbereichausdrücken nicht verarbeiten. Sie müssen Literale sein: {1..10}. Aufgrund der Art, wie Sie es jetzt haben, wird die innere Schleife immer genau einmal pro Iteration der äußeren Schleife statt acht Mal (oder was auch immer der Wert von PROCS_PER_NODE ist) ausgeführt. Als Ergebnis geht chn von seinem Anfangswert zu jenem plus NODES, wenn es von Original_chn zu NODES * PROCS_PER_NODE gehen sollte.

Verwenden Sie eine C-Stil for Schleife statt:

for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++)) 

Sie beide job_idx erhöhen könnte und chn im for (wenn das nicht geben Sie off-by-one-Probleme):

for ((job_idx=1; job_idx<=$PROCS_PER_NODE; job_idx++, chn++)) 
3

Ich glaube nicht, dass das passiert. Können Sie versuchen, diese ausgeführt wird:

cnt=0 
for a in 1 2; do 
    for b in 1 2; do 
    echo --- $cnt 
    ssh somehost "echo result: '$cnt'" & 
    let cnt++ 
    done 
done 

mit einigen Host ersetzen some wo Sie sshd Laufen haben. Dies druckt die Nummern 0 - 3, die von echo result: '$cnt' zurückkommen, die entfernt ausgeführt werden. Daher funktioniert die Ausführung selbst OK.

Eine Sache, die ich vorschlagen kann ist, dass Sie Ihren Befehl (matlab ...) in ein Skript in einem bekannten Ordner verschieben, dann führen Sie das Skript in den obigen Schleifen durch einen vollständigen Pfad zu diesem Skript. Etwas wie:

ssh $NOTE "/path/to/script.sh $cnt" 

Im Skript $1 geben Sie den gewünschten Wert (das heißt $cnt von der Schleife). Sie können echo $1 >> /tmp/values am Anfang Ihres Skripts verwenden, um alle Werte in der Datei /tmp/values zu sammeln. Natürlich, rm /tmp/values bevor Sie beginnen. Dies wird bestätigen, ob Sie alle Werte erhalten, wie Sie sie wollen.

0

Wenn $ PBS_NODEFILE den Dateinamen mit der Liste der Knoten (einen pro Zeile) enthält, dann sollte dies funktionieren:

seq 1 100 | parallel --slf $PBS_NODEFILE "matlab -nodisplay -nodesktop -nojvm -nosplash -r 'cd $WORK_DIR; chnJob({}); quit'" 

Weitere Informationen: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Verwandte Themen