Remove G-API (#21131)

* Remove G-API

* Apply comments

* Revert "Apply comments" - tests shared classes only

This reverts commit 8d07082341.

---------

Co-authored-by: Ilya Churaev <ilyachur@gmail.com>
This commit is contained in:
Vitaliy Urusovskij 2023-12-25 17:50:54 +04:00 committed by GitHub
parent b6ba2408ba
commit 2eaed979a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 37 additions and 24525 deletions

4
.gitmodules vendored
View File

@ -14,10 +14,6 @@
path = thirdparty/pugixml
url = https://github.com/zeux/pugixml.git
ignore = dirty
[submodule "thirdparty/ade"]
path = thirdparty/ade
url = https://github.com/opencv/ade.git
ignore = dirty
[submodule "thirdparty/gflags/gflags"]
path = thirdparty/gflags/gflags
url = https://github.com/gflags/gflags.git

View File

@ -103,8 +103,6 @@ endif()
ov_dependent_option (ENABLE_TBBBIND_2_5 "Enable TBBBind_2_5 static usage in OpenVINO runtime" ${ENABLE_TBBBIND_2_5_DEFAULT} "THREADING MATCHES TBB; NOT APPLE" OFF)
ov_dependent_option (ENABLE_TBB_RELEASE_ONLY "Only Release TBB libraries are linked to the OpenVINO Runtime binaries" ON "THREADING MATCHES TBB;LINUX" OFF)
ov_dependent_option (ENABLE_GAPI_PREPROCESSING "Enables G-API preprocessing" ON "NOT MINGW64" OFF)
ov_option (ENABLE_MULTI "Enables MULTI Device Plugin" ON)
ov_option (ENABLE_AUTO "Enables AUTO Device Plugin" ON)
ov_option (ENABLE_AUTO_BATCH "Enables Auto-Batching Plugin" ON)
@ -113,8 +111,6 @@ ov_option (ENABLE_TEMPLATE "Enable template plugin" ON)
ov_dependent_option (ENABLE_PLUGINS_XML "Generate plugins.xml configuration file or not" OFF "BUILD_SHARED_LIBS" OFF)
ov_dependent_option (GAPI_TEST_PERF "if GAPI unit tests should examine performance" OFF "ENABLE_TESTS;ENABLE_GAPI_PREPROCESSING" OFF)
ov_dependent_option (ENABLE_FUNCTIONAL_TESTS "functional tests" ON "ENABLE_TESTS" OFF)
ov_option (ENABLE_SAMPLES "console samples are part of OpenVINO Runtime package" ON)

View File

@ -333,17 +333,6 @@ macro(_ov_find_itt)
unset(_ENABLE_SYSTEM_ITTAPI)
endmacro()
macro(_ov_find_ade)
set(_OV_ENABLE_GAPI_PREPROCESSING "@ENABLE_GAPI_PREPROCESSING@")
# whether 'ade' is found via find_package
set(_ENABLE_SYSTEM_ADE "@ade_FOUND@")
if(_OV_ENABLE_GAPI_PREPROCESSING AND _ENABLE_SYSTEM_ADE)
_ov_find_dependency(ade @ade_VERSION@)
endif()
unset(_OV_ENABLE_GAPI_PREPROCESSING)
unset(_ENABLE_SYSTEM_ADE)
endmacro()
macro(_ov_find_intel_cpu_dependencies)
set(_OV_ENABLE_CPU_ACL "@DNNL_USE_ACL@")
if(_OV_ENABLE_CPU_ACL)
@ -493,9 +482,6 @@ if(NOT _OV_ENABLE_OPENVINO_BUILD_SHARED)
_ov_find_itt()
_ov_find_pugixml()
# preprocessing dependencies
_ov_find_ade()
# frontend dependencies
_ov_find_protobuf_frontend_dependency()
_ov_find_tensorflow_frontend_dependencies()

View File

@ -205,7 +205,6 @@ OpenVINO 2022.1 introduced a reorganization of the libraries, to make deployment
Below are detailed comparisons of the library structure between OpenVINO 2022.1 and the previous versions:
* Starting with 2022.1 release, a single core library with all the functionalities (``openvino`` for C++ Runtime, ``openvino_c`` for Inference Engine API C interface) is used, instead of the previous core libraries which contained ``inference_engine``, ``ngraph``, ``inference_engine_transformations`` and ``inference_engine_lp_transformations``.
* The optional ``inference_engine_preproc`` preprocessing library (if `InferenceEngine::PreProcessInfo::setColorFormat <classInferenceEngine_1_1PreProcessInfo.html#doxid-class-inference-engine-1-1-pre-process-info-1a3a10ba0d562a2268fe584d4d2db94cac>`__ or `InferenceEngine::PreProcessInfo::setResizeAlgorithm <classInferenceEngine_1_1PreProcessInfo.html#doxid-class-inference-engine-1-1-pre-process-info-1a0c083c43d01c53c327f09095e3e3f004>`__ is used) has been renamed to ``openvino_gapi_preproc`` and deprecated in 2022.1. For more details, see the :doc:`Preprocessing capabilities of OpenVINO API 2.0 <openvino_2_0_preprocessing>`.
* The libraries of plugins have been renamed as follows:
@ -234,8 +233,6 @@ Older versions of OpenVINO had several core libraries and plugin modules:
Now, the modularity is more clear:
- A single core library with all the functionality ``openvino`` for C++ runtime
- ``openvino_c`` with Inference Engine API C interface
- **Deprecated** Optional ``openvino_gapi_preproc`` preprocessing library (if ``InferenceEngine::PreProcessInfo::setColorFormat`` or ``InferenceEngine::PreProcessInfo::setResizeAlgorithm`` are used)
- Use :doc:`preprocessing capabilities of OpenVINO API 2.0 <openvino_2_0_preprocessing>`
- Plugin libraries with clear names:
- ``openvino_intel_cpu_plugin``
- ``openvino_intel_gpu_plugin``

View File

@ -278,7 +278,7 @@ Generate final optimal binaries size of OpenVINO package
md build
cd build
cmake -G "Visual Studio 16 2019" -A x64 -DENABLE_CPPLINT=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DENABLE_FASTER_BUILD=ON -DENABLE_PROFILING_ITT=OFF -DSELECTIVE_BUILD=ON -DENABLE_INTEL_GPU=OFF -DENABLE_MULTI=OFF -DENABLE_AUTO=OFF -DENABLE_AUTO_BATCH=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_OV_ONNX_FRONTEND=OFF -DENABLE_OV_PADDLE_FRONTEND=OFF -DENABLE_OV_PYTORCH_FRONTEND=OFF -DENABLE_OV_TF_FRONTEND=OFF -DSELECTIVE_BUILD_STAT=%OPENVINO_HOME%\cc_data\*.csv -DBUILD_SHARED_LIBS=OFF -DENABLE_LTO=ON -DENABLE_ONEDNN_FOR_GPU=OFF -DENABLE_GAPI_PREPROCESSING=OFF -DENABLE_OV_TF_LITE_FRONTEND=OFF -DENABLE_PROFILING_FIRST_INFERENCE=OFF ..
cmake -G "Visual Studio 16 2019" -A x64 -DENABLE_CPPLINT=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF -DCMAKE_BUILD_TYPE=Release -DENABLE_FASTER_BUILD=ON -DENABLE_PROFILING_ITT=OFF -DSELECTIVE_BUILD=ON -DENABLE_INTEL_GPU=OFF -DENABLE_MULTI=OFF -DENABLE_AUTO=OFF -DENABLE_AUTO_BATCH=OFF -DENABLE_HETERO=OFF -DENABLE_TEMPLATE=OFF -DENABLE_OV_ONNX_FRONTEND=OFF -DENABLE_OV_PADDLE_FRONTEND=OFF -DENABLE_OV_PYTORCH_FRONTEND=OFF -DENABLE_OV_TF_FRONTEND=OFF -DSELECTIVE_BUILD_STAT=%OPENVINO_HOME%\cc_data\*.csv -DBUILD_SHARED_LIBS=OFF -DENABLE_LTO=ON -DENABLE_ONEDNN_FOR_GPU=OFF -DENABLE_OV_TF_LITE_FRONTEND=OFF -DENABLE_PROFILING_FIRST_INFERENCE=OFF ..
cmake --build . --config Release

View File

@ -44,8 +44,6 @@ This document provides description and default values for CMake options that can
* `ON` is default.
* `ENABLE_OV_IR_FRONTEND` enables OpenVINO Intermediate Representation frontend plugin for OpenVINO Runtime:
* `ON` is default.
* `ENABLE_GAPI_PREPROCESSING` enables G-API preprocessing:
* `ON` is default.
* `OPENVINO_EXTRA_MODULES` specifies path to add extra OpenVINO modules to the build.
* See [OpenVINO Contrib] to add extra modules from.
* `ENABLE_SAMPLES` enables OpenVINO Runtime samples build:

View File

@ -47,7 +47,6 @@ cmake -DENABLE_INTEL_GPU=OFF \
-DENABLE_OV_TF_FRONTEND=OFF \
-DENABLE_OV_TF_LITE_FRONTEND=OFF \
-DENABLE_OV_PYTORCH_FRONTEND=OFF \
-DENABLE_GAPI_PREPROCESSING=OFF \
-DENABLE_INTEL_CPU=ON \
-DENABLE_OV_IR_FRONTEND=ON
```
@ -150,4 +149,4 @@ cmake -DCMAKE_TOOLCHAIN_FILE=<openvino source dir>/cmake/toolchains/mt.runtime.w
* [OpenVINO Developer Documentation](index.md)
* [How to Build OpenVINO](build.md)

View File

@ -18,8 +18,6 @@ add_subdirectory(frontends)
add_subdirectory(plugins)
add_subdirectory(inference)
include(cmake/openvino.cmake)
# preprocessing has dependency on `openvino` for static build
add_subdirectory(common/preprocessing)
add_subdirectory(bindings)
if(ENABLE_TESTS)

View File

@ -108,11 +108,7 @@ add_library(openvino::runtime::dev ALIAS openvino_runtime_dev)
target_include_directories(openvino_runtime_dev INTERFACE
$<BUILD_INTERFACE:${OpenVINO_SOURCE_DIR}/src/inference/dev_api>
$<BUILD_INTERFACE:${OpenVINO_SOURCE_DIR}/src/common/low_precision_transformations/include>
$<BUILD_INTERFACE:$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_INCLUDE_DIRECTORIES>>)
target_compile_definitions(openvino_runtime_dev INTERFACE
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_COMPILE_DEFINITIONS>)
$<BUILD_INTERFACE:${OpenVINO_SOURCE_DIR}/src/common/low_precision_transformations/include>)
target_link_libraries(openvino_runtime_dev INTERFACE ${TARGET_NAME} openvino::core::dev)

View File

@ -265,7 +265,7 @@ function(ov_set_threading_interface_for TARGET_NAME)
set(LINK_TYPE "PRIVATE")
set(COMPILE_DEF_TYPE "PRIVATE")
elseif(target_type STREQUAL "STATIC_LIBRARY")
# Affected libraries: inference_engine_s, openvino_gapi_preproc_s
# Affected libraries: inference_engine_s
# they don't have TBB in public headers => PRIVATE
set(LINK_TYPE "PRIVATE")
set(COMPILE_DEF_TYPE "PUBLIC")

View File

@ -1,11 +0,0 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
ov_deprecated_no_errors()
add_subdirectory(src)
if(ENABLE_TESTS AND ENABLE_GAPI_PREPROCESSING)
add_subdirectory(tests)
endif()

View File

@ -1,224 +0,0 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
set (TARGET_NAME "openvino_gapi_preproc")
file(GLOB LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
file(GLOB LIBRARY_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp)
#
# Provides compilation flags for AVX512F, AVX512BW, AVX512DQ
# instructions support depending on an OS and a compiler
#
macro(ie_avx512_core_optimization_flags flags)
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(${flags} /arch:AVX512)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
if(WIN32)
set(${flags} /QxCORE-AVX512)
else()
set(${flags} -xCORE-AVX512)
endif()
elseif(CMAKE_COMPILER_IS_GNUCXX OR OV_COMPILER_IS_CLANG)
set(${flags} -mavx512f -mavx512bw -mavx512dq -mfma)
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
list(APPEND ${flags} -Wno-error=maybe-uninitialized -Wno-maybe-uninitialized)
endif()
else()
message(WARNING "Unsupported CXX compiler ${CMAKE_CXX_COMPILER_ID}")
endif()
endmacro()
if(ENABLE_SSE42)
file(GLOB SSE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_sse42/*.cpp)
file(GLOB SSE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_sse42/*.hpp)
list(APPEND LIBRARY_HEADERS ${SSE_HEADERS})
list(APPEND LIBRARY_SRC ${SSE_SRC})
ov_sse42_optimization_flags(sse4_2_flags)
set_source_files_properties(${SSE_SRC} PROPERTIES COMPILE_OPTIONS "${sse4_2_flags}")
add_definitions(-DHAVE_SSE=1)
endif()
if(ENABLE_AVX2)
file(GLOB AVX2_SRC ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_avx2/*.cpp)
file(GLOB AVX2_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_avx2/*.hpp)
list(APPEND LIBRARY_HEADERS ${AVX2_HEADERS})
list(APPEND LIBRARY_SRC ${AVX2_SRC})
ov_avx2_optimization_flags(avx2_flags)
set_source_files_properties(${AVX2_SRC} PROPERTIES COMPILE_OPTIONS "${avx2_flags}")
add_definitions(-DHAVE_AVX2=1)
endif()
# Workaround for GCC version 5.4 and 5.5 bugs in Debug configuration.
if (CMAKE_COMPILER_IS_GNUCXX AND
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.5) AND
(CMAKE_BUILD_TYPE STREQUAL Debug))
set(GNU_5_DEBUG_CASE ON)
endif()
if(ENABLE_AVX512F AND NOT GNU_5_DEBUG_CASE)
file(GLOB AVX512_SRC ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_avx512/*.cpp)
file(GLOB AVX512_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/cpu_x86_avx512/*.hpp)
list(APPEND LIBRARY_HEADERS ${AVX512_HEADERS})
list(APPEND LIBRARY_SRC ${AVX512_SRC})
ie_avx512_core_optimization_flags(avx512_flags)
set_source_files_properties(${AVX512_SRC} PROPERTIES COMPILE_OPTIONS "${avx512_flags}")
add_definitions(-DHAVE_AVX512=1)
endif()
if(ARM OR AARCH64)
ov_arm_neon_optimization_flags(neon_flags)
file(GLOB NEON_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/arm_neon/*.hpp)
file(GLOB NEON_SRC ${CMAKE_CURRENT_SOURCE_DIR}/arm_neon/*.cpp)
list(APPEND LIBRARY_HEADERS ${NEON_HEADERS})
list(APPEND LIBRARY_SRC ${NEON_SRC})
if(neon_flags)
set_source_files_properties(${NEON_SRC} PROPERTIES COMPILE_OPTIONS "${neon_flags}")
endif()
add_definitions(-DHAVE_NEON=1)
endif()
# Create object library
if(ENABLE_GAPI_PREPROCESSING)
add_library(${TARGET_NAME}_obj OBJECT
${LIBRARY_SRC}
${LIBRARY_HEADERS})
ov_build_target_faster(${TARGET_NAME}_obj UNITY)
target_compile_definitions(${TARGET_NAME}_obj PRIVATE
IMPLEMENT_INFERENCE_ENGINE_PLUGIN
$<TARGET_PROPERTY:openvino::runtime,INTERFACE_COMPILE_DEFINITIONS>
$<TARGET_PROPERTY:fluid,INTERFACE_COMPILE_DEFINITIONS>
ENABLE_GAPI_PREPROCESSING)
target_include_directories(${TARGET_NAME}_obj SYSTEM PRIVATE
$<TARGET_PROPERTY:ocv_hal,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:fluid,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:inference_engine_plugin_api,INTERFACE_INCLUDE_DIRECTORIES>)
target_include_directories(${TARGET_NAME}_obj PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}"
$<TARGET_PROPERTY:openvino::util,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::itt,INTERFACE_INCLUDE_DIRECTORIES>)
ov_set_threading_interface_for(${TARGET_NAME}_obj)
add_cpplint_target(${TARGET_NAME}_obj_cpplint FOR_TARGETS ${TARGET_NAME}_obj)
set(library_sources $<TARGET_OBJECTS:${TARGET_NAME}_obj>)
endif()
# Create module library file from object library
if(ENABLE_GAPI_PREPROCESSING)
if(BUILD_SHARED_LIBS)
set(library_type MODULE)
else()
set(library_type STATIC)
endif()
else()
set(library_type INTERFACE)
endif()
add_library(${TARGET_NAME} ${library_type} ${library_sources})
ov_set_threading_interface_for(${TARGET_NAME})
if(ENABLE_GAPI_PREPROCESSING)
target_compile_definitions(${TARGET_NAME} PUBLIC ENABLE_GAPI_PREPROCESSING)
target_link_libraries(${TARGET_NAME} PRIVATE fluid openvino::itt openvino::util)
if(BUILD_SHARED_LIBS)
target_link_libraries(${TARGET_NAME} PRIVATE openvino::runtime)
# make plugin to depend on preprocessing library
foreach(plugin IN LISTS PLUGIN_FILES)
string(REPLACE ":" ";" plugin "${plugin}")
list(REMOVE_AT plugin 0)
add_dependencies(${plugin} openvino_gapi_preproc)
endforeach()
add_dependencies(ov_plugins openvino_gapi_preproc)
else()
# for static linkage the dependencies are in opposite order
target_link_libraries(openvino PRIVATE ${TARGET_NAME})
endif()
# Workaround to avoid warnings caused with bug in the avx512intrin.h of GCC5
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.5))
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS_RELEASE "-Wno-error=maybe-uninitialized -Wno-maybe-uninitialized")
endif()
if(WIN32 AND NOT library_type STREQUAL "INTERFACE")
set_target_properties(${TARGET_NAME} PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME})
endif()
# must be called after all target_link_libraries
ov_add_api_validator_post_build_step(TARGET ${TARGET_NAME})
ov_add_vs_version_file(NAME ${TARGET_NAME}
FILEDESCRIPTION "OpenVINO Preprocessing plugin")
endif()
target_include_directories(${TARGET_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<TARGET_PROPERTY:openvino,INTERFACE_INCLUDE_DIRECTORIES>)
# Static library used for unit tests which are always built
if(ENABLE_GAPI_PREPROCESSING)
add_library(${TARGET_NAME}_s STATIC EXCLUDE_FROM_ALL
$<TARGET_OBJECTS:${TARGET_NAME}_obj>)
ov_set_threading_interface_for(${TARGET_NAME}_s)
target_include_directories(${TARGET_NAME}_s INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
if(WIN32)
set_target_properties(${TARGET_NAME}_s PROPERTIES COMPILE_PDB_NAME ${TARGET_NAME}_s)
endif()
target_link_libraries(${TARGET_NAME}_s PRIVATE fluid openvino::itt openvino::runtime)
target_compile_definitions(${TARGET_NAME}_s INTERFACE USE_STATIC_IE)
set_target_properties(${TARGET_NAME}_s PROPERTIES EXCLUDE_FROM_ALL ON)
endif()
# LTO
if(TARGET ${TARGET_NAME}_obj)
set_target_properties(${TARGET_NAME}_obj ${TARGET_NAME}_s
PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})
endif()
if(NOT library_type STREQUAL "INTERFACE")
set_target_properties(${TARGET_NAME}
PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE ${ENABLE_LTO})
endif()
# developer package
ov_developer_package_export_targets(TARGET ${TARGET_NAME})
# install
if(BUILD_SHARED_LIBS)
install(TARGETS ${TARGET_NAME}
LIBRARY DESTINATION ${OV_CPACK_PLUGINSDIR} COMPONENT ${OV_CPACK_COMP_CORE}
${OV_CPACK_COMP_CORE_EXCLUDE_ALL})
else()
ov_install_static_lib(${TARGET_NAME} ${OV_CPACK_COMP_CORE})
endif()

View File

@ -1,651 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_gapi_kernels_impl.hpp"
#include "ie_preprocess_gapi_kernels_neon.hpp"
#include <arm_neon.h>
#ifdef CV_NEON
#undef CV_NEON
#endif
#define CV_NEON 1
#ifdef CV_SIMD128
#undef CV_SIMD128
#endif
#define CV_SIMD128 1
#include "opencv_hal_intrin.hpp"
#include "ie_preprocess_gapi_kernels_simd_impl.hpp"
using namespace cv;
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace neon {
template<int chanNum>
CV_ALWAYS_INLINE void channels2planes_store(std::array<std::array<uint8_t*, 4>, chanNum>& dst,
const uchar* src, const int width,
const int line) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
GAPI_DbgAssert(width >= nlanes);
v_uint8 chan;
int x = 0;
for (;;) {
for (; x <= width - nlanes && x >= 0; x += nlanes) {
for (int c = 0; c < chanNum; ++c) {
v_gather_channel<chanNum>(chan, &src[chanNum * x], c);
vx_store(&dst[c][line][x], chan);
}
}
if (x < width) {
x = width - nlanes;
continue;
}
break;
}
}
CV_ALWAYS_INLINE void vertical_anyLPI(const uchar* src0, const uchar* src1,
uchar* tmp, const int inLength,
const short beta) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
GAPI_DbgAssert(inLength >= nlanes);
const int half_nlanes = nlanes/2;
int w = 0;
for (;;) {
for (; w <= inLength - nlanes; w += nlanes) {
v_int16 s0 = v_reinterpret_as_s16(vx_load_expand(&src0[w]));
v_int16 s1 = v_reinterpret_as_s16(vx_load_expand(&src1[w]));
v_int16 s2 = v_reinterpret_as_s16(vx_load_expand(&src0[w + half_nlanes]));
v_int16 s3 = v_reinterpret_as_s16(vx_load_expand(&src1[w + half_nlanes]));
v_int16 res1 = v_mulhrs(s0 - s1, beta) + s1;
v_int16 res2 = v_mulhrs(s2 - s3, beta) + s3;
vx_store(tmp + w, v_pack_u(res1, res2));
}
if (w < inLength) {
w = inLength - nlanes;
continue;
}
break;
}
}
template<int chanNum>
CV_ALWAYS_INLINE void horizontal_anyLPI(std::array<std::array<uint8_t*, 4>, chanNum>& dst,
const uchar* src, const short mapsx[],
const short alpha[], const int width,
const int line) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
const int half_nlanes = nlanes/2;
GAPI_DbgAssert(width >= half_nlanes);
v_int16 t0, t1;//, t2, t3;
int x = 0;
for (;;) {
for (; x <= width - half_nlanes && x >= 0; x += half_nlanes) {
v_int16 a0 = vx_load(&alpha[x]);
for (int c = 0; c < chanNum; ++c) {
v_gather_channel<chanNum>(t0, src, &mapsx[x], c, 0);
v_gather_channel<chanNum>(t1, src, &mapsx[x], c, 1);
//v_gather_channel<chanNum>(t2, src, &mapsx[x + half_nlanes], c, 0);
//v_gather_channel<chanNum>(t3, src, &mapsx[x + half_nlanes], c, 1);
v_int16 res1 = v_mulhrs(t0 - t1, a0) + t1;
//v_int16 res2 = v_mulhrs(t2 - t3, a0) + t3;
//vx_store(&dst[c][line][x], v_pack_u(res1, res2));
v_pack_u_store(&dst[c][line][x], res1);
}
}
if (x < width) {
//x = width - nlanes;
x = width - half_nlanes;
continue;
}
break;
}
}
CV_ALWAYS_INLINE void vertical_4LPI(const uint8_t* src0[], const uint8_t* src1[],
uchar tmp[], const short beta[], const int length) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
constexpr int half_nlanes = nlanes / 2;
GAPI_Assert(length >= half_nlanes);
v_int16 b0 = vx_setall_s16(beta[0]);
v_int16 b1 = vx_setall_s16(beta[1]);
v_int16 b2 = vx_setall_s16(beta[2]);
v_int16 b3 = vx_setall_s16(beta[3]);
v_int16 lo1, hi1, lo2, hi2;
v_int32 res1_s32, res2_s32;
int w = 0;
for (;;) {
for (; w <= length - half_nlanes; w += half_nlanes) {
v_int16 val0_0 = v_reinterpret_as_s16(vx_load_expand(&src0[0][w]));
v_int16 val0_1 = v_reinterpret_as_s16(vx_load_expand(&src0[1][w]));
v_int16 val0_2 = v_reinterpret_as_s16(vx_load_expand(&src0[2][w]));
v_int16 val0_3 = v_reinterpret_as_s16(vx_load_expand(&src0[3][w]));
v_int16 val1_0 = v_reinterpret_as_s16(vx_load_expand(&src1[0][w]));
v_int16 val1_1 = v_reinterpret_as_s16(vx_load_expand(&src1[1][w]));
v_int16 val1_2 = v_reinterpret_as_s16(vx_load_expand(&src1[2][w]));
v_int16 val1_3 = v_reinterpret_as_s16(vx_load_expand(&src1[3][w]));
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), b0);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), b1);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), b2);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), b3);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_interleave(r0, r1, lo1, hi1);
v_interleave(r2, r3, lo2, hi2);
v_int32 lo1_s32 = v_reinterpret_as_s32(lo1);
v_int32 hi1_s32 = v_reinterpret_as_s32(hi1);
v_int32 lo2_s32 = v_reinterpret_as_s32(lo2);
v_int32 hi2_s32 = v_reinterpret_as_s32(hi2);
v_interleave(lo1_s32, lo2_s32, res1_s32, res2_s32);
v_int16 res1 = v_reinterpret_as_s16(res1_s32);
v_int16 res2 = v_reinterpret_as_s16(res2_s32);
v_pack_u_store(&tmp[4 * w + 0], res1);
v_pack_u_store(&tmp[4 * w + half_nlanes], res2);
v_interleave(hi1_s32, hi2_s32, res1_s32, res2_s32);
v_int16 res3 = v_reinterpret_as_s16(res1_s32);
v_int16 res4 = v_reinterpret_as_s16(res2_s32);
v_pack_u_store(&tmp[4 * w + 2*half_nlanes], res3);
v_pack_u_store(&tmp[4 * w + 3*half_nlanes], res4);
}
if (w < length) {
w = length - half_nlanes;
continue;
}
break;
}
}
template<int chanNum>
CV_ALWAYS_INLINE void horizontal_4LPI(std::array<std::array<uint8_t*, 4>, chanNum>& dst,
const uchar* tmp, const short mapsx[], const uchar _mask_horizontal[],
const short clone[],
const int length) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
constexpr int half_nlanes = nlanes / 2;
GAPI_DbgAssert(length >= half_nlanes);
const int shift = static_cast<int>(half_nlanes / 4);
v_uint8 hmask = vx_load(_mask_horizontal);
v_uint8 val_0, val_1, val_2, val_3;
int x = 0;
for (;;) {
for (; x <= length - half_nlanes && x >= 0; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 2)]);
v_int16 a54 = vx_load(&clone[4 * (x + 4)]);
v_int16 a76 = vx_load(&clone[4 * (x + 6)]);
for (int c = 0; c < chanNum; ++c) {
v_gather_channel(val_0, tmp, &mapsx[x], chanNum, c, 0);
v_gather_channel(val_1, tmp, &mapsx[x], chanNum, c, shift);
v_gather_channel(val_2, tmp, &mapsx[x], chanNum, c, shift * 2);
v_gather_channel(val_3, tmp, &mapsx[x], chanNum, c, shift * 3);
v_int16 val0_0 = v_reinterpret_as_s16(v_expand_low(val_0));
v_int16 val0_1 = v_reinterpret_as_s16(v_expand_low(val_1));
v_int16 val0_2 = v_reinterpret_as_s16(v_expand_low(val_2));
v_int16 val0_3 = v_reinterpret_as_s16(v_expand_low(val_3));
v_int16 val1_0 = v_reinterpret_as_s16(v_expand_high(val_0));
v_int16 val1_1 = v_reinterpret_as_s16(v_expand_high(val_1));
v_int16 val1_2 = v_reinterpret_as_s16(v_expand_high(val_2));
v_int16 val1_3 = v_reinterpret_as_s16(v_expand_high(val_3));
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), a10);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), a32);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), a54);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), a76);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_pack_u(r0, r1);
v_uint8 q1 = v_pack_u(r2, r3);
v_uint8 q2 = v_shuffle(q0, hmask);
v_uint8 q3 = v_shuffle(q1, hmask);
v_uint8 q4 = v_blend<0xCC /*0b11001100*/>(q2, v_shift_left<4>(q3));
v_uint8 q5 = v_blend<0xCC /*0b11001100*/>(v_shift_right<4>(q2), q3);
v_store_low(&dst[c][0][x], q4);
v_store_high(&dst[c][1][x], q4);
v_store_low(&dst[c][2][x], q5);
v_store_high(&dst[c][3][x], q5);
}
}
if (x < length) {
x = length - half_nlanes;
continue;
}
break;
}
}
template<int chanNum>
CV_ALWAYS_INLINE bool calcRowLinear_8UC_Impl(neon_tag,
std::array<std::array<uint8_t*, 4>, chanNum>& dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi) {
static_assert(v_uint8::nlanes == 16,
"The wide of NEON vector is 128 bits, so one vector contains 16 uchars");
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
if ((inSz.width * chanNum < nlanes) || (outSz.width < nlanes))
return false;
bool xRatioEq = inSz.width == outSz.width;
bool yRatioEq = inSz.height == outSz.height;
if (!xRatioEq && !yRatioEq) {
uchar _mask_horizontal[nlanes] = { 0, 4, 8, 12, 2, 6, 10, 14,
1, 5, 9, 13, 3, 7, 11, 15 };
if (4 == lpi) {
// vertical pass
vertical_4LPI(src0, src1, tmp, beta, inSz.width * chanNum);
// horizontal pass
horizontal_4LPI<chanNum>(dst, tmp, mapsx, _mask_horizontal, clone, outSz.width);
} else { // if any lpi
int inLength = inSz.width * chanNum;
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
const uchar* s0 = src0[l];
const uchar* s1 = src1[l];
// vertical pass
vertical_anyLPI(s0, s1, tmp, inLength, beta0);
// horizontal pass
horizontal_anyLPI<chanNum>(dst, tmp, mapsx, alpha, outSz.width, l);
}
}
} else if (!xRatioEq) {
GAPI_DbgAssert(yRatioEq);
uchar _mask_horizontal[nlanes] = { 0, 4, 8, 12, 2, 6, 10, 14,
1, 5, 9, 13, 3, 7, 11, 15 };
if (4 == lpi) {
int inLength = inSz.width * chanNum;
// vertical pass
GAPI_DbgAssert(inLength >= nlanes);
v_uint8 s0, s1, s2, s3;
int w = 0;
for (;;) {
for (; w <= inLength - nlanes; w += nlanes) {
s0 = vx_load(&src0[0][w]);
s1 = vx_load(&src0[1][w]);
s2 = vx_load(&src0[2][w]);
s3 = vx_load(&src0[3][w]);
v_store_interleave(&tmp[lpi * w], s0, s1, s2, s3);
}
if (w < inLength) {
w = inLength - nlanes;
continue;
}
break;
}
// horizontal pass
horizontal_4LPI<chanNum>(dst, tmp, mapsx, _mask_horizontal, clone, outSz.width);
} else { // any LPI
for (int l = 0; l < lpi; ++l) {
const uchar* src = src0[l];
// horizontal pass
horizontal_anyLPI<chanNum>(dst, src, mapsx, alpha, outSz.width, l);
}
}
} else if (!yRatioEq) {
GAPI_DbgAssert(xRatioEq);
int inLength = inSz.width*chanNum; // == outSz.width
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
const uchar* s0 = src0[l];
const uchar* s1 = src1[l];
// vertical pass
vertical_anyLPI(s0, s1, tmp, inLength, beta0);
//split channels to planes and store
channels2planes_store<chanNum>(dst, tmp, outSz.width, l);
}
} else {
GAPI_DbgAssert(xRatioEq && yRatioEq);
//split channels to planes and store
for (int l = 0; l < lpi; ++l) {
const uchar* src = src0[l];
channels2planes_store<chanNum>(dst, src, outSz.width, l);
}
}
return true;
}
CV_ALWAYS_INLINE void horizontal_4LPI(uint8_t* dst[],
const uchar* tmp, const short mapsx[],
const short clone[], const int length) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
constexpr int half_nlanes = nlanes / 2;
GAPI_DbgAssert(length >= half_nlanes);
uchar _mask_horizontal[nlanes] = { 0, 4, 8, 12, 2, 6, 10, 14,
1, 5, 9, 13, 3, 7, 11, 15 };
v_uint8 hmask = vx_load(_mask_horizontal);
int x = 0;
for (;;) {
for (; x <= length - half_nlanes; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 2)]);
v_int16 a54 = vx_load(&clone[4 * (x + 4)]);
v_int16 a76 = vx_load(&clone[4 * (x + 6)]);
v_uint8 val_0 = v_gather_lines(tmp, &mapsx[x]);
v_uint8 val_1 = v_gather_lines(tmp, &mapsx[x + 2]);
v_uint8 val_2 = v_gather_lines(tmp, &mapsx[x + 4]);
v_uint8 val_3 = v_gather_lines(tmp, &mapsx[x + 6]);
v_int16 val0_0 = v_reinterpret_as_s16(v_expand_low(val_0));
v_int16 val0_1 = v_reinterpret_as_s16(v_expand_low(val_1));
v_int16 val0_2 = v_reinterpret_as_s16(v_expand_low(val_2));
v_int16 val0_3 = v_reinterpret_as_s16(v_expand_low(val_3));
v_int16 val1_0 = v_reinterpret_as_s16(v_expand_high(val_0));
v_int16 val1_1 = v_reinterpret_as_s16(v_expand_high(val_1));
v_int16 val1_2 = v_reinterpret_as_s16(v_expand_high(val_2));
v_int16 val1_3 = v_reinterpret_as_s16(v_expand_high(val_3));
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), a10);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), a32);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), a54);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), a76);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_pack_u(r0, r1);
v_uint8 q1 = v_pack_u(r2, r3);
v_uint8 q2 = v_shuffle(q0, hmask);
v_uint8 q3 = v_shuffle(q1, hmask);
v_uint8 q4 = v_blend<0xCC /*0b11001100*/>(q2, v_shift_left<4>(q3));
v_uint8 q5 = v_blend<0xCC /*0b11001100*/>(v_shift_right<4>(q2), q3);
v_store_low(&dst[0][x], q4);
v_store_high(&dst[1][x], q4);
v_store_low(&dst[2][x], q5);
v_store_high(&dst[3][x], q5);
}
if (x < length) {
x = length - half_nlanes;
continue;
}
break;
}
}
CV_ALWAYS_INLINE void horizontal_anyLPI(uint8_t* dst,
const uchar* src, const short mapsx[],
const short alpha[], const int length) {
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
constexpr int half_nlanes = nlanes / 2;
GAPI_DbgAssert(length >= half_nlanes);
v_int16 t0, t1;
int x = 0;
for (;;) {
for (; x <= length - half_nlanes; x += half_nlanes) {
v_int16 a0 = vx_load(&alpha[x]);
v_uint8 t = v_gather_pairs(src, &mapsx[x]);
v_deinterleave_expand(t, t0, t1);
v_int16 d = v_mulhrs(t0 - t1, a0) + t1;
v_pack_u_store(&dst[x], d);
}
if (x < length) {
x = length - half_nlanes;
continue;
}
break;
}
}
} // namespace neon
template<>
bool calcRowLinear8UC3C4Impl<neon_tag, 3>(neon_tag,
std::array<std::array<uint8_t*, 4>, 3> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 3;
return neon::calcRowLinear_8UC_Impl<chanNum>(neon_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// Resize (bi-linear, 8UC4)
template<>
bool calcRowLinear8UC3C4Impl<neon_tag, 4>(neon_tag,
std::array<std::array<uint8_t*, 4>, 4> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 4;
return neon::calcRowLinear_8UC_Impl<chanNum>(neon_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// 8UC1 Resize (bi-linear)
template<>
bool calcRowLinear8UC1Impl(neon_tag,
uint8_t* dst[],
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int) {
static_assert(v_uint8::nlanes == 16,
"The wide of NEON vector is 128 bits, so one vector contains 16 uchars");
constexpr int nlanes = static_cast<int>(v_uint8::nlanes);
constexpr int half_nlanes = v_uint8::nlanes / 2;
if (inSz.width < nlanes || outSz.width < half_nlanes)
return false;
bool xRatioEq = inSz.width == outSz.width;
bool yRatioEq = inSz.height == outSz.height;
if (!xRatioEq && !yRatioEq) {
if (4 == lpi) {
// vertical pass
neon::vertical_4LPI(src0, src1, tmp, beta, inSz.width);
// horizontal pass
neon::horizontal_4LPI(dst, tmp, mapsx, clone, outSz.width);
} else { // if any lpi
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
const uchar* s0 = src0[l];
const uchar* s1 = src1[l];
uchar* _dst = dst[l];
// vertical pass
neon::vertical_anyLPI(s0, s1, tmp, inSz.width, beta0);
// horizontal pass
neon::horizontal_anyLPI(_dst, tmp, mapsx, alpha, outSz.width);
}
} // if lpi == 4
} else if (!xRatioEq) {
GAPI_DbgAssert(yRatioEq);
GAPI_DbgAssert(inSz.width >= nlanes);
if (4 == lpi) {
// vertical pass
int w = 0;
for (;;) {
for (; w <= inSz.width - nlanes; w += nlanes) {
v_uint8 s0 = vx_load(&src0[0][w]);
v_uint8 s1 = vx_load(&src0[1][w]);
v_uint8 s2 = vx_load(&src0[2][w]);
v_uint8 s3 = vx_load(&src0[3][w]);
v_store_interleave(&tmp[4 * w], s0, s1, s2, s3);
}
if (w < inSz.width) {
w = inSz.width - nlanes;
continue;
}
break;
}
// horizontal pass
neon::horizontal_4LPI(dst, tmp, mapsx, clone, outSz.width);
} else { // any LPI
for (int l = 0; l < lpi; ++l) {
const uchar* src = src0[l];
uchar* _dst = dst[l];
// horizontal pass
neon::horizontal_anyLPI(_dst, src, mapsx, alpha, outSz.width);
}
}
} else if (!yRatioEq) {
GAPI_DbgAssert(xRatioEq);
int length = inSz.width; // == outSz.width
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
const uchar* s0 = src0[l];
const uchar* s1 = src1[l];
// vertical pass
neon::vertical_anyLPI(s0, s1, dst[l], length, beta0);
}
} else {
GAPI_DbgAssert(xRatioEq && yRatioEq);
int length = inSz.width; // == outSz.width
for (int l = 0; l < lpi; ++l) {
memcpy(dst[l], src0[l], length);
}
}
return true;
}
template void chanToPlaneRowImpl(neon_tag, const uint8_t* in, int chan, int chs, uint8_t* out, const int length);
template void chanToPlaneRowImpl(neon_tag, const float* in, int chan, int chs, float * out, const int length);
template void nv12ToRgbRowImpl(neon_tag, const uint8_t** y_rows, const uint8_t* uv_row, uint8_t** out_rows, const int buf_width);
template void i420ToRgbRowImpl(neon_tag, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template void splitRowImpl<neon_tag, uint8_t, 2>(neon_tag, const uint8_t* in, std::array<uint8_t*, 2>& outs, const int length);
template void splitRowImpl<neon_tag, float, 2>(neon_tag, const float* in, std::array<float*, 2>& outs, const int length);
template void splitRowImpl<neon_tag, uint8_t, 3>(neon_tag, const uint8_t* in, std::array<uint8_t*, 3>& outs, const int length);
template void splitRowImpl<neon_tag, float, 3>(neon_tag, const float* in, std::array<float*, 3>& outs, const int length);
template void splitRowImpl<neon_tag, uint8_t, 4>(neon_tag, const uint8_t* in, std::array<uint8_t*, 4>& outs, const int length);
template void splitRowImpl<neon_tag, float, 4>(neon_tag, const float* in, std::array<float*, 4>& outs, const int length);
template void mergeRowImpl<neon_tag, uint8_t, 2>(neon_tag, const std::array<const uint8_t*, 2>& ins, uint8_t* out, const int length);
template void mergeRowImpl<neon_tag, float, 2>(neon_tag, const std::array<const float*, 2>& ins, float* out, const int length);
template void mergeRowImpl<neon_tag, uint8_t, 3>(neon_tag, const std::array<const uint8_t*, 3>& ins, uint8_t* out, const int length);
template void mergeRowImpl<neon_tag, float, 3>(neon_tag, const std::array<const float*, 3>& ins, float* out, const int length);
template void mergeRowImpl<neon_tag, uint8_t, 4>(neon_tag, const std::array<const uint8_t*, 4>& ins, uint8_t* out, const int length);
template void mergeRowImpl<neon_tag, float, 4>(neon_tag, const std::array<const float*, 4>& ins, float* out, const int length);
template void calcRowLinear32FC1Impl(neon_tag, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[], const float beta[],
const Size& inSz, const Size& outSz, const int lpi, const int l);
template void calcRowAreaImpl<neon_tag, uint8_t, Q0_16, short, Q8_8>(neon_tag, uint8_t dst[], const uint8_t* src[], const Size& inSz,
const Size& outSz, Q0_16 yalpha, const MapperUnit8U &ymap,
int xmaxdf, const short xindex[], const Q0_16 xalpha[],
Q8_8 vbuf[]);
template void calcRowAreaImpl<neon_tag, float, float, int, float>(neon_tag, float dst[], const float *src[], const Size& inSz,
const Size& outSz, float yalpha, const MapperUnit32F& ymap,
int xmaxdf, const int xindex[], const float xalpha[],
float vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,73 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_gapi_kernels_impl.hpp"
#include <type_traits>
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace neon {
using C3 = std::integral_constant<int, 3>;
using C4 = std::integral_constant<int, 4>;
//-----------------------------------------------------------------------------
typedef MapperUnit<float, int> MapperUnit32F;
typedef MapperUnit<Q0_16, short> MapperUnit8U;
void calcRowArea_8U(uchar dst[], const uchar *src[], const Size &inSz, const Size &outSz,
Q0_16 yalpha, const MapperUnit8U& ymap, int xmaxdf, const short xindex[],
const Q0_16 xalpha[], Q8_8 vbuf[]);
void calcRowArea_32F(float dst[], const float *src[], const Size &inSz, const Size &outSz,
float yalpha, const MapperUnit32F& ymap, int xmaxdf, const int xindex[],
const float xalpha[], float vbuf[]);
} // namespace neon
template<typename isa_tag_t, typename T>
void chanToPlaneRowImpl(isa_tag_t, const T* in, const int chan, const int chs, T* out, const int length);
template<typename isa_tag_t>
void nv12ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* uv_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t>
void i420ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t, typename T, int chs>
void splitRowImpl(isa_tag_t, const T* in, std::array<T*, chs>& outs, const int length);
template<typename isa_tag_t, typename T, int chs>
void mergeRowImpl(isa_tag_t, const std::array<const T*, chs>& ins, T* out, const int length);
template<typename isa_tag_t>
bool calcRowLinear8UC1Impl(isa_tag_t, uint8_t* dst[], const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t>
void calcRowLinear32FC1Impl(isa_tag_t, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[],
const float beta[], const Size& inSz, const Size& outSz,
const int lpi, const int l);
template<typename isa_tag_t, int chs>
bool calcRowLinear8UC3C4Impl(isa_tag_t, std::array<std::array<uint8_t*, 4>, chs>& dst,
const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t, typename T, typename A, typename I, typename W>
void calcRowAreaImpl(isa_tag_t, T dst[], const T* src[], const Size& inSz,
const Size& outSz, A yalpha, const MapperUnit<A, I>& ymap,
int xmaxdf, const I xindex[], const A xalpha[], W vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,529 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <algorithm>
#include <utility>
#include "ie_preprocess_gapi_kernels_avx2.hpp"
#include <immintrin.h>
#ifdef CV_AVX2
#undef CV_AVX2
#endif
#define CV_AVX2 1
#define CV_CPU_HAS_SUPPORT_SSE2 1
#ifdef CV_SIMD256
#undef CV_SIMD256
#endif
#define CV_SIMD256 1
#include "opencv_hal_intrin.hpp"
#include "ie_preprocess_gapi_kernels_simd_impl.hpp"
#if !CV_SIMD256
#error CV_SIMD256 is required!
#endif
#include <cstring>
#if defined __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstrict-overflow"
#endif
using namespace cv;
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace avx {
CV_ALWAYS_INLINE void main_computation_horizontalPass_lpi4(const v_uint8& val_0,
const v_uint8& val_1,
const v_uint8& val_2,
const v_uint8& val_3,
const v_int16& a10,
const v_int16& a32,
const v_int16& a54,
const v_int16& a76,
v_uint8& shuf_mask1,
v_uint8& shuf_mask2,
v_uint8& res1, v_uint8& res2) {
v_int16 val0_0 = v_reinterpret_as_s16(v_expand_low(val_0));
v_int16 val0_1 = v_reinterpret_as_s16(v_expand_low(val_1));
v_int16 val0_2 = v_reinterpret_as_s16(v_expand_low(val_2));
v_int16 val0_3 = v_reinterpret_as_s16(v_expand_low(val_3));
v_int16 val1_0 = v_reinterpret_as_s16(v_expand_high(val_0));
v_int16 val1_1 = v_reinterpret_as_s16(v_expand_high(val_1));
v_int16 val1_2 = v_reinterpret_as_s16(v_expand_high(val_2));
v_int16 val1_3 = v_reinterpret_as_s16(v_expand_high(val_3));
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), a10);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), a32);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), a54);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), a76);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_packus(r0, r1);
v_uint8 q1 = v_packus(r2, r3);
v_uint8 q2 = v_shuffle_s8(q0, shuf_mask1);
v_uint8 q3 = v_shuffle_s8(q1, shuf_mask1);
v_uint8 q4 = v_blend_shiftleft<0xCC /*0b11001100*/, 4>(q2, q3);
v_uint8 q5 = v_blend_shiftright<0xCC /*0b11001100*/, 4>(q2, q3);
v_uint8 q6 = v256_permute4x64<0xD8>(q4);
v_uint8 q7 = v256_permute4x64<0xD8>(q5);
res1 = v_shuffle_s8(q6, shuf_mask2);
res2 = v_shuffle_s8(q7, shuf_mask2);
}
CV_ALWAYS_INLINE void verticalPass_lpi4_8U(const uint8_t* src0[], const uint8_t* src1[],
uint8_t tmp[], const short beta[],
const int& length) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length >= half_nlanes);
v_int16 b0 = vx_setall_s16(beta[0]);
v_int16 b1 = vx_setall_s16(beta[1]);
v_int16 b2 = vx_setall_s16(beta[2]);
v_int16 b3 = vx_setall_s16(beta[3]);
v_uint8 shuf_mask = v_setr_s8(0, 8, 4, 12, 1, 9, 5, 13,
2, 10, 6, 14, 3, 11, 7, 15,
0, 8, 4, 12, 1, 9, 5, 13,
2, 10, 6, 14, 3, 11, 7, 15);
for (int w = 0; w < length; ) {
for (; w <= length - half_nlanes; w += half_nlanes) {
v_int16 val0_0 = v_load_ccache_expand(&src0[0][w]);
v_int16 val0_1 = v_load_ccache_expand(&src0[1][w]);
v_int16 val0_2 = v_load_ccache_expand(&src0[2][w]);
v_int16 val0_3 = v_load_ccache_expand(&src0[3][w]);
v_int16 val1_0 = v_load_ccache_expand(&src1[0][w]);
v_int16 val1_1 = v_load_ccache_expand(&src1[1][w]);
v_int16 val1_2 = v_load_ccache_expand(&src1[2][w]);
v_int16 val1_3 = v_load_ccache_expand(&src1[3][w]);
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), b0);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), b1);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), b2);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), b3);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_packus(r0, r1);
v_uint8 q1 = v_packus(r2, r3);
v_uint8 q2 = v_blend_shiftleft<0xCC /*0b11001100*/, 4>(q0, q1);
v_uint8 q3 = v_blend_shiftright<0xCC /*0b11001100*/, 4>(q0, q1);
v_uint8 q4 = v_shuffle_s8(q2, shuf_mask);
v_uint8 q5 = v_shuffle_s8(q3, shuf_mask);
v_uint8 q6 = v256_permute2x128<0x20>(q4, q5);
v_uint8 q7 = v256_permute2x128<0x31>(q4, q5);
vx_store(&tmp[4 * w + 0], q6);
vx_store(&tmp[4 * w + 2 * half_nlanes], q7);
}
if (w < length) {
w = length - half_nlanes;
}
}
}
CV_ALWAYS_INLINE v_uint8 setHorizontalShufMask1() {
return v_setr_s8(0, 4, 8, 12, 2, 6, 10, 14,
1, 5, 9, 13, 3, 7, 11, 15,
0, 4, 8, 12, 2, 6, 10, 14,
1, 5, 9, 13, 3, 7, 11, 15);
}
CV_ALWAYS_INLINE v_uint8 setHorizontalShufMask2() {
return v_setr_s8(0, 1, 8, 9, 2, 3, 10, 11,
4, 5, 12, 13, 6, 7, 14, 15,
0, 1, 8, 9, 2, 3, 10, 11,
4, 5, 12, 13, 6, 7, 14, 15);
}
CV_ALWAYS_INLINE void verticalPass_anylpi_8U(const uint8_t* src0[], const uint8_t* src1[],
uint8_t tmp[], const int& beta0,
const int l, const int length1, const int length2) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length1 >= half_nlanes);
for (int w = 0; w < length2; ) {
for (; w <= length1 - half_nlanes; w += half_nlanes) {
v_int16 s0 = v_reinterpret_as_s16(vx_load_expand(&src0[l][w]));
v_int16 s1 = v_reinterpret_as_s16(vx_load_expand(&src1[l][w]));
v_int16 t = v_mulhrs(s0 - s1, beta0) + s1;
v_pack_u_store(tmp + w, t);
}
if (w < length1) {
w = length1 - half_nlanes;
}
}
}
template<int chanNum>
CV_ALWAYS_INLINE bool calcRowLinear_8UC_Impl(avx2_tag,
std::array<std::array<uint8_t*, 4>, chanNum> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
if ((inSz.width * chanNum < half_nlanes) || (outSz.width < half_nlanes))
return false;
const int shift = (half_nlanes / 4);
if (4 == lpi) {
GAPI_DbgAssert(inSz.width*chanNum >= half_nlanes);
verticalPass_lpi4_8U(src0, src1, tmp, beta,
inSz.width*chanNum);
// horizontal pass
GAPI_DbgAssert(outSz.width >= half_nlanes);
//This variables are here to initialize them once. This variant don't affect performance.
v_uint8 val_0, val_1, val_2, val_3, res1, res2;
v_uint8 shuf_mask1 = setHorizontalShufMask1();
v_uint8 shuf_mask2 = setHorizontalShufMask2();
for (int x = 0; x < outSz.width; ) {
for (; x <= outSz.width - half_nlanes && x >= 0; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 4)]);
v_int16 a54 = vx_load(&clone[4 * (x + 8)]);
v_int16 a76 = vx_load(&clone[4 * (x + 12)]);
for (int c = 0; c < chanNum; ++c) {
v_gather_channel(val_0, tmp, mapsx, chanNum, c, x, 0);
v_gather_channel(val_1, tmp, mapsx, chanNum, c, x, shift);
v_gather_channel(val_2, tmp, mapsx, chanNum, c, x, shift * 2);
v_gather_channel(val_3, tmp, mapsx, chanNum, c, x, shift * 3);
main_computation_horizontalPass_lpi4(val_0, val_1, val_2, val_3,
a10, a32, a54, a76,
shuf_mask1, shuf_mask2,
res1, res2);
v_store_low(&dst[c][0][x], res1);
v_store_high(&dst[c][1][x], res1);
v_store_low(&dst[c][2][x], res2);
v_store_high(&dst[c][3][x], res2);
}
}
if (x < outSz.width) {
x = outSz.width - half_nlanes;
}
}
} else { // if any lpi
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
verticalPass_anylpi_8U(src0, src1, tmp, beta0, l,
inSz.width*chanNum, inSz.width*chanNum);
// horizontal pass
GAPI_DbgAssert(outSz.width >= half_nlanes);
for (int x = 0; x < outSz.width; ) {
for (; x <= outSz.width - half_nlanes && x >= 0; x += half_nlanes) {
for (int c = 0; c < chanNum; ++c) {
v_int16 a0 = vx_load(&alpha[x]); // as signed Q1.1.14
v_int16 sx = vx_load(&mapsx[x]); // as integer (int16)
v_int16 t0 = v_gather_chan<chanNum>(tmp, sx, c, 0);
v_int16 t1 = v_gather_chan<chanNum>(tmp, sx, c, 1);
v_int16 d = v_mulhrs(t0 - t1, a0) + t1;
v_pack_u_store(&dst[c][l][x], d);
}
}
if (x < outSz.width) {
x = outSz.width - half_nlanes;
}
}
}
}
return true;
}
CV_ALWAYS_INLINE void horizontalPass_lpi4_8UC1(const short clone[], const short mapsx[],
uint8_t tmp[], uint8_t* dst[], const int& length) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length >= half_nlanes);
v_uint8 val_0, val_1, val_2, val_3, res1, res2;
constexpr int shift = 4;
v_uint8 shuf_mask1 = avx::setHorizontalShufMask1();
v_uint8 shuf_mask2 = avx::setHorizontalShufMask2();
v_uint32 idxs = v_setr_s32(0, 2, 4, 6, 1, 3, 5, 7);
for (int x = 0; x < length; ) {
for (; x <= length - half_nlanes; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 4)]);
v_int16 a54 = vx_load(&clone[4 * (x + 8)]);
v_int16 a76 = vx_load(&clone[4 * (x + 12)]);
v_setr64(val_0, val_1, val_2, val_3, mapsx, tmp, x, shift);
val_0 = v_permute32(val_0, idxs);
val_1 = v_permute32(val_1, idxs);
val_2 = v_permute32(val_2, idxs);
val_3 = v_permute32(val_3, idxs);
avx::main_computation_horizontalPass_lpi4(val_0, val_1, val_2, val_3,
a10, a32, a54, a76,
shuf_mask1, shuf_mask2,
res1, res2);
v_store_low(&dst[0][x], res1);
v_store_high(&dst[1][x], res1);
v_store_low(&dst[2][x], res2);
v_store_high(&dst[3][x], res2);
}
if (x < length) {
x = length - half_nlanes;
}
}
}
CV_ALWAYS_INLINE void horizontalPass_anylpi_8U(const short alpha[], const short mapsx[],
uint8_t* dst[], const uchar tmp[], const int l,
const int length) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length >= half_nlanes);
v_int16 t0, t1;
for (int x = 0; x < length; ) {
for (; x <= length - half_nlanes; x += half_nlanes) {
v_int16 a0 = vx_load(&alpha[x]); // as signed Q1.1.14
v_int16 sx = vx_load(&mapsx[x]); // as integer (int16)
v_uint8 t = v_gather_pairs(tmp, sx); // 16 pairs of src0 pixels
v_deinterleave_expand(t, t0, t1); // tmp pixels as int16
v_int16 d = v_mulhrs(t0 - t1, a0) + t1;
v_pack_u_store(&dst[l][x], d);
}
if (x < length) {
x = length - half_nlanes;
}
}
}
} // namespace avx
// Resize (bi-linear, 8UC3)
template<>
bool calcRowLinear8UC3C4Impl<avx2_tag, 3>(avx2_tag,
std::array<std::array<uint8_t*, 4>, 3> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 3;
return avx::calcRowLinear_8UC_Impl<chanNum>(avx2_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// Resize (bi-linear, 8UC4)
template<>
bool calcRowLinear8UC3C4Impl<avx2_tag, 4>(avx2_tag,
std::array<std::array<uint8_t*, 4>, 4> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 4;
return avx::calcRowLinear_8UC_Impl<chanNum>(avx2_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// 8UC1 Resize (bi-linear)
template<>
bool calcRowLinear8UC1Impl(avx2_tag,
uint8_t* dst[],
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int) {
constexpr int nlanes = v_uint8::nlanes;
constexpr int half_nlanes = (v_uint8::nlanes / 2);
if (inSz.width < nlanes || outSz.width < half_nlanes)
return false;
bool xRatioEq = inSz.width == outSz.width;
bool yRatioEq = inSz.height == outSz.height;
if (!xRatioEq && !yRatioEq) {
if (4 == lpi) {
// vertical pass
avx::verticalPass_lpi4_8U(src0, src1, tmp, beta, inSz.width);
// horizontal pass
avx::horizontalPass_lpi4_8UC1(clone, mapsx, tmp, dst, outSz.width);
} else { // if any lpi
int inLength = inSz.width;
int outLength = outSz.width;
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
avx::verticalPass_anylpi_8U(src0, src1, tmp, beta0, l, inLength, inLength);
// horizontal pass
avx::horizontalPass_anylpi_8U(alpha, mapsx, dst, tmp, l, outLength);
}
} // if lpi == 4
} else if (!xRatioEq) {
GAPI_DbgAssert(yRatioEq);
if (4 == lpi) {
// vertical pass
GAPI_DbgAssert(inSz.width >= nlanes);
v_uint8 s0, s1, s2, s3;
for (int w = 0; w < inSz.width; ) {
for (; w <= inSz.width - nlanes; w += nlanes) {
s0 = vx_load(&src0[0][w]);
s1 = vx_load(&src0[1][w]);
s2 = vx_load(&src0[2][w]);
s3 = vx_load(&src0[3][w]);
v_store_interleave(&tmp[4 * w], s0, s1, s2, s3);
}
if (w < inSz.width) {
w = inSz.width - nlanes;
}
}
// horizontal pass
avx::horizontalPass_lpi4_8UC1(clone, mapsx, tmp, dst, outSz.width);
} else { // any LPI
for (int l = 0; l < lpi; ++l) {
const uchar* src = src0[l];
// horizontal pass
avx::horizontalPass_anylpi_8U(alpha, mapsx, dst, src, l, outSz.width);
}
}
} else if (!yRatioEq) {
GAPI_DbgAssert(xRatioEq);
int inLength = inSz.width;
int outLength = outSz.width;
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
avx::verticalPass_anylpi_8U(src0, src1, dst[l], beta0, l, inLength, outLength);
}
} else {
GAPI_DbgAssert(xRatioEq && yRatioEq);
int length = inSz.width;
for (int l = 0; l < lpi; ++l) {
memcpy(dst[l], src0[l], length);
}
}
return true;
}
template void chanToPlaneRowImpl(avx2_tag, const uint8_t* in, const int chan, const int chs, uint8_t* out, const int length);
template void chanToPlaneRowImpl(avx2_tag, const float* in, const int chan, const int chs, float* out, const int length);
template void nv12ToRgbRowImpl(avx2_tag, const uint8_t** y_rows, const uint8_t* uv_row,
uint8_t** out_rows, const int buf_width);
template void i420ToRgbRowImpl(avx2_tag, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template void splitRowImpl<avx2_tag, uint8_t, 2>(avx2_tag, const uint8_t* in, std::array<uint8_t*, 2>& outs, const int length);
template void splitRowImpl<avx2_tag, float, 2>(avx2_tag, const float* in, std::array<float*, 2>& outs, const int length);
template void splitRowImpl<avx2_tag, uint8_t, 3>(avx2_tag, const uint8_t* in, std::array<uint8_t*, 3>& outs, const int length);
template void splitRowImpl<avx2_tag, float, 3>(avx2_tag, const float* in, std::array<float*, 3>& outs, const int length);
template void splitRowImpl<avx2_tag, uint8_t, 4>(avx2_tag, const uint8_t* in, std::array<uint8_t*, 4>& outs, const int length);
template void splitRowImpl<avx2_tag, float, 4>(avx2_tag, const float* in, std::array<float*, 4>& outs, const int length);
template void mergeRowImpl<avx2_tag, uint8_t, 2>(avx2_tag, const std::array<const uint8_t*, 2>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx2_tag, float, 2>(avx2_tag, const std::array<const float*, 2>& ins, float* out, const int length);
template void mergeRowImpl<avx2_tag, uint8_t, 3>(avx2_tag, const std::array<const uint8_t*, 3>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx2_tag, float, 3>(avx2_tag, const std::array<const float*, 3>& ins, float* out, const int length);
template void mergeRowImpl<avx2_tag, uint8_t, 4>(avx2_tag, const std::array<const uint8_t*, 4>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx2_tag, float, 4>(avx2_tag, const std::array<const float*, 4>& ins, float* out, const int length);
template void calcRowLinear32FC1Impl(avx2_tag, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[],
const float beta[], const Size& inSz, const Size& outSz,
const int lpi, const int l);
template void calcRowAreaImpl<avx2_tag, uint8_t, Q0_16, short, Q8_8>(avx2_tag, uint8_t dst[], const uint8_t* src[], const Size& inSz,
const Size& outSz, Q0_16 yalpha, const MapperUnit8U &ymap,
int xmaxdf, const short xindex[], const Q0_16 xalpha[],
Q8_8 vbuf[]);
template void calcRowAreaImpl<avx2_tag, float, float, int, float>(avx2_tag, float dst[], const float *src[], const Size& inSz,
const Size& outSz, float yalpha, const MapperUnit32F& ymap,
int xmaxdf, const int xindex[], const float xalpha[],
float vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,86 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_gapi_kernels_impl.hpp"
#include <type_traits>
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace avx {
using C3 = std::integral_constant<int, 3>;
using C4 = std::integral_constant<int, 4>;
//----------------------------------------------------------------------
void calcRowArea_8U(uchar dst[], const uchar *src[], const Size &inSz, const Size &outSz,
Q0_16 yalpha, const MapperUnit8U& ymap, int xmaxdf, const short xindex[],
const Q0_16 xalpha[], Q8_8 vbuf[]);
void calcRowArea_32F(float dst[], const float *src[], const Size &inSz, const Size &outSz,
float yalpha, const MapperUnit32F& ymap, int xmaxdf, const int xindex[],
const float xalpha[], float vbuf[]);
#if USE_CVKL
void calcRowArea_CVKL_U8_SSE42(const uchar * src[],
uchar dst[],
const Size & inSz,
const Size & outSz,
int y,
const uint16_t xsi[],
const uint16_t ysi[],
const uint16_t xalpha[],
const uint16_t yalpha[],
int x_max_count,
int y_max_count,
uint16_t vert_sum[]);
#endif
} // namespace avx
template<typename isa_tag_t, typename T>
void chanToPlaneRowImpl(isa_tag_t, const T* in, const int chan, const int chs, T* out, const int length);
template<typename isa_tag_t>
void nv12ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* uv_row,
uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t>
void i420ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t, typename T, int chs>
void splitRowImpl(isa_tag_t, const T* in, std::array<T*, chs>& outs, const int length);
template<typename isa_tag_t, typename T, int chs>
void mergeRowImpl(isa_tag_t, const std::array<const T*, chs>& ins, T* out, const int length);
template<typename isa_tag_t>
bool calcRowLinear8UC1Impl(isa_tag_t, uint8_t* dst[], const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t>
void calcRowLinear32FC1Impl(isa_tag_t, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[],
const float beta[], const Size& inSz, const Size& outSz,
const int lpi, const int l);
template<typename isa_tag_t, int chs>
bool calcRowLinear8UC3C4Impl(isa_tag_t, std::array<std::array<uint8_t*, 4>, chs>& dst,
const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t, typename T, typename A, typename I, typename W>
void calcRowAreaImpl(isa_tag_t, T dst[], const T* src[], const Size& inSz,
const Size& outSz, A yalpha, const MapperUnit<A, I>& ymap,
int xmaxdf, const I xindex[], const A xalpha[], W vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,557 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <algorithm>
#include <utility>
#include "ie_preprocess_gapi_kernels_avx512.hpp"
#include <immintrin.h>
#ifdef CV_AVX512_SKX
#undef CV_AVX512_SKX
#endif
#define CV_AVX512_SKX 1
#define CV_CPU_HAS_SUPPORT_SSE2 1
#ifdef CV_SIMD512
#undef CV_SIMD512
#endif
#define CV_SIMD512 1
#include "opencv_hal_intrin.hpp"
#include "ie_preprocess_gapi_kernels_simd_impl.hpp"
using namespace cv;
#if defined __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wstrict-overflow"
#endif
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace avx512 {
CV_ALWAYS_INLINE void verticalPass_lpi4_8U(const uint8_t* src0[], const uint8_t* src1[],
uint8_t tmp[], const short beta[], const v_uint8& shuf_mask,
const int width) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(width >= half_nlanes);
v_int16 b0 = vx_setall_s16(beta[0]);
v_int16 b1 = vx_setall_s16(beta[1]);
v_int16 b2 = vx_setall_s16(beta[2]);
v_int16 b3 = vx_setall_s16(beta[3]);
v_uint32 permute_idxs1 = v_set_s32(23, 21, 7, 5, 22, 20, 6, 4, 19, 17, 3, 1, 18, 16, 2, 0);
v_uint32 permute_idxs2 = v_set_s32(31, 29, 15, 13, 30, 28, 14, 12, 27, 25, 11, 9, 26, 24, 10, 8);
for (int w = 0; w < width; ) {
for (; w <= width - half_nlanes; w += half_nlanes) {
v_int16 val0_0 = v_load_ccache_expand(&src0[0][w]);
v_int16 val0_1 = v_load_ccache_expand(&src0[1][w]);
v_int16 val0_2 = v_load_ccache_expand(&src0[2][w]);
v_int16 val0_3 = v_load_ccache_expand(&src0[3][w]);
v_int16 val1_0 = v_load_ccache_expand(&src1[0][w]);
v_int16 val1_1 = v_load_ccache_expand(&src1[1][w]);
v_int16 val1_2 = v_load_ccache_expand(&src1[2][w]);
v_int16 val1_3 = v_load_ccache_expand(&src1[3][w]);
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), b0);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), b1);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), b2);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), b3);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_packus(r0, r1);
v_uint8 q1 = v_packus(r2, r3);
v_uint8 q2 = v_permutex2_s32(q0, q1, permute_idxs1);
v_uint8 q3 = v_permutex2_s32(q0, q1, permute_idxs2);
v_uint8 q4 = v_shuffle_s8(q2, shuf_mask);
v_uint8 q5 = v_shuffle_s8(q3, shuf_mask);
vx_store(&tmp[4 * w + 0], q4);
vx_store(&tmp[4 * w + 2 * half_nlanes], q5);
}
if (w < width) {
w = width - half_nlanes;
}
}
}
CV_ALWAYS_INLINE void main_computation_horizontalPass_lpi4(const v_uint8& val_0,
const v_uint8& val_1,
const v_uint8& val_2,
const v_uint8& val_3,
const v_int16& a10,
const v_int16& a32,
const v_int16& a54,
const v_int16& a76,
v_uint8& shuf_mask1,
v_uint8& shuf_mask2,
v_uint32& idxs1,
v_uint32& idxs2,
v_uint8& res1, v_uint8& res2) {
v_int16 val0_0 = v_reinterpret_as_s16(v_expand_low(val_0));
v_int16 val0_1 = v_reinterpret_as_s16(v_expand_low(val_1));
v_int16 val0_2 = v_reinterpret_as_s16(v_expand_low(val_2));
v_int16 val0_3 = v_reinterpret_as_s16(v_expand_low(val_3));
v_int16 val1_0 = v_reinterpret_as_s16(v_expand_high(val_0));
v_int16 val1_1 = v_reinterpret_as_s16(v_expand_high(val_1));
v_int16 val1_2 = v_reinterpret_as_s16(v_expand_high(val_2));
v_int16 val1_3 = v_reinterpret_as_s16(v_expand_high(val_3));
v_int16 t0 = v_mulhrs(v_sub_wrap(val0_0, val1_0), a10);
v_int16 t1 = v_mulhrs(v_sub_wrap(val0_1, val1_1), a32);
v_int16 t2 = v_mulhrs(v_sub_wrap(val0_2, val1_2), a54);
v_int16 t3 = v_mulhrs(v_sub_wrap(val0_3, val1_3), a76);
v_int16 r0 = v_add_wrap(val1_0, t0);
v_int16 r1 = v_add_wrap(val1_1, t1);
v_int16 r2 = v_add_wrap(val1_2, t2);
v_int16 r3 = v_add_wrap(val1_3, t3);
v_uint8 q0 = v_packus(r0, r1);
v_uint8 q1 = v_packus(r2, r3);
v_uint8 q2 = v_shuffle_s8(q0, shuf_mask1);
v_uint8 q3 = v_shuffle_s8(q1, shuf_mask1);
v_uint8 q4 = v_permutex2_s32(q2, q3, idxs1);
v_uint8 q5 = v_permutex2_s32(q2, q3, idxs2);
res1 = v_shuffle_s8(q4, shuf_mask2);
res2 = v_shuffle_s8(q5, shuf_mask2);
}
CV_ALWAYS_INLINE void verticalPass_anylpi_8U(const uint8_t* src0[], const uint8_t* src1[],
uint8_t tmp[], const int beta0,
const int l, const int length1, const int length2) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length1 >= half_nlanes);
for (int w = 0; w < length2; ) {
for (; w <= length1 - half_nlanes; w += half_nlanes) {
v_int16 s0 = v_reinterpret_as_s16(vx_load_expand(&src0[l][w]));
v_int16 s1 = v_reinterpret_as_s16(vx_load_expand(&src1[l][w]));
v_int16 t = v_mulhrs(s0 - s1, beta0) + s1;
v_pack_u_store(tmp + w, t);
}
if (w < length1) {
w = length1 - half_nlanes;
}
}
}
// Resize (bi-linear, 8U, generic number of channels)
template<int chanNum>
CV_ALWAYS_INLINE bool calcRowLinear_8UC_Impl(avx512_tag,
std::array<std::array<uint8_t*, 4>, chanNum> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
if ((inSz.width * chanNum < half_nlanes) || (outSz.width < half_nlanes))
return false;
constexpr int shift = (half_nlanes / 4);
if (4 == lpi) {
GAPI_DbgAssert(inSz.width >= half_nlanes);
v_uint8 shuf_mask1 = v_setr_s8(0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15);
// vertical pass
verticalPass_lpi4_8U(src0, src1, tmp, beta,
shuf_mask1, inSz.width*chanNum);
// horizontal pass
v_uint8 val_0, val_1, val_2, val_3, res1, res2;
v_uint8 shuf_mask2 = v_setr_s8(0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15);
v_uint32 idxs3 = v_set_s32(29, 25, 21, 17, 13, 9, 5, 1, 28, 24, 20, 16, 12, 8, 4, 0);
v_uint32 idxs4 = v_set_s32(31, 27, 23, 19, 15, 11, 7, 3, 30, 26, 22, 18, 14, 10, 6, 2);
GAPI_DbgAssert(outSz.width >= half_nlanes);
for (int x = 0; x < outSz.width; ) {
for (; x <= outSz.width - half_nlanes && x >= 0; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 8)]);
v_int16 a54 = vx_load(&clone[4 * (x + 16)]);
v_int16 a76 = vx_load(&clone[4 * (x + 24)]);
for (int c = 0; c < chanNum; ++c) {
v_gather_channel(val_0, tmp, mapsx, chanNum, c, x, 0);
v_gather_channel(val_1, tmp, mapsx, chanNum, c, x, shift);
v_gather_channel(val_2, tmp, mapsx, chanNum, c, x, shift * 2);
v_gather_channel(val_3, tmp, mapsx, chanNum, c, x, shift * 3);
main_computation_horizontalPass_lpi4(val_0, val_1, val_2, val_3,
a10, a32, a54, a76,
shuf_mask1, shuf_mask2,
idxs3, idxs4,
res1, res2);
v_store_low(&dst[c][0][x], res1);
v_store_high(&dst[c][1][x], res1);
v_store_low(&dst[c][2][x], res2);
v_store_high(&dst[c][3][x], res2);
}
}
if (x < outSz.width) {
x = outSz.width - half_nlanes;
}
}
} else { // if any lpi
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
GAPI_DbgAssert(inSz.width*chanNum >= half_nlanes);
verticalPass_anylpi_8U(src0, src1, tmp, beta0, l,
inSz.width*chanNum, inSz.width*chanNum);
// horizontal pass
GAPI_DbgAssert(outSz.width >= half_nlanes);
for (int x = 0; x < outSz.width; ) {
for (; x <= outSz.width - half_nlanes && x >= 0; x += half_nlanes) {
for (int c = 0; c < chanNum; ++c) {
v_int16 a0 = vx_load(&alpha[x]); // as signed Q1.1.14
v_int16 sx = vx_load(&mapsx[x]); // as integer (int16)
v_int16 t0 = v_gather_chan<chanNum>(tmp, sx, c, 0);
v_int16 t1 = v_gather_chan<chanNum>(tmp, sx, c, 1);
v_int16 d = v_mulhrs(t0 - t1, a0) + t1;
v_pack_u_store(&dst[c][l][x], d);
}
}
if (x < outSz.width) {
x = outSz.width - half_nlanes;
}
}
}
}
return true;
}
CV_ALWAYS_INLINE void horizontalPass_lpi4_U8C1(const short clone[], const short mapsx[],
uint8_t tmp[], uint8_t* dst[],
v_uint8& shuf_mask1,
const int width) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(width >= half_nlanes);
v_uint8 shuf_mask2 = v_setr_s8(0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15,
0, 1, 4, 5, 8, 9, 12, 13,
2, 3, 6, 7, 10, 11, 14, 15);
v_uint32 permute_idxs1 = v_set_s32(15, 13, 11, 9, 7, 5, 3, 1, 14, 12, 10, 8, 6, 4, 2, 0);
v_uint32 permute_idxs2 = v_set_s32(29, 25, 21, 17, 13, 9, 5, 1, 28, 24, 20, 16, 12, 8, 4, 0);
v_uint32 permute_idxs3 = v_set_s32(31, 27, 23, 19, 15, 11, 7, 3, 30, 26, 22, 18, 14, 10, 6, 2);
v_uint8 val_0, val_1, val_2, val_3, res1, res2;
const int shift = half_nlanes / 4;
for (int x = 0; x < width; ) {
for (; x <= width - half_nlanes; x += half_nlanes) {
v_int16 a10 = vx_load(&clone[4 * x]);
v_int16 a32 = vx_load(&clone[4 * (x + 8)]);
v_int16 a54 = vx_load(&clone[4 * (x + 16)]);
v_int16 a76 = vx_load(&clone[4 * (x + 24)]);
v_set(val_0, val_1, val_2, val_3, tmp, mapsx, x, shift);
val_0 = v_permute32(val_0, permute_idxs1);
val_1 = v_permute32(val_1, permute_idxs1);
val_2 = v_permute32(val_2, permute_idxs1);
val_3 = v_permute32(val_3, permute_idxs1);
main_computation_horizontalPass_lpi4(val_0, val_1, val_2, val_3,
a10, a32, a54, a76,
shuf_mask1, shuf_mask2,
permute_idxs2, permute_idxs3,
res1, res2);
v_store_low(&dst[0][x], res1);
v_store_high(&dst[1][x], res1);
v_store_low(&dst[2][x], res2);
v_store_high(&dst[3][x], res2);
}
if (x < width) {
x = width - half_nlanes;
}
}
}
CV_ALWAYS_INLINE void horizontalPass_anylpi_8U(const short alpha[], const short mapsx[],
uint8_t* dst[], const uchar tmp[], const int l,
const int length) {
constexpr int half_nlanes = (v_uint8::nlanes / 2);
GAPI_DbgAssert(length >= half_nlanes);
v_int16 t0, t1;
for (int x = 0; x < length; ) {
for (; x <= length - half_nlanes; x += half_nlanes) {
v_int16 a0 = vx_load(&alpha[x]); // as signed Q1.1.14
v_int16 sx = vx_load(&mapsx[x]); // as integer (int16)
v_uint8 t = v_gather_pairs(tmp, sx);
v_deinterleave_expand(t, t0, t1); // tmp pixels as int16
v_int16 d = v_mulhrs(t0 - t1, a0) + t1;
v_pack_u_store(&dst[l][x], d);
}
if (x < length) {
x = length - half_nlanes;
}
}
}
} // namespace avx512
// Resize (bi-linear, 8UC3)
template<>
bool calcRowLinear8UC3C4Impl<avx512_tag, 3>(avx512_tag,
std::array<std::array<uint8_t*, 4>, 3> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 3;
return avx512::calcRowLinear_8UC_Impl<chanNum>(avx512_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// Resize (bi-linear, 8UC4)
template<>
bool calcRowLinear8UC3C4Impl<avx512_tag, 4>(avx512_tag,
std::array<std::array<uint8_t*, 4>, 4> &dst,
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int ) {
constexpr int chanNum = 4;
return avx512::calcRowLinear_8UC_Impl<chanNum>(avx512_tag{}, dst, src0, src1, alpha, clone, mapsx, beta, tmp, inSz, outSz, lpi);
}
// 8UC1 Resize (bi-linear)
template<>
bool calcRowLinear8UC1Impl(avx512_tag,
uint8_t* dst[],
const uint8_t* src0[],
const uint8_t* src1[],
const short alpha[],
const short clone[], // 4 clones of alpha
const short mapsx[],
const short beta[],
uint8_t tmp[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int) {
constexpr int nlanes = v_uint8::nlanes;
constexpr int half_nlanes = (v_uint8::nlanes / 2);
if (inSz.width < nlanes || outSz.width < half_nlanes)
return false;
bool xRatioEq = inSz.width == outSz.width;
bool yRatioEq = inSz.height == outSz.height;
if (!xRatioEq && !yRatioEq) {
if (4 == lpi) {
v_uint8 shuf_mask1 = v_setr_s8(0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15);
// vertical pass
avx512::verticalPass_lpi4_8U(src0, src1, tmp, beta, shuf_mask1, inSz.width);
// horizontal pass
avx512::horizontalPass_lpi4_U8C1(clone, mapsx, tmp, dst, shuf_mask1,
outSz.width);
} else { // if any lpi
int inLength = inSz.width;
int outLength = outSz.width;
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
avx512::verticalPass_anylpi_8U(src0, src1, tmp, beta0, l, inLength, inLength);
// horizontal pass
avx512::horizontalPass_anylpi_8U(alpha, mapsx, dst, tmp, l, outLength);
}
} // if lpi == 4
} else if (!xRatioEq) {
GAPI_DbgAssert(yRatioEq);
if (4 == lpi) {
// vertical pass
GAPI_DbgAssert(inSz.width >= nlanes);
for (int w = 0; w < inSz.width; ) {
for (; w <= inSz.width - nlanes; w += nlanes) {
v_uint8 s0, s1, s2, s3;
s0 = vx_load(&src0[0][w]);
s1 = vx_load(&src0[1][w]);
s2 = vx_load(&src0[2][w]);
s3 = vx_load(&src0[3][w]);
v_store_interleave(&tmp[4 * w], s0, s1, s2, s3);
}
if (w < inSz.width) {
w = inSz.width - nlanes;
}
}
// horizontal pass
v_uint8 shuf_mask1 = v_setr_s8(0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15,
0, 4, 8, 12, 1, 5, 9, 13,
2, 6, 10, 14, 3, 7, 11, 15);
avx512::horizontalPass_lpi4_U8C1(clone, mapsx, tmp, dst, shuf_mask1,
outSz.width);
} else { // any LPI
for (int l = 0; l < lpi; ++l) {
const uchar* src = src0[l];
// horizontal pass
avx512::horizontalPass_anylpi_8U(alpha, mapsx, dst, src, l, outSz.width);
}
}
} else if (!yRatioEq) {
GAPI_DbgAssert(xRatioEq);
int inLength = inSz.width;
int outLength = outSz.width;
for (int l = 0; l < lpi; ++l) {
short beta0 = beta[l];
// vertical pass
avx512::verticalPass_anylpi_8U(src0, src1, dst[l], beta0, l, inLength, outLength);
}
} else {
GAPI_DbgAssert(xRatioEq && yRatioEq);
int length = inSz.width;
for (int l = 0; l < lpi; ++l) {
memcpy(dst[l], src0[l], length);
}
}
return true;
}
template void chanToPlaneRowImpl(avx512_tag, const uint8_t* in, const int chan, const int chs, uint8_t* out, const int length);
template void chanToPlaneRowImpl(avx512_tag, const float* in, const int chan, const int chs, float* out, const int length);
template void nv12ToRgbRowImpl(avx512_tag, const uint8_t** y_rows, const uint8_t* uv_row, uint8_t** out_rows, const int buf_width);
template void i420ToRgbRowImpl(avx512_tag, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template void splitRowImpl<avx512_tag, uint8_t, 2>(avx512_tag, const uint8_t* in, std::array<uint8_t*, 2>& outs, const int length);
template void splitRowImpl<avx512_tag, float, 2>(avx512_tag, const float* in, std::array<float*, 2>& outs, const int length);
template void splitRowImpl<avx512_tag, uint8_t, 3>(avx512_tag, const uint8_t* in, std::array<uint8_t*, 3>& outs, const int length);
template void splitRowImpl<avx512_tag, float, 3>(avx512_tag, const float* in, std::array<float*, 3>& outs, const int length);
template void splitRowImpl<avx512_tag, uint8_t, 4>(avx512_tag, const uint8_t* in, std::array<uint8_t*, 4>& outs, const int length);
template void splitRowImpl<avx512_tag, float, 4>(avx512_tag, const float* in, std::array<float*, 4>& outs, const int length);
template void mergeRowImpl<avx512_tag, uint8_t, 2>(avx512_tag, const std::array<const uint8_t*, 2>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx512_tag, float, 2>(avx512_tag, const std::array<const float*, 2>& ins, float* out, const int length);
template void mergeRowImpl<avx512_tag, uint8_t, 3>(avx512_tag, const std::array<const uint8_t*, 3>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx512_tag, float, 3>(avx512_tag, const std::array<const float*, 3>& ins, float* out, const int length);
template void mergeRowImpl<avx512_tag, uint8_t, 4>(avx512_tag, const std::array<const uint8_t*, 4>& ins, uint8_t* out, const int length);
template void mergeRowImpl<avx512_tag, float, 4>(avx512_tag, const std::array<const float*, 4>& ins, float* out, const int length);
template void calcRowLinear32FC1Impl(avx512_tag, float* dst[], const float* src0[],
const float* src1[], const float alpha[],
const int mapsx[], const float beta[],
const Size& inSz, const Size& outSz,
const int lpi, const int l);
template void calcRowAreaImpl<avx512_tag, uint8_t, Q0_16, short, Q8_8>(avx512_tag, uint8_t dst[], const uint8_t* src[], const Size& inSz,
const Size& outSz, Q0_16 yalpha, const MapperUnit8U &ymap,
int xmaxdf, const short xindex[], const Q0_16 xalpha[],
Q8_8 vbuf[]);
template void calcRowAreaImpl<avx512_tag, float, float, int, float>(avx512_tag, float dst[], const float *src[], const Size& inSz,
const Size& outSz, float yalpha, const MapperUnit32F& ymap,
int xmaxdf, const int xindex[], const float xalpha[],
float vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,85 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_gapi_kernels_impl.hpp"
#include <type_traits>
namespace InferenceEngine {
namespace gapi {
namespace kernels {
namespace avx512 {
using C3 = std::integral_constant<int, 3>;
using C4 = std::integral_constant<int, 4>;
//-----------------------------------------------------------------------------
void calcRowArea_8U(uchar dst[], const uchar *src[], const Size &inSz, const Size &outSz,
Q0_16 yalpha, const MapperUnit8U& ymap, int xmaxdf, const short xindex[],
const Q0_16 xalpha[], Q8_8 vbuf[]);
void calcRowArea_32F(float dst[], const float *src[], const Size &inSz, const Size &outSz,
float yalpha, const MapperUnit32F& ymap, int xmaxdf, const int xindex[],
const float xalpha[], float vbuf[]);
#if USE_CVKL
void calcRowArea_CVKL_U8(const uchar * src[],
uchar dst[],
const Size & inSz,
const Size & outSz,
int y,
const uint16_t xsi[],
const uint16_t ysi[],
const uint16_t xalpha[],
const uint16_t yalpha[],
int x_max_count,
int y_max_count,
uint16_t vert_sum[]);
#endif
} // namespace avx512
template<typename isa_tag_t, typename T>
void chanToPlaneRowImpl(isa_tag_t, const T* in, const int chan, const int chs, T* out, const int length);
template<typename isa_tag_t>
void nv12ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* uv_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t>
void i420ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t, typename T, int chs>
void splitRowImpl(isa_tag_t, const T* in, std::array<T*, chs>& outs, const int length);
template<typename isa_tag_t, typename T, int chs>
void mergeRowImpl(isa_tag_t, const std::array<const T*, chs>& ins, T* out, const int length);
template<typename isa_tag_t>
bool calcRowLinear8UC1Impl(isa_tag_t, uint8_t* dst[], const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t>
void calcRowLinear32FC1Impl(isa_tag_t, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[],
const float beta[], const Size& inSz, const Size& outSz,
const int lpi, const int l);
template<typename isa_tag_t, int chs>
bool calcRowLinear8UC3C4Impl(isa_tag_t, std::array<std::array<uint8_t*, 4>, chs>& dst,
const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t, typename T, typename A, typename I, typename W>
void calcRowAreaImpl(isa_tag_t, T dst[], const T* src[], const Size& inSz,
const Size& outSz, A yalpha, const MapperUnit<A, I>& ymap,
int xmaxdf, const I xindex[], const A xalpha[], W vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,85 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_gapi_kernels_impl.hpp"
#include <type_traits>
namespace InferenceEngine {
namespace gapi {
namespace kernels {
using C3 = std::integral_constant<int, 3>;
using C4 = std::integral_constant<int, 4>;
//----------------------------------------------------------------------
void calcRowArea_8U(uchar dst[], const uchar *src[], const Size &inSz, const Size &outSz,
Q0_16 yalpha, const MapperUnit8U& ymap, int xmaxdf, const short xindex[], const Q0_16 xalpha[],
Q8_8 vbuf[]);
void calcRowArea_32F(float dst[], const float *src[], const Size &inSz, const Size &outSz,
float yalpha, const MapperUnit32F& ymap, int xmaxdf, const int xindex[], const float xalpha[],
float vbuf[]);
#if USE_CVKL
void calcRowArea_CVKL_U8_SSE42(const uchar * src[],
uchar dst[],
const Size & inSz,
const Size & outSz,
int y,
const uint16_t xsi[],
const uint16_t ysi[],
const uint16_t xalpha[],
const uint16_t yalpha[],
int x_max_count,
int y_max_count,
uint16_t vert_sum[]);
#endif
//----------------------------------------------------------------------
template<typename isa_tag_t, typename T>
void chanToPlaneRowImpl(isa_tag_t, const T* in, const int chan, const int chs,
T* out, const int length);
template<typename isa_tag_t>
void nv12ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* uv_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t>
void i420ToRgbRowImpl(isa_tag_t, const uint8_t** y_rows, const uint8_t* u_row,
const uint8_t* v_row, uint8_t** out_rows, const int buf_width);
template<typename isa_tag_t, typename T, int chs>
void splitRowImpl(isa_tag_t, const T* in, std::array<T*, chs>& outs, const int length);
template<typename isa_tag_t, typename T, int chs>
void mergeRowImpl(isa_tag_t, const std::array<const T*, chs>& ins, T* out, const int length);
template<typename isa_tag_t>
bool calcRowLinear8UC1Impl(isa_tag_t, uint8_t* dst[], const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t>
void calcRowLinear32FC1Impl(isa_tag_t, float* dst[], const float* src0[], const float* src1[],
const float alpha[], const int mapsx[],
const float beta[], const Size& inSz, const Size& outSz,
const int lpi, const int l);
template<typename isa_tag_t, int chs>
bool calcRowLinear8UC3C4Impl(isa_tag_t, std::array<std::array<uint8_t*, 4>, chs>& dst,
const uint8_t* src0[], const uint8_t* src1[],
const short alpha[], const short clone[], const short mapsx[],
const short beta[], uint8_t tmp[], const Size& inSz,
const Size& outSz, const int lpi, const int l);
template<typename isa_tag_t, typename T, typename A, typename I, typename W>
void calcRowAreaImpl(isa_tag_t, T dst[], const T* src[], const Size& inSz,
const Size& outSz, A yalpha, const MapperUnit<A, I>& ymap,
int xmaxdf, const I xindex[], const A xalpha[], W vbuf[]);
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,79 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "ie_preprocess_gapi.hpp"
#include "ie_system_conf.h"
#include "ie_preprocess_data.hpp"
#include "ie_preprocess_itt.hpp"
#include "debug.h"
#include <ie_input_info.hpp>
#include <memory>
namespace InferenceEngine {
IE_SUPPRESS_DEPRECATED_START
/**
* @brief This class stores pre-process information for exact input
*/
class PreProcessData : public IPreProcessData {
/**
* @brief ROI blob.
*/
Blob::Ptr _userBlob = nullptr;
/**
* @brief Pointer-to-implementation (PIMPL) hiding preprocessing implementation details.
* BEWARE! Will be shared among copies!
*/
std::shared_ptr<PreprocEngine> _preproc;
public:
void setRoiBlob(const Blob::Ptr &blob) override;
Blob::Ptr getRoiBlob() const override;
void execute(Blob::Ptr &preprocessedBlob, const PreProcessInfo &info, bool serial, int batchSize = -1) override;
void isApplicable(const Blob::Ptr &src, const Blob::Ptr &dst) override;
};
void CreatePreProcessData(std::shared_ptr<IPreProcessData>& data) {
data = std::make_shared<PreProcessData>();
}
void PreProcessData::setRoiBlob(const Blob::Ptr &blob) {
_userBlob = blob;
}
Blob::Ptr PreProcessData::getRoiBlob() const {
return _userBlob;
}
void PreProcessData::execute(Blob::Ptr &preprocessedBlob, const PreProcessInfo &info, bool serial,
int batchSize) {
OV_ITT_SCOPED_TASK(itt::domains::IEPreproc, "Preprocessing");
auto algorithm = info.getResizeAlgorithm();
auto fmt = info.getColorFormat();
if (_userBlob == nullptr || preprocessedBlob == nullptr) {
IE_THROW() << "Input pre-processing is called with null " << (_userBlob == nullptr ? "_userBlob" : "preprocessedBlob");
}
batchSize = PreprocEngine::getCorrectBatchSize(batchSize, _userBlob);
if (!_preproc) {
_preproc.reset(new PreprocEngine);
}
_preproc->preprocessWithGAPI(_userBlob, preprocessedBlob, algorithm, fmt, serial, batchSize);
}
void PreProcessData::isApplicable(const Blob::Ptr &src, const Blob::Ptr &dst) {
PreprocEngine::checkApplicabilityGAPI(src, dst);
}
} // namespace InferenceEngine

View File

@ -1,137 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <map>
#include <string>
#include <memory>
#include "openvino/runtime/common.hpp"
#include "openvino/util/file_util.hpp"
#include "openvino/util/shared_object.hpp"
#include <ie_blob.h>
#include <file_utils.h>
#include <ie_preprocess.hpp>
#include "ie_version.hpp"
namespace InferenceEngine {
IE_SUPPRESS_DEPRECATED_START
/**
* @brief This class stores pre-process information for exact input
*/
class IPreProcessData : public std::enable_shared_from_this<IPreProcessData> {
public:
/**
* @brief Sets ROI blob to be resized and placed to the default input blob during pre-processing.
* @param blob ROI blob.
*/
virtual void setRoiBlob(const Blob::Ptr &blob) = 0;
/**
* @brief Gets pointer to the ROI blob used for a given input.
* @return Blob pointer.
*/
virtual Blob::Ptr getRoiBlob() const = 0;
/**
* @brief Executes input pre-processing with a given pre-processing information.
* @param outBlob pre-processed output blob to be used for inference.
* @param info pre-processing info that specifies resize algorithm and color format.
* @param serial disable OpenMP threading if the value set to true.
* @param batchSize batch size for pre-processing.
*/
virtual void execute(Blob::Ptr &preprocessedBlob, const PreProcessInfo& info, bool serial, int batchSize = -1) = 0;
virtual void isApplicable(const Blob::Ptr &src, const Blob::Ptr &dst) = 0;
protected:
virtual ~IPreProcessData() = default;
};
OPENVINO_PLUGIN_API void CreatePreProcessData(std::shared_ptr<IPreProcessData>& data);
#define OV_PREPROC_PLUGIN_CALL_STATEMENT(...) \
if (!_ptr) \
IE_THROW() << "Wrapper used in the OV_PREPROC_PLUGIN_CALL_STATEMENT was not initialized."; \
try { \
__VA_ARGS__; \
} catch (...) { \
::InferenceEngine::details::Rethrow(); \
}
class PreProcessDataPlugin {
std::shared_ptr<void> _so = nullptr;
std::shared_ptr<IPreProcessData> _ptr = nullptr;
public:
PreProcessDataPlugin() {
#ifdef OPENVINO_STATIC_LIBRARY
# ifdef ENABLE_GAPI_PREPROCESSING
CreatePreProcessData(_ptr);
if (!_ptr)
IE_THROW() << "Failed to create IPreProcessData for G-API based preprocessing";
# else
IE_THROW() << "OpenVINO Runtime is compiled without G-API preprocessing support.\n"
"Use 'cmake -DENABLE_GAPI_PREPROCESSING=ON ...'";
# endif // ENABLE_GAPI_PREPROCESSING
#else
// preprocessing plugin can be found in the following locations
// 1. in openvino-X.Y.Z location relative to libopenvino.so
// 2. in the same folder as libopenvino.so
ov::util::FilePath ovLibraryPath = getInferenceEngineLibraryPath();
ov::util::FilePath libraryName = ov::util::to_file_path(std::string("openvino_gapi_preproc") + std::string(OV_BUILD_POSTFIX));
libraryName = FileUtils::makePluginLibraryName({}, libraryName);
std::ostringstream str;
str << "openvino-" << IE_VERSION_MAJOR << "." << IE_VERSION_MINOR << "." << IE_VERSION_PATCH;
ov::util::FilePath ovLibraryPathPlusOV = FileUtils::makePath(ovLibraryPath, ov::util::to_file_path(str.str()));
const ov::util::FilePath preprocLibraryPathPlusOV = FileUtils::makePath(ovLibraryPathPlusOV, libraryName);
const ov::util::FilePath preprocLibraryPath = FileUtils::makePath(ovLibraryPath, libraryName);
const bool existsInOV = FileUtils::fileExist(preprocLibraryPathPlusOV);
const bool existsInLib = FileUtils::fileExist(preprocLibraryPath);
if (!existsInOV && !existsInLib) {
IE_THROW() << "Please, make sure that pre-processing library "
<< ov::util::from_file_path(libraryName) << " is in "
<< ov::util::from_file_path(preprocLibraryPathPlusOV) << " or " << ov::util::from_file_path(preprocLibraryPath);
}
using CreateF = void(std::shared_ptr<IPreProcessData>& data);
_so = ov::util::load_shared_object(existsInOV ? preprocLibraryPathPlusOV.c_str() : preprocLibraryPath.c_str());
reinterpret_cast<CreateF *>(ov::util::get_symbol(_so, "CreatePreProcessData"))(_ptr);
#endif
}
void setRoiBlob(const Blob::Ptr &blob) {
OV_PREPROC_PLUGIN_CALL_STATEMENT(_ptr->setRoiBlob(blob));
}
Blob::Ptr getRoiBlob() const {
OV_PREPROC_PLUGIN_CALL_STATEMENT(return _ptr->getRoiBlob());
}
void execute(Blob::Ptr &preprocessedBlob, const PreProcessInfo& info, bool serial, int batchSize = -1) {
OV_PREPROC_PLUGIN_CALL_STATEMENT(_ptr->execute(preprocessedBlob, info, serial, batchSize));
}
void isApplicable(const Blob::Ptr &src, const Blob::Ptr &dst) {
OV_PREPROC_PLUGIN_CALL_STATEMENT(_ptr->isApplicable(src, dst));
}
};
#undef OV_PREPROC_PLUGIN_CALL_STATEMENT
using PreProcessDataPtr = std::shared_ptr<PreProcessDataPlugin>;
inline PreProcessDataPtr CreatePreprocDataHelper() {
return std::make_shared<PreProcessDataPlugin>();
}
IE_SUPPRESS_DEPRECATED_END
} // namespace InferenceEngine

View File

@ -1,872 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <utility>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <tuple>
#include <string>
#include <unordered_map>
#include <functional>
// Careful reader, don't worry -- it is not the whole OpenCV,
// it is just a single stand-alone component of it
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/util/util.hpp>
#include "ie_blob.h"
#include "ie_compound_blob.h"
#include "ie_input_info.hpp"
#include "ie_preprocess_gapi.hpp"
#include "ie_preprocess_gapi_kernels.hpp"
#include "ie_preprocess_itt.hpp"
#include "debug.h"
#include "ie_parallel.hpp"
#include <opencv2/gapi/fluid/gfluidkernel.hpp> // GFluidOutputRois
IE_SUPPRESS_DEPRECATED_START
namespace InferenceEngine {
namespace {
int get_cv_depth(const TensorDesc &ie_desc);
namespace G {
struct Strides {int N; int C; int H; int W;};
struct Dims {int N; int C; int H; int W;};
struct Desc {Dims d; Strides s; int prec;};
void fix_strides_nhwc(const Dims &d, Strides &s) {
if (s.W > d.C) {
s.C = 1;
s.W = s.C*d.C;
s.H = s.W*d.W;
s.N = s.H*d.H;
}
}
Desc decompose(const TensorDesc& ie_desc) {
const auto& ie_blk_desc = ie_desc.getBlockingDesc();
const auto& ie_dims = ie_desc.getDims();
const auto& ie_strides = ie_blk_desc.getStrides();
const bool nhwc_layout = ie_desc.getLayout() == NHWC;
Dims d = {
static_cast<int>(ie_dims[0]),
static_cast<int>(ie_dims[1]),
static_cast<int>(ie_dims[2]),
static_cast<int>(ie_dims[3])
};
Strides s = {
static_cast<int>(ie_strides[0]),
static_cast<int>(nhwc_layout ? ie_strides[3] : ie_strides[1]),
static_cast<int>(nhwc_layout ? ie_strides[1] : ie_strides[2]),
static_cast<int>(nhwc_layout ? ie_strides[2] : ie_strides[3]),
};
if (nhwc_layout) fix_strides_nhwc(d, s);
return Desc{d, s, get_cv_depth(ie_desc)};
}
Desc decompose(const Blob::Ptr& blob) {
return decompose(blob->getTensorDesc());
}
} // namespace G
inline int get_cv_depth(const TensorDesc &ie_desc) {
switch (ie_desc.getPrecision()) {
case Precision::U8: return CV_8U;
case Precision::FP32: return CV_32F;
case Precision::U16: return CV_16U;
case Precision::I16: return CV_16S;
case Precision::FP16: return CV_16F;
default: IE_THROW() << "Unsupported data type";
}
}
std::vector<std::vector<cv::gapi::own::Mat>> bind_to_blob(const Blob::Ptr& blob,
int batch_size) {
const auto& ie_desc = blob->getTensorDesc();
const auto& ie_desc_blk = ie_desc.getBlockingDesc();
const auto desc = G::decompose(blob);
const auto cv_depth = get_cv_depth(ie_desc);
const auto stride = desc.s.H*blob->element_size();
const auto planeSize = cv::gapi::own::Size(desc.d.W, desc.d.H);
// Note: operating with strides (desc.s) rather than dimensions (desc.d) which is vital for ROI
// blobs (data buffer is shared but dimensions are different due to ROI != original image)
const auto batch_offset = desc.s.N * blob->element_size();
std::vector<std::vector<cv::gapi::own::Mat>> result(batch_size);
uint8_t* blob_ptr = static_cast<uint8_t*>(blob->buffer());
if (blob_ptr == nullptr) {
IE_THROW() << "Blob buffer is nullptr";
}
blob_ptr += blob->element_size()*ie_desc_blk.getOffsetPadding();
for (int i = 0; i < batch_size; ++i) {
uint8_t* curr_data_ptr = blob_ptr + i * batch_offset;
std::vector<cv::gapi::own::Mat> planes;
if (ie_desc.getLayout() == Layout::NHWC) {
planes.emplace_back(planeSize.height, planeSize.width, CV_MAKETYPE(cv_depth, desc.d.C),
curr_data_ptr, stride);
} else { // NCHW
if (desc.d.C <= 0) {
IE_THROW() << "Invalid number of channels in blob tensor descriptor, "
"expected >0, actual: " << desc.d.C;
}
const auto planeType = CV_MAKETYPE(cv_depth, 1);
for (int ch = 0; ch < desc.d.C; ch++) {
cv::gapi::own::Mat plane(planeSize.height, planeSize.width, planeType,
curr_data_ptr + ch*desc.s.C*blob->element_size(), stride);
planes.emplace_back(plane);
}
}
result[i] = std::move(planes);
}
return result;
}
template<typename... Ts, int... IIs>
std::vector<cv::GMat> to_vec_impl(std::tuple<Ts...> &&gmats, cv::detail::Seq<IIs...>) {
return { std::get<IIs>(gmats)... };
}
template<typename... Ts>
std::vector<cv::GMat> to_vec(std::tuple<Ts...> &&gmats) {
return to_vec_impl(std::move(gmats), typename cv::detail::MkSeq<sizeof...(Ts)>::type());
}
// convert input to planar format
std::vector<cv::GMat> split(const std::vector<cv::GMat>& inputs,
int channels) {
if (inputs.empty()) {
return inputs;
}
std::vector<cv::GMat> planes;
switch (channels) {
case 1: planes = { inputs[0] }; break;
case 2: planes = to_vec(gapi::Split2::on(inputs[0])); break;
case 3: planes = to_vec(gapi::Split3::on(inputs[0])); break;
case 4: planes = to_vec(gapi::Split4::on(inputs[0])); break;
default:
for (int chan = 0; chan < channels; chan++)
planes.emplace_back(gapi::ChanToPlane::on(inputs[0], chan));
break;
}
return planes;
}
// convert input to interleaved format
std::vector<cv::GMat> merge(const std::vector<cv::GMat>& inputs,
int channels) {
if (inputs.empty()) {
return inputs;
}
std::vector<cv::GMat> interleaved;
switch (channels) {
case 1: interleaved.emplace_back(inputs[0]); break;
case 2: interleaved.emplace_back(gapi::Merge2::on(inputs[0], inputs[1])); break;
case 3: interleaved.emplace_back(gapi::Merge3::on(inputs[0], inputs[1], inputs[2])); break;
case 4: interleaved.emplace_back(gapi::Merge4::on(inputs[0], inputs[1], inputs[2], inputs[3])); break;
default: IE_THROW() << "output channels value " << channels
<< " is not supported for HWC [by G-API]."
<< " Expected range (inclusive): [1;4].";
}
return interleaved;
}
// validate input/output ColorFormat-related parameters
void validateColorFormats(const G::Desc &in_desc,
const G::Desc &out_desc,
Layout in_layout,
Layout out_layout,
ColorFormat input_color_format,
ColorFormat output_color_format) {
const auto verify_desc = [] (const G::Desc& desc, ColorFormat fmt, const std::string& desc_prefix) {
const auto throw_invalid_number_of_channels = [&](){
IE_THROW() << desc_prefix << " tensor descriptor "
<< "has invalid number of channels "
<< desc.d.C << " for " << fmt
<< "color format";
};
switch (fmt) {
case ColorFormat::RGB:
case ColorFormat::BGR: {
if (desc.d.C != 3) throw_invalid_number_of_channels();
break;
}
case ColorFormat::RGBX:
case ColorFormat::BGRX: {
if (desc.d.C != 4) throw_invalid_number_of_channels();
break;
}
default: break;
}
};
const auto verify_layout = [] (Layout layout, const std::string& layout_prefix) {
if (layout != NHWC && layout != NCHW) {
IE_THROW() << layout_prefix << " layout " << layout
<< " is not supported by pre-processing [by G-API]";
}
};
// verify inputs/outputs and throw on error
const bool color_conv_required = !((output_color_format == input_color_format) || (input_color_format == ColorFormat::RAW));
if (color_conv_required && (output_color_format == ColorFormat::RAW)) {
IE_THROW() << "Network's expected color format is unspecified";
}
verify_layout(in_layout, "Input blob");
verify_layout(out_layout, "Network's blob");
if (!color_conv_required) {
// verify input and output have the same number of channels
if (in_desc.d.C != out_desc.d.C) {
IE_THROW() << "Input and network expected blobs have different number of "
<< "channels: expected " << out_desc.d.C << " channels but provided "
<< in_desc.d.C << " channels";
}
return;
}
// planar 4-channel input is not supported, user can easily pass 3 channels instead of 4
if (in_layout == NCHW
&& (input_color_format == ColorFormat::RGBX || input_color_format == ColorFormat::BGRX)) {
IE_THROW() << "Input blob with NCHW layout and BGRX/RGBX color format is "
<< "explicitly not supported, use NCHW + BGR/RGB color format "
<< "instead (3 image planes instead of 4)";
}
// verify input and output against their corresponding color format
verify_desc(in_desc, input_color_format, "Input blob");
verify_desc(out_desc, output_color_format, "Network's blob");
}
bool has_zeros(const SizeVector& vec) {
return std::any_of(vec.cbegin(), vec.cend(), [] (size_t e) { return e == 0; });
}
void validateTensorDesc(const TensorDesc& desc) {
auto supports_layout = [](Layout l) { return l == Layout::NCHW || l == Layout::NHWC; };
const auto layout = desc.getLayout();
const auto& dims = desc.getDims();
if (!supports_layout(layout)
|| dims.size() != 4
|| desc.getBlockingDesc().getStrides().size() != 4) {
IE_THROW() << "Preprocess support NCHW/NHWC only";
}
if (has_zeros(dims)) {
IE_THROW() << "Invalid input data dimensions: "
<< details::dumpVec(dims);
}
}
void validateBlob(const MemoryBlob::Ptr &) {}
const std::pair<const TensorDesc&, Layout> getTensorDescAndLayout(const MemoryBlob::Ptr &blob) {
const auto& desc = blob->getTensorDesc();
return {desc, desc.getLayout()};
}
G::Desc getGDesc(G::Desc in_desc_y, const MemoryBlob::Ptr &) {
return in_desc_y;
}
class PlanarColorConversions {
using GMats = std::vector<cv::GMat>;
using CvtFunction = std::function<GMats(const GMats&, Layout, Layout, ResizeAlgorithm)>;
struct Hash {
inline size_t operator()(const std::pair<ColorFormat, ColorFormat>& p) const {
return static_cast<size_t>((p.first << 16) ^ p.second);
}
};
std::unordered_map<std::pair<ColorFormat, ColorFormat>, CvtFunction, Hash> m_conversions;
// convert RGB -> BGR and BGR -> RGB
static std::vector<cv::GMat> reverse3(const std::vector<cv::GMat>& inputs,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm algorithm) {
auto planes = inputs;
if (in_layout == NHWC) {
planes = split(inputs, 3);
}
// if there's no resize after color convert && output is planar, we have to copy input to
// output by doing actual G-API operation. otherwise, the graph will be empty (no
// operations)
if (algorithm == NO_RESIZE && in_layout == out_layout && out_layout == NCHW) {
std::vector<cv::GMat> reversed(3);
reversed[0] = gapi::ChanToPlane::on(planes[2], 0);
reversed[1] = gapi::ChanToPlane::on(planes[1], 0);
reversed[2] = gapi::ChanToPlane::on(planes[0], 0);
return reversed;
}
std::reverse(planes.begin(), planes.end());
return planes;
}
// convert RGBX -> RGB and BGRX -> BGR
static std::vector<cv::GMat> dropLastChan(const std::vector<cv::GMat>& inputs,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm /*algorithm*/) {
// Note: input is always interleaved, planar input is converted to RGB/BGR on the user side
auto planes = split(inputs, 4);
planes.pop_back();
return planes;
}
// convert RGBX -> BGR and BGRX -> RGB
static std::vector<cv::GMat> dropLastChanAndReverse(const std::vector<cv::GMat>& inputs,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm algorithm) {
auto planes = dropLastChan(inputs, in_layout, out_layout, algorithm);
std::reverse(planes.begin(), planes.end());
return planes;
}
static std::vector<cv::GMat> NV12toRGB(const std::vector<cv::GMat>& inputs,
Layout,
Layout,
ResizeAlgorithm) {
// in_layout is always NCHW
auto interleaved_rgb = gapi::NV12toRGB::on(inputs[0], inputs[1]);
return split({interleaved_rgb}, 3);
}
static std::vector<cv::GMat> NV12toBGR(const std::vector<cv::GMat>& inputs,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm algorithm) {
auto planes = NV12toRGB(inputs, in_layout, out_layout, algorithm);
std::reverse(planes.begin(), planes.end());
return planes;
}
static std::vector<cv::GMat> I420toRGB(const std::vector<cv::GMat>& inputs,
Layout,
Layout,
ResizeAlgorithm) {
// in_layout is always NCHW
auto interleaved_rgb = gapi::I420toRGB::on(inputs[0], inputs[1], inputs[2]);
return split({interleaved_rgb}, 3);
}
static std::vector<cv::GMat> I420toBGR(const std::vector<cv::GMat>& inputs,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm algorithm) {
auto planes = I420toRGB(inputs, in_layout, out_layout, algorithm);
std::reverse(planes.begin(), planes.end());
return planes;
}
public:
PlanarColorConversions() {
IE_SUPPRESS_DEPRECATED_START
m_conversions = {
{ {ColorFormat::RGB, ColorFormat::BGR}, reverse3 },
{ {ColorFormat::BGR, ColorFormat::RGB}, reverse3 },
{ {ColorFormat::RGBX, ColorFormat::RGB}, dropLastChan },
{ {ColorFormat::BGRX, ColorFormat::BGR}, dropLastChan },
{ {ColorFormat::RGBX, ColorFormat::BGR}, dropLastChanAndReverse },
{ {ColorFormat::BGRX, ColorFormat::RGB}, dropLastChanAndReverse }
};
IE_SUPPRESS_DEPRECATED_END
}
const CvtFunction& at(ColorFormat in_fmt, ColorFormat out_fmt) const {
auto cvtFunc = m_conversions.find(std::make_pair(in_fmt, out_fmt));
if (cvtFunc == m_conversions.cend()) {
IE_THROW() << "Color conversion " << in_fmt << " -> " << out_fmt
<< " is not supported";
}
return cvtFunc->second;
}
};
// construct G-API graph pipeline to color convert input into output
// Note: always returns planar output
std::vector<cv::GMat>
convertColorPlanar(const std::vector<cv::GMat>& inputs,
const G::Desc& in_desc,
Layout in_layout,
Layout out_layout,
ColorFormat input_color_format,
ColorFormat output_color_format,
ResizeAlgorithm algorithm) {
// do not perform color conversions if not requested (ColorFormat::RAW) or if input already has
// network's expected color format
if (input_color_format == ColorFormat::RAW || input_color_format == output_color_format) {
// convert input into planar form
if (in_layout == NHWC) {
return split(inputs, in_desc.d.C);
}
return inputs;
}
static PlanarColorConversions conversions;
const auto& convert = conversions.at(input_color_format, output_color_format);
auto planes = convert(inputs, in_layout, out_layout, algorithm);
if (planes.empty()) {
IE_THROW() << "[G-API] internal error: failed to convert input data into planar "
<< "format";
}
return planes;
}
cv::GComputation buildGraph(const G::Desc &in_desc,
const G::Desc &out_desc,
Layout in_layout,
Layout out_layout,
ResizeAlgorithm algorithm,
ColorFormat input_color_format,
ColorFormat output_color_format) {
// perform basic validation to ensure our assumptions about input and output are correct
validateColorFormats(in_desc, out_desc, in_layout, out_layout, input_color_format,
output_color_format);
std::vector<cv::GMat> inputs; // 1 element if NHWC, C elements if NCHW
if (in_layout == NHWC) {
inputs.resize(1);
} else if (in_layout == NCHW) {
inputs.resize(in_desc.d.C);
}
// specific pre-processing case:
// 1. Requires interleaved image of type CV_8UC3/CV_8UC4 (except for NV12/I420 input)
// 2. Supports bilinear resize only
// 3. Supports NV12/I420 -> RGB/BGR color transformations
const auto io_color_formats = std::make_tuple(input_color_format, output_color_format);
const bool drop_channel = (io_color_formats == std::make_tuple(ColorFormat::RGBX, ColorFormat::RGB)) ||
(io_color_formats == std::make_tuple(ColorFormat::BGRX, ColorFormat::BGR));
const bool specific_case_of_preproc = ((in_layout == NHWC)
&& (in_desc.d.C == 3 || drop_channel)
&& ((in_desc.prec == CV_8U) && (in_desc.prec == out_desc.prec))
&& (algorithm == RESIZE_BILINEAR)
&& (input_color_format == ColorFormat::RAW
|| input_color_format == output_color_format
|| drop_channel));
if (specific_case_of_preproc) {
const auto input_sz = cv::gapi::own::Size(in_desc.d.W, in_desc.d.H);
const auto scale_sz = cv::gapi::own::Size(out_desc.d.W, out_desc.d.H);
// convert color format to RGB in case of NV12 input
std::vector<cv::GMat> color_converted_input;
color_converted_input = inputs;
auto planes = drop_channel ?
to_vec(gapi::ScalePlanes4:: on(
color_converted_input[0], in_desc.prec, input_sz, scale_sz, cv::INTER_LINEAR))
: to_vec(gapi::ScalePlanes ::on(
color_converted_input[0], in_desc.prec, input_sz, scale_sz, cv::INTER_LINEAR));
if (drop_channel) {
planes.pop_back();
}
std::vector<cv::GMat> outputs;
if (out_layout == NHWC) {
outputs.emplace_back(gapi::Merge3::on(planes[0], planes[1], planes[2]));
} else {
outputs = planes;
}
return cv::GComputation(inputs, outputs);
}
auto planes = convertColorPlanar(inputs, in_desc, in_layout, out_layout,
input_color_format, output_color_format, algorithm);
const int number_of_planes = static_cast<int>(planes.size());
if (number_of_planes != out_desc.d.C) {
IE_THROW() << "[G-API] internal error: number of channels after color conversion "
<< "!= network's expected number of channels: "
<< number_of_planes << " != " << out_desc.d.C;
}
const int tmp_prec = CV_32F;
std::vector<cv::GMat> outputs;
const bool resize_needed = (algorithm != NO_RESIZE);
const bool need_tmp_prec_conv = resize_needed && (in_desc.prec != CV_8U) && (in_desc.prec != CV_32F);
if (resize_needed) {
// resize every plane
std::vector<cv::GMat> out_planes;
out_planes.reserve(planes.size());
const int interp_type = [](const ResizeAlgorithm &ar) {
switch (ar) {
case RESIZE_AREA: return cv::INTER_AREA;
case RESIZE_BILINEAR: return cv::INTER_LINEAR;
default: IE_THROW() << "Unsupported resize operation";
}
} (algorithm);
std::transform(planes.begin(), planes.end(), std::back_inserter(out_planes), [&](const cv::GMat& m) {
const auto input_sz = cv::gapi::own::Size(in_desc.d.W, in_desc.d.H);
const auto scale_sz = cv::gapi::own::Size(out_desc.d.W, out_desc.d.H);
cv::GMat converted = m;
int prec = in_desc.prec;
if (need_tmp_prec_conv) {
std::tie(converted, prec) = std::make_tuple(gapi::ConvertDepth::on(m, tmp_prec), tmp_prec);
}
return gapi::ScalePlane::on(converted, prec, input_sz, scale_sz, interp_type);
});
outputs = out_planes;
} else {
outputs = planes;
}
if ((in_desc.prec != out_desc.prec) || need_tmp_prec_conv) {
auto convert_prec = [](const std::vector<cv::GMat> & src_gmats, int dst_precision) {
std::vector<cv::GMat> dst_gmats;
std::transform(src_gmats.begin(), src_gmats.end(), std::back_inserter(dst_gmats), [&](cv::GMat const& m){
return gapi::ConvertDepth::on(m, dst_precision);
});
return dst_gmats;
};
outputs = convert_prec(outputs, out_desc.prec);
}
// convert to interleaved if NHWC is required as output
if (out_layout == NHWC) {
outputs = merge(outputs, out_desc.d.C);
}
return cv::GComputation(inputs, outputs);
}
} // anonymous namespace
PreprocEngine::PreprocEngine() : _lastComp(parallel_get_max_threads()) {}
PreprocEngine::Update PreprocEngine::needUpdate(const CallDesc &newCallOrig) const {
// Given our knowledge about Fluid, full graph rebuild is required
// if and only if:
// 0. This is the first call ever
// 1. precision has changed (affects kernel versions)
// 2. layout has changed (affects graph topology)
// 3. algorithm has changed (affects kernel version)
// 4. dimensions have changed from downscale to upscale or vice-versa if interpolation is AREA
// 5. color format has changed (affects graph topology)
if (!_lastCall) {
return Update::REBUILD;
}
BlobDesc last_in;
BlobDesc last_out;
ResizeAlgorithm last_algo = ResizeAlgorithm::NO_RESIZE;
std::tie(last_in, last_out, last_algo) = *_lastCall;
CallDesc newCall = newCallOrig;
BlobDesc new_in;
BlobDesc new_out;
ResizeAlgorithm new_algo = ResizeAlgorithm::NO_RESIZE;
std::tie(new_in, new_out, new_algo) = newCall;
// Declare two empty vectors per each call
SizeVector last_in_size;
SizeVector last_out_size;
SizeVector new_in_size;
SizeVector new_out_size;
// Now swap it with in/out descriptor vectors
// Now last_in/last_out would contain everything but sizes
last_in_size.swap(std::get<2>(last_in));
last_out_size.swap(std::get<2>(last_out));
new_in_size.swap(std::get<2>(new_in));
new_out_size.swap(std::get<2>(new_out));
// If anything (except input sizes) changes, rebuild is required
if (last_in != new_in || last_out != new_out || last_algo != new_algo) {
return Update::REBUILD;
}
// If output sizes change, graph should be regenerated (resize
// ratio is taken from parameters)
if (last_out_size != new_out_size) {
return Update::REBUILD;
}
// If interpolation is AREA and sizes change upscale/downscale
// mode, rebuild is required
if (last_algo == RESIZE_AREA) {
// 0123 == NCHW
const auto is_upscale = [](const SizeVector &in, const SizeVector &out) -> bool {
return in[2] < out[2] || in[3] < out[3];
};
const bool old_upscale = is_upscale(last_in_size, last_out_size);
const bool new_upscale = is_upscale(new_in_size, new_out_size);
if (old_upscale != new_upscale) {
return Update::REBUILD;
}
}
// If only sizes changes (considering the above exception),
// reshape is enough
if (last_in_size != new_in_size) {
return Update::RESHAPE;
}
return Update::NOTHING;
}
void PreprocEngine::checkApplicabilityGAPI(const Blob::Ptr &src, const Blob::Ptr &dst) {
// Note: src blob is the ROI blob, dst blob is the network's input blob
if (!src->is<MemoryBlob>()) {
IE_THROW() << "Unsupported input blob type: expected MemoryBlob";
}
// dst is always a memory blob
if (!dst->is<MemoryBlob>()) {
IE_THROW() << "Unsupported network's input blob type: expected MemoryBlob";
}
const auto &src_dims = src->getTensorDesc().getDims();
const auto &dst_dims = dst->getTensorDesc().getDims();
// dimensions sizes must be equal if both blobs are memory blobs
if (src_dims.size() != dst_dims.size()) {
IE_THROW() << "Preprocessing is not applicable. Source and destination blobs "
"have different number of dimensions.";
}
if (dst_dims.size() != 4) {
IE_THROW() << "Preprocessing is not applicable. Only 4D tensors are supported.";
}
// dimensions must not have values that are equal to 0
if (has_zeros(src_dims)) {
IE_THROW() << "Invalid input data dimensions: " << details::dumpVec(src_dims);
}
if (has_zeros(dst_dims)) {
IE_THROW() << "Invalid network's input dimensions: " << details::dumpVec(dst_dims);
}
}
int PreprocEngine::getCorrectBatchSize(int batch, const Blob::Ptr& blob) {
if (batch == 0) {
IE_THROW() << "Input pre-processing is called with invalid batch size " << batch;
}
if (blob->is<CompoundBlob>()) {
// batch size must always be 1 in compound blob case
if (batch > 1) {
IE_THROW() << "Provided input blob batch size " << batch
<< " is not supported in compound blob pre-processing";
}
batch = 1;
} else if (batch < 0) {
// if batch size is unspecified, process the whole input blob
batch = static_cast<int>(blob->getTensorDesc().getDims()[0]);
}
return batch;
}
void PreprocEngine::executeGraph(Opt<cv::GComputation>& lastComputation,
const std::vector<std::vector<cv::gapi::own::Mat>>& batched_input_plane_mats,
std::vector<std::vector<cv::gapi::own::Mat>>& batched_output_plane_mats, int batch_size, bool omp_serial,
Update update) {
const int thread_num =
#if IE_THREAD == IE_THREAD_OMP
omp_serial ? 1 : // disable threading for OpenMP if was asked for
#endif
0; // use all available threads
// to suppress unused warnings
(void)(omp_serial);
// Split the whole graph into `total_slices` slices, where
// `total_slices` is provided by the parallel runtime and assumed
// to be number of threads used. However it is not guaranteed
// that an actual number of threads will be as assumed, so it
// possible that all slices are processed by the same thread.
//
parallel_nt_static(thread_num, [&, this](int slice_n, const int total_slices) {
OV_ITT_SCOPED_TASK(itt::domains::IEPreproc, _perf_exec_tile);
auto& compiled = _lastComp[slice_n];
if (Update::REBUILD == update || Update::RESHAPE == update) {
// need to compile (or reshape) own object for a particular ROI
OV_ITT_SCOPED_TASK(itt::domains::IEPreproc, _perf_graph_compiling);
using cv::gapi::own::Rect;
// current design implies all images in batch are equal
const auto& input_plane_mats = batched_input_plane_mats[0];
const auto& output_plane_mats = batched_output_plane_mats[0];
auto lines_per_thread = output_plane_mats[0].rows / total_slices;
const auto remainder = output_plane_mats[0].rows % total_slices;
// remainder shows how many threads must calculate 1 additional row. now these additions
// must also be addressed in rect's Y coordinate:
int roi_y = 0;
if (slice_n < remainder) {
lines_per_thread++; // 1 additional row
roi_y = slice_n * lines_per_thread; // all previous rois have lines+1 rows
} else {
// remainder rois have lines+1 rows, the rest prior to slice_n have lines rows
roi_y =
remainder * (lines_per_thread + 1) + (slice_n - remainder) * lines_per_thread;
}
if (lines_per_thread <= 0) return; // no job for current thread
auto roi = Rect{0, roi_y, output_plane_mats[0].cols, lines_per_thread};
std::vector<Rect> rois(output_plane_mats.size(), roi);
// TODO: make a ROI a runtime argument to avoid
// recompilations
auto args = cv::compile_args(gapi::preprocKernels(), cv::GFluidOutputRois{std::move(rois)});
if (Update::REBUILD == update) {
auto& computation = lastComputation.value();
compiled = computation.compile(descrs_of(input_plane_mats), std::move(args));
} else {
IE_ASSERT(compiled);
compiled.reshape(descrs_of(input_plane_mats), std::move(args));
}
}
for (int i = 0; i < batch_size; ++i) {
const auto& input_plane_mats = batched_input_plane_mats[i];
auto& output_plane_mats = batched_output_plane_mats[i];
cv::GRunArgs call_ins;
cv::GRunArgsP call_outs;
for (const auto & m : input_plane_mats) { call_ins.emplace_back(m);}
for (auto & m : output_plane_mats) { call_outs.emplace_back(&m);}
OV_ITT_SCOPED_TASK(itt::domains::IEPreproc, _perf_exec_graph);
compiled(std::move(call_ins), std::move(call_outs));
}
});
}
template<typename BlobTypePtr>
void PreprocEngine::preprocessBlob(const BlobTypePtr &inBlob, MemoryBlob::Ptr &outBlob,
ResizeAlgorithm algorithm, ColorFormat in_fmt, ColorFormat out_fmt, bool omp_serial,
int batch_size) {
validateBlob(inBlob);
auto desc_and_layout = getTensorDescAndLayout(inBlob);
const auto& in_desc_ie = desc_and_layout.first;
const auto in_layout = desc_and_layout.second;
const auto& out_desc_ie = outBlob->getTensorDesc();
validateTensorDesc(in_desc_ie);
validateTensorDesc(out_desc_ie);
const auto out_layout = out_desc_ie.getLayout();
// For YUV420, check batch via Y plane descriptor
const G::Desc
in_desc = G::decompose(in_desc_ie),
out_desc = G::decompose(out_desc_ie);
// according to the IE's current design, input blob batch size _must_ match networks's expected
// batch size, even if the actual processing batch size (set on infer request) is different.
if (in_desc.d.N != out_desc.d.N) {
IE_THROW() << "Input blob batch size is invalid: (input blob) "
<< in_desc.d.N << " != " << out_desc.d.N << " (expected by network)";
}
// sanity check batch size
if (batch_size > out_desc.d.N) {
IE_THROW() << "Provided batch size is invalid: (provided)"
<< batch_size << " > " << out_desc.d.N << " (expected by network)";
}
CallDesc thisCall = CallDesc{ BlobDesc{ in_desc_ie.getPrecision(),
in_layout,
in_desc_ie.getDims(),
in_fmt },
BlobDesc{ out_desc_ie.getPrecision(),
out_layout,
out_desc_ie.getDims(),
out_fmt },
algorithm };
if (algorithm == NO_RESIZE && std::get<0>(thisCall) == std::get<1>(thisCall)) {
//if requested output parameters match input blob no need to do anything
IE_THROW() << "No job to do in the PreProcessing ?";
}
const Update update = needUpdate(thisCall);
Opt<cv::GComputation> _lastComputation;
if (Update::REBUILD == update || Update::RESHAPE == update) {
_lastCall = cv::util::make_optional(std::move(thisCall));
if (Update::REBUILD == update) {
// rebuild the graph
OV_ITT_SCOPED_TASK(itt::domains::IEPreproc, _perf_graph_building);
// FIXME: what is a correct G::Desc to be passed for NV12/I420 case?
auto custom_desc = getGDesc(in_desc, inBlob);
_lastComputation = cv::util::make_optional(
buildGraph(custom_desc,
out_desc,
in_layout,
out_layout,
algorithm,
in_fmt,
out_fmt));
}
}
auto batched_input_plane_mats = bind_to_blob(inBlob, batch_size);
auto batched_output_plane_mats = bind_to_blob(outBlob, batch_size);
executeGraph(_lastComputation, batched_input_plane_mats, batched_output_plane_mats, batch_size,
omp_serial, update);
}
void PreprocEngine::preprocessWithGAPI(const Blob::Ptr &inBlob, Blob::Ptr &outBlob,
const ResizeAlgorithm& algorithm, ColorFormat in_fmt, bool omp_serial, int batch_size) {
const auto out_fmt = (in_fmt == ColorFormat::RAW) ? ColorFormat::RAW : ColorFormat::BGR; // FIXME: get expected color format from network
// output is always a memory blob
auto outMemoryBlob = as<MemoryBlob>(outBlob);
if (!outMemoryBlob) {
IE_THROW() << "Unsupported network's input blob type: expected MemoryBlob";
}
auto inMemoryBlob = as<MemoryBlob>(inBlob);
if (!inMemoryBlob) {
IE_THROW() << "Unsupported input blob for color format " << in_fmt
<< ": expected MemoryBlob";
}
return preprocessBlob(inMemoryBlob, outMemoryBlob, algorithm, in_fmt, out_fmt, omp_serial,
batch_size);
}
} // namespace InferenceEngine

View File

@ -1,61 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include "ie_blob.h"
#include "ie_compound_blob.h"
#include "ie_input_info.hpp"
#include <tuple>
#include <vector>
#include <opencv2/gapi/gcompiled.hpp>
#include <opencv2/gapi/gcomputation.hpp>
#include <opencv2/gapi/util/optional.hpp>
#include <openvino/itt.hpp>
// FIXME: Move this definition back to ie_preprocess_data,
// also free ie_preprocess_gapi of these details
namespace InferenceEngine {
IE_SUPPRESS_DEPRECATED_START
class PreprocEngine {
using BlobDesc = std::tuple<Precision, Layout, SizeVector, ColorFormat>;
using CallDesc = std::tuple<BlobDesc, BlobDesc, ResizeAlgorithm>;
template<typename T> using Opt = cv::util::optional<T>;
Opt<CallDesc> _lastCall;
std::vector<cv::GCompiled> _lastComp;
openvino::itt::handle_t _perf_graph_building = openvino::itt::handle("Preproc Graph Building");
openvino::itt::handle_t _perf_exec_tile = openvino::itt::handle("Preproc Calc Tile");
openvino::itt::handle_t _perf_exec_graph = openvino::itt::handle("Preproc Exec Graph");
openvino::itt::handle_t _perf_graph_compiling = openvino::itt::handle("Preproc Graph compiling");
enum class Update { REBUILD, RESHAPE, NOTHING };
Update needUpdate(const CallDesc &newCall) const;
void executeGraph(Opt<cv::GComputation>& lastComputation,
const std::vector<std::vector<cv::gapi::own::Mat>>& src,
std::vector<std::vector<cv::gapi::own::Mat>>& dst,
int batch_size,
bool omp_serial,
Update update);
template<typename BlobTypePtr>
void preprocessBlob(const BlobTypePtr &inBlob, MemoryBlob::Ptr &outBlob,
ResizeAlgorithm algorithm, ColorFormat in_fmt, ColorFormat out_fmt, bool omp_serial,
int batch_size);
public:
PreprocEngine();
static void checkApplicabilityGAPI(const Blob::Ptr &src, const Blob::Ptr &dst);
static int getCorrectBatchSize(int batch_size, const Blob::Ptr& roiBlob);
void preprocessWithGAPI(const Blob::Ptr &inBlob, Blob::Ptr &outBlob, const ResizeAlgorithm &algorithm,
ColorFormat in_fmt, bool omp_serial, int batch_size = -1);
};
IE_SUPPRESS_DEPRECATED_END
} // namespace InferenceEngine

File diff suppressed because it is too large Load Diff

View File

@ -1,364 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
# ifndef GAPI_STANDALONE
# error non standalone GAPI
# endif
#include <cstdint>
#include <tuple>
#include <opencv2/gapi/opencv_includes.hpp>
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/gmat.hpp>
#include <opencv2/gapi/gkernel.hpp>
namespace InferenceEngine {
namespace gapi {
using Size = cv::gapi::own::Size;
using GMat2 = std::tuple<cv::GMat, cv::GMat>;
using GMat3 = std::tuple<cv::GMat, cv::GMat, cv::GMat>;
using GMat4 = std::tuple<cv::GMat, cv::GMat, cv::GMat, cv::GMat>;
G_TYPED_KERNEL(ChanToPlane, <cv::GMat(cv::GMat, int)>, "com.intel.ie.chan_to_plane") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in, int chan) {
GAPI_Assert(chan < in.chan);
return in.withType(in.depth, 1);
}
};
G_TYPED_KERNEL(ScalePlane, <cv::GMat(cv::GMat, int, Size, Size, int)>, "com.intel.ie.scale_plane") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in, int type, const Size &szIn, const Size &szOut, int) {
GAPI_Assert(type == in.depth);
return in.withSize(szOut);
}
};
G_TYPED_KERNEL_M(ScalePlanes, <GMat3(cv::GMat, int, Size, Size, int)>, "com.intel.ie.scale_planes") {
static std::tuple<cv::GMatDesc, cv::GMatDesc, cv::GMatDesc> outMeta(const cv::GMatDesc &in, int /*type*/, const Size &szIn,
const Size &szOut, int interp) {
// This kernel supports only RGB 8U inputs
GAPI_Assert(in.depth == CV_8U);
GAPI_Assert(in.chan == 3);
// cv::INTER_LINEAR is the only supported interpolation
GAPI_Assert(interp == cv::INTER_LINEAR);
// ad-hoc withChan
cv::GMatDesc out_desc = in.withType(in.depth, 1).withSize(szOut);
return std::make_tuple(out_desc, out_desc, out_desc);
}
};
G_TYPED_KERNEL_M(ScalePlanes4, <GMat4(cv::GMat, int, Size, Size, int)>, "com.intel.ie.scale_planes4") {
static std::tuple<cv::GMatDesc, cv::GMatDesc, cv::GMatDesc, cv::GMatDesc> outMeta(const cv::GMatDesc &in, int /*type*/, const Size &szIn,
const Size &szOut, int interp) {
// This kernel supports only RGB 8U inputs
GAPI_Assert(in.depth == CV_8U);
GAPI_Assert(in.chan == 4);
// cv::INTER_LINEAR is the only supported interpolation
GAPI_Assert(interp == cv::INTER_LINEAR);
// ad-hoc withChan
cv::GMatDesc out_desc = in.withType(in.depth, 1).withSize(szOut);
return std::make_tuple(out_desc, out_desc, out_desc, out_desc);
}
};
G_TYPED_KERNEL(ScalePlane8u, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.scale_plane_8u") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_8U && in.chan == 1);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(ScalePlane32f, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.scale_plane_32f") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_32F && in.chan == 1);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(UpscalePlaneArea8u, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.upscale_plane_area_8u") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_8U && in.chan == 1);
GAPI_DbgAssert(in.size.width < sz.width || in.size.height < sz.height);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(UpscalePlaneArea32f, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.upscale_plane_area_32f") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_32F && in.chan == 1);
GAPI_DbgAssert(in.size.width < sz.width || in.size.height < sz.height);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(ScalePlaneArea8u, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.scale_plane_area_8u") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_8U && in.chan == 1);
GAPI_DbgAssert(in.size.width >= sz.width && in.size.height >= sz.height);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(ScalePlaneArea32f, <cv::GMat(cv::GMat, Size, int)>, "com.intel.ie.scale_plane_area_32f") {
static cv::GMatDesc outMeta(const cv::GMatDesc & in, const Size & sz, int) {
GAPI_DbgAssert(in.depth == CV_32F && in.chan == 1);
GAPI_DbgAssert(in.size.width >= sz.width && in.size.height >= sz.height);
return in.withSize(sz);
}
};
G_TYPED_KERNEL(Merge2, <cv::GMat(cv::GMat, cv::GMat)>, "com.intel.ie.merge2") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in, const cv::GMatDesc &) {
// FIXME: check a/b are equal!
return in.withType(in.depth, 2);
}
};
G_TYPED_KERNEL(Merge3, <cv::GMat(cv::GMat, cv::GMat, cv::GMat)>, "com.intel.ie.merge3") {
static cv::GMatDesc outMeta(const cv::GMatDesc &in, const cv::GMatDesc &, const cv::GMatDesc &) {
// FIXME: check a/b are equal!
return in.withType(in.depth, 3);
}
};
G_TYPED_KERNEL(Merge4, <cv::GMat(cv::GMat, cv::GMat, cv::GMat, cv::GMat)>, "com.intel.ie.merge4") {
static cv::GMatDesc outMeta(const cv::GMatDesc& in,
const cv::GMatDesc&, const cv::GMatDesc&, const cv::GMatDesc&) {
// FIXME: check a/b are equal!
return in.withType(in.depth, 4);
}
};
G_TYPED_KERNEL_M(Split2, <GMat2(cv::GMat)>, "com.intel.ie.split2") {
static std::tuple<cv::GMatDesc, cv::GMatDesc> outMeta(const cv::GMatDesc& in) {
const auto out_depth = in.depth;
const auto out_desc = in.withType(out_depth, 1);
return std::make_tuple(out_desc, out_desc);
}
};
G_TYPED_KERNEL_M(Split3, <GMat3(cv::GMat)>, "com.intel.ie.split3") {
static std::tuple<cv::GMatDesc, cv::GMatDesc, cv::GMatDesc> outMeta(const cv::GMatDesc& in) {
const auto out_depth = in.depth;
const auto out_desc = in.withType(out_depth, 1);
return std::make_tuple(out_desc, out_desc, out_desc);
}
};
G_TYPED_KERNEL_M(Split4, <GMat4(cv::GMat)>, "com.intel.ie.split4") {
static std::tuple<cv::GMatDesc, cv::GMatDesc, cv::GMatDesc, cv::GMatDesc> outMeta(const cv::GMatDesc& in) {
const auto out_depth = in.depth;
const auto out_desc = in.withType(out_depth, 1);
return std::make_tuple(out_desc, out_desc, out_desc, out_desc);
}
};
G_TYPED_KERNEL(NV12toRGB, <cv::GMat(cv::GMat, cv::GMat)>, "com.intel.ie.nv12torgb") {
static cv::GMatDesc outMeta(cv::GMatDesc in_y, cv::GMatDesc in_uv) {
GAPI_Assert(in_y.chan == 1);
GAPI_Assert(in_uv.chan == 2);
GAPI_Assert(in_y.depth == CV_8U);
GAPI_Assert(in_uv.depth == CV_8U);
// UV size should be aligned with Y
GAPI_Assert(in_y.size.width == 2 * in_uv.size.width);
GAPI_Assert(in_y.size.height == 2 * in_uv.size.height);
return in_y.withType(CV_8U, 3);
}
};
G_TYPED_KERNEL(I420toRGB, <cv::GMat(cv::GMat, cv::GMat, cv::GMat)>, "com.intel.ie.i420torgb") {
static cv::GMatDesc outMeta(cv::GMatDesc in_y, cv::GMatDesc in_u, cv::GMatDesc in_v) {
GAPI_Assert(in_y.chan == 1);
GAPI_Assert(in_u.chan == 1);
GAPI_Assert(in_v.chan == 1);
GAPI_Assert(in_y.depth == CV_8U);
GAPI_Assert(in_u.depth == CV_8U);
GAPI_Assert(in_v.depth == CV_8U);
// U and V size should be aligned with Y
GAPI_Assert(in_y.size.width == 2 * in_u.size.width);
GAPI_Assert(in_y.size.height == 2 * in_u.size.height);
GAPI_Assert(in_y.size.width == 2 * in_v.size.width);
GAPI_Assert(in_y.size.height == 2 * in_v.size.height);
return in_y.withType(CV_8U, 3);
}
};
G_TYPED_KERNEL(ConvertDepth, <cv::GMat(cv::GMat, int depth)>, "com.intel.ie.ConvertDepth") {
static cv::GMatDesc outMeta(const cv::GMatDesc& in, int depth) {
GAPI_Assert(in.depth == CV_8U || in.depth == CV_16U || in.depth == CV_32F);
GAPI_Assert(depth == CV_8U || depth == CV_32F || depth == CV_16U);
return in.withDepth(depth);
}
};
G_TYPED_KERNEL(GSubC, <cv::GMat(cv::GMat, cv::GScalar, int)>, "com.intel.ie.math.subC") {
static cv::GMatDesc outMeta(cv::GMatDesc a, cv::GScalarDesc, int ddepth) {
return a.withDepth(ddepth);
}
};
G_TYPED_KERNEL(GDivC, <cv::GMat(cv::GMat, cv::GScalar, double, int)>, "com.intel.ie.math.divC") {
static cv::GMatDesc outMeta(cv::GMatDesc a, cv::GScalarDesc, double, int ddepth) {
return a.withDepth(ddepth);
}
};
cv::gapi::GKernelPackage preprocKernels();
namespace kernels {
struct fp_16_t {
int16_t v;
};
template<typename type>
struct cv_type_to_depth;
template<> struct cv_type_to_depth<std::uint8_t> { enum { depth = CV_8U }; };
template<> struct cv_type_to_depth<std::int8_t> { enum { depth = CV_8S }; };
template<> struct cv_type_to_depth<std::uint16_t> { enum { depth = CV_16U }; };
template<> struct cv_type_to_depth<std::int16_t> { enum { depth = CV_16S }; };
template<> struct cv_type_to_depth<std::int32_t> { enum { depth = CV_32S }; };
template<> struct cv_type_to_depth<float> { enum { depth = CV_32F }; };
template<> struct cv_type_to_depth<fp_16_t> { enum { depth = CV_16F }; };
template<typename ... types>
struct typelist {};
template<typename type_list>
struct head;
template<template<typename ...> class list, typename head_t, typename ... types>
struct head<list<head_t, types...>> { using type = head_t; };
template<typename typelist>
using head_t = typename head<typelist>::type;
template<typename type>
struct type_to_type {};
template <typename typelist>
struct type_dispatch_impl;
//FIXME: add test for type_dispatch
template <template<typename ...> class typelist, typename... type>
struct type_dispatch_impl<typelist<type...>> {
template <typename result_t, typename default_t, typename type_id_t, typename type_to_id_t, typename type_to_value_t>
static result_t dispatch(type_id_t type_id, type_to_id_t&& type_to_id, type_to_value_t&& type_to_value, default_t default_value) {
result_t res = default_value;
bool matched = false;
std::initializer_list<int>({
!matched && (type_id == type_to_id(type_to_type<type>{})) ?
(matched = true, res = type_to_value(type_to_type<type>{})), 0
: 0
...
});
return res;
}
template <typename result_t, typename default_t, typename pred_t, typename type_to_value_t>
static result_t dispatch(pred_t&& pred, type_to_value_t&& type_to_value, default_t default_value) {
result_t res = default_value;
bool matched = false;
std::initializer_list<int>({
!matched && pred(type_to_type<type>{}) ?
(matched = true, res = type_to_value(type_to_type<type>{})), 0
: 0
...
});
return res;
}
};
template<typename left_typelsist, typename right_typelsist>
struct concat;
template<typename left_typelsist, typename right_typelsist>
using concat_t = typename concat<left_typelsist, right_typelsist>::type;
template<template<typename ...> class left_list, typename ... left_types, template<typename ...> class right_list, typename ... right_types>
struct concat<left_list<left_types...>, right_list<right_types...>> {
using type = left_list<left_types..., right_types...>;
};
template< class T, class U >
using is_same_t = typename std::is_same<T, U>::type;
template<bool C, class T, class E> struct if_c_impl;
template<class T, class E> struct if_c_impl<true, T, E> {
using type = T;
};
template<class T, class E> struct if_c_impl<false, T, E> {
using type = E;
};
template<bool C, class T, class E>
using if_c = typename if_c_impl<C, T, E>::type;
template<class C, class T, class E>
using if_ = typename if_c_impl<C::value != 0, T, E>::type;
template<typename typelist, typename type>
struct remove;
template<typename typelist, typename type>
using remove_t = typename remove<typelist, type>::type;
template<template<typename ...> class list, typename head_t, typename ... types, typename t>
struct remove<list<head_t, types...>, t> {
using type = concat_t<
if_<is_same_t<head_t, t>, list<>, list<head_t>>,
remove_t<list<types...>, t>
>;
};
template<template<typename ...> class list, typename t>
struct remove<list<>, t> {
using type = list<>;
};
template <typename typelist, typename default_t, typename type_id_t, typename type_to_id_t, typename type_to_value_t,
typename result_t = decltype(std::declval<type_to_value_t>()(type_to_type<head_t<typelist>> {})) >
inline result_t type_dispatch(type_id_t type_id, type_to_id_t&& type_to_id, type_to_value_t&& type_to_value, default_t default_value = {}) {
return type_dispatch_impl<typelist>::template dispatch<result_t>(std::forward<type_id_t>(type_id),
std::forward<type_to_id_t>(type_to_id),
std::forward<type_to_value_t>(type_to_value),
std::forward<default_t>(default_value));
}
template <typename typelist, typename default_t, typename pred_t, typename type_to_value_t,
typename result_t = decltype(std::declval<type_to_value_t>()(type_to_type<head_t<typelist>> {})) >
inline result_t type_dispatch(pred_t&& pred, type_to_value_t&& type_to_value, default_t default_value = {}) {
return type_dispatch_impl<typelist>::template dispatch<result_t>(std::forward<pred_t>(pred),
std::forward<type_to_value_t>(type_to_value),
std::forward<default_t>(default_value));
}
namespace {
struct cv_type_id {
template <typename type>
int operator()(type_to_type<type>) { return cv_type_to_depth<type>::depth; }
};
} // namespace
template <typename typelist>
bool is_cv_type_in_list(const int type_id) {
return type_dispatch<typelist>(type_id, cv_type_id{}, [](...) { return true; }, false);
}
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,154 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#if defined(HAVE_SSE) || defined(HAVE_AVX2) || defined(HAVE_AVX512) || defined(HAVE_NEON)
#define MANUAL_SIMD 1 // 1=call manually vectored code, 0=don't
#else
#define MANUAL_SIMD 0
#endif
#ifdef HAVE_SSE
#define USE_CVKL 1 // 1=reuse CVKL code for Resize, 0=don't
#else
#define USE_CVKL 0
#endif
#if defined(HAVE_SSE) || defined(HAVE_AVX2) || defined(HAVE_AVX512)
#define CPU_SIMD 1
#else
#define CPU_SIMD 0
#endif
#include <climits>
#include <cstdint>
#include <limits>
#if defined(__GNUC__) && (__GNUC__ <= 5)
#include <cmath>
#endif
namespace InferenceEngine {
namespace gapi {
namespace kernels {
// dummy field is needed to workaround ABI change issue between CXX ABI 11 (g++-7) and 12 (g++-8)
// see https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html
struct avx512_tag { int _ = 0; };
struct avx2_tag { int _ = 0; };
struct sse42_tag { int _ = 0; };
struct neon_tag { int _ = 0; };
struct scalar_tag { int _ = 0; };
template<typename DST, typename SRC> static inline DST saturate_cast(SRC x);
template<> inline short saturate_cast(int x) { return (std::min)(SHRT_MAX, (std::max)(SHRT_MIN, x)); }
template<> inline short saturate_cast(float x) { return saturate_cast<short>(static_cast<int>(std::rint(x))); }
template<> inline float saturate_cast(float x) { return x; }
template<> inline short saturate_cast(short x) { return x; }
template<> inline uint16_t saturate_cast(uint16_t x) { return x; }
template<> inline float saturate_cast(uint16_t x) { return x; }
template<> inline uint16_t saturate_cast(int x) { return (std::min)(USHRT_MAX, (std::max)(0, x)); }
template<> inline uint16_t saturate_cast(float x) { return saturate_cast<uint16_t>(static_cast<int>(std::rint(x))); }
template<> inline uchar saturate_cast<uchar>(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); }
template<> inline uint16_t saturate_cast(uint8_t x) { return x; }
template<> inline float saturate_cast(uint8_t x) { return x; }
template<> inline uint8_t saturate_cast(uint8_t x) { return x; }
template<> inline uint8_t saturate_cast(uint16_t x) {
using lim = std::numeric_limits<uint8_t>;
return (uint8_t)std::min(static_cast<uint16_t>(lim::max()),
std::max(static_cast<uint16_t>(lim::min()), x));
}
template<> inline uint8_t saturate_cast(float x) { return saturate_cast<uint8_t>(static_cast<int>(std::rint(x))); }
template<> inline float saturate_cast(double x) { return static_cast<float>(x); }
//------------------------------------------------------------------------------
constexpr static const int ONE = 1 << 15;
inline static uint8_t calc(short alpha0, uint8_t src0, short alpha1, uint8_t src1) {
constexpr static const int half = 1 << 14;
return (src0 * alpha0 + src1 * alpha1 + half) >> 15;
}
inline static float calc(float alpha0, float src0, float alpha1, float src1) {
return src0 * alpha0 + src1 * alpha1;
}
//------------------------------------------------------------------------------
// Variants:
// - F=float, I=int
// - F=short, I=short (e.g. F is Q1.7.8 encoded with short)
template<typename F, typename I>
struct MapperUnit {
F alpha0, alpha1;
I index0, index1;
};
//------------------------------------------------------------------------------
typedef uint16_t Q0_16; // value [0..1) with 16 fractional bits
typedef uint16_t Q8_8; // value [0..255) with 8 fractional bits
typedef uint8_t U8; // value [0..255)
typedef MapperUnit<float, int> MapperUnit32F;
typedef MapperUnit<Q0_16, short> MapperUnit8U;
template<typename DST, typename SRC> static inline DST convert_cast(SRC x);
template<> inline uint8_t convert_cast(uint8_t x) { return x; }
template<> inline uint8_t convert_cast(float x) { return static_cast<uint8_t>(x); }
template<> inline float convert_cast(float x) { return x; }
template<> inline float convert_cast(double x) { return static_cast<float>(x); }
template<> inline Q0_16 convert_cast(double x) {
int ix = static_cast<int>(std::rint(x * (1 << 16)));
return saturate_cast<Q0_16>(ix);
}
template<> inline Q8_8 convert_cast(uchar x) { return x << 8; }
template<> inline uchar convert_cast(Q8_8 x) { return x >> 8; }
template<typename DST, typename SRC> static inline DST checked_cast(SRC x) {
short dx = static_cast<DST>(x);
GAPI_Assert(x == dx); // check
return dx;
}
static inline Q8_8 mulas(Q0_16 a, U8 s) { return static_cast<Q8_8>((a * s) >> 8); }
static inline Q8_8 mulaw(Q0_16 a, Q8_8 w) { return static_cast<Q8_8>((static_cast<uint32_t>(a) * w) >> 16); }
static inline float mulas(float a, float s) { return a * s; }
static inline float mulaw(float a, float w) { return a * w; }
static const int ITUR_BT_601_CY = 1220542;
static const int ITUR_BT_601_CUB = 2116026;
static const int ITUR_BT_601_CUG = -409993;
static const int ITUR_BT_601_CVG = -852492;
static const int ITUR_BT_601_CVR = 1673527;
static const int ITUR_BT_601_SHIFT = 20;
static inline void uvToRGBuv(const uchar u, const uchar v, int& ruv, int& guv, int& buv) {
int uu, vv;
uu = static_cast<int>(u) - 128;
vv = static_cast<int>(v) - 128;
ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * vv;
guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * vv + ITUR_BT_601_CUG * uu;
buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * uu;
}
static inline void yRGBuvToRGB(const uchar vy, const int ruv, const int guv, const int buv,
uchar& r, uchar& g, uchar& b) {
int yy = static_cast<int>(vy);
int y = std::max(0, yy - 16) * ITUR_BT_601_CY;
r = saturate_cast<uchar>((y + ruv) >> ITUR_BT_601_SHIFT);
g = saturate_cast<uchar>((y + guv) >> ITUR_BT_601_SHIFT);
b = saturate_cast<uchar>((y + buv) >> ITUR_BT_601_SHIFT);
}
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine

View File

@ -1,765 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#ifndef IE_PREPROCESS_GAPI_KERNELS_SIMD_IMPL_H
#define IE_PREPROCESS_GAPI_KERNELS_SIMD_IMPL_H
#include <algorithm>
#include <utility>
#include "ie_preprocess_gapi_kernels_impl.hpp"
using namespace cv;
namespace InferenceEngine {
namespace gapi {
namespace kernels {
template <typename VecT, typename T>
CV_ALWAYS_INLINE void mergeRowC2_Impl(const T in0[], const T in1[],
T out[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
GAPI_DbgAssert(length >= nlanes);
VecT r0, r1;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
r0 = vx_load(&in0[x]);
r1 = vx_load(&in1[x]);
v_store_interleave(&out[2*x], r0, r1);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out[2*x + 0] = in0[x];
out[2*x + 1] = in1[x];
}
}
template <typename VecT, typename T>
CV_ALWAYS_INLINE void mergeRowC3_Impl(const T in0[], const T in1[],
const T in2[], T out[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
GAPI_DbgAssert(length >= nlanes);
VecT r0, r1, r2;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
r0 = vx_load(&in0[x]);
r1 = vx_load(&in1[x]);
r2 = vx_load(&in2[x]);
v_store_interleave(&out[3*x], r0, r1, r2);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out[3*x + 0] = in0[x];
out[3*x + 1] = in1[x];
out[3*x + 2] = in2[x];
}
}
template <typename VecT, typename T>
CV_ALWAYS_INLINE void mergeRowC4_Impl(const T in0[], const T in1[],
const T in2[], const T in3[],
T out[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
GAPI_DbgAssert(length >= nlanes);
VecT r0, r1, r2, r3;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
r0 = vx_load(&in0[x]);
r1 = vx_load(&in1[x]);
r2 = vx_load(&in2[x]);
r3 = vx_load(&in3[x]);
v_store_interleave(&out[4* x], r0, r1, r2, r3);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out[4*x + 0] = in0[x];
out[4*x + 1] = in1[x];
out[4*x + 2] = in2[x];
out[4*x + 3] = in3[x];
}
}
//------------------------------------------------------------------------------
template <typename VecT, typename T>
CV_ALWAYS_INLINE void splitRowC2_Impl(const T in[], T out0[],
T out1[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
GAPI_DbgAssert(length >= nlanes);
VecT r0, r1;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
v_load_deinterleave(&in[2*x], r0, r1);
vx_store(&out0[x], r0);
vx_store(&out1[x], r1);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out0[x] = in[2*x + 0];
out1[x] = in[2*x + 1];
}
}
template <typename VecT, typename T>
CV_ALWAYS_INLINE void splitRowC3_Impl(const T in[], T out0[],
T out1[], T out2[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
VecT r0, r1, r2;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
v_load_deinterleave(&in[3*x], r0, r1, r2);
vx_store(&out0[x], r0);
vx_store(&out1[x], r1);
vx_store(&out2[x], r2);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out0[x] = in[3*x + 0];
out1[x] = in[3*x + 1];
out2[x] = in[3*x + 2];
}
}
template <typename VecT, typename T>
CV_ALWAYS_INLINE void splitRowC4_Impl(const T in[], T out0[], T out1[],
T out2[], T out3[], const int length) {
int x = 0;
#if MANUAL_SIMD
constexpr int nlanes = VecT::nlanes;
GAPI_DbgAssert(length >= nlanes);
VecT r0, r1, r2, r3;
for (; length >= nlanes;) {
for (; x <= length - nlanes; x += nlanes) {
v_load_deinterleave(&in[4*x], r0, r1, r2, r3);
vx_store(&out0[x], r0);
vx_store(&out1[x], r1);
vx_store(&out2[x], r2);
vx_store(&out3[x], r3);
}
if (x < length) {
x = length - nlanes;
continue;
}
break;
}
#endif
for (; x < length; ++x) {
out0[x] = in[4*x + 0];
out1[x] = in[4*x + 1];
out2[x] = in[4*x + 2];
out3[x] = in[4*x + 3];
}
}
//------------------------------------------------------------------------------
CV_ALWAYS_INLINE void uvToRGBuv(const v_uint8& u, const v_uint8& v,
v_int32 (&ruv)[4], v_int32 (&guv)[4],
v_int32 (&buv)[4]) {
v_uint8 v128 = vx_setall_u8(128);
v_int8 su = v_reinterpret_as_s8(v_sub_wrap(u, v128));
v_int8 sv = v_reinterpret_as_s8(v_sub_wrap(v, v128));
v_int16 uu0, uu1, vv0, vv1;
v_expand(su, uu0, uu1);
v_expand(sv, vv0, vv1);
v_int32 uu[4], vv[4];
v_expand(uu0, uu[0], uu[1]); v_expand(uu1, uu[2], uu[3]);
v_expand(vv0, vv[0], vv[1]); v_expand(vv1, vv[2], vv[3]);
v_int32 vshift = vx_setall_s32(1 << (ITUR_BT_601_SHIFT - 1));
v_int32 vr = vx_setall_s32(ITUR_BT_601_CVR);
v_int32 vg = vx_setall_s32(ITUR_BT_601_CVG);
v_int32 ug = vx_setall_s32(ITUR_BT_601_CUG);
v_int32 ub = vx_setall_s32(ITUR_BT_601_CUB);
for (int k = 0; k < 4; k++) {
ruv[k] = vshift + vr * vv[k];
guv[k] = vshift + vg * vv[k] + ug * uu[k];
buv[k] = vshift + ub * uu[k];
}
}
CV_ALWAYS_INLINE void yRGBuvToRGB(const v_uint8& vy,
const v_int32 (&ruv)[4],
const v_int32 (&guv)[4],
const v_int32 (&buv)[4],
v_uint8& rr, v_uint8& gg, v_uint8& bb) {
v_uint8 v16 = vx_setall_u8(16);
v_uint8 posY = vy - v16;
v_uint16 yy0, yy1;
v_expand(posY, yy0, yy1);
v_int32 yy[4];
v_int32 yy00, yy01, yy10, yy11;
v_expand(v_reinterpret_as_s16(yy0), yy[0], yy[1]);
v_expand(v_reinterpret_as_s16(yy1), yy[2], yy[3]);
v_int32 vcy = vx_setall_s32(ITUR_BT_601_CY);
v_int32 y[4], r[4], g[4], b[4];
for (int k = 0; k < 4; k++) {
y[k] = yy[k]*vcy;
r[k] = (y[k] + ruv[k]) >> ITUR_BT_601_SHIFT;
g[k] = (y[k] + guv[k]) >> ITUR_BT_601_SHIFT;
b[k] = (y[k] + buv[k]) >> ITUR_BT_601_SHIFT;
}
v_int16 r0, r1, g0, g1, b0, b1;
r0 = v_pack(r[0], r[1]);
r1 = v_pack(r[2], r[3]);
g0 = v_pack(g[0], g[1]);
g1 = v_pack(g[2], g[3]);
b0 = v_pack(b[0], b[1]);
b1 = v_pack(b[2], b[3]);
rr = v_pack_u(r0, r1);
gg = v_pack_u(g0, g1);
bb = v_pack_u(b0, b1);
}
template<typename isa_tag_t>
CV_ALWAYS_INLINE void nv12ToRgbRowImpl(isa_tag_t, const uchar** srcY, const uchar* srcUV,
uchar** dstRGBx, const int width) {
int i = 0;
#if MANUAL_SIMD
constexpr int nlanes = v_uint8::nlanes;
for (; i <= width - 2 * nlanes; i += 2 * nlanes) {
v_uint8 u, v;
v_load_deinterleave(srcUV + i, u, v);
v_uint8 vy[4];
v_load_deinterleave(srcY[0] + i, vy[0], vy[1]);
v_load_deinterleave(srcY[1] + i, vy[2], vy[3]);
v_int32 ruv[4], guv[4], buv[4];
uvToRGBuv(u, v, ruv, guv, buv);
v_uint8 r[4], g[4], b[4];
for (int k = 0; k < 4; k++) {
yRGBuvToRGB(vy[k], ruv, guv, buv, r[k], g[k], b[k]);
}
for (int k = 0; k < 4; k++)
std::swap(r[k], b[k]);
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
v_uint8 r0_0, r0_1, r1_0, r1_1;
v_zip(r[0], r[1], r0_0, r0_1);
v_zip(r[2], r[3], r1_0, r1_1);
v_uint8 g0_0, g0_1, g1_0, g1_1;
v_zip(g[0], g[1], g0_0, g0_1);
v_zip(g[2], g[3], g1_0, g1_1);
v_uint8 b0_0, b0_1, b1_0, b1_1;
v_zip(b[0], b[1], b0_0, b0_1);
v_zip(b[2], b[3], b1_0, b1_1);
v_store_interleave(dstRGBx[0] + i * 3, b0_0, g0_0, r0_0);
v_store_interleave(dstRGBx[0] + i * 3 + 3 * nlanes, b0_1, g0_1, r0_1);
v_store_interleave(dstRGBx[1] + i * 3, b1_0, g1_0, r1_0);
v_store_interleave(dstRGBx[1] + i * 3 + 3 * nlanes, b1_1, g1_1, r1_1);
}
//vx_cleanup();
#endif
for (; i < width; i += 2) {
uchar u = srcUV[i];
uchar v = srcUV[i + 1];
int ruv, guv, buv;
uvToRGBuv(u, v, ruv, guv, buv);
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
uchar vy = srcY[y][i + x];
uchar r, g, b;
yRGBuvToRGB(vy, ruv, guv, buv, r, g, b);
dstRGBx[y][3 * (i + x)] = r;
dstRGBx[y][3 * (i + x) + 1] = g;
dstRGBx[y][3 * (i + x) + 2] = b;
}
}
}
}
template<typename isa_tag_t>
CV_ALWAYS_INLINE void i420ToRgbRowImpl(isa_tag_t, const uint8_t** srcY, const uint8_t* srcU,
const uint8_t* srcV, uint8_t** dstRGBx, const int width) {
int i = 0;
#if MANUAL_SIMD
constexpr int nlanes = v_uint8::nlanes;
for (; i <= width - 2 * nlanes; i += 2 * nlanes) {
v_uint8 u = vx_load(srcU + i / 2);
v_uint8 v = vx_load(srcV + i / 2);
v_uint8 vy[4];
v_load_deinterleave(srcY[0] + i, vy[0], vy[1]);
v_load_deinterleave(srcY[1] + i, vy[2], vy[3]);
v_int32 ruv[4], guv[4], buv[4];
uvToRGBuv(u, v, ruv, guv, buv);
v_uint8 r[4], g[4], b[4];
for (int k = 0; k < 4; k++) {
yRGBuvToRGB(vy[k], ruv, guv, buv, r[k], g[k], b[k]);
}
for (int k = 0; k < 4; k++)
std::swap(r[k], b[k]);
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
v_uint8 r0_0, r0_1, r1_0, r1_1;
v_zip(r[0], r[1], r0_0, r0_1);
v_zip(r[2], r[3], r1_0, r1_1);
v_uint8 g0_0, g0_1, g1_0, g1_1;
v_zip(g[0], g[1], g0_0, g0_1);
v_zip(g[2], g[3], g1_0, g1_1);
v_uint8 b0_0, b0_1, b1_0, b1_1;
v_zip(b[0], b[1], b0_0, b0_1);
v_zip(b[2], b[3], b1_0, b1_1);
v_store_interleave(dstRGBx[0] + i * 3, b0_0, g0_0, r0_0);
v_store_interleave(dstRGBx[0] + i * 3 + 3 * nlanes, b0_1, g0_1, r0_1);
v_store_interleave(dstRGBx[1] + i * 3, b1_0, g1_0, r1_0);
v_store_interleave(dstRGBx[1] + i * 3 + 3 * nlanes, b1_1, g1_1, r1_1);
}
//vx_cleanup();
#endif
for (; i < width; i += 2) {
uchar u = srcU[i / 2];
uchar v = srcV[i / 2];
int ruv, guv, buv;
uvToRGBuv(u, v, ruv, guv, buv);
for (int y = 0; y < 2; y++) {
for (int x = 0; x < 2; x++) {
uchar vy = srcY[y][i + x];
uchar r, g, b;
yRGBuvToRGB(vy, ruv, guv, buv, r, g, b);
dstRGBx[y][3 * (i + x)] = r;
dstRGBx[y][3 * (i + x) + 1] = g;
dstRGBx[y][3 * (i + x) + 2] = b;
}
}
}
}
//------------------------------------------------------------------------------
// vertical pass
template<typename T, typename A, typename I, typename W>
CV_ALWAYS_INLINE void downy(const T *src[], int inWidth, const MapperUnit<A, I>& ymap,
A yalpha, W vbuf[]) {
int y_1st = ymap.index0;
int ylast = ymap.index1 - 1;
// yratio > 1, so at least 2 rows
GAPI_DbgAssert(y_1st < ylast);
#if MANUAL_SIMD
constexpr int nlanes = v_uint16::nlanes;
#endif
// 1st and last rows
{
int w = 0;
#if MANUAL_SIMD
if (std::is_same<T, uint8_t>::value) {
for (; w <= inWidth - nlanes; w += nlanes) {
v_uint16 vsrc0 = vx_load_expand(reinterpret_cast<const uint8_t*>(& src[0][w]));
v_uint16 vsrc1 = vx_load_expand(reinterpret_cast<const uint8_t*>(& src[ylast - y_1st][w]));
v_uint16 vres = v_mulhi(vsrc0 << 8, static_cast<Q0_16>(ymap.alpha0)) +
v_mulhi(vsrc1 << 8, static_cast<Q0_16>(ymap.alpha1));
vx_store(reinterpret_cast<Q8_8*>(& vbuf[w]), vres);
}
}
#endif
for (; w < inWidth; w++) {
vbuf[w] = mulas(ymap.alpha0, src[0][w])
+ mulas(ymap.alpha1, src[ylast - y_1st][w]);
}
}
// inner rows (if any)
for (int i = 1; i < ylast - y_1st; i++) {
int w = 0;
#if MANUAL_SIMD
if (std::is_same<T, uint8_t>::value) {
for (; w <= inWidth - nlanes; w += nlanes) {
v_uint16 vsrc = vx_load_expand(reinterpret_cast<const uint8_t*>(& src[i][w]));
v_uint16 vres = vx_load(reinterpret_cast<Q8_8*>(& vbuf[w]));
vres = vres + v_mulhi(vsrc << 8, static_cast<Q0_16>(yalpha));
vx_store(reinterpret_cast<Q8_8*>(& vbuf[w]), vres);
}
}
#endif
for (; w < inWidth; w++) {
vbuf[w] += mulas(yalpha, src[i][w]);
}
}
}
// horizontal pass
template<typename T, typename A, typename I, typename W>
CV_ALWAYS_INLINE void downx(T dst[], int outWidth, int xmaxdf, const I xindex[],
const A xalpha[], const W vbuf[]) {
// TO DO: try lambda here
#define HSUM(xmaxdf) \
for (int x = 0; x < outWidth; x++) { \
int index = xindex[x]; \
const A *alpha = &xalpha[x * xmaxdf]; \
\
W sum = 0; \
for (int i = 0; i < xmaxdf; i++) { \
sum += mulaw(alpha[i], vbuf[index + i]); \
} \
\
dst[x] = convert_cast<T>(sum); \
}
if (2 == xmaxdf) {
HSUM(2);
} else if (3 == xmaxdf) {
HSUM(3);
} else if (4 == xmaxdf) {
HSUM(4);
} else if (5 == xmaxdf) {
HSUM(5);
} else if (6 == xmaxdf) {
HSUM(6);
} else if (7 == xmaxdf) {
HSUM(7);
} else if (8 == xmaxdf) {
HSUM(8);
} else {
HSUM(xmaxdf);
}
#undef HSUM
}
template<typename isa_tag_t, typename T, typename A, typename I, typename W>
CV_ALWAYS_INLINE void calcRowAreaImpl(isa_tag_t, T dst[], const T *src[],
const Size& inSz, const Size& outSz, A yalpha,
const MapperUnit<A, I>& ymap, int xmaxdf,
const I xindex[], const A xalpha[], W vbuf[]) {
bool xRatioEq1 = inSz.width == outSz.width;
bool yRatioEq1 = inSz.height == outSz.height;
if (!yRatioEq1 && !xRatioEq1) {
downy(src, inSz.width, ymap, yalpha, vbuf);
downx(dst, outSz.width, xmaxdf, xindex, xalpha, vbuf);
} else if (!yRatioEq1) {
GAPI_DbgAssert(xRatioEq1);
downy(src, inSz.width, ymap, yalpha, vbuf);
for (int x = 0; x < outSz.width; x++) {
dst[x] = convert_cast<T>(vbuf[x]);
}
} else if (!xRatioEq1) {
GAPI_DbgAssert(yRatioEq1);
for (int w = 0; w < inSz.width; w++) {
vbuf[w] = convert_cast<W>(src[0][w]);
}
downx(dst, outSz.width, xmaxdf, xindex, xalpha, vbuf);
} else {
GAPI_DbgAssert(xRatioEq1 && yRatioEq1);
memcpy(dst, src[0], outSz.width * sizeof(T));
}
}
//------------------------------------------------------------------------------
template <typename VecT, typename T>
CV_ALWAYS_INLINE void copyRow_Impl(const T in[], T out[], int length) {
int l = 0;
#if MANUAL_SIMD
const int nlanes = VecT::nlanes;
auto copy_row = [](const T in[], T out[], int l) {
VecT r = vx_load(&in[l]);
vx_store(&out[l], r);
};
for (; l <= length - nlanes; l += nlanes) {
copy_row(in, out, l);
}
if (l < length && length >= nlanes) {
copy_row(in, out, length - nlanes);
l = length;
}
#endif
for (; l < length; l++) {
out[l] = in[l];
}
}
// Resize (bi-linear, 32FC1)
template<typename isa_tag_t>
CV_ALWAYS_INLINE void calcRowLinear32FC1Impl(isa_tag_t,
float *dst[],
const float *src0[],
const float *src1[],
const float alpha[],
const int mapsx[],
const float beta[],
const Size& inSz,
const Size& outSz,
const int lpi,
const int) {
bool xRatioEq1 = inSz.width == outSz.width;
bool yRatioEq1 = inSz.height == outSz.height;
#if MANUAL_SIMD
constexpr int nlanes = v_float32::nlanes;
#endif
if (!xRatioEq1 && !yRatioEq1) {
for (int line = 0; line < lpi; ++line) {
float beta0 = beta[line];
float beta1 = 1 - beta0;
int x = 0;
#if MANUAL_SIMD
v_float32 low1, high1, s00, s01;
v_float32 low2, high2, s10, s11;
for (; x <= outSz.width - nlanes; x += nlanes) {
v_float32 alpha0 = vx_load(&alpha[x]);
// v_float32 alpha1 = 1.f - alpha0;
v_gather_pairs(src0[line], mapsx, x, low1, high1);
v_deinterleave(low1, high1, s00, s01);
// v_float32 res0 = s00*alpha0 + s01*alpha1;
v_float32 res0 = v_fma(s00 - s01, alpha0, s01);
v_gather_pairs(src1[line], mapsx, x, low2, high2);
v_deinterleave(low2, high2, s10, s11);
// v_float32 res1 = s10*alpha0 + s11*alpha1;
v_float32 res1 = v_fma(s10 - s11, alpha0, s11);
// v_float32 d = res0*beta0 + res1*beta1;
v_float32 d = v_fma(res0 - res1, beta0, res1);
vx_store(&dst[line][x], d);
}
#endif
for (; x < outSz.width; ++x) {
float alpha0 = alpha[x];
float alpha1 = 1 - alpha0;
int sx0 = mapsx[x];
int sx1 = sx0 + 1;
float res0 = src0[line][sx0] * alpha0 + src0[line][sx1] * alpha1;
float res1 = src1[line][sx0] * alpha0 + src1[line][sx1] * alpha1;
dst[line][x] = beta0 * res0 + beta1 * res1;
}
}
} else if (!xRatioEq1) {
GAPI_DbgAssert(yRatioEq1);
for (int line = 0; line < lpi; ++line) {
int x = 0;
#if MANUAL_SIMD
v_float32 low, high, s00, s01;
for (; x <= outSz.width - nlanes; x += nlanes) {
v_float32 alpha0 = vx_load(&alpha[x]);
// v_float32 alpha1 = 1.f - alpha0;
v_gather_pairs(src0[line], mapsx, x, low, high);
v_deinterleave(low, high, s00, s01);
// v_float32 d = s00*alpha0 + s01*alpha1;
v_float32 d = v_fma(s00 - s01, alpha0, s01);
vx_store(&dst[line][x], d);
}
#endif
for (; x < outSz.width; ++x) {
float alpha0 = alpha[x];
float alpha1 = 1 - alpha0;
int sx0 = mapsx[x];
int sx1 = sx0 + 1;
dst[line][x] = src0[line][sx0] * alpha0 + src0[line][sx1] * alpha1;
}
}
} else if (!yRatioEq1) {
GAPI_DbgAssert(xRatioEq1);
int length = inSz.width; // == outSz.width
for (int line = 0; line < lpi; ++line) {
float beta0 = beta[line];
float beta1 = 1 - beta0;
int x = 0;
#if MANUAL_SIMD
for (; x <= length - nlanes; x += nlanes) {
v_float32 s0 = vx_load(&src0[line][x]);
v_float32 s1 = vx_load(&src1[line][x]);
// v_float32 d = s0*beta0 + s1*beta1;
v_float32 d = v_fma(s0 - s1, beta0, s1);
vx_store(&dst[line][x], d);
}
#endif
for (; x < length; ++x) {
dst[line][x] = beta0 * src0[line][x] + beta1 * src1[line][x];
}
}
} else {
GAPI_DbgAssert(xRatioEq1 && yRatioEq1);
int length = inSz.width; // == outSz.width
for (int line = 0; line < lpi; ++line) {
memcpy(dst[line], src0[line], length * sizeof(float));
}
}
}
template<typename isa_tag_t, typename scalar_t>
struct vector_type_of;
template<typename isa_tag_t, typename scalar_t>
using vector_type_of_t = typename vector_type_of<isa_tag_t, scalar_t>::type;
template<typename isa_tag_t> struct vector_type_of<isa_tag_t, uint8_t> { using type = v_uint8; };
template<typename isa_tag_t> struct vector_type_of<isa_tag_t, float> { using type = v_float32;};
template<typename isa_tag_t, typename T>
CV_ALWAYS_INLINE void chanToPlaneRowImpl(isa_tag_t, const T* in, const int chan,
const int chs, T* out, const int length) {
if (chs == 1) {
copyRow_Impl<vector_type_of_t<isa_tag_t, T>, T>(in, out, length);
return;
}
for (int x = 0; x < length; x++) {
out[x] = in[x*chs + chan];
}
}
template<typename isa_tag_t, typename T, int chs>
CV_ALWAYS_INLINE void splitRowImpl(isa_tag_t, const T* in, std::array<T*, chs>& outs, const int length) {
static_assert(chs > 1 && chs < 5, "This number of channels isn't supported.");
if (chs == 2) {
splitRowC2_Impl<vector_type_of_t<isa_tag_t, T>, T>(in, outs[0], outs[1], length);
return;
} else if (chs == 3) {
splitRowC3_Impl<vector_type_of_t<isa_tag_t, T>, T>(in, outs[0], outs[1], outs[2], length);
return;
} else {
splitRowC4_Impl<vector_type_of_t<isa_tag_t, T>, T>(in, outs[0], outs[1], outs[2], outs[3], length);
return;
}
}
template<typename isa_tag_t, typename T, int chs>
CV_ALWAYS_INLINE void mergeRowImpl(isa_tag_t, const std::array<const T*, chs>& ins, T* out, const int length) {
static_assert(chs > 1 && chs < 5, "This number of channels isn't supported.");
if (chs == 2) {
mergeRowC2_Impl<vector_type_of_t<isa_tag_t, T>, T>(ins[0], ins[1], out, length);
return;
} else if (chs == 3) {
mergeRowC3_Impl<vector_type_of_t<isa_tag_t, T>, T>(ins[0], ins[1], ins[2], out, length);
return;
} else {
mergeRowC4_Impl<vector_type_of_t<isa_tag_t, T>, T>(ins[0], ins[1], ins[2], ins[3], out, length);
return;
}
}
} // namespace kernels
} // namespace gapi
} // namespace InferenceEngine
#endif // IE_PREPROCESS_GAPI_KERNELS_SIMD_IMPL_H

View File

@ -1,20 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
/**
* @brief Defines openvino domains for tracing
* @file ie_preprocess_itt.hpp
*/
#pragma once
#include <openvino/itt.hpp>
namespace InferenceEngine {
namespace itt {
namespace domains {
OV_ITT_DOMAIN(IEPreproc);
}
}
}

View File

@ -1,46 +0,0 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
set(TARGET fluid_preproc_tests)
ov_disable_deprecated_warnings()
find_package(OpenCV QUIET COMPONENTS gapi core imgproc)
if(NOT OpenCV_FOUND OR NOT OpenCV_VERSION VERSION_GREATER_EQUAL 4)
message(WARNING "OpenCV ver. 4.0+ is not found, ${TARGET} skipped")
return()
endif()
add_subdirectory(fluid_test_computations)
file(GLOB SOURCES *.cpp common/*.cpp cpu/*.cpp)
file(GLOB HEADERS *.hpp common/*.hpp cpu/*.hpp)
add_executable(${TARGET} ${SOURCES} ${HEADERS})
target_include_directories(${TARGET} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/common"
"${CMAKE_CURRENT_SOURCE_DIR}/cpu"
$<TARGET_PROPERTY:inference_engine_plugin_api,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_definitions(${TARGET} PRIVATE
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(${TARGET} PRIVATE opencv_core opencv_imgproc openvino::util
inference_engine fluid_test_computations gtest gtest_main)
if(GAPI_TEST_PERF)
target_compile_definitions(${TARGET} PRIVATE -DPERF_TEST=1)
else()
target_compile_definitions(${TARGET} PRIVATE -DPERF_TEST=0)
endif()
add_test(NAME ${TARGET} COMMAND ${TARGET})
set_property(TEST ${TARGET} PROPERTY LABELS IE PREPROC)
install(TARGETS ${TARGET}
RUNTIME DESTINATION tests
COMPONENT tests
EXCLUDE_FROM_ALL)

File diff suppressed because it is too large Load Diff

View File

@ -1,83 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FLUID_TESTS_HPP
#define FLUID_TESTS_HPP
#include "fluid_tests_common.hpp"
#include "ie_preprocess.hpp"
#include <gtest/gtest.h>
struct ResizeTestGAPI: public testing::TestWithParam<std::tuple<int, int, std::pair<cv::Size, cv::Size>, double>> {};
struct ResizeRGB8UTestGAPI: public testing::TestWithParam<std::tuple<int, int, std::pair<cv::Size, cv::Size>, double>> {};
struct SplitTestGAPI: public TestParams<std::tuple<int, int, cv::Size, double>> {};
struct ChanToPlaneTestGAPI: public TestParams<std::tuple<int, int, cv::Size, double>> {};
struct MergeTestGAPI: public TestParams<std::tuple<int, int, cv::Size, double>> {};
struct NV12toRGBTestGAPI: public TestParams<std::tuple<cv::Size, double>> {};
struct I420toRGBTestGAPI: public TestParams<std::tuple<cv::Size, double>> {};
struct ResizeRoiTestGAPI: public testing::TestWithParam<std::tuple<int, int, std::pair<cv::Size, cv::Size>, cv::Rect, double>> {};
struct ResizeRGB8URoiTestGAPI: public testing::TestWithParam<std::tuple<int, int, std::pair<cv::Size, cv::Size>, cv::Rect, double>> {};
struct ConvertDepthTestGAPI: public TestParams<std::tuple<
int, // input matrix depth
int, // output matrix depth
cv::Size,
double>> // tolerance
{};
struct DivCTestGAPI: public TestParams<std::tuple<
int, // input matrix depth
int, // input matrix channels number
cv::Size,
cv::Scalar, // second operarnd
double>> // tolerance
{};
struct SubCTestGAPI : public DivCTestGAPI
{};
struct MeanValueGAPI: public TestParams<std::tuple<cv::Size, double>> {};
//------------------------------------------------------------------------------
struct ResizeTestIE: public testing::TestWithParam<std::tuple<int, int, std::pair<cv::Size, cv::Size>, double>> {};
struct SplitTestIE: public TestParams<std::tuple<int, cv::Size, double>> {};
struct MergeTestIE: public TestParams<std::tuple<int, cv::Size, double>> {};
struct ColorConvertTestIE:
public testing::TestWithParam<std::tuple<int, // matrix depth
InferenceEngine::ColorFormat, // input color format
InferenceEngine::Layout, // input layout
InferenceEngine::Layout, // output layout
cv::Size, // matrix size (input and output)
double>> // tolerance
{};
struct ColorConvertYUV420TestIE:
public testing::TestWithParam<std::tuple<InferenceEngine::ColorFormat, // input color format NV12 or I420
InferenceEngine::Layout, // output layout
cv::Size, // matrix size (input and output)
double>> // tolerance
{};
struct PrecisionConvertTestIE: public TestParams<std::tuple<cv::Size,
int, // input matrix depth
int, // output matrix depth
double>> // tolerance
{};
//------------------------------------------------------------------------------
using PreprocParams = std::tuple< std::pair<InferenceEngine::Precision // input data type
, InferenceEngine::Precision> // output data type
, InferenceEngine::ResizeAlgorithm // resize algorithm, if needed
, InferenceEngine::ColorFormat // input color format, if needed
, InferenceEngine::Layout // input tensor layout
, InferenceEngine::Layout // output tensor layout
, std::pair<int, int> // number of input and output channels
, std::pair<cv::Size, cv::Size>
>;
struct PreprocTest: public TestParams<PreprocParams> {};
#endif //FLUID_TESTS_HPP

View File

@ -1,71 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/gapi/cpu/core.hpp"
#include <gtest/gtest.h>
class TestFunctional
{
public:
cv::Mat in_mat1;
cv::Mat in_mat2;
cv::Mat out_mat_gapi;
cv::Mat out_mat_ocv;
cv::Scalar sc;
void initMatsRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
{
in_mat1 = cv::Mat(sz_in, type);
in_mat2 = cv::Mat(sz_in, type);
auto& rng = cv::theRNG();
sc = cv::Scalar(rng(100),rng(100),rng(100),rng(100));
cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
cv::randu(in_mat2, cv::Scalar::all(0), cv::Scalar::all(255));
if (createOutputMatrices && dtype != -1)
{
out_mat_gapi = cv::Mat (sz_in, dtype);
out_mat_ocv = cv::Mat (sz_in, dtype);
}
}
void initMatrixRandU(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
{
in_mat1 = cv::Mat(sz_in, type);
auto& rng = cv::theRNG();
sc = cv::Scalar(rng(100),rng(100),rng(100),rng(100));
cv::randu(in_mat1, cv::Scalar::all(0), cv::Scalar::all(255));
if (createOutputMatrices && dtype != -1)
{
out_mat_gapi = cv::Mat (sz_in, dtype);
out_mat_ocv = cv::Mat (sz_in, dtype);
}
}
void initMatsRandN(int type, cv::Size sz_in, int dtype, bool createOutputMatrices = true)
{
in_mat1 = cv::Mat(sz_in, type);
cv::randn(in_mat1, cv::Scalar::all(127), cv::Scalar::all(40.f));
if (createOutputMatrices && dtype != -1)
{
out_mat_gapi = cv::Mat(sz_in, dtype);
out_mat_ocv = cv::Mat(sz_in, dtype);
}
}
};
template<class T>
class TestParams: public TestFunctional, public testing::TestWithParam<T>{};

View File

@ -1,413 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "fluid_tests.hpp"
#include <opencv2/opencv.hpp>
#include <gtest/gtest.h>
#define TEST_SIZES \
cv::Size(3840, 2160), \
cv::Size(1920, 1080), \
cv::Size(1280, 720), \
cv::Size(1280, 960), \
cv::Size( 960, 720), \
cv::Size( 640, 480), \
cv::Size( 320, 200), \
cv::Size( 113, 71)
#define TEST_RESIZE_DOWN \
std::make_pair(cv::Size(3840, 2160), cv::Size(1920, 1080)), \
std::make_pair(cv::Size(3840, 2160), cv::Size(1280, 720)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(1280, 720)), \
std::make_pair(cv::Size(1920, 1080), cv::Size( 640, 480)), \
std::make_pair(cv::Size(1280, 720), cv::Size( 640, 480)), \
std::make_pair(cv::Size(1280, 720), cv::Size( 320, 200)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 320, 200)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 113, 71)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 113, 71))
#define TEST_RESIZE_UP \
std::make_pair(cv::Size(1920, 1080), cv::Size(3840, 2160)), \
std::make_pair(cv::Size(1280, 720), cv::Size(3840, 2160)), \
std::make_pair(cv::Size(1280, 720), cv::Size(1920, 1080)), \
std::make_pair(cv::Size( 640, 480), cv::Size(1920, 1080)), \
std::make_pair(cv::Size( 640, 480), cv::Size(1280, 720)), \
std::make_pair(cv::Size( 320, 200), cv::Size(1280, 720)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 640, 480)), \
std::make_pair(cv::Size( 113, 71), cv::Size( 640, 480)), \
std::make_pair(cv::Size( 113, 71), cv::Size( 320, 200))
#define TEST_RESIZE_HORZ \
std::make_pair(cv::Size(3840, 2160), cv::Size(1920, 2160)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(3840, 1080)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(1280, 1080)), \
std::make_pair(cv::Size(1280, 720), cv::Size(1920, 720)), \
std::make_pair(cv::Size(1280, 720), cv::Size( 640, 720)), \
std::make_pair(cv::Size( 640, 480), cv::Size(1280, 480)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 320, 480)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 640, 200)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 113, 200)), \
std::make_pair(cv::Size( 113, 71), cv::Size( 320, 71))
#define TEST_RESIZE_VERT \
std::make_pair(cv::Size(3840, 2160), cv::Size(3840, 1080)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(1920, 2160)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(1920, 720)), \
std::make_pair(cv::Size(1280, 720), cv::Size(1280, 1080)), \
std::make_pair(cv::Size(1280, 720), cv::Size(1280, 480)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 640, 720)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 640, 200)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 320, 480)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 320, 71)), \
std::make_pair(cv::Size( 113, 71), cv::Size( 113, 200))
#define TEST_RESIZE_COPY \
std::make_pair(cv::Size(3840, 2160), cv::Size(3840, 2160)), \
std::make_pair(cv::Size(1920, 1080), cv::Size(1920, 1080)), \
std::make_pair(cv::Size(1280, 720), cv::Size(1280, 720)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 640, 480)), \
std::make_pair(cv::Size( 320, 200), cv::Size( 320, 200)), \
std::make_pair(cv::Size( 113, 71), cv::Size( 113, 71))
#define TEST_RESIZE_SPECIAL \
std::make_pair(cv::Size(300, 300), cv::Size(300, 199)), \
std::make_pair(cv::Size(300, 300), cv::Size(199, 300)), \
std::make_pair(cv::Size(300, 300), cv::Size(199, 199)), \
std::make_pair(cv::Size(199, 199), cv::Size(300, 300)), \
std::make_pair(cv::Size(199, 300), cv::Size(300, 300)), \
std::make_pair(cv::Size(300, 199), cv::Size(300, 300))
#define TEST_RESIZE_PAIRS \
TEST_RESIZE_DOWN, \
TEST_RESIZE_UP, \
TEST_RESIZE_HORZ, \
TEST_RESIZE_VERT, \
TEST_RESIZE_COPY, \
TEST_RESIZE_SPECIAL
#define TEST_SIZES_PREPROC \
std::make_pair(cv::Size(1920, 1080), cv::Size(1024, 1024)), \
std::make_pair(cv::Size(1280, 720), cv::Size( 544, 320)), \
std::make_pair(cv::Size( 640, 480), cv::Size( 896, 512)), \
std::make_pair(cv::Size( 200, 400), cv::Size( 128, 384)), \
std::make_pair(cv::Size( 256, 256), cv::Size( 72, 72)), \
std::make_pair(cv::Size( 96, 256), cv::Size( 128, 384))
using namespace testing;
#if defined(__arm__) || defined(__aarch64__)
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_U8, ResizeTestGAPI,
Combine(Values(CV_8UC1, CV_8UC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(4))); // error not more than 4 unit
INSTANTIATE_TEST_SUITE_P(ResizeRGB8UTestFluid_U8, ResizeRGB8UTestGAPI,
Combine(Values(CV_8UC3, CV_8UC4),
Values(cv::INTER_LINEAR),
Values(TEST_RESIZE_PAIRS),
Values(4))); // error not more than 4 unit
#else
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_U8, ResizeTestGAPI,
Combine(Values(CV_8UC1, CV_8UC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(1))); // error not more than 1 unit
INSTANTIATE_TEST_SUITE_P(ResizeRGB8UTestFluid_U8, ResizeRGB8UTestGAPI,
Combine(Values(CV_8UC3, CV_8UC4),
Values(cv::INTER_LINEAR),
Values(TEST_RESIZE_PAIRS),
Values(1))); // error not more than 1 unit
#endif
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_F32, ResizeTestGAPI,
Combine(Values(CV_32FC1, CV_32FC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(0.015))); // accuracy like ~1.5%
INSTANTIATE_TEST_SUITE_P(SplitTestFluid, SplitTestGAPI,
Combine(Values(2, 3, 4),
Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_16F, CV_32F, CV_32S),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(ChanToPlaneTestFluid, ChanToPlaneTestGAPI,
Combine(Values(1, 3),
Values(CV_8U, CV_32F),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(MergeTestFluid, MergeTestGAPI,
Combine(Values(2, 3, 4),
Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_16F, CV_32F, CV_32S),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(NV12toRGBTestFluid, NV12toRGBTestGAPI,
Combine(Values(cv::Size(3840, 2160),
cv::Size(1920, 1080),
cv::Size(1280, 720),
cv::Size(1280, 960),
cv::Size( 960, 720),
cv::Size( 640, 480),
cv::Size( 300, 300),
cv::Size( 320, 200)),
Values(1)));
INSTANTIATE_TEST_SUITE_P(I420toRGBTestFluid, I420toRGBTestGAPI,
Combine(Values(cv::Size(3840, 2160),
cv::Size(1920, 1080),
cv::Size(1280, 720),
cv::Size(1280, 960),
cv::Size( 960, 720),
cv::Size( 640, 480),
cv::Size( 300, 300),
cv::Size( 320, 200)),
Values(1)));
INSTANTIATE_TEST_SUITE_P(ConvertDepthFluid, ConvertDepthTestGAPI,
Combine(Values(CV_16U, CV_32F, CV_8U),
Values(CV_32F, CV_16U, CV_8U),
Values(cv::Size(3840, 2160),
cv::Size(1920, 1080),
cv::Size(1280, 720),
cv::Size(1280, 960),
cv::Size( 960, 720),
cv::Size( 640, 480),
cv::Size( 300, 300),
cv::Size( 320, 200)),
Values(1)));
INSTANTIATE_TEST_SUITE_P(DivCFluid, DivCTestGAPI,
Combine(Values(CV_32F),
Values(1), //channels
Values(TEST_SIZES),
Values(cv::Scalar{0.229}),
Values(0)));
INSTANTIATE_TEST_SUITE_P(SubCFluid, SubCTestGAPI,
Combine(Values(CV_32F),
Values(1), //channels
Values(TEST_SIZES),
Values(cv::Scalar{0.229}),
Values(0.00001)));
INSTANTIATE_TEST_SUITE_P(ResizeRoiTestFluid, ResizeRoiTestGAPI,
Combine(Values(CV_8UC1, CV_8UC3),
Values(cv::INTER_LINEAR),
Values(std::make_pair(cv::Size(24, 24), cv::Size(12, 12))),
Values(cv::Rect{0, 0, 12, 3},
cv::Rect{0, 3, 12, 3},
cv::Rect{0, 6, 12, 3},
cv::Rect{0, 9, 12, 3}),
Values(1))); // error not more than 1 unit
INSTANTIATE_TEST_SUITE_P(ResizeRGB8URoiTestFluid, ResizeRGB8URoiTestGAPI,
Combine(Values(CV_8UC3, CV_8UC4),
Values(cv::INTER_LINEAR),
Values(std::make_pair(cv::Size(24, 24), cv::Size(12, 12))),
Values(cv::Rect{0, 0, 12, 3},
cv::Rect{0, 3, 12, 3},
cv::Rect{0, 6, 12, 3},
cv::Rect{0, 9, 12, 3}),
Values(1))); // error not more than 1 unit
//----------------------------------------------------------------------
#if defined(__arm__) || defined(__aarch64__)
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_U8, ResizeTestIE,
Combine(Values(CV_8UC1, CV_8UC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(4))); // error not more than 4 unit
#else
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_U8, ResizeTestIE,
Combine(Values(CV_8UC1, CV_8UC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(1))); // error not more than 1 unit
#endif
INSTANTIATE_TEST_SUITE_P(ResizeTestFluid_F32, ResizeTestIE,
Combine(Values(CV_32FC1, CV_32FC3),
Values(cv::INTER_LINEAR, cv::INTER_AREA),
Values(TEST_RESIZE_PAIRS),
Values(0.05))); // error within 0.05 units
INSTANTIATE_TEST_SUITE_P(SplitTestFluid, SplitTestIE,
Combine(Values(CV_8UC2, CV_8UC3, CV_8UC4,
CV_32FC2, CV_32FC3, CV_32FC4),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(MergeTestFluid, MergeTestIE,
Combine(Values(CV_8UC2, CV_8UC3, CV_8UC4,
CV_32FC2, CV_32FC3, CV_32FC4),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(ColorConvertFluid_3ch, ColorConvertTestIE,
Combine(Values(CV_8U, CV_32F),
Values(InferenceEngine::ColorFormat::RGB),
Values(InferenceEngine::NHWC, InferenceEngine::NCHW),
Values(InferenceEngine::NHWC, InferenceEngine::NCHW),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(ColorConvertFluid_4ch, ColorConvertTestIE,
Combine(Values(CV_8U, CV_32F),
Values(InferenceEngine::ColorFormat::RGBX,
InferenceEngine::ColorFormat::BGRX),
Values(InferenceEngine::NHWC),
Values(InferenceEngine::NHWC, InferenceEngine::NCHW),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(Reorder_HWC2CHW, ColorConvertTestIE,
Combine(Values(CV_8U, CV_32F, CV_16S, CV_16F),
Values(InferenceEngine::ColorFormat::BGR),
Values(InferenceEngine::NHWC),
Values(InferenceEngine::NCHW),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(Reorder_CHW2HWC, ColorConvertTestIE,
Combine(Values(CV_8U, CV_32F, CV_16S, CV_16F),
Values(InferenceEngine::ColorFormat::BGR),
Values(InferenceEngine::NCHW),
Values(InferenceEngine::NHWC),
Values(TEST_SIZES),
Values(0)));
INSTANTIATE_TEST_SUITE_P(MeanValueGAPI32F, MeanValueGAPI,
Combine(Values(TEST_SIZES),
Values(0.00001)));
//------------------------------------------------------------------------------
namespace IE = InferenceEngine;
static const auto FRAME_SIZES =
Values(std::make_pair(cv::Size(1920,1080),
cv::Size(1024,1024)), // person-vehicle-bike-detection-crossroad-0078
std::make_pair(cv::Size(1024, 768),
cv::Size( 992, 544)), // person-detection-retail-0001
std::make_pair(cv::Size(1280, 720),
cv::Size( 896, 512)), // road-segmentation-adas-0001
std::make_pair(cv::Size(3840, 2160),
cv::Size(2048, 1024)), // semantic-segmentation-adas-0001
std::make_pair(cv::Size(1270, 720),
cv::Size(2048, 1024)), // semantic-segmentation-adas-0001 (UPSCALE)
std::make_pair(cv::Size( 640, 480),
cv::Size( 544, 320))); // 320 - face-person-detection-retail-0002,
// 320 - person-detection-retail-10013
// 300 - face-detection-retail-0004
static const auto PATCH_SIZES =
Values(std::make_pair(cv::Size(200,400),
cv::Size(128,384)), // person-reidentification-retail-0076
std::make_pair(cv::Size( 96,256),
cv::Size(128,384)), // person-reidentification-retail-0076 (UPSCALE)
std::make_pair(cv::Size(340,340),
cv::Size(320,256)), // vehicle-license-plate-detection-barrier-0007
std::make_pair(cv::Size(256,256),
cv::Size( 72,72)), // vehicle-attributes-recognition-barrier-0039
std::make_pair(cv::Size(96,96),
cv::Size(64,64)), // 60 - head-pose-estimation-adas-0001
// 62 - age-gender-recognition-retail-0013
// 64 - emotions-recognition-retail-0003
std::make_pair(cv::Size(128,48),
cv::Size( 94,24)), // license-plate-recognition-barrier-0001
std::make_pair(cv::Size(120,200),
cv::Size(80, 160))); // 80 - person-attributes-recognition-crossroad-0031
// 64 - person-reidentification-retail-0079
static const auto U8toU8 = std::make_pair(IE::Precision::U8,IE::Precision::U8);
static const auto PRECISIONS = Values(U8toU8, std::make_pair(IE::Precision::FP32,IE::Precision::FP32));
INSTANTIATE_TEST_SUITE_P(ReorderResize_Frame, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR), // AREA is not there yet
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC),
Values(IE::Layout::NCHW),
Values(std::make_pair(1, 1), std::make_pair(3, 3)),
FRAME_SIZES));
INSTANTIATE_TEST_SUITE_P(Scale3ch_Frame, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR), // AREA is not there yet
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC),
Values(IE::Layout::NHWC),
Values(std::make_pair(3, 3)),
FRAME_SIZES));
INSTANTIATE_TEST_SUITE_P(ReorderResize_Patch, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR), // AREA is not there yet
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC),
Values(IE::Layout::NCHW, IE::Layout::NCHW),
Values(std::make_pair(1, 1), std::make_pair(3, 3)),
PATCH_SIZES));
INSTANTIATE_TEST_SUITE_P(Everything_Resize, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR, IE::ResizeAlgorithm::RESIZE_AREA),
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(std::make_pair(1, 1),
std::make_pair(2, 2),
std::make_pair(3, 3),
std::make_pair(4, 4)),
Values(TEST_SIZES_PREPROC)));
INSTANTIATE_TEST_SUITE_P(ColorFormats_3ch, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR, IE::ResizeAlgorithm::RESIZE_AREA),
Values(IE::ColorFormat::RGB),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(std::make_pair(3, 3)),
Values(TEST_SIZES_PREPROC)));
INSTANTIATE_TEST_SUITE_P(ColorFormats_4ch, PreprocTest,
Combine(PRECISIONS,
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR, IE::ResizeAlgorithm::RESIZE_AREA),
Values(IE::ColorFormat::BGRX, IE::ColorFormat::RGBX),
Values(IE::Layout::NHWC),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(std::make_pair(4, 3)),
Values(TEST_SIZES_PREPROC)));
INSTANTIATE_TEST_SUITE_P(PlainPrecisionConversions, PreprocTest,
Combine(Values(std::make_pair(IE::Precision::U16,IE::Precision::FP32),
std::make_pair(IE::Precision::FP32,IE::Precision::U16)
),
Values(IE::ResizeAlgorithm::NO_RESIZE),
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC),
Values(IE::Layout::NHWC),
Values(std::make_pair(1, 1)),
Values(std::make_pair(cv::Size(640,480), cv::Size(640,480)))));
INSTANTIATE_TEST_SUITE_P(PrecisionConversionsPipelines, PreprocTest,
Combine(Values(std::make_pair(IE::Precision::U16, IE::Precision::FP32),
std::make_pair(IE::Precision::FP32,IE::Precision::U8),
std::make_pair(IE::Precision::U8, IE::Precision::FP32)
),
Values(IE::ResizeAlgorithm::RESIZE_BILINEAR),
Values(IE::ColorFormat::RAW),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(IE::Layout::NHWC, IE::Layout::NCHW),
Values(std::make_pair(1, 1), std::make_pair(3, 3)),
Values(TEST_SIZES_PREPROC)));

View File

@ -1,22 +0,0 @@
# Copyright (C) 2018-2023 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
#
file(GLOB SRC *.cpp)
file(GLOB HDR *.hpp)
set(TARGET_NAME fluid_test_computations)
add_library(${TARGET_NAME} STATIC ${SRC} ${HDR})
# Workaround to avoid warnings caused with bug in the avx512intrin.h of GCC5
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND
(CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.5))
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS_RELEASE "-Wno-error=maybe-uninitialized -Wno-maybe-uninitialized")
endif()
target_include_directories(${TARGET_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(${TARGET_NAME} PRIVATE openvino_gapi_preproc_s inference_engine fluid opencv_gapi)
add_dependencies(${TARGET_NAME} openvino_gapi_preproc)

View File

@ -1,314 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <fluid_test_computations.hpp>
#include <opencv2/gapi.hpp>
#include <ie_preprocess_gapi_kernels.hpp>
#include <opencv2/gapi/fluid/gfluidkernel.hpp>
#define CV_MAT_CHANNELS(flags) (((flags) >> CV_CN_SHIFT) + 1)
struct FluidComputation::Priv
{
cv::GComputation m_c;
cv::GRunArgs m_v_in;
std::vector<cv::gapi::own::Mat> m_v_out;
Priv(cv::GComputation && c, std::vector<cv::gapi::own::Mat>&& v_in, std::vector<cv::gapi::own::Mat>&& v_out)
: m_c(std::move(c)),
m_v_in(v_in.begin(), v_in.end()),
m_v_out(std::move(v_out))
{}
Priv(cv::GComputation && c, cv::gapi::own::Mat&& v_in, cv::gapi::own::Mat&& v_out)
: m_c(std::move(c)),
m_v_in{std::move(v_in)},
m_v_out{std::move(v_out)}
{}
Priv(cv::GComputation && c, cv::gapi::own::Mat&& v_in, std::vector<cv::gapi::own::Mat>&& v_out)
: m_c(std::move(c)),
m_v_in{std::move(v_in)},
m_v_out(std::move(v_out))
{}
Priv(cv::GComputation && c, cv::GRunArgs&& v_in, std::vector<cv::gapi::own::Mat>&& v_out)
: m_c(std::move(c)),
m_v_in(std::move(v_in)),
m_v_out(std::move(v_out))
{}
cv::GRunArgs ins() { return m_v_in;}
cv::GRunArgsP outs() {
cv::GRunArgsP call_outs;
for (auto &m : m_v_out) { call_outs.emplace_back(&m); }
return call_outs;
}
};
FluidComputation::FluidComputation(Priv *priv)
: m_priv(priv)
{}
namespace
{
cv::gapi::own::Rect to_own(test::Rect rect) { return {rect.x, rect.y, rect.width, rect.height}; }
}
void FluidComputation::warmUp(test::Rect roi)
{
auto compile_args = roi.empty() ? cv::compile_args(InferenceEngine::gapi::preprocKernels())
: cv::compile_args(InferenceEngine::gapi::preprocKernels(),
cv::GFluidOutputRois{{to_own(roi)}});
m_priv->m_c.apply(m_priv->ins(), m_priv->outs(), std::move(compile_args));
}
void FluidComputation::apply()
{
m_priv->m_c.apply(m_priv->ins(), m_priv->outs());
}
namespace
{
cv::gapi::own::Scalar to_own(test::Scalar const& s) {
return {s.v[0], s.v[1], s.v[2], s.v[3]};
}
cv::gapi::own::Mat to_own(test::Mat mat) {
return {mat.rows, mat.cols, mat.type, mat.data, mat.step};
}
std::vector<cv::gapi::own::Mat> to_own(std::vector<test::Mat> mats)
{
std::vector<cv::gapi::own::Mat> own_mats(mats.size());
for (size_t i = 0; i < mats.size(); i++) {
own_mats[i] = to_own(mats[i]);
}
return own_mats;
}
template<typename... Ts, int... IIs>
std::vector<cv::GMat> to_vec_impl(std::tuple<Ts...> &&gmats, cv::detail::Seq<IIs...>) {
return { std::get<IIs>(gmats)... };
}
template<typename... Ts>
std::vector<cv::GMat> to_vec(std::tuple<Ts...> &&gmats) {
return to_vec_impl(std::move(gmats), typename cv::detail::MkSeq<sizeof...(Ts)>::type());
}
} // anonymous namespace
static cv::GComputation buildResizeComputation(test::Mat inMat, test::Mat outMat, int interp)
{
cv::gapi::own::Size sz_in { inMat.cols, inMat.rows};
cv::gapi::own::Size sz_out {outMat.cols, outMat.rows};
int type = outMat.type;
cv::GMat in, out;
switch (CV_MAT_CHANNELS(type)) {
case 1:
out = InferenceEngine::gapi::ScalePlane::on(in, type, sz_in, sz_out, interp);
break;
case 3:
{
int depth = CV_MAT_DEPTH(type);
int type1 = CV_MAKE_TYPE(depth, 1);
cv::GMat in0, in1, in2, out0, out1, out2;
std::tie(in0, in1, in2) = InferenceEngine::gapi::Split3::on(in);
out0 = InferenceEngine::gapi::ScalePlane::on(in0, type1, sz_in, sz_out, interp);
out1 = InferenceEngine::gapi::ScalePlane::on(in1, type1, sz_in, sz_out, interp);
out2 = InferenceEngine::gapi::ScalePlane::on(in2, type1, sz_in, sz_out, interp);
out = InferenceEngine::gapi::Merge3::on(out0, out1, out2);
}
break;
default: GAPI_Assert(!"ERROR: unsupported number of channels!");
}
return cv::GComputation(in, out);
}
FluidResizeComputation::FluidResizeComputation(test::Mat inMat, test::Mat outMat, int interp)
: FluidComputation(new Priv{buildResizeComputation(inMat, outMat, interp)
,to_own(inMat)
,to_own(outMat)
})
{}
static cv::GComputation buildResizeRGB8UComputation(test::Mat inMat, test::Mat outMat, int interp)
{
cv::gapi::own::Size sz_in { inMat.cols, inMat.rows};
cv::gapi::own::Size sz_out {outMat.cols, outMat.rows};
int type = outMat.type;
cv::GMat in, out, out_r, out_g, out_b, out_x;
if (type == CV_8UC3) {
std::tie(out_r, out_g, out_b) = InferenceEngine::gapi::ScalePlanes::on(in, type, sz_in, sz_out, interp);
out = InferenceEngine::gapi::Merge3::on(out_r, out_g, out_b);
}
else if (type == CV_8UC4) {
std::tie(out_r, out_g, out_b, out_x) = InferenceEngine::gapi::ScalePlanes4::on(in, type, sz_in, sz_out, interp);
out = InferenceEngine::gapi::Merge4::on(out_r, out_g, out_b, out_x);
} else {
GAPI_Assert(!"ERROR: unsupported number of channels!");
}
return cv::GComputation(in, out);
}
FluidResizeRGB8UComputation::FluidResizeRGB8UComputation(test::Mat inMat, test::Mat outMat, int interp)
: FluidComputation(new Priv{buildResizeRGB8UComputation(inMat, outMat, interp)
,to_own(inMat)
,to_own(outMat)
})
{}
static cv::GComputation buildSplitComputation(int planes)
{
std::vector<cv::GMat> ins(1);
std::vector<cv::GMat> outs(planes);
switch (planes) {
case 2: outs = to_vec(InferenceEngine::gapi::Split2::on(ins[0])); break;
case 3: outs = to_vec(InferenceEngine::gapi::Split3::on(ins[0])); break;
case 4: outs = to_vec(InferenceEngine::gapi::Split4::on(ins[0])); break;
default: GAPI_Assert(false);
}
return cv::GComputation(ins, outs);
}
FluidSplitComputation::FluidSplitComputation(test::Mat inMat, std::vector<test::Mat> outMats)
: FluidComputation(new Priv{buildSplitComputation(outMats.size())
,to_own(inMat)
,to_own(outMats)
})
{}
static cv::GComputation buildChanToPlaneComputation(int chan)
{
cv::GMat in, out;
out = InferenceEngine::gapi::ChanToPlane::on(in, chan);
return cv::GComputation(in, out);
}
FluidChanToPlaneComputation::FluidChanToPlaneComputation(test::Mat inMat, test::Mat outMat, int chan)
: FluidComputation(new Priv{buildChanToPlaneComputation(chan)
,to_own(inMat)
,to_own(outMat)
})
{}
static cv::GComputation buildMergeComputation(int planes)
{
std::vector<cv::GMat> ins(planes);
std::vector<cv::GMat> outs(1);
switch (planes) {
case 2: outs[0] = InferenceEngine::gapi::Merge2::on(ins[0], ins[1]); break;
case 3: outs[0] = InferenceEngine::gapi::Merge3::on(ins[0], ins[1], ins[2]); break;
case 4: outs[0] = InferenceEngine::gapi::Merge4::on(ins[0], ins[1], ins[2], ins[3]); break;
default: GAPI_Assert(false);
}
return cv::GComputation(ins, outs);
}
FluidMergeComputation::FluidMergeComputation(std::vector<test::Mat> inMats, test::Mat outMat)
: FluidComputation(new Priv{buildMergeComputation(inMats.size())
,to_own(inMats)
,{to_own(outMat)}
})
{}
static cv::GComputation buildFluidNV12toRGBComputation()
{
cv::GMat in_y, in_uv;
cv::GMat out = InferenceEngine::gapi::NV12toRGB::on(in_y,in_uv);
return cv::GComputation(cv::GIn(in_y,in_uv), cv::GOut(out));
}
FluidNV12toRGBComputation::FluidNV12toRGBComputation(test::Mat inMat_y, test::Mat inMat_uv, test::Mat outMat)
: FluidComputation(new Priv{buildFluidNV12toRGBComputation()
,to_own({inMat_y,inMat_uv})
,{to_own(outMat)}
})
{}
static cv::GComputation buildFluidI420toRGBComputation()
{
cv::GMat in_y, in_u, in_v;
cv::GMat out = InferenceEngine::gapi::I420toRGB::on(in_y, in_u, in_v);
return cv::GComputation(cv::GIn(in_y, in_u, in_v), cv::GOut(out));
}
FluidI420toRGBComputation::FluidI420toRGBComputation(test::Mat inMat_y, test::Mat inMat_u, test::Mat inMat_v, test::Mat outMat)
: FluidComputation(new Priv{buildFluidI420toRGBComputation()
,to_own({inMat_y,inMat_u, inMat_v})
,{to_own(outMat)}
})
{}
ConvertDepthComputation::ConvertDepthComputation(test::Mat inMat, test::Mat outMat, int depth)
: FluidComputation(new Priv{ [depth]()-> cv::GComputation {
cv::GMat in;
cv::GMat out = InferenceEngine::gapi::ConvertDepth::on(in, depth);
return cv::GComputation(cv::GIn(in), cv::GOut(out));
}()
, to_own(inMat)
, to_own(outMat)
})
{}
DivCComputation::DivCComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& c)
: FluidComputation(new Priv{ []()-> cv::GComputation {
cv::GMat in;
cv::GScalar C;
cv::GMat out = in / C;
return cv::GComputation(cv::GIn(in, C), cv::GOut(out));
}()
, cv::GRunArgs{cv::GRunArg{to_own(inMat)}, cv::GRunArg{to_own(c)}}
, {to_own(outMat)}
})
{}
SubCComputation::SubCComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& c)
: FluidComputation(new Priv{ []()-> cv::GComputation{
cv::GMat in;
cv::GScalar C;
cv::GMat out = in - C;
return cv::GComputation(cv::GIn(in, C), cv::GOut(out));
}()
, cv::GRunArgs{cv::GRunArg{to_own(inMat)}, cv::GRunArg{to_own(c)}}
, {to_own(outMat)}
})
{}
MeanValueSubtractComputation::MeanValueSubtractComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& mean, test::Scalar const& std)
: FluidComputation(new Priv{ []()-> cv::GComputation{
cv::GMat in;
cv::GScalar _mean;
cv::GScalar _std;
cv::GMat out = (in - _mean) / _std;
return cv::GComputation(cv::GIn(in, _mean, _std), cv::GOut(out));
}()
, cv::GRunArgs{cv::GRunArg{to_own(inMat)}, cv::GRunArg{to_own(mean)}, cv::GRunArg{to_own(std)}}
, {to_own(outMat)}
})
{}
namespace cv {
cv::GMat operator-(const cv::GMat& lhs, const cv::GScalar& rhs)
{
return InferenceEngine::gapi::GSubC::on(lhs, rhs, -1);
}
cv::GMat operator/(const cv::GMat& lhs, const cv::GScalar& rhs)
{
return InferenceEngine::gapi::GDivC::on(lhs, rhs, 1.0, -1);
}
}

View File

@ -1,117 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FLUID_TEST_COMPUTATIONS_HPP
#define FLUID_TEST_COMPUTATIONS_HPP
#include <ie_api.h>
#include <memory>
#include <vector>
#include <array>
namespace test
{
struct Mat
{
int rows;
int cols;
int type;
void* data;
size_t step;
};
struct Rect{
int x;
int y;
int width;
int height;
bool empty(){
return width == 0 && height == 0;
};
};
struct Scalar
{
std::array<double, 4> v;
};
}
class FluidComputation
{
protected:
struct Priv;
std::shared_ptr<Priv> m_priv;
public:
FluidComputation(Priv* priv);
void warmUp(test::Rect roi = {});
void apply();
};
class FluidResizeComputation : public FluidComputation
{
public:
FluidResizeComputation(test::Mat inMat, test::Mat outMat, int interp);
};
class FluidResizeRGB8UComputation : public FluidComputation
{
public:
FluidResizeRGB8UComputation(test::Mat inMat, test::Mat outMat, int interp);
};
class FluidSplitComputation : public FluidComputation
{
public:
FluidSplitComputation(test::Mat inMat, std::vector<test::Mat> outMats);
};
class FluidChanToPlaneComputation : public FluidComputation
{
public:
FluidChanToPlaneComputation(test::Mat inMat, test::Mat outMat, int chan);
};
class FluidMergeComputation : public FluidComputation
{
public:
FluidMergeComputation(std::vector<test::Mat> inMats, test::Mat outMat);
};
class FluidNV12toRGBComputation : public FluidComputation
{
public:
FluidNV12toRGBComputation(test::Mat inMat_y, test::Mat inMat_uv, test::Mat outMat);
};
class FluidI420toRGBComputation : public FluidComputation
{
public:
FluidI420toRGBComputation(test::Mat inMat_y, test::Mat inMat_u, test::Mat inMat_v, test::Mat outMat);
};
class ConvertDepthComputation : public FluidComputation
{
public:
ConvertDepthComputation(test::Mat inMat, test::Mat outMat, int depth);
};
class DivCComputation : public FluidComputation
{
public:
DivCComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& c);
};
class SubCComputation : public FluidComputation
{
public:
SubCComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& c);
};
class MeanValueSubtractComputation : public FluidComputation
{
public:
MeanValueSubtractComputation(test::Mat inMat, test::Mat outMat, test::Scalar const& mean, test::Scalar const& std);
};
#endif // FLUID_TEST_COMPUTATIONS_HPP

View File

@ -85,15 +85,11 @@ source_group("include" FILES ${LIBRARY_HEADERS} ${PUBLIC_HEADERS})
add_library(${TARGET_NAME}_plugin_api INTERFACE)
target_include_directories(${TARGET_NAME}_plugin_api INTERFACE
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:openvino::core::dev,INTERFACE_INCLUDE_DIRECTORIES>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/dev_api>
$<BUILD_INTERFACE:${PUBLIC_HEADERS_DIR}>
$<BUILD_INTERFACE:${PUBLIC_HEADERS_DIR}/ie>)
target_compile_definitions(${TARGET_NAME}_plugin_api INTERFACE
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_COMPILE_DEFINITIONS>)
target_link_libraries(${TARGET_NAME}_plugin_api INTERFACE openvino::pugixml openvino::itt openvino::util)
ov_set_threading_interface_for(${TARGET_NAME}_plugin_api)
@ -128,8 +124,7 @@ ov_build_target_faster(${TARGET_NAME}_obj
target_compile_definitions(${TARGET_NAME}_obj PRIVATE
IMPLEMENT_INFERENCE_ENGINE_API
$<$<TARGET_EXISTS:openvino_proxy_plugin_obj>:PROXY_PLUGIN_ENABLED>
$<TARGET_PROPERTY:ngraph,INTERFACE_COMPILE_DEFINITIONS>
$<TARGET_PROPERTY:openvino_gapi_preproc,INTERFACE_COMPILE_DEFINITIONS>)
$<TARGET_PROPERTY:ngraph,INTERFACE_COMPILE_DEFINITIONS>)
target_include_directories(${TARGET_NAME}_obj SYSTEM PRIVATE
$<TARGET_PROPERTY:ngraph,INTERFACE_INCLUDE_DIRECTORIES>

View File

@ -4,6 +4,7 @@
#pragma once
#include <ie_preprocess.hpp>
#include <map>
#include <memory>
#include <string>
@ -12,7 +13,6 @@
#include "ie_common.h"
#include "ie_compound_blob.h"
#include "ie_input_info.hpp"
#include "ie_preprocess_data.hpp"
#include "openvino/core/node_output.hpp"
#include "so_ptr.hpp"
@ -328,9 +328,22 @@ protected:
InferenceEngine::BlobMap _outputs; //!< A map of user passed blobs for network outputs
std::vector<std::shared_ptr<const ov::Node>> _parameters; //!< A vector of function inputs
std::vector<std::shared_ptr<const ov::Node>> _results; //!< A vector of function outputs
std::map<std::string, PreProcessDataPtr> _preProcData; //!< A map of pre-process data per input
std::map<std::string, BatchedBlob::Ptr> _batched_inputs; //!< A map of user passed blobs for network inputs
class PreProcessDataPlugin {
public:
void setRoiBlob(const Blob::Ptr& blob) {}
Blob::Ptr getRoiBlob() const {
return nullptr;
}
void execute(Blob::Ptr& preprocessedBlob, const PreProcessInfo& info, bool serial, int batchSize = -1) {}
void isApplicable(const Blob::Ptr& src, const Blob::Ptr& dst) {}
};
std::map<std::string, std::shared_ptr<PreProcessDataPlugin>> _preProcData; //!< A map of pre-process data per input
/**
* @brief A shared pointer to IInferRequestInternal
* @note Needed to correctly handle ownership between objects.

View File

@ -143,24 +143,19 @@ void IInferRequestInternal::SetBlob(const std::string& name, const Blob::Ptr& us
}
auto& devBlob = _deviceInputs[name];
const bool preProcRequired = preProcessingRequired(foundInput, userBlob, devBlob);
if (compoundBlobPassed && !preProcRequired) {
if (compoundBlobPassed) {
IE_THROW(NotImplemented) << "cannot set compound blob: supported only for input pre-processing";
}
if (preProcRequired) {
addInputPreProcessingFor(name, userBlob, devBlob ? devBlob : _inputs[name]);
} else {
size_t inputSize = foundInput->getTensorDesc().getLayout() != InferenceEngine::Layout::SCALAR
? InferenceEngine::details::product(foundInput->getTensorDesc().getDims())
: 1;
if (!isInputDynamic && dataSize != inputSize) {
IE_THROW() << "Input tensor size is not equal network input size (" << dataSize << "!=" << inputSize
<< ").";
}
_inputs[name] = userBlob;
devBlob = userBlob;
size_t inputSize = foundInput->getTensorDesc().getLayout() != InferenceEngine::Layout::SCALAR
? InferenceEngine::details::product(foundInput->getTensorDesc().getDims())
: 1;
if (!isInputDynamic && dataSize != inputSize) {
IE_THROW() << "Input tensor size is not equal network input size (" << dataSize << "!=" << inputSize
<< ").";
}
_inputs[name] = userBlob;
devBlob = userBlob;
_batched_inputs.erase(name);
} else {
if (compoundBlobPassed) {
@ -369,24 +364,12 @@ Blob::Ptr IInferRequestInternal::GetBlob(const std::string& name) {
if (findInputAndOutputBlobByName(name, foundInput, foundOutput)) {
const auto input = findInputByNodeName(name);
const bool isInputDynamic = input && input->get_output_partial_shape(0).is_dynamic();
// ROI blob is returned only if it was set previously. Otherwise default blob is returned.
auto it = _preProcData.find(name);
if (it != _preProcData.end()) {
data = it->second->getRoiBlob();
} else {
data = _inputs[name];
const auto& dims = foundInput->getTensorDesc().getDims();
if (isInputDynamic)
checkBlob(data, name, true);
else
checkBlob(data, name, true, foundInput->getTensorDesc().getLayout() != SCALAR ? dims : oneVector);
auto& devBlob = _deviceInputs[name];
if (preProcessingRequired(foundInput, data, devBlob)) {
// if no devBlob, performs inplace
addInputPreProcessingFor(name, data, devBlob ? devBlob : _inputs[name]);
}
}
data = _inputs[name];
const auto& dims = foundInput->getTensorDesc().getDims();
if (isInputDynamic)
checkBlob(data, name, true);
else
checkBlob(data, name, true, foundInput->getTensorDesc().getLayout() != SCALAR ? dims : oneVector);
} else {
const auto output = findOutputByNodeName(name);
const bool isOutputDynamic = output && output->get_output_partial_shape(0).is_dynamic();
@ -438,16 +421,7 @@ void IInferRequestInternal::SetCallback(Callback callback) {
_callback = std::move(callback);
}
void IInferRequestInternal::execDataPreprocessing(InferenceEngine::BlobMap& preprocessedBlobs, bool serial) {
for (auto& input : preprocessedBlobs) {
// If there is a pre-process entry for an input then it must be pre-processed
// using preconfigured resize algorithm.
auto it = _preProcData.find(input.first);
if (it != _preProcData.end()) {
it->second->execute(input.second, _networkInputs[input.first]->getPreProcess(), serial, -1);
}
}
}
void IInferRequestInternal::execDataPreprocessing(InferenceEngine::BlobMap& preprocessedBlobs, bool serial) {}
bool IInferRequestInternal::findInputAndOutputBlobByName(const std::string& name,
InputInfo::Ptr& foundInput,
@ -569,56 +543,6 @@ std::shared_ptr<void> IInferRequestInternal::getPointerToSo() const {
return _so;
}
bool IInferRequestInternal::preProcessingRequired(const InputInfo::Ptr& info,
const Blob::Ptr& userBlob,
const Blob::Ptr& deviceBlob) {
// pre-processing is required if:
// 1. resize algorithm is specified (resize required)
// 2. color format specified:
// 2.a. color format is not equal to network's expected (color conversion required)
// 2.b. network's layout != blob's layout (reorder required)
// 3. precision conversion is required
const auto& preProcessInfo = info->getPreProcess();
const auto inputColorFormat = preProcessInfo.getColorFormat();
// FIXME: support other network's input formats once the API is ready. Assuming input is in
// the BGR format by default
const auto networkColorFormat = ColorFormat::BGR;
const bool colorFormatSpecified = inputColorFormat != ColorFormat::RAW;
auto blob_layout = [](const Blob::Ptr& b) {
return b->getTensorDesc().getLayout();
};
auto blob_prec = [](const Blob::Ptr& b) {
return b->getTensorDesc().getPrecision();
};
auto dst_layout = deviceBlob ? blob_layout(deviceBlob) : info->getLayout();
auto dst_prec = deviceBlob ? blob_prec(deviceBlob) : info->getPrecision();
// FIXME: remove the first part to allow any needed conversion?
const bool need_layout_conv = (colorFormatSpecified || deviceBlob) && (blob_layout(userBlob) != dst_layout);
return preProcessInfo.getResizeAlgorithm() != ResizeAlgorithm::NO_RESIZE ||
(colorFormatSpecified && inputColorFormat != networkColorFormat) || need_layout_conv ||
(blob_prec(userBlob) != dst_prec);
}
void IInferRequestInternal::addInputPreProcessingFor(const std::string& name,
const Blob::Ptr& from,
const Blob::Ptr& to) {
auto ppDataIt = _preProcData.find(name);
if (ppDataIt == _preProcData.end()) {
ppDataIt = (_preProcData.emplace(name, CreatePreprocDataHelper())).first;
}
auto& preproc_ptr = ppDataIt->second;
preproc_ptr->isApplicable(from, to);
// Stores the given blob as ROI blob. It will be used to fill in network input
// during pre-processing
preproc_ptr->setRoiBlob(from);
}
void* IInferRequestInternal::GetUserData() noexcept {
return _userData;
}

View File

@ -803,8 +803,7 @@ ov::SoPtr<ov::ICompiledModel> ov::CoreImpl::compile_model_with_preprocess(ov::Pl
std::shared_ptr<const ov::Model> preprocessed_model = model;
// Disable conversion for proxy plugin and virtual devices to add pre-processing based on API of internal plugins
if (!is_new_api() && !std::dynamic_pointer_cast<InferenceEngine::IPluginWrapper>(plugin.m_ptr) &&
!is_virtual_device(plugin.get_name()) && !is_proxy_device(plugin)) {
if (!is_new_api() && !is_virtual_device(plugin.get_name()) && !is_proxy_device(plugin)) {
ov::pass::Manager manager;
manager.register_pass<ov::pass::AddPreprocessing>();

View File

@ -1,84 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/plugin/set_preprocess.hpp"
#ifdef ENABLE_GAPI_PREPROCESSING
using namespace BehaviorTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16};
const std::vector<std::map<std::string, std::string>> multiConfigs = {
{{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, ov::test::utils::DEVICE_TEMPLATE}}};
const std::vector<InferenceEngine::Precision> ioPrecisions = {InferenceEngine::Precision::FP32,
InferenceEngine::Precision::U8};
const std::vector<InferenceEngine::Layout> netLayouts = {
InferenceEngine::Layout::NCHW,
// InferenceEngine::Layout::NHWC
};
const std::vector<InferenceEngine::Layout> ioLayouts = {InferenceEngine::Layout::NCHW, InferenceEngine::Layout::NHWC};
INSTANTIATE_TEST_SUITE_P(smoke_Multi_BehaviorTests,
InferRequestPreprocessConversionTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_MULTI),
::testing::ValuesIn(multiConfigs)),
InferRequestPreprocessConversionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Multi_BehaviorTests,
InferRequestPreprocessDynamicallyInSetBlobTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::Bool(),
::testing::Bool(),
::testing::ValuesIn(netLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(true), // only SetBlob
::testing::Values(true), // only SetBlob
::testing::Values(ov::test::utils::DEVICE_MULTI),
::testing::ValuesIn(multiConfigs)),
InferRequestPreprocessDynamicallyInSetBlobTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests,
InferRequestPreprocessConversionTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_AUTO),
::testing::ValuesIn(multiConfigs)),
InferRequestPreprocessConversionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests,
InferRequestPreprocessDynamicallyInSetBlobTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::Bool(),
::testing::Bool(),
::testing::ValuesIn(netLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(true), // only SetBlob
::testing::Values(true), // only SetBlob
::testing::Values(ov::test::utils::DEVICE_AUTO),
::testing::ValuesIn(multiConfigs)),
InferRequestPreprocessDynamicallyInSetBlobTest::getTestCaseName);
} // namespace
#endif // ENABLE_GAPI_PREPROCESSING

View File

@ -1,41 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/plugin/preprocessing.hpp"
#ifdef ENABLE_GAPI_PREPROCESSING
using namespace BehaviorTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> inputPrecisions = {
InferenceEngine::Precision::U16,
InferenceEngine::Precision::FP32
};
const std::vector<std::map<std::string, std::string>> configs = {
{}
};
INSTANTIATE_TEST_SUITE_P(BehaviourPreprocessingTestsViaSetInput, PreprocessingPrecisionConvertTest,
::testing::Combine(
::testing::ValuesIn(inputPrecisions),
::testing::Values(1, 2, 3, 4, 5), // Number of input tensor channels
::testing::Values(true), // Use SetInput
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::ValuesIn(configs)),
PreprocessingPrecisionConvertTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(BehaviourPreprocessingTestsViaGetBlob, PreprocessingPrecisionConvertTest,
::testing::Combine(
::testing::ValuesIn(inputPrecisions),
::testing::Values(4, 5), // Number of input tensor channels (blob_copy only supports 4d and 5d tensors)
::testing::Values(false), // use GetBlob
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::ValuesIn(configs)),
PreprocessingPrecisionConvertTest::getTestCaseName);
} // namespace
#endif // ENABLE_GAPI_PREPROCESSING

View File

@ -1,111 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/plugin/set_preprocess.hpp"
#ifdef ENABLE_GAPI_PREPROCESSING
using namespace BehaviorTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16
};
const std::vector<std::map<std::string, std::string>> configs = {
{},
{{InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, InferenceEngine::PluginConfigParams::CPU_THROUGHPUT_AUTO}},
{{InferenceEngine::PluginConfigParams::KEY_CPU_THROUGHPUT_STREAMS, "0"}, {InferenceEngine::PluginConfigParams::KEY_CPU_THREADS_NUM, "1"}}
};
const std::vector<std::map<std::string, std::string>> heteroConfigs = {
{{ "TARGET_FALLBACK" , ov::test::utils::DEVICE_CPU}}
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::ValuesIn(configs)),
InferRequestPreprocessTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, InferRequestPreprocessTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_HETERO),
::testing::ValuesIn(heteroConfigs)),
InferRequestPreprocessTest::getTestCaseName);
const std::vector<InferenceEngine::Precision> ioPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::U8
};
const std::vector<InferenceEngine::Layout> netLayouts = {
InferenceEngine::Layout::NCHW,
// InferenceEngine::Layout::NHWC
};
const std::vector<InferenceEngine::Layout> ioLayouts = {
InferenceEngine::Layout::NCHW,
InferenceEngine::Layout::NHWC
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessConversionTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::ValuesIn(configs)),
InferRequestPreprocessConversionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessDynamicallyInSetBlobTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Bool(),
::testing::Bool(),
::testing::ValuesIn(netLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(true), // only SetBlob
::testing::Values(true), // only SetBlob
::testing::Values(ov::test::utils::DEVICE_CPU),
::testing::ValuesIn(configs)),
InferRequestPreprocessDynamicallyInSetBlobTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, InferRequestPreprocessConversionTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_HETERO),
::testing::ValuesIn(heteroConfigs)),
InferRequestPreprocessConversionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests, InferRequestPreprocessDynamicallyInSetBlobTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Bool(),
::testing::Bool(),
::testing::ValuesIn(netLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(true), // only SetBlob
::testing::Values(true), // only SetBlob
::testing::Values(ov::test::utils::DEVICE_HETERO),
::testing::ValuesIn(heteroConfigs)),
InferRequestPreprocessDynamicallyInSetBlobTest::getTestCaseName);
} // namespace
#endif // ENABLE_GAPI_PREPROCESSING

View File

@ -1,76 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <base/behavior_test_utils.hpp>
#include "behavior/plugin/set_preprocess.hpp"
#ifdef ENABLE_GAPI_PREPROCESSING
using namespace BehaviorTestsDefinitions;
namespace {
using PreprocessBehTest = BehaviorTestsUtils::BehaviorTestsBasic;
const std::vector<InferenceEngine::Precision> netPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16
};
auto configs = []() {
return std::vector<std::map<std::string, std::string>>{
{},
};
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_GPU),
::testing::ValuesIn(configs())),
InferRequestPreprocessTest::getTestCaseName);
const std::vector<InferenceEngine::Precision> ioPrecisions = {
InferenceEngine::Precision::FP32,
InferenceEngine::Precision::U8
};
const std::vector<InferenceEngine::Layout> netLayouts = {
InferenceEngine::Layout::NCHW,
// InferenceEngine::Layout::NHWC
};
const std::vector<InferenceEngine::Layout> ioLayouts = {
InferenceEngine::Layout::NCHW,
InferenceEngine::Layout::NHWC
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessConversionTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_GPU),
::testing::ValuesIn(configs())),
InferRequestPreprocessConversionTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests, InferRequestPreprocessDynamicallyInSetBlobTest,
::testing::Combine(
::testing::ValuesIn(netPrecisions),
::testing::Bool(),
::testing::Bool(),
::testing::ValuesIn(netLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(true), // only SetBlob
::testing::Values(true), // only SetBlob
::testing::Values(ov::test::utils::DEVICE_GPU),
::testing::ValuesIn(configs())),
InferRequestPreprocessDynamicallyInSetBlobTest::getTestCaseName);
} // namespace
#endif // ENABLE_GAPI_PREPROCESSING

View File

@ -1,39 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/plugin/preprocessing.hpp"
#ifdef ENABLE_GAPI_PREPROCESSING
using namespace BehaviorTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> inputPrecisions = {InferenceEngine::Precision::U8,
InferenceEngine::Precision::FP32};
const std::vector<std::map<std::string, std::string>> configs = {{}};
INSTANTIATE_TEST_SUITE_P(smoke_Behavior_PreprocessingPrecisionConvertTestsViaSetInput,
PreprocessingPrecisionConvertTest,
::testing::Combine(::testing::ValuesIn(inputPrecisions),
::testing::Values(4), // Number of input tensor channels
::testing::Values(true), // Use SetInput
::testing::Values(ov::test::utils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
PreprocessingPrecisionConvertTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Behavior_PreprocessingPrecisionConvertTestsViaGetBlob,
PreprocessingPrecisionConvertTest,
::testing::Combine(::testing::ValuesIn(inputPrecisions),
::testing::Values(4), // Number of input tensor channels (blob_copy only
// supports 4d and 5d tensors)
::testing::Values(false), // use GetBlob
::testing::Values(ov::test::utils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
PreprocessingPrecisionConvertTest::getTestCaseName);
} // namespace
#endif // ENABLE_GAPI_PREPROCESSING

View File

@ -1,68 +0,0 @@
// Copyright (C) 2018-2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include "behavior/plugin/set_preprocess.hpp"
using namespace BehaviorTestsDefinitions;
namespace {
const std::vector<InferenceEngine::Precision> netPrecisions = {InferenceEngine::Precision::FP32,
InferenceEngine::Precision::FP16};
const std::vector<std::map<std::string, std::string>> configs = {{}};
const std::vector<std::map<std::string, std::string>> multiConfigs = {
{{InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES, ov::test::utils::DEVICE_TEMPLATE}}};
const std::vector<std::map<std::string, std::string>> heteroConfigs = {
{{"TARGET_FALLBACK", ov::test::utils::DEVICE_TEMPLATE}}};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests,
InferRequestPreprocessTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
InferRequestPreprocessTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Multi_BehaviorTests,
InferRequestPreprocessTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_MULTI),
::testing::ValuesIn(multiConfigs)),
InferRequestPreprocessTest::getTestCaseName);
INSTANTIATE_TEST_SUITE_P(smoke_Hetero_BehaviorTests,
InferRequestPreprocessTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::Values(ov::test::utils::DEVICE_HETERO),
::testing::ValuesIn(heteroConfigs)),
InferRequestPreprocessTest::getTestCaseName);
const std::vector<InferenceEngine::Precision> ioPrecisions = {InferenceEngine::Precision::FP32,
InferenceEngine::Precision::U8};
const std::vector<InferenceEngine::Layout> netLayouts = {
InferenceEngine::Layout::NCHW,
};
const std::vector<InferenceEngine::Layout> ioLayouts = {
InferenceEngine::Layout::NCHW,
InferenceEngine::Layout::NHWC,
};
INSTANTIATE_TEST_SUITE_P(smoke_BehaviorTests,
InferRequestPreprocessConversionTest,
::testing::Combine(::testing::ValuesIn(netPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(ioPrecisions),
::testing::ValuesIn(netLayouts),
::testing::ValuesIn(ioLayouts),
::testing::ValuesIn(ioLayouts),
::testing::Bool(),
::testing::Bool(),
::testing::Values(ov::test::utils::DEVICE_TEMPLATE),
::testing::ValuesIn(configs)),
InferRequestPreprocessConversionTest::getTestCaseName);
} // namespace

View File

@ -71,10 +71,6 @@ ov_add_target(
${DEPENDENCIES}
)
if(ENABLE_GAPI_PREPROCESSING)
target_compile_definitions(${TARGET_NAME} PUBLIC ENABLE_GAPI_PREPROCESSING)
endif()
ov_build_target_faster(${TARGET_NAME}
PCH PRIVATE "src/precomp.hpp"
)

1
thirdparty/ade vendored

@ -1 +0,0 @@
Subproject commit 0e8a2ccdd34f29dba55894f5f3c5179809888b9e

View File

@ -260,46 +260,6 @@ if(NOT TARGET openvino::pugixml)
ov_build_pugixml()
endif()
#
# Fluid, G-API, OpenCV HAL
#
if(ENABLE_GAPI_PREPROCESSING)
add_library(ocv_hal INTERFACE)
target_include_directories(ocv_hal INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/ocv")
# ade
find_package(ade 0.1.0 QUIET)
if(ade_FOUND)
# conan and vcpkg create 'ade' target
# we just need to remove non-numerical symbols from version,
# because conan defines it as 0.1.2a, which is invalid in cmake
string(REGEX REPLACE "[a-z]" "" ade_VERSION "${ade_VERSION}")
else()
add_subdirectory(thirdparty/ade EXCLUDE_FROM_ALL)
set_target_properties(ade PROPERTIES FOLDER thirdparty)
ov_developer_package_export_targets(TARGET ade)
ov_install_static_lib(ade ${OV_CPACK_COMP_CORE})
endif()
# fluid
add_subdirectory(thirdparty/fluid/modules/gapi EXCLUDE_FROM_ALL)
if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11)
target_compile_options(fluid PRIVATE "-Wno-maybe-uninitialized")
endif()
if(UNUSED_BUT_SET_VARIABLE_SUPPORTED)
target_compile_options(fluid PRIVATE "-Wno-unused-but-set-variable")
endif()
set_target_properties(fluid PROPERTIES FOLDER thirdparty)
ov_developer_package_export_targets(TARGET fluid)
ov_install_static_lib(fluid ${OV_CPACK_COMP_CORE})
endif()
#
# Gflags
#

View File

@ -1,45 +0,0 @@
# OpenCV G-API (Fluid), standalone edition
This subtree hosts sources of G-API - a new OpenCV module for
efficient image processing. G-API serves as a preprocessing vehicle
for Inference Engine. At the moment, only Fluid (CPU) backend is used.
The sources are taken from OpenCV's [main repository](https://github.com/opencv).
There are supplementary scripts which ease and verify the update
process.
## Usage
Updating to the latest `master`:
./update.sh
Updating to a particular revision:
./update.sh COMMIT_HASH
During update, this script checks if the source tree was modified
after the latest update. If it was, update fails -- we want to avoid
any diverge in the source so _no changes_ should be committed ever to
this copy of G-API.
One can check manually if sources were diverged from its last "valid"
copy by running
./check.sh
An error message and non-zero exit code indicate possible inconsitency
with this source copy.
One updated, all changes will be automatically staged.
## Files
In addition to the source tree, the above two scripts maintain two
files:
- `revision.txt` -- the OpenCV's revision used to produce this source
copy. If the code was taken from `master`, a timestamp is stored
otherwise.
- `checksum.txt` -- latest valid copy's check sum. Don't update this
file manually.

View File

@ -1,15 +0,0 @@
#!/usr/bin/env bash
if [ ! -f modules ] && [ ! -f checksum.txt ]; then
exit 0
fi
THIS_HASH=$(./checksum.sh)
OLD_HASH=$(cat checksum.txt)
if [ $THIS_HASH != $OLD_HASH ]; then
echo "Invalid checksum -- any changes were done to the source tree here?"
exit 1
fi
echo "Check done."

View File

@ -1,3 +0,0 @@
#!/usr/bin/env bash
find modules/ -type f -exec md5sum {} \; | sort -k 2 | md5sum | cut -d' ' -f 1

View File

@ -1 +0,0 @@
52e7351a888ee42076be4db81d9ac992

View File

@ -1 +0,0 @@
4.x

View File

@ -1,73 +0,0 @@
#!/usr/bin/env bash
REVISION=""
TARGET_DIR=$(pwd)
case "$#" in
"0") echo "Using latest master..."
REVISION="master"
;;
"1") REVISION=$1
echo "Using revision ${REVISION}..."
;;
*) echo "Usage: ${0} [REVISION]
Update Fluid to OpenCV source tree at the given REVISION.
If no revision specified, the most recent 'master' commit is used.
"
exit 1 ;;
esac
# Before doing anything, check if this snapshot was not modified
./check.sh
if [ $? -ne 0 ]; then
echo "Consistency check failed, please reset this subtree to its initial state first!"
exit 1
fi
# Download the stuff...
URL="https://github.com/opencv/opencv/archive/${REVISION}.zip"
wget -c ${URL}
if [ $? -ne 0 ]; then
echo "Failed to download ${URL}!"
exit 1
fi
unzip -qq ${REVISION}.zip
# Remove current files
if [ -f modules ]; then
find modules -type f | xargs git rm
find modules -type f | xargs rm
rm -vd modules
fi
# Put a new copy. Extend this section if needed
# BOM thing might help here, probably
pushd "opencv-${REVISION}"
cp -rv --parent modules/gapi ${TARGET_DIR}
popd
# Note "-f" is used to add files like doc/ which are omitted
# now by IE's current .gitignore - it breaks checksum otherwise.
git add -f modules/gapi
# Clean-up files
rm -rf "opencv-${REVISION}"
rm "${REVISION}.zip"
# Calculate and store checksum
./checksum.sh > checksum.txt
git add checksum.txt
# Store revision
if [ ${REVISION} == "master" ]; then
REVISION="${REVISION} / $(date +%F)"
fi
echo ${REVISION} > revision.txt
git add revision.txt
# Display status
git status
# Fin
echo "Done!"

View File

@ -1,256 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Copyright (C) 2015, Itseez Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_HAL_HPP
#define OPENCV_HAL_HPP
#include "opencv2/core/cvdef.h"
#include "opencv2/core/cvstd.hpp"
#include "opencv2/core/hal/interface.h"
namespace cv { namespace hal {
//! @addtogroup core_hal_functions
//! @{
CV_EXPORTS int normHamming(const uchar* a, int n);
CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n);
CV_EXPORTS int normHamming(const uchar* a, int n, int cellSize);
CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize);
CV_EXPORTS int LU32f(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS int LU64f(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky32f(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky64f(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS void SVD32f(float* At, size_t astep, float* W, float* U, size_t ustep, float* Vt, size_t vstep, int m, int n, int flags);
CV_EXPORTS void SVD64f(double* At, size_t astep, double* W, double* U, size_t ustep, double* Vt, size_t vstep, int m, int n, int flags);
CV_EXPORTS int QR32f(float* A, size_t astep, int m, int n, int k, float* b, size_t bstep, float* hFactors);
CV_EXPORTS int QR64f(double* A, size_t astep, int m, int n, int k, double* b, size_t bstep, double* hFactors);
CV_EXPORTS void gemm32f(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
int m_a, int n_a, int n_d, int flags);
CV_EXPORTS void gemm64f(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
int m_a, int n_a, int n_d, int flags);
CV_EXPORTS void gemm32fc(const float* src1, size_t src1_step, const float* src2, size_t src2_step,
float alpha, const float* src3, size_t src3_step, float beta, float* dst, size_t dst_step,
int m_a, int n_a, int n_d, int flags);
CV_EXPORTS void gemm64fc(const double* src1, size_t src1_step, const double* src2, size_t src2_step,
double alpha, const double* src3, size_t src3_step, double beta, double* dst, size_t dst_step,
int m_a, int n_a, int n_d, int flags);
CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n);
CV_EXPORTS float normL1_(const float* a, const float* b, int n);
CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n);
CV_EXPORTS void exp32f(const float* src, float* dst, int n);
CV_EXPORTS void exp64f(const double* src, double* dst, int n);
CV_EXPORTS void log32f(const float* src, float* dst, int n);
CV_EXPORTS void log64f(const double* src, double* dst, int n);
CV_EXPORTS void fastAtan32f(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
CV_EXPORTS void fastAtan64f(const double* y, const double* x, double* dst, int n, bool angleInDegrees);
CV_EXPORTS void magnitude32f(const float* x, const float* y, float* dst, int n);
CV_EXPORTS void magnitude64f(const double* x, const double* y, double* dst, int n);
CV_EXPORTS void sqrt32f(const float* src, float* dst, int len);
CV_EXPORTS void sqrt64f(const double* src, double* dst, int len);
CV_EXPORTS void invSqrt32f(const float* src, float* dst, int len);
CV_EXPORTS void invSqrt64f(const double* src, double* dst, int len);
CV_EXPORTS void split8u(const uchar* src, uchar** dst, int len, int cn );
CV_EXPORTS void split16u(const ushort* src, ushort** dst, int len, int cn );
CV_EXPORTS void split32s(const int* src, int** dst, int len, int cn );
CV_EXPORTS void split64s(const int64* src, int64** dst, int len, int cn );
CV_EXPORTS void merge8u(const uchar** src, uchar* dst, int len, int cn );
CV_EXPORTS void merge16u(const ushort** src, ushort* dst, int len, int cn );
CV_EXPORTS void merge32s(const int** src, int* dst, int len, int cn );
CV_EXPORTS void merge64s(const int64** src, int64* dst, int len, int cn );
CV_EXPORTS void add8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
CV_EXPORTS void add64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
CV_EXPORTS void sub64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
CV_EXPORTS void max64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
CV_EXPORTS void min64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* );
CV_EXPORTS void absdiff64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* );
CV_EXPORTS void and8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void or8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void xor8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void not8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* );
CV_EXPORTS void cmp8u(const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp8s(const schar* src1, size_t step1, const schar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp16u(const ushort* src1, size_t step1, const ushort* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp16s(const short* src1, size_t step1, const short* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp32s(const int* src1, size_t step1, const int* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp32f(const float* src1, size_t step1, const float* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void cmp64f(const double* src1, size_t step1, const double* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _cmpop);
CV_EXPORTS void mul8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void mul64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void div64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip8u( const uchar *, size_t, const uchar * src2, size_t step2, uchar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip8s( const schar *, size_t, const schar * src2, size_t step2, schar* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip16u( const ushort *, size_t, const ushort * src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip16s( const short *, size_t, const short * src2, size_t step2, short* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip32s( const int *, size_t, const int * src2, size_t step2, int* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip32f( const float *, size_t, const float * src2, size_t step2, float* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void recip64f( const double *, size_t, const double * src2, size_t step2, double* dst, size_t step, int width, int height, void* scale);
CV_EXPORTS void addWeighted8u( const uchar* src1, size_t step1, const uchar* src2, size_t step2, uchar* dst, size_t step, int width, int height, void* _scalars );
CV_EXPORTS void addWeighted8s( const schar* src1, size_t step1, const schar* src2, size_t step2, schar* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted16u( const ushort* src1, size_t step1, const ushort* src2, size_t step2, ushort* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted16s( const short* src1, size_t step1, const short* src2, size_t step2, short* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted32s( const int* src1, size_t step1, const int* src2, size_t step2, int* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted32f( const float* src1, size_t step1, const float* src2, size_t step2, float* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void addWeighted64f( const double* src1, size_t step1, const double* src2, size_t step2, double* dst, size_t step, int width, int height, void* scalars );
CV_EXPORTS void cvt16f32f( const float16_t* src, float* dst, int len );
CV_EXPORTS void cvt32f16f( const float* src, float16_t* dst, int len );
CV_EXPORTS void addRNGBias32f( float* arr, const float* scaleBiasPairs, int len );
CV_EXPORTS void addRNGBias64f( double* arr, const double* scaleBiasPairs, int len );
struct CV_EXPORTS DFT1D
{
static Ptr<DFT1D> create(int len, int count, int depth, int flags, bool * useBuffer = 0);
virtual void apply(const uchar *src, uchar *dst) = 0;
virtual ~DFT1D() {}
};
struct CV_EXPORTS DFT2D
{
static Ptr<DFT2D> create(int width, int height, int depth,
int src_channels, int dst_channels,
int flags, int nonzero_rows = 0);
virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
virtual ~DFT2D() {}
};
struct CV_EXPORTS DCT2D
{
static Ptr<DCT2D> create(int width, int height, int depth, int flags);
virtual void apply(const uchar *src_data, size_t src_step, uchar *dst_data, size_t dst_step) = 0;
virtual ~DCT2D() {}
};
//! @} core_hal
//=============================================================================
// for binary compatibility with 3.0
//! @cond IGNORED
CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS void exp(const float* src, float* dst, int n);
CV_EXPORTS void exp(const double* src, double* dst, int n);
CV_EXPORTS void log(const float* src, float* dst, int n);
CV_EXPORTS void log(const double* src, double* dst, int n);
CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
CV_EXPORTS void magnitude(const double* x, const double* y, double* dst, int n);
CV_EXPORTS void sqrt(const float* src, float* dst, int len);
CV_EXPORTS void sqrt(const double* src, double* dst, int len);
CV_EXPORTS void invSqrt(const float* src, float* dst, int len);
CV_EXPORTS void invSqrt(const double* src, double* dst, int len);
//! @endcond
}} //cv::hal
#endif //OPENCV_HAL_HPP

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,572 +0,0 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Copyright (C) 2015, Itseez Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef OPENCV_HAL_INTRIN_HPP
#define OPENCV_HAL_INTRIN_HPP
#include <cmath>
#include <float.h>
#include <stdlib.h>
//! @name Data types
//! primitive types
//! - schar - signed 1 byte integer
//! - uchar - unsigned 1 byte integer
//! - short - signed 2 byte integer
//! - ushort - unsigned 2 byte integer
//! - int - signed 4 byte integer
//! - uint - unsigned 4 byte integer
//! - int64 - signed 8 byte integer
//! - uint64 - unsigned 8 byte integer
//! @{
#if !defined _MSC_VER && !defined __BORLANDC__
# if defined __cplusplus && __cplusplus >= 201103L && !defined __APPLE__
# include <cstdint>
# ifdef __NEWLIB__
typedef unsigned int uint;
# else
typedef std::uint32_t uint;
# endif
# else
# include <stdint.h>
typedef uint32_t uint;
# endif
#else
typedef unsigned uint;
#endif
#if defined _MSC_VER || defined __BORLANDC__
typedef __int64 int64;
typedef unsigned __int64 uint64;
# define CV_BIG_INT(n) n##I64
# define CV_BIG_UINT(n) n##UI64
#else
typedef int64_t int64;
typedef uint64_t uint64;
# define CV_BIG_INT(n) n##LL
# define CV_BIG_UINT(n) n##ULL
#endif
#if defined(__cplusplus)
#if defined(_MSC_VER) && _MSC_VER < 1600 /* MSVS 2010 */
namespace cv {
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;
typedef unsigned short uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
}
#elif defined(_MSC_VER) || __cplusplus >= 201103L
#include <cstdint>
namespace cv {
using std::int8_t;
using std::uint8_t;
using std::int16_t;
using std::uint16_t;
using std::int32_t;
using std::uint32_t;
using std::int64_t;
using std::uint64_t;
}
#else
#include <stdint.h>
namespace cv {
typedef ::int8_t int8_t;
typedef ::uint8_t uint8_t;
typedef ::int16_t int16_t;
typedef ::uint16_t uint16_t;
typedef ::int32_t int32_t;
typedef ::uint32_t uint32_t;
typedef ::int64_t int64_t;
typedef ::uint64_t uint64_t;
}
#endif
#else // pure C
#include <stdint.h>
#endif
#define OPENCV_HAL_ADD(a, b) ((a) + (b))
#define OPENCV_HAL_AND(a, b) ((a) & (b))
#define OPENCV_HAL_NOP(a) (a)
#define OPENCV_HAL_1ST(a, b) (a)
#ifdef __GNUC__
# define CV_DECL_ALIGNED(x) __attribute__ ((aligned (x)))
#elif defined _MSC_VER
# define CV_DECL_ALIGNED(x) __declspec(align(x))
#else
# define CV_DECL_ALIGNED(x)
#endif
typedef union Cv32suf
{
int i;
unsigned u;
float f;
}
Cv32suf;
#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_X64))
// This is needed for _tzcnt_u32().
#include <immintrin.h>
#endif
namespace {
inline unsigned int trailingZeros32(unsigned int value) {
#if defined(_MSC_VER)
#if (_MSC_VER < 1700) || defined(_M_ARM) || defined(_M_ARM64)
unsigned long index = 0;
_BitScanForward(&index, value);
return (unsigned int)index;
#elif defined(__clang__)
// clang-cl doesn't export _tzcnt_u32 for non BMI systems
return value ? __builtin_ctz(value) : 32;
#else
return _tzcnt_u32(value);
#endif
#elif defined(__GNUC__) || defined(__GNUG__)
return __builtin_ctz(value);
#elif defined(__ICC) || defined(__INTEL_COMPILER)
return _bit_scan_forward(value);
#elif defined(__clang__)
return llvm.cttz.i32(value, true);
#else
static const int MultiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 };
return MultiplyDeBruijnBitPosition[((uint32_t)((value & -value) * 0x077CB531U)) >> 27];
#endif
}
}
// unlike HAL API, which is in cv::hal,
// we put intrinsics into cv namespace to make its
// access from within opencv code more accessible
namespace cv {
#ifndef CV_ALWAYS_INLINE
#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define CV_ALWAYS_INLINE inline __attribute__((always_inline))
#elif defined(_MSC_VER)
#define CV_ALWAYS_INLINE __forceinline
#else
#define CV_ALWAYS_INLINE inline
#endif
#endif
namespace hal {
enum StoreMode
{
STORE_UNALIGNED = 0,
STORE_ALIGNED = 1,
STORE_ALIGNED_NOCACHE = 2
};
}
template<typename _Tp> struct V_TypeTraits
{
};
#define CV_INTRIN_DEF_TYPE_TRAITS(type, int_type_, uint_type_, abs_type_, w_type_, q_type_, sum_type_, nlanes128_) \
template<> struct V_TypeTraits<type> \
{ \
typedef type value_type; \
typedef int_type_ int_type; \
typedef abs_type_ abs_type; \
typedef uint_type_ uint_type; \
typedef w_type_ w_type; \
typedef q_type_ q_type; \
typedef sum_type_ sum_type; \
enum { nlanes128 = nlanes128_ }; \
\
static inline int_type reinterpret_int(type x) \
{ \
union { type l; int_type i; } v; \
v.l = x; \
return v.i; \
} \
\
static inline type reinterpret_from_int(int_type x) \
{ \
union { type l; int_type i; } v; \
v.i = x; \
return v.l; \
} \
}
CV_INTRIN_DEF_TYPE_TRAITS(uchar, schar, uchar, uchar, ushort, unsigned, unsigned, 16);
CV_INTRIN_DEF_TYPE_TRAITS(schar, schar, uchar, uchar, short, int, int, 16);
CV_INTRIN_DEF_TYPE_TRAITS(ushort, short, ushort, ushort, unsigned, uint64, unsigned, 8);
CV_INTRIN_DEF_TYPE_TRAITS(short, short, ushort, ushort, int, int64, int, 8);
CV_INTRIN_DEF_TYPE_TRAITS(unsigned, int, unsigned, unsigned, uint64, void, unsigned, 4);
CV_INTRIN_DEF_TYPE_TRAITS(int, int, unsigned, unsigned, int64, void, int, 4);
CV_INTRIN_DEF_TYPE_TRAITS(float, int, unsigned, float, double, void, float, 4);
CV_INTRIN_DEF_TYPE_TRAITS(uint64, int64, uint64, uint64, void, void, uint64, 2);
CV_INTRIN_DEF_TYPE_TRAITS(int64, int64, uint64, uint64, void, void, int64, 2);
CV_INTRIN_DEF_TYPE_TRAITS(double, int64, uint64, double, void, void, double, 2);
#ifndef CV_DOXYGEN
#ifdef CV_CPU_DISPATCH_MODE
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE __CV_CAT(hal_, CV_CPU_DISPATCH_MODE)
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace __CV_CAT(hal_, CV_CPU_DISPATCH_MODE) {
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END }
#else
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE hal_baseline
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN namespace hal_baseline {
#define CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END }
#endif
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
#endif
}
/*#ifdef CV_DOXYGEN
# undef CV_AVX2
# undef CV_SSE2
# undef CV_NEON
# undef CV_VSX
# undef CV_FP16
# undef CV_MSA
#endif*/
#if CV_SSE2 || CV_NEON
#define CV__SIMD_FORWARD 128
#include "opencv_hal_intrin_forward.hpp"
#endif
#if CV_SSE2
#include "opencv_hal_sse.hpp"
#elif CV_NEON
#include "opencv_hal_neon.hpp"
#endif
// AVX2 can be used together with SSE2, so
// we define those two sets of intrinsics at once.
// Most of the intrinsics do not conflict (the proper overloaded variant is
// resolved by the argument types, e.g. v_float32x4 ~ SSE2, v_float32x8 ~ AVX2),
// but some of AVX2 intrinsics get v256_ prefix instead of v_, e.g. v256_load() vs v_load().
// Correspondingly, the wide intrinsics (which are mapped to the "widest"
// available instruction set) will get vx_ prefix
// (and will be mapped to v256_ counterparts) (e.g. vx_load() => v256_load())
#if CV_AVX2
#define CV__SIMD_FORWARD 256
#include "opencv_hal_intrin_forward.hpp"
#include "opencv_hal_avx.hpp"
#endif
// AVX512 can be used together with SSE2 and AVX2, so
// we define those sets of intrinsics at once.
// For some of AVX512 intrinsics get v512_ prefix instead of v_, e.g. v512_load() vs v_load().
// Wide intrinsics will be mapped to v512_ counterparts in this case(e.g. vx_load() => v512_load())
#if CV_AVX512_SKX
#define CV__SIMD_FORWARD 512
#include "opencv_hal_intrin_forward.hpp"
#include "opencv_hal_avx512.hpp"
#endif
//! @cond IGNORED
namespace cv {
#ifndef CV_DOXYGEN
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
#endif
#ifndef CV_SIMD128
#define CV_SIMD128 0
#endif
#ifndef CV_SIMD128_64F
#define CV_SIMD128_64F 0
#endif
#ifndef CV_SIMD256
#define CV_SIMD256 0
#endif
#ifndef CV_SIMD256_64F
#define CV_SIMD256_64F 0
#endif
#ifndef CV_SIMD512
#define CV_SIMD512 0
#endif
#ifndef CV_SIMD512_64F
#define CV_SIMD512_64F 0
#endif
#ifndef CV_SIMD128_FP16
#define CV_SIMD128_FP16 0
#endif
#ifndef CV_SIMD256_FP16
#define CV_SIMD256_FP16 0
#endif
#ifndef CV_SIMD512_FP16
#define CV_SIMD512_FP16 0
#endif
//==================================================================================================
#define CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \
inline vtyp vx_setall_##short_typ(typ v) { return prefix##_setall_##short_typ(v); } \
inline vtyp vx_setzero_##short_typ() { return prefix##_setzero_##short_typ(); } \
inline vtyp vx_##loadsfx(const typ* ptr) { return prefix##_##loadsfx(ptr); } \
inline vtyp vx_##loadsfx##_aligned(const typ* ptr) { return prefix##_##loadsfx##_aligned(ptr); } \
inline vtyp vx_##loadsfx##_low(const typ* ptr) { return prefix##_##loadsfx##_low(ptr); } \
inline vtyp vx_##loadsfx##_halves(const typ* ptr0, const typ* ptr1) { return prefix##_##loadsfx##_halves(ptr0, ptr1); } \
inline void vx_store(typ* ptr, const vtyp& v) { return v_store(ptr, v); } \
inline void vx_store_aligned(typ* ptr, const vtyp& v) { return v_store_aligned(ptr, v); } \
inline vtyp vx_lut(const typ* ptr, const int* idx) { return prefix##_lut(ptr, idx); } \
inline vtyp vx_lut_pairs(const typ* ptr, const int* idx) { return prefix##_lut_pairs(ptr, idx); }
#define CV_INTRIN_DEFINE_WIDE_LUT_QUAD(typ, vtyp, prefix) \
inline vtyp vx_lut_quads(const typ* ptr, const int* idx) { return prefix##_lut_quads(ptr, idx); }
#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(typ, wtyp, prefix) \
inline wtyp vx_load_expand(const typ* ptr) { return prefix##_load_expand(ptr); }
#define CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND_Q(typ, qtyp, prefix) \
inline qtyp vx_load_expand_q(const typ* ptr) { return prefix##_load_expand_q(ptr); }
#define CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(typ, vtyp, short_typ, wtyp, qtyp, prefix, loadsfx) \
CV_INTRIN_DEFINE_WIDE_INTRIN(typ, vtyp, short_typ, prefix, loadsfx) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(typ, vtyp, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(typ, wtyp, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND_Q(typ, qtyp, prefix)
#define CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(uchar, v_uint8, u8, v_uint16, v_uint32, prefix, load) \
CV_INTRIN_DEFINE_WIDE_INTRIN_WITH_EXPAND(schar, v_int8, s8, v_int16, v_int32, prefix, load) \
CV_INTRIN_DEFINE_WIDE_INTRIN(ushort, v_uint16, u16, prefix, load) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(ushort, v_uint16, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(ushort, v_uint32, prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN(short, v_int16, s16, prefix, load) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(short, v_int16, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(short, v_int32, prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN(int, v_int32, s32, prefix, load) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(int, v_int32, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(int, v_int64, prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN(unsigned, v_uint32, u32, prefix, load) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(unsigned, v_uint32, prefix) \
CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(unsigned, v_uint64, prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN(float, v_float32, f32, prefix, load) \
CV_INTRIN_DEFINE_WIDE_LUT_QUAD(float, v_float32, prefix) \
CV_INTRIN_DEFINE_WIDE_INTRIN(int64, v_int64, s64, prefix, load) \
CV_INTRIN_DEFINE_WIDE_INTRIN(uint64, v_uint64, u64, prefix, load) \
//CV_INTRIN_DEFINE_WIDE_LOAD_EXPAND(float16_t, v_float32, prefix) //Unsupported case
template<typename _Tp> struct V_RegTraits
{
};
#define CV_DEF_REG_TRAITS(prefix, _reg, lane_type, suffix, _u_reg, _w_reg, _q_reg, _int_reg, _round_reg) \
template<> struct V_RegTraits<_reg> \
{ \
typedef _reg reg; \
typedef _u_reg u_reg; \
typedef _w_reg w_reg; \
typedef _q_reg q_reg; \
typedef _int_reg int_reg; \
typedef _round_reg round_reg; \
}
#if CV_SIMD128 || CV_SIMD128_CPP
CV_DEF_REG_TRAITS(v, v_uint8x16, uchar, u8, v_uint8x16, v_uint16x8, v_uint32x4, v_int8x16, void);
CV_DEF_REG_TRAITS(v, v_int8x16, schar, s8, v_uint8x16, v_int16x8, v_int32x4, v_int8x16, void);
CV_DEF_REG_TRAITS(v, v_uint16x8, ushort, u16, v_uint16x8, v_uint32x4, v_uint64x2, v_int16x8, void);
CV_DEF_REG_TRAITS(v, v_int16x8, short, s16, v_uint16x8, v_int32x4, v_int64x2, v_int16x8, void);
CV_DEF_REG_TRAITS(v, v_uint32x4, unsigned, u32, v_uint32x4, v_uint64x2, void, v_int32x4, void);
CV_DEF_REG_TRAITS(v, v_int32x4, int, s32, v_uint32x4, v_int64x2, void, v_int32x4, void);
#if CV_SIMD128_64F
CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, v_float64x2, void, v_int32x4, v_int32x4);
#else
CV_DEF_REG_TRAITS(v, v_float32x4, float, f32, v_float32x4, void, void, v_int32x4, v_int32x4);
#endif
CV_DEF_REG_TRAITS(v, v_uint64x2, uint64, u64, v_uint64x2, void, void, v_int64x2, void);
CV_DEF_REG_TRAITS(v, v_int64x2, int64, s64, v_uint64x2, void, void, v_int64x2, void);
#if CV_SIMD128_64F
CV_DEF_REG_TRAITS(v, v_float64x2, double, f64, v_float64x2, void, void, v_int64x2, v_int32x4);
#endif
#endif
#if CV_SIMD256
CV_DEF_REG_TRAITS(v256, v_uint8x32, uchar, u8, v_uint8x32, v_uint16x16, v_uint32x8, v_int8x32, void);
CV_DEF_REG_TRAITS(v256, v_int8x32, schar, s8, v_uint8x32, v_int16x16, v_int32x8, v_int8x32, void);
CV_DEF_REG_TRAITS(v256, v_uint16x16, ushort, u16, v_uint16x16, v_uint32x8, v_uint64x4, v_int16x16, void);
CV_DEF_REG_TRAITS(v256, v_int16x16, short, s16, v_uint16x16, v_int32x8, v_int64x4, v_int16x16, void);
CV_DEF_REG_TRAITS(v256, v_uint32x8, unsigned, u32, v_uint32x8, v_uint64x4, void, v_int32x8, void);
CV_DEF_REG_TRAITS(v256, v_int32x8, int, s32, v_uint32x8, v_int64x4, void, v_int32x8, void);
CV_DEF_REG_TRAITS(v256, v_float32x8, float, f32, v_float32x8, v_float64x4, void, v_int32x8, v_int32x8);
CV_DEF_REG_TRAITS(v256, v_uint64x4, uint64, u64, v_uint64x4, void, void, v_int64x4, void);
CV_DEF_REG_TRAITS(v256, v_int64x4, int64, s64, v_uint64x4, void, void, v_int64x4, void);
CV_DEF_REG_TRAITS(v256, v_float64x4, double, f64, v_float64x4, void, void, v_int64x4, v_int32x8);
#endif
#if CV_SIMD512
CV_DEF_REG_TRAITS(v512, v_uint8x64, uchar, u8, v_uint8x64, v_uint16x32, v_uint32x16, v_int8x64, void);
CV_DEF_REG_TRAITS(v512, v_int8x64, schar, s8, v_uint8x64, v_int16x32, v_int32x16, v_int8x64, void);
CV_DEF_REG_TRAITS(v512, v_uint16x32, ushort, u16, v_uint16x32, v_uint32x16, v_uint64x8, v_int16x32, void);
CV_DEF_REG_TRAITS(v512, v_int16x32, short, s16, v_uint16x32, v_int32x16, v_int64x8, v_int16x32, void);
CV_DEF_REG_TRAITS(v512, v_uint32x16, unsigned, u32, v_uint32x16, v_uint64x8, void, v_int32x16, void);
CV_DEF_REG_TRAITS(v512, v_int32x16, int, s32, v_uint32x16, v_int64x8, void, v_int32x16, void);
CV_DEF_REG_TRAITS(v512, v_float32x16, float, f32, v_float32x16, v_float64x8, void, v_int32x16, v_int32x16);
CV_DEF_REG_TRAITS(v512, v_uint64x8, uint64, u64, v_uint64x8, void, void, v_int64x8, void);
CV_DEF_REG_TRAITS(v512, v_int64x8, int64, s64, v_uint64x8, void, void, v_int64x8, void);
CV_DEF_REG_TRAITS(v512, v_float64x8, double, f64, v_float64x8, void, void, v_int64x8, v_int32x16);
#endif
#if CV_SIMD512// && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 512)
#define CV__SIMD_NAMESPACE simd512
namespace CV__SIMD_NAMESPACE {
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD512_64F
#define CV_SIMD_FP16 CV_SIMD512_FP16
#define CV_SIMD_WIDTH 64
typedef v_uint8x64 v_uint8;
typedef v_int8x64 v_int8;
typedef v_uint16x32 v_uint16;
typedef v_int16x32 v_int16;
typedef v_uint32x16 v_uint32;
typedef v_int32x16 v_int32;
typedef v_uint64x8 v_uint64;
typedef v_int64x8 v_int64;
typedef v_float32x16 v_float32;
CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v512)
#if CV_SIMD512_64F
typedef v_float64x8 v_float64;
CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v512, load)
#endif
inline void vx_cleanup() { v512_cleanup(); }
} // namespace
using namespace CV__SIMD_NAMESPACE;
#elif CV_SIMD256// && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 256)
#define CV__SIMD_NAMESPACE simd256
namespace CV__SIMD_NAMESPACE {
#define CV_SIMD 1
#define CV_SIMD_64F CV_SIMD256_64F
#define CV_SIMD_FP16 CV_SIMD256_FP16
#define CV_SIMD_WIDTH 32
typedef v_uint8x32 v_uint8;
typedef v_int8x32 v_int8;
typedef v_uint16x16 v_uint16;
typedef v_int16x16 v_int16;
typedef v_uint32x8 v_uint32;
typedef v_int32x8 v_int32;
typedef v_uint64x4 v_uint64;
typedef v_int64x4 v_int64;
typedef v_float32x8 v_float32;
CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v256)
#if CV_SIMD256_64F
typedef v_float64x4 v_float64;
CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v256, load)
#endif
inline void vx_cleanup() { v256_cleanup(); }
} // namespace
using namespace CV__SIMD_NAMESPACE;
#elif (CV_SIMD128 || CV_SIMD128_CPP) && (!defined(CV__SIMD_FORCE_WIDTH) || CV__SIMD_FORCE_WIDTH == 128)
#define CV__SIMD_NAMESPACE simd128
namespace CV__SIMD_NAMESPACE {
#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;
typedef v_int16x8 v_int16;
typedef v_uint32x4 v_uint32;
typedef v_int32x4 v_int32;
typedef v_uint64x2 v_uint64;
typedef v_int64x2 v_int64;
typedef v_float32x4 v_float32;
CV_INTRIN_DEFINE_WIDE_INTRIN_ALL_TYPES(v)
#if CV_SIMD128_64F
typedef v_float64x2 v_float64;
CV_INTRIN_DEFINE_WIDE_INTRIN(double, v_float64, f64, v, load)
#endif
inline void vx_cleanup() { v_cleanup(); }
} // namespace
using namespace CV__SIMD_NAMESPACE;
#endif
#ifndef CV_DOXYGEN
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
#endif
#ifndef CV_SIMD_64F
#define CV_SIMD_64F 0
#endif
#ifndef CV_SIMD_FP16
#define CV_SIMD_FP16 0 //!< Defined to 1 on native support of operations with float16x8_t / float16x16_t (SIMD256) types
#endif
#ifndef CV_SIMD
#define CV_SIMD 0
#endif
} // cv::
//! @endcond
#endif

View File

@ -1,191 +0,0 @@
// This file is part of OpenCV project.
// 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
#ifndef CV__SIMD_FORWARD
#error "Need to pre-define forward width"
#endif
namespace cv
{
//! @cond IGNORED
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_BEGIN
/** Types **/
#if CV__SIMD_FORWARD == 1024
// [todo] 1024
#error "1024-long ops not implemented yet"
#elif CV__SIMD_FORWARD == 512
// 512
#define __CV_VX(fun) v512_##fun
#define __CV_V_UINT8 v_uint8x64
#define __CV_V_INT8 v_int8x64
#define __CV_V_UINT16 v_uint16x32
#define __CV_V_INT16 v_int16x32
#define __CV_V_UINT32 v_uint32x16
#define __CV_V_INT32 v_int32x16
#define __CV_V_UINT64 v_uint64x8
#define __CV_V_INT64 v_int64x8
#define __CV_V_FLOAT32 v_float32x16
#define __CV_V_FLOAT64 v_float64x8
struct v_uint8x64;
struct v_int8x64;
struct v_uint16x32;
struct v_int16x32;
struct v_uint32x16;
struct v_int32x16;
struct v_uint64x8;
struct v_int64x8;
struct v_float32x16;
struct v_float64x8;
#elif CV__SIMD_FORWARD == 256
// 256
#define __CV_VX(fun) v256_##fun
#define __CV_V_UINT8 v_uint8x32
#define __CV_V_INT8 v_int8x32
#define __CV_V_UINT16 v_uint16x16
#define __CV_V_INT16 v_int16x16
#define __CV_V_UINT32 v_uint32x8
#define __CV_V_INT32 v_int32x8
#define __CV_V_UINT64 v_uint64x4
#define __CV_V_INT64 v_int64x4
#define __CV_V_FLOAT32 v_float32x8
#define __CV_V_FLOAT64 v_float64x4
struct v_uint8x32;
struct v_int8x32;
struct v_uint16x16;
struct v_int16x16;
struct v_uint32x8;
struct v_int32x8;
struct v_uint64x4;
struct v_int64x4;
struct v_float32x8;
struct v_float64x4;
#else
// 128
#define __CV_VX(fun) v_##fun
#define __CV_V_UINT8 v_uint8x16
#define __CV_V_INT8 v_int8x16
#define __CV_V_UINT16 v_uint16x8
#define __CV_V_INT16 v_int16x8
#define __CV_V_UINT32 v_uint32x4
#define __CV_V_INT32 v_int32x4
#define __CV_V_UINT64 v_uint64x2
#define __CV_V_INT64 v_int64x2
#define __CV_V_FLOAT32 v_float32x4
#define __CV_V_FLOAT64 v_float64x2
struct v_uint8x16;
struct v_int8x16;
struct v_uint16x8;
struct v_int16x8;
struct v_uint32x4;
struct v_int32x4;
struct v_uint64x2;
struct v_int64x2;
struct v_float32x4;
struct v_float64x2;
#endif
/** Value reordering **/
// Expansion
void v_expand(const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
void v_expand(const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
void v_expand(const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
void v_expand(const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
void v_expand(const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
void v_expand(const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
// Low Expansion
__CV_V_UINT16 v_expand_low(const __CV_V_UINT8&);
__CV_V_INT16 v_expand_low(const __CV_V_INT8&);
__CV_V_UINT32 v_expand_low(const __CV_V_UINT16&);
__CV_V_INT32 v_expand_low(const __CV_V_INT16&);
__CV_V_UINT64 v_expand_low(const __CV_V_UINT32&);
__CV_V_INT64 v_expand_low(const __CV_V_INT32&);
// High Expansion
__CV_V_UINT16 v_expand_high(const __CV_V_UINT8&);
__CV_V_INT16 v_expand_high(const __CV_V_INT8&);
__CV_V_UINT32 v_expand_high(const __CV_V_UINT16&);
__CV_V_INT32 v_expand_high(const __CV_V_INT16&);
__CV_V_UINT64 v_expand_high(const __CV_V_UINT32&);
__CV_V_INT64 v_expand_high(const __CV_V_INT32&);
// Load & Low Expansion
__CV_V_UINT16 __CV_VX(load_expand)(const uchar*);
__CV_V_INT16 __CV_VX(load_expand)(const schar*);
__CV_V_UINT32 __CV_VX(load_expand)(const ushort*);
__CV_V_INT32 __CV_VX(load_expand)(const short*);
__CV_V_UINT64 __CV_VX(load_expand)(const uint*);
__CV_V_INT64 __CV_VX(load_expand)(const int*);
// Load lower 8-bit and expand into 32-bit
__CV_V_UINT32 __CV_VX(load_expand_q)(const uchar*);
__CV_V_INT32 __CV_VX(load_expand_q)(const schar*);
// Saturating Pack
__CV_V_UINT8 v_pack(const __CV_V_UINT16&, const __CV_V_UINT16&);
__CV_V_INT8 v_pack(const __CV_V_INT16&, const __CV_V_INT16&);
__CV_V_UINT16 v_pack(const __CV_V_UINT32&, const __CV_V_UINT32&);
__CV_V_INT16 v_pack(const __CV_V_INT32&, const __CV_V_INT32&);
// Non-saturating Pack
__CV_V_UINT32 v_pack(const __CV_V_UINT64&, const __CV_V_UINT64&);
__CV_V_INT32 v_pack(const __CV_V_INT64&, const __CV_V_INT64&);
// Pack signed integers with unsigned saturation
__CV_V_UINT8 v_pack_u(const __CV_V_INT16&, const __CV_V_INT16&);
__CV_V_UINT16 v_pack_u(const __CV_V_INT32&, const __CV_V_INT32&);
/** Arithmetic, bitwise and comparison operations **/
// Non-saturating multiply
#if CV_VSX
template<typename Tvec>
Tvec v_mul_wrap(const Tvec& a, const Tvec& b);
#else
__CV_V_UINT8 v_mul_wrap(const __CV_V_UINT8&, const __CV_V_UINT8&);
__CV_V_INT8 v_mul_wrap(const __CV_V_INT8&, const __CV_V_INT8&);
__CV_V_UINT16 v_mul_wrap(const __CV_V_UINT16&, const __CV_V_UINT16&);
__CV_V_INT16 v_mul_wrap(const __CV_V_INT16&, const __CV_V_INT16&);
#endif
// Multiply and expand
#if CV_VSX
template<typename Tvec, typename Twvec>
void v_mul_expand(const Tvec& a, const Tvec& b, Twvec& c, Twvec& d);
#else
void v_mul_expand(const __CV_V_UINT8&, const __CV_V_UINT8&, __CV_V_UINT16&, __CV_V_UINT16&);
void v_mul_expand(const __CV_V_INT8&, const __CV_V_INT8&, __CV_V_INT16&, __CV_V_INT16&);
void v_mul_expand(const __CV_V_UINT16&, const __CV_V_UINT16&, __CV_V_UINT32&, __CV_V_UINT32&);
void v_mul_expand(const __CV_V_INT16&, const __CV_V_INT16&, __CV_V_INT32&, __CV_V_INT32&);
void v_mul_expand(const __CV_V_UINT32&, const __CV_V_UINT32&, __CV_V_UINT64&, __CV_V_UINT64&);
void v_mul_expand(const __CV_V_INT32&, const __CV_V_INT32&, __CV_V_INT64&, __CV_V_INT64&);
#endif
// Conversions
__CV_V_FLOAT32 v_cvt_f32(const __CV_V_INT32& a);
__CV_V_FLOAT32 v_cvt_f32(const __CV_V_FLOAT64& a);
__CV_V_FLOAT32 v_cvt_f32(const __CV_V_FLOAT64& a, const __CV_V_FLOAT64& b);
__CV_V_FLOAT64 v_cvt_f64(const __CV_V_INT32& a);
__CV_V_FLOAT64 v_cvt_f64_high(const __CV_V_INT32& a);
__CV_V_FLOAT64 v_cvt_f64(const __CV_V_FLOAT32& a);
__CV_V_FLOAT64 v_cvt_f64_high(const __CV_V_FLOAT32& a);
__CV_V_FLOAT64 v_cvt_f64(const __CV_V_INT64& a);
/** Cleanup **/
#undef CV__SIMD_FORWARD
#undef __CV_VX
#undef __CV_V_UINT8
#undef __CV_V_INT8
#undef __CV_V_UINT16
#undef __CV_V_INT16
#undef __CV_V_UINT32
#undef __CV_V_INT32
#undef __CV_V_UINT64
#undef __CV_V_INT64
#undef __CV_V_FLOAT32
#undef __CV_V_FLOAT64
CV_CPU_OPTIMIZATION_HAL_NAMESPACE_END
//! @endcond
} // cv::

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff