Разница между функциями 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,

Другие вопросы по тегам