Lange Rede kurzer Sinn, verwenden MKL_Set_Num_Threads
und seine camelcase Freunde, wenn MKL Aufruf aus Python. Das gleiche gilt für C, wenn Sie nicht #include <mkl.h>
.
Die MKL documentation scheint darauf hinzudeuten, dass die richtige Art Signatur in C:
void mkl_set_num_threads(int nt);
Okay, lassen Sie uns ein Minimalprogramm versuchen dann:
void mkl_set_num_threads(int);
int main(void) {
mkl_set_num_threads(1);
return 0;
}
es Kompilieren mit GCC und Boom, Segmentation fault
wieder. Es scheint also, dass das Problem nicht auf Python beschränkt ist.
es läuft durch einen Debugger (GDB) offenbart:
Program received signal SIGSEGV, Segmentation fault.
0x0000… in mkl_set_num_threads_()
from /…/mkl/lib/intel64/libmkl_intel_lp64.so
Warte eine Sekunde, mkl_set_num_threads_
?? Das ist die Fortran-Version von mkl_set_num_threads
! Wie haben wir am Ende die Fortran-Version genannt? (Beachten Sie, dass die Aufrufkonvention von Fortran erfordert, dass die Argumente als Zeiger und nicht als Wert übergeben werden.)
Es stellt sich heraus, dass die Dokumentation eine vollständige Fassade war. Wenn Sie tatsächlich die Header-Dateien für die aktuellen Versionen von MKL untersuchen, werden Sie diese nette kleine Definition finden:
void MKL_Set_Num_Threads(int nth);
#define mkl_set_num_threads MKL_Set_Num_Threads
... und jetzt ist alles macht Sinn! Die korrekte Funktion do call (für C-Code) ist MKL_Set_Num_Threads
, nicht mkl_set_num_threads
.die Symboltabelle Inspizieren zeigt, dass es tatsächlich vier verschiedene Varianten definiert sind:
nm -D /…/mkl/lib/intel64/libmkl_rt.so | grep -i mkl_set_num_threads
00000000000e3060 T MKL_SET_NUM_THREADS
…
00000000000e30b0 T MKL_Set_Num_Threads
…
00000000000e3060 T mkl_set_num_threads
00000000000e3060 T mkl_set_num_threads_
…
Warum hat Intel legte in vier verschiedenen Varianten einer Funktion trotz nur C und Fortran sind Varianten in der Dokumentation? Ich weiß es nicht genau, aber ich vermute, dass es für die Kompatibilität mit verschiedenen Fortran-Compilern ist. Sie sehen, Fortran Aufruf Konvention ist nicht standardisiert. Verschiedene Compiler mangle the names der Funktionen unterschiedlich:
- einige verwenden Großbuchstaben,
- einige verwenden Kleinbuchstaben mit einem hinteren Unterstrich und
- einige verwenden Kleinbuchstaben ohne Dekoration alles an.
Es kann sogar andere Wege geben, die mir nicht bekannt sind. Dieser Trick erlaubt es, die MKL-Bibliothek mit meisten Fortran-Compilern ohne jegliche Modifikation zu verwenden, der Nachteil ist, dass C-Funktionen "gemangelt" werden müssen, um Platz für die 3 Varianten der Fortran-Aufrufkonvention zu schaffen.
Als ich die Enthought Python Distribution hatte, konnte ich 'mkl' als Modul importieren. Ich frage mich, was hinter den Kulissen passiert ist. –