2 # SSE / SSE2 (always available on 64-bit CPUs)
4 # SSE4_1 / SSE4_2 / POPCNT
5 # AVX / AVX2 / AVX_512F
8 # CPU_{opt}_SUPPORTED=ON/OFF - compiler support (possibly with additional flag)
9 # CPU_{opt}_IMPLIES=<list>
10 # CPU_{opt}_FORCE=<list> - subset of "implies" list
11 # CPU_{opt}_GROUP=<list> - similar to "implies" list, but additionally merges compiler flags
12 # CPU_{opt}_FLAGS_ON=""
13 # CPU_{opt}_FEATURE_ALIAS - mapping to CV_CPU_* HWFeature enum
16 # CPU_BASELINE=<list> - preferred list of baseline optimizations
17 # CPU_DISPATCH=<list> - preferred list of dispatched optimizations
19 # Advanced input variables:
20 # CPU_BASELINE_REQUIRE=<list> - list of required baseline optimizations
21 # CPU_DISPATCH_REQUIRE=<list> - list of required dispatched optimizations
22 # CPU_BASELINE_DISABLE=<list> - list of disabled baseline optimizations
25 # CPU_BASELINE_FINAL=<list> - final list of enabled compiler optimizations
26 # CPU_DISPATCH_FINAL=<list> - final list of dispatched optimizations
28 # CPU_DISPATCH_FLAGS_${opt} - flags for source files compiled separately (<name>.avx2.cpp)
30 set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F;AVX512_SKX")
31 list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16)
32 list(APPEND CPU_ALL_OPTIMIZATIONS VSX)
33 list(REMOVE_DUPLICATES CPU_ALL_OPTIMIZATIONS)
35 ocv_update(CPU_VFPV3_FEATURE_ALIAS "")
38 set(HELP_CPU_BASELINE "Specify list of enabled baseline CPU optimizations")
39 set(HELP_CPU_BASELINE_REQUIRE "Specify list of required baseline CPU optimizations")
40 set(HELP_CPU_BASELINE_DISABLE "Specify list of forbidden baseline CPU optimizations")
41 set(HELP_CPU_DISPATCH "Specify list of dispatched CPU optimizations")
42 set(HELP_CPU_DISPATCH_REQUIRE "Specify list of required dispatched CPU optimizations")
44 foreach(var CPU_BASELINE CPU_BASELINE_REQUIRE CPU_BASELINE_DISABLE CPU_DISPATCH CPU_DISPATCH_REQUIRE)
46 string(REPLACE "," ";" _list "${${var}}")
47 set(${var} "${_list}" CACHE STRING "${HELP_${var}}" FORCE)
51 # process legacy flags
52 macro(ocv_optimization_process_obsolete_option legacy_flag OPT legacy_warn)
53 if(DEFINED ${legacy_flag})
55 message(STATUS "WARNING: Option ${legacy_flag}='${${legacy_flag}}' is deprecated and should not be used anymore")
56 message(STATUS " Behaviour of this option is not backward compatible")
57 message(STATUS " Refer to 'CPU_BASELINE'/'CPU_DISPATCH' CMake options documentation")
60 if(NOT ";${CPU_BASELINE_REQUIRE};" MATCHES ";${OPT};")
61 set(CPU_BASELINE_REQUIRE "${CPU_BASELINE_REQUIRE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_REQUIRE}" FORCE)
64 if(NOT ";${CPU_BASELINE_DISABLE};" MATCHES ";${OPT};")
65 set(CPU_BASELINE_DISABLE "${CPU_BASELINE_DISABLE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_DISABLE}" FORCE)
70 ocv_optimization_process_obsolete_option(ENABLE_SSE SSE ON)
71 ocv_optimization_process_obsolete_option(ENABLE_SSE2 SSE2 ON)
72 ocv_optimization_process_obsolete_option(ENABLE_SSE3 SSE3 ON)
73 ocv_optimization_process_obsolete_option(ENABLE_SSSE3 SSSE3 ON)
74 ocv_optimization_process_obsolete_option(ENABLE_SSE41 SSE4_1 ON)
75 ocv_optimization_process_obsolete_option(ENABLE_SSE42 SSE4_2 ON)
76 ocv_optimization_process_obsolete_option(ENABLE_POPCNT POPCNT ON)
77 ocv_optimization_process_obsolete_option(ENABLE_AVX AVX ON)
78 ocv_optimization_process_obsolete_option(ENABLE_AVX2 AVX2 ON)
79 ocv_optimization_process_obsolete_option(ENABLE_FMA3 FMA3 ON)
81 ocv_optimization_process_obsolete_option(ENABLE_VFPV3 VFPV3 OFF)
82 ocv_optimization_process_obsolete_option(ENABLE_NEON NEON OFF)
84 ocv_optimization_process_obsolete_option(ENABLE_VSX VSX OFF)
86 macro(ocv_is_optimization_in_list resultvar check_opt)
90 while(__queue AND NOT ${resultvar})
91 list(REMOVE_DUPLICATES __queue)
92 set(__queue_current ${__queue})
94 foreach(OPT ${__queue_current})
95 if("x${OPT}" STREQUAL "x${check_opt}")
98 elseif(NOT ";${__checked};" MATCHES ";${OPT};")
99 list(APPEND __queue ${CPU_${OPT}_IMPLIES})
101 list(APPEND __checked ${OPT})
106 macro(ocv_is_optimization_in_force_list resultvar check_opt)
110 while(__queue AND NOT ${resultvar})
111 list(REMOVE_DUPLICATES __queue)
112 set(__queue_current ${__queue})
114 foreach(OPT ${__queue_current})
115 if(OPT STREQUAL "${check_opt}")
118 elseif(NOT ";${__checked};" MATCHES ";${OPT};")
119 list(APPEND __queue ${CPU_${OPT}_FORCE})
121 list(APPEND __checked ${OPT})
126 macro(ocv_append_optimization_flag var OPT)
127 if(CPU_${OPT}_FLAGS_CONFLICT)
128 string(REGEX REPLACE " ${CPU_${OPT}_FLAGS_CONFLICT}" "" ${var} " ${${var}} ")
129 string(REGEX REPLACE "^ +" "" ${var} "${${var}}")
131 set(${var} "${${var}} ${CPU_${OPT}_FLAGS_ON}")
134 # Support GCC -march=native or Intel Compiler -xHost flags
135 if(";${CPU_BASELINE};" MATCHES ";NATIVE;" OR ";${CPU_BASELINE};" MATCHES ";HOST;")
136 set(CPU_BASELINE_DETECT ON)
137 set(_add_native_flag ON)
138 elseif(";${CPU_BASELINE};" MATCHES ";DETECT;")
139 set(CPU_BASELINE_DETECT ON)
140 elseif(" ${CMAKE_CXX_FLAGS} " MATCHES " -march=native | -xHost | /QxHost ")
141 if(DEFINED CPU_BASELINE)
142 message(STATUS "CPU: Detected '-march=native' or '-xHost' compiler flag. Force CPU_BASELINE=DETECT.")
144 set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
145 set(CPU_BASELINE_DETECT ON)
149 ocv_update(CPU_KNOWN_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;POPCNT;SSE4_2;FP16;FMA3;AVX;AVX2;AVX_512F;AVX512_SKX")
151 ocv_update(CPU_AVX512_SKX_GROUP "AVX_512F;AVX_512CD;AVX_512BW;AVX_512DQ;AVX_512VL")
153 ocv_update(CPU_SSE_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse.cpp")
154 ocv_update(CPU_SSE2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse2.cpp")
155 ocv_update(CPU_SSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse3.cpp")
156 ocv_update(CPU_SSSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_ssse3.cpp")
157 ocv_update(CPU_SSE4_1_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse41.cpp")
158 ocv_update(CPU_SSE4_2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse42.cpp")
159 ocv_update(CPU_POPCNT_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_popcnt.cpp")
160 ocv_update(CPU_AVX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx.cpp")
161 ocv_update(CPU_AVX2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx2.cpp")
162 ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
163 ocv_update(CPU_AVX_512F_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512.cpp")
164 ocv_update(CPU_AVX512_SKX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512skx.cpp")
166 if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
167 ocv_update(CPU_AVX_512F_IMPLIES "AVX2")
168 ocv_update(CPU_AVX_512F_FORCE "") # Don't force other optimizations
169 ocv_update(CPU_AVX2_IMPLIES "AVX;FMA3;FP16")
170 ocv_update(CPU_FMA3_IMPLIES "AVX2")
171 ocv_update(CPU_FMA3_FORCE "") # Don't force other optimizations
172 ocv_update(CPU_FP16_IMPLIES "AVX")
173 ocv_update(CPU_FP16_FORCE "") # Don't force other optimizations
174 ocv_update(CPU_AVX_IMPLIES "SSE4_2")
175 ocv_update(CPU_SSE4_2_IMPLIES "SSE4_1;POPCNT")
176 ocv_update(CPU_POPCNT_IMPLIES "SSE4_1")
177 ocv_update(CPU_POPCNT_FORCE "") # Don't force other optimizations
178 ocv_update(CPU_SSE4_1_IMPLIES "SSE3;SSSE3")
179 ocv_update(CPU_SSSE3_IMPLIES "SSE3")
180 ocv_update(CPU_SSE3_IMPLIES "SSE2")
181 ocv_update(CPU_SSE2_IMPLIES "SSE")
185 macro(ocv_intel_compiler_optimization_option name unix_flags msvc_flags)
186 ocv_update(CPU_${name}_FLAGS_NAME "${name}")
188 set(enable_flags "${msvc_flags}")
189 set(flags_conflict "/arch:[^ ]+")
191 set(enable_flags "${unix_flags}")
192 set(flags_conflict "-msse[^ ]*|-mssse3|-mavx[^ ]*|-march[^ ]+")
194 ocv_update(CPU_${name}_FLAGS_ON "${enable_flags}")
196 ocv_update(CPU_${name}_FLAGS_CONFLICT "${flags_conflict}")
199 ocv_intel_compiler_optimization_option(AVX2 "-march=core-avx2" "/arch:CORE-AVX2")
200 ocv_intel_compiler_optimization_option(FP16 "-mavx" "/arch:AVX")
201 ocv_intel_compiler_optimization_option(AVX "-mavx" "/arch:AVX")
202 ocv_intel_compiler_optimization_option(FMA3 "" "")
203 ocv_intel_compiler_optimization_option(POPCNT "" "")
204 ocv_intel_compiler_optimization_option(SSE4_2 "-msse4.2" "/arch:SSE4.2")
205 ocv_intel_compiler_optimization_option(SSE4_1 "-msse4.1" "/arch:SSE4.1")
206 ocv_intel_compiler_optimization_option(SSE3 "-msse3" "/arch:SSE3")
207 ocv_intel_compiler_optimization_option(SSSE3 "-mssse3" "/arch:SSSE3")
208 ocv_intel_compiler_optimization_option(SSE2 "-msse2" "/arch:SSE2")
209 if(NOT X86_64) # x64 compiler doesn't support /arch:sse
210 ocv_intel_compiler_optimization_option(SSE "-msse" "/arch:SSE")
212 ocv_intel_compiler_optimization_option(AVX_512F "-march=common-avx512" "/arch:COMMON-AVX512")
213 ocv_intel_compiler_optimization_option(AVX512_SKX "-march=core-avx512" "/arch:CORE-AVX512")
214 elseif(CV_GCC OR CV_CLANG)
215 ocv_update(CPU_AVX2_FLAGS_ON "-mavx2")
216 ocv_update(CPU_FP16_FLAGS_ON "-mf16c")
217 ocv_update(CPU_AVX_FLAGS_ON "-mavx")
218 ocv_update(CPU_FMA3_FLAGS_ON "-mfma")
219 ocv_update(CPU_POPCNT_FLAGS_ON "-mpopcnt")
220 ocv_update(CPU_SSE4_2_FLAGS_ON "-msse4.2")
221 ocv_update(CPU_SSE4_1_FLAGS_ON "-msse4.1")
222 ocv_update(CPU_SSE3_FLAGS_ON "-msse3")
223 ocv_update(CPU_SSSE3_FLAGS_ON "-mssse3")
224 ocv_update(CPU_SSE2_FLAGS_ON "-msse2")
225 ocv_update(CPU_SSE_FLAGS_ON "-msse")
226 if(NOT (CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")) # GCC >= 5.0
227 # -mavx512f -mavx512pf -mavx512er -mavx512cd -mavx512vl -mavx512bw -mavx512dq -mavx512ifma -mavx512vbmi
228 ocv_update(CPU_AVX_512F_FLAGS_ON "-mavx512f")
229 ocv_update(CPU_AVX512_SKX_FLAGS_ON "-mavx512f -mavx512cd -mavx512vl -mavx512bw -mavx512dq")
231 ocv_update(CPU_AVX_512F_SUPPORTED OFF)
232 ocv_update(CPU_AVX512_SKX_SUPPORTED OFF)
235 ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2")
236 ocv_update(CPU_AVX_FLAGS_ON "/arch:AVX")
237 ocv_update(CPU_FP16_FLAGS_ON "/arch:AVX")
239 # 64-bit MSVC compiler uses SSE/SSE2 by default
240 ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE")
241 ocv_update(CPU_SSE_SUPPORTED ON)
242 ocv_update(CPU_SSE2_FLAGS_ON "/arch:SSE2")
243 ocv_update(CPU_SSE2_SUPPORTED ON)
245 ocv_update(CPU_SSE_SUPPORTED ON)
246 ocv_update(CPU_SSE2_SUPPORTED ON)
248 # Other instruction sets are supported by default since MSVC 2008 at least
250 message(WARNING "TODO: Unsupported compiler")
253 if(NOT DEFINED CPU_DISPATCH)
255 set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16;AVX2;AVX512_SKX" CACHE STRING "${HELP_CPU_DISPATCH}")
257 set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16" CACHE STRING "${HELP_CPU_DISPATCH}")
261 if(NOT DEFINED CPU_BASELINE)
263 # MacOS X has limited set of possible supported H/W, so compiler is configured well
264 set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
266 set(CPU_BASELINE "SSE3" CACHE STRING "${HELP_CPU_BASELINE}")
268 set(CPU_BASELINE "SSE2" CACHE STRING "${HELP_CPU_BASELINE}")
272 elseif(ARM OR AARCH64)
273 ocv_update(CPU_NEON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_neon.cpp")
274 ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
276 ocv_update(CPU_KNOWN_OPTIMIZATIONS "VFPV3;NEON;FP16")
278 ocv_update(CPU_VFPV3_FLAGS_ON "-mfpu=vfpv3")
279 ocv_update(CPU_NEON_FLAGS_ON "-mfpu=neon")
280 ocv_update(CPU_NEON_FLAGS_CONFLICT "-mfpu=[^ ]*")
281 ocv_update(CPU_FP16_FLAGS_ON "-mfpu=neon-fp16")
282 ocv_update(CPU_FP16_FLAGS_CONFLICT "-mfpu=[^ ]*")
284 ocv_update(CPU_FP16_IMPLIES "NEON")
286 ocv_update(CPU_KNOWN_OPTIMIZATIONS "NEON;FP16")
287 ocv_update(CPU_NEON_FLAGS_ON "")
288 ocv_update(CPU_FP16_IMPLIES "NEON")
289 set(CPU_BASELINE "NEON;FP16" CACHE STRING "${HELP_CPU_BASELINE}")
292 ocv_update(CPU_KNOWN_OPTIMIZATIONS "VSX")
293 ocv_update(CPU_VSX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx.cpp")
295 if(CV_CLANG AND (NOT ${CMAKE_CXX_COMPILER} MATCHES "xlc"))
296 ocv_update(CPU_VSX_FLAGS_ON "-mvsx -maltivec")
298 ocv_update(CPU_VSX_FLAGS_ON "-mcpu=power8")
302 # Helper values for cmake-gui
303 set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
304 set(CPU_DISPATCH "" CACHE STRING "${HELP_CPU_DISPATCH}")
305 set_property(CACHE CPU_BASELINE PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
306 set_property(CACHE CPU_DISPATCH PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
308 # Update CPU_BASELINE_DETECT flag
309 if(";${CPU_BASELINE};" MATCHES ";DETECT;")
310 set(CPU_BASELINE_DETECT ON)
313 set(CPU_BASELINE_FLAGS "")
315 set(CPU_BASELINE_FINAL "")
316 set(CPU_DISPATCH_FINAL "")
318 if(CV_DISABLE_OPTIMIZATION)
320 set(CPU_DISPATCH_REQUIRE "")
323 macro(ocv_check_compiler_optimization OPT)
324 if(NOT DEFINED CPU_${OPT}_SUPPORTED)
325 if((DEFINED CPU_${OPT}_FLAGS_ON AND NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x") OR CPU_${OPT}_TEST_FILE)
327 if(CPU_${OPT}_TEST_FILE)
329 if(CPU_BASELINE_DETECT)
330 set(_varname "HAVE_CPU_${OPT}_SUPPORT")
331 ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
333 list(APPEND CPU_BASELINE_FINAL ${OPT})
338 if(NOT "x${CPU_${OPT}_FLAGS_NAME}" STREQUAL "x")
339 set(_varname "HAVE_CPU_${CPU_${OPT}_FLAGS_NAME}")
340 set(_compile_flags "${CPU_BASELINE_FLAGS}")
341 ocv_append_optimization_flag(_compile_flags ${OPT})
342 ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
343 elseif(NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x")
344 ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "" "${CPU_${OPT}_TEST_FILE}")
346 set(_varname "HAVE_CPU_${OPT}_SUPPORT")
347 set(_compile_flags "${CPU_BASELINE_FLAGS}")
348 ocv_append_optimization_flag(_compile_flags ${OPT})
349 ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
353 ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "")
355 if(_varname AND ${_varname})
356 set(CPU_${OPT}_SUPPORTED ON)
357 elseif(NOT CPU_${OPT}_SUPPORTED)
358 message(STATUS "${OPT} is not supported by C++ compiler")
361 set(CPU_${OPT}_SUPPORTED ON)
366 foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
367 set(CPU_${OPT}_USAGE_COUNT 0 CACHE INTERNAL "")
368 if("${CPU_${OPT}_FLAGS_ON}" STREQUAL "disabled")
369 set(CPU_${OPT}_SUPPORTED OFF)
370 elseif(DEFINED CPU_${OPT}_GROUP)
371 if(NOT DEFINED CPU_${OPT}_IMPLIES)
372 set(CPU_${OPT}_IMPLIES "${CPU_${OPT}_GROUP}")
376 foreach(OPT2 ${CPU_${OPT}_GROUP})
377 if("${CPU_${OPT2}_FLAGS_ON}" STREQUAL "disabled" OR (DEFINED CPU_${OPT2}_SUPPORTED AND NOT CPU_${OPT}_SUPPORTED))
380 set(__flags "${__flags} ${CPU_${OPT2}_FLAGS_ON}")
381 string(STRIP "${__flags}" __flags)
384 set(CPU_${OPT}_SUPPORTED OFF)
386 if(NOT DEFINED CPU_${OPT}_FLAGS_ON)
387 set(CPU_${OPT}_FLAGS_ON "${__flags}")
391 if(NOT DEFINED CPU_${OPT}_FORCE)
392 set(CPU_${OPT}_FORCE "${CPU_${OPT}_IMPLIES}")
397 set(_varname "HAVE_CPU_NATIVE_SUPPORT")
398 ocv_check_compiler_flag(CXX "-march=native" "${_varname}" "")
400 set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} -march=native")
402 set(_varname "HAVE_CPU_HOST_SUPPORT")
408 ocv_check_compiler_flag(CXX "${_flag}" "${_varname}" "")
410 set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} ${_flag}")
415 foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
417 foreach(OPT2 ${CPU_BASELINE_DISABLE})
418 ocv_is_optimization_in_list(__is_disabled ${OPT2} ${OPT})
424 set(__is_from_baseline 0)
426 if(CPU_${OPT}_SUPPORTED AND CPU_BASELINE_DETECT)
427 list(APPEND CPU_BASELINE_FINAL ${OPT})
429 ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_REQUIRE})
430 if(NOT __is_from_baseline)
431 ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE})
434 ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH_REQUIRE})
435 if(NOT __is_from_dispatch)
436 ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH})
438 if(__is_from_dispatch OR __is_from_baseline OR CPU_BASELINE_DETECT)
439 ocv_check_compiler_optimization(${OPT})
441 if(CPU_BASELINE_DETECT AND NOT __is_from_baseline AND NOT __is_disabled)
442 ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_FINAL})
444 if(CPU_${OPT}_SUPPORTED)
445 if(";${CPU_DISPATCH};" MATCHES ";${OPT};" AND NOT __is_from_baseline)
446 list(APPEND CPU_DISPATCH_FINAL ${OPT})
447 elseif(__is_from_baseline)
448 if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
449 list(APPEND CPU_BASELINE_FINAL ${OPT})
451 ocv_append_optimization_flag(CPU_BASELINE_FLAGS ${OPT})
456 foreach(OPT ${CPU_BASELINE_REQUIRE})
457 if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
458 message(SEND_ERROR "Required baseline optimization is not supported: ${OPT} (CPU_BASELINE_REQUIRE=${CPU_BASELINE_REQUIRE})")
462 foreach(OPT ${CPU_BASELINE})
463 if(OPT STREQUAL "DETECT" OR OPT STREQUAL "HOST" OR OPT STREQUAL "NATIVE")
465 elseif(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
466 message(STATUS "Optimization ${OPT} is not available, skipped")
470 foreach(OPT ${CPU_DISPATCH_REQUIRE})
471 if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
473 elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
474 message(SEND_ERROR "Dispatched optimization ${OPT} is in baseline list (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
476 message(SEND_ERROR "Required dispatch optimization is not supported: ${OPT} (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
480 foreach(OPT ${CPU_DISPATCH})
481 if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
483 elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
486 message(STATUS "Dispatch optimization ${OPT} is not available, skipped")
490 #message(STATUS "CPU_BASELINE_FINAL=${CPU_BASELINE_FINAL}")
491 #message(STATUS "CPU_DISPATCH_FINAL=${CPU_DISPATCH_FINAL}")
493 #if(CPU_DISPATCH_FINAL AND NOT PYTHON_DEFAULT_EXECUTABLE)
494 # message(FATAL_ERROR "Python is required for CPU dispatched optimization support")
497 macro(ocv_compiler_optimization_options)
498 set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${CPU_BASELINE_FLAGS}")
499 if(NOT __flags STREQUAL CACHED_CPU_BASELINE_FLAGS)
500 set(CACHED_CPU_BASELINE_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
501 ocv_clear_vars(HAVE_CPU_BASELINE_FLAGS)
503 ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_BASELINE_FLAGS)
504 if(NOT HAVE_CPU_BASELINE_FLAGS)
505 message(FATAL_ERROR "Compiler doesn't support baseline optimization flags: ${CPU_BASELINE_FLAGS}")
507 add_extra_compiler_option_force("${CPU_BASELINE_FLAGS}")
509 foreach(OPT ${CPU_DISPATCH_FINAL})
510 set(__dispatch_flags "")
511 set(__dispatch_definitions "")
512 set(__dispatch_opts "")
513 set(__dispatch_opts_force "")
514 foreach(OPT2 ${CPU_KNOWN_OPTIMIZATIONS})
515 if(NOT CPU_${OPT2}_SUPPORTED)
518 ocv_is_optimization_in_list(__is_from_baseline ${OPT2} ${CPU_BASELINE_FINAL})
519 if(NOT __is_from_baseline)
520 ocv_is_optimization_in_list(__is_active ${OPT2} ${OPT})
522 ocv_append_optimization_flag(__dispatch_flags ${OPT2})
523 list(APPEND __dispatch_definitions "CV_CPU_COMPILE_${OPT2}=1")
524 list(APPEND __dispatch_opts "${OPT2}")
526 ocv_is_optimization_in_force_list(__is_force ${OPT2} ${OPT})
528 list(APPEND __dispatch_opts_force "${OPT2}")
533 set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${__dispatch_flags}")
534 if(NOT __flags STREQUAL CACHED_CPU_DISPATCH_${OPT}_FLAGS)
535 set(CACHED_CPU_DISPATCH_${OPT}_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
536 ocv_clear_vars(HAVE_CPU_DISPATCH_FLAGS_${OPT})
538 ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_DISPATCH_FLAGS_${OPT})
539 if(NOT HAVE_CPU_DISPATCH_FLAGS_${OPT})
540 message(FATAL_ERROR "Compiler doesn't support optimization flags for ${OPT} dispatch mode: ${__dispatch_flags}")
542 set(CPU_DISPATCH_FLAGS_${OPT} "${__dispatch_flags}")
543 set(CPU_DISPATCH_DEFINITIONS_${OPT} "${__dispatch_definitions}")
544 set(CPU_DISPATCH_${OPT}_INCLUDED "${__dispatch_opts}")
545 set(CPU_DISPATCH_${OPT}_FORCED "${__dispatch_opts_force}")
549 add_extra_compiler_option("-mcpu=G3 -mtune=G5")
552 add_extra_compiler_option("-mfp16-format=ieee")
556 macro(ocv_compiler_optimization_options_finalize)
557 if((CV_GCC OR CV_CLANG) AND (X86 OR X86_64))
558 if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4)
559 if(OPENCV_EXTRA_CXX_FLAGS MATCHES "-m(sse2|avx)")
560 add_extra_compiler_option(-mfpmath=sse) # !! important - be on the same wave with x64 compilers
562 add_extra_compiler_option(-mfpmath=387)
568 # Generate Intrinsic Functions
569 set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Oi")
571 if((X86 OR X86_64) AND CMAKE_SIZEOF_VOID_P EQUAL 4 AND ";${CPU_BASELINE_FINAL};" MATCHES ";SSE;")
572 set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /fp:fast") # !! important - be on the same wave with x64 compilers
577 macro(ocv_compiler_optimization_process_sources SOURCES_VAR_NAME LIBS_VAR_NAME TARGET_BASE_NAME)
579 set(__result_libs "")
580 foreach(OPT ${CPU_DISPATCH_FINAL})
581 set(__result_${OPT} "")
583 foreach(fname ${${SOURCES_VAR_NAME}})
584 string(TOLOWER "${fname}" fname_LOWER)
585 get_filename_component(fname_LOWER "${fname_LOWER}" NAME)
586 if(fname_LOWER MATCHES ".+\\.([^\\.]*)\\.cpp$")
587 string(TOUPPER "${CMAKE_MATCH_1}" OPT_)
588 if(OPT_ MATCHES "(CUDA.*|DISPATCH.*|OCL)") # don't touch files like filename.cuda.cpp
589 list(APPEND __result "${fname}")
591 elseif(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
592 ocv_get_smart_file_name(fname_ "${fname}")
593 message(STATUS "Excluding from source files list (optimization is disabled): ${fname_}")
596 get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
598 list(APPEND __definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
600 set(__definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
602 set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
605 foreach(OPT ${CPU_BASELINE_FINAL})
606 string(TOLOWER "${OPT}" OPT_LOWER)
607 if(fname_LOWER MATCHES "\\.${OPT_LOWER}\\.cpp$")
608 #message("${fname} BASELINE-${OPT}")
610 list(APPEND __result "${fname}")
614 foreach(OPT ${CPU_DISPATCH_FINAL})
615 foreach(OPT2 ${CPU_DISPATCH_${OPT}_FORCED})
616 string(TOLOWER "${OPT2}" OPT2_LOWER)
617 if(fname_LOWER MATCHES "\\.${OPT2_LOWER}\\.cpp$")
618 list(APPEND __result_${OPT} "${fname}")
619 math(EXPR CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}+1")
620 set(CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}" CACHE INTERNAL "" FORCE)
621 #message("(${CPU_${OPT}_USAGE_COUNT})${fname} ${OPT}")
622 #message(" ${CPU_DISPATCH_${OPT}_INCLUDED}")
623 #message(" ${CPU_DISPATCH_DEFINITIONS_${OPT}}")
624 #message(" ${CPU_DISPATCH_FLAGS_${OPT}}")
635 ocv_get_smart_file_name(fname_ "${fname}")
636 message(STATUS "Excluding from source files list: ${fname_}")
640 list(APPEND __result "${fname}")
644 foreach(OPT ${CPU_DISPATCH_FINAL})
646 #message("${OPT}: ${__result_${OPT}}")
647 if(CMAKE_GENERATOR MATCHES "^Visual")
648 # extra flags are added before common flags, so switching between optimizations doesn't work correctly
649 # Also CMAKE_CXX_FLAGS doesn't work (it is directory-based, so add_subdirectory is required)
650 add_library(${TARGET_BASE_NAME}_${OPT} OBJECT ${__result_${OPT}})
651 ocv_append_dependant_targets(${TARGET_BASE_NAME} ${TARGET_BASE_NAME}_${OPT})
652 set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_DEFINITIONS "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
653 set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
654 target_include_directories(${TARGET_BASE_NAME}_${OPT} PRIVATE $<TARGET_PROPERTY:${TARGET_BASE_NAME},INCLUDE_DIRECTORIES>)
655 #list(APPEND __result_libs ${TARGET_BASE_NAME}_${OPT})
656 list(APPEND __result "$<TARGET_OBJECTS:${TARGET_BASE_NAME}_${OPT}>")
657 if(ENABLE_SOLUTION_FOLDERS)
658 set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES FOLDER "dispatched")
661 foreach(fname ${__result_${OPT}})
662 get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
664 list(APPEND __definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
666 set(__definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
668 set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
669 set_source_files_properties("${fname}" PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
671 list(APPEND __result ${__result_${OPT}})
675 set(${SOURCES_VAR_NAME} "${__result}")
676 list(APPEND ${LIBS_VAR_NAME} ${__result_libs})
679 macro(ocv_compiler_optimization_fill_cpu_config)
680 set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "")
681 foreach(OPT ${CPU_BASELINE_FINAL})
682 set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
683 #define CV_CPU_COMPILE_${OPT} 1
684 #define CV_CPU_BASELINE_COMPILE_${OPT} 1
688 set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
689 #define CV_CPU_BASELINE_FEATURES 0 \\")
690 foreach(OPT ${CPU_BASELINE_FINAL})
691 if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
692 set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
696 set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}\n")
698 set(__dispatch_modes "")
699 foreach(OPT ${CPU_DISPATCH_FINAL})
700 list(APPEND __dispatch_modes ${CPU_DISPATCH_${OPT}_FORCE} ${OPT})
702 list(REMOVE_DUPLICATES __dispatch_modes)
703 set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "")
704 foreach(OPT ${__dispatch_modes})
705 set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
706 #define CV_CPU_DISPATCH_COMPILE_${OPT} 1")
709 set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "// AUTOGENERATED, DO NOT EDIT\n")
710 foreach(OPT ${CPU_ALL_OPTIMIZATIONS})
711 if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
712 set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
713 #if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_${OPT}
714 # define CV_TRY_${OPT} 1
715 # define CV_CPU_FORCE_${OPT} 1
716 # define CV_CPU_HAS_SUPPORT_${OPT} 1
717 # define CV_CPU_CALL_${OPT}(fn, args) return (cpu_baseline::fn args)
718 # define CV_CPU_CALL_${OPT}_(fn, args) return (opt_${OPT}::fn args)
719 #elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_${OPT}
720 # define CV_TRY_${OPT} 1
721 # define CV_CPU_FORCE_${OPT} 0
722 # define CV_CPU_HAS_SUPPORT_${OPT} (cv::checkHardwareSupport(CV_CPU_${OPT}))
723 # define CV_CPU_CALL_${OPT}(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
724 # define CV_CPU_CALL_${OPT}_(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
726 # define CV_TRY_${OPT} 0
727 # define CV_CPU_FORCE_${OPT} 0
728 # define CV_CPU_HAS_SUPPORT_${OPT} 0
729 # define CV_CPU_CALL_${OPT}(fn, args)
730 # define CV_CPU_CALL_${OPT}_(fn, args)
732 #define __CV_CPU_DISPATCH_CHAIN_${OPT}(fn, args, mode, ...) CV_CPU_CALL_${OPT}(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
737 set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
738 #define CV_CPU_CALL_BASELINE(fn, args) return (cpu_baseline::fn args)
739 #define __CV_CPU_DISPATCH_CHAIN_BASELINE(fn, args, mode, ...) CV_CPU_CALL_BASELINE(fn, args) /* last in sequence */
743 set(__file "${OpenCV_SOURCE_DIR}/modules/core/include/opencv2/core/cv_cpu_helper.h")
744 if(EXISTS "${__file}")
745 file(READ "${__file}" __content)
747 if(__content STREQUAL OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE)
748 #message(STATUS "${__file} contains same content")
750 file(WRITE "${__file}" "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}")
751 message(WARNING "${__file} is updated")
755 macro(ocv_add_dispatched_file filename)
756 if(NOT OPENCV_INITIAL_PASS)
758 #include \"${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp\"
759 #include \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"
762 set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"")
763 set(__dispatch_modes "BASELINE")
765 set(__optimizations "${ARGN}")
766 if(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
767 set(__optimizations "")
770 foreach(OPT ${__optimizations})
771 string(TOLOWER "${OPT}" OPT_LOWER)
772 set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.${OPT_LOWER}.cpp")
773 if(EXISTS "${__file}")
774 file(READ "${__file}" __content)
778 if(__content STREQUAL __codestr)
779 #message(STATUS "${__file} contains up-to-date content")
781 file(WRITE "${__file}" "${__codestr}")
784 if(";${CPU_DISPATCH};" MATCHES "${OPT}" OR __CPU_DISPATCH_INCLUDE_ALL)
785 list(APPEND OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED "${__file}")
788 set(__declarations_str "${__declarations_str}
789 #define CV_CPU_DISPATCH_MODE ${OPT}
790 #include \"opencv2/core/private/cv_cpu_include_simd_declarations.hpp\"
792 set(__dispatch_modes "${OPT}, ${__dispatch_modes}")
795 set(__declarations_str "${__declarations_str}
796 #define CV_CPU_DISPATCH_MODES_ALL ${__dispatch_modes}
799 set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.simd_declarations.hpp")
800 if(EXISTS "${__file}")
801 file(READ "${__file}" __content)
803 if(__content STREQUAL __declarations_str)
804 #message(STATUS "${__file} contains up-to-date content")
806 file(WRITE "${__file}" "${__declarations_str}")
811 # Workaround to support code which always require all code paths
812 macro(ocv_add_dispatched_file_force_all)
813 set(__CPU_DISPATCH_INCLUDE_ALL 1)
814 ocv_add_dispatched_file(${ARGN})
815 unset(__CPU_DISPATCH_INCLUDE_ALL)
819 if(CV_DISABLE_OPTIMIZATION OR CV_ICC)
820 ocv_update(CV_ENABLE_UNROLLED 0)
822 ocv_update(CV_ENABLE_UNROLLED 1)