Skip to content

Commit

Permalink
core(test): intrinsic tests for all dispatched CPU optimizations
Browse files Browse the repository at this point in the history
- tests for both SIMD128 / SIMD256
- different dispatched + baseline(SIMD128) intrinsics
  • Loading branch information
alalek committed Aug 1, 2018
1 parent 67f79aa commit 3f302ca
Show file tree
Hide file tree
Showing 12 changed files with 527 additions and 426 deletions.
33 changes: 25 additions & 8 deletions cmake/OpenCVCompilerOptimizations.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -761,24 +761,24 @@ macro(ocv_compiler_optimization_fill_cpu_config)
endif()
endmacro()

macro(ocv_add_dispatched_file filename)
macro(__ocv_add_dispatched_file filename target_src_var src_directory dst_directory precomp_hpp optimizations_var)
if(NOT OPENCV_INITIAL_PASS)
set(__codestr "
#include \"${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp\"
#include \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"
#include \"${src_directory}/${precomp_hpp}\"
#include \"${src_directory}/${filename}.simd.hpp\"
")

set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${CMAKE_CURRENT_LIST_DIR}/src/${filename}.simd.hpp\"")
set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${src_directory}/${filename}.simd.hpp\"")
set(__dispatch_modes "BASELINE")

set(__optimizations "${ARGN}")
set(__optimizations "${${optimizations_var}}")
if(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
set(__optimizations "")
endif()

foreach(OPT ${__optimizations})
string(TOLOWER "${OPT}" OPT_LOWER)
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.${OPT_LOWER}.cpp")
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.${OPT_LOWER}.cpp")
if(EXISTS "${__file}")
file(READ "${__file}" __content)
else()
Expand All @@ -791,7 +791,11 @@ macro(ocv_add_dispatched_file filename)
endif()

if(";${CPU_DISPATCH};" MATCHES "${OPT}" OR __CPU_DISPATCH_INCLUDE_ALL)
list(APPEND OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED "${__file}")
if(EXISTS "${src_directory}/${filename}.${OPT_LOWER}.cpp")
message(STATUS "Using overrided ${OPT} source: ${src_directory}/${filename}.${OPT_LOWER}.cpp")
else()
list(APPEND ${target_src_var} "${__file}")
endif()
endif()

set(__declarations_str "${__declarations_str}
Expand All @@ -803,9 +807,11 @@ macro(ocv_add_dispatched_file filename)

set(__declarations_str "${__declarations_str}
#define CV_CPU_DISPATCH_MODES_ALL ${__dispatch_modes}
#undef CV_CPU_SIMD_FILENAME
")

set(__file "${CMAKE_CURRENT_BINARY_DIR}/${filename}.simd_declarations.hpp")
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.simd_declarations.hpp")
if(EXISTS "${__file}")
file(READ "${__file}" __content)
endif()
Expand All @@ -817,6 +823,17 @@ macro(ocv_add_dispatched_file filename)
endif()
endmacro()

macro(ocv_add_dispatched_file filename)
set(__optimizations "${ARGN}")
if(" ${ARGV1}" STREQUAL " TEST")
list(REMOVE_AT __optimizations 0)
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/test" "test/" "test_precomp.hpp" __optimizations)
else()
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/src" "" "precomp.hpp" __optimizations)
endif()
endmacro()


# Workaround to support code which always require all code paths
macro(ocv_add_dispatched_file_force_all)
set(__CPU_DISPATCH_INCLUDE_ALL 1)
Expand Down
6 changes: 6 additions & 0 deletions cmake/OpenCVModule.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,9 @@ function(ocv_add_accuracy_tests)
set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs})
endif()

if(OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED)
list(APPEND OPENCV_TEST_${the_module}_SOURCES ${OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED})
endif()
ocv_compiler_optimization_process_sources(OPENCV_TEST_${the_module}_SOURCES OPENCV_TEST_${the_module}_DEPS ${the_target})

if(NOT BUILD_opencv_world)
Expand All @@ -1211,6 +1214,9 @@ function(ocv_add_accuracy_tests)
source_group("Src" FILES "${${the_target}_pch}")
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test")
ocv_target_include_directories(${the_target} "${CMAKE_CURRENT_BINARY_DIR}/test")
endif()
ocv_target_link_libraries(${the_target} LINK_PRIVATE ${test_deps} ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_LINKER_LIBS} ${OPENCV_TEST_${the_module}_DEPS})
add_dependencies(opencv_tests ${the_target})

Expand Down
4 changes: 4 additions & 0 deletions modules/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ set(the_description "The Core Functionality")
ocv_add_dispatched_file(mathfuncs_core SSE2 AVX AVX2)
ocv_add_dispatched_file(stat SSE4_2 AVX2)

# dispatching for accuracy tests
ocv_add_dispatched_file_force_all(test_intrin128 TEST SSE2 SSE3 SSSE3 SSE4_1 SSE4_2 AVX FP16 AVX2)
ocv_add_dispatched_file_force_all(test_intrin256 TEST AVX2)

ocv_add_module(core
OPTIONAL opencv_cudev
WRAP java python js)
Expand Down
37 changes: 21 additions & 16 deletions modules/core/include/opencv2/core/hal/intrin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,20 +204,6 @@ CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
#define CV_SIMD512_64F 0
#endif

#if CV_SIMD512
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD512_64F
#define CV_SIMD_WIDTH 64
#elif CV_SIMD256
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD256_64F
#define CV_SIMD_WIDTH 32
#else
#define CV_SIMD CV_SIMD128
#define CV_SIMD_64F CV_SIMD128_64F
#define CV_SIMD_WIDTH 16
#endif

//==================================================================================================

#define CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \
Expand Down Expand Up @@ -309,7 +295,15 @@ template<typename _Tp> struct V_RegTraits
#endif
#endif

#if CV_SIMD256
#if CV_SIMD512 && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 512)
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD512_64F
#define CV_SIMD_WIDTH 64
// TODO typedef v_uint8 / v_int32 / etc types here
#elif CV_SIMD256 && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 256)
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD256_64F
#define CV_SIMD_WIDTH 32
typedef v_uint8x32 v_uint8;
typedef v_int8x32 v_int8;
typedef v_uint16x16 v_uint16;
Expand All @@ -329,7 +323,10 @@ template<typename _Tp> struct V_RegTraits
CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v256)
CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v256, load)
inline void vx_cleanup() { v256_cleanup(); }
#elif CV_SIMD128 || CV_SIMD128_CPP
#elif (CV_SIMD128 || CV_SIMD128_CPP) && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 128)
#define CV_SIMD CV_SIMD128
#define CV_SIMD_64F CV_SIMD128_64F
#define CV_SIMD_WIDTH 16
typedef v_uint8x16 v_uint8;
typedef v_int8x16 v_int8;
typedef v_uint16x8 v_uint16;
Expand Down Expand Up @@ -380,6 +377,14 @@ inline unsigned int trailingZeros32(unsigned int value) {
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
#endif

#ifndef CV_SIMD_64F
#define CV_SIMD_64F 0
#endif

#ifndef CV_SIMD
#define CV_SIMD 0
#endif

} // cv::

//! @endcond
Expand Down
5 changes: 0 additions & 5 deletions modules/core/test/test_intrin.avx2.cpp

This file was deleted.

151 changes: 75 additions & 76 deletions modules/core/test/test_intrin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,101 +2,100 @@
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "test_intrin.simd.hpp"

#define CV_CPU_SIMD_FILENAME "test_intrin.simd.hpp"
#define CV_CPU_DISPATCH_MODE FP16
#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
#include "test_intrin128.simd.hpp"
#include "test_intrin128.simd_declarations.hpp"

#define CV_CPU_DISPATCH_MODE AVX2
#include "opencv2/core/private/cv_cpu_include_simd_declarations.hpp"
#undef CV_CPU_DISPATCH_MODES_ALL

namespace opencv_test { namespace hal {
using namespace CV_CPU_OPTIMIZATION_NAMESPACE;

TEST(hal_intrin, uint8x16)
{ test_hal_intrin_uint8(); }

TEST(hal_intrin, int8x16)
{ test_hal_intrin_int8(); }

TEST(hal_intrin, uint16x8)
{ test_hal_intrin_uint16(); }

TEST(hal_intrin, int16x8)
{ test_hal_intrin_int16(); }

TEST(hal_intrin, int32x4)
{ test_hal_intrin_int32(); }

TEST(hal_intrin, uint32x4)
{ test_hal_intrin_uint32(); }

TEST(hal_intrin, uint64x2)
{ test_hal_intrin_uint64(); }

TEST(hal_intrin, int64x2)
{ test_hal_intrin_int64(); }
#include "opencv2/core/cv_cpu_dispatch.h"
#include "test_intrin256.simd.hpp"
#include "test_intrin256.simd_declarations.hpp"

TEST(hal_intrin, float32x4)
{ test_hal_intrin_float32(); }

TEST(hal_intrin, float64x2)
{ test_hal_intrin_float64(); }
namespace opencv_test { namespace hal {

TEST(hal_intrin, float16x8)
#define CV_CPU_CALL_BASELINE_(fn, args) CV_CPU_CALL_BASELINE(fn, args)

#define DISPATCH_SIMD128(fn, cpu_opt) do { \
CV_CPU_CALL_ ## cpu_opt ## _(fn, ()); \
throw SkipTestException("SIMD128 (" #cpu_opt ") is not available or disabled"); \
} while(0)

#define DISPATCH_SIMD256(fn, cpu_opt) do { \
CV_CPU_CALL_ ## cpu_opt ## _(fn, ()); \
throw SkipTestException("SIMD256 (" #cpu_opt ") is not available or disabled"); \
} while(0)

#define DEFINE_SIMD_TESTS(simd_size, cpu_opt) \
TEST(hal_intrin ## simd_size, uint8x16_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint8, cpu_opt); } \
TEST(hal_intrin ## simd_size, int8x16_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int8, cpu_opt); } \
TEST(hal_intrin ## simd_size, uint16x8_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint16, cpu_opt); } \
TEST(hal_intrin ## simd_size, int16x8_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int16, cpu_opt); } \
TEST(hal_intrin ## simd_size, int32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int32, cpu_opt); } \
TEST(hal_intrin ## simd_size, uint32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint32, cpu_opt); } \
TEST(hal_intrin ## simd_size, uint64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_uint64, cpu_opt); } \
TEST(hal_intrin ## simd_size, int64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_int64, cpu_opt); } \
TEST(hal_intrin ## simd_size, float32x4_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_float32, cpu_opt); } \
TEST(hal_intrin ## simd_size, float64x2_ ## cpu_opt) { DISPATCH_SIMD ## simd_size(test_hal_intrin_float64, cpu_opt); } \

namespace intrin128 {

DEFINE_SIMD_TESTS(128, BASELINE)

#if defined CV_CPU_DISPATCH_COMPILE_SSE2 || defined CV_CPU_BASELINE_COMPILE_SSE2
DEFINE_SIMD_TESTS(128, SSE2)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_SSE3 || defined CV_CPU_BASELINE_COMPILE_SSE3
DEFINE_SIMD_TESTS(128, SSE3)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_SSSE3 || defined CV_CPU_BASELINE_COMPILE_SSSE3
DEFINE_SIMD_TESTS(128, SSSE3)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_SSE4_1 || defined CV_CPU_BASELINE_COMPILE_SSE4_1
DEFINE_SIMD_TESTS(128, SSE4_1)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_SSE4_2 || defined CV_CPU_BASELINE_COMPILE_SSE4_2
DEFINE_SIMD_TESTS(128, SSE4_2)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_AVX || defined CV_CPU_BASELINE_COMPILE_AVX
DEFINE_SIMD_TESTS(128, AVX)
#endif
#if defined CV_CPU_DISPATCH_COMPILE_AVX2 || defined CV_CPU_BASELINE_COMPILE_AVX2
DEFINE_SIMD_TESTS(128, AVX2)
#endif

TEST(hal_intrin128, float16x8_FP16)
{
CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
throw SkipTestException("Unsupported hardware: FP16 is not available");
}

#define DISPATCH_SIMD_MODES AVX2
#define DISPATCH_SIMD_NAME "SIMD256"
#define DISPATCH_SIMD(fun) \
do { \
CV_CPU_DISPATCH(fun, (), DISPATCH_SIMD_MODES); \
throw SkipTestException( \
"Unsupported hardware: " \
DISPATCH_SIMD_NAME \
" is not available" \
); \
} while(0)

TEST(hal_intrin256, uint8x32)
{ DISPATCH_SIMD(test_hal_intrin_uint8); }

TEST(hal_intrin256, int8x32)
{ DISPATCH_SIMD(test_hal_intrin_int8); }

TEST(hal_intrin256, uint16x16)
{ DISPATCH_SIMD(test_hal_intrin_uint16); }
} // namespace intrin128

TEST(hal_intrin256, int16x16)
{ DISPATCH_SIMD(test_hal_intrin_int16); }

TEST(hal_intrin256, uint32x8)
{ DISPATCH_SIMD(test_hal_intrin_uint32); }
namespace intrin256 {

TEST(hal_intrin256, int32x8)
{ DISPATCH_SIMD(test_hal_intrin_int32); }

TEST(hal_intrin256, uint64x4)
{ DISPATCH_SIMD(test_hal_intrin_uint64); }
// Not available due missing C++ backend for SIMD256
//DEFINE_SIMD_TESTS(256, BASELINE)

TEST(hal_intrin256, int64x4)
{ DISPATCH_SIMD(test_hal_intrin_int64); }
//#if defined CV_CPU_DISPATCH_COMPILE_AVX
//DEFINE_SIMD_TESTS(256, AVX)
//#endif

TEST(hal_intrin256, float32x8)
{ DISPATCH_SIMD(test_hal_intrin_float32); }
#if defined CV_CPU_DISPATCH_COMPILE_AVX2 || defined CV_CPU_BASELINE_COMPILE_AVX2
DEFINE_SIMD_TESTS(256, AVX2)
#endif

TEST(hal_intrin256, float64x4)
{ DISPATCH_SIMD(test_hal_intrin_float64); }

TEST(hal_intrin256, float16x16)
TEST(hal_intrin256, float16x16_FP16)
{
if (!CV_CPU_HAS_SUPPORT_FP16)
throw SkipTestException("Unsupported hardware: FP16 is not available");
DISPATCH_SIMD(test_hal_intrin_float16);
//CV_CPU_CALL_FP16_(test_hal_intrin_float16, ());
CV_CPU_CALL_AVX2_(test_hal_intrin_float16, ());
throw SkipTestException("Unsupported hardware: FP16 is not available");
}


} // namespace intrin256

}} // namespace
19 changes: 0 additions & 19 deletions modules/core/test/test_intrin.fp16.cpp

This file was deleted.

Loading

0 comments on commit 3f302ca

Please sign in to comment.