File: eigen.cmake

package info (click to toggle)
tiledarray 1.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 9,568 kB
  • sloc: cpp: 53,449; javascript: 1,599; sh: 393; ansic: 226; python: 223; xml: 195; makefile: 36
file content (175 lines) | stat: -rw-r--r-- 7,117 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# -*- mode: cmake -*-

include(CMakePushCheckState)
include(CheckCXXSourceCompiles)
include(AppendFlags)

# if CUDA is enabled (assuming CUDA version is 9 or 10) need Eigen 3.3.7
# see https://gitlab.com/libeigen/eigen/issues/1491
if (ENABLE_CUDA)
  set(_tiledarray_required_eigen_version 3.3.7)
else(ENABLE_CUDA)
  set(_tiledarray_required_eigen_version ${TA_TRACKED_EIGEN_VERSION})
endif(ENABLE_CUDA)

set(_tiledarray_eigen_use_lapacke FALSE)
if ("${LAPACK_COMPILE_DEFINITIONS}" MATCHES "TILEDARRAY_EIGEN_USE_LAPACKE")
  set(_tiledarray_eigen_use_lapacke TRUE)
  if (_tiledarray_required_eigen_version VERSION_LESS 3.3.7)
    message(
      WARNING
      "Eigen3 version => 3.3.7 is required if TILEDARRAY_EIGEN_USE_LAPACKE is set.  "
      "Prior Eigen3 with LAPACKE enabled may give incorrect eigenvalue results"
      )
    set(_tiledarray_required_eigen_version 3.3.7)
  endif()
endif ()

# Check for existing Eigen
# prefer CMake-configured-and-installed instance
# re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ...
#                               to avoid issues with wiped build directory look for installed eigen
find_package(Eigen3 ${_tiledarray_required_eigen_version} NO_MODULE QUIET NO_CMAKE_PACKAGE_REGISTRY)
if (TARGET Eigen3::Eigen)
  # import alias into TiledArray "namespace"
  add_library(TiledArray_Eigen INTERFACE)
  foreach(prop INTERFACE_INCLUDE_DIRECTORIES INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_LINK_LIBRARIES INTERFACE_POSITION_INDEPENDENT_CODE)
    get_property(EIGEN3_${prop} TARGET Eigen3::Eigen PROPERTY ${prop})
    set_property(TARGET TiledArray_Eigen PROPERTY
            ${prop} ${EIGEN3_${prop}})
  endforeach()
else (TARGET Eigen3::Eigen)
  # otherwise use bundled FindEigen3.cmake module controlled by EIGEN3_INCLUDE_DIR
  # but make sure EIGEN3_INCLUDE_DIR exists!
  find_package(Eigen3 ${_tiledarray_required_eigen_version})

  if (EIGEN3_FOUND)
    if (NOT EXISTS "${EIGEN3_INCLUDE_DIR}")
      message(WARNING "Eigen3 is \"found\", but the reported EIGEN3_INCLUDE_DIR=${EIGEN3_INCLUDE_DIR} does not exist; likely corrupt Eigen3 build registered in user or system package registry; specify EIGEN3_INCLUDE_DIR manually or (better) configure (with CMake) and install Eigen3 package")
    else(NOT EXISTS "${EIGEN3_INCLUDE_DIR}")
      add_library(TiledArray_Eigen INTERFACE)
      set_property(TARGET TiledArray_Eigen PROPERTY
              INTERFACE_INCLUDE_DIRECTORIES ${EIGEN3_INCLUDE_DIR})
    endif(NOT EXISTS "${EIGEN3_INCLUDE_DIR}")
  endif (EIGEN3_FOUND)
endif (TARGET Eigen3::Eigen)

# validate found
if (TARGET TiledArray_Eigen)

  # Perform a compile check with Eigen
  cmake_push_check_state()

  # INTERFACE libraries cannot be used as CMAKE_REQUIRED_LIBRARIES, so must manually transfer deps info
  get_property(EIGEN3_INCLUDE_DIRS TARGET TiledArray_Eigen PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
  if (NOT MADNESS_INTERNAL_INCLUDE_DIRS)
    message(FATAL_ERROR "eigen.cmake must be loaded after calling detect_MADNESS_config()")
  endif()
  list(APPEND CMAKE_REQUIRED_INCLUDES ${EIGEN3_INCLUDE_DIRS} ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src
       ${MADNESS_INTERNAL_INCLUDE_DIRS} ${LAPACK_INCLUDE_DIRS})
  list(APPEND CMAKE_REQUIRED_LIBRARIES ${LAPACK_LIBRARIES})
  foreach(_def ${LAPACK_COMPILE_DEFINITIONS})
    list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D${_def}")
  endforeach()
  list(APPEND CMAKE_REQUIRED_FLAGS ${LAPACK_COMPILE_OPTIONS})

  CHECK_CXX_SOURCE_COMPILES("
    #include <Eigen/Dense>
    #include <Eigen/SparseCore>
    #include <iostream>
    int main(int argc, char* argv[]){
      Eigen::MatrixXd m = Eigen::MatrixXd::Random(5, 5);
      m = m.transpose() + m;
      Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eig(m);
      Eigen::MatrixXd m_invsqrt = eig.operatorInverseSqrt();
      std::cout << m_invsqrt << std::endl;
    }"
    EIGEN3_COMPILES)

  cmake_pop_check_state()

  if (NOT EIGEN3_COMPILES)
    message(FATAL_ERROR "Eigen3 found, but failed to compile test program")
  endif()

elseif(TA_EXPERT)

  message("** Eigen3 was not found")
  message(FATAL_ERROR "** Downloading and building Eigen3 is explicitly disabled in EXPERT mode")

else()

  include(ExternalProject)

  # Set source and build path for Eigen3 in the TiledArray Project
  set(EXTERNAL_SOURCE_DIR   ${PROJECT_BINARY_DIR}/external/source/eigen)
  set(EXTERNAL_BUILD_DIR  ${PROJECT_BINARY_DIR}/external/build/eigen)
  set(EIGEN3_URL https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.bz2)
  set(EIGEN3_URL_HASH MD5=05b1f7511c93980c385ebe11bd3c93fa)

  message("** Will build Eigen from ${EIGEN3_URL}")

  ExternalProject_Add(eigen3
    PREFIX ${CMAKE_INSTALL_PREFIX}
    STAMP_DIR ${EXTERNAL_BUILD_DIR}/stamp
    TMP_DIR ${EXTERNAL_BUILD_DIR}/tmp
   #--Download step--------------
    DOWNLOAD_DIR ${EXTERNAL_SOURCE_DIR}
    URL ${EIGEN3_URL}
    URL_HASH ${EIGEN3_URL_HASH}
   #--Configure step-------------
    SOURCE_DIR ${EXTERNAL_SOURCE_DIR}
    CONFIGURE_COMMAND ""
   #--Build step-----------------
    BINARY_DIR ${EXTERNAL_BUILD_DIR}
    BUILD_COMMAND ""
   #--Install step---------------
    INSTALL_COMMAND ""
   #--Custom targets-------------
    STEP_TARGETS download
    )

  # Add eigen3 dependency to External
  add_dependencies(External-tiledarray eigen3)

  # create an exportable interface target for eigen3
  add_library(TiledArray_Eigen INTERFACE)
  set_property(TARGET TiledArray_Eigen PROPERTY
          INTERFACE_INCLUDE_DIRECTORIES $<BUILD_INTERFACE:${EXTERNAL_SOURCE_DIR}>
          $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/eigen3>)

  # Install Eigen 3
  install(
    DIRECTORY
        ${EXTERNAL_SOURCE_DIR}/Eigen
        ${EXTERNAL_SOURCE_DIR}/unsupported
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/eigen3
    COMPONENT eigen3
    )
  install(
    FILES ${EXTERNAL_SOURCE_DIR}/signature_of_eigen3_matrix_library
    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/eigen3
    COMPONENT eigen3
    )

endif()

# finish configuring TiledArray_Eigen and install
if (TARGET TiledArray_Eigen)
  # TiledArray_Eigen uses LAPACK/MKL
  target_link_libraries(TiledArray_Eigen INTERFACE ${LAPACK_LIBRARIES})
  target_include_directories(TiledArray_Eigen INTERFACE ${LAPACK_INCLUDE_DIRS})
  target_compile_definitions(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_DEFINITIONS})
  target_compile_options(TiledArray_Eigen INTERFACE ${LAPACK_COMPILE_OPTIONS})
  if (MADNESS_HAS_MKL)
    target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_MKL_ALL)
  else(MADNESS_HAS_MKL)
    # Eigen's prototypes for non-MKL (i.e. F77) BLAS interface libraries do not match those in MADNESS (and are not const correct)
    # thus can't use non-MKL BLAS, only LAPACK
    # target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_BLAS)
    if (_tiledarray_eigen_use_lapacke)
      target_compile_definitions(TiledArray_Eigen INTERFACE EIGEN_USE_LAPACKE EIGEN_USE_LAPACKE_STRICT)
    endif ()
  endif(MADNESS_HAS_MKL)
  install(TARGETS TiledArray_Eigen EXPORT tiledarray COMPONENT tiledarray)
endif(TARGET TiledArray_Eigen)