Связывание C++ с BLAS и LAPACK

Чтобы вызвать подпрограмму Fortran из С++, я использовал: extern "C" void procedurename_(...) с добавленным символом подчеркивания, делающим это совместимым с именем подпрограммы Fortran "ROUTINENAME".

Когда я связываю С++ с BLAS или LAPACK, он работает только БЕЗ подчеркивания. В чем разница между компоновкой С++ с этими библиотеками, написанными на Фортране, что делает подчеркивание ненужным?


person user99439    schedule 12.08.2013    source источник
comment
Вы слышали о LAPACKE (интерфейс C к Lapack)? Существует также интерфейс C для BLAS.   -  person Stefan    schedule 13.08.2013


Ответы (2)


Я могу ошибаться, учитывая, что информации очень мало, но...

Из здесь: первые компиляторы F77 добавили _ к именам функций в ABI. Это поведение отличается от C, который просто берет имя функции и использует его в качестве имени в ABI.

Некоторые компиляторы F77 вели себя по-другому, вместо этого вводя все имя подпрограммы в верхний регистр, так что foo() становилось FOO() при просмотре C. Компиляторы UNIX Fortran имитировали поведение C и просто копировали и вставляли имя, так что foo() также было foo() в ABI.

Если вы посмотрите на привязки BLAS к C для эталонной реализации здесь, вы увидите, что они обрабатывают конечные символы подчеркивания при работе с F77. Могу поспорить, что подчеркивания были гораздо более распространенной чертой F77 ABI в прошлом, чем их отсутствие.

Позже в Fortran 2003 появилась совместимость с C (см. здесь) . Это сделало схему именования функций одинаковой при использовании определенных конструкций Фортрана (см. -Функции" rel="nofollow">здесь).

Таким образом, я собираюсь сделать дикое предположение, что это как-то связано с различиями ABI в версиях Fortran. Или даже просто для разных компиляторов, учитывая, что разные компиляторы ведут себя в Фортране по-разному.

Итак, опять же, я не уверен, соответствует ли это вашей ситуации, учитывая, что в вашем вопросе не так много всего, но я не смог уместить все это в комментарий, так что вот он как «ответ». .

И ЕСЛИ Я НЕПРАВ, СКАЖИТЕ МНЕ, ЧТОБЫ Я МОГУ ИСПРАВИТЬ МАХ' ПОСТ.

tl;dr: потому что версии компилятора

person user    schedule 13.08.2013

Я помещаю общий ответ для связывания BLAS не только с этим вопросом, но и с ответом на этот вопрос в конце ниже.

сначала вам нужно убедиться, что у вас установлен BLAS с помощью (+lapack)

$ sudo apt-get установить libblas-dev libblapack-dev

затем вы можете связать с помощью -lblas после файлов вашей программы. или вы можете использовать файл make.

например: g++ test.o dmatrix_denseCM.o mmio.o -o output -lblas

со своей стороны, я предпочитаю использовать OpenBlas, вы можете использовать следующее в make-файле.

  1. www.openblas.net, получите tar.gz и скопируйте его в свой каталог
  2. извлеките его: tar -zxvf OpenBLAS-0.2.20.tar.gz
  3. скомпилировать: cd OpenBLAS-0.2.20 make

Когда это будет сделано, у вас должен быть файл libopenblas.a, библиотека openblas

  • BLASLIB = OpenBLAS/libopenblas.a -lpthread, затем добавьте его в файл, связанный вместе как: $(BLASLIB)

этот каталог OpenBLAS/libopenblas.a должен находиться в том же рабочем каталоге.

пример кода в файле .cc:

extern "C"{
  void dgemm_( const char &TRANSA, const char &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);
}

Кроме того, при вызове подпрограмм LAPACK или BLAS из C следует помнить, что, поскольку язык Фортран не чувствителен к регистру, имена подпрограмм могут быть как в верхнем, так и в нижнем регистре, с символом подчеркивания в конце или без него. Например, следующие имена эквивалентны:

LAPACK: dgetrf, DGETRF, dgetrf_ и DGETRF_

BLAS: dgemm, DGEMM, dgemm_ и DGEMM_ Библиотека ядра Intel® Math 11.3, обновление 4. Руководство разработчика

вы можете добавить дополнительную информацию о компиляторе FORTRAN, который вы использовали для компиляции BLAS, например:

Скомпилируйте программу на Фортране с параметром -U, который указывает компилятору сохранять существующие различия между прописными и строчными буквами в именах функций/подпрограмм.

Компилятор Fortran обычно добавляет символ подчеркивания (_) к именам подпрограмм, появляющимся как в определении точки входа, так и в вызовах. Это соглашение отличается от процедур C или внешних переменных с тем же именем, назначаемым пользователем. здесь

Изменение имени в C++ создает проблему в C. Поскольку C не поддерживает перегрузку, мы должны использовать extern c{}.

person Ibrahim zawra    schedule 03.03.2021