【问题标题】:What distinguishes these LAPACK programmes? One compiles, the other does not这些 LAPACK 计划有什么区别?一个编译,另一个不编译
【发布时间】:2015-05-28 19:07:46
【问题描述】:

我有两个程序在 C 中使用 LAPACK 例程 dgeev。一个似乎正在工作,另一个没有编译,声称对 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 个退出状态

【问题讨论】:

  • 这是来自链接器的消息,而不是编译器。显然您错过了为库或目标文件添加内容。可能是一个缺少的包,其中包含一个带有“dgeev”(从 dgeTranspose() 调用?)符号的库? (不知道那会是什么)。边注;不要将void * 转换为malloc() 返回的内容,并且您不应该对变量使用大写字母。这些通常用于常量,在这里会产生误导。
  • @Olaf 49 抱歉,我不确定,因为我无法区分它们,而且我不太了解这一点。我应该调查什么?为什么其他程序使用 dgeev 运行?
  • 金发女郎给医生打电话:“医生,我这边有点痒。”医生:“所以请掀开你的衬衫给我看。”
  • @Olaf 49 双面 ;)
  • 我不明白这是什么意思。文化参考在国际论坛中存在问题。

标签: c gcc lapack


【解决方案1】:

仔细检查您的函数名称。链接器抱怨对函数 dgeev() 的未定义引用。工作代码正在调用另一个名为 dgeev_() 的函数。

使用选项-D编译如下:

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

确实有效。

【讨论】:

  • 道歉。我看到了。但它是官方示例代码。我没想到必须改变里面的任何东西。
  • 当然你是对的。那是一个区别。那么问题可能就变成了,如果不使用与另一个相同的选项,应该如何编译代码。
  • 您正在使用 Fortran 接口连接 LAPACK。示例代码可能假定使用不会破坏 Fortran 函数名称的工具链编译的 LAPACK 实现。另一方面,您安装的库是使用 确实 修改 Fortran 函数名称的工具链构建的,这并不罕见。 GFortran 确实做到了。
  • 您应该通过函数的实际名称调用函数。如果您不想更改 C 代码,请使用预处理器宏来更正相关的函数名称(如果需要,可以在命令行中定义)。
猜你喜欢
  • 1970-01-01
  • 2011-09-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 2017-02-11
相关资源
最近更新 更多