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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
|
cmake_minimum_required(VERSION 2.6)
# avoid some cmake warnings
IF(POLICY CMP0026)
CMAKE_POLICY(SET CMP0026 OLD)
ENDIF()
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
SET(CMAKE_LIBRARY_PATH /usr/lib/x86_64-linux-gnu/ ${CMAKE_LIBRARY_PATH})
#######################################################################
##### flags section
######################################################################
IF(MSVC)
# MSVC now supports C99 since VS2013/VS2015, however the standard version switch is not provided yet
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /std:c99")
ELSE(MSVC)
# enable gnu99 and not c99 because we use
# gnu extensions like posix_memalign
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
ENDIF(MSVC)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE=1) # respect the standard
ENDIF(MSVC)
IF(UNIX)
# prevent Unknown CMake command "check_function_exists".
INCLUDE(CheckFunctionExists)
ENDIF(UNIX)
# OpenMP support?
IF (WITH_OPENMP)
FIND_PACKAGE(OpenMP)
IF(OPENMP_FOUND)
MESSAGE(STATUS "Compiling with OpenMP support")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
ENDIF(OPENMP_FOUND)
ENDIF (WITH_OPENMP)
# ARM specific flags
FIND_PACKAGE(ARM)
IF (ASIMD_FOUND)
MESSAGE(STATUS "asimd/Neon found with compiler flag : -D__NEON__")
SET(CMAKE_C_FLAGS "-D__NEON__ ${CMAKE_C_FLAGS}")
ELSEIF (NEON_FOUND)
MESSAGE(STATUS "Neon found with compiler flag : -mfpu=neon -D__NEON__")
SET(CMAKE_C_FLAGS "-mfpu=neon -D__NEON__ ${CMAKE_C_FLAGS}")
ENDIF (ASIMD_FOUND)
IF (CORTEXA8_FOUND)
MESSAGE(STATUS "Cortex-A8 Found with compiler flag : -mcpu=cortex-a8")
SET(CMAKE_C_FLAGS "-mcpu=cortex-a8 -fprefetch-loop-arrays ${CMAKE_C_FLAGS}")
ENDIF (CORTEXA8_FOUND)
IF (CORTEXA9_FOUND)
MESSAGE(STATUS "Cortex-A9 Found with compiler flag : -mcpu=cortex-a9")
SET(CMAKE_C_FLAGS "-mcpu=cortex-a9 ${CMAKE_C_FLAGS}")
ENDIF (CORTEXA9_FOUND)
INCLUDE (CheckIncludeFile)
INCLUDE (CheckCSourceCompiles)
CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
# Check for a cpuid intrinsic
IF(HAVE_CPUID_H)
CHECK_C_SOURCE_COMPILES("#include <cpuid.h>
int main()
{
unsigned int eax, ebx, ecx, edx;
return __get_cpuid(0, &eax, &ebx, &ecx, &edx);
}" HAVE_GCC_GET_CPUID)
ENDIF()
IF(HAVE_GCC_GET_CPUID)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_GCC_GET_CPUID")
ENDIF(HAVE_GCC_GET_CPUID)
CHECK_C_SOURCE_COMPILES("#include <stdint.h>
static inline void cpuid(uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
uint32_t a = *eax, b, c = *ecx, d;
asm volatile ( \"cpuid\" : \"+a\"(a), \"=b\"(b), \"+c\"(c), \"=d\"(d) );
*eax = a; *ebx = b; *ecx = c; *edx = d;
}
int main() {
uint32_t a,b,c,d;
cpuid(&a, &b, &c, &d);
return 0;
}" NO_GCC_EBX_FPIC_BUG)
IF(NOT NO_GCC_EBX_FPIC_BUG)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_GCC_GET_CPUID")
ENDIF(NOT NO_GCC_EBX_FPIC_BUG)
FIND_PACKAGE(SSE) # checks SSE, AVX and AVX2
IF(C_SSE2_FOUND)
MESSAGE(STATUS "SSE2 Found")
SET(CMAKE_C_FLAGS "${C_SSE2_FLAGS} -DUSE_SSE2 ${CMAKE_C_FLAGS}")
ENDIF(C_SSE2_FOUND)
IF(C_SSE3_FOUND)
MESSAGE(STATUS "SSE3 Found")
SET(CMAKE_C_FLAGS "${C_SSE3_FLAGS} -DUSE_SSE3 ${CMAKE_C_FLAGS}")
ENDIF(C_SSE3_FOUND)
# we dont set -mavx and -mavx2 flags globally, but only for specific files
# however, we want to enable the AVX codepaths, so we still need to
# add USE_AVX and USE_AVX2 macro defines
IF(FALSE)
IF(C_AVX_FOUND)
MESSAGE(STATUS "AVX Found")
SET(CMAKE_C_FLAGS "-DUSE_AVX ${CMAKE_C_FLAGS}")
ENDIF(C_AVX_FOUND)
IF(C_AVX2_FOUND)
MESSAGE(STATUS "AVX2 Found")
SET(CMAKE_C_FLAGS "-DUSE_AVX2 ${CMAKE_C_FLAGS}")
ENDIF(C_AVX2_FOUND)
ENDIF()
CHECK_C_SOURCE_RUNS("
#include <stdatomic.h>
int main()
{
int a;
int oa;
atomic_store(&a, 1);
atomic_fetch_add(&a, 1);
oa = atomic_load(&a);
if(!atomic_compare_exchange_strong(&a, &oa, 3))
return -1;
return 0;
}
" HAS_C11_ATOMICS)
IF(NOT HAS_C11_ATOMICS)
CHECK_C_SOURCE_RUNS("
#include <intrin.h>
int main()
{
long a;
_InterlockedExchange(&a, 1);
_InterlockedExchangeAdd(&a, 1);
if(_InterlockedCompareExchange(&a, 3, 2) != 2)
return -1;
return 0;
}
" HAS_MSC_ATOMICS)
CHECK_C_SOURCE_RUNS("
int main()
{
int a;
__sync_lock_test_and_set(&a, 1);
__sync_fetch_and_add(&a, 1);
if(!__sync_bool_compare_and_swap(&a, 2, 3))
return -1;
return 0;
}
" HAS_GCC_ATOMICS)
ENDIF()
#######################################################################
##### sources section
######################################################################
# IF ANY SIMD FOUND
IF ("${ARCH}" STREQUAL "x86_64")
SET(simd generic/simd/convolve.c generic/simd/convolve5x5_sse.c)
SET(CMAKE_C_FLAGS "-DUSE_SSE2 ${CMAKE_C_FLAGS}")
SET_SOURCE_FILES_PROPERTIES(generic/simd/convolve5x5_sse.c PROPERTIES COMPILE_FLAGS "-O3 -ffast-math")
ENDIF()
# IF AVX FOUND
IF(FALSE)
IF(C_AVX_FOUND)
IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(generic/simd/convolve5x5_avx.c PROPERTIES COMPILE_FLAGS "/Ox /fp:fast ${C_AVX_FLAGS}")
SET_SOURCE_FILES_PROPERTIES(vector/AVX.c PROPERTIES COMPILE_FLAGS "/Ox /arch:AVX ${C_AVX_FLAGS}")
ELSE(MSVC)
SET_SOURCE_FILES_PROPERTIES(generic/simd/convolve5x5_avx.c PROPERTIES COMPILE_FLAGS "-O3 -ffast-math ${C_AVX_FLAGS}")
SET_SOURCE_FILES_PROPERTIES(vector/AVX.c PROPERTIES COMPILE_FLAGS "-O3 ${C_AVX_FLAGS}")
ENDIF(MSVC)
SET(simd ${simd} vector/AVX.c generic/simd/convolve5x5_avx.c)
ENDIF(C_AVX_FOUND)
IF(C_AVX2_FOUND)
IF(MSVC)
SET_SOURCE_FILES_PROPERTIES(vector/AVX2.c PROPERTIES COMPILE_FLAGS "/Ox /arch:AVX2 ${C_AVX2_FLAGS}")
ELSE(MSVC)
SET_SOURCE_FILES_PROPERTIES(vector/AVX2.c PROPERTIES COMPILE_FLAGS "-O3 ${C_AVX2_FLAGS}")
ENDIF(MSVC)
SET(simd ${simd} vector/AVX2.c)
ENDIF(C_AVX2_FOUND)
ENDIF()
SET(hdr
THGeneral.h THHalf.h THAllocator.h THSize.h THStorage.h THTensor.h THTensorApply.h THBlas.h THMath.h
THLapack.h THLogAdd.h THRandom.h THVector.h THAtomic.h )
SET(src
THGeneral.c THHalf.c THAllocator.c THSize.c THStorage.c THTensor.c THBlas.c THLapack.c
THLogAdd.c THRandom.c THFile.c THDiskFile.c THMemoryFile.c THAtomic.c THVector.c)
SET(src ${src} ${hdr} ${simd})
#######################################################################
##### build section
######################################################################
ADD_TORCH_LIBRARY(TH SHARED "${src}")
IF(HAS_C11_ATOMICS)
ADD_DEFINITIONS(-DUSE_C11_ATOMICS=1)
MESSAGE(STATUS "Atomics: using C11 intrinsics")
ELSEIF(HAS_MSC_ATOMICS)
ADD_DEFINITIONS(-DUSE_MSC_ATOMICS=1)
MESSAGE(STATUS "Atomics: using MSVC intrinsics")
ELSEIF(HAS_GCC_ATOMICS)
ADD_DEFINITIONS(-DUSE_GCC_ATOMICS=1)
MESSAGE(STATUS "Atomics: using GCC intrinsics")
ELSE()
SET(CMAKE_THREAD_PREFER_PTHREAD TRUE)
FIND_PACKAGE(Threads)
IF(THREADS_FOUND)
ADD_DEFINITIONS(-DUSE_PTHREAD_ATOMICS=1)
TARGET_LINK_LIBRARIES(TH ${CMAKE_THREAD_LIBS_INIT})
MESSAGE(STATUS "Atomics: using pthread")
ENDIF()
ENDIF()
FIND_PACKAGE(BLAS)
IF(BLAS_FOUND)
SET(USE_BLAS 1)
TARGET_LINK_LIBRARIES(TH ${BLAS_LIBRARIES})
IF(BLAS_INFO STREQUAL "mkl")
ADD_DEFINITIONS(-DTH_BLAS_MKL)
ELSEIF(BLAS_INFO STREQUAL "open")
ADD_DEFINITIONS(-DTH_BLAS_OPEN)
ENDIF()
ENDIF(BLAS_FOUND)
FIND_PACKAGE(LAPACK)
IF(LAPACK_FOUND)
SET(USE_LAPACK 1)
TARGET_LINK_LIBRARIES(TH ${LAPACK_LIBRARIES})
ENDIF(LAPACK_FOUND)
IF (UNIX AND NOT APPLE)
INCLUDE(CheckLibraryExists)
# https://github.com/libgit2/libgit2/issues/2128#issuecomment-35649830
CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT)
IF(NEED_LIBRT)
TARGET_LINK_LIBRARIES(TH rt)
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
ENDIF(NEED_LIBRT)
ENDIF(UNIX AND NOT APPLE)
IF(UNIX)
SET(CMAKE_EXTRA_INCLUDE_FILES "sys/mman.h")
CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
IF(HAVE_MMAP)
ADD_DEFINITIONS(-DHAVE_MMAP=1)
ENDIF(HAVE_MMAP)
# done for lseek: https://www.gnu.org/software/libc/manual/html_node/File-Position-Primitive.html
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
CHECK_FUNCTION_EXISTS(shm_open HAVE_SHM_OPEN)
IF(HAVE_SHM_OPEN)
ADD_DEFINITIONS(-DHAVE_SHM_OPEN=1)
ENDIF(HAVE_SHM_OPEN)
CHECK_FUNCTION_EXISTS(shm_unlink HAVE_SHM_UNLINK)
IF(HAVE_SHM_UNLINK)
ADD_DEFINITIONS(-DHAVE_SHM_UNLINK=1)
ENDIF(HAVE_SHM_UNLINK)
CHECK_FUNCTION_EXISTS(malloc_usable_size HAVE_MALLOC_USABLE_SIZE)
IF(HAVE_MALLOC_USABLE_SIZE)
ADD_DEFINITIONS(-DHAVE_MALLOC_USABLE_SIZE=1)
ENDIF(HAVE_MALLOC_USABLE_SIZE)
ENDIF(UNIX)
IF(NOT MSVC)
TARGET_LINK_LIBRARIES(TH m)
ENDIF(NOT MSVC)
# Is __thread supported?
IF(NOT MSVC)
CHECK_C_SOURCE_COMPILES("static __thread int x = 1; int main() { return x; }" C_HAS_THREAD)
ELSE(NOT MSVC)
CHECK_C_SOURCE_COMPILES("static __declspec( thread ) int x = 1; int main() { return x; }" C_HAS_THREAD)
ENDIF(NOT MSVC)
IF(NOT C_HAS_THREAD)
MESSAGE(STATUS "Warning: __thread is not supported, generating thread-unsafe code")
ELSE(NOT C_HAS_THREAD)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTH_HAVE_THREAD")
ENDIF(NOT C_HAS_THREAD)
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
CONFIGURE_FILE(THGeneral.h.in "${CMAKE_CURRENT_BINARY_DIR}/THGeneral.h")
|