Ich versuche Cython zu verwenden, um eine teure Operation zu parallelisieren, bei der intermediäre multidimensionale Arrays generiert werden.
Der folgende sehr vereinfachte Code veranschaulicht die Art von Sache, die ich versuche zu tun:
%Vor%Es gibt mindestens zwei Gründe, warum dies nicht kompiliert werden kann:
Basierend auf der Ausgabe von cython -a
, wird hier die typisierte Speicheransicht erstellt:
scheint Python-API-Aufrufe zu enthalten, und daher kann ich die GIL nicht freigeben, damit die äußere Schleife parallel ausgeführt werden kann.
Ich hatte den Eindruck, dass getippte Speicheransichten keine Python-Objekte waren und daher ein untergeordneter Prozess in der Lage sein sollte, sie zu erstellen, ohne zuerst die GIL zu erwerben. Ist das der Fall?
2. Selbst wenn ich prange(m, nogil=True)
durch ein normales range(m)
ersetze, scheint Cython das Vorhandensein eines cdef
in der inneren Schleife noch immer nicht zu mögen:
Es stellt sich heraus, dass das zweite Problem leicht durch Verschieben von
gelöst werden konnte %Vor% außerhalb der for
-Schleife und einfach zuweisen
innerhalb der Schleife. Ich verstehe immer noch nicht ganz, warum das notwendig ist.
Wenn ich nun versuche, prange
zu verwenden, drücke ich den folgenden Kompilierungsfehler:
Haftungsausschluss: Alles hier ist mit einem Körnchen Salz zu nehmen. Ich vermute eher, dass Sie das wissen. Sie sollten die Frage auf Cython-User stellen. a>. Sie sind immer freundlich und schnell zu beantworten.
Ich stimme zu, dass Cythons Dokumentation nicht sehr klar ist:
[...] memoryviews brauchen oft nicht die GIL:
cpdef int sum3d (int [:,:,:] arr) nogil: ...
Insbesondere brauchen Sie die GIL nicht für die Indexierung, das Slicing oder die Transponierung von Speicheransichten. Memoryviews erfordern die GIL für die Kopiermethoden (C und Fortran zusammenhängende Kopien), oder wenn der dtype Objekt ist und ein Objektelement gelesen oder geschrieben wird.
Ich denke, das bedeutet, dass Python GIL nicht benötigt wird, um einen Memory-View-Parameter zu übergeben oder ihn zum Slicen oder Transponieren zu verwenden. Allerdings benötigt Erstellen eine Speicheransicht oder Kopieren die GIL.
Ein weiteres Argument, das dies unterstützt, ist, dass eine Cython-Funktion eine Memory-Ansicht zu Python zurückgeben kann.
%Vor%Gibt:
%Vor%Dies bedeutet, dass die Speicheransicht in Pythons verwaltetem GC-Speicher zugeordnet ist und somit die GIL erstellt werden muss. So können Sie in einem nogil-Abschnitt keine Speicheransicht erstellen
Was nun die Fehlermeldung betrifft
Memoryview Slices können nur in parallelen Abschnitten geteilt werden
Ich denke, Sie sollten es lesen als "Sie können nicht einen Thread private memoryview Slices haben. Es muss ein Thread shared memoryview Slices sein".
Tags und Links python thread-local-storage parallel-processing numpy cython