Что отличает эти программы LAPACK? Один компилируется, другой нет

У меня есть две программы, использующие подпрограмму LAPACK dgeev в C. Одна работает, другая не компилируется, заявляя о неопределенной ссылке на dgeev. Я пытаюсь понять, почему.

Первый приведенный ниже код, называемый mamapack.c, дает разумные результаты при компиляции и запуске следующим образом:

ludi@ludi-M17xR4:~/Desktop/tests$ gcc -o mamapack mamapack.c -L/usr/local/lib -llapack -lblas && ./mamapack

#include<stdio.h>
#include<math.h>

#include <stdlib.h>

//...........................................................................
void dgeTranspose( double *Transposed, double *M ,int n) {
  int i,j;
  for(i=0;i<n;i++)
    for(j=0;j<n;j++)
      Transposed[i+n*j] = M[i*n+j];
}
//...........................................................................
//  MatrixComplexEigensystem: computes the eigenvectors and eigenValues of input matrix A
//  The eigenvectors are stored in columns
//............................................................................
void MatrixComplexEigensystem( double *eigenvectorsVR, double *eigenvaluesW, double *A, int N) {
  int i;
  double *AT = (double *) malloc( N*N*sizeof(double ) );
  dgeTranspose( AT, A , N);
  char JOBVL ='N';   // Compute Right eigenvectors
  char JOBVR ='V';   // Do not compute Left eigenvectors
  double VL[1];
  int LDVL = 1; 
  int LDVR = N;
  int LWORK = 4*N; 
  double *WORK =  (double *)malloc( LWORK*sizeof(double));   
  double *RWORK = (double *)malloc( 2*N*sizeof(double));
  int INFO;
  double *eigenvaluesWR =eigenvaluesW;
  double *eigenvaluesWI = eigenvaluesW + N;
  dgeev_( &JOBVL, &JOBVR, &N, AT ,  &N,
       eigenvaluesWR, eigenvaluesWI,
       VL, &LDVL, 
       eigenvectorsVR, &LDVR, 
       WORK, &LWORK, &INFO );
  printf("\nping1\n");

  dgeTranspose( AT, eigenvectorsVR , N);

  for(i=0;i<N*N;i++) eigenvectorsVR[i]=AT[i];

  free(WORK);
  free(RWORK);
  free(AT);
}

int main() {
  int i,j;
  const int N = 3;
  double A[] = { 1. , 0. ,  0. , 0. , 1., 0. , 0., 0., 1.};
  double eigenVectors[N*N];
  double eigenValues[2*N];

  MatrixComplexEigensystem( eigenVectors, eigenValues, A, N);

  printf("\nEigenvectors\n");

  for(i=0;i<N;i++){
    for(j=0;j<N;j++) printf("%e ", eigenVectors[i*N + j]);
    printf("\n");
  }

  printf("\nEigenvalues \n");
  for(i=0;i<N;i++) printf("%e ",  eigenValues[i] );
  printf("\n--------------------------------------------------------\n"); 

  return 0;
}

Затем я запустил другой код, который я назвал lapack1.c, который является просто официальным «Примером программы на C» из этой документации: https://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/mkl_lapack_examples/dgeev.htm (смею не размещать его отдельно из-за потенциальных ограничений авторского права)

ludi@ludi-M17xR4:~/Desktop/tests$ gcc -o lapack1 lapack1.c -L/usr/local/lib -llapack -lblas && ./lapack1

производит

tmp/cciRzQru.o: В функции main': lapack1.c:(.text+0xf3): undefined reference todgeev' lapack1.c:(.text+0x1b6): неопределенная ссылка на `dgeev' collect2: ошибка: ld вернул 1 статус выхода


person Ludi    schedule 28.05.2015    source источник
comment
Это сообщение компоновщика, а не компилятора. Видимо вы пропустили подкладку библиотеки или объектного файла. Может быть, отсутствует пакет, который включает библиотеку с символом dgeev (вызывается из dgeTranspose()?)? (не знаю, что это будет). Примечание; не переводите void * как возвращенное malloc() И вы не должны использовать прописные буквы для переменных. Они обычно используются для констант и здесь вводят в заблуждение.   -  person too honest for this site    schedule 28.05.2015
comment
@Olaf 49 Извините, я был не уверен, так как не могу их различить и плохо понимаю. Что я должен исследовать? Почему другая программа запускается с помощью dgeev?   -  person Ludi    schedule 28.05.2015
comment
Блондинка по телефону доктору: Доктор, у меня чешется с этой стороны. Доктор: Пожалуйста, поднимите рубашку и покажите мне.   -  person too honest for this site    schedule 28.05.2015
comment
@ Олаф 49 двойное лицо ;)   -  person Ludi    schedule 28.05.2015
comment
Я не понимаю, что это значит. Культурные ссылки проблематичны на международном форуме.   -  person too honest for this site    schedule 28.05.2015
comment
Я имел в виду, то, что могло показаться шуткой о блондинках, превратилось в шутку о врачах. На самом деле эта фраза, вероятно, работает только на моем родном языке (с французским произношением). Я новичок в этом сообществе. Боюсь, модераторы могут наказать нас за злоупотребление разделом комментариев.   -  person Ludi    schedule 28.05.2015
comment
Давайте продолжим это обсуждение в чате.   -  person Ludi    schedule 28.05.2015
comment
Шутка на самом деле была связана с вашим вопросом и дружеским намеком! Чтобы понять, нужно знать, что когда-то в телефонах не было камеры, поэтому был только звук (где-то до нашей эры). Теперь подумайте об этом!   -  person too honest for this site    schedule 28.05.2015
comment
@ Олаф 49 Это я понял. Так я понял шутку, что врач еще более невежественен, чем пациентка, и просит ее показать себя по аналоговому телефону...   -  person Ludi    schedule 28.05.2015
comment
эм.. нет, не было. На самом деле это была аналогия: вы спрашиваете о чем-то, что мне нужно было бы знать (видеть) в вашей среде, например, что установлено в вашем /ur/local/lib/ и где будет этот отсутствующий символ. Без камеры - понятно? Дело в том, что блондинка спрашивает что-то, на что, очевидно, нельзя дать удаленный ответ, поскольку отсутствует информация. Однако вам лучше продолжить ответ Джона.   -  person too honest for this site    schedule 28.05.2015


Ответы (1)


Внимательно проверьте имена функций. Компоновщик жалуется на неопределенную ссылку на функцию dgeev(). Рабочий код вызывает другую функцию с именем dgeev_().

Компилируется с опцией -D следующим образом:

ludi@ludi-M17xR4:~/Desktop/tests$ gcc -Ddgeev=dgeev_ -o lapack1 lapack1.c -L/usr/local/lib -llapack -lblas && ./lapack1

Действительно будет работать.

person John Bollinger    schedule 28.05.2015
comment
Извинения. Я видел это. Но это официальный пример кода. Я не ожидал, что придется что-то менять внутри. - person Ludi; 28.05.2015
comment
Но, конечно, вы правы. В этом разница. Возможно, тогда возникает вопрос, как должен быть скомпилирован код, если не с теми же параметрами, что и другой. - person Ludi; 28.05.2015
comment
Вы используете интерфейс Fortran для LAPACK. Пример кода может предполагать реализацию LAPACK, скомпилированную с набором инструментов, который не искажает имена функций Fortran. Ваша установленная библиотека, с другой стороны, была построена с набором инструментов, который действительно искажает имена функций Fortran, что не является чем-то необычным. GForran делает это, конечно. - person John Bollinger; 28.05.2015
comment
Вы должны вызывать функции через их настоящие имена. Если вы не хотите изменять код C, используйте макрос препроцессора, чтобы исправить соответствующие имена функций (при необходимости это можно определить в командной строке). - person John Bollinger; 28.05.2015