Python Multiprocessing innerhalb von mpi

Ich habe ein Python-Skript, das ich mit dem Multiprocessing-Modul geschrieben habe, um die Ausführung zu beschleunigen. Die Berechnung verläuft peinlich parallel, sodass die Effizienz mit der Anzahl der Prozessoren skaliert. Jetzt möchte ich dies in einem MPI-Programm verwenden, das eine MCMC-Berechnung auf mehreren Computern verwaltet. Dieser Code hat einen Aufruf an system (), der das Python-Skript aufruft. Ich stelle jedoch fest, dass der Effizienzgewinn durch die Verwendung von Python Multiprocessing verschwindet, wenn man es so nennt.

Wie kann ich erreichen, dass mein Python-Skript die Geschwindigkeitszuwächse aus der Mehrfachverarbeitung beibehält, wenn es von MPI aufgerufen wird?

Here ist ein einfaches Beispiel, das den viel komplizierteren Codes entspricht, die ich verwenden möchte, aber dasselbe allgemeine Verhalten zeigt. Ich schreibe ein ausführbares Python-Skript namens junk.py.

#!/usr/bin/python
import multiprocessing
import numpy as np

nproc = 3
nlen = 100000


def f(x):
    print x
    v = np.arange(nlen)
    result = 0.
    for i, y in enumerate(v):
        result += (x+v[i:]).sum()
    return result


def foo():
    pool = multiprocessing.Pool(processes=nproc)
    xlist = range(2,2+nproc)
    print xlist
    result = pool.map(f, xlist)
    print result

if __name__ == '__main__':
    foo()

Wenn ich dies von der Shell aus selbst ausführe und "top" benutze, kann ich drei Python-Prozesse sehen, die jeweils 100% der CPU auf meinem 16-Core-Rechner beanspruchen.

node094:mpi[ 206 ] /usr/bin/time junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
62.68user 0.04system 0:21.11elapsed 297%CPU (0avgtext+0avgdata 16516maxresident)k
0inputs+0outputs (0major+11092minor)pagefaults 0swaps

Wenn ich dies jedoch mit mpirun aufrufe, benötigt jeder Python-Prozess 33% der CPU und insgesamt dauert die Ausführung etwa dreimal so lange. Das Aufrufen mit -np 2 oder mehr führt zu mehr Prozessen, beschleunigt jedoch die Berechnung nicht.

node094:mpi[ 208 ] /usr/bin/time mpirun -np 1 junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
61.63user 0.07system 1:01.91elapsed 99%CPU (0avgtext+0avgdata 16520maxresident)k
0inputs+8outputs (0major+13715minor)pagefaults 0swaps

(Zusätzliche Hinweise: Dies ist mpirun 1.8.1, python 2.7.3 unter Linux Debian Version wheezy. Ich habe gehört, dass system () in MPI-Programmen nicht immer erlaubt ist, aber es funktioniert seit fünf Jahren für mich auf diesem Computer Ich habe zum Beispiel einen pthread-basierten Parallelcode von system () innerhalb eines MPI-Programms aufgerufen, der je nach Wunsch 100% der CPU-Kapazität für jeden Thread verwendet und rufe es einfach auf mehr Knoten auf ... die MCMC-Berechnung beinhaltet eine feste Anzahl von Ketten, die sich synchron bewegen müssen, so dass die Berechnung leider nicht auf diese Weise reorganisiert werden kann.)

Antworten auf die Frage(1)

Ihre Antwort auf die Frage