-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathOpenMP.cmake
155 lines (135 loc) Β· 6.04 KB
/
OpenMP.cmake
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
# Check if OpenMP supports 128-bit integers out of the box
# or if we have to link against libatomic.
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
find_package(OpenMP QUIET)
if(NOT (OpenMP_FOUND OR OpenMP_CXX_FOUND))
message(STATUS "Performing Test OpenMP")
message(STATUS "Performing Test OpenMP - Failed")
endif()
# CMake has found OpenMP, now we need to check
# if OpenMP supports 128-bit integers.
if(OpenMP_FOUND OR OpenMP_CXX_FOUND)
cmake_push_check_state()
if(TARGET OpenMP::OpenMP_CXX)
set(CMAKE_REQUIRED_LIBRARIES "OpenMP::OpenMP_CXX")
else()
set(CMAKE_REQUIRED_FLAGS "${OpenMP_CXX_FLAGS}")
endif()
# Our <int128_t.hpp> requires C++11 or later
if(NOT compiler_supports_cpp11)
if(CMAKE_CXX11_EXTENSION_COMPILE_OPTION)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${CMAKE_CXX11_EXTENSION_COMPILE_OPTION} ${CMAKE_CXX_FLAGS}")
elseif(CMAKE_CXX11_STANDARD_COMPILE_OPTION)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${CMAKE_CXX11_STANDARD_COMPILE_OPTION} ${CMAKE_CXX_FLAGS}")
endif()
endif()
if(DISABLE_INT128)
set(CMAKE_REQUIRED_DEFINITIONS "-D${DISABLE_INT128}")
endif()
set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/include")
# Check if OpenMP supports 128-bit integers
check_cxx_source_compiles("
#include <int128_t.hpp>
#include <omp.h>
#include <stdint.h>
#include <iostream>
int main(int, char** argv) {
using primecount::maxint_t;
uintptr_t n = (uintptr_t) argv;
maxint_t sum = (maxint_t) n;
int iters = (int) n;
#pragma omp parallel for reduction(+: sum)
for (int i = 0; i < iters; i++)
sum += (i / 3) * omp_get_thread_num();
std::cout << (long) sum;
return 0;
}" OpenMP)
if(NOT OpenMP)
# Try if OpenMP works if we link against libatomic.
# This is sometimes required for LLVM/Clang.
find_library(LIB_ATOMIC NAMES atomic atomic.so.1 libatomic.so.1)
if(NOT LIB_ATOMIC)
# Some package managers like homebrew and macports store the compiler's
# libraries in a subdirectory of the library directory. E.g. GCC
# installed via homebrew stores libatomic at lib/gcc/13/libatomic.dylib
# instead of lib/libatomic.dylib. CMake's find_library() cannot easily
# be used to recursively find libraries. Therefore we use this workaround
# here (try adding -latomic to linker options) for this use case.
set(LIB_ATOMIC "-latomic")
endif()
set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}" "${LIB_ATOMIC}")
# Check if OpenMP compiles with libatomic
check_cxx_source_compiles("
#include <int128_t.hpp>
#include <omp.h>
#include <stdint.h>
#include <iostream>
int main(int, char** argv) {
using primecount::maxint_t;
uintptr_t n = (uintptr_t) argv;
maxint_t sum = (maxint_t) n;
int iters = (int) n;
#pragma omp parallel for reduction(+: sum)
for (int i = 0; i < iters; i++)
sum += (i / 3) * omp_get_thread_num();
std::cout << (long) sum;
return 0;
}" OpenMP_with_libatomic)
if(OpenMP_with_libatomic)
list(APPEND PRIMECOUNT_LINK_LIBRARIES "${LIB_ATOMIC}")
else()
set(LIB_ATOMIC "")
if(NOT DISABLE_INT128)
# As a last resort check if OpenMP supports int128_t if
# we include our <int128_OpenMP_patch.hpp> header.
# In this case OpenMP will use critical sections instead
# of atomics for 128-bit integers which is slightly less
# efficient. (required for LLVM/Clang on Windows)
check_cxx_source_compiles("
#include <int128_t.hpp>
#include <int128_OpenMP_patch.hpp>
#include <omp.h>
#include <stdint.h>
#include <iostream>
int main(int, char** argv) {
using primecount::maxint_t;
uintptr_t n = (uintptr_t) argv;
maxint_t sum = (maxint_t) n;
int iters = (int) n;
#pragma omp parallel for reduction(+: sum)
for (int i = 0; i < iters; i++)
sum += (i / 3) * omp_get_thread_num();
std::cout << (long) sum;
return 0;
}" OpenMP_int128_patch)
if(OpenMP_int128_patch)
list(APPEND PRIMECOUNT_COMPILE_DEFINITIONS "ENABLE_INT128_OPENMP_PATCH")
endif()
endif()
endif()
endif()
cmake_pop_check_state()
# OpenMP has been tested successfully, enable it
if(OpenMP OR OpenMP_with_libatomic OR OpenMP_int128_patch)
if(TARGET OpenMP::OpenMP_CXX)
list(APPEND PRIMECOUNT_LINK_LIBRARIES "OpenMP::OpenMP_CXX")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
# Create list of OpenMP libs for pkg-config/pkgconf
foreach(X IN LISTS OpenMP_CXX_LIB_NAMES)
string(APPEND PKGCONFIG_LIBS_OPENMP "-l${X} ")
endforeach()
endif()
endif()
# OpenMP test has failed, print warning message
if(NOT OpenMP AND NOT OpenMP_with_libatomic AND NOT OpenMP_int128_patch)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|LLVM")
message(WARNING "Install the OpenMP library (libomp) to enable multithreading in primecount!")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
message(WARNING "Install the OpenMP library (libgomp) to enable multithreading in primecount!")
else()
message(WARNING "Install the OpenMP library to enable multithreading in primecount!")
endif()
endif()