Skip to content

Commit 7d67d60

Browse files
committed
cmake(opt): AVX512_SKX
1 parent fc1d85b commit 7d67d60

File tree

10 files changed

+88
-18
lines changed

10 files changed

+88
-18
lines changed

cmake/OpenCVCompilerOptimizations.cmake

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
# CPU_{opt}_SUPPORTED=ON/OFF - compiler support (possibly with additional flag)
99
# CPU_{opt}_IMPLIES=<list>
1010
# CPU_{opt}_FORCE=<list> - subset of "implies" list
11+
# CPU_{opt}_GROUP=<list> - similar to "implies" list, but additionally merges compiler flags
1112
# CPU_{opt}_FLAGS_ON=""
1213
# CPU_{opt}_FEATURE_ALIAS - mapping to CV_CPU_* HWFeature enum
1314

@@ -26,7 +27,7 @@
2627
#
2728
# CPU_DISPATCH_FLAGS_${opt} - flags for source files compiled separately (<name>.avx2.cpp)
2829

29-
set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F")
30+
set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F;AVX512_SKX")
3031
list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16)
3132
list(APPEND CPU_ALL_OPTIMIZATIONS VSX)
3233
list(REMOVE_DUPLICATES CPU_ALL_OPTIMIZATIONS)
@@ -145,7 +146,9 @@ elseif(" ${CMAKE_CXX_FLAGS} " MATCHES " -march=native | -xHost | /QxHost ")
145146
endif()
146147

147148
if(X86 OR X86_64)
148-
ocv_update(CPU_KNOWN_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;POPCNT;SSE4_2;FP16;FMA3;AVX;AVX2;AVX_512F")
149+
ocv_update(CPU_KNOWN_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;POPCNT;SSE4_2;FP16;FMA3;AVX;AVX2;AVX_512F;AVX512_SKX")
150+
151+
ocv_update(CPU_AVX512_SKX_GROUP "AVX_512F;AVX_512CD;AVX_512BW;AVX_512DQ;AVX_512VL")
149152

150153
ocv_update(CPU_SSE_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse.cpp")
151154
ocv_update(CPU_SSE2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse2.cpp")
@@ -158,6 +161,7 @@ if(X86 OR X86_64)
158161
ocv_update(CPU_AVX2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx2.cpp")
159162
ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
160163
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")
161165

162166
if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
163167
ocv_update(CPU_AVX_512F_IMPLIES "AVX2")
@@ -206,6 +210,7 @@ if(X86 OR X86_64)
206210
ocv_intel_compiler_optimization_option(SSE "-msse" "/arch:SSE")
207211
endif()
208212
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")
209214
elseif(CMAKE_COMPILER_IS_GNUCXX)
210215
ocv_update(CPU_AVX2_FLAGS_ON "-mavx2")
211216
ocv_update(CPU_FP16_FLAGS_ON "-mf16c")
@@ -221,6 +226,7 @@ if(X86 OR X86_64)
221226
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")
222227
# -mavx512f -mavx512pf -mavx512er -mavx512cd -mavx512vl -mavx512bw -mavx512dq -mavx512ifma -mavx512vbmi
223228
ocv_update(CPU_AVX_512F_FLAGS_ON "-mavx512f")
229+
ocv_update(CPU_AVX512_SKX_FLAGS_ON "-mavx512f -mavx512cd -mavx512vl -mavx512bw -mavx512dq")
224230
endif()
225231
elseif(MSVC)
226232
ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2")
@@ -348,6 +354,18 @@ endmacro()
348354

349355
foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
350356
set(CPU_${OPT}_USAGE_COUNT 0 CACHE INTERNAL "")
357+
if(DEFINED CPU_${OPT}_GROUP)
358+
if(NOT DEFINED CPU_${OPT}_IMPLIES)
359+
set(CPU_${OPT}_IMPLIES "${CPU_${OPT}_GROUP}")
360+
endif()
361+
if(NOT DEFINED CPU_${OPT}_FLAGS_ON)
362+
set(__flags "")
363+
foreach(OPT2 ${CPU_${OPT}_GROUP})
364+
set(__flags "${__flags} ${CPU_${OPT2}_FLAGS_ON}")
365+
endforeach()
366+
set(CPU_${OPT}_FLAGS_ON "${__flags}")
367+
endif()
368+
endif()
351369
if(NOT DEFINED CPU_${OPT}_FORCE)
352370
set(CPU_${OPT}_FORCE "${CPU_${OPT}_IMPLIES}")
353371
endif()

cmake/checks/cpu_avx512skx.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#if defined __AVX512__ || defined __AVX512F__
2+
#include <immintrin.h>
3+
void test()
4+
{
5+
__m512i zmm = _mm512_setzero_si512();
6+
__m256i a = _mm256_setzero_si256();
7+
__m256i b = _mm256_abs_epi64(a); // VL
8+
__m512i c = _mm512_abs_epi8(zmm); // BW
9+
__m512i d = _mm512_broadcast_i32x8(b); // DQ
10+
}
11+
#else
12+
#error "AVX512-SKX is not supported"
13+
#endif
14+
int main() { return 0; }

modules/core/include/opencv2/core/cv_cpu_dispatch.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@
8686
# include <immintrin.h>
8787
# define CV_AVX_512F 1
8888
#endif
89+
#ifdef CV_CPU_COMPILE_AVX512_SKX
90+
# include <immintrin.h>
91+
# define CV_AVX512_SKX 1
92+
#endif
8993
#ifdef CV_CPU_COMPILE_FMA3
9094
# define CV_FMA3 1
9195
#endif
@@ -222,6 +226,9 @@ struct VZeroUpperGuard {
222226
#ifndef CV_AVX_512VL
223227
# define CV_AVX_512VL 0
224228
#endif
229+
#ifndef CV_AVX512_SKX
230+
# define CV_AVX512_SKX 0
231+
#endif
225232

226233
#ifndef CV_NEON
227234
# define CV_NEON 0

modules/core/include/opencv2/core/cv_cpu_helper.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,21 @@
180180
#endif
181181
#define __CV_CPU_DISPATCH_CHAIN_AVX_512F(fn, args, mode, ...) CV_CPU_CALL_AVX_512F(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
182182

183+
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_AVX512_SKX
184+
# define CV_TRY_AVX512_SKX 1
185+
# define CV_CPU_HAS_SUPPORT_AVX512_SKX 1
186+
# define CV_CPU_CALL_AVX512_SKX(fn, args) return (opt_AVX512_SKX::fn args)
187+
#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_AVX512_SKX
188+
# define CV_TRY_AVX512_SKX 1
189+
# define CV_CPU_HAS_SUPPORT_AVX512_SKX (cv::checkHardwareSupport(CV_CPU_AVX512_SKX))
190+
# define CV_CPU_CALL_AVX512_SKX(fn, args) if (CV_CPU_HAS_SUPPORT_AVX512_SKX) return (opt_AVX512_SKX::fn args)
191+
#else
192+
# define CV_TRY_AVX512_SKX 0
193+
# define CV_CPU_HAS_SUPPORT_AVX512_SKX 0
194+
# define CV_CPU_CALL_AVX512_SKX(fn, args)
195+
#endif
196+
#define __CV_CPU_DISPATCH_CHAIN_AVX512_SKX(fn, args, mode, ...) CV_CPU_CALL_AVX512_SKX(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
197+
183198
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_NEON
184199
# define CV_TRY_NEON 1
185200
# define CV_CPU_HAS_SUPPORT_NEON 1

modules/core/include/opencv2/core/cvdef.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
146146
#define CV_CPU_AVX_512CD 15
147147
#define CV_CPU_AVX_512DQ 16
148148
#define CV_CPU_AVX_512ER 17
149-
#define CV_CPU_AVX_512IFMA512 18
149+
#define CV_CPU_AVX_512IFMA512 18 // deprecated
150+
#define CV_CPU_AVX_512IFMA 18
150151
#define CV_CPU_AVX_512PF 19
151152
#define CV_CPU_AVX_512VBMI 20
152153
#define CV_CPU_AVX_512VL 21
@@ -155,8 +156,11 @@ namespace cv { namespace debug_build_guard { } using namespace debug_build_guard
155156

156157
#define CV_CPU_VSX 200
157158

159+
// CPU features groups
160+
#define CV_CPU_AVX512_SKX 256
161+
158162
// when adding to this list remember to update the following enum
159-
#define CV_HARDWARE_MAX_FEATURE 255
163+
#define CV_HARDWARE_MAX_FEATURE 512
160164

161165
/** @brief Available CPU features.
162166
*/
@@ -179,14 +183,19 @@ enum CpuFeatures {
179183
CPU_AVX_512CD = 15,
180184
CPU_AVX_512DQ = 16,
181185
CPU_AVX_512ER = 17,
182-
CPU_AVX_512IFMA512 = 18,
186+
CPU_AVX_512IFMA512 = 18, // deprecated
187+
CPU_AVX_512IFMA = 18,
183188
CPU_AVX_512PF = 19,
184189
CPU_AVX_512VBMI = 20,
185190
CPU_AVX_512VL = 21,
186191

187192
CPU_NEON = 100,
188193

189-
CPU_VSX = 200
194+
CPU_VSX = 200,
195+
196+
CPU_AVX512_SKX = 256, //!< Skylake-X with AVX-512F/CD/BW/DQ/VL
197+
198+
CPU_MAX_FEATURE = 512 // see CV_HARDWARE_MAX_FEATURE
190199
};
191200

192201

modules/core/src/system.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,16 @@ struct HWFeatures
301301
g_hwFeatureNames[CPU_AVX_512CD] = "AVX512CD";
302302
g_hwFeatureNames[CPU_AVX_512DQ] = "AVX512DQ";
303303
g_hwFeatureNames[CPU_AVX_512ER] = "AVX512ER";
304-
g_hwFeatureNames[CPU_AVX_512IFMA512] = "AVX512IFMA";
304+
g_hwFeatureNames[CPU_AVX_512IFMA] = "AVX512IFMA";
305305
g_hwFeatureNames[CPU_AVX_512PF] = "AVX512PF";
306306
g_hwFeatureNames[CPU_AVX_512VBMI] = "AVX512VBMI";
307307
g_hwFeatureNames[CPU_AVX_512VL] = "AVX512VL";
308308

309309
g_hwFeatureNames[CPU_NEON] = "NEON";
310310

311311
g_hwFeatureNames[CPU_VSX] = "VSX";
312+
313+
g_hwFeatureNames[CPU_AVX512_SKX] = "AVX512-SKX";
312314
}
313315

314316
void initialize(void)
@@ -456,6 +458,11 @@ struct HWFeatures
456458
have[CV_CPU_AVX_512VBMI] = false;
457459
have[CV_CPU_AVX_512VL] = false;
458460
}
461+
462+
if (have[CV_CPU_AVX_512F])
463+
{
464+
have[CV_CPU_AVX512_SKX] = have[CV_CPU_AVX_512F] & have[CV_CPU_AVX_512CD] & have[CV_CPU_AVX_512BW] & have[CV_CPU_AVX_512DQ] & have[CV_CPU_AVX_512VL];
465+
}
459466
}
460467
#else
461468
CV_UNUSED(cpuid_data);

modules/dnn/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ endif()
1313

1414
set(the_description "Deep neural network module. It allows to load models from different frameworks and to make forward pass")
1515

16-
ocv_add_dispatched_file("layers/layers_common" AVX AVX2 AVX_512F)
16+
ocv_add_dispatched_file("layers/layers_common" AVX AVX2 AVX512_SKX)
1717

1818
ocv_add_module(dnn opencv_core opencv_imgproc WRAP python matlab java js)
1919
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-shadow -Wno-parentheses -Wmaybe-uninitialized -Wsign-promo

modules/dnn/src/layers/convolution_layer.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
384384
p.is1x1_ = kernel == Size(0,0) && pad == Size(0, 0);
385385
p.useAVX = checkHardwareSupport(CPU_AVX);
386386
p.useAVX2 = checkHardwareSupport(CPU_AVX2);
387-
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX_512F;
387+
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX;
388388

389389
int ncn = std::min(inpCn, (int)BLK_SIZE_CN);
390390
p.ofstab_.resize(kernel.width*kernel.height*ncn);
@@ -564,10 +564,10 @@ class ConvolutionLayerImpl : public BaseConvolutionLayerImpl
564564
// now compute dot product of the weights
565565
// and im2row-transformed part of the tensor
566566
int bsz = ofs1 - ofs0;
567-
#if CV_TRY_AVX_512F
567+
#if CV_TRY_AVX512_SKX
568568
/* AVX512 convolution requires an alignment of 16, and ROI is only there for larger vector sizes */
569569
if(useAVX512)
570-
opt_AVX_512F::fastConv(wptr, wstep, biasptr, rowbuf0, data_out0 + ofs0,
570+
opt_AVX512_SKX::fastConv(wptr, wstep, biasptr, rowbuf0, data_out0 + ofs0,
571571
outShape, bsz, vsz, vsz_a, relu, cn0 == 0);
572572
else
573573
#endif
@@ -1102,7 +1102,7 @@ class DeConvolutionLayerImpl : public BaseConvolutionLayerImpl
11021102
nstripes_ = nstripes;
11031103
useAVX = checkHardwareSupport(CPU_AVX);
11041104
useAVX2 = checkHardwareSupport(CPU_AVX2);
1105-
useAVX512 = CV_CPU_HAS_SUPPORT_AVX_512F;
1105+
useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX;
11061106
}
11071107

11081108
void operator()(const Range& range_) const
@@ -1120,9 +1120,9 @@ class DeConvolutionLayerImpl : public BaseConvolutionLayerImpl
11201120
size_t bstep = b_->step1();
11211121
size_t cstep = c_->step1();
11221122

1123-
#if CV_TRY_AVX_512F
1123+
#if CV_TRY_AVX512_SKX
11241124
if( useAVX512 )
1125-
opt_AVX_512F::fastGEMM( aptr, astep, bptr, bstep, cptr, cstep, mmax, kmax, nmax );
1125+
opt_AVX512_SKX::fastGEMM( aptr, astep, bptr, bstep, cptr, cstep, mmax, kmax, nmax );
11261126
else
11271127
#endif
11281128
#if CV_TRY_AVX2

modules/dnn/src/layers/fully_connected_layer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class FullyConnectedLayerImpl : public InnerProductLayer
161161
p.activ = activ;
162162
p.useAVX = checkHardwareSupport(CPU_AVX);
163163
p.useAVX2 = checkHardwareSupport(CPU_AVX2);
164-
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX_512F;
164+
p.useAVX512 = CV_CPU_HAS_SUPPORT_AVX512_SKX;
165165

166166
parallel_for_(Range(0, nstripes), p, nstripes);
167167
}
@@ -196,9 +196,9 @@ class FullyConnectedLayerImpl : public InnerProductLayer
196196

197197
memcpy(sptr, sptr_, vecsize*sizeof(sptr[0]));
198198

199-
#if CV_TRY_AVX_512F
199+
#if CV_TRY_AVX512_SKX
200200
if( useAVX512 )
201-
opt_AVX_512F::fastGEMM1T( sptr, wptr, wstep, biasptr, dptr, nw, vecsize);
201+
opt_AVX512_SKX::fastGEMM1T( sptr, wptr, wstep, biasptr, dptr, nw, vecsize);
202202
else
203203
#endif
204204
#if CV_TRY_AVX2

modules/dnn/src/layers/layers_common.simd.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ void fastGEMM( const float* aptr, size_t astep, const float* bptr,
301301
{
302302
int n = 0;
303303

304-
#if CV_AVX_512F
304+
#if CV_AVX512_SKX // AVX512VL is necessary to avoid register spilling
305305
for( ; n <= nb - 32; n += 32 )
306306
{
307307
for( int m = 0; m < ma; m += 4 )

0 commit comments

Comments
 (0)