2013-04-27 10 views
6

Ich versuche zu berechnen und zu generieren, Plots mit Multiprocessing. Unter Linux wird der Code unten richtig, aber auf dem Mac (ML) dies nicht der Fall, so dass der Fehler unter:Python rpy2 und matplotlib Konflikt bei der Verwendung von Multiprocessing

import multiprocessing 
import matplotlib.pyplot as plt 
import numpy as np 
import rpy2.robjects as robjects 

def main(): 
    pool = multiprocessing.Pool() 
    num_figs = 2 
    # generate some random numbers 
    input = zip(np.random.randint(10,1000,num_figs), 
       range(num_figs)) 

    pool.map(plot, input) 

def plot(args): 
    num, i = args 
    fig = plt.figure() 
    data = np.random.randn(num).cumsum() 
    plt.plot(data) 

main() 

Die Rpy2 ist rpy2 == 2.3.1 und R 2.13.2 (ich konnte Installieren Sie nicht die neueste Version von R 3.0 und Rpy2 auf einem Mac, ohne einen Segmentierungsfehler zu bekommen.

Der Fehler ist:

The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). 
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug. 
The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). 

ich alles versucht haben, zu verstehen, was das Problem ohne Glück ist. Meine Konfiguration ist:

Danials-MacBook-Pro:~ danialt$ brew --config 
HOMEBREW_VERSION: 0.9.4 
ORIGIN: https://github.com/mxcl/homebrew 
HEAD: 705b5e133d8334cae66710fac1c14ed8f8713d6b 
HOMEBREW_PREFIX: /usr/local 
HOMEBREW_CELLAR: /usr/local/Cellar 
CPU: dual-core 64-bit penryn 
OS X: 10.8.3-x86_64 
Xcode: 4.6.2 
CLT: 4.6.0.0.1.1365549073 
GCC-4.2: build 5666 
LLVM-GCC: build 2336 
Clang: 4.2 build 425 
X11: 2.7.4 => /opt/X11 
System Ruby: 1.8.7-358 
Perl: /usr/bin/perl 
Python: /usr/local/bin/python => /usr/local/Cellar/python/2.7.4/Frameworks/Python.framework/Versions/2.7/bin/python2.7 
Ruby: /usr/bin/ruby => /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby 

Irgendwelche Ideen?

+1

Rpy2-2.3.6 wurde früher heute veröffentlicht. Es sollte die segfaults auf OS X adressieren. – lgautier

+0

Laurent, vielen Dank für die neue rpy2 Version. Es funktioniert jetzt wunderbar mit R 3.0.0.Trotzdem bleibt der obige Fehler gleich:/ –

Antwort

6

Dieser Fehler tritt auf Mac OS X, wenn Sie einen GUI-Betrieb außerhalb der Haupt-Thread ausführen, das ist genau das, was Sie durch Verschieben Ihre Plotfunktion zum multiprocessing.Pool tun (Ich stelle mir vor, dass es nicht unter Windows arbeiten entweder aus dem gleichen Grund - da Windows die gleiche Anforderung hat). Der einzige Weg, wie ich mir das vorstellen kann, ist, dass ich den Pool benutze, um die Daten zu generieren, und dann den Hauptthread in einer Schleife auf die zurückgegebenen Daten warten lasse (eine Warteschlange ist die Art, wie ich normalerweise damit umgehe ...).

Hier ist ein Beispiel (zu erkennen, dass dies nicht tun kann, was Sie wollen - plotten Sie alle Zahlen "gleichzeitig"? - plt.show() blockiert, so dass nur einer nach dem anderen gezeichnet wird und ich bemerke, dass Sie nicht haben es in Ihrem Beispielcode - aber ohne ich sehe nichts auf meinem Bildschirm - jedoch, wenn ich es herausnehmen - es gibt keine Blockierung und keinen Fehler, weil alle GUI-Funktionen im Haupt-Thread passiert sind):

import multiprocessing 
import matplotlib.pyplot as plt 
import numpy as np 
import rpy2.robjects as robjects 

data_queue = multiprocessing.Queue() 


def main(): 
    pool = multiprocessing.Pool() 
    num_figs = 10 

    # generate some random numbers 
    input = zip(np.random.randint(10,10000,num_figs), range(num_figs)) 
    pool.map(worker, input) 

    figs_complete = 0 
    while figs_complete < num_figs: 
     data = data_queue.get() 
     plt.figure() 
     plt.plot(data) 
     plt.show() 
     figs_complete += 1 

def worker(args): 
    num, i = args 
    data = np.random.randn(num).cumsum() 
    data_queue.put(data) 
    print('done ',i) 

main() 

Hoffe, das hilft.

1

Dies könnte rpy2-spezifisch sein. Es gibt Berichte über ein ähnliches Problem mit OS X und Multiprocessing here und there.

Ich denke, dass die Verwendung eines Initialisierers, der die Pakete importiert, die zum Ausführen des Codes im Plot benötigt werden, das Problem lösen könnte (multiprocessing-doc).

5

Ich hatte ein ähnliches Problem mit meinem Arbeiter, der einige Daten geladen, ein Diagramm erstellt und in einer Datei gespeichert wurde. Beachten Sie, dass dies etwas anders ist als im Fall des OP, der sich an interaktiven Plots orientiert. Trotzdem denke ich, dass es relevant ist.

Eine vereinfachte Version meines Code:

def worker(id): 
    data = load_data(id) 
    plot_data_to_file(data) # Generates a plot and saves it to a file. 

def plot_something_parallel(ids): 
    pool = multiprocessing.Pool() 
    pool.map(worker, ids) 

plot_something_parallel(ids=[1,2,3]) 

Dies hat die gleichen Fehler andere verursachten erwähnen:

The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec(). 
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug. 

Nach Zuge @ bbbruce des Denkens, löste ich mein Problem, indem den matplotlib Backend Umschalten von TKAgg auf den Standardwert. Genauer gesagt, ich habe die folgende Zeile in meiner matplotlibrc Datei auskommentiert:

#backend : TkAgg 
+0

Das war genau mein Problem, also danke fürs Posting, auch wenn es nicht ganz das OP-Problem ist :). Aus Neugier - irgendwelche Ideen * warum * Änderungen am Backend behebt die Dinge? Mein Backend war standardmäßig auf 'macosx' eingestellt, daher scheint das Problem nicht spezifisch für das 'TkAgg'-Backend zu sein (als ich das aussprach, funktionierten die Dinge). – dwanderson

Verwandte Themen