1CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
2
3INCLUDE(GNUInstallDirs)
4
5# ---[ Project
6PROJECT(FP16 C CXX)
7
8# ---[ Options.
9OPTION(FP16_BUILD_TESTS "Build FP16 unit tests" ON)
10OPTION(FP16_BUILD_BENCHMARKS "Build FP16 micro-benchmarks" ON)
11
12# ---[ CMake options
13IF(FP16_BUILD_TESTS)
14  ENABLE_TESTING()
15ENDIF()
16
17MACRO(FP16_TARGET_ENABLE_CXX11 target)
18  IF(${CMAKE_VERSION} VERSION_LESS "3.1")
19    IF(NOT MSVC)
20      TARGET_COMPILE_OPTIONS(${target} PRIVATE -std=c++11)
21    ENDIF()
22  ELSE()
23    SET_TARGET_PROPERTIES(${target} PROPERTIES
24      CXX_STANDARD 11
25      CXX_STANDARD_REQUIRED YES
26      CXX_EXTENSIONS YES)
27  ENDIF()
28ENDMACRO()
29
30# ---[ Download deps
31SET(CONFU_DEPENDENCIES_SOURCE_DIR ${CMAKE_SOURCE_DIR}/deps
32  CACHE PATH "Confu-style dependencies source directory")
33SET(CONFU_DEPENDENCIES_BINARY_DIR ${CMAKE_BINARY_DIR}/deps
34  CACHE PATH "Confu-style dependencies binary directory")
35
36IF(NOT DEFINED PSIMD_SOURCE_DIR)
37  MESSAGE(STATUS "Downloading PSimd to ${CONFU_DEPENDENCIES_SOURCE_DIR}/psimd (define PSIMD_SOURCE_DIR to avoid it)")
38  CONFIGURE_FILE(cmake/DownloadPSimd.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/psimd-download/CMakeLists.txt")
39  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
40    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/psimd-download")
41  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
42    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/psimd-download")
43  SET(PSIMD_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/psimd" CACHE STRING "PSimd source directory")
44ENDIF()
45
46IF(FP16_BUILD_TESTS AND NOT DEFINED GOOGLETEST_SOURCE_DIR)
47  MESSAGE(STATUS "Downloading Google Test to ${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest (define GOOGLETEST_SOURCE_DIR to avoid it)")
48  CONFIGURE_FILE(cmake/DownloadGoogleTest.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download/CMakeLists.txt")
49  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
50    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
51  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
52    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
53  SET(GOOGLETEST_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest" CACHE STRING "Google Test source directory")
54ENDIF()
55
56IF(FP16_BUILD_BENCHMARKS AND NOT DEFINED GOOGLEBENCHMARK_SOURCE_DIR)
57  MESSAGE(STATUS "Downloading Google Benchmark to ${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark (define GOOGLEBENCHMARK_SOURCE_DIR to avoid it)")
58  CONFIGURE_FILE(cmake/DownloadGoogleBenchmark.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download/CMakeLists.txt")
59  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
60    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download")
61  EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
62    WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download")
63  SET(GOOGLEBENCHMARK_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark" CACHE STRING "Google Benchmark source directory")
64ENDIF()
65
66# ---[ FP16 library
67IF(${CMAKE_VERSION} VERSION_LESS "3.0")
68  ADD_LIBRARY(fp16 STATIC
69    include/fp16.h
70    include/fp16/fp16.h
71    include/fp16/bitcasts.h
72    include/fp16/psimd.h)
73  SET_TARGET_PROPERTIES(fp16 PROPERTIES LINKER_LANGUAGE C)
74ELSE()
75  ADD_LIBRARY(fp16 INTERFACE)
76ENDIF()
77TARGET_INCLUDE_DIRECTORIES(fp16 INTERFACE
78    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
79    $<INSTALL_INTERFACE:include>)
80
81INSTALL(FILES include/fp16.h
82  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
83INSTALL(FILES
84    include/fp16/bitcasts.h
85    include/fp16/fp16.h
86    include/fp16/psimd.h
87    include/fp16/__init__.py
88    include/fp16/avx.py
89    include/fp16/avx2.py
90  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fp16)
91
92# ---[ Configure psimd
93IF(NOT TARGET psimd)
94  ADD_SUBDIRECTORY(
95    "${PSIMD_SOURCE_DIR}"
96    "${CONFU_DEPENDENCIES_BINARY_DIR}/psimd")
97ENDIF()
98
99IF(FP16_BUILD_TESTS)
100  # ---[ Build google test
101  IF(NOT TARGET gtest)
102    SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
103    ADD_SUBDIRECTORY(
104      "${GOOGLETEST_SOURCE_DIR}"
105      "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest")
106  ENDIF()
107
108  # ---[ Build FP16 unit tests
109  ADD_EXECUTABLE(ieee-to-fp32-bits-test test/ieee-to-fp32-bits.cc test/tables.cc)
110  TARGET_INCLUDE_DIRECTORIES(ieee-to-fp32-bits-test PRIVATE test)
111  TARGET_LINK_LIBRARIES(ieee-to-fp32-bits-test fp16 gtest gtest_main)
112  ADD_TEST(ieee-to-fp32-bits ieee-to-fp32-bits-test)
113
114  ADD_EXECUTABLE(ieee-to-fp32-value-test test/ieee-to-fp32-value.cc test/tables.cc)
115  TARGET_INCLUDE_DIRECTORIES(ieee-to-fp32-value-test PRIVATE test)
116  TARGET_LINK_LIBRARIES(ieee-to-fp32-value-test fp16 gtest gtest_main)
117  ADD_TEST(ieee-to-fp32-value ieee-to-fp32-value-test)
118
119  ADD_EXECUTABLE(ieee-from-fp32-value-test test/ieee-from-fp32-value.cc test/tables.cc)
120  TARGET_INCLUDE_DIRECTORIES(ieee-from-fp32-value-test PRIVATE test)
121  TARGET_LINK_LIBRARIES(ieee-from-fp32-value-test fp16 gtest gtest_main)
122  ADD_TEST(ieee-from-fp32-value ieee-from-fp32-value-test)
123
124  ADD_EXECUTABLE(alt-to-fp32-bits-test test/alt-to-fp32-bits.cc test/tables.cc)
125  TARGET_INCLUDE_DIRECTORIES(alt-to-fp32-bits-test PRIVATE test)
126  TARGET_LINK_LIBRARIES(alt-to-fp32-bits-test fp16 gtest gtest_main)
127  ADD_TEST(alt-to-fp32-bits alt-to-fp32-bits-test)
128
129  ADD_EXECUTABLE(alt-to-fp32-value-test test/alt-to-fp32-value.cc test/tables.cc)
130  TARGET_INCLUDE_DIRECTORIES(alt-to-fp32-value-test PRIVATE test)
131  TARGET_LINK_LIBRARIES(alt-to-fp32-value-test fp16 gtest gtest_main)
132  ADD_TEST(alt-to-fp32-value alt-to-fp32-value-test)
133
134  ADD_EXECUTABLE(alt-from-fp32-value-test test/alt-from-fp32-value.cc test/tables.cc)
135  TARGET_INCLUDE_DIRECTORIES(alt-from-fp32-value-test PRIVATE test)
136  TARGET_LINK_LIBRARIES(alt-from-fp32-value-test fp16 gtest gtest_main)
137  ADD_TEST(alt-from-fp32-value alt-from-fp32-value-test)
138
139  ADD_EXECUTABLE(bitcasts-test test/bitcasts.cc)
140  TARGET_LINK_LIBRARIES(bitcasts-test fp16 gtest gtest_main)
141  ADD_TEST(bitcasts bitcasts-test)
142ENDIF()
143
144IF(FP16_BUILD_BENCHMARKS)
145  # ---[ Build google benchmark
146  IF(NOT TARGET benchmark)
147    SET(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "")
148    ADD_SUBDIRECTORY(
149      "${GOOGLEBENCHMARK_SOURCE_DIR}"
150      "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark")
151  ENDIF()
152
153  # ---[ Build FP16 benchmarks
154  ADD_EXECUTABLE(ieee-element-bench bench/ieee-element.cc)
155  TARGET_COMPILE_DEFINITIONS(ieee-element-bench PRIVATE FP16_COMPARATIVE_BENCHMARKS=1)
156  TARGET_INCLUDE_DIRECTORIES(ieee-element-bench PRIVATE ${PROJECT_SOURCE_DIR})
157  TARGET_LINK_LIBRARIES(ieee-element-bench fp16 psimd benchmark)
158
159  ADD_EXECUTABLE(alt-element-bench bench/alt-element.cc)
160  TARGET_LINK_LIBRARIES(alt-element-bench fp16 psimd benchmark)
161
162  ADD_EXECUTABLE(from-ieee-array-bench bench/from-ieee-array.cc)
163  FP16_TARGET_ENABLE_CXX11(from-ieee-array-bench)
164  TARGET_COMPILE_DEFINITIONS(from-ieee-array-bench PRIVATE FP16_COMPARATIVE_BENCHMARKS=1)
165  TARGET_INCLUDE_DIRECTORIES(from-ieee-array-bench PRIVATE ${PROJECT_SOURCE_DIR})
166  TARGET_LINK_LIBRARIES(from-ieee-array-bench fp16 psimd benchmark)
167
168  ADD_EXECUTABLE(from-alt-array-bench bench/from-alt-array.cc)
169  FP16_TARGET_ENABLE_CXX11(from-alt-array-bench)
170  TARGET_LINK_LIBRARIES(from-alt-array-bench fp16 psimd benchmark)
171
172  ADD_EXECUTABLE(to-ieee-array-bench bench/to-ieee-array.cc)
173  FP16_TARGET_ENABLE_CXX11(to-ieee-array-bench)
174  TARGET_COMPILE_DEFINITIONS(to-ieee-array-bench PRIVATE FP16_COMPARATIVE_BENCHMARKS=1)
175  TARGET_INCLUDE_DIRECTORIES(to-ieee-array-bench PRIVATE ${PROJECT_SOURCE_DIR})
176  TARGET_LINK_LIBRARIES(to-ieee-array-bench fp16 psimd benchmark)
177
178  ADD_EXECUTABLE(to-alt-array-bench bench/to-alt-array.cc)
179  FP16_TARGET_ENABLE_CXX11(to-alt-array-bench)
180  TARGET_LINK_LIBRARIES(to-alt-array-bench fp16 psimd benchmark)
181ENDIF()
182