2012-01-23 17 views
5

Mam tablicę wskaźników funkcji, której używam do wywoływania odpowiedniego cblas_xgemm (np. cblas_dgemm lub cblas_sgemm itd. Z ATLAS/CBLAS).Dlaczego cblas_dgemm i cblas_sgemm mają różne typy wskaźników w tablicy wskaźników funkcji?

Działa to świetnie, gdy mówię, aby użyć cblas_dgemm przez wskaźnik funkcji; dgemm zostanie wywołany z odpowiednimi argumentami i zwróci poprawny wynik.

Jednakże gdy zgłoszę cblas_sgemm przez wskaźnik funkcji, pojawia się następujący komunikat:

ldc must be >= MAX(N,1): ldc=0 N=2Parameter 14 to routine cblas_sgemm was incorrect 

Napisałem short test program który demonstruje problem. Połączenia z cblas_sgemm bez wskaźnika funkcji działają poprawnie.

Uwaga zwłaszcza następujące gcc ostrzeżenie (patrz również sens umieszczonego powyżej, który ma pełną moc gcc):

test_cblas_sgemm.c:20:3: warning: initialization from incompatible pointer type [enabled by default] 

Gdybym zakomentować linię w definicji tablicy wskaźnik funkcji cblas_sgemm, nie uzyskać takie ostrzeżenie, nawet dla linii cblas_dgemm. Ale to nie ma sensu, ponieważ obie te funkcje powinny mieć ten sam typ zwrotu!

Oto odpowiednie linie z cblas.h:

void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, 
       const enum CBLAS_TRANSPOSE TransB, const int M, const int N, 
       const int K, const float alpha, const float *A, 
       const int lda, const float *B, const int ldb, 
       const float beta, float *C, const int ldc); 
void cblas_dgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, 
       const enum CBLAS_TRANSPOSE TransB, const int M, const int N, 
       const int K, const double alpha, const double *A, 
       const int lda, const double *B, const int ldb, 
       const double beta, double *C, const int ldc); 

Więc co się dzieje? Czy w jakiś sposób można uzyskać jedną z funkcji xgemm z jednego nagłówka, a drugą z innego? Czy mam do czynienia z jakimś dziwnym problemem dotyczącym wskaźnika funkcji?

+0

Czy możesz pokazać kod, bardzo trudno jest komentować abstrakcyjne błędy kompilatora bez kontekstu. – talonmies

+0

W pytaniu jest powiązany kod: https://gist.github.com/1671571 –

Odpowiedz

1

Twoje pytanie wydaje się sprowadzać do faktu, że masz funkcje różnych sygnatur, które próbujesz wywołać z tablicy wskaźników funkcji. Nigdy tego nie próbowałem, ale z niewielkich badań nie wygląda na to, że jest to możliwe. To ma sens, ponieważ statycznie napisany język nie byłby w stanie ocenić bezpieczeństwa typu tego manewru.

Widziałem sugestie użycia boost :: variant i innych sposobów obejścia tego problemu, ale ponieważ łączysz się z biblioteką, która nie jest naszą odpowiedzią, nie jestem pewna, czy warto wykonać te opcje.

Jeśli chcesz udowodnić lub zakwestionować, możesz usunąć CBLAS z programu testowego i po prostu zaimplementować klasę z wieloma metodami podpisu, które różnią się tylko typem danych.

Na marginesie głównym kolumną jest poważny ból.

+0

Czy możesz wyjaśnić, co masz na myśli przez podpis? Moje zrozumienie było takie samo jak typ zwrotu i ten sam typ argumentu + liczba => ten sam podpis. –

+0

Tak, zgadzam się z tym. Ale twoje typy parametrów nie są takie same. Spójrz na wersję beta. Jest to funkcja pływająca w funkcjach SGE i podwójna w funkcjach DGE. Niedawno pracowałem z BLAS, niejasno przypominam sobie, że typy danych, które te funkcje działają, to różnica między D prefixed (double) i S prefixed (domyślam się singiel, który zmienia się w float po przeniesieniu do C++). – Evan

+0

O mój Boże. [Myślałem, że] tak uważnie czytałem te listy argumentów. Masz całkowitą rację. Dziękuję bardzo. –

Powiązane problemy