Разница между функциями xxxxx_(), LAPACK_xxxxx() и LAPACKE_xxxxx()
Допустим, я хочу использовать LAPACK для решения системы линейных уравнений в C (GCC). Я поставил проблему следующим образом:
/* 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, так как это отличается?
Благодарю.
Обновить
Любопытно, что функция dgemm_()
(матричное умножение) не имеет никакого LAPACK_dgemm()
эквивалент. В чем дело?
1 ответ
Заметить, что
LAPACKE_dgesv()
имеет дополнительный флаг, который может бытьLAPACK_COL_MAJOR
(обычный фортран) илиLAPACK_ROW_MAJOR
(обычный заказ c). В случае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()
нужны только заголовки лапаке. По сравнению с dgesv_
можно избежать некоторых проблем, связанных с соглашениями об именах в библиотеках. Но LAPACK_dgesv()
точно так же, как dgesv_()
, Функция LAPACKE_dgesv()
расширяет сферу LAPACK_dgesv()
обрабатывать обычную матрицу c. Но это все еще вызывает dgesv_
в конце.
Функция dgemm()
является частью библиотеки BLAS. Завернутая версия c cblas_dgemm()
можно найти в CBLAS. Опять же, дополнительный флаг CBLAS_ORDER
требуется, с возможными значениями CblasRowMajor
а также CblasColMajor
,