diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-02-05 09:36:52 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-02-05 09:36:52 +0000 |
commit | da45184635855d280ff612ecaa79e5f7d40ffacd (patch) | |
tree | 94eea9a87ef3ed1e5e6b579a1412e7e803a2d7e0 | |
parent | 1119f846cfcf7999be5d2d08dee689dd9e53c0e8 (diff) |
add custom FindBLAS FindLAPACK working for c++ compiler
fix issues in Cholmod/Taucs supports
-rw-r--r-- | Eigen/Sparse | 5 | ||||
-rw-r--r-- | Eigen/src/Sparse/CholmodSupport.h | 25 | ||||
-rw-r--r-- | Eigen/src/Sparse/MappedSparseMatrix.h | 24 | ||||
-rw-r--r-- | Eigen/src/Sparse/TaucsSupport.h | 8 | ||||
-rw-r--r-- | cmake/FindBLAS.cmake | 419 | ||||
-rw-r--r-- | cmake/FindLAPACK.cmake | 273 | ||||
-rw-r--r-- | cmake/FindTaucs.cmake | 28 | ||||
-rw-r--r-- | cmake/FindUmfpack.cmake | 15 | ||||
-rw-r--r-- | test/CMakeLists.txt | 8 |
9 files changed, 755 insertions, 50 deletions
diff --git a/Eigen/Sparse b/Eigen/Sparse index 57e9af6a2..289985ed9 100644 --- a/Eigen/Sparse +++ b/Eigen/Sparse @@ -22,7 +22,6 @@ #endif #ifdef EIGEN_TAUCS_SUPPORT - // taucs.h declares a lot of mess #define isnan #define finite @@ -40,7 +39,9 @@ #ifdef max #undef max #endif - + #ifdef complex + #undef complex + #endif #endif #ifdef EIGEN_SUPERLU_SUPPORT diff --git a/Eigen/src/Sparse/CholmodSupport.h b/Eigen/src/Sparse/CholmodSupport.h index 3a95b2253..1550fd055 100644 --- a/Eigen/src/Sparse/CholmodSupport.h +++ b/Eigen/src/Sparse/CholmodSupport.h @@ -54,16 +54,17 @@ void ei_cholmod_configure_matrix(CholmodType& mat) } } -template<typename Scalar, int Flags> -cholmod_sparse SparseMatrixBase<Scalar,Flags>::asCholmodMatrix() +template<typename Derived> +cholmod_sparse SparseMatrixBase<Derived>::asCholmodMatrix() { + typedef typename Derived::Scalar Scalar; cholmod_sparse res; res.nzmax = nonZeros(); res.nrow = rows();; res.ncol = cols(); - res.p = _outerIndexPtr(); - res.i = _innerIndexPtr(); - res.x = _valuePtr(); + res.p = derived()._outerIndexPtr(); + res.i = derived()._innerIndexPtr(); + res.x = derived()._valuePtr(); res.xtype = CHOLMOD_REAL; res.itype = CHOLMOD_INT; res.sorted = 1; @@ -73,11 +74,11 @@ cholmod_sparse SparseMatrixBase<Scalar,Flags>::asCholmodMatrix() ei_cholmod_configure_matrix<Scalar>(res); - if (Flags & SelfAdjoint) + if (Derived::Flags & SelfAdjoint) { - if (Flags & UpperTriangular) + if (Derived::Flags & UpperTriangular) res.stype = 1; - else if (Flags & LowerTriangular) + else if (Derived::Flags & LowerTriangular) res.stype = -1; else res.stype = 0; @@ -115,7 +116,7 @@ MappedSparseMatrix<Scalar,Flags>::MappedSparseMatrix(cholmod_sparse& cm) m_outerIndex = reinterpret_cast<int*>(cm.p); m_innerIndices = reinterpret_cast<int*>(cm.i); m_values = reinterpret_cast<Scalar*>(cm.x); - m_nnz = res.m_outerIndex[cm.ncol]); + m_nnz = m_outerIndex[cm.ncol]; } template<typename MatrixType> @@ -123,8 +124,8 @@ class SparseLLT<MatrixType,Cholmod> : public SparseLLT<MatrixType> { protected: typedef SparseLLT<MatrixType> Base; - using typename Base::Scalar; - using Base::RealScalar; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; using Base::MatrixLIsDirty; using Base::SupernodalFactorIsDirty; using Base::m_flags; @@ -205,7 +206,7 @@ SparseLLT<MatrixType,Cholmod>::matrixL() const ei_assert(!(m_status & SupernodalFactorIsDirty)); cholmod_sparse* cmRes = cholmod_factor_to_sparse(m_cholmodFactor, &m_cholmod); - const_cast<typename Base::CholMatrixType&>(m_matrix) = MappedSparseMatrix(*cmRes); + const_cast<typename Base::CholMatrixType&>(m_matrix) = MappedSparseMatrix<Scalar>(*cmRes); free(cmRes); m_status = (m_status & ~MatrixLIsDirty); diff --git a/Eigen/src/Sparse/MappedSparseMatrix.h b/Eigen/src/Sparse/MappedSparseMatrix.h index b4a12cf0d..f4935d834 100644 --- a/Eigen/src/Sparse/MappedSparseMatrix.h +++ b/Eigen/src/Sparse/MappedSparseMatrix.h @@ -65,10 +65,10 @@ class MappedSparseMatrix //---------------------------------------- // direct access interface - inline const Scalar* _valuePtr() const { return &m_values; } - inline Scalar* _valuePtr() { return &m_values; } + inline const Scalar* _valuePtr() const { return m_values; } + inline Scalar* _valuePtr() { return m_values; } - inline const int* _innerIndexPtr() const { return &m_innerIndices; } + inline const int* _innerIndexPtr() const { return m_innerIndices; } inline int* _innerIndexPtr() { return m_innerIndices; } inline const int* _outerIndexPtr() const { return m_outerIndex; } @@ -108,7 +108,7 @@ class MappedSparseMatrix ei_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient"); return m_values[id]; } - + class InnerIterator; /** \returns the number of non zero coefficients */ @@ -140,21 +140,25 @@ class MappedSparseMatrix<Scalar,_Flags>::InnerIterator { public: InnerIterator(const MappedSparseMatrix& mat, int outer) - : m_matrix(mat), m_outer(outer), m_id(mat._outerIndexPtr[outer]), m_start(m_id), m_end(mat._outerIndexPtr[outer+1]) + : m_matrix(mat), + m_outer(outer), + m_id(mat._outerIndexPtr()[outer]), + m_start(m_id), + m_end(mat._outerIndexPtr()[outer+1]) {} template<unsigned int Added, unsigned int Removed> InnerIterator(const Flagged<MappedSparseMatrix,Added,Removed>& mat, int outer) - : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr[outer]), - m_start(m_id), m_end(m_matrix._outerIndexPtr[outer+1]) + : m_matrix(mat._expression()), m_id(m_matrix._outerIndexPtr()[outer]), + m_start(m_id), m_end(m_matrix._outerIndexPtr()[outer+1]) {} inline InnerIterator& operator++() { m_id++; return *this; } - inline Scalar value() const { return m_matrix.m_valuePtr[m_id]; } - inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix._valuePtr[m_id]); } + inline Scalar value() const { return m_matrix._valuePtr()[m_id]; } + inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix._valuePtr()[m_id]); } - inline int index() const { return m_matrix._innerIndexPtr(m_id); } + inline int index() const { return m_matrix._innerIndexPtr()[m_id]; } inline int row() const { return IsRowMajor ? m_outer : index(); } inline int col() const { return IsRowMajor ? index() : m_outer; } diff --git a/Eigen/src/Sparse/TaucsSupport.h b/Eigen/src/Sparse/TaucsSupport.h index c8665349e..2035a2af7 100644 --- a/Eigen/src/Sparse/TaucsSupport.h +++ b/Eigen/src/Sparse/TaucsSupport.h @@ -78,8 +78,8 @@ class SparseLLT<MatrixType,Taucs> : public SparseLLT<MatrixType> { protected: typedef SparseLLT<MatrixType> Base; - using Base::Scalar; - using Base::RealScalar; + typedef typename Base::Scalar Scalar; + typedef typename Base::RealScalar RealScalar; using Base::MatrixLIsDirty; using Base::SupernodalFactorIsDirty; using Base::m_flags; @@ -129,7 +129,7 @@ void SparseLLT<MatrixType,Taucs>::compute(const MatrixType& a) { taucs_ccs_matrix taucsMatA = const_cast<MatrixType&>(a).asTaucsMatrix(); taucs_ccs_matrix* taucsRes = taucs_ccs_factor_llt(&taucsMatA, Base::m_precision, 0); - m_matrix = MappedSparseMatrix(*taucsRes); + m_matrix = MappedSparseMatrix<Scalar>(*taucsRes); free(taucsRes); m_status = (m_status & ~(CompleteFactorization|MatrixLIsDirty)) | IncompleteFactorization @@ -161,7 +161,7 @@ SparseLLT<MatrixType,Taucs>::matrixL() const ei_assert(!(m_status & SupernodalFactorIsDirty)); taucs_ccs_matrix* taucsL = taucs_supernodal_factor_to_ccs(m_taucsSupernodalFactor); - const_cast<typename Base::CholMatrixType&>(m_matrix) = MappedSparseMatrix(*taucsL); + const_cast<typename Base::CholMatrixType&>(m_matrix) = MappedSparseMatrix<Scalar>(*taucsL); free(taucsL); m_status = (m_status & ~MatrixLIsDirty); } diff --git a/cmake/FindBLAS.cmake b/cmake/FindBLAS.cmake new file mode 100644 index 000000000..68c4e0724 --- /dev/null +++ b/cmake/FindBLAS.cmake @@ -0,0 +1,419 @@ +# Find BLAS library +# +# This module finds an installed library that implements the BLAS +# linear-algebra interface (see http://www.netlib.org/blas/). +# The list of libraries searched for is mainly taken +# from the autoconf macro file, acx_blas.m4 (distributed at +# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html). +# +# This module sets the following variables: +# BLAS_FOUND - set to true if a library implementing the BLAS interface +# is found +# BLAS_INCLUDE_DIR - Directories containing the BLAS header files +# BLAS_DEFINITIONS - Compilation options to use BLAS +# BLAS_LINKER_FLAGS - Linker flags to use BLAS (excluding -l +# and -L). +# BLAS_LIBRARIES_DIR - Directories containing the BLAS libraries. +# May be null if BLAS_LIBRARIES contains libraries name using full path. +# BLAS_LIBRARIES - List of libraries to link against BLAS interface. +# May be null if the compiler supports auto-link (e.g. VC++). +# BLAS_USE_FILE - The name of the cmake module to include to compile +# applications or libraries using BLAS. +# +# This module was modified by CGAL team: +# - find libraries for a C++ compiler, instead of Fortran +# - added BLAS_INCLUDE_DIR, BLAS_DEFINITIONS and BLAS_LIBRARIES_DIR +# - removed BLAS95_LIBRARIES + +include(CheckFunctionExists) + + +# This macro checks for the existence of the combination of fortran libraries +# given by _list. If the combination is found, this macro checks (using the +# check_function_exists macro) whether can link against that library +# combination using the name of a routine given by _name using the linker +# flags given by _flags. If the combination of libraries is found and passes +# the link test, LIBRARIES is set to the list of complete library paths that +# have been found and DEFINITIONS to the required definitions. +# Otherwise, LIBRARIES is set to FALSE. +# N.B. _prefix is the prefix applied to the names of all cached variables that +# are generated internally and marked advanced by this macro. +macro(check_fortran_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _path) + #message("DEBUG: check_fortran_libraries(${_list} in ${_path})") + + # Check for the existence of the libraries given by _list + set(_libraries_found TRUE) + set(_libraries_work FALSE) + set(${DEFINITIONS} "") + set(${LIBRARIES} "") + set(_combined_name) + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) + + if(_libraries_found) + # search first in ${_path} + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ${_path} NO_DEFAULT_PATH + ) + # if not found, search in environment variables and system + if ( WIN32 ) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ENV LIB + ) + elseif ( APPLE ) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH + ) + else () + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH + ) + endif() + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_found ${${_prefix}_${_library}_LIBRARY}) + endif(_libraries_found) + endforeach(_library ${_list}) + if(_libraries_found) + set(_libraries_found ${${LIBRARIES}}) + endif() + + # Test this combination of libraries with the Fortran/f2c interface. + # We test the Fortran interface first as it is well standardized. + if(_libraries_found AND NOT _libraries_work) + set(${DEFINITIONS} "-D${_prefix}_USE_F2C") + set(${LIBRARIES} ${_libraries_found}) + # Some C++ linkers require the f2c library to link with Fortran libraries. + # I do not know which ones, thus I just add the f2c library if it is available. + find_package( F2C QUIET ) + if ( F2C_FOUND ) + set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS}) + set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES}) + endif() + set(CMAKE_REQUIRED_DEFINITIONS ${${DEFINITIONS}}) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}}) + #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}") + #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + # Check if function exists with f2c calling convention (ie a trailing underscore) + check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS) + set(CMAKE_REQUIRED_DEFINITIONS} "") + set(CMAKE_REQUIRED_LIBRARIES "") + mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS) + set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS}) + endif(_libraries_found AND NOT _libraries_work) + + # If not found, test this combination of libraries with a C interface. + # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard. + if(_libraries_found AND NOT _libraries_work) + set(${DEFINITIONS} "") + set(${LIBRARIES} ${_libraries_found}) + set(CMAKE_REQUIRED_DEFINITIONS "") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}}) + #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS) + set(CMAKE_REQUIRED_LIBRARIES "") + mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS}) + endif(_libraries_found AND NOT _libraries_work) + + # on failure + if(NOT _libraries_work) + set(${DEFINITIONS} "") + set(${LIBRARIES} FALSE) + endif() + #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}") + #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") +endmacro(check_fortran_libraries) + + +# +# main +# + +# Is it already configured? +if (BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES) + + set(BLAS_FOUND TRUE) + +else() + + # reset variables + set( BLAS_INCLUDE_DIR "" ) + set( BLAS_DEFINITIONS "" ) + set( BLAS_LINKER_FLAGS "" ) + set( BLAS_LIBRARIES "" ) + set( BLAS_LIBRARIES_DIR "" ) + + # + # If Unix, search for BLAS function in possible libraries + # + + # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "cblas;f77blas;atlas" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in PhiPACK libraries? (requires generic BLAS lib, too) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "sgemm;dgemm;blas" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in Alpha CXML library? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "cxml" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in Alpha DXML library? (now called CXML, see above) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "dxml" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in Sun Performance library? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "-xlic_lib=sunperf" + "sunperf;sunmath" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + if(BLAS_LIBRARIES) + # Extra linker flag + set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf") + endif() + endif() + + # BLAS in SCSL library? (SGI/Cray Scientific Library) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "scsl" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in SGIMATH library? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "complib.sgimath" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # BLAS in IBM ESSL library? (requires generic BLAS lib, too) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "essl;blas" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + #BLAS in intel mkl 10 library? (em64t 64bit) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide;pthread" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + ### windows version of intel mkl 10? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + SGEMM + "" + "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + #older versions of intel mkl libs + + # BLAS in intel mkl library? (shared) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "mkl;guide;pthread" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + #BLAS in intel mkl library? (static, 32bit) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "mkl_ia32;guide;pthread" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + #BLAS in intel mkl library? (static, em64t 64bit) + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "mkl_em64t;guide;pthread" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + #BLAS in acml library? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "acml" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + # Apple BLAS library? + if(NOT BLAS_LIBRARIES) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "Accelerate" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + if ( NOT BLAS_LIBRARIES ) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "vecLib" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif ( NOT BLAS_LIBRARIES ) + + # Generic BLAS library? + # This configuration *must* be the last try as this library is notably slow. + if ( NOT BLAS_LIBRARIES ) + check_fortran_libraries( + BLAS_DEFINITIONS + BLAS_LIBRARIES + BLAS + sgemm + "" + "blas" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR" + ) + endif() + + if(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES) + set(BLAS_FOUND TRUE) + else() + set(BLAS_FOUND FALSE) + endif() + + if(NOT BLAS_FIND_QUIETLY) + if(BLAS_FOUND) + message(STATUS "A library with BLAS API found.") + else(BLAS_FOUND) + if(BLAS_FIND_REQUIRED) + message(FATAL_ERROR "A required library with BLAS API not found. Please specify library location.") + else() + message(STATUS "A library with BLAS API not found. Please specify library location.") + endif() + endif(BLAS_FOUND) + endif(NOT BLAS_FIND_QUIETLY) + + # Add variables to cache + set( BLAS_INCLUDE_DIR "${BLAS_INCLUDE_DIR}" + CACHE PATH "Directories containing the BLAS header files" FORCE ) + set( BLAS_DEFINITIONS "${BLAS_DEFINITIONS}" + CACHE STRING "Compilation options to use BLAS" FORCE ) + set( BLAS_LINKER_FLAGS "${BLAS_LINKER_FLAGS}" + CACHE STRING "Linker flags to use BLAS" FORCE ) + set( BLAS_LIBRARIES "${BLAS_LIBRARIES}" + CACHE FILEPATH "BLAS libraries name" FORCE ) + set( BLAS_LIBRARIES_DIR "${BLAS_LIBRARIES_DIR}" + CACHE PATH "Directories containing the BLAS libraries" FORCE ) + + #message("DEBUG: BLAS_INCLUDE_DIR = ${BLAS_INCLUDE_DIR}") + #message("DEBUG: BLAS_DEFINITIONS = ${BLAS_DEFINITIONS}") + #message("DEBUG: BLAS_LINKER_FLAGS = ${BLAS_LINKER_FLAGS}") + #message("DEBUG: BLAS_LIBRARIES = ${BLAS_LIBRARIES}") + #message("DEBUG: BLAS_LIBRARIES_DIR = ${BLAS_LIBRARIES_DIR}") + #message("DEBUG: BLAS_FOUND = ${BLAS_FOUND}") + +endif(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES) diff --git a/cmake/FindLAPACK.cmake b/cmake/FindLAPACK.cmake new file mode 100644 index 000000000..2fcae2199 --- /dev/null +++ b/cmake/FindLAPACK.cmake @@ -0,0 +1,273 @@ +# Find LAPACK library +# +# This module finds an installed library that implements the LAPACK +# linear-algebra interface (see http://www.netlib.org/lapack/). +# The approach follows mostly that taken for the autoconf macro file, acx_lapack.m4 +# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html). +# +# This module sets the following variables: +# LAPACK_FOUND - set to true if a library implementing the LAPACK interface +# is found +# LAPACK_INCLUDE_DIR - Directories containing the LAPACK header files +# LAPACK_DEFINITIONS - Compilation options to use LAPACK +# LAPACK_LINKER_FLAGS - Linker flags to use LAPACK (excluding -l +# and -L). +# LAPACK_LIBRARIES_DIR - Directories containing the LAPACK libraries. +# May be null if LAPACK_LIBRARIES contains libraries name using full path. +# LAPACK_LIBRARIES - List of libraries to link against LAPACK interface. +# May be null if the compiler supports auto-link (e.g. VC++). +# LAPACK_USE_FILE - The name of the cmake module to include to compile +# applications or libraries using LAPACK. +# +# This module was modified by CGAL team: +# - find libraries for a C++ compiler, instead of Fortran +# - added LAPACK_INCLUDE_DIR, LAPACK_DEFINITIONS and LAPACK_LIBRARIES_DIR +# - removed LAPACK95_LIBRARIES + + +include(CheckFunctionExists) + +# This macro checks for the existence of the combination of fortran libraries +# given by _list. If the combination is found, this macro checks (using the +# check_function_exists macro) whether can link against that library +# combination using the name of a routine given by _name using the linker +# flags given by _flags. If the combination of libraries is found and passes +# the link test, LIBRARIES is set to the list of complete library paths that +# have been found and DEFINITIONS to the required definitions. +# Otherwise, LIBRARIES is set to FALSE. +# N.B. _prefix is the prefix applied to the names of all cached variables that +# are generated internally and marked advanced by this macro. +macro(check_lapack_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _blas _path) + #message("DEBUG: check_lapack_libraries(${_list} in ${_path} with ${_blas})") + + # Check for the existence of the libraries given by _list + set(_libraries_found TRUE) + set(_libraries_work FALSE) + set(${DEFINITIONS} "") + set(${LIBRARIES} "") + set(_combined_name) + foreach(_library ${_list}) + set(_combined_name ${_combined_name}_${_library}) + + if(_libraries_found) + # search first in ${_path} + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ${_path} NO_DEFAULT_PATH + ) + # if not found, search in environment variables and system + if ( WIN32 ) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS ENV LIB + ) + elseif ( APPLE ) + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH + ) + else () + find_library(${_prefix}_${_library}_LIBRARY + NAMES ${_library} + PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH + ) + endif() + mark_as_advanced(${_prefix}_${_library}_LIBRARY) + set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY}) + set(_libraries_found ${${_prefix}_${_library}_LIBRARY}) + endif(_libraries_found) + endforeach(_library ${_list}) + if(_libraries_found) + set(_libraries_found ${${LIBRARIES}}) + endif() + + # Test this combination of libraries with the Fortran/f2c interface. + # We test the Fortran interface first as it is well standardized. + if(_libraries_found AND NOT _libraries_work) + set(${DEFINITIONS} "-D${_prefix}_USE_F2C") + set(${LIBRARIES} ${_libraries_found}) + # Some C++ linkers require the f2c library to link with Fortran libraries. + # I do not know which ones, thus I just add the f2c library if it is available. + find_package( F2C QUIET ) + if ( F2C_FOUND ) + set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS}) + set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES}) + endif() + set(CMAKE_REQUIRED_DEFINITIONS ${${DEFINITIONS}}) + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas}) + #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}") + #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + # Check if function exists with f2c calling convention (ie a trailing underscore) + check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS) + set(CMAKE_REQUIRED_DEFINITIONS} "") + set(CMAKE_REQUIRED_LIBRARIES "") + mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS) + set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS}) + endif(_libraries_found AND NOT _libraries_work) + + # If not found, test this combination of libraries with a C interface. + # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard. + if(_libraries_found AND NOT _libraries_work) + set(${DEFINITIONS} "") + set(${LIBRARIES} ${_libraries_found}) + set(CMAKE_REQUIRED_DEFINITIONS "") + set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas}) + #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}") + check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS) + set(CMAKE_REQUIRED_LIBRARIES "") + mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS) + set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS}) + endif(_libraries_found AND NOT _libraries_work) + + # on failure + if(NOT _libraries_work) + set(${DEFINITIONS} "") + set(${LIBRARIES} FALSE) + endif() + #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}") + #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}") +endmacro(check_lapack_libraries) + + +# +# main +# + +# LAPACK requires BLAS +if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED) + find_package(BLAS) +else() + find_package(BLAS REQUIRED) +endif() + +if (NOT BLAS_FOUND) + + message(STATUS "LAPACK requires BLAS.") + set(LAPACK_FOUND FALSE) + +# Is it already configured? +elseif (LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES) + + set(LAPACK_FOUND TRUE) + +else() + + # reset variables + set( LAPACK_INCLUDE_DIR "" ) + set( LAPACK_DEFINITIONS "" ) + set( LAPACK_LINKER_FLAGS "" ) # unused (yet) + set( LAPACK_LIBRARIES "" ) + set( LAPACK_LIBRARIES_DIR "" ) + + # + # If Unix, search for LAPACK function in possible libraries + # + + #intel mkl lapack? + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_DEFINITIONS + LAPACK_LIBRARIES + LAPACK + cheev + "" + "mkl_lapack" + "${BLAS_LIBRARIES}" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR" + ) + endif() + + #acml lapack? + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_DEFINITIONS + LAPACK_LIBRARIES + LAPACK + cheev + "" + "acml" + "${BLAS_LIBRARIES}" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR" + ) + endif() + + # Apple LAPACK library? + if(NOT LAPACK_LIBRARIES) + check_lapack_libraries( + LAPACK_DEFINITIONS + LAPACK_LIBRARIES + LAPACK + cheev + "" + "Accelerate" + "${BLAS_LIBRARIES}" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR" + ) + endif() + + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_DEFINITIONS + LAPACK_LIBRARIES + LAPACK + cheev + "" + "vecLib" + "${BLAS_LIBRARIES}" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR" + ) + endif ( NOT LAPACK_LIBRARIES ) + + # Generic LAPACK library? + # This configuration *must* be the last try as this library is notably slow. + if ( NOT LAPACK_LIBRARIES ) + check_lapack_libraries( + LAPACK_DEFINITIONS + LAPACK_LIBRARIES + LAPACK + cheev + "" + "lapack" + "${BLAS_LIBRARIES}" + "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR" + ) + endif() + + if(LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES) + set(LAPACK_FOUND TRUE) + else() + set(LAPACK_FOUND FALSE) + endif() + + if(NOT LAPACK_FIND_QUIETLY) + if(LAPACK_FOUND) + message(STATUS "A library with LAPACK API found.") + else(LAPACK_FOUND) + if(LAPACK_FIND_REQUIRED) + message(FATAL_ERROR "A required library with LAPACK API not found. Please specify library location.") + else() + message(STATUS "A library with LAPACK API not found. Please specify library location.") + endif() + endif(LAPACK_FOUND) + endif(NOT LAPACK_FIND_QUIETLY) + + # Add variables to cache + set( LAPACK_INCLUDE_DIR "${LAPACK_INCLUDE_DIR}" + CACHE PATH "Directories containing the LAPACK header files" FORCE ) + set( LAPACK_DEFINITIONS "${LAPACK_DEFINITIONS}" + CACHE STRING "Compilation options to use LAPACK" FORCE ) + set( LAPACK_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}" + CACHE STRING "Linker flags to use LAPACK" FORCE ) + set( LAPACK_LIBRARIES "${LAPACK_LIBRARIES}" + CACHE FILEPATH "LAPACK libraries name" FORCE ) + set( LAPACK_LIBRARIES_DIR "${LAPACK_LIBRARIES_DIR}" + CACHE PATH "Directories containing the LAPACK libraries" FORCE ) + + #message("DEBUG: LAPACK_INCLUDE_DIR = ${LAPACK_INCLUDE_DIR}") + #message("DEBUG: LAPACK_DEFINITIONS = ${LAPACK_DEFINITIONS}") + #message("DEBUG: LAPACK_LINKER_FLAGS = ${LAPACK_LINKER_FLAGS}") + #message("DEBUG: LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}") + #message("DEBUG: LAPACK_LIBRARIES_DIR = ${LAPACK_LIBRARIES_DIR}") + #message("DEBUG: LAPACK_FOUND = ${LAPACK_FOUND}") + +endif(NOT BLAS_FOUND) diff --git a/cmake/FindTaucs.cmake b/cmake/FindTaucs.cmake index 2a046572f..ace322075 100644 --- a/cmake/FindTaucs.cmake +++ b/cmake/FindTaucs.cmake @@ -3,15 +3,25 @@ if (TAUCS_INCLUDES AND TAUCS_LIBRARIES) set(TAUCS_FIND_QUIETLY TRUE) endif (TAUCS_INCLUDES AND TAUCS_LIBRARIES) -find_path(TAUCS_INCLUDES - NAMES - taucs.h - PATHS - $ENV{TAUCSDIR} - ${INCLUDE_INSTALL_DIR} -) - -find_library(TAUCS_LIBRARIES taucs PATHS $ENV{TAUCSDIR} ${LIB_INSTALL_DIR}) +find_package(LAPACK) + +if(LAPACK_FOUND) + + find_path(TAUCS_INCLUDES + NAMES + taucs.h + PATHS + $ENV{TAUCSDIR} + ${INCLUDE_INSTALL_DIR} + ) + + find_library(TAUCS_LIBRARIES taucs PATHS $ENV{TAUCSDIR} ${LIB_INSTALL_DIR}) + + if(TAUCS_LIBRARIES) + set(TAUCS_LIBRARIES ${TAUCS_LIBRARIES} ${LAPACK_LIBRARY}) + endif(TAUCS_LIBRARIES) + +endif(LAPACK_FOUND) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(TAUCS DEFAULT_MSG diff --git a/cmake/FindUmfpack.cmake b/cmake/FindUmfpack.cmake index c736e765f..a2c7439f7 100644 --- a/cmake/FindUmfpack.cmake +++ b/cmake/FindUmfpack.cmake @@ -3,11 +3,9 @@ if (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) set(UMFPACK_FIND_QUIETLY TRUE) endif (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES) -if(CMAKE_Fortran_COMPILER_WORKS) +find_package(BLAS) - find_package(BLAS) - - if(BLAS_FOUND) +if(BLAS_FOUND) find_path(UMFPACK_INCLUDES NAMES @@ -49,12 +47,11 @@ if(CMAKE_Fortran_COMPILER_WORKS) set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES}) endif(UMFPACK_LIBRARIES) - endif(BLAS_FOUND) +endif(BLAS_FOUND) -endif(CMAKE_Fortran_COMPILER_WORKS) - include(FindPackageHandleStandardArgs) - find_package_handle_standard_args(UMFPACK DEFAULT_MSG - UMFPACK_INCLUDES UMFPACK_LIBRARIES) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(UMFPACK DEFAULT_MSG + UMFPACK_INCLUDES UMFPACK_LIBRARIES) mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e515ecd09..57df6e6c0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,10 +34,10 @@ else(CHOLMOD_FOUND) set(EIGEN_MISSING_BACKENDS ${EIGEN_MISSING_BACKENDS} Cholmod) endif(CHOLMOD_FOUND) -option(EIGEN_TEST_NO_FORTRAN "Disable Fortran" OFF) -if(NOT MSVC AND NOT EIGEN_TEST_NO_FORTRAN) - enable_language(Fortran OPTIONAL) -endif(NOT MSVC AND NOT EIGEN_TEST_NO_FORTRAN) +# option(EIGEN_TEST_NO_FORTRAN "Disable Fortran" OFF) +# if(NOT MSVC AND NOT EIGEN_TEST_NO_FORTRAN) +# enable_language(Fortran OPTIONAL) +# endif(NOT MSVC AND NOT EIGEN_TEST_NO_FORTRAN) find_package(Umfpack) if(UMFPACK_FOUND) |