-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeLists.txt
246 lines (224 loc) · 9.01 KB
/
CMakeLists.txt
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
#
# The University of Texas at Austin, and Stanford University
#
# This file is part of Distributed-Memory Hierarchical Matrices (DMHM) and is
# under the GPLv3 License, which can be found in the LICENSE file in the root
# directory, or at http://opensource.org/licenses/GPL-3.0
#
cmake_minimum_required(VERSION 2.8.5) # for the new FindMPI module
project(DMHM)
set(DMHM_VERSION_MAJOR 0)
set(DMHM_VERSION_MINOR 2)
option(RELEASE "Avoid unnecessary assertions." ON)
option(TIME_MULTIPLY "Instrument H-matrix multiply with timers." OFF)
option(BUILD_TESTS "Build the test drivers" ON)
option(AVOID_COMPLEX_MPI "Avoid complex MPI routines for robustness" ON)
option(MEMORY_INFO "Collect memory infomation during the code." OFF)
mark_as_advanced(AVOID_COMPLEX_MPI)
# Whether or not to use Qt5 for visualization if it is found (experimental)
option(USE_QT5 "Attempt to use Qt5?" OFF)
if(RELEASE)
set(CXX_FLAGS "-O3" CACHE STRING "CXX flags")
else()
set(CXX_FLAGS "-g -Wall" CACHE STRING "CXX flags")
endif()
find_package(MPI)
if(NOT MPI_CXX_FOUND)
message(FATAL_ERROR "MPI C++ compiler was not found and is required")
endif()
include_directories(${MPI_CXX_INCLUDE_PATH})
set(EXTRA_FLAGS "${MPI_CXX_COMPILE_FLAGS}")
set(HAVE_QT5 FALSE)
if(USE_QT5)
# Search for Qt5
find_package(Qt5Widgets)
if(Qt5Widgets_FOUND)
set(DMHM_HEADERS_PREMOC "include/dmhm/graphics/display_window-premoc.hpp")
qt_wrap_cpp(dmhm DMHM_MOC_SRC ${DMHM_HEADERS_PREMOC})
include_directories(${Qt5Widgets_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS})
set(EXTRA_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ${EXTRA_FLAGS}")
set(HAVE_QT5 TRUE)
message(STATUS "Found Qt5")
else()
message(STATUS "Did NOT find Qt5")
endif()
endif()
# Now append the extra flags
set(CMAKE_CXX_FLAGS "${CXX_FLAGS} ${EXTRA_FLAGS}")
if(NOT MATH_LIBS)
set(MATH_DESC "BLAS/LAPACK link flags")
# Look for default BLAS/LAPACK
set(REFERENCE_REQUIRED LAPACK BLAS)
find_library(BLAS_LIB
NAMES blas blas.a blas.lib
PATHS ${REFERENCE_ROOT})
find_library(LAPACK_LIB
NAMES lapack lapack.a lapack.lib
reflapack reflapack.a reflapack.lib
PATHS ${REFERENCE_ROOT})
set(REFERENCE_FOUND ON)
set(MATH_LIBS "")
foreach(NAME ${REFERENCE_REQUIRED})
if( ${NAME}_LIB )
message(STATUS "Found ${NAME}_LIB: ${${NAME}_LIB}")
list(APPEND MATH_LIBS ${${NAME}_LIB})
else()
message(STATUS "Could not find ${NAME}_LIB")
set(REFERENCE_FOUND OFF)
endif()
endforeach()
message(STATUS "REFERENCE_FOUND=${REFERENCE_FOUND}")
if(REFERENCE_FOUND)
message(STATUS "WARNING: Using reference BLAS/LAPACK.")
message(STATUS "MATH_LIBS=${MATH_LIBS}")
else()
set(MATH_LIBS "" CACHE STRING ${MATH_DESC})
message(FATAL_ERROR
"Could not find BLAS/LAPACK libs. Please provide the root directory of MKL with -DMKL_ROOT, the directory of reference implementations with -DREFERENCE_ROOT, or manually specify all math libraries with -DMATH_LIBS. There are numerous idiosyncratic library dependencies for BLAS/LAPACK, so you will almost certainly need to manually specify -DMATH_LIBS.")
endif()
# Append the standard math libraries to the link list.
list(APPEND MATH_LIBS m)
endif()
# Attempt to detect the BLAS and LAPACK underscore conventions.
# We currently only handle whether or not there is an underscore appended.
include(CheckFunctionExists)
set(CMAKE_REQUIRED_LIBRARIES ${MATH_LIBS})
check_function_exists(daxpy HAVE_DAXPY)
check_function_exists(daxpy_ HAVE_DAXPY_POST)
if(HAVE_DAXPY)
set(BLAS_POST FALSE)
set(BLAS_DEFS "")
elseif(HAVE_DAXPY_POST)
set(BLAS_POST TRUE)
set(BLAS_DEFS "-DBLAS_POST")
else()
message(FATAL_ERROR "Could not determine BLAS format.")
endif()
check_function_exists(dpotrf HAVE_DPOTRF)
check_function_exists(dpotrf_ HAVE_DPOTRF_POST)
if(HAVE_DPOTRF)
set(LAPACK_POST FALSE)
set(LAPACK_DEFS "")
elseif(HAVE_DPOTRF_POST)
set(LAPACK_POST TRUE)
set(LAPACK_DEFS "-DLAPACK_POST")
else()
message(FATAL_ERROR "Could not determine LAPACK format.")
endif()
# Look for MPI_Reduce_scatter_block (and MPI_Reduce_scatter as sanity check)
set(CMAKE_REQUIRED_FLAGS "${MPI_C_COMPILE_FLAGS} ${MPI_C_LINK_FLAGS}")
set(CMAKE_REQUIRED_INCLUDES ${MPI_C_INCLUDE_PATH})
set(CMAKE_REQUIRED_LIBRARIES ${MPI_C_LIBRARIES})
check_function_exists(MPI_Reduce_scatter HAVE_MPI_REDUCE_SCATTER)
if(NOT HAVE_MPI_REDUCE_SCATTER)
message(FATAL_ERROR "Could not find MPI_Reduce_scatter")
endif()
# Check for MPI_IN_PLACE (essentially MPI2 support)
include(CheckCSourceCompiles)
set(MPI_IN_PLACE_CODE
"#include \"mpi.h\"
int main( int argc, char* argv[] )
{
MPI_Init( &argc, &argv );
float a;
MPI_Allreduce
( MPI_IN_PLACE, &a, 1, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD );
MPI_Finalize();
return 0;
}")
check_c_source_compiles("${MPI_IN_PLACE_CODE}" HAVE_MPI_IN_PLACE)
if(NOT HAVE_MPI_IN_PLACE)
message(FATAL_ERROR "Could not find MPI_IN_PLACE")
endif()
# Look for restrict support
include(CheckCXXSourceCompiles)
set(RESTRICT_CODE "int main(void) { int* RESTRICT a; return 0; }")
set(CMAKE_REQUIRED_DEFINITIONS "-DRESTRICT=__restrict__")
check_cxx_source_compiles("${RESTRICT_CODE}" HAVE___restrict__)
set(CMAKE_REQUIRED_DEFINITIONS "-DRESTRICT=__restrict")
check_cxx_source_compiles("${RESTRICT_CODE}" HAVE___restrict)
set(CMAKE_REQUIRED_DEFINITIONS "-DRESTRICT=restrict")
check_cxx_source_compiles("${RESTRICT_CODE}" HAVE_restrict)
if(HAVE___restrict__)
set(RESTRICT "__restrict__")
message(STATUS "Using __restrict__ keyword.")
elseif(HAVE___restrict)
set(RESTRICT "__restrict")
message(STATUS "Using __restrict keyword.")
elseif(HAVE_restrict)
set(RESTRICT "restrict")
message(STATUS "Using restrict keyword.")
else()
set(RESTRICT "")
message(STATUS "Could not find a restrict keyword.")
endif()
# Store all of our system-specific definitions
configure_file(${PROJECT_SOURCE_DIR}/cmake/config.h.cmake
${PROJECT_BINARY_DIR}/include/dmhm/config.h)
install(FILES ${PROJECT_BINARY_DIR}/include/dmhm/config.h
DESTINATION include/dmhm)
# Grab all of the .c, .cpp, .h, and .hpp DMHM files
file(GLOB_RECURSE DMHM_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
"src/*.c" "src/*.cpp" "src/*-incl.hpp")
file(GLOB_RECURSE DMHM_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
"include/*.h" "include/*.hpp")
set(DMHM_SRC "${DMHM_CPP};${DMHM_HEADERS};${DMHM_MOC_SRC}")
# Build the DMHM source
add_library(dmhm STATIC ${DMHM_SRC})
install(TARGETS dmhm DESTINATION lib)
# Copy the headers into the build directory
set(PREPARED_HEADERS)
foreach(HEADER ${DMHM_HEADERS})
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${HEADER}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}
${CMAKE_CURRENT_BINARY_DIR}/${HEADER}
DEPENDS "${PROJECT_SOURCE_DIR}/${HEADER}")
list(APPEND PREPARED_HEADERS ${PROJECT_BINARY_DIR}/${HEADER})
get_filename_component(HEADER_PATH ${HEADER} PATH)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${HEADER} DESTINATION ${HEADER_PATH})
endforeach()
add_custom_target(prepare_dmhm_headers DEPENDS ${PREPARED_HEADERS})
add_dependencies(dmhm prepare_dmhm_headers)
# Make sure the DMHM headers can be found
include_directories("${PROJECT_BINARY_DIR}/include")
# Create a dummy library in order to be able to force the math libraries
# to be linked last
add_library(cmake-dummy-lib STATIC cmake/CMakeDummyFunction.cpp)
list(APPEND EXTERNAL_LIBS "${MATH_LIBS} ${MPI_CXX_LIBRARIES}")
if(HAVE_QT5)
list(APPEND EXTERNAL_LIBS "${Qt5Widgets_LIBRARIES}")
endif()
target_link_libraries(cmake-dummy-lib ${EXTERNAL_LIBS})
# Build the test drivers if necessary
set(MPI_LINK_FLAGS "${MPI_CXX_LINK_FLAGS}")
if(BUILD_TESTS)
set(TEST_DIR ${PROJECT_SOURCE_DIR}/tests)
set(TEST_TYPES core hmat_tools HMat2d DistHMat2d HMat3d DistHMat3d)
set(core_TESTS MemoryMap ParallelLcg Timer)
set(hmat_tools_TESTS MatrixAdd Compress ConvertSubmatrix PackedQR)
set(HMat2d_TESTS Invert LowRankConstructor MultiplyHMat Pack)
set(DistHMat2d_TESTS Ghost ImportSparse MultiplyHMat Pack
RandomMultiplyHMat RandomMultiplyVectors
InvertHMat SparseToHMat)
set(HMat3d_TESTS Invert LowRankConstructor MultiplyHMat Pack)
set(DistHMat3d_TESTS Ghost ImportSparse MultiplyHMat Pack
RandomMultiplyHMat RandomMultiplyVectors
InvertHMat SparseToHMat)
foreach(TYPE ${TEST_TYPES})
set(OUTPUT_DIR "${PROJECT_BINARY_DIR}/bin/${TYPE}")
foreach(TEST ${${TYPE}_TESTS})
add_executable(${TYPE}-${TEST} ${TEST_DIR}/${TYPE}/${TEST}.cpp)
target_link_libraries(${TYPE}-${TEST} dmhm cmake-dummy-lib)
set_target_properties(${TYPE}-${TEST}
PROPERTIES OUTPUT_NAME ${TEST}
RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_DIR})
if(MPI_LINK_FLAGS)
set_target_properties(${TYPE}-${TEST} PROPERTIES
LINK_FLAGS ${MPI_LINK_FLAGS})
endif()
install(TARGETS ${TYPE}-${TEST} DESTINATION bin/${TYPE})
endforeach()
endforeach()
endif()