1

I was previously using Armadillo with blas and lapack but have decided to use OpenBlas to speed up computations. I have followed the steps given in this link and compiled OpenBlas in MinGW to generate libopenblas.dll and libopenblas.dll.a. Now I have tried to use these in an example application in VS 2012 and found linker errors related to OpenBlas. What am I doing wrong?

The example is given below:

#include <iostream>
#include <armadillo>

using namespace std;
using namespace arma;


int
main(int argc, char** argv)
{
  cout << "Armadillo version: " << arma_version::as_string() << endl;

  mat A(2,3);  // directly specify the matrix size (elements are uninitialised)

  cout << "A.n_rows: " << A.n_rows << endl;  // .n_rows and .n_cols are read only
  cout << "A.n_cols: " << A.n_cols << endl;

  A(1,2) = 456.0;  // directly access an element (indexing starts at 0)
  A.print("A:");


  A = 5.0;         // scalars are treated as a 1x1 matrix
  A.print("A:");


  A.set_size(4,5); // change the size (data is not preserved)

  A.fill(5.0);     // set all elements to a particular value
  A.print("A:");

  // endr indicates "end of row"
  A << 0.165300 << 0.454037 << 0.995795 << 0.124098 << 0.047084 << endr
    << 0.688782 << 0.036549 << 0.552848 << 0.937664 << 0.866401 << endr
    << 0.348740 << 0.479388 << 0.506228 << 0.145673 << 0.491547 << endr
    << 0.148678 << 0.682258 << 0.571154 << 0.874724 << 0.444632 << endr
    << 0.245726 << 0.595218 << 0.409327 << 0.367827 << 0.385736 << endr;

   A.print("A:");

  // determinant
  cout << "det(A): " << det(A) << endl;

  // inverse
  cout << "inv(A): " << endl << inv(A) << endl;

  // save matrix as a file
  A.save("A.txt", raw_ascii);

  // load from file
  mat B;
  B.load("A.txt");

  // submatrices
  cout << "B( span(0,2), span(3,4) ):" << endl << B( span(0,2), span(3,4) ) << endl;

  cout << "B.row(0): " << endl << B.row(0) << endl;

  cout << "B.col(1): " << endl << B.col(1) << endl;

 // transpose
  cout << "B.t(): " << endl << B.t() << endl;

  // maximum from each column (traverse along rows)
  cout << "max(B): " << endl << max(B) << endl;

  // maximum from each row (traverse along columns)
  cout << "max(B,1): " << endl << max(B,1) << endl;

  // maximum value in B
  cout << "max(max(B)) = " << max(max(B)) << endl;

  // sum of each column (traverse along rows)
  cout << "sum(B): " << endl << sum(B) << endl;

  // sum of each row (traverse along columns)
  cout << "sum(B,1) =" << endl << sum(B,1) << endl;

  // sum of all elements
  cout << "accu(B): " << accu(B) << endl;

  // trace = sum along diagonal
  cout << "trace(B): " << trace(B) << endl;

  // generate the identity matrix
  mat C = eye<mat>(4,4);

  // random matrix with values uniformly distributed in the [0,1] interval
  mat D = randu<mat>(4,4);
  D.print("D:");

  // row vectors are treated like a matrix with one row
  rowvec r;
  r << 0.59119 << 0.77321 << 0.60275 << 0.35887 << 0.51683;
  r.print("r:");

  // column vectors are treated like a matrix with one column
  colvec q;
  q << 0.14333 << 0.59478 << 0.14481 << 0.58558 << 0.60809;
  q.print("q:");

  // dot or inner product
  cout << "as_scalar(r*q): " << as_scalar(r*q) << endl;

  // outer product
  cout << "q*r: " << endl << q*r << endl;

  // multiply-and-accumulate operation (no temporary matrices are created)
  cout << "accu(A % B) = " << accu(A % B) << endl;

  // example of a compound operation
  B += 2.0 * A.t();
  B.print("B:");

  // imat specifies an integer matrix
  imat AA;
  imat BB;

  AA << 1 << 2 << 3 << endr << 4 << 5 << 6 << endr << 7 << 8 << 9;
  BB << 3 << 2 << 1 << endr << 6 << 5 << 4 << endr << 9 << 8 << 7;

  // comparison of matrices (element-wise); output of a relational operator is a umat
  umat ZZ = (AA >= BB);
  ZZ.print("ZZ:");

  // cubes ("3D matrices")
  cube Q( B.n_rows, B.n_cols, 2 );

  Q.slice(0) = B;
  Q.slice(1) = 2.0 * B;

  Q.print("Q:");

  // 2D field of arbitrary length row vectors (fields can also store abitrary objects, eg. instances of std::string)
  field<rowvec> xyz(3,2);

  xyz(0,0) = randu(1,2);
  xyz(1,0) = randu(1,3);
  xyz(2,0) = randu(1,4);
  xyz(0,1) = randu(1,5);
  xyz(1,1) = randu(1,6);
  xyz(2,1) = randu(1,7);

  cout << "xyz:" << endl;
  cout << xyz << endl;

  return 0;
 }

The linker errors are:

 1>example1.obj : error LNK2019: unresolved external symbol ddot_ referenced in function "public: static void __cdecl arma::syrk_vec<1,1,0>::apply<double,class arma::Col<double> >(class arma::Mat<double> &,class arma::Col<double> const &,double,double)" (??$apply@NV?$Col@N@arma@@@?$syrk_vec@$00$00$0A@@arma@@SAXAEAV?$Mat@N@1@AEBV?$Col@N@1@NN@Z)
 1>example1.obj : error LNK2019: unresolved external symbol dgemv_ referenced in function "public: static void __cdecl arma::gemv<1,1,0>::apply_blas_type<double,class arma::Col<double> >(double *,class arma::Col<double> const &,double const *,double,double)" (??$apply_blas_type@NV?$Col@N@arma@@@?$gemv@$00$00$0A@@arma@@SAXPEANAEBV?$Col@N@1@PEBNNN@Z)
 1>example1.obj : error LNK2019: unresolved external symbol dgemm_ referenced in function "public: static void __cdecl arma::gemm<1,1,1,0>::apply_blas_type<double,class arma::Col<double>,class arma::Row<double> >(class arma::Mat<double> &,class arma::Col<double> const &,class arma::Row<double> const &,double,double)" (??$apply_blas_type@NV?$Col@N@arma@@V?$Row@N@2@@?$gemm@$00$00$00$0A@@arma@@SAXAEAV?$Mat@N@1@AEBV?$Col@N@1@AEBV?$Row@N@1@NN@Z)
 1>example1.obj : error LNK2019: unresolved external symbol dsyrk_ referenced in function "public: static void __cdecl arma::syrk<1,1,0>::apply_blas_type<double,class arma::Col<double> >(class arma::Mat<double> &,class arma::Col<double> const &,double,double)" (??$apply_blas_type@NV?$Col@N@arma@@@?$syrk@$00$00$0A@@arma@@SAXAEAV?$Mat@N@1@AEBV?$Col@N@1@NN@Z)
 1>D:\iUH\Research\armadillo-5.200.1\examples\x64\Debug\example1_win64.exe : fatal error LNK1120: 4 unresolved externals
shunyo
  • 1,277
  • 15
  • 32
  • add your build statement please, e.g: 'g++ -larmadilo main.cpp' – hich9n Jun 13 '15 at 06:57
  • I build it in VS 2012 with the `lapack.lib` and `libopenblas.dll.a` with the `liopenblas.dll` in the same folder. – shunyo Jun 13 '15 at 16:09
  • Used the prebuilt binaries and it worked. Have no idea why. – shunyo Jun 18 '15 at 20:05
  • @shunyo : I know this question is long time ago. But have you had the solution? I have the same issue. – Arnold Jun 01 '16 at 10:09
  • Yes, look at the previous comment. Used the prebuilt binaries worked. – shunyo Jun 10 '16 at 14:44
  • I forgot to link BLAS lib files in addition to the LAPACK lib and got the same error messages. If you use static libs, than both the lapack and the blas libs have to be linked into your project as blas is a dependency of lapack – Oliver Zendel Jan 18 '17 at 16:02

0 Answers0