2016-05-17 12 views
0

Ich versuche, direkten Zugriff auf numpy Funktionen random/randomkit.h, Zufallsgeneratoren in einer Multithread-Anwendung mit Cython (d. H. Ohne die Gil) zu verwenden.Cython: dynamische "cdef extern von xxx"

Zu diesem Zweck Ich versuche, die Header-Datei aus numpy Ordnern mit dem folgenden Code zuzugreifen:

import os 
import numpy 

str_rkdir = os.path.dirname(os.path.abspath(numpy.__file__)) 
str_randomkit_h = str_rkdir + "/random/randomkit.h" 

cdef extern from str_randomkit_h: 
    ctypedef struct rk_state 
    cdef unsigned long rk_random(rk_state * state) nogil 
    cdef signed long rk_gauss(rk_state * state) nogil 
    cdef void rk_seed(unsigned long seed, rk_state * state) nogil 

Allerdings funktioniert das nicht mit pyximport weil cython der str_randomkit_h String beklagt (Ich denke, es doesn interpretiere den Python-Code nicht vor dem Kompilieren ... gibt es einen einfachen Weg dazu?

Als eine dreckige Workaround, bin ich dynamisch generieren die .pxd vor der Cython-Compilation, aber das ist nicht wirklich nett, so dass ich mich fragte, ob es einen besseren Weg, es zu tun war.

+1

Diese Art von Sache wird normalerweise durch das Build-Skript behandelt. Kann "setup.py" die richtigen Verzeichnisse zum Build-Pfad hinzufügen? –

+0

Ok, ich verstehe was du meinst! Die Tatsache ist (und ich hätte das wahrscheinlich spezifiziert) Ich benutze pyximport für Bequemlichkeit und ich denke, das erfordert den absoluten Pfad, aber ich werde wieder überprüfen – Silmathoron

Antwort

1

Dynamisch können Sie es nicht so arbeiten, weil, wie Sie auch sagten, es kein Dolmetschen gibt, nur kompilieren. DEF s wird auch nicht helfen, da die Funktionen, die in der Vorverarbeitungsstufe verwendet werden können, begrenzt sind. Ich glaube nicht, dass es einen anderen hinterhältigen Weg gibt, dies zu tun; Sie müssen pyximport oder setup.py Skript verwenden.

Mit pyximport können Sie der install-Funktion entsprechende Argumente liefern. Das Verzeichnis/ies die Include-Datei (en) enthält, kann mit der Taste 'include_dirs' im setup_args Wörterbuch als Wert angegeben werden:

>>> from numpy import random as rnd  
>>> from pyximport import install 
>>> install(setup_args={'include_dirs':rnd.__path__[0] + '/'}) 

Natürlich tut dies bedeutet, dass Sie auch Ihre .pxd Datei ändern die Header-Namen zu liefern als Stringliteral:

cdef extern from "randomkit.h": 
    ... 

Alternativ ist using a setup script ziemlich einfach. Auch hier liefern Sie einfach die include_dirs nach der Berechnung in irgendeiner Weise.

+1

ok, das ist gut, vielen Dank für die Erklärung und den Link! – Silmathoron