Weisen Sie intermediäre mehrdimensionale Arrays in Cython zu, ohne die GIL zu erwerben

8

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:

  1. Basierend auf der Ausgabe von cython -a , wird hier die typisierte Speicheransicht erstellt:

    %Vor%

    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:

%Vor%

Aktualisieren

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

%Vor%

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:

%Vor%     
ali_m 06.03.2014, 15:36
quelle

2 Antworten

5

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".

    
hivert 06.03.2014, 22:59
quelle
0

Ссылка

"" "

  

Freigabe der GIL

     

Sie können die GIL um einen Codeabschnitt freigeben, indem Sie den Befehl mit nogil verwenden   Aussage:

%Vor%
%Vor%      

rufe nichts auf, das Python-Objekte manipuliert, ohne zuerst   Wiedererwerb der GIL. Cython überprüft dies derzeit nicht.

"" "

    
jsbueno 06.03.2014 16:04
quelle