Использование GotoBLAS2 с C - PullRequest
       11

Использование GotoBLAS2 с C

0 голосов
/ 01 сентября 2011

Я вроде новичка в C-кодировании, но я написал программу Matlab для имитации нейронных сетей, и я хочу перевести ее в C-код, потому что наш суперкомпьютерный кластер не позволит запускать больше, чем несколько симуляций Matlab в один раз. С этой целью я нашел GotoBLAS, чтобы заботиться о математике.

К сожалению, я не уверен, как его использовать, так как у меня нет большого опыта в C и использовании внешних библиотек. Я предполагаю, что «dgemm» - это функция в GotoBLAS, прочитав руководство PDF BLAS. Я был в состоянии успешно скомпилировать GotoBLAS, но когда я делаю:

gcc -o outputprog main.c -Wall -L -lgoto2.a

Я получаю сообщения:

undefined reference to 'dgemm'

Насколько я понимаю, я должен включить какой-нибудь файл .h (или, возможно, нет) из GotoBLAS, но я не уверен, какой именно (или если это вообще верно).

Любая помощь с этим будет оценена. Дайте мне знать, если потребуется дополнительная информация.

Ответы [ 2 ]

6 голосов
/ 01 сентября 2011

Одной из проблем может быть то, что опция -L ожидает имя «каталога» после него, и поэтому gcc (или компоновщик, вызываемый gcc) обрабатывает -lgoto2.a как каталог. Компилятор не жалуется на несуществующие каталоги; это просто игнорирует их. В каком каталоге вы ожидали найти библиотеку? (Для целей этого ответа я предполагаю, что он находится в /usr/local/lib.)

Другая проблема может заключаться в том, что библиотека не называется libgoto2.a.a или libgoto2.a.so или чем-то подобным. Обычно вы не указали бы суффикс .a. (Для целей этого ответа я предполагаю, что библиотека либо libgoto2.a, либо libgoto2.so.)

Похоже, вам не нужно указывать, где находятся заголовки; это означает, что они находятся в достаточно обычном месте, что компилятор смотрит туда в любом случае. Если это правильно, библиотека тоже может находиться в достаточно обычном месте, и опция -L может быть ненужной.

Итак, вы можете использовать:

gcc -Wall -o outputprog main.c -lgoto2

Или вам может понадобиться:

gcc -Wall -o outputprog main.c -L/usr/local/lib -lgoto2

После некоторого подробного обсуждения в комментариях и информации о том, что библиотека находится в текущем каталоге и называется libgoto2.a и что символ dgemm по-прежнему отсутствует, я скачал GotoBLAS2 версии 1.13 и попытался скомпилировать его на полу-поддерживаемой платформе (MacOS X, вероятно, претендующий на Linux, с архитектурой x86_64). Сборка не была полностью успешной - проблемы в коде ассемблера. Однако, оглядываясь на заголовки, есть один, который выглядит как решение ваших проблем:

cblas.h

В этом, среди многих других определений функций, мы находим:

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

Все функциональные символы в заголовке имеют префикс cblas_. Ваш код должен использовать:

#include "cblas.h"

Вы должны вызывать функции, используя имя Фортрана (в нижнем регистре) с префиксом cblas_:

cblas_dgemm(...);

И правильная линия связи - это первая опция, указанная выше:

gcc -Wall -o outputprog main.c -lgoto2

В крайнем случае, вы можете определить макросы для сопоставления обычных (без префикса) имен с правильными именами функций C, но я не уверен, что оно того стоит:

#define DGEMM cblas_dgemm

или (безопаснее, потому что он проверяет длину списка аргументов, но более многословно):

#define DGEMM(a,b,c,d,e,f,g,h,i,j,k,l,m,n) cblas_dgemm(a,b,c,d,e,f,g,h,i,j,k,l,m,n)

Вы можете написать:

DGEMM(a, ..., n);

и будет вызвана правильная функция.


Эксперимент с частично успешной сборкой GotoBLAS2, упомянутой выше, показывает, что:

  • cblas.h не является автономным (в отличие от хороших стандартов кодирования).
  • common.h должно быть включено до него.
  • common.h включает в себя множество других заголовков:
    • config.h
    • common_x86_64.h
    • param.h
    • common_param.h
    • common_interface.h
    • common_macro.h
    • common_s.h
    • common_d.h
    • common_q.h
    • common_c.h
    • common_z.h
    • common_x.h
    • common_level1.h
    • common_level2.h
    • common_level3.h
    • common_lapack.h
  • Следующий код дает возможность связать с полной библиотекой:

    #include "common.h"
    #include "cblas.h"
    
    void check_dgemm(void)
    {
        double A[33] = { 0.0 };
        double B[33] = { 0.0 };
        double C[33] = { 0.0 };
        cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
                    3, 3, 3, 2.0, A, 3, B, 3, 3.0, C, 3);
    }
    
    int main(void)
    {
        check_dgemm();
        return 0;
    }
    

    (В моей, по общему признанию, неработающей сборке библиотеки, жалобы перешли от «cblas_dgemm() not found» к ряду других отсутствующих функций. Это огромное улучшение!)

3 голосов
/ 02 сентября 2011

Хорошо. Мне удалось найти ответ в списке рассылки GotoBLAS https://lists.tacc.utexas.edu/mailman/listinfo/gotoblas (которого нет на сайте, насколько я вижу). Вот быстрый шаг за шагом по использованию GotoBLAS2 с компилятором C и GCC.

Сборка библиотек GotoBLAS2 (.so и .a), в них есть хорошая документация, поэтому я не буду публиковать ее здесь. Включите ОБА этих файлов в каталог libs по вашему выбору, как установлено -L. Я включил только одну, потому что думал, что это просто разные версии одной и той же библиотеки, что было неверно.

Также ссылка на -lgfortran также, если вы хотите скомпилировать с gcc. -lpthread также может быть полезно, хотя я не уверен, я видел примеры с ним, но он компилируется без. Ваш gcc должен выглядеть примерно так:

gcc -Wall -o outprog -L./GotoLIBSDIR -lgoto2 -lgfortran -lpthread(maybe) main.c

Наконец, вызовите function_() вместо function(), например, dgemm_() при использовании gfortran для компиляции интерфейсов fortran.

В качестве альтернативы интерфейсу fortran интерфейс cblas может использоваться как cblas_dgemm(). Вам по-прежнему необходимо указать ссылку на -lgfortran, поскольку в противном случае ссылка на libgoto2.so не удастся выполнить, и вам необходимо указать ссылку на этот файл, чтобы можно было правильно использовать cblas_dgemm().

Кажется, нет необходимости включать какие-либо файлы .h или что-либо еще.

Надеюсь, кто-то еще найдет это полезным. Спасибо за помощь!

...