1

我使用“sudo apt install libarpack2-dev”安装了 Arpack。

下一个库位于 /usr/lib 中:

libarpack.a,
libarpack.so,
libarpack.so.2,
libarpack.so.2.0.0

我想从名为 ising.cpp 的 cpp 文件中调用此库中的 dsaupd 子例程。

运行“make --debug”时出现错误

undefined reference to `dsaupd_'
collect2: error: ld returned 1 exit status

我在从 fortran 库中调用子例程方面经验不足,无法弄清楚问题出在哪里。

需要哪些修改:

  • 解决未定义的引用错误
  • 成功调用子程序

编辑:第一部分似乎通过将 l 标志放在 cpp 文件之后来解决。这会将 g++ 命令更改为

g++ -g -O3 -mavx2 -funroll-loops -std=c++17 -o ising.exe ising.cpp -lblas -llapack -larpack -lgfortran

这与这个问题有关

在能够编译代码之后,我仍然难以调用子例程。运行程序时出现“17713 Segmentation fault (core dumped)”

似乎这个问题与这个问题有关,它基本上归结为按值传递(C++)VS按引用传递(fortran)的不匹配。

make 命令的完整输出(包括实际的 g++ 调用)是 (was)

GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
 File 'all' does not exist.
   File 'ising.exe' does not exist.
  Must remake target 'ising.exe'.
g++ -g -O3 -mavx2 -funroll-loops -std=c++17 -lblas -llapack -larpack -lgfortran -o ising.exe ising.cpp
/tmp/ccyV1Kcn.o: In function `main':
/home/josja/Programs/Ising/ising.cpp:45: undefined reference to `dsaupd_'
collect2: error: ld returned 1 exit status
Makefile:7: recipe for target 'ising.exe' failed
make: *** [ising.exe] Error 1

我要调用的 arpack 例程是这个例程:

c-----------------------------------------------------------------------
c\BeginDoc
c
c\Name: dsaupd 
c
c\Description: 
...
c  dsaupd  is usually called iteratively to solve one of the 
c  following problems:
c
c  Mode 1:  A*x = lambda*x, A symmetric 
c           ===> OP = A  and  B = I.
...
c\Usage:
c  call dsaupd  
c     ( IDO, BMAT, N, WHICH, NEV, TOL, RESID, NCV, V, LDV, IPARAM,
c       IPNTR, WORKD, WORKL, LWORKL, INFO )
c
c\Arguments
c  IDO     Integer.  (INPUT/OUTPUT)
...             
c  BMAT    Character*1.  (INPUT)
...
c  N       Integer.  (INPUT)
...
c  WHICH   Character*2.  (INPUT)
...
c  NEV     Integer.  (INPUT)
...
c  TOL     Double precision  scalar.  (INPUT)
...
c  RESID   Double precision  array of length N.  (INPUT/OUTPUT)
...
c  NCV     Integer.  (INPUT)
...
c  V       Double precision  N by NCV array.  (OUTPUT)
...
c  LDV     Integer.  (INPUT)
...
c  IPARAM  Integer array of length 11.  (INPUT/OUTPUT)
...
c  IPNTR   Integer array of length 11.  (OUTPUT)         -------------------------------------------------------------
...
c  WORKD   Double precision  work array of length 3*N.  (REVERSE COMMUNICATION)
...
c  WORKL   Double precision  work array of length LWORKL.  (OUTPUT/WORKSPACE)
...
c  LWORKL  Integer.  (INPUT)
...
c  INFO    Integer.  (INPUT/OUTPUT)
...
c-----------------------------------------------------------------------
c
      subroutine dsaupd 
     &   ( ido, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, 
     &     ipntr, workd, workl, lworkl, info )
c
c     %----------------------------------------------------%
c     | Include files for debugging and timing information |
c     %----------------------------------------------------%
c
      include   'debug.h'
      include   'stat.h'
c
c     %------------------%
c     | Scalar Arguments |
c     %------------------%
c
      character  bmat*1, which*2
      integer    ido, info, ldv, lworkl, n, ncv, nev
      Double precision 
     &           tol
c
c     %-----------------%
c     | Array Arguments |
c     %-----------------%
c
      integer    iparam(11), ipntr(11)
      Double precision 
     &           resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
c
c     %------------%
c     | Parameters |
c     %------------%
c
      Double precision 
     &           one, zero
      parameter (one = 1.0D+0 , zero = 0.0D+0 )
c
c     %---------------%
c     | Local Scalars |
c     %---------------%
c
      integer    bounds, ierr, ih, iq, ishift, iupd, iw, 
     &           ldh, ldq, msglvl, mxiter, mode, nb,
     &           nev0, next, np, ritz, j
      save       bounds, ierr, ih, iq, ishift, iupd, iw,
     &           ldh, ldq, msglvl, mxiter, mode, nb,
     &           nev0, next, np, ritz

我要从中调用例程的 cpp 文件是 ising.cpp。这是一个避免上述分段错误的版本。

#include <iostream>
#include <bitset>
#include <string>
#include <vector>
using namespace std;

...

extern"C" {
void dsaupd_(int & IDO, char & BMAT, int & N, char WHICH[2], int & NEV,
    double & TOL, double * RESID, int & NCV, double * V, int & LDV,
    int IPARAM[11], int IPNTR[11], double * WORKD,
    double * WORKL, int & LWORKL, int & INFO );
}

int main(int argc, char *argv[]) {
    ...
    int ido = 0;            // Reverse communication flag. (in/out-)
    char bmat = 'I';        // Normal eigenvalue equation. (in)
    int n = 1<<L;           // Dimension of the eigenproblem. (in)
    char which[3] = "SM";   // Compute smallest (in magnitude) eigenvalues. (in)
    int nev = 4;            // Number of eigenvalues to be computed. (in)
    double tol = 0;         // Tolerated error on the eigenvalues. (in)

    double resid[n];        // Will contain the final residual vector. (in/out)
    int ncv = min(n, max(2*nev + 1, 20));   // Number of Lanczos vectors. (in)
    double v[n*ncv];        // Will contain the Lanczos vectors. (out)
    int ldv = n;            //???? Leading dimension of v.??? (in)
    int iparam[11];         // Itaration parameters: (in)
        iparam[0] = 1;          // Exact shifts are used.
        iparam[2] = 300;        // Maximum number of Arnoldi iterations allowed.
        iparam[6] = 1;          // Mode 1 of dsaupd (normal eigenvalue equation).
    int ipntr[11];          // Pointers inside working spaces. (work)
    double workd[3*n];      // Workspace that will contain residuals. (out/work)
    int lworkl = ncv*(ncv+8);   // Size of private workspace. (in/work)
    double workl[lworkl];       // Private workspace. (work)
    int info = 0;           // Randomly initial residual vector is used. (in/out)

    dsaupd_(ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
            iparam, ipntr, workd, workl, lworkl, info );

    ...
}

...

对于stackoverflow:请允许提交问题。您正确识别代码块的工具不起作用,并导致拒绝有用的问题并破坏问题的布局。

4

0 回答 0