BLAS/accelerate related fixes
This commit is contained in:
		
				
					committed by
					
						
						Knut Morten Okstad
					
				
			
			
				
	
			
			
			
						parent
						
							7d0330c715
						
					
				
				
					commit
					d1adf474ec
				
			@@ -1,11 +1,17 @@
 | 
			
		||||
IF (CBLAS_LIBRARIES)
 | 
			
		||||
  SET(CBLAS_FIND_QUIETLY TRUE)
 | 
			
		||||
ENDIF (CBLAS_LIBRARIES)
 | 
			
		||||
if(APPLE)
 | 
			
		||||
  set(CBLAS_LIBRARIES "-framework Accelerate")
 | 
			
		||||
  set(CBLAS_DEFINITIONS -DUSE_ACCELERATE=1)
 | 
			
		||||
else()
 | 
			
		||||
  IF (CBLAS_LIBRARIES)
 | 
			
		||||
    SET(CBLAS_FIND_QUIETLY TRUE)
 | 
			
		||||
  ENDIF (CBLAS_LIBRARIES)
 | 
			
		||||
 | 
			
		||||
FIND_LIBRARY(CBLAS_LIBRARIES
 | 
			
		||||
  NAMES cblas
 | 
			
		||||
  PATHS $ENV{HOME}/lib
 | 
			
		||||
        /usr/lib/atlas/)
 | 
			
		||||
  FIND_LIBRARY(CBLAS_LIBRARIES
 | 
			
		||||
    NAMES cblas
 | 
			
		||||
    PATHS $ENV{HOME}/lib
 | 
			
		||||
          /usr/lib/atlas/)
 | 
			
		||||
  set(CBLAS_DEFINITIONS -DUSE_CBLAS=1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
IF(NOT CBLAS_LIBRARIES)
 | 
			
		||||
  FIND_PACKAGE(BLAS)
 | 
			
		||||
@@ -20,5 +26,5 @@ ENDIF(NOT CBLAS_LIBRARIES)
 | 
			
		||||
 | 
			
		||||
INCLUDE(FindPackageHandleStandardArgs)
 | 
			
		||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CBLAS DEFAULT_MSG
 | 
			
		||||
                                  CBLAS_LIBRARIES)
 | 
			
		||||
                                  CBLAS_LIBRARIES CBLAS_DEFINITIONS)
 | 
			
		||||
MARK_AS_ADVANCED(CBLAS_LIBRARIES)
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,13 @@ ENABLE_LANGUAGE(CXX)
 | 
			
		||||
IF(CMAKE_CXX_COMPILER_ID MATCHES Intel)
 | 
			
		||||
  SET(IFEM_CXX_FLAGS "${IFEM_CXX_FLAGS} -DUSE_MKL -mkl=sequential")
 | 
			
		||||
  SET(IFEM_BUILD_CXX_FLAGS "${IFEM_BUILD_CXX_FLAGS} -DUSE_MKL -mkl=sequential")
 | 
			
		||||
ELSE(CMAKE_CXX_COMPILER_ID MATCHES Intel)
 | 
			
		||||
  SET(IFEM_CXX_FLAGS "${IFEM_CXX_FLAGS} -DUSE_CBLAS")
 | 
			
		||||
  SET(IFEM_BUILD_CXX_FLAGS "${IFEM_BUILD_CXX_FLAGS} -DUSE_CBLAS")
 | 
			
		||||
  FIND_PACKAGE(CBLAS REQUIRED)
 | 
			
		||||
  FIND_PACKAGE(LAPACK REQUIRED)
 | 
			
		||||
ELSE(CMAKE_CXX_COMPILER_ID MATCHES Intel)
 | 
			
		||||
  FIND_PACKAGE(CBLAS REQUIRED)
 | 
			
		||||
  FIND_PACKAGE(LAPACK REQUIRED)
 | 
			
		||||
  SET(IFEM_CXX_FLAGS "${IFEM_CXX_FLAGS} ${CBLAS_DEFINITIONS}")
 | 
			
		||||
  SET(IFEM_BUILD_CXX_FLAGS "${IFEM_BUILD_CXX_FLAGS} ${CBLAS_DEFINITIONS}")
 | 
			
		||||
ENDIF(CMAKE_CXX_COMPILER_ID MATCHES Intel)
 | 
			
		||||
 | 
			
		||||
if(MINGW)
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,7 @@
 | 
			
		||||
#define dgeev_  dgeev
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(USE_CBLAS) || defined(USE_MKL)
 | 
			
		||||
extern "C" {
 | 
			
		||||
//! \brief Adds an element matrix \a eK into the system matrix \a sysK.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the SAM library.
 | 
			
		||||
@@ -53,69 +54,70 @@ void addem2_(const Real* eK, const Real* ttcc, const int* mpar,
 | 
			
		||||
//! \brief Estimates the reciprocal of the condition number of the matrix \b A.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgecon_(const char& norm, const int& n, const Real* A, const int& lda,
 | 
			
		||||
             const Real& anorm, Real& rcond, Real* work, int* iwork, int& info);
 | 
			
		||||
void dgecon_(const char* norm, const int* n, const Real* A, const int* lda,
 | 
			
		||||
             const Real* anorm, Real* rcond, Real* work, int* iwork, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the linear equation system \a A*x=b.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgesv_(const int& n, const int& nrhs,
 | 
			
		||||
	    Real* A, const int& lda, int* ipiv,
 | 
			
		||||
	    Real* B, const int& ldb, int& info);
 | 
			
		||||
void dgesv_(const int* n, const int* nrhs,
 | 
			
		||||
	    Real* A, const int* lda, int* ipiv,
 | 
			
		||||
	    Real* B, const int* ldb, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the equation system \a A*x=b when \a A is already factorized.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgetrs_(const char& trans, const int& n, const int& nrhs,
 | 
			
		||||
	     Real* A, const int& lda, int* ipiv,
 | 
			
		||||
	     Real* B, const int& ldb, int& info);
 | 
			
		||||
void dgetrs_(const char* trans, const int* n, const int* nrhs,
 | 
			
		||||
	     Real* A, const int* lda, int* ipiv,
 | 
			
		||||
	     Real* B, const int* ldb, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Returns a norm of the matrix \b A.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
double dlange_(const char& norm, const int& m, const int& n, const Real* A,
 | 
			
		||||
               const int& lda, Real* work);
 | 
			
		||||
double dlange_(const char* norm, const int* m, const int* n, const Real* A,
 | 
			
		||||
               const int* lda, Real* work);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the symmetric linear equation system \a A*x=b.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dposv_(const char& uplo, const int& n, const int& nrhs,
 | 
			
		||||
            Real* A, const int& lda, Real* B, const int& ldb, int& info);
 | 
			
		||||
void dposv_(const char* uplo, const int* n, const int* nrhs,
 | 
			
		||||
            Real* A, const int* lda, Real* B, const int* ldb, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the symmetric equation system \a A*x=b for prefactored \b A.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dpotrs_(const char& uplo, const int& n, const int& nrhs,
 | 
			
		||||
             Real* A, const int& lda, Real* B, const int& ldb, int& info);
 | 
			
		||||
void dpotrs_(const char* uplo, const int* n, const int* nrhs,
 | 
			
		||||
             Real* A, const int* lda, Real* B, const int* ldb, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the standard eigenproblem \a A*x=(lambda)*x.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dsyevx_(const char& jobz, const char& range, const char& uplo,
 | 
			
		||||
	     const int& n, Real* a, const int& lda,
 | 
			
		||||
	     const Real& vl, const Real& vu, const int& il, const int& iu,
 | 
			
		||||
	     const Real& abstol, const int& m, Real* w, Real* z, const int& ldz,
 | 
			
		||||
	     Real* work, const int& lwork, int* iwork, int* ifail, int& info);
 | 
			
		||||
void dsyevx_(const char* jobz, const char* range, const char* uplo,
 | 
			
		||||
	     const int* n, Real* a, const int* lda,
 | 
			
		||||
	     const Real* vl, const Real* vu, const int* il, const int* iu,
 | 
			
		||||
	     const Real* abstol, const int* m, Real* w, Real* z, const int* ldz,
 | 
			
		||||
	     Real* work, const int* lwork, int* iwork, int* ifail, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the generalized eigenproblem \a A*x=(lambda)*B*x.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dsygvx_(const int& itype, const char& jobz, const char& range,
 | 
			
		||||
	     const char& uplo, const int& n, Real* a, const int& lda,
 | 
			
		||||
	     Real* b, const int& ldb, const Real& vl, const Real& vu,
 | 
			
		||||
	     const int& il, const int& iu, const Real& abstol,
 | 
			
		||||
	     const int& m, Real* w, Real* z, const int& ldz,
 | 
			
		||||
	     Real* work, const int& lwork, int* iwork, int* ifail, int& info);
 | 
			
		||||
void dsygvx_(const int* itype, const char* jobz, const char* range,
 | 
			
		||||
	     const char* uplo, const int* n, Real* a, const int* lda,
 | 
			
		||||
	     Real* b, const int* ldb, const Real* vl, const Real* vu,
 | 
			
		||||
	     const int* il, const int* iu, const Real* abstol,
 | 
			
		||||
	     const int* m, Real* w, Real* z, const int* ldz,
 | 
			
		||||
	     Real* work, const int* lwork, int* iwork, int* ifail, int* info);
 | 
			
		||||
 | 
			
		||||
//! \brief Solves the non-symmetric eigenproblem \a A*x=(lambda)*x.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgeev_(const char& jobvl, const char& jobvr,
 | 
			
		||||
            const int& n, Real* a, const int& lda,
 | 
			
		||||
            Real* wr, Real* wi, Real* vl, const int& ldvl,
 | 
			
		||||
            Real* vr, const int& ldvr,
 | 
			
		||||
            Real* work, const int& lwork, int& info);
 | 
			
		||||
void dgeev_(const char* jobvl, const char* jobvr,
 | 
			
		||||
            const int* n, Real* a, const int* lda,
 | 
			
		||||
            Real* wr, Real* wi, Real* vl, const int* ldvl,
 | 
			
		||||
            Real* vr, const int* ldvr,
 | 
			
		||||
            Real* work, const int* lwork, int* info);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
DenseMatrix::DenseMatrix (size_t m, size_t n, bool s) : myMat(m,n), ipiv(nullptr)
 | 
			
		||||
@@ -469,34 +471,45 @@ bool DenseMatrix::solve (Real* B, size_t nrhs, Real* rcond)
 | 
			
		||||
  if (n > myMat.cols()) return false; // More equations than unknowns
 | 
			
		||||
 | 
			
		||||
  const char* dsolv = symm ? "DGESV" : "DPOSV";
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  int info = 0;
 | 
			
		||||
  int noncons = n;
 | 
			
		||||
  if (symm)
 | 
			
		||||
  {
 | 
			
		||||
    // Matrix is marked as symmetric - use Cholesky instead of full LU
 | 
			
		||||
    if (ipiv)
 | 
			
		||||
      dpotrs_('U',n,nrhs,myMat.ptr(),n,B,n,info);
 | 
			
		||||
    else
 | 
			
		||||
    if (ipiv) {
 | 
			
		||||
      char uplo = 'U';
 | 
			
		||||
      int nr = nrhs;
 | 
			
		||||
      dpotrs_(&uplo,&noncons,&nr,myMat.ptr(),&noncons,B,&noncons,&info);
 | 
			
		||||
    } else
 | 
			
		||||
    {
 | 
			
		||||
      ipiv = new int[1]; // dummy allocation to flag factorization reuse
 | 
			
		||||
      dposv_('U',n,nrhs,myMat.ptr(),n,B,n,info);
 | 
			
		||||
      char uplo = 'U';
 | 
			
		||||
      int nr = nrhs;
 | 
			
		||||
      dposv_(&uplo,&noncons,&nr,myMat.ptr(),&noncons,B,&noncons,&info);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (ipiv)
 | 
			
		||||
    dgetrs_('N',n,nrhs,myMat.ptr(),n,ipiv,B,n,info);
 | 
			
		||||
  else
 | 
			
		||||
  else if (ipiv) {
 | 
			
		||||
    char trans = 'N';
 | 
			
		||||
    int nr = nrhs;
 | 
			
		||||
    dgetrs_(&trans,&noncons,&nr,myMat.ptr(),&noncons,ipiv,B,&noncons,&info);
 | 
			
		||||
  } else
 | 
			
		||||
  {
 | 
			
		||||
    Real anorm;
 | 
			
		||||
    if (rcond) // Evaluate the 1-norm of the original LHS-matrix
 | 
			
		||||
      anorm = dlange_('1',n,n,myMat.ptr(),n,rcond);
 | 
			
		||||
    if (rcond) { // Evaluate the 1-norm of the original LHS-matrix
 | 
			
		||||
      char norm = '1';
 | 
			
		||||
      anorm = dlange_(&norm,&noncons,&noncons,myMat.ptr(),&noncons,rcond);
 | 
			
		||||
    }
 | 
			
		||||
    ipiv = new int[n];
 | 
			
		||||
    dgesv_(n,nrhs,myMat.ptr(),n,ipiv,B,n,info);
 | 
			
		||||
    int nr = nrhs;
 | 
			
		||||
    dgesv_(&noncons,&nr,myMat.ptr(),&noncons,ipiv,B,&noncons,&info);
 | 
			
		||||
    if (rcond && info == 0)
 | 
			
		||||
    {
 | 
			
		||||
      // Estimate the condition number
 | 
			
		||||
      Real* work = new Real[4*n];
 | 
			
		||||
      int* iwork = new int[n];
 | 
			
		||||
      dgecon_('1',n,myMat.ptr(),n,anorm,*rcond,work,iwork,info);
 | 
			
		||||
      char norm='1';
 | 
			
		||||
      dgecon_(&norm,&noncons,myMat.ptr(),&noncons,&anorm,rcond,work,iwork,&info);
 | 
			
		||||
      delete[] work;
 | 
			
		||||
      delete[] iwork;
 | 
			
		||||
    }
 | 
			
		||||
@@ -522,14 +535,20 @@ bool DenseMatrix::solveEig (RealArray& val, Matrix& vec, int nv)
 | 
			
		||||
  if (n < 1 || nv < 1) return true; // No equations to solve
 | 
			
		||||
  if (n > myMat.cols()) return false;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  std::cout <<"  Solving dense eigenproblem using LAPACK::DSYEVX"<< std::endl;
 | 
			
		||||
  int m, info = 0;
 | 
			
		||||
  Real dummy = 0.0;
 | 
			
		||||
  Real abstol = 0.0;
 | 
			
		||||
  // Invoke with Lwork = -1 to estimate work space size
 | 
			
		||||
  dsyevx_('V','I','U',n,myMat.ptr(),n,dummy,dummy,1,nv,
 | 
			
		||||
          abstol,m,&val.front(),vec.ptr(),n,&dummy,-1,0,0,info);
 | 
			
		||||
  char jobz='V';
 | 
			
		||||
  char range='I';
 | 
			
		||||
  char uplo='U';
 | 
			
		||||
  int il = 1;
 | 
			
		||||
  int lwork = -1;
 | 
			
		||||
  int noncons = n;
 | 
			
		||||
  dsyevx_(&jobz,&range,&uplo,&noncons,myMat.ptr(),&noncons,&dummy,&dummy,&il,&nv,
 | 
			
		||||
          &abstol,&m,&val.front(),vec.ptr(),&noncons,&dummy,&lwork,nullptr,nullptr,&info);
 | 
			
		||||
 | 
			
		||||
  if (info == 0)
 | 
			
		||||
  {
 | 
			
		||||
@@ -540,8 +559,12 @@ bool DenseMatrix::solveEig (RealArray& val, Matrix& vec, int nv)
 | 
			
		||||
    val.resize(n);
 | 
			
		||||
    vec.resize(n,nv);
 | 
			
		||||
    // Solve the eigenproblem
 | 
			
		||||
    dsyevx_('V','I','U',n,myMat.ptr(),n,dummy,dummy,1,nv,
 | 
			
		||||
	    abstol,m,&val.front(),vec.ptr(),n,work,Lwork,Iwork+n,Iwork,info);
 | 
			
		||||
    char jobz='V';
 | 
			
		||||
    char range='I';
 | 
			
		||||
    char uplo='U';
 | 
			
		||||
    int il = 1;
 | 
			
		||||
    dsyevx_(&jobz,&range,&uplo,&noncons,myMat.ptr(),&noncons,&dummy,&dummy,&il,&nv,
 | 
			
		||||
	    &abstol,&m,&val.front(),vec.ptr(),&noncons,work,&Lwork,Iwork+n,Iwork,&info);
 | 
			
		||||
    delete[] work;
 | 
			
		||||
    delete[] Iwork;
 | 
			
		||||
    val.resize(nv);
 | 
			
		||||
@@ -567,15 +590,22 @@ bool DenseMatrix::solveEig (DenseMatrix& B, RealArray& val, Matrix& vec, int nv,
 | 
			
		||||
  if (n < 1 || nv < 1) return true; // No equations to solve
 | 
			
		||||
  if (n > myMat.cols()) return false;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  std::cout <<"  Solving dense eigenproblem using LAPACK::DSYGVX"<< std::endl;
 | 
			
		||||
  int m, info = 0;
 | 
			
		||||
  Real dummy = 0.0;
 | 
			
		||||
  Real abstol = 0.0;
 | 
			
		||||
  int itype = 1;
 | 
			
		||||
  char jobz = 'V';
 | 
			
		||||
  char range = 'I';
 | 
			
		||||
  char uplo = 'U';
 | 
			
		||||
  int il = 1;
 | 
			
		||||
  int lwork = -1;
 | 
			
		||||
  int noncons = n;
 | 
			
		||||
  // Invoke with Lwork = -1 to estimate work space size
 | 
			
		||||
  dsygvx_(1,'V','I','U',n,myMat.ptr(),n,B.myMat.ptr(),n,
 | 
			
		||||
          dummy,dummy,1,nv,abstol,m,&val.front(),vec.ptr(),n,
 | 
			
		||||
          &dummy,-1,0,0,info);
 | 
			
		||||
  dsygvx_(&itype,&jobz,&range,&uplo,&noncons,myMat.ptr(),&noncons,B.myMat.ptr(),&noncons,
 | 
			
		||||
          &dummy,&dummy,&il,&nv,&abstol,&m,&val.front(),vec.ptr(),&noncons,
 | 
			
		||||
          &dummy,&lwork,nullptr,nullptr,&info);
 | 
			
		||||
 | 
			
		||||
  if (info == 0)
 | 
			
		||||
  {
 | 
			
		||||
@@ -586,9 +616,9 @@ bool DenseMatrix::solveEig (DenseMatrix& B, RealArray& val, Matrix& vec, int nv,
 | 
			
		||||
    val.resize(n);
 | 
			
		||||
    vec.resize(n,nv);
 | 
			
		||||
    // Solve the eigenproblem
 | 
			
		||||
    dsygvx_(1,'V','I','U',n,myMat.ptr(),n,B.myMat.ptr(),n,
 | 
			
		||||
	    dummy,dummy,1,nv,abstol,m,&val.front(),vec.ptr(),n,
 | 
			
		||||
	    work,Lwork,Iwork+n,Iwork,info);
 | 
			
		||||
    dsygvx_(&itype,&jobz,&range,&uplo,&noncons,myMat.ptr(),&noncons,B.myMat.ptr(),&noncons,
 | 
			
		||||
	    &dummy,&dummy,&il,&nv,&abstol,&m,&val.front(),vec.ptr(),&noncons,
 | 
			
		||||
	    work,&Lwork,Iwork+n,Iwork,&info);
 | 
			
		||||
    delete[] work;
 | 
			
		||||
    delete[] Iwork;
 | 
			
		||||
    val.resize(nv);
 | 
			
		||||
@@ -612,15 +642,19 @@ bool DenseMatrix::solveEig (DenseMatrix& B, RealArray& val, Matrix& vec, int nv,
 | 
			
		||||
 | 
			
		||||
bool DenseMatrix::solveEigNon (RealArray& r_val, RealArray& c_val)
 | 
			
		||||
{
 | 
			
		||||
  const size_t n = myMat.rows();
 | 
			
		||||
  const int n = myMat.rows();
 | 
			
		||||
  if (n < 1) return true; // No equations to solve
 | 
			
		||||
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  int  info  = 0;
 | 
			
		||||
  Real dummy = 0.0;
 | 
			
		||||
  char jobvl = 'N';
 | 
			
		||||
  int ldvl = 1;
 | 
			
		||||
  int lwork = -1;
 | 
			
		||||
  int noncons = n;
 | 
			
		||||
  // Invoke with Lwork = -1 to estimate work space size
 | 
			
		||||
  dgeev_('N','N',n,myMat.ptr(),n,&r_val.front(),&c_val.front(),
 | 
			
		||||
	 &dummy,1,&dummy,1,&dummy,-1,info);
 | 
			
		||||
  dgeev_(&jobvl,&jobvl,&noncons,myMat.ptr(),&noncons,&r_val.front(),&c_val.front(),
 | 
			
		||||
	 &dummy,&ldvl,&dummy,&ldvl,&dummy,&lwork,&info);
 | 
			
		||||
 | 
			
		||||
  if (info == 0)
 | 
			
		||||
  {
 | 
			
		||||
@@ -630,8 +664,8 @@ bool DenseMatrix::solveEigNon (RealArray& r_val, RealArray& c_val)
 | 
			
		||||
    r_val.resize(n);
 | 
			
		||||
    c_val.resize(n);
 | 
			
		||||
    // Solve the eigenproblem
 | 
			
		||||
    dgeev_('N','N',n,myMat.ptr(),n,&r_val.front(),&c_val.front(),
 | 
			
		||||
	   &dummy,1,&dummy,1,work,Lwork,info);
 | 
			
		||||
    dgeev_(&jobvl,&jobvl,&noncons,myMat.ptr(),&noncons,&r_val.front(),&c_val.front(),
 | 
			
		||||
	   &dummy,&ldvl,&dummy,&ldvl,work,&Lwork,&info);
 | 
			
		||||
    delete[] work;
 | 
			
		||||
    if (info == 0) return true;
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,18 +24,20 @@
 | 
			
		||||
#define dgetri_ dgetri
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(USE_CBLAS) || defined(USE_MKL)
 | 
			
		||||
extern "C" {
 | 
			
		||||
//! \brief Computes an LU factorization of a general M-by-N matrix A.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgetrf_(const int& M, const int& N, double* A, const int& LDA,
 | 
			
		||||
             int* IPIV, int& INFO);
 | 
			
		||||
void dgetrf_(const int* M, const int* N, double* A, const int* LDA,
 | 
			
		||||
             int* IPIV, int* INFO);
 | 
			
		||||
//! \brief Computes the inverse of a matrix based on its LU factorization.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dgetri_(const int& N, double* A, const int& LDA,
 | 
			
		||||
             int* IPIV, double* WORK, const int& LWORK, int& INFO);
 | 
			
		||||
void dgetri_(const int* N, double* A, const int* LDA,
 | 
			
		||||
             int* IPIV, double* WORK, const int* LWORK, int* INFO);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Set default values on some global variables.
 | 
			
		||||
@@ -131,11 +133,12 @@ bool utl::invert (Matrix& A)
 | 
			
		||||
  if (A.rows() <= 3)
 | 
			
		||||
    return A.inverse() > 0.0;
 | 
			
		||||
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  // Use LAPack/BLAS for larger matrices
 | 
			
		||||
  int INFO, N = A.rows() > A.cols() ? A.rows() : A.cols();
 | 
			
		||||
  int* IPIV = new int[N];
 | 
			
		||||
  dgetrf_(N,N,A.ptr(),A.rows(),IPIV,INFO);
 | 
			
		||||
  int r = A.rows();
 | 
			
		||||
  dgetrf_(&N,&N,A.ptr(),&r,IPIV,&INFO);
 | 
			
		||||
  if (INFO != 0)
 | 
			
		||||
  {
 | 
			
		||||
    delete[] IPIV;
 | 
			
		||||
@@ -143,9 +146,11 @@ bool utl::invert (Matrix& A)
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  double NWORK;
 | 
			
		||||
  dgetri_(N,A.ptr(),A.rows(),IPIV,&NWORK,-1,INFO);
 | 
			
		||||
  int m1 = -1;
 | 
			
		||||
  dgetri_(&N,A.ptr(),&r,IPIV,&NWORK,&m1,&INFO);
 | 
			
		||||
  double* WORK = new double[int(NWORK)];
 | 
			
		||||
  dgetri_(N,A.ptr(),A.rows(),IPIV,WORK,int(NWORK),INFO);
 | 
			
		||||
  int nwork = NWORK;
 | 
			
		||||
  dgetri_(&N,A.ptr(),&r,IPIV,WORK,&nwork,&INFO);
 | 
			
		||||
  delete[] IPIV;
 | 
			
		||||
  delete[] WORK;
 | 
			
		||||
  if (INFO == 0) return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,8 @@
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#ifdef USE_MKL
 | 
			
		||||
#include <mkl_cblas.h>
 | 
			
		||||
#elif defined(USE_ACCELERATE)
 | 
			
		||||
#include <Accelerate/Accelerate.h>
 | 
			
		||||
#elif defined(USE_CBLAS)
 | 
			
		||||
extern "C"
 | 
			
		||||
{
 | 
			
		||||
@@ -33,6 +35,8 @@ extern "C"
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define USE_BLAS defined(USE_CBLAS) || defined(USE_MKL) || defined(USE_ACCELERATE)
 | 
			
		||||
 | 
			
		||||
#ifdef INDEX_CHECK
 | 
			
		||||
#if INDEX_CHECK > 1
 | 
			
		||||
#define ABORT_ON_INDEX_CHECK abort()
 | 
			
		||||
@@ -808,7 +812,7 @@ namespace utl //! General utility classes and functions.
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(USE_CBLAS) || defined(USE_MKL)
 | 
			
		||||
#if USE_BLAS
 | 
			
		||||
  //============================================================================
 | 
			
		||||
  //===   BLAS-implementation of the matrix/vector multiplication methods   ====
 | 
			
		||||
  //============================================================================
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#include "Tensor.h"
 | 
			
		||||
#include "Vec3.h"
 | 
			
		||||
#include "matrix.h"
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
@@ -23,14 +24,16 @@
 | 
			
		||||
#define dsyev_ dsyev
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(USE_CBLAS) || defined(USE_MKL)
 | 
			
		||||
extern "C" {
 | 
			
		||||
//! \brief Solves the standard eigenproblem \a A*x=(lambda)*x.
 | 
			
		||||
//! \details This is a FORTRAN-77 subroutine in the LAPack library.
 | 
			
		||||
//! \sa LAPack library documentation.
 | 
			
		||||
void dsyev_(const char& jobz, const char& uplo,
 | 
			
		||||
            const int& n, double* a, const int& lda, double* w,
 | 
			
		||||
            double* work, const int& lwork, int& info);
 | 
			
		||||
void dsyev_(const char* jobz, const char* uplo,
 | 
			
		||||
            const int* n, double* a, const int* lda, double* w,
 | 
			
		||||
            double* work, const int* lwork, int* info);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef epsZ
 | 
			
		||||
//! \brief Zero tolerance for the incremental rotations.
 | 
			
		||||
@@ -1129,7 +1132,7 @@ bool SymmTensor::principal (Vec3& p) const
 | 
			
		||||
bool SymmTensor::principal (Vec3& p, Vec3* pdir, int ndir) const
 | 
			
		||||
{
 | 
			
		||||
  p = 0.0;
 | 
			
		||||
#ifdef USE_CBLAS
 | 
			
		||||
#ifdef USE_BLAS
 | 
			
		||||
  // Set up the upper triangle of the symmetric tensor
 | 
			
		||||
  double A[9], W[3];
 | 
			
		||||
  if (n == 3)
 | 
			
		||||
@@ -1154,7 +1157,11 @@ bool SymmTensor::principal (Vec3& p, Vec3* pdir, int ndir) const
 | 
			
		||||
  int       info = 0;
 | 
			
		||||
  const int Lwork = 12;
 | 
			
		||||
  double    Work[Lwork];
 | 
			
		||||
  dsyev_('V','U',n,A,n,W,Work,Lwork,info);
 | 
			
		||||
  char jobz='V';
 | 
			
		||||
  char uplo='U';
 | 
			
		||||
  int noncons = n;
 | 
			
		||||
  int Noncons = Lwork;
 | 
			
		||||
  dsyev_(&jobz,&uplo,&noncons,A,&noncons,W,Work,&Noncons,&info);
 | 
			
		||||
  if (info)
 | 
			
		||||
  {
 | 
			
		||||
    std::cerr <<" *** LAPack::dsyev: info ="<< info;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user