-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
226 lines (203 loc) · 7.18 KB
/
Copy pathCMakeLists.txt
File metadata and controls
226 lines (203 loc) · 7.18 KB
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
cmake_minimum_required(VERSION 3.22)
project(clustering)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}
)
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
include(CheckCXXCompilerFlag)
include(cmake/CPM.cmake)
include(cmake/Tooling.cmake)
include(cmake/CitorDep.cmake)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(CLUSTERING_BUILD_BENCHMARK "Build benchmarks" ${CLUSTERING_IS_TOP_LEVEL})
option(CLUSTERING_BUILD_TESTS "Build unit tests" ${CLUSTERING_IS_TOP_LEVEL})
option(
CLUSTERING_BUILD_DOCS
"Build API documentation (Doxygen + doxygen-awesome-css)"
OFF
)
check_cxx_compiler_flag("-mavx2" CLUSTERING_COMPILER_SUPPORTS_AVX2)
set(CLUSTERING_USE_AVX2
${CLUSTERING_COMPILER_SUPPORTS_AVX2}
CACHE BOOL
"Use AVX2"
)
set(CLUSTERING_BUILD_WITH_SANITIZER OFF CACHE BOOL "Build with sanitizer")
add_library(clustering_header_lib INTERFACE)
target_include_directories(
clustering_header_lib
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include
)
target_link_libraries(clustering_header_lib INTERFACE citor::citor)
# Top-level-only: enforce -Wall -Wextra -Werror on our executables.
# Consumers that pull us in as a subdirectory do not inherit these flags.
add_library(clustering_warnings INTERFACE)
if(CLUSTERING_IS_TOP_LEVEL)
target_compile_options(
clustering_warnings
INTERFACE
$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wall;-Wextra;-Werror>
$<$<CXX_COMPILER_ID:GNU>:-Wno-ignored-attributes>
)
endif()
add_executable(clustering_demo app/main.cpp)
target_link_libraries(
clustering_demo
PRIVATE clustering_header_lib clustering_warnings
)
clustering_enable_tidy(clustering_demo)
if(CLUSTERING_USE_AVX2)
if(NOT CLUSTERING_COMPILER_SUPPORTS_AVX2)
message(FATAL_ERROR "AVX2 not supported but requested")
endif()
target_compile_options(clustering_header_lib INTERFACE -mavx2 -mfma)
target_compile_definitions(
clustering_header_lib
INTERFACE CLUSTERING_USE_AVX2
)
endif()
if(CLUSTERING_BUILD_WITH_SANITIZER)
target_compile_options(
clustering_header_lib
INTERFACE -fsanitize=thread -fno-omit-frame-pointer
)
target_link_options(clustering_header_lib INTERFACE -fsanitize=thread)
message(STATUS "Build with sanitizer")
endif()
if(CLUSTERING_BUILD_BENCHMARK)
cpmaddpackage(
NAME benchmark
GITHUB_REPOSITORY google/benchmark
VERSION 1.9.4
SYSTEM YES
OPTIONS "BENCHMARK_ENABLE_GTEST_TESTS OFF;BENCHMARK_ENABLE_TESTING OFF"
)
add_executable(kdtree_benchmark benchmark/kdtree_benchmark.cpp)
target_link_libraries(
kdtree_benchmark
benchmark::benchmark
clustering_header_lib
clustering_warnings
)
clustering_enable_tidy(kdtree_benchmark)
add_executable(gemm_benchmark benchmark/gemm_benchmark.cpp)
target_link_libraries(
gemm_benchmark
benchmark::benchmark
clustering_header_lib
clustering_warnings
)
add_executable(kmeans_benchmark benchmark/kmeans_benchmark.cpp)
target_link_libraries(
kmeans_benchmark
benchmark::benchmark
clustering_header_lib
clustering_warnings
)
clustering_enable_tidy(kmeans_benchmark)
add_executable(nn_descent_benchmark benchmark/nn_descent_benchmark.cpp)
target_link_libraries(
nn_descent_benchmark
benchmark::benchmark
clustering_header_lib
clustering_warnings
)
clustering_enable_tidy(nn_descent_benchmark)
add_executable(dbscan_benchmark benchmark/dbscan_benchmark.cpp)
target_link_libraries(
dbscan_benchmark
benchmark::benchmark
clustering_header_lib
clustering_warnings
)
clustering_enable_tidy(dbscan_benchmark)
# OpenBLAS is optional: when available the benchmark adds a comparative
# cblas_sgemm fixture next to ours. pkg-config reliably reports the include
# dir on every distro that ships openblas.pc (Nix, Debian, Arch, Homebrew),
# avoiding the install-tree probe that find_package(BLAS) skips.
find_package(PkgConfig QUIET)
set(_clustering_openblas_target "")
if(PkgConfig_FOUND)
# NixOS's openblas package exports cblas.pc (not openblas.pc); Debian /
# Homebrew / Arch all do the same. Try cblas first, fall back to
# openblas for the rare distro that uses that name.
pkg_check_modules(CLUSTERING_OPENBLAS QUIET IMPORTED_TARGET cblas)
if(NOT CLUSTERING_OPENBLAS_FOUND)
pkg_check_modules(
CLUSTERING_OPENBLAS
QUIET
IMPORTED_TARGET
openblas
)
endif()
if(CLUSTERING_OPENBLAS_FOUND)
set(_clustering_openblas_target PkgConfig::CLUSTERING_OPENBLAS)
endif()
endif()
if(NOT _clustering_openblas_target)
# Fallback for systems without pkg-config: find_package(BLAS) locates the
# library, then probe common cblas.h locations.
find_package(BLAS QUIET)
if(BLAS_FOUND)
find_path(
CLUSTERING_CBLAS_INCLUDE_DIR
cblas.h
PATHS
/usr/include
/usr/include/openblas
/usr/local/include
$ENV{OPENBLAS_INCLUDE_DIR}
)
if(CLUSTERING_CBLAS_INCLUDE_DIR)
add_library(_clustering_blas_fallback INTERFACE)
target_link_libraries(
_clustering_blas_fallback
INTERFACE ${BLAS_LIBRARIES}
)
target_include_directories(
_clustering_blas_fallback
INTERFACE ${CLUSTERING_CBLAS_INCLUDE_DIR}
)
set(_clustering_openblas_target _clustering_blas_fallback)
endif()
endif()
endif()
if(_clustering_openblas_target)
message(STATUS "OpenBLAS found; gemm benchmark will compare against it")
target_compile_definitions(
gemm_benchmark
PRIVATE CLUSTERING_BENCHMARK_OPENBLAS
)
target_link_libraries(gemm_benchmark ${_clustering_openblas_target})
else()
message(
STATUS
"OpenBLAS not found; gemm benchmark will run our path only"
)
endif()
clustering_enable_tidy(gemm_benchmark)
endif()
if(CLUSTERING_BUILD_TESTS)
include(cmake/GTestDep.cmake)
enable_testing()
add_subdirectory(tests)
endif()
if(CLUSTERING_BUILD_DOCS)
find_package(Doxygen REQUIRED)
include(cmake/DocsDep.cmake)
set(AWESOME_CSS_DIR ${doxygen-awesome-css_SOURCE_DIR})
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/docs)
set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in)
set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
add_custom_target(
docs
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
endif()