2015-07-01 8 views
2

Предположим, что я хочу использовать LAPACK для решения системы линейных уравнений в C (GCC). Я создал эту проблему следующим образом:Разница между функциями xxxxx_(), LAPACK_xxxxx() и LAPACKE_xxxxx()

/* Want to solve Ax=b */ 
int n = ...;  // size 
double *A = ...; // nxn matrix 
double *b = ...; // length-n vector 
int m = 1;  // number of columns in b (needs to be in a variable) 
double *pivot; // records pivoting 
int info;   // return value 

Теперь я, кажется, можно использовать один из трех функций, чтобы решить эту проблему. Первый заключается в следующем:

dgesv_(&n, &m, A, &n, pivot, b, &n, &info); 

Я был удивлен, увидев, что это не требует каких-либо #include с, что кажется ... странно.

Вторая функция имеет почти такую ​​же подпись, для префикса LAPACK_, который я думаю, вызывает меньше двусмысленности и, возможно, является исключением менее подвержен ошибкам:

#include <lapack/lapacke.h> 
LAPACK_dgesv(&n, &m, A, &n, pivot, b, &n, &info); 

Обратите внимание, что это требует от меня, чтобы включить lapacke.h.

Третья функция изменяет подпись несколько вернув info и не принимать все аргументы в качестве указателей:

#include <lapack/lapacke.h> 
info = LAPACKE_dgesv(LAPACK_COL_MAJOR, n, m, A, n, pivot, b, n); 

Опять же, эта функция требует lapacke.h. Это также требует ссылки на дополнительную библиотеку с -llapacke. Все три функции нуждаются в -llapack.

Я пытаюсь выяснить различия между этими функциями. Я сделал некоторые шныряли и я нашел следующие макросы в lapacke.h и связанные файлы заголовков:

#define LAPACK_GLOBAL(name,NAME) name##_ 
#define LAPACK_dgesv LAPACK_GLOBAL(dgesv,DGESV) 

Таким образом, кажется, что LAPACK_dgesv() и dgesv_() разные названия для той же самой функции. Однако оказалось, что LAPACKE_dgesv() - это что-то другое, возможно, с другой реализацией, особенно учитывая тот факт, что ему нужна дополнительная библиотека.

Итак, мой вопрос: каковы различия между этими двумя функциями? В документации указано, что LAPACKE является интерфейсом C для LAPACK, но как насчет функции dgesv_()? Очевидно, что я могу использовать его, как правило, без LAPACKE и без компиляции чего-либо в Fortran, так как это отличается?

Спасибо.


Update

Любопытно, что функция dgemm_() (матричное умножение) не имеет никакого LAPACK_dgemm() эквивалента. Что происходит?

+2

DGEMM не является процедурой LAPACK. DGESV_ - символ Фортрана, принимающий одностороннее соглашение о подчеркивании. Для этого нужно использовать целое число правильного размера для Fortran. – Jeff

ответ

2
  • Обратите внимание, что LAPACKE_dgesv() имеет дополнительный флаг, который может быть LAPACK_COL_MAJOR (обычный Fortran порядок) или LAPACK_ROW_MAJOR (обычно, с порядка). В случае LAPACK_COL_MAJOR он просто вызывает LAPACK_dgesv(). В случае LAPACK_ROW_MAJOR, LAPACKE_dgesv() транспонирует матрицу перед вызовом LAPACK_dgesv().Это не новая реализация dgesv_(). Взгляните на lapack-3.5.0/lapacke/src/dgesv_work.c В этом файле содержатся небольшие изменения в обработке ошибок.

  • LAPACK_dgesv() определен в заголовке lapacke.h как LAPACK_GLOBAL(dgesv,DGESV). Макрос LAPACK_GLOBAL определяется в lapacke_mangling.h: он просто обертывает dgesv_ и заботится об именовании, если используются другие соглашения.

Таким образом, в основном, функция LAPACK_dgesv() просто требует заголовки lapacke. По сравнению с dgesv_ можно избежать некоторых проблем, связанных с соглашениями об именах в библиотеках. Но LAPACK_dgesv() точно так же, как dgesv_(). Функция LAPACKE_dgesv() расширяет область применения LAPACK_dgesv() для обработки обычной c-матрицы. Но она по-прежнему вызывает dgesv_ в конце.

Функция dgemm() является частью библиотеки BLAS. Обернутую версию c cblas_dgemm() можно найти в CBLAS. Опять же, необходим дополнительный флаг CBLAS_ORDER с возможными значениями CblasRowMajor и CblasColMajor.

+0

А, я думаю, это имеет смысл сейчас. Вызов LAPACKE «Интерфейс C для LAPACK» меня смутил, но я предполагаю, что это просто означает, что функции более дружественны к C. Значит ли это, что разница в производительности незначительна? (при условии, что LAPACKE использует, по крайней мере, порядок столбцов) – jadhachem

+1

Да, разница в производительности незначительна, поскольку используется «LAPACK_COL_MAJOR». Что касается 'LAPACK_ROW_MAJOR', есть дополнительные требования к памяти из-за транспонированных матриц. Сложность операции транспонирования - [O (n^2)] (http://cs.stackexchange.com/questions/10081/what-is-the-complexity-this-matrix-transposition) и сложность dgesv является [O (n^3)] (http://stackoverflow.com/questions/12660052/time-complexity-of-scipy-linalg-solve-lapack-gesv-on-large-matrix). Таким образом, разницу в производительности можно пренебречь, даже если используется «LAPACK_ROW_MAJOR». – francis