From ae3dfa80db593ee8d192659cd095b4f90b3ec469 Mon Sep 17 00:00:00 2001 From: Maksim Shabunin Date: Thu, 25 Aug 2016 16:08:35 +0300 Subject: [PATCH] OpenVX HAL --- 3rdparty/openvx/CMakeLists.txt | 17 +++ 3rdparty/openvx/include/openvx_hal.hpp | 196 +++++++++++++++++++++++++ 3rdparty/openvx/src/openvx_hal.cpp | 8 + CMakeLists.txt | 15 ++ cmake/FindOpenVX.cmake | 20 +++ 5 files changed, 256 insertions(+) create mode 100644 3rdparty/openvx/CMakeLists.txt create mode 100644 3rdparty/openvx/include/openvx_hal.hpp create mode 100644 3rdparty/openvx/src/openvx_hal.cpp create mode 100644 cmake/FindOpenVX.cmake diff --git a/3rdparty/openvx/CMakeLists.txt b/3rdparty/openvx/CMakeLists.txt new file mode 100644 index 0000000000..ae9285eaf7 --- /dev/null +++ b/3rdparty/openvx/CMakeLists.txt @@ -0,0 +1,17 @@ +add_library(openvx_hal STATIC src/openvx_hal.cpp) +target_include_directories(openvx_hal PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/modules/core/include + ${OPENVX_INCLUDE_DIR}) +target_link_libraries(openvx_hal LINK_PUBLIC ${OPENVX_LIBRARIES}) +set_target_properties(openvx_hal PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +set_target_properties(openvx_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}) +if(NOT BUILD_SHARED_LIBS) + ocv_install_target(openvx_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev) +endif() + +set(OPENVX_HAL_FOUND TRUE PARENT_SCOPE) +set(OPENVX_HAL_VERSION 0.0.1 PARENT_SCOPE) +set(OPENVX_HAL_LIBRARIES "openvx_hal" PARENT_SCOPE) +set(OPENVX_HAL_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/include/openvx_hal.hpp" PARENT_SCOPE) +set(OPENVX_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" "${OPENVX_INCLUDE_DIR}" PARENT_SCOPE) diff --git a/3rdparty/openvx/include/openvx_hal.hpp b/3rdparty/openvx/include/openvx_hal.hpp new file mode 100644 index 0000000000..893547dfdf --- /dev/null +++ b/3rdparty/openvx/include/openvx_hal.hpp @@ -0,0 +1,196 @@ +#ifndef OPENCV_OPENVX_HAL_HPP_INCLUDED +#define OPENCV_OPENVX_HAL_HPP_INCLUDED + +#include "opencv2/core/hal/interface.h" + +#include "VX/vx.h" +#include "VX/vxu.h" + +#include + +//================================================================================================== +// utility +// ... + +#if 0 +#include +#define PRINT(...) printf(__VA_ARGS__) +#else +#define PRINT(...) +#endif + +#if __cplusplus >= 201103L +#include +struct Tick +{ + typedef std::chrono::time_point point_t; + point_t start; + point_t point; + Tick() + { + start = std::chrono::steady_clock::now(); + point = std::chrono::steady_clock::now(); + } + inline int one() + { + point_t old = point; + point = std::chrono::steady_clock::now(); + return std::chrono::duration_cast(point - old).count(); + } + inline int total() + { + return std::chrono::duration_cast(std::chrono::steady_clock::now() - start).count(); + } +}; +#endif + +//================================================================================================== +// One more OpenVX C++ binding :-) +// ... + +template +struct VX_Traits +{ + enum { + Type = 0 + }; +}; + +template <> +struct VX_Traits +{ + enum { + Type = VX_DF_IMAGE_U8 + }; +}; + +template <> +struct VX_Traits +{ + enum { + Type = VX_DF_IMAGE_U16 + }; +}; + +template <> +struct VX_Traits +{ + enum { + Type = VX_DF_IMAGE_S16 + }; +}; + + +struct vxContext; +struct vxImage; +struct vxErr; + + +struct vxErr +{ + vx_status status; + std::string msg; + vxErr(vx_status status_, const std::string & msg_) : status(status_), msg(msg_) {} + void check() + { + if (status != VX_SUCCESS) + throw *this; + } + void print() + { + PRINT("OpenVX HAL impl error: %d (%s)\n", status, msg.c_str()); + } + static void check(vx_context ctx) + { + vxErr(vxGetStatus((vx_reference)ctx), "context check").check(); + } + static void check(vx_image img) + { + vxErr(vxGetStatus((vx_reference)img), "image check").check(); + } + static void check(vx_status s) + { + vxErr(s, "status check").check(); + } +}; + + +struct vxContext +{ + vx_context ctx; + static vxContext * getContext(); +private: + vxContext() + { + ctx = vxCreateContext(); + vxErr::check(ctx); + } + ~vxContext() + { + vxReleaseContext(&ctx); + } +}; + + +struct vxImage +{ + vx_image img; + + template + vxImage(vxContext &ctx, const T *data, size_t step, int w, int h) + { + if (h == 1) + step = w * sizeof(T); + vx_imagepatch_addressing_t addr; + addr.dim_x = w; + addr.dim_y = h; + addr.stride_x = sizeof(T); + addr.stride_y = step; + addr.scale_x = VX_SCALE_UNITY; + addr.scale_y = VX_SCALE_UNITY; + addr.step_x = 1; + addr.step_y = 1; + void *ptrs[] = { (void*)data }; + img = vxCreateImageFromHandle(ctx.ctx, VX_Traits::Type, &addr, ptrs, VX_MEMORY_TYPE_HOST); + vxErr::check(img); + } + ~vxImage() + { + vxSwapImageHandle(img, NULL, NULL, 1); + vxReleaseImage(&img); + } +}; + +//================================================================================================== +// real code starts here +// ... + +template +inline int ovx_hal_add(const T *a, size_t astep, const T *b, size_t bstep, T *c, size_t cstep, int w, int h) +{ + try + { + vxContext * ctx = vxContext::getContext(); + vxImage ia(*ctx, a, astep, w, h); + vxImage ib(*ctx, b, bstep, w, h); + vxImage ic(*ctx, c, cstep, w, h); + vxErr::check(vxuAdd(ctx->ctx, ia.img, ib.img, VX_CONVERT_POLICY_SATURATE, ic.img)); + } + catch (vxErr & e) + { + e.print(); + return CV_HAL_ERROR_UNKNOWN; + } + return CV_HAL_ERROR_OK; +} + +//================================================================================================== +// functions redefinition +// ... + +#undef cv_hal_add8u +#define cv_hal_add8u ovx_hal_add +#undef cv_hal_add16s +#define cv_hal_add16s ovx_hal_add + +#endif diff --git a/3rdparty/openvx/src/openvx_hal.cpp b/3rdparty/openvx/src/openvx_hal.cpp new file mode 100644 index 0000000000..e95bbb2b58 --- /dev/null +++ b/3rdparty/openvx/src/openvx_hal.cpp @@ -0,0 +1,8 @@ +#include "openvx_hal.hpp" + +vxContext * vxContext::getContext() +{ + // not thread safe + static vxContext instance; + return &instance; +} diff --git a/CMakeLists.txt b/CMakeLists.txt index c9568546f7..9daf330033 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,7 @@ OCV_OPTION(WITH_JPEG "Include JPEG support" ON) OCV_OPTION(WITH_WEBP "Include WebP support" ON IF (NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ON IF (NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF IF (NOT ANDROID AND NOT WINRT) ) +OCV_OPTION(WITH_OPENVX "Include OpenVX support" OFF) OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_OPENNI2 "Include OpenNI2 support" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT) ) OCV_OPTION(WITH_PNG "Include PNG support" ON) @@ -615,6 +616,9 @@ endif() include(cmake/OpenCVDetectVTK.cmake) +if(WITH_OPENVX) + include(cmake/FindOpenVX.cmake) +endif() # ---------------------------------------------------------------------------- # OpenCV HAL @@ -640,6 +644,12 @@ if(NOT DEFINED OpenCV_HAL) set(OpenCV_HAL "OpenCV_HAL") endif() +if(HAVE_OPENVX) + if(NOT ";${OpenCV_HAL};" MATCHES ";openvx;") + set(OpenCV_HAL "openvx;${OpenCV_HAL}") + endif() +endif() + if(WITH_CAROTENE) ocv_debug_message(STATUS "Enable carotene acceleration") if(NOT ";${OpenCV_HAL};" MATCHES ";carotene;") @@ -652,6 +662,10 @@ foreach(hal ${OpenCV_HAL}) add_subdirectory(3rdparty/carotene/hal) ocv_hal_register(CAROTENE_HAL_LIBRARIES CAROTENE_HAL_HEADERS CAROTENE_HAL_INCLUDE_DIRS) list(APPEND OpenCV_USED_HAL "carotene (ver ${CAROTENE_HAL_VERSION})") + elseif(hal STREQUAL "openvx") + add_subdirectory(3rdparty/openvx) + ocv_hal_register(OPENVX_HAL_LIBRARIES OPENVX_HAL_HEADERS OPENVX_HAL_INCLUDE_DIRS) + list(APPEND OpenCV_USED_HAL "openvx (ver ${OPENVX_HAL_VERSION})") else() ocv_debug_message(STATUS "OpenCV HAL: ${hal} ...") ocv_clear_vars(OpenCV_HAL_LIBRARIES OpenCV_HAL_HEADERS OpenCV_HAL_INCLUDE_DIRS) @@ -1219,6 +1233,7 @@ endif(DEFINED WITH_LAPACK) status(" Use Eigen:" HAVE_EIGEN THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO) status(" Use Cuda:" HAVE_CUDA THEN "YES (ver ${CUDA_VERSION_STRING})" ELSE NO) status(" Use OpenCL:" HAVE_OPENCL THEN YES ELSE NO) +status(" Use OpenVX:" HAVE_OPENVX THEN "YES (${OPENVX_LIBS})" ELSE "NO") status(" Use custom HAL:" OpenCV_USED_HAL THEN "YES (${OpenCV_USED_HAL})" ELSE "NO") if(HAVE_CUDA) diff --git a/cmake/FindOpenVX.cmake b/cmake/FindOpenVX.cmake new file mode 100644 index 0000000000..dc1f7617bd --- /dev/null +++ b/cmake/FindOpenVX.cmake @@ -0,0 +1,20 @@ +ocv_clear_vars(HAVE_OPENVX OPENVX_LIBS) + +set(OPENVX_ROOT "" CACHE PATH "OpenVX install directory") + +if(OPENVX_ROOT) + find_path(OPENVX_INCLUDE_DIR "VX/vx.h" PATHS "${OPENVX_ROOT}/include" DOC "OpenVX include path") + find_library(OPENVX_openvx_LIB "openvx" PATHS "${OPENVX_ROOT}/lib") + find_library(OPENVX_vxu_LIB "vxu" PATHS "${OPENVX_ROOT}/lib") + set(OPENVX_LIBRARIES "${OPENVX_openvx_LIB}" "${OPENVX_vxu_LIB}" CACHE STRING "OpenVX libraries") + if (OPENVX_INCLUDE_DIR AND OPENVX_LIBRARIES) + set(HAVE_OPENVX TRUE) + endif() +endif() + +if(NOT HAVE_OPENVX) + unset(OPENVX_LIBRARIES CACHE) + unset(OPENVX_INCLUDE_DIR CACHE) + unset(HAVE_OPENVX) + message(STATUS "OpenVX: OFF") +endif()