mirror of
https://github.com/opencv/opencv.git
synced 2025-08-05 22:19:14 +08:00
Merge pull request #24231 from fengyuentau:halide_cleanup_5.x
dnn: cleanup of halide backend for 5.x #24231 Merge with https://github.com/opencv/opencv_extra/pull/1092. ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
parent
0976765c62
commit
d789cb459c
@ -297,9 +297,6 @@ OCV_OPTION(WITH_WAYLAND "Include Wayland support" OFF
|
||||
OCV_OPTION(WITH_IPP "Include Intel IPP support" (NOT MINGW AND NOT CV_DISABLE_OPTIMIZATION)
|
||||
VISIBLE_IF (X86_64 OR X86) AND NOT WINRT AND NOT IOS
|
||||
VERIFY HAVE_IPP)
|
||||
OCV_OPTION(WITH_HALIDE "Include Halide support" OFF
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY HAVE_HALIDE)
|
||||
OCV_OPTION(WITH_VULKAN "Include Vulkan support" OFF
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY HAVE_VULKAN)
|
||||
@ -831,11 +828,6 @@ if(WITH_OPENCL)
|
||||
include(cmake/OpenCVDetectOpenCL.cmake)
|
||||
endif()
|
||||
|
||||
# --- Halide ---
|
||||
if(WITH_HALIDE)
|
||||
include(cmake/OpenCVDetectHalide.cmake)
|
||||
endif()
|
||||
|
||||
# --- VkCom ---
|
||||
if(WITH_VULKAN)
|
||||
include(cmake/OpenCVDetectVulkan.cmake)
|
||||
@ -1621,10 +1613,6 @@ if(WITH_LAPACK OR HAVE_LAPACK)
|
||||
status(" Lapack:" HAVE_LAPACK THEN "YES (${LAPACK_LIBRARIES} ${LAPACK_VERSION})" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(WITH_HALIDE OR HAVE_HALIDE)
|
||||
status(" Halide:" HAVE_HALIDE THEN "YES (${HALIDE_LIBRARIES} ${HALIDE_INCLUDE_DIRS})" ELSE NO)
|
||||
endif()
|
||||
|
||||
if(HAVE_OPENVINO
|
||||
OR (WITH_OPENVINO AND NOT WITH_INF_ENGINE AND NOT INF_ENGINE_TARGET)
|
||||
)
|
||||
|
@ -1,47 +0,0 @@
|
||||
cmake_minimum_required(VERSION ${MIN_VER_CMAKE})
|
||||
|
||||
if(" ${HALIDE_ROOT_DIR}" STREQUAL " ")
|
||||
unset(HALIDE_ROOT_DIR CACHE)
|
||||
endif()
|
||||
ocv_check_environment_variables(HALIDE_ROOT_DIR)
|
||||
set(HALIDE_ROOT_DIR "${HALIDE_ROOT_DIR}" CACHE PATH "Halide root directory")
|
||||
|
||||
if(NOT HAVE_HALIDE)
|
||||
find_package(Halide QUIET) # Try CMake-based config files
|
||||
if(Halide_FOUND)
|
||||
if(TARGET Halide::Halide) # modern Halide scripts defines imported target
|
||||
set(HALIDE_INCLUDE_DIRS "")
|
||||
set(HALIDE_LIBRARIES "Halide::Halide")
|
||||
set(HAVE_HALIDE TRUE)
|
||||
else()
|
||||
# using HALIDE_INCLUDE_DIRS / Halide_LIBRARIES
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_HALIDE AND HALIDE_ROOT_DIR)
|
||||
# Try manual search
|
||||
find_library(HALIDE_LIBRARY
|
||||
NAMES Halide
|
||||
HINTS ${HALIDE_ROOT_DIR}/lib # Unix
|
||||
HINTS ${HALIDE_ROOT_DIR}/lib/Release # Win32
|
||||
)
|
||||
find_path(HALIDE_INCLUDE_DIR
|
||||
NAMES Halide.h HalideRuntime.h
|
||||
HINTS ${HALIDE_ROOT_DIR}/include
|
||||
)
|
||||
if(HALIDE_LIBRARY AND HALIDE_INCLUDE_DIR)
|
||||
# TODO try_compile
|
||||
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}")
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}")
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_HALIDE)
|
||||
if(HALIDE_INCLUDE_DIRS)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
endif()
|
||||
list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES})
|
||||
endif()
|
@ -53,9 +53,6 @@
|
||||
/* Geospatial Data Abstraction Library */
|
||||
#cmakedefine HAVE_GDAL
|
||||
|
||||
/* Halide support */
|
||||
#cmakedefine HAVE_HALIDE
|
||||
|
||||
/* Vulkan support */
|
||||
#cmakedefine HAVE_VULKAN
|
||||
|
||||
|
@ -3,7 +3,7 @@ Load Caffe framework models {#tutorial_dnn_googlenet}
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@next_tutorial{tutorial_dnn_halide}
|
||||
@next_tutorial{tutorial_dnn_openvino}
|
||||
|
||||
| | |
|
||||
| -: | :- |
|
||||
|
@ -1,88 +0,0 @@
|
||||
# How to enable Halide backend for improve efficiency {#tutorial_dnn_halide}
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@prev_tutorial{tutorial_dnn_googlenet}
|
||||
@next_tutorial{tutorial_dnn_halide_scheduling}
|
||||
|
||||
| | |
|
||||
| -: | :- |
|
||||
| Original author | Dmitry Kurtaev |
|
||||
| Compatibility | OpenCV >= 3.3 |
|
||||
|
||||
## Introduction
|
||||
This tutorial guidelines how to run your models in OpenCV deep learning module
|
||||
using Halide language backend. Halide is an open-source project that let us
|
||||
write image processing algorithms in well-readable format, schedule computations
|
||||
according to specific device and evaluate it with a quite good efficiency.
|
||||
|
||||
An official website of the Halide project: http://halide-lang.org/.
|
||||
|
||||
An up to date efficiency comparison: https://github.com/opencv/opencv/wiki/DNN-Efficiency
|
||||
|
||||
## Requirements
|
||||
### LLVM compiler
|
||||
|
||||
@note LLVM compilation might take a long time.
|
||||
|
||||
- Download LLVM source code from http://releases.llvm.org/4.0.0/llvm-4.0.0.src.tar.xz.
|
||||
Unpack it. Let **llvm_root** is a root directory of source code.
|
||||
|
||||
- Create directory **llvm_root**/tools/clang
|
||||
|
||||
- Download Clang with the same version as LLVM. In our case it will be from
|
||||
http://releases.llvm.org/4.0.0/cfe-4.0.0.src.tar.xz. Unpack it into
|
||||
**llvm_root**/tools/clang. Note that it should be a root for Clang source code.
|
||||
|
||||
- Build LLVM on Linux
|
||||
@code
|
||||
cd llvm_root
|
||||
mkdir build && cd build
|
||||
cmake -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Release ..
|
||||
make -j4
|
||||
@endcode
|
||||
|
||||
- Build LLVM on Windows (Developer Command Prompt)
|
||||
@code
|
||||
mkdir \\path-to-llvm-build\\ && cd \\path-to-llvm-build\\
|
||||
cmake.exe -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_TARGETS_TO_BUILD=X86 -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=\\path-to-llvm-install\\ -G "Visual Studio 14 Win64" \\path-to-llvm-src\\
|
||||
MSBuild.exe /m:4 /t:Build /p:Configuration=Release .\\INSTALL.vcxproj
|
||||
@endcode
|
||||
|
||||
@note `\\path-to-llvm-build\\` and `\\path-to-llvm-install\\` are different directories.
|
||||
|
||||
### Halide language.
|
||||
|
||||
- Download source code from GitHub repository, https://github.com/halide/Halide
|
||||
or using git. The root directory will be a **halide_root**.
|
||||
@code
|
||||
git clone https://github.com/halide/Halide.git
|
||||
@endcode
|
||||
|
||||
- Build Halide on Linux
|
||||
@code
|
||||
cd halide_root
|
||||
mkdir build && cd build
|
||||
cmake -DLLVM_DIR=llvm_root/build/lib/cmake/llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_VERSION=40 -DWITH_TESTS=OFF -DWITH_APPS=OFF -DWITH_TUTORIALS=OFF ..
|
||||
make -j4
|
||||
@endcode
|
||||
|
||||
- Build Halide on Windows (Developer Command Prompt)
|
||||
@code
|
||||
cd halide_root
|
||||
mkdir build && cd build
|
||||
cmake.exe -DLLVM_DIR=\\path-to-llvm-install\\lib\\cmake\\llvm -DLLVM_VERSION=40 -DWITH_TESTS=OFF -DWITH_APPS=OFF -DWITH_TUTORIALS=OFF -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 14 Win64" ..
|
||||
MSBuild.exe /m:4 /t:Build /p:Configuration=Release .\\ALL_BUILD.vcxproj
|
||||
@endcode
|
||||
|
||||
## Build OpenCV with Halide backend
|
||||
When you build OpenCV add the following configuration flags:
|
||||
|
||||
- `WITH_HALIDE` - enable Halide linkage
|
||||
|
||||
- `HALIDE_ROOT_DIR` - path to Halide build directory
|
||||
|
||||
## Set Halide as a preferable backend
|
||||
@code
|
||||
net.setPreferableBackend(DNN_BACKEND_HALIDE);
|
||||
@endcode
|
@ -1,92 +0,0 @@
|
||||
# How to schedule your network for Halide backend {#tutorial_dnn_halide_scheduling}
|
||||
|
||||
@tableofcontents
|
||||
|
||||
@prev_tutorial{tutorial_dnn_halide}
|
||||
@next_tutorial{tutorial_dnn_openvino}
|
||||
|
||||
| | |
|
||||
| -: | :- |
|
||||
| Original author | Dmitry Kurtaev |
|
||||
| Compatibility | OpenCV >= 3.3 |
|
||||
|
||||
## Introduction
|
||||
Halide code is the same for every device we use. But for achieving the satisfied
|
||||
efficiency we should schedule computations properly. In this tutorial we describe
|
||||
the ways to schedule your networks using Halide backend in OpenCV deep learning module.
|
||||
|
||||
For better understanding of Halide scheduling you might want to read tutorials @ http://halide-lang.org/tutorials.
|
||||
|
||||
If it's your first meeting with Halide in OpenCV, we recommend to start from @ref tutorial_dnn_halide.
|
||||
|
||||
## Configuration files
|
||||
You can schedule computations of Halide pipeline by writing textual configuration files.
|
||||
It means that you can easily vectorize, parallelize and manage loops order of
|
||||
layers computation. Pass path to file with scheduling directives for specific
|
||||
device into ```cv::dnn::Net::setHalideScheduler``` before the first ```cv::dnn::Net::forward``` call.
|
||||
|
||||
Scheduling configuration files represented as YAML files where each node is a
|
||||
scheduled function or a scheduling directive.
|
||||
@code
|
||||
relu1:
|
||||
reorder: [x, c, y]
|
||||
split: { y: 2, c: 8 }
|
||||
parallel: [yo, co]
|
||||
unroll: yi
|
||||
vectorize: { x: 4 }
|
||||
conv1_constant_exterior:
|
||||
compute_at: { relu1: yi }
|
||||
@endcode
|
||||
|
||||
Considered use variables `n` for batch dimension, `c` for channels,
|
||||
`y` for rows and `x` for columns. For variables after split are used names
|
||||
with the same prefix but `o` and `i` suffixes for outer and inner variables
|
||||
correspondingly. In example, for variable `x` in range `[0, 10)` directive
|
||||
`split: { x: 2 }` gives new ones `xo` in range `[0, 5)` and `xi` in range `[0, 2)`.
|
||||
Variable name `x` is no longer available in the same scheduling node.
|
||||
|
||||
You can find scheduling examples at [opencv_extra/testdata/dnn](https://github.com/opencv/opencv_extra/tree/5.x/testdata/dnn)
|
||||
and use it for schedule your networks.
|
||||
|
||||
## Layers fusing
|
||||
Thanks to layers fusing we can schedule only the top layers of fused sets.
|
||||
Because for every output value we use the fused formula.
|
||||
In example, if you have three layers Convolution + Scale + ReLU one by one,
|
||||
@code
|
||||
conv(x, y, c, n) = sum(...) + bias(c);
|
||||
scale(x, y, c, n) = conv(x, y, c, n) * weights(c);
|
||||
relu(x, y, c, n) = max(scale(x, y, c, n), 0);
|
||||
@endcode
|
||||
|
||||
fused function is something like
|
||||
@code
|
||||
relu(x, y, c, n) = max((sum(...) + bias(c)) * weights(c), 0);
|
||||
@endcode
|
||||
|
||||
So only function called `relu` require scheduling.
|
||||
|
||||
## Scheduling patterns
|
||||
Sometimes networks built using blocked structure that means some layer are
|
||||
identical or quite similar. If you want to apply the same scheduling for
|
||||
different layers accurate to tiling or vectorization factors, define scheduling
|
||||
patterns in section `patterns` at the beginning of scheduling file.
|
||||
Also, your patterns may use some parametric variables.
|
||||
@code
|
||||
# At the beginning of the file
|
||||
patterns:
|
||||
fully_connected:
|
||||
split: { c: c_split }
|
||||
fuse: { src: [x, y, co], dst: block }
|
||||
parallel: block
|
||||
vectorize: { ci: c_split }
|
||||
# Somewhere below
|
||||
fc8:
|
||||
pattern: fully_connected
|
||||
params: { c_split: 8 }
|
||||
@endcode
|
||||
|
||||
## Automatic scheduling
|
||||
You can let DNN to schedule layers automatically. Just skip call of ```cv::dnn::Net::setHalideScheduler```. Sometimes it might be even more efficient than manual scheduling.
|
||||
But if specific layers require be scheduled manually, you would be able to
|
||||
mix both manual and automatic scheduling ways. Write scheduling file
|
||||
and skip layers that you want to be scheduled automatically.
|
@ -1,7 +1,7 @@
|
||||
OpenCV usage with OpenVINO {#tutorial_dnn_openvino}
|
||||
=====================
|
||||
|
||||
@prev_tutorial{tutorial_dnn_halide_scheduling}
|
||||
@prev_tutorial{tutorial_dnn_googlenet}
|
||||
@next_tutorial{tutorial_dnn_android}
|
||||
|
||||
| | |
|
||||
|
@ -2,8 +2,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
=====================================
|
||||
|
||||
- @subpage tutorial_dnn_googlenet
|
||||
- @subpage tutorial_dnn_halide
|
||||
- @subpage tutorial_dnn_halide_scheduling
|
||||
- @subpage tutorial_dnn_openvino
|
||||
- @subpage tutorial_dnn_android
|
||||
- @subpage tutorial_dnn_yolo
|
||||
|
@ -492,7 +492,6 @@ OpenCV have own DNN inference module which have own build-in engine, but can als
|
||||
| `WITH_NGRAPH` | _OFF_ | **Deprecated since OpenVINO 2022.1** Enables Intel NGraph library support. This library is part of Inference Engine backend which allows executing arbitrary networks read from files in multiple formats supported by OpenCV: Caffe, TensorFlow, PyTorch, Darknet, etc.. NGraph library must be installed, it is included into Inference Engine. |
|
||||
| `WITH_OPENVINO` | _OFF_ | Enable Intel OpenVINO Toolkit support. Should be used for OpenVINO>=2022.1 instead of `WITH_INF_ENGINE` and `WITH_NGRAPH`. |
|
||||
| `OPENCV_DNN_CUDA` | _OFF_ | Enable CUDA backend. [CUDA](https://en.wikipedia.org/wiki/CUDA), CUBLAS and [CUDNN](https://developer.nvidia.com/cudnn) must be installed. |
|
||||
| `WITH_HALIDE` | _OFF_ | Use experimental [Halide](https://en.wikipedia.org/wiki/Halide_(programming_language)) backend which can generate optimized code for dnn-layers at runtime. Halide must be installed. |
|
||||
| `WITH_VULKAN` | _OFF_ | Enable experimental [Vulkan](https://en.wikipedia.org/wiki/Vulkan_(API)) backend. Does not require additional dependencies, but can use external Vulkan headers (`VULKAN_INCLUDE_DIRS`). |
|
||||
|
||||
|
||||
|
@ -168,7 +168,7 @@ ocv_target_link_libraries(${the_module} PRIVATE
|
||||
"${ZLIB_LIBRARIES}" "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}"
|
||||
"${OPENGL_LIBRARIES}"
|
||||
"${GLX_LIBRARIES}"
|
||||
"${LAPACK_LIBRARIES}" "${CPUFEATURES_LIBRARIES}" "${HALIDE_LIBRARIES}"
|
||||
"${LAPACK_LIBRARIES}" "${CPUFEATURES_LIBRARIES}"
|
||||
"${ITT_LIBRARIES}"
|
||||
"${OPENCV_HAL_LINKER_LIBS}"
|
||||
)
|
||||
|
@ -71,9 +71,8 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
{
|
||||
//! DNN_BACKEND_DEFAULT equals to OPENCV_DNN_BACKEND_DEFAULT, which can be defined using CMake or a configuration parameter
|
||||
DNN_BACKEND_DEFAULT = 0,
|
||||
DNN_BACKEND_HALIDE,
|
||||
DNN_BACKEND_INFERENCE_ENGINE, //!< Intel OpenVINO computational backend
|
||||
//!< @note Tutorial how to build OpenCV with OpenVINO: @ref tutorial_dnn_openvino
|
||||
DNN_BACKEND_INFERENCE_ENGINE = 2, //!< Intel OpenVINO computational backend
|
||||
//!< @note Tutorial how to build OpenCV with OpenVINO: @ref tutorial_dnn_openvino
|
||||
DNN_BACKEND_OPENCV,
|
||||
DNN_BACKEND_VKCOM,
|
||||
DNN_BACKEND_CUDA,
|
||||
@ -314,18 +313,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
*/
|
||||
virtual bool supportBackend(int backendId); // FIXIT const
|
||||
|
||||
/**
|
||||
* @brief Returns Halide backend node.
|
||||
* @param[in] inputs Input Halide buffers.
|
||||
* @see BackendNode, BackendWrapper
|
||||
*
|
||||
* Input buffers should be exactly the same that will be used in forward invocations.
|
||||
* Despite we can use Halide::ImageParam based on input shape only,
|
||||
* it helps prevent some memory management issues (if something wrong,
|
||||
* Halide tests will be failed).
|
||||
*/
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs);
|
||||
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> > &inputs, const std::vector<Ptr<BackendNode> >& nodes);
|
||||
|
||||
virtual Ptr<BackendNode> initVkCom(const std::vector<Ptr<BackendWrapper> > &inputs, std::vector<Ptr<BackendWrapper> > &outputs);
|
||||
@ -369,33 +356,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes);
|
||||
|
||||
/**
|
||||
* @brief Automatic Halide scheduling based on layer hyper-parameters.
|
||||
* @param[in] node Backend node with Halide functions.
|
||||
* @param[in] inputs Blobs that will be used in forward invocations.
|
||||
* @param[in] outputs Blobs that will be used in forward invocations.
|
||||
* @param[in] targetId Target identifier
|
||||
* @see BackendNode, Target
|
||||
*
|
||||
* Layer don't use own Halide::Func members because we can have applied
|
||||
* layers fusing. In this way the fused function should be scheduled.
|
||||
*/
|
||||
virtual void applyHalideScheduler(Ptr<BackendNode>& node,
|
||||
const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs,
|
||||
int targetId) const;
|
||||
|
||||
/**
|
||||
* @brief Implement layers fusing.
|
||||
* @param[in] node Backend node of bottom layer.
|
||||
* @see BackendNode
|
||||
*
|
||||
* Actual for graph-based backends. If layer attached successfully,
|
||||
* returns non-empty cv::Ptr to node of the same backend.
|
||||
* Fuse only over the last function.
|
||||
*/
|
||||
virtual Ptr<BackendNode> tryAttach(const Ptr<BackendNode>& node);
|
||||
|
||||
/**
|
||||
* @brief Tries to attach to the layer the subsequent activation layer, i.e. do the layer fusion in a partial case.
|
||||
* @param[in] layer The subsequent activation layer.
|
||||
@ -671,17 +631,6 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
*/
|
||||
CV_WRAP void getOutputDetails(CV_OUT std::vector<float>& scales, CV_OUT std::vector<int>& zeropoints) const;
|
||||
|
||||
/**
|
||||
* @brief Compile Halide layers.
|
||||
* @param[in] scheduler Path to YAML file with scheduling directives.
|
||||
* @see setPreferableBackend
|
||||
*
|
||||
* Schedule layers that support Halide backend. Then compile them for
|
||||
* specific target. For layers that not represented in scheduling file
|
||||
* or if no manual scheduling used at all, automatic scheduling will be applied.
|
||||
*/
|
||||
CV_WRAP void setHalideScheduler(const String& scheduler);
|
||||
|
||||
/**
|
||||
* @brief Ask network to use specific computation backend where it supported.
|
||||
* @param[in] backendId backend identifier.
|
||||
@ -695,16 +644,16 @@ CV__DNN_INLINE_NS_BEGIN
|
||||
* @see Target
|
||||
*
|
||||
* List of supported combinations backend / target:
|
||||
* | | DNN_BACKEND_OPENCV | DNN_BACKEND_INFERENCE_ENGINE | DNN_BACKEND_HALIDE | DNN_BACKEND_CUDA |
|
||||
* |------------------------|--------------------|------------------------------|--------------------|-------------------|
|
||||
* | DNN_TARGET_CPU | + | + | + | |
|
||||
* | DNN_TARGET_OPENCL | + | + | + | |
|
||||
* | DNN_TARGET_OPENCL_FP16 | + | + | | |
|
||||
* | DNN_TARGET_MYRIAD | | + | | |
|
||||
* | DNN_TARGET_FPGA | | + | | |
|
||||
* | DNN_TARGET_CUDA | | | | + |
|
||||
* | DNN_TARGET_CUDA_FP16 | | | | + |
|
||||
* | DNN_TARGET_HDDL | | + | | |
|
||||
* | | DNN_BACKEND_OPENCV | DNN_BACKEND_INFERENCE_ENGINE | DNN_BACKEND_CUDA |
|
||||
* |------------------------|--------------------|------------------------------|-------------------|
|
||||
* | DNN_TARGET_CPU | + | + | |
|
||||
* | DNN_TARGET_OPENCL | + | + | |
|
||||
* | DNN_TARGET_OPENCL_FP16 | + | + | |
|
||||
* | DNN_TARGET_MYRIAD | | + | |
|
||||
* | DNN_TARGET_FPGA | | + | |
|
||||
* | DNN_TARGET_CUDA | | | + |
|
||||
* | DNN_TARGET_CUDA_FP16 | | | + |
|
||||
* | DNN_TARGET_HDDL | | + | |
|
||||
*/
|
||||
CV_WRAP void setPreferableTarget(int targetId);
|
||||
|
||||
|
@ -10,8 +10,6 @@
|
||||
// because whole output includes Caffe's logs.
|
||||
//
|
||||
// Note: Be sure that interesting version of Caffe was linked.
|
||||
// Note: There is an impact on Halide performance. Comment this tests if you
|
||||
// want to run the last one.
|
||||
//
|
||||
// How to build Intel-Caffe with MKLDNN backend
|
||||
// ============================================
|
||||
|
@ -889,7 +889,7 @@ PERF_TEST_P_(Conv, conv)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Conv, Combine(
|
||||
ConvParamID::all(),
|
||||
dnnBackendsAndTargets(false, false) // defined in ../test/test_common.hpp
|
||||
dnnBackendsAndTargets(/* withInferenceEngine = */false, /* obsolete_withHalide = */false) // defined in ../test/test_common.hpp
|
||||
));
|
||||
|
||||
} // namespace
|
||||
|
@ -157,7 +157,7 @@ PERF_TEST_P_(Conv1D, conv1d)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Conv1D, Combine(
|
||||
Conv1DParamID::all(),
|
||||
dnnBackendsAndTargets(false, false) // defined in ../test/test_common.hpp
|
||||
dnnBackendsAndTargets(/* withInferenceEngine = */false, /* obsolete_withHalide = */false) // defined in ../test/test_common.hpp
|
||||
));
|
||||
|
||||
} // namespace
|
||||
|
@ -176,7 +176,7 @@ PERF_TEST_P_(Conv3D, conv3d)
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Conv3D, Combine(
|
||||
Conv3DParamID::all(),
|
||||
dnnBackendsAndTargets(false, false) // defined in ../test/test_common.hpp
|
||||
dnnBackendsAndTargets(/* withInferenceEngine = */false, /* obsolete_withHalide = */false) // defined in ../test/test_common.hpp
|
||||
));
|
||||
|
||||
} // namespace
|
||||
|
@ -633,7 +633,7 @@ PERF_TEST_P_(Layer_LayerNormExpanded, DISABLED_LayerNormExpanded)
|
||||
test_layer({N, H ,W});
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_Slice, dnnBackendsAndTargets(false, false));
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_Slice, dnnBackendsAndTargets(/* withInferenceEngine = */false, /* obsolete_withHalide = */false));
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_NaryEltwise, testing::Values(std::make_tuple(DNN_BACKEND_OPENCV, DNN_TARGET_CPU)));
|
||||
#ifdef HAVE_CUDA
|
||||
INSTANTIATE_TEST_CASE_P(CUDA, Layer_NaryEltwise, testing::Values(std::make_tuple(DNN_BACKEND_CUDA, DNN_TARGET_CUDA)));
|
||||
|
@ -28,29 +28,17 @@ public:
|
||||
target = (dnn::Target)(int)get<1>(GetParam());
|
||||
}
|
||||
|
||||
void processNet(std::string weights, std::string proto, std::string halide_scheduler,
|
||||
const Mat& input, const std::string& outputLayer = "")
|
||||
void processNet(std::string weights, std::string proto, const Mat& input, const std::string& outputLayer = "")
|
||||
{
|
||||
randu(input, 0.0f, 1.0f);
|
||||
|
||||
weights = findDataFile(weights, false);
|
||||
if (!proto.empty())
|
||||
proto = findDataFile(proto);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
if (halide_scheduler == "disabled")
|
||||
throw cvtest::SkipTestException("Halide test is disabled");
|
||||
if (!halide_scheduler.empty())
|
||||
halide_scheduler = findDataFile(std::string("dnn/halide_scheduler_") + (target == DNN_TARGET_OPENCL ? "opencl_" : "") + halide_scheduler, true);
|
||||
}
|
||||
net = readNet(proto, weights);
|
||||
net.setInput(blobFromImage(input, 1.0, Size(), Scalar(), false));
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
net.setHalideScheduler(halide_scheduler);
|
||||
}
|
||||
|
||||
MatShape netInputShape = shape(1, 3, input.rows, input.cols);
|
||||
size_t weightsMemory = 0, blobsMemory = 0;
|
||||
@ -76,34 +64,28 @@ public:
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, AlexNet)
|
||||
{
|
||||
processNet("dnn/bvlc_alexnet.caffemodel", "dnn/bvlc_alexnet.prototxt",
|
||||
"alexnet.yml", Mat(cv::Size(227, 227), CV_32FC3));
|
||||
processNet("dnn/bvlc_alexnet.caffemodel", "dnn/bvlc_alexnet.prototxt", Mat(cv::Size(227, 227), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, GoogLeNet)
|
||||
{
|
||||
processNet("dnn/bvlc_googlenet.caffemodel", "dnn/bvlc_googlenet.prototxt",
|
||||
"", Mat(cv::Size(224, 224), CV_32FC3));
|
||||
processNet("dnn/bvlc_googlenet.caffemodel", "dnn/bvlc_googlenet.prototxt", Mat(cv::Size(224, 224), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, ResNet_50)
|
||||
{
|
||||
processNet("dnn/ResNet-50-model.caffemodel", "dnn/ResNet-50-deploy.prototxt",
|
||||
"resnet_50.yml", Mat(cv::Size(224, 224), CV_32FC3));
|
||||
processNet("dnn/ResNet-50-model.caffemodel", "dnn/ResNet-50-deploy.prototxt", Mat(cv::Size(224, 224), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, SqueezeNet_v1_1)
|
||||
{
|
||||
processNet("dnn/squeezenet_v1.1.caffemodel", "dnn/squeezenet_v1.1.prototxt",
|
||||
"squeezenet_v1_1.yml", Mat(cv::Size(227, 227), CV_32FC3));
|
||||
processNet("dnn/squeezenet_v1.1.caffemodel", "dnn/squeezenet_v1.1.prototxt", Mat(cv::Size(227, 227), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, Inception_5h)
|
||||
{
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019) throw SkipTestException("");
|
||||
processNet("dnn/tensorflow_inception_graph.pb", "",
|
||||
"inception_5h.yml",
|
||||
Mat(cv::Size(224, 224), CV_32FC3), "softmax2");
|
||||
processNet("dnn/tensorflow_inception_graph.pb", "", Mat(cv::Size(224, 224), CV_32FC3), "softmax2");
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, ENet)
|
||||
@ -115,92 +97,65 @@ PERF_TEST_P_(DNNTestNetwork, ENet)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
throw SkipTestException("");
|
||||
#endif
|
||||
processNet("dnn/Enet-model-best.net", "", "enet.yml",
|
||||
Mat(cv::Size(512, 256), CV_32FC3));
|
||||
processNet("dnn/Enet-model-best.net", "", Mat(cv::Size(512, 256), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, SSD)
|
||||
{
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", "dnn/ssd_vgg16.prototxt", "disabled",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel", "dnn/ssd_vgg16.prototxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, OpenFace)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_HDDL))
|
||||
throw SkipTestException("");
|
||||
#endif
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", "",
|
||||
Mat(cv::Size(96, 96), CV_32FC3));
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Mat(cv::Size(96, 96), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_Caffe)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt", "",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "ssd_mobilenet_v1_coco_2017_11_17.pbtxt", "",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "ssd_mobilenet_v1_coco_2017_11_17.pbtxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "ssd_mobilenet_v2_coco_2018_03_29.pbtxt", "",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "ssd_mobilenet_v2_coco_2018_03_29.pbtxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", "",
|
||||
Mat(cv::Size(224, 224), CV_32FC3));
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Mat(cv::Size(224, 224), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_HDDL)))
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_HDDL))
|
||||
throw SkipTestException("");
|
||||
// The same .caffemodel but modified .prototxt
|
||||
// See https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/src/openpose/pose/poseParameters.cpp
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi_faster_4_stages.prototxt", "",
|
||||
Mat(cv::Size(368, 368), CV_32FC3));
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi_faster_4_stages.prototxt", Mat(cv::Size(368, 368), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, opencv_face_detector)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/opencv_face_detector.caffemodel", "dnn/opencv_face_detector.prototxt", "",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/opencv_face_detector.caffemodel", "dnn/opencv_face_detector.prototxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "ssd_inception_v2_coco_2017_11_17.pbtxt", "",
|
||||
Mat(cv::Size(300, 300), CV_32FC3));
|
||||
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "ssd_inception_v2_coco_2017_11_17.pbtxt", Mat(cv::Size(300, 300), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_2GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2020.4");
|
||||
@ -216,14 +171,12 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv3)
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
|
||||
processNet("dnn/yolov3.weights", "dnn/yolov3.cfg", "", inp);
|
||||
processNet("dnn/yolov3.weights", "dnn/yolov3.cfg", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_2GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
if (target == DNN_TARGET_MYRIAD) // not enough resources
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2020040000) // nGraph compilation failure
|
||||
@ -236,13 +189,11 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
|
||||
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", "", inp);
|
||||
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2021010000) // nGraph compilation failure
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("");
|
||||
@ -251,21 +202,17 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
|
||||
cvtColor(sample, sample, COLOR_BGR2RGB);
|
||||
Mat inp;
|
||||
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
|
||||
processNet("dnn/yolov4-tiny-2020-12.weights", "dnn/yolov4-tiny-2020-12.cfg", "", inp);
|
||||
processNet("dnn/yolov4-tiny-2020-12.weights", "dnn/yolov4-tiny-2020-12.cfg", inp);
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/frozen_east_text_detection.pb", "", "", Mat(cv::Size(320, 320), CV_32FC3));
|
||||
processNet("dnn/frozen_east_text_detection.pb", "", Mat(cv::Size(320, 320), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", "", Mat(cv::Size(320, 240), CV_32FC3));
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", Mat(cv::Size(320, 240), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)
|
||||
@ -282,24 +229,22 @@ PERF_TEST_P_(DNNTestNetwork, Inception_v2_Faster_RCNN)
|
||||
if (target == DNN_TARGET_MYRIAD)
|
||||
throw SkipTestException("Test is disabled in OpenVINO 2021.1+ / MYRIAD");
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE ||
|
||||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU) ||
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target != DNN_TARGET_CPU) ||
|
||||
(backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16))
|
||||
throw SkipTestException("");
|
||||
processNet("dnn/faster_rcnn_inception_v2_coco_2018_01_28.pb",
|
||||
"dnn/faster_rcnn_inception_v2_coco_2018_01_28.pbtxt", "",
|
||||
Mat(cv::Size(800, 600), CV_32FC3));
|
||||
"dnn/faster_rcnn_inception_v2_coco_2018_01_28.pbtxt", Mat(cv::Size(800, 600), CV_32FC3));
|
||||
}
|
||||
|
||||
PERF_TEST_P_(DNNTestNetwork, EfficientDet)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE || target != DNN_TARGET_CPU)
|
||||
if (target != DNN_TARGET_CPU)
|
||||
throw SkipTestException("");
|
||||
Mat sample = imread(findDataFile("dnn/dog416.png"));
|
||||
resize(sample, sample, Size(512, 512));
|
||||
Mat inp;
|
||||
sample.convertTo(inp, CV_32FC3, 1.0/255);
|
||||
processNet("dnn/efficientdet-d0.pb", "dnn/efficientdet-d0.pbtxt", "", inp);
|
||||
processNet("dnn/efficientdet-d0.pb", "dnn/efficientdet-d0.pbtxt", inp);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets());
|
||||
|
@ -1,301 +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.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "halide_scheduler.hpp"
|
||||
#include "op_halide.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
{
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
static void applySplit(const FileNode& directive, Halide::Func& func,
|
||||
const FileNode& params)
|
||||
{
|
||||
for (const auto& varNode : directive)
|
||||
{
|
||||
const std::string varName = varNode.name();
|
||||
const std::string factorName = (std::string)varNode;
|
||||
Halide::Var var(varName);
|
||||
Halide::Var outerVar(varName + "o");
|
||||
Halide::Var innerVar(varName + "i");
|
||||
// If split factor is integer or parameters map has parameter value.
|
||||
CV_Assert(varNode.isString() && !params[factorName].empty() ||
|
||||
varNode.isInt());
|
||||
int factor = (int)(varNode.isInt() ? varNode : params[factorName]);
|
||||
func.split(var, outerVar, innerVar, factor);
|
||||
}
|
||||
}
|
||||
|
||||
static void applyReorder(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
std::string varName;
|
||||
const int numVars = directive.size();
|
||||
std::vector<Halide::VarOrRVar> reorderedVars;
|
||||
reorderedVars.reserve(numVars);
|
||||
for (int i = 0; i < numVars; ++i)
|
||||
{
|
||||
directive[i] >> varName;
|
||||
reorderedVars.push_back(Halide::Var(varName));
|
||||
}
|
||||
func.reorder(reorderedVars);
|
||||
}
|
||||
|
||||
static void applyFuse(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
CV_Assert(directive["src"].size() >= 2);
|
||||
CV_Assert(directive["dst"].size() == 1);
|
||||
|
||||
std::string str;
|
||||
directive["src"][0] >> str;
|
||||
Halide::Var firstVar(str);
|
||||
directive["src"][1] >> str;
|
||||
Halide::Var secondVar(str);
|
||||
directive["dst"] >> str;
|
||||
Halide::Var dstVar(str);
|
||||
|
||||
func.fuse(firstVar, secondVar, dstVar);
|
||||
for (int i = 2, n = directive["src"].size(); i < n; ++i)
|
||||
{
|
||||
directive["src"][i] >> str;
|
||||
func.fuse(Halide::Var(str), dstVar, dstVar);
|
||||
}
|
||||
}
|
||||
|
||||
static void applyParallel(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
std::string varName;
|
||||
if (directive.isSeq())
|
||||
{
|
||||
for (int i = 0, n = directive.size(); i < n; ++i)
|
||||
{
|
||||
directive[i] >> varName;
|
||||
func.parallel(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
directive >> varName;
|
||||
func.parallel(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
|
||||
static void applyUnroll(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
std::string varName;
|
||||
if (directive.isSeq())
|
||||
{
|
||||
for (int i = 0, n = directive.size(); i < n; ++i)
|
||||
{
|
||||
directive[i] >> varName;
|
||||
func.unroll(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
directive >> varName;
|
||||
func.unroll(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
|
||||
static void applyVectorize(const FileNode& directive, Halide::Func& func,
|
||||
const FileNode& params)
|
||||
{
|
||||
for (const auto& varNode : directive)
|
||||
{
|
||||
const std::string varName = varNode.name();
|
||||
const std::string factorName = (std::string)varNode;
|
||||
// If split factor is integer or parameters map has parameter value.
|
||||
CV_Assert(varNode.isString() && !params[factorName].empty() ||
|
||||
varNode.isInt());
|
||||
int factor = (int)(varNode.isInt() ? varNode : params[factorName]);
|
||||
Halide::Var var(varName);
|
||||
Halide::Var inner(varName + "v");
|
||||
func.split(var, var, inner, factor);
|
||||
func.vectorize(inner);
|
||||
}
|
||||
}
|
||||
|
||||
static void applyStoreAt(const FileNode& directive, Halide::Func& func,
|
||||
std::map<std::string, Halide::Func>& funcsMap)
|
||||
{
|
||||
for (const auto& funcNode : directive)
|
||||
{
|
||||
const std::string targetFuncName = funcNode.name();
|
||||
if (funcsMap.find(targetFuncName) == funcsMap.end())
|
||||
CV_Error(cv::Error::StsParseError, "Function " + targetFuncName +
|
||||
" is not represented in Halide pipeline");
|
||||
Halide::Func targetFunc = funcsMap[targetFuncName];
|
||||
func.store_at(targetFunc, (std::string)funcNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void applyComputeAt(const FileNode& directive, Halide::Func& func,
|
||||
std::map<std::string, Halide::Func>& funcsMap)
|
||||
{
|
||||
for (const auto& funcNode : directive)
|
||||
{
|
||||
const std::string targetFuncName = funcNode.name();
|
||||
if (funcsMap.find(targetFuncName) == funcsMap.end())
|
||||
CV_Error(cv::Error::StsParseError, "Function " + targetFuncName +
|
||||
" is not represented in Halide pipeline");
|
||||
Halide::Func targetFunc = funcsMap[targetFuncName];
|
||||
func.compute_at(targetFunc, (std::string)funcNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void applyComputeRoot(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
bool compute_root;
|
||||
directive >> compute_root;
|
||||
if (compute_root)
|
||||
func.compute_root();
|
||||
}
|
||||
|
||||
static void applyGpuBlocks(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
std::string varName;
|
||||
for (int i = 0, n = directive.size(); i < n; ++i)
|
||||
{
|
||||
directive[i] >> varName;
|
||||
func.gpu_blocks(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
|
||||
static void applyGpuThreads(const FileNode& directive, Halide::Func& func)
|
||||
{
|
||||
std::string varName;
|
||||
for (int i = 0, n = directive.size(); i < n; ++i)
|
||||
{
|
||||
directive[i] >> varName;
|
||||
func.gpu_threads(Halide::Var(varName));
|
||||
}
|
||||
}
|
||||
|
||||
static void apply(const FileNode& directives, Halide::Func& func,
|
||||
std::map<std::string, Halide::Func>& funcsMap,
|
||||
const FileNode& params)
|
||||
{
|
||||
for (const auto& directive : directives)
|
||||
{
|
||||
if (directive.name() == "split")
|
||||
applySplit(directive, func, params);
|
||||
else if (directive.name() == "reorder")
|
||||
applyReorder(directive, func);
|
||||
else if (directive.name() == "fuse")
|
||||
applyFuse(directive, func);
|
||||
else if (directive.name() == "parallel")
|
||||
applyParallel(directive, func);
|
||||
else if (directive.name() == "unroll")
|
||||
applyUnroll(directive, func);
|
||||
else if (directive.name() == "vectorize")
|
||||
applyVectorize(directive, func, params);
|
||||
else if (directive.name() == "store_at")
|
||||
applyStoreAt(directive, func, funcsMap);
|
||||
else if (directive.name() == "compute_at")
|
||||
applyComputeAt(directive, func, funcsMap);
|
||||
else if (directive.name() == "compute_root")
|
||||
applyComputeRoot(directive, func);
|
||||
else if (directive.name() == "gpu_blocks")
|
||||
applyGpuBlocks(directive, func);
|
||||
else if (directive.name() == "gpu_threads")
|
||||
applyGpuThreads(directive, func);
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Scheduling directive " +
|
||||
directive.name() + " is not implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any numeric symbols after '$' sign.
|
||||
static std::string Deunique(std::string str)
|
||||
{
|
||||
int pos = -1;
|
||||
do
|
||||
{
|
||||
pos = str.find('$');
|
||||
if (pos != -1)
|
||||
{
|
||||
int len = str.find_first_not_of("0123456789", pos + 1) - pos;
|
||||
str = str.replace(pos, len, "");
|
||||
}
|
||||
}
|
||||
while (pos != -1);
|
||||
return str;
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
HalideScheduler::HalideScheduler(const std::string& configFile)
|
||||
{
|
||||
if (!configFile.empty())
|
||||
fs = FileStorage(configFile, FileStorage::READ);
|
||||
}
|
||||
|
||||
HalideScheduler::~HalideScheduler()
|
||||
{
|
||||
if (fs.isOpened())
|
||||
fs.release();
|
||||
}
|
||||
|
||||
bool HalideScheduler::process(Ptr<BackendNode>& node)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
if (!fs.isOpened())
|
||||
return false;
|
||||
|
||||
const FileNode& scheduleNode = fs["scheduling"];
|
||||
if (scheduleNode.empty())
|
||||
CV_Error(cv::Error::StsParseError, "Scheduling file should has scheduling node");
|
||||
|
||||
std::string str;
|
||||
std::map<std::string, Halide::Func> funcsMap; // Scheduled functions.
|
||||
// For every function, from top to bottom, we try to find a scheduling node.
|
||||
// Scheduling is successful (return true) if for the first function (top)
|
||||
// node is represented.
|
||||
CV_Assert(!node.empty());
|
||||
std::vector<Halide::Func>& funcs = node.dynamicCast<HalideBackendNode>()->funcs;
|
||||
for (int i = funcs.size() - 1; i >= 0; --i)
|
||||
{
|
||||
Halide::Func& func = funcs[i];
|
||||
// For functions with the same name Halide generates unique names
|
||||
// for example func, func$1, func$2.
|
||||
// They are always formed with '$' and number.
|
||||
std::string funcName = Deunique(func.name());
|
||||
|
||||
const FileNode& funcNode = scheduleNode[funcName];
|
||||
if (!funcNode.empty())
|
||||
{
|
||||
if (!funcNode["pattern"].empty())
|
||||
{
|
||||
funcNode["pattern"] >> str;
|
||||
if (fs["patterns"][str].empty())
|
||||
CV_Error(cv::Error::StsParseError, "Scheduling pattern " + str +
|
||||
" is not defined");
|
||||
apply(fs["patterns"][str], func, funcsMap, funcNode["params"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
apply(funcNode, func, funcsMap, funcNode["params"]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (funcsMap.empty())
|
||||
return false;
|
||||
}
|
||||
funcsMap[funcName] = func;
|
||||
}
|
||||
return true;
|
||||
#endif // HAVE_HALIDE
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace cv
|
@ -1,37 +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.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#ifndef __OPENCV_DNN_HALIDE_SCHEDULER_HPP__
|
||||
#define __OPENCV_DNN_HALIDE_SCHEDULER_HPP__
|
||||
|
||||
#include <opencv2/dnn.hpp>
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
{
|
||||
|
||||
class HalideScheduler
|
||||
{
|
||||
public:
|
||||
HalideScheduler(const std::string& configFile);
|
||||
|
||||
~HalideScheduler();
|
||||
|
||||
// Returns true if pipeline found in scheduling file.
|
||||
// If more than one function, returns true if the top function scheduled.
|
||||
// Other functions are optional to scheduling.
|
||||
bool process(Ptr<BackendNode>& node);
|
||||
|
||||
private:
|
||||
FileStorage fs;
|
||||
};
|
||||
|
||||
} // namespace dnn
|
||||
} // namespace cv
|
||||
|
||||
#endif // __OPENCV_DNN_HALIDE_SCHEDULER_HPP__
|
@ -57,12 +57,6 @@ Ptr<BackendNode> Layer::initVkCom(const std::vector<Ptr<BackendWrapper> > &input
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
Ptr<BackendNode> Layer::initHalide(const std::vector<Ptr<BackendWrapper>>&)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "Halide pipeline of " + type + " layers is not defined.");
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
Ptr<BackendNode> Layer::initNgraph(const std::vector<Ptr<BackendWrapper>>& inputs, const std::vector<Ptr<BackendNode>>& nodes)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "Inference Engine pipeline of " + type + " layers is not defined.");
|
||||
@ -93,11 +87,6 @@ Ptr<BackendNode> Layer::initCann(const std::vector<Ptr<BackendWrapper> > &inputs
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
Ptr<BackendNode> Layer::tryAttach(const Ptr<BackendNode>& node)
|
||||
{
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
bool Layer::setActivation(const Ptr<ActivationLayer>&) { return false; }
|
||||
bool Layer::tryFuse(Ptr<Layer>&) { return false; }
|
||||
void Layer::getScaleShift(Mat& scale, Mat& shift) const
|
||||
|
@ -12,7 +12,6 @@ Implementation of Batch Normalization layer.
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_webnn.hpp"
|
||||
@ -181,7 +180,6 @@ public:
|
||||
#endif
|
||||
return (backendId == DNN_BACKEND_OPENCV) ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide()) ||
|
||||
backendId == DNN_BACKEND_WEBNN ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
@ -345,52 +343,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> tryAttach(const Ptr<BackendNode>& node) CV_OVERRIDE
|
||||
{
|
||||
switch (node->backendId)
|
||||
{
|
||||
case DNN_BACKEND_HALIDE:
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
auto base = node.dynamicCast<HalideBackendNode>();
|
||||
Halide::Func& input = base->funcs.back();
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = attachHalide(input(x, y, c, n));
|
||||
return Ptr<BackendNode>(new HalideBackendNode(base, top));
|
||||
#endif // HAVE_HALIDE
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> input = halideBuffer(inputs[0]);
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = attachHalide(input(x, y, c, n));
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
// attachHalide can work both with Halide::Buffer and Halide::Func. In the
|
||||
// second case it will be a fusion.
|
||||
Halide::Func attachHalide(const Halide::Expr& input)
|
||||
{
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
|
||||
const int numChannels = weights_.total();
|
||||
auto weights = wrapToHalideBuffer(weights_, {numChannels});
|
||||
auto bias = wrapToHalideBuffer(bias_, {numChannels});
|
||||
top(x, y, c, n) = input * weights(c) + bias(c);
|
||||
return top;
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_vkcom.hpp"
|
||||
@ -139,7 +138,6 @@ public:
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 && !padding) || // By channels
|
||||
(backendId == DNN_BACKEND_WEBNN && !padding) ||
|
||||
(backendId == DNN_BACKEND_CANN && !padding);
|
||||
}
|
||||
@ -331,29 +329,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &input) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
std::vector<Halide::Buffer<> > inputBuffers = halideBuffers(input);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
int offset = inputBuffers[0].channels();
|
||||
Halide::Expr topExpr = select(c < offset,
|
||||
inputBuffers[0](x, y, c, n),
|
||||
inputBuffers[1](x, y, c - offset, n));
|
||||
for (int i = 2; i < input.size(); ++i)
|
||||
{
|
||||
offset += inputBuffers[i - 1].channels();
|
||||
topExpr = select(c < offset, topExpr,
|
||||
inputBuffers[i](x, y, c - offset, n));
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_vkcom.hpp"
|
||||
@ -199,46 +198,6 @@ public:
|
||||
}
|
||||
|
||||
virtual void fuseWeights(const Mat& w_, const Mat& b_) = 0;
|
||||
|
||||
virtual void applyHalideScheduler(Ptr<BackendNode>& node,
|
||||
const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs,
|
||||
int targetId) const CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
if (targetId != DNN_TARGET_CPU)
|
||||
{
|
||||
Layer::applyHalideScheduler(node, inputs, outputs, targetId);
|
||||
return;
|
||||
}
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n"), tile("tile"), yi("yi"), yo("yo"), co("co"), ci("ci");
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs[1];
|
||||
Halide::Func& padded_input = node.dynamicCast<HalideBackendNode>()->funcs[0];
|
||||
|
||||
int outW, outH, outC, outN;
|
||||
getCanonicalSize(outputs[0].size, &outW, &outH, &outC, &outN);
|
||||
|
||||
if (outW == 1 || outH <= 2)
|
||||
return;
|
||||
|
||||
if (is1x1() || outC <= 16)
|
||||
top.reorder(x, c, y)
|
||||
.split(y, yo, yi, 2)
|
||||
.fuse(yo, n, tile)
|
||||
.parallel(tile)
|
||||
.unroll(yi)
|
||||
.vectorize(x, outW >= 16 ? 16 : outW);
|
||||
else
|
||||
top.reorder(x, c, y)
|
||||
.split(y, yo, yi, 2)
|
||||
.split(c, co, ci, 16)
|
||||
.fuse(yo, co, tile).fuse(n, tile, tile)
|
||||
.parallel(tile)
|
||||
.unroll(yi)
|
||||
.vectorize(x, outW >= 16 ? 16 : outW);
|
||||
padded_input.compute_at(top, yi);
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -329,10 +288,6 @@ public:
|
||||
#endif
|
||||
if (backendId == DNN_BACKEND_OPENCV)
|
||||
return ksize >= 1 && ksize <= 3;
|
||||
#ifdef HAVE_HALIDE
|
||||
if (backendId == DNN_BACKEND_HALIDE)
|
||||
return ksize == 2 && !blobs.empty();
|
||||
#endif
|
||||
#ifdef HAVE_VULKAN
|
||||
if (backendId == DNN_BACKEND_VKCOM)
|
||||
return ksize == 2;
|
||||
@ -684,55 +639,6 @@ public:
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
CV_Assert(!blobs.empty());
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
|
||||
const int inpCn = inputBuffer.channels();
|
||||
const int outCn = blobs[0].size[0];
|
||||
const int inpGroupCn = blobs[0].size[1];
|
||||
const int group = inpCn / inpGroupCn;
|
||||
const int outGroupCn = outCn / group;
|
||||
|
||||
Halide::Buffer<float> weights = wrapToHalideBuffer(blobs[0]);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Func padded_input(name + "_constant_exterior");
|
||||
if (pad.width || pad.height)
|
||||
{
|
||||
Halide::Func bounded =
|
||||
Halide::BoundaryConditions::constant_exterior(inputBuffer, 0);
|
||||
padded_input(x, y, c, n) = bounded(x, y, c, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
padded_input(x, y, c, n) = inputBuffer(x, y, c, n);
|
||||
}
|
||||
|
||||
Halide::RDom r(0, kernel.width, 0, kernel.height, 0, inpGroupCn);
|
||||
Halide::Expr kx = x * stride.width - pad.width + r.x * dilation.width;
|
||||
Halide::Expr ky = y * stride.height - pad.height + r.y * dilation.height;
|
||||
Halide::Expr kc = r.z;
|
||||
for (int i = 1; i < group; ++i)
|
||||
{
|
||||
kc = select(c < outGroupCn * i, kc, inpGroupCn * i + r.z);
|
||||
}
|
||||
Halide::Expr topExpr = sum(padded_input(kx, ky, kc, n) *
|
||||
weights(r.x, r.y, r.z, c));
|
||||
if (hasBias())
|
||||
{
|
||||
Halide::Buffer<float> bias = wrapToHalideBuffer(blobs[1], {outCn});
|
||||
topExpr += bias(c);
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return Ptr<BackendNode>(new HalideBackendNode({ padded_input, top }));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
@ -1506,7 +1412,7 @@ public:
|
||||
#endif // HAVE_INF_ENGINE
|
||||
{
|
||||
return backendId == DNN_BACKEND_CUDA ||
|
||||
(kernel_size.size() == 2 && (backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE)) ||
|
||||
(kernel_size.size() == 2 && backendId == DNN_BACKEND_OPENCV) ||
|
||||
(kernel_size.size() == 2 && backendId == DNN_BACKEND_CANN);
|
||||
}
|
||||
}
|
||||
@ -2114,60 +2020,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
CV_Assert(!blobs.empty());
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
|
||||
int inW, inH, inC, inN;
|
||||
getCanonicalSize(inputBuffer, &inW, &inH, &inC, &inN);
|
||||
const int outGroupCn = blobs[0].size[1];
|
||||
const int group = numOutput / outGroupCn;
|
||||
const int inpGroupCn = blobs[0].size[0] / group;
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Func padded_input(name + "_constant_exterior");
|
||||
auto weights = wrapToHalideBuffer(blobs[0]);
|
||||
|
||||
Halide::Func dilated_input("dilated_input");
|
||||
dilated_input(x, y, c, n) = 0.0f;
|
||||
Halide::RDom r1(0, inW, 0, inH);
|
||||
dilated_input(r1.x * stride.width, r1.y * stride.height, c, n) =
|
||||
inputBuffer(r1.x, r1.y, c, n);
|
||||
dilated_input.compute_root();
|
||||
|
||||
Halide::Func bounded =
|
||||
Halide::BoundaryConditions::constant_exterior(dilated_input, 0,
|
||||
0, (inW - 1) * stride.width + 1,
|
||||
0, (inH - 1) * stride.height + 1,
|
||||
0, inC, 0, inN);
|
||||
padded_input(x, y, c, n) = bounded(x, y, c, n);
|
||||
|
||||
Halide::RDom r(0, kernel.width, 0, kernel.height, 0, inpGroupCn);
|
||||
Halide::Expr kx = x + pad.width - r.x;
|
||||
Halide::Expr ky = y + pad.height - r.y;
|
||||
Halide::Expr kInC = r.z;
|
||||
Halide::Expr kOutC = c;
|
||||
for (int i = 1; i < group; ++i)
|
||||
{
|
||||
kInC = select(c < outGroupCn * i, kInC, inpGroupCn * i + r.z);
|
||||
kOutC = select(c < outGroupCn * i, kOutC, c - outGroupCn * i);
|
||||
}
|
||||
Halide::Expr topExpr = sum(padded_input(kx, ky, kInC, n) *
|
||||
weights(r.x, r.y, kOutC, kInC));
|
||||
if (hasBias())
|
||||
{
|
||||
auto bias = wrapToHalideBuffer(blobs[1], {numOutput});
|
||||
topExpr += bias(c);
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return Ptr<BackendNode>(new HalideBackendNode({ padded_input, top }));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_vkcom.hpp"
|
||||
@ -155,38 +154,6 @@ public:
|
||||
func.finalize();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> tryAttach(const Ptr<BackendNode>& node) CV_OVERRIDE
|
||||
{
|
||||
switch (node->backendId)
|
||||
{
|
||||
case DNN_BACKEND_HALIDE:
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
auto base = node.dynamicCast<HalideBackendNode>();
|
||||
Halide::Func& input = base->funcs.back();
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (this->name.empty() ? Halide::Func() : Halide::Func(this->name));
|
||||
func.attachHalide(input(x, y, c, n), top);
|
||||
return Ptr<BackendNode>(new HalideBackendNode(base, top));
|
||||
#endif // HAVE_HALIDE
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> input = halideBuffer(inputs[0]);
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (this->name.empty() ? Halide::Func() : Halide::Func(this->name));
|
||||
func.attachHalide(input(x, y, c, n), top);
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
@ -351,7 +318,6 @@ struct ReLUFunctor : public BaseFunctor
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -438,21 +404,6 @@ struct ReLUFunctor : public BaseFunctor
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
if (slope)
|
||||
{
|
||||
top(x, y, c, n) = select(input >= 0.0f, input, slope * input);
|
||||
}
|
||||
else
|
||||
{
|
||||
top(x, y, c, n) = max(input, 0.0f);
|
||||
}
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -555,7 +506,6 @@ struct ReLU6Functor : public BaseFunctor
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_WEBNN ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
@ -632,14 +582,6 @@ struct ReLU6Functor : public BaseFunctor
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = clamp(input, minValue, maxValue);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -779,13 +721,6 @@ struct BaseDefaultFunctor : public BaseFunctor
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -883,7 +818,6 @@ struct TanHFunctor : public BaseDefaultFunctor<TanHFunctor>
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -899,14 +833,6 @@ struct TanHFunctor : public BaseDefaultFunctor<TanHFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = tanh(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -949,7 +875,6 @@ struct SwishFunctor : public BaseDefaultFunctor<SwishFunctor>
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
@ -966,14 +891,6 @@ struct SwishFunctor : public BaseDefaultFunctor<SwishFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = input / (1.0f + exp(-input));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -1019,7 +936,6 @@ struct MishFunctor : public BaseDefaultFunctor<MishFunctor>
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
@ -1044,14 +960,6 @@ struct MishFunctor : public BaseDefaultFunctor<MishFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = input * tanh(log(1.0f + exp(input)));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -1104,7 +1012,6 @@ struct SigmoidFunctor : public BaseDefaultFunctor<SigmoidFunctor>
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -1127,14 +1034,6 @@ struct SigmoidFunctor : public BaseDefaultFunctor<SigmoidFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = 1.0f / (1.0f + exp(-input));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -1184,7 +1083,6 @@ struct ELUFunctor : public BaseDefaultFunctor<ELUFunctor>
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -1205,14 +1103,6 @@ struct ELUFunctor : public BaseDefaultFunctor<ELUFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = select(input >= 0.0f, input, alpha * (exp(input) - 1));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -1261,7 +1151,6 @@ struct AbsValFunctor : public BaseDefaultFunctor<AbsValFunctor>
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -1277,14 +1166,6 @@ struct AbsValFunctor : public BaseDefaultFunctor<AbsValFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = abs(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -1330,7 +1211,6 @@ struct BNLLFunctor : public BaseDefaultFunctor<BNLLFunctor>
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -1368,15 +1248,6 @@ struct BNLLFunctor : public BaseDefaultFunctor<BNLLFunctor>
|
||||
}
|
||||
#endif // HAVE_CANN
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
// https://github.com/BVLC/caffe/blame/1.0/src/caffe/layers/bnll_layer.cpp#L17
|
||||
top(x, y, c, n) = max(input, 0) + log(1.0f + exp(-abs(input)));
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 5; }
|
||||
};
|
||||
|
||||
@ -1389,7 +1260,7 @@ struct CeilFunctor : public BaseDefaultFunctor<CeilFunctor>
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -1425,14 +1296,6 @@ struct CeilFunctor : public BaseDefaultFunctor<CeilFunctor>
|
||||
}
|
||||
#endif // HAVE_CANN
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = ceil(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 1; }
|
||||
};
|
||||
|
||||
@ -1447,7 +1310,6 @@ struct FloorFunctor : public BaseDefaultFunctor<FloorFunctor>
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -1484,14 +1346,6 @@ struct FloorFunctor : public BaseDefaultFunctor<FloorFunctor>
|
||||
}
|
||||
#endif // HAVE_CANN
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = floor(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 1; }
|
||||
};
|
||||
|
||||
@ -1504,7 +1358,7 @@ struct LogFunctor : public BaseDefaultFunctor<LogFunctor>
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -1519,14 +1373,6 @@ struct LogFunctor : public BaseDefaultFunctor<LogFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = log(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 1; }
|
||||
};
|
||||
|
||||
@ -1539,7 +1385,7 @@ struct RoundFunctor : public BaseDefaultFunctor<RoundFunctor>
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -1559,14 +1405,6 @@ struct RoundFunctor : public BaseDefaultFunctor<RoundFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = round(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 2; }
|
||||
};
|
||||
|
||||
@ -1579,7 +1417,7 @@ struct SqrtFunctor : public BaseDefaultFunctor<SqrtFunctor>
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -1594,14 +1432,6 @@ struct SqrtFunctor : public BaseDefaultFunctor<SqrtFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = sqrt(input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
std::shared_ptr<ngraph::Node> initNgraphAPI(const ngraph::Output<ngraph::Node>& node)
|
||||
{
|
||||
@ -1621,7 +1451,7 @@ struct NotFunctor : public BaseDefaultFunctor<NotFunctor>
|
||||
|
||||
bool supportBackend(int backendId, int)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -1636,14 +1466,6 @@ struct NotFunctor : public BaseDefaultFunctor<NotFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = floor(1.0f - input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
int64 getFLOPSPerElement() const { return 2; }
|
||||
};
|
||||
|
||||
@ -2224,8 +2046,7 @@ struct PowerFunctor : public BaseFunctor
|
||||
#endif
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE;
|
||||
backendId == DNN_BACKEND_CUDA;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2302,23 +2123,6 @@ struct PowerFunctor : public BaseFunctor
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Expr topExpr = (scale == 1.0f ? input : input * scale);
|
||||
if (shift)
|
||||
{
|
||||
topExpr += shift;
|
||||
}
|
||||
if (power != 1.0f)
|
||||
{
|
||||
topExpr = pow(topExpr, power);
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
@ -2409,7 +2213,7 @@ struct ExpFunctor : public BaseDefaultFunctor<ExpFunctor>
|
||||
bool supportBackend(int backendId, int targetId)
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE || backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH;
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH;
|
||||
}
|
||||
|
||||
inline float calculate(float x) const
|
||||
@ -2430,14 +2234,6 @@ struct ExpFunctor : public BaseDefaultFunctor<ExpFunctor>
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
top(x, y, c, n) = exp(normScale * input + normShift);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
std::shared_ptr<ngraph::Node> initNgraphAPI(const ngraph::Output<ngraph::Node>& node)
|
||||
{
|
||||
@ -2478,7 +2274,6 @@ struct ChannelsPReLUFunctor : public BaseFunctor
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -2561,15 +2356,6 @@ struct ChannelsPReLUFunctor : public BaseFunctor
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
void attachHalide(const Halide::Expr& input, Halide::Func& top)
|
||||
{
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
auto weights = wrapToHalideBuffer(scale, {(int)scale.total()});
|
||||
top(x, y, c, n) = select(input >= 0.0f, input, weights(c) * input);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
Ptr<BackendNode> initCannOp(const std::string& name,
|
||||
const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_cann.hpp"
|
||||
@ -183,9 +182,7 @@ public:
|
||||
return channelsModeInput == ELTWISE_CHANNNELS_SAME;
|
||||
}
|
||||
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
(backendId == DNN_BACKEND_HALIDE && op != DIV) // TODO: not implemented, see PR #15811
|
||||
;
|
||||
return backendId == DNN_BACKEND_OPENCV;
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@ -790,64 +787,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &input) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Expr topExpr;
|
||||
std::vector<Halide::Buffer<> > inputBuffers = halideBuffers(input);
|
||||
switch (op)
|
||||
{
|
||||
case SUM:
|
||||
if (coeffs.empty())
|
||||
{
|
||||
topExpr = inputBuffers[0](x, y, c, n) +
|
||||
inputBuffers[1](x, y, c, n);
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr += inputBuffers[i](x, y, c, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
topExpr = coeffs[0] * inputBuffers[0](x, y, c, n) +
|
||||
coeffs[1] * inputBuffers[1](x, y, c, n);
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr += coeffs[i] * inputBuffers[i](x, y, c, n);
|
||||
}
|
||||
break;
|
||||
case PROD:
|
||||
topExpr = inputBuffers[0](x, y, c, n) *
|
||||
inputBuffers[1](x, y, c, n);
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr *= inputBuffers[i](x, y, c, n);
|
||||
break;
|
||||
case DIV:
|
||||
topExpr = inputBuffers[0](x, y, c, n) /
|
||||
inputBuffers[1](x, y, c, n);
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr /= inputBuffers[i](x, y, c, n);
|
||||
break;
|
||||
case MAX:
|
||||
topExpr = max(inputBuffers[0](x, y, c, n),
|
||||
inputBuffers[1](x, y, c, n));
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr = max(topExpr, inputBuffers[i](x, y, c, n));
|
||||
break;
|
||||
case MIN:
|
||||
topExpr = min(inputBuffers[0](x, y, c, n),
|
||||
inputBuffers[1](x, y, c, n));
|
||||
for (int i = 2; i < inputBuffers.size(); ++i)
|
||||
topExpr = min(topExpr, inputBuffers[i](x, y, c, n));
|
||||
break;
|
||||
default:
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_webnn.hpp"
|
||||
@ -182,7 +181,6 @@ public:
|
||||
bool tranAorB = transA || transB;
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axis == 1 && !tranAorB) ||
|
||||
(backendId == DNN_BACKEND_WEBNN && axis == 1 && !tranAorB) ||
|
||||
backendId == DNN_BACKEND_CANN ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
@ -703,31 +701,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
int inW, inH, inC, inN, outC = blobs[0].size[0];
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
getCanonicalSize(inputBuffer, &inW, &inH, &inC, &inN);
|
||||
auto weights = wrapToHalideBuffer(blobs[0], {inW, inH, inC, outC});
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::RDom r(0, inW, 0, inH, 0, inC);
|
||||
Halide::Expr topExpr = sum(inputBuffer(r.x, r.y, r.z, n) *
|
||||
weights(r.x, r.y, r.z, c));
|
||||
if (bias)
|
||||
{
|
||||
Halide::Buffer<float> bias = wrapToHalideBuffer(blobs[1], {outC});
|
||||
topExpr += bias(c);
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_vkcom.hpp"
|
||||
@ -106,7 +105,6 @@ public:
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -361,79 +359,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
float alphaSize = alpha;
|
||||
if (normBySize)
|
||||
alphaSize /= (type == CHANNEL_NRM ? size : size * size);
|
||||
int width, height, channels, numImgs;
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
getCanonicalSize(inputBuffer, &width, &height, &channels, &numImgs);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Func padded_sq(name + "_padded_sq");
|
||||
Halide::Func sq("sq");
|
||||
sq(x, y, c, n) = inputBuffer(x, y, c, n) * inputBuffer(x, y, c, n);
|
||||
|
||||
Halide::Func bounded =
|
||||
Halide::BoundaryConditions::constant_exterior(sq, 0, 0, width,
|
||||
0, height,
|
||||
0, channels,
|
||||
0, numImgs);
|
||||
padded_sq(x, y, c, n) = bounded(x, y, c, n);
|
||||
|
||||
Halide::Expr base;
|
||||
if (type == CHANNEL_NRM)
|
||||
{
|
||||
Halide::RDom r((1 - size) / 2, size);
|
||||
base = alphaSize * sum(padded_sq(x, y, c + r, n));
|
||||
}
|
||||
else // SPATIAL_NRM
|
||||
{
|
||||
Halide::RDom r((1 - size) / 2, size, (1 - size) / 2, size);
|
||||
base = alphaSize * sum(padded_sq(x + r.x, y + r.y, c, n));
|
||||
}
|
||||
base += static_cast<float>(bias);
|
||||
top(x, y, c, n) = inputBuffer(x, y, c, n) / pow(base, beta);
|
||||
return Ptr<BackendNode>(new HalideBackendNode({ padded_sq, top }));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual void applyHalideScheduler(Ptr<BackendNode>& node,
|
||||
const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs,
|
||||
int targetId) const CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
if (targetId != DNN_TARGET_CPU)
|
||||
{
|
||||
Layer::applyHalideScheduler(node, inputs, outputs, targetId);
|
||||
return;
|
||||
}
|
||||
int outW, outH, outC, outN;
|
||||
getCanonicalSize(outputs[0].size, &outW, &outH, &outC, &outN);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n"), yo("yo"), yi("yi"), tile("tile");
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs[1];
|
||||
Halide::Func& padded_sq = node.dynamicCast<HalideBackendNode>()->funcs[0];
|
||||
|
||||
if (outW < 8 || outH <= 2)
|
||||
return;
|
||||
|
||||
top.reorder(x, c, y, n)
|
||||
.split(y, yo, yi, 2)
|
||||
.fuse(yo, n, tile)
|
||||
.parallel(tile)
|
||||
.unroll(yi)
|
||||
.vectorize(x, 8);
|
||||
padded_sq.store_at(top, tile)
|
||||
.compute_at(top, yi);
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -12,7 +12,6 @@ Implementation of Batch Normalization layer.
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
@ -42,8 +41,7 @@ public:
|
||||
{
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && !poolPad.width && !poolPad.height);
|
||||
backendId == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH;
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@ -156,34 +154,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &input) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
// Meaningless operation if false because if kernel > stride
|
||||
// it is not deterministic and if kernel < stride we just
|
||||
// skip a part of input data (you'd better change your model).
|
||||
if (poolKernel.width != poolStride.width ||
|
||||
poolKernel.height != poolStride.height)
|
||||
CV_Error(cv::Error::StsNotImplemented,
|
||||
"Halide backend for maximum unpooling "
|
||||
"is not support cases when kernel != stride");
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(input[0]);
|
||||
Halide::Buffer<float> indices = halideBuffer(input[1]);
|
||||
|
||||
Halide::Expr pooledX = x / poolKernel.width;
|
||||
Halide::Expr pooledY = y / poolKernel.height;
|
||||
|
||||
const int outW = inputBuffer.width() * poolKernel.width;
|
||||
top(x, y, c, n) = select(y * outW + x == indices(pooledX, pooledY, c, n),
|
||||
inputBuffer(pooledX, pooledY, c, n), 0.0f);
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
|
@ -82,11 +82,6 @@ public:
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
@ -108,19 +103,6 @@ public:
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
}
|
||||
|
||||
virtual void applyHalideScheduler(Ptr<BackendNode>& node,
|
||||
const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs,
|
||||
int targetId) const CV_OVERRIDE
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> tryAttach(const Ptr<BackendNode>& node) CV_OVERRIDE
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
}
|
||||
|
||||
virtual bool setActivation(const Ptr<ActivationLayer>& layer) CV_OVERRIDE
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, msg);
|
||||
|
@ -12,7 +12,6 @@ Implementation of padding layer, which adds paddings to input blob.
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_cann.hpp"
|
||||
@ -114,7 +113,6 @@ public:
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && dstRanges.size() == 4) ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -200,27 +198,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
int inW, inH, inC, inN;
|
||||
int minN = std::max(dstRanges[0].start, 0);
|
||||
int minC = std::max(dstRanges[1].start, 0);
|
||||
int minY = std::max(dstRanges[2].start, 0);
|
||||
int minX = std::max(dstRanges[3].start, 0);
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
getCanonicalSize(inputBuffer, &inW, &inH, &inC, &inN);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Func padded =
|
||||
Halide::BoundaryConditions::constant_exterior(inputBuffer, paddingValue);
|
||||
top(x, y, c, n) = padded(x - minX, y - minY, c - minC, n - minN);
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "layers_common.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../op_webnn.hpp"
|
||||
#include "../op_cann.hpp"
|
||||
@ -73,14 +72,6 @@ using std::min;
|
||||
using namespace cv::dnn::ocl4dnn;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
#if 0 // size_t is not well supported in Halide operations
|
||||
typedef size_t HALIDE_DIFF_T;
|
||||
#else
|
||||
typedef int HALIDE_DIFF_T;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
#include "../cuda4dnn/primitives/pooling.hpp"
|
||||
#include "../cuda4dnn/primitives/roi_pooling.hpp"
|
||||
@ -222,12 +213,6 @@ public:
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
if (kernel_size.empty() || kernel_size.size() == 2)
|
||||
return haveHalide() &&
|
||||
(type == MAX || (type == AVE && !pads_begin[0] && !pads_begin[1] && !pads_end[0] && !pads_end[1]));
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_WEBNN)
|
||||
{
|
||||
if (kernel_size.empty() || kernel_size.size() == 2)
|
||||
@ -495,16 +480,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
if (type == MAX)
|
||||
return initMaxPoolingHalide(inputs);
|
||||
else if (type == AVE)
|
||||
return initAvePoolingHalide(inputs);
|
||||
else
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
@ -1194,142 +1169,6 @@ public:
|
||||
PoolingInvoker::run(src, rois, dst, mask, kernel_size, strides, pads_begin, pads_end, avePoolPaddedArea, type, spatialScale, computeMaxIdx, nstripes);
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initMaxPoolingHalide(const std::vector<Ptr<BackendWrapper> > &inputs)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
const int inWidth = inputBuffer.width();
|
||||
const int inHeight = inputBuffer.height();
|
||||
const HALIDE_DIFF_T kernelHeight = (HALIDE_DIFF_T)kernel_size[0];
|
||||
const HALIDE_DIFF_T kernelWidth = (HALIDE_DIFF_T)kernel_size[1];
|
||||
const HALIDE_DIFF_T strideHeight = (HALIDE_DIFF_T)strides[0];
|
||||
const HALIDE_DIFF_T strideWidth = (HALIDE_DIFF_T)strides[1];
|
||||
const HALIDE_DIFF_T paddingTop = (HALIDE_DIFF_T)pads_begin[0];
|
||||
const HALIDE_DIFF_T paddingLeft = (HALIDE_DIFF_T)pads_begin[1];
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::RDom r(0, kernelWidth, 0, kernelHeight);
|
||||
Halide::Expr kx, ky;
|
||||
if(paddingLeft || paddingTop)
|
||||
{
|
||||
kx = clamp(x * strideWidth + r.x - paddingLeft, 0, inWidth - 1);
|
||||
ky = clamp(y * strideHeight + r.y - paddingTop, 0, inHeight - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
kx = min(x * strideWidth + r.x, inWidth - 1);
|
||||
ky = min(y * strideHeight + r.y, inHeight - 1);
|
||||
}
|
||||
|
||||
// Halide::argmax returns tuple (r.x, r.y, max).
|
||||
Halide::Tuple res = argmax(inputBuffer(kx, ky, c, n));
|
||||
|
||||
if (!computeMaxIdx)
|
||||
{
|
||||
top(x, y, c, n) = res[2];
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
}
|
||||
|
||||
// Compute offset from argmax in range [0, kernel_size).
|
||||
Halide::Expr max_index;
|
||||
if(paddingLeft || paddingTop)
|
||||
{
|
||||
max_index = clamp(y * strideHeight + res[1] - paddingTop,
|
||||
0, inHeight - 1) * inWidth +
|
||||
clamp(x * strideWidth + res[0] - paddingLeft,
|
||||
0, inWidth - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
max_index = min(y * strideHeight + res[1], inHeight - 1) * inWidth +
|
||||
min(x * strideWidth + res[0], inWidth - 1);
|
||||
}
|
||||
top(x, y, c, n) = { res[2], Halide::cast<float>(max_index) };
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initAvePoolingHalide(const std::vector<Ptr<BackendWrapper> > &inputs)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
|
||||
const int inW = inputBuffer.width(), inH = inputBuffer.height();
|
||||
const HALIDE_DIFF_T kernelHeight = (HALIDE_DIFF_T)kernel_size[0];
|
||||
const HALIDE_DIFF_T kernelWidth = (HALIDE_DIFF_T)kernel_size[1];
|
||||
const HALIDE_DIFF_T strideHeight = (HALIDE_DIFF_T)strides[0];
|
||||
const HALIDE_DIFF_T strideWidth = (HALIDE_DIFF_T)strides[1];
|
||||
if ((inW - kernelWidth) % strideWidth || (inH - kernelHeight) % strideHeight)
|
||||
{
|
||||
CV_Error(cv::Error::StsNotImplemented,
|
||||
"Halide backend for average pooling with partial "
|
||||
"kernels is not implemented");
|
||||
}
|
||||
|
||||
const float norm = 1.0f / (kernelWidth * kernelHeight);
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::RDom r(0, kernelWidth, 0, kernelHeight);
|
||||
top(x, y, c, n) = sum(
|
||||
inputBuffer(x * strideWidth + r.x,
|
||||
y * strideHeight + r.y, c, n)) * norm;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual void applyHalideScheduler(Ptr<BackendNode>& node,
|
||||
const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs,
|
||||
int targetId) const CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
if (targetId != DNN_TARGET_CPU)
|
||||
{
|
||||
Layer::applyHalideScheduler(node, inputs, outputs, targetId);
|
||||
return;
|
||||
}
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n"), tile("tile"),
|
||||
xi("xi"), yi("yi"), ci("ci"), xo("xo"), yo("yo"), co("co");
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs.back();
|
||||
|
||||
int outW, outH, outC, outN;
|
||||
getCanonicalSize(outputs[0].size, &outW, &outH, &outC, &outN);
|
||||
|
||||
if (outW < 8 || outH < 8)
|
||||
{
|
||||
if (outC > 8)
|
||||
top.split(c, co, ci, 8)
|
||||
.fuse(x, y, tile).fuse(co, tile, tile).fuse(n, tile, tile)
|
||||
.parallel(tile)
|
||||
.vectorize(ci);
|
||||
else
|
||||
{
|
||||
top.fuse(y, c, tile).fuse(n, tile, tile)
|
||||
.parallel(tile);
|
||||
if (outW > 1)
|
||||
top.vectorize(x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outC > 8)
|
||||
top.split(x, xo, xi, 8).split(y, yo, yi, 8).split(c, co, ci, 8)
|
||||
.fuse(xo, yo, tile).fuse(co, tile, tile).fuse(n, tile, tile)
|
||||
.parallel(tile)
|
||||
.vectorize(xi);
|
||||
else
|
||||
top.split(x, xo, xi, 8).split(y, yo, yi, 8)
|
||||
.fuse(xo, yo, tile).fuse(c, tile, tile).fuse(n, tile, tile)
|
||||
.parallel(tile)
|
||||
.vectorize(xi);
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
const int requiredOutputs,
|
||||
std::vector<MatShape> &outputs,
|
||||
|
@ -12,7 +12,6 @@ Implementation of Scale layer.
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_webnn.hpp"
|
||||
@ -84,7 +83,6 @@ public:
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
(backendId == DNN_BACKEND_WEBNN && axis >0);
|
||||
}
|
||||
|
||||
@ -270,63 +268,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> tryAttach(const Ptr<BackendNode>& node) CV_OVERRIDE
|
||||
{
|
||||
switch (node->backendId)
|
||||
{
|
||||
case DNN_BACKEND_HALIDE:
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
auto base = node.dynamicCast<HalideBackendNode>();
|
||||
Halide::Func& input = base->funcs.back();
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = attachHalide(input(x, y, c, n));
|
||||
return Ptr<BackendNode>(new HalideBackendNode(base, top));
|
||||
#endif // HAVE_HALIDE
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> input = halideBuffer(inputs[0]);
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = attachHalide(input(x, y, c, n));
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
// attachHalide can work both with Halide::Buffer and Halide::Func. In the
|
||||
// second case it will be a fusion.
|
||||
Halide::Func attachHalide(const Halide::Expr& input)
|
||||
{
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
|
||||
const int numChannels = blobs[0].total();
|
||||
|
||||
Halide::Expr topExpr = input;
|
||||
if (hasWeights)
|
||||
{
|
||||
auto weights = wrapToHalideBuffer(blobs[0], {numChannels});
|
||||
topExpr *= weights(c);
|
||||
}
|
||||
if (hasBias)
|
||||
{
|
||||
auto bias = wrapToHalideBuffer(blobs.back(), {numChannels});
|
||||
topExpr += bias(c);
|
||||
}
|
||||
top(x, y, c, n) = topExpr;
|
||||
return top;
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
|
||||
#ifdef HAVE_DNN_NGRAPH
|
||||
virtual Ptr<BackendNode> initNgraph(const std::vector<Ptr<BackendWrapper> >& inputs, const std::vector<Ptr<BackendNode> >& nodes) CV_OVERRIDE
|
||||
{
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "../precomp.hpp"
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_cuda.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../ie_ngraph.hpp"
|
||||
#include "../op_webnn.hpp"
|
||||
@ -115,7 +114,6 @@ public:
|
||||
#endif
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_CUDA ||
|
||||
(backendId == DNN_BACKEND_HALIDE && haveHalide() && axisRaw == 1) ||
|
||||
backendId == DNN_BACKEND_CANN;
|
||||
}
|
||||
|
||||
@ -325,31 +323,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
Halide::Buffer<float> inputBuffer = halideBuffer(inputs[0]);
|
||||
int inW, inH, inC, inN;
|
||||
getCanonicalSize(inputBuffer, &inW, &inH, &inC, &inN);
|
||||
|
||||
if (inW != 1 || inH != 1)
|
||||
CV_Error(cv::Error::StsNotImplemented,
|
||||
"Halide backend for SoftMax with spatial size "
|
||||
"more than 1x1 is not implemented");
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
Halide::Func top = (name.empty() ? Halide::Func() : Halide::Func(name));
|
||||
|
||||
Halide::Func expInput("expInput");
|
||||
Halide::RDom r(0, inW, 0, inH, 0, inC);
|
||||
expInput(x, y, c, n) = exp(inputBuffer(x, y, c, n));
|
||||
Halide::Expr globalSum = sum(expInput(r.x, r.y, r.z, n));
|
||||
top(x, y, c, n) = expInput(x, y, c, n) / globalSum;
|
||||
return Ptr<BackendNode>(new HalideBackendNode(top));
|
||||
#endif // HAVE_HALIDE
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
#ifdef HAVE_CANN
|
||||
virtual Ptr<BackendNode> initCann(const std::vector<Ptr<BackendWrapper> > &inputs,
|
||||
const std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#include "legacy_backend.hpp"
|
||||
|
||||
#include "op_halide.hpp"
|
||||
#include "op_inf_engine.hpp"
|
||||
#include "ie_ngraph.hpp"
|
||||
#include "op_vkcom.hpp"
|
||||
@ -63,13 +62,6 @@ Ptr<BackendWrapper> wrapMat(int backendId, int targetId, cv::Mat& m)
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Unknown/unsupported target identifier");
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
CV_Assert(haveHalide());
|
||||
#ifdef HAVE_HALIDE
|
||||
return Ptr<BackendWrapper>(new HalideBackendWrapper(targetId, m));
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
else if (backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
{
|
||||
CV_ERROR_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019;
|
||||
|
@ -402,14 +402,6 @@ void Net::enableWinograd(bool useWinograd)
|
||||
return impl->enableWinograd(useWinograd);
|
||||
}
|
||||
|
||||
void Net::setHalideScheduler(const String& scheduler)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG_VALUE(scheduler, "scheduler", scheduler.c_str());
|
||||
CV_Assert(impl);
|
||||
return impl->setHalideScheduler(scheduler);
|
||||
}
|
||||
|
||||
int64 Net::getPerfProfile(std::vector<double>& timings)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
@ -104,9 +104,6 @@ void Net::Impl::validateBackendAndTarget()
|
||||
preferableTarget == DNN_TARGET_CPU_FP16 ||
|
||||
preferableTarget == DNN_TARGET_OPENCL ||
|
||||
preferableTarget == DNN_TARGET_OPENCL_FP16);
|
||||
CV_Assert(preferableBackend != DNN_BACKEND_HALIDE ||
|
||||
preferableTarget == DNN_TARGET_CPU ||
|
||||
preferableTarget == DNN_TARGET_OPENCL);
|
||||
#ifdef HAVE_WEBNN
|
||||
if (preferableBackend == DNN_BACKEND_WEBNN)
|
||||
{
|
||||
@ -204,16 +201,6 @@ void Net::Impl::setUpNet(const std::vector<LayerPin>& blobsToKeep_)
|
||||
|
||||
initBackend(blobsToKeep_);
|
||||
|
||||
if (!netWasAllocated)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
compileHalide();
|
||||
#else
|
||||
CV_Assert(preferableBackend != DNN_BACKEND_HALIDE);
|
||||
#endif
|
||||
}
|
||||
|
||||
netWasAllocated = true;
|
||||
|
||||
if (dumpLevel)
|
||||
@ -808,10 +795,6 @@ void Net::Impl::forwardLayer(LayerData& ld)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
forwardHalide(ld.outputBlobsWrappers, node);
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
CV_Assert(preferableBackend != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && "Inheritance internal error");
|
||||
@ -1566,7 +1549,6 @@ string Net::Impl::dump(bool forceAllocation) const
|
||||
switch (prefBackend)
|
||||
{
|
||||
case DNN_BACKEND_DEFAULT: backend = "DEFAULT/"; break;
|
||||
case DNN_BACKEND_HALIDE: backend = "HALIDE/"; break;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: // fallthru
|
||||
case DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019: // fallthru
|
||||
case DNN_BACKEND_INFERENCE_ENGINE_NGRAPH: backend = "OpenVINO/"; break;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef __OPENCV_DNN_SRC_NET_IMPL_HPP__
|
||||
#define __OPENCV_DNN_SRC_NET_IMPL_HPP__
|
||||
|
||||
#include "op_halide.hpp"
|
||||
#include "op_inf_engine.hpp"
|
||||
#include "ie_ngraph.hpp"
|
||||
#include "op_vkcom.hpp"
|
||||
@ -54,7 +53,6 @@ struct Net::Impl : public detail::NetImplBase
|
||||
BlobManager blobManager;
|
||||
int preferableBackend;
|
||||
int preferableTarget;
|
||||
String halideConfigFile;
|
||||
bool hasDynamicShapes;
|
||||
// Map host data to backend specific wrapper.
|
||||
std::map<void*, Ptr<BackendWrapper>> backendWrappers;
|
||||
@ -167,12 +165,6 @@ struct Net::Impl : public detail::NetImplBase
|
||||
|
||||
virtual void initBackend(const std::vector<LayerPin>& blobsToKeep_);
|
||||
|
||||
void setHalideScheduler(const String& scheduler);
|
||||
#ifdef HAVE_HALIDE
|
||||
void compileHalide();
|
||||
void initHalideBackend();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WEBNN
|
||||
void addWebnnOutputs(LayerData& ld);
|
||||
void initWebnnBackend(const std::vector<LayerPin>& blobsToKeep_);
|
||||
|
@ -36,13 +36,6 @@ Ptr<BackendWrapper> Net::Impl::wrap(Mat& host)
|
||||
return OpenCLBackendWrapper::create(baseBuffer, host);
|
||||
#else
|
||||
CV_Error(Error::StsInternal, "");
|
||||
#endif
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
CV_Assert(haveHalide());
|
||||
#ifdef HAVE_HALIDE
|
||||
return Ptr<BackendWrapper>(new HalideBackendWrapper(baseBuffer, shape));
|
||||
#endif
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
|
||||
@ -107,14 +100,6 @@ void Net::Impl::initBackend(const std::vector<LayerPin>& blobsToKeep_)
|
||||
{
|
||||
CV_Assert(preferableTarget == DNN_TARGET_CPU || preferableTarget == DNN_TARGET_CPU_FP16 || IS_DNN_OPENCL_TARGET(preferableTarget));
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
initHalideBackend();
|
||||
#else
|
||||
CV_Error(Error::StsNotImplemented, "This OpenCV version is built without support of Halide");
|
||||
#endif
|
||||
}
|
||||
else if (preferableBackend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
CV_Assert(0 && "Inheritance must be used with OpenVINO backend");
|
||||
|
@ -1,429 +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.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <opencv2/dnn/shape_utils.hpp>
|
||||
#include "op_halide.hpp"
|
||||
#include "net_impl.hpp"
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
#include "halide_scheduler.hpp"
|
||||
|
||||
#include <HalideRuntimeOpenCL.h>
|
||||
#include <thread>
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
namespace cv {
|
||||
namespace dnn {
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
|
||||
void Net::Impl::setHalideScheduler(const String& scheduler)
|
||||
{
|
||||
halideConfigFile = scheduler;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
|
||||
|
||||
void Net::Impl::compileHalide()
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
CV_Assert(preferableBackend == DNN_BACKEND_HALIDE);
|
||||
|
||||
HalideScheduler scheduler(halideConfigFile);
|
||||
std::vector< std::reference_wrapper<LayerData> > compileList; compileList.reserve(64);
|
||||
for (MapIdToLayerData::iterator it = layers.begin(); it != layers.end(); ++it)
|
||||
{
|
||||
LayerData& ld = it->second;
|
||||
Ptr<Layer> layer = ld.layerInstance;
|
||||
if (layer->supportBackend(DNN_BACKEND_HALIDE) && !ld.skip)
|
||||
{
|
||||
CV_Assert(!ld.backendNodes[DNN_BACKEND_HALIDE].empty());
|
||||
bool scheduled = scheduler.process(ld.backendNodes[DNN_BACKEND_HALIDE]);
|
||||
if (!scheduled)
|
||||
{
|
||||
// Use automatic scheduling provided by layer.
|
||||
layer->applyHalideScheduler(ld.backendNodes[DNN_BACKEND_HALIDE],
|
||||
ld.inputBlobs, ld.outputBlobs,
|
||||
preferableTarget);
|
||||
}
|
||||
compileList.emplace_back(ld);
|
||||
}
|
||||
}
|
||||
std::atomic<int> progress(0);
|
||||
auto fn = ([&] () -> void
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int id = progress.fetch_add(1);
|
||||
if ((size_t)id >= compileList.size())
|
||||
return;
|
||||
const LayerData& ld = compileList[id].get();
|
||||
Ptr<BackendNode> node = ld.backendNodes.find(DNN_BACKEND_HALIDE)->second;
|
||||
dnn::compileHalide(ld.outputBlobs, node, preferableTarget);
|
||||
}
|
||||
});
|
||||
size_t num_threads = std::min(compileList.size(), (size_t)std::thread::hardware_concurrency());
|
||||
num_threads = std::max((size_t)1u, std::min((size_t)8u, num_threads));
|
||||
std::vector<std::thread> threads(num_threads - 1);
|
||||
for (auto& t: threads) t = std::thread(fn);
|
||||
fn(); // process own tasks
|
||||
for (auto& t: threads) t.join();
|
||||
}
|
||||
|
||||
|
||||
void Net::Impl::initHalideBackend()
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_Assert_N(preferableBackend == DNN_BACKEND_HALIDE, haveHalide());
|
||||
|
||||
// Iterator to current layer.
|
||||
MapIdToLayerData::iterator it = layers.begin();
|
||||
// Iterator to base layer for fusion. In example, in case of conv+bn+relu
|
||||
// it'll be a conv layer.
|
||||
MapIdToLayerData::iterator baseIt = layers.begin();
|
||||
for (; it != layers.end(); it++)
|
||||
{
|
||||
LayerData &ldTop = it->second;
|
||||
Ptr<Layer> layerTop = ldTop.layerInstance;
|
||||
if (!layerTop->supportBackend(preferableBackend))
|
||||
{
|
||||
// Move base iterator to layer that don't support preferable
|
||||
// backend to prevent fusion over layer of different backend.
|
||||
baseIt = it;
|
||||
continue;
|
||||
}
|
||||
// Try to do layers fusion.
|
||||
LayerData &ldBot = baseIt->second;
|
||||
Ptr<Layer> layerBot = ldBot.layerInstance;
|
||||
// 1. Check that bottom and top from the same backends.
|
||||
if (it != layers.begin() && layerBot->supportBackend(preferableBackend))
|
||||
{
|
||||
// 2. Check that current layer works in-place.
|
||||
bool inPlace = ldTop.inputBlobs.size() == 1 &&
|
||||
ldBot.outputBlobs.size() == 1 &&
|
||||
ldTop.inputBlobs[0]->data ==
|
||||
ldBot.outputBlobs[0].data;
|
||||
if (inPlace)
|
||||
{
|
||||
// 3. Try to attach node.
|
||||
CV_Assert(!ldBot.backendNodes[preferableBackend].empty());
|
||||
Ptr<BackendNode> fusedNode =
|
||||
layerTop->tryAttach(ldBot.backendNodes[preferableBackend]);
|
||||
if (!fusedNode.empty())
|
||||
{
|
||||
ldTop.skip = true;
|
||||
ldBot.backendNodes[preferableBackend] = fusedNode;
|
||||
ldBot.outputBlobsWrappers = ldTop.outputBlobsWrappers;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// No layers fusion.
|
||||
ldTop.skip = false;
|
||||
ldTop.backendNodes[DNN_BACKEND_HALIDE] =
|
||||
layerTop->initHalide(ldTop.inputBlobsWrappers);
|
||||
baseIt = it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // HAVE_HALIDE
|
||||
CV__DNN_INLINE_NS_END
|
||||
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
static MatShape getBufferShape(const MatShape& shape)
|
||||
{
|
||||
if (shape.size() == 2 || shape.size() == 4)
|
||||
{
|
||||
int w, h, c, n;
|
||||
getCanonicalSize(shape, &w, &h, &c, &n);
|
||||
return {w, h, c, n};
|
||||
}
|
||||
else
|
||||
{
|
||||
MatShape bufferShape(shape);
|
||||
std::reverse(bufferShape.begin(), bufferShape.end());
|
||||
return bufferShape;
|
||||
}
|
||||
}
|
||||
|
||||
static MatShape getBufferShape(const MatSize& size)
|
||||
{
|
||||
return getBufferShape(shape(size));
|
||||
}
|
||||
|
||||
Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat)
|
||||
{
|
||||
return wrapToHalideBuffer(mat, getBufferShape(mat.size));
|
||||
}
|
||||
|
||||
Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat,
|
||||
const std::vector<int>& sizes)
|
||||
{
|
||||
Halide::Buffer<float> buffer((float*)mat.data, sizes);
|
||||
buffer.set_host_dirty(); // Indicate that data is on CPU.
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Halide::Buffer<> halideBuffer(const Ptr<BackendWrapper>& ptr)
|
||||
{
|
||||
CV_Assert(!ptr.empty());
|
||||
return ptr.dynamicCast<HalideBackendWrapper>()->buffer;
|
||||
}
|
||||
|
||||
std::vector<Halide::Buffer<> > halideBuffers(const std::vector<Ptr<BackendWrapper> >& ptrs)
|
||||
{
|
||||
std::vector<Halide::Buffer<> > vec;
|
||||
vec.reserve(ptrs.size());
|
||||
for (const Ptr<BackendWrapper>& ptr : ptrs)
|
||||
{
|
||||
vec.push_back(halideBuffer(ptr));
|
||||
}
|
||||
return vec;
|
||||
}
|
||||
|
||||
void getCanonicalSize(const Halide::Buffer<>& buffer, int* width, int* height,
|
||||
int* channels, int* batch)
|
||||
{
|
||||
CV_Assert(buffer.dimensions() == 4);
|
||||
*width = buffer.extent(0);
|
||||
*height = buffer.extent(1);
|
||||
*channels = buffer.extent(2);
|
||||
*batch = buffer.extent(3);
|
||||
}
|
||||
|
||||
HalideBackendNode::HalideBackendNode(const Halide::Func& func)
|
||||
: BackendNode(DNN_BACKEND_HALIDE), funcs(1, func) {}
|
||||
|
||||
HalideBackendNode::HalideBackendNode(const std::vector<Halide::Func>& funcs)
|
||||
: BackendNode(DNN_BACKEND_HALIDE), funcs(funcs) {}
|
||||
|
||||
HalideBackendNode::HalideBackendNode(const Ptr<HalideBackendNode>& base,
|
||||
const Halide::Func& top)
|
||||
: BackendNode(DNN_BACKEND_HALIDE), funcs(base->funcs)
|
||||
{
|
||||
funcs.back() = top;
|
||||
}
|
||||
|
||||
HalideBackendWrapper::HalideBackendWrapper(int targetId, const cv::Mat& m)
|
||||
: BackendWrapper(DNN_BACKEND_HALIDE, targetId)
|
||||
{
|
||||
managesDevMemory = true;
|
||||
buffer = wrapToHalideBuffer(m);
|
||||
if (targetId == DNN_TARGET_CPU)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
Halide::Target t = Halide::get_host_target();
|
||||
t.set_feature(Halide::Target::OpenCL);
|
||||
buffer.copy_to_device(t);
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Unknown target identifier");
|
||||
}
|
||||
|
||||
HalideBackendWrapper::HalideBackendWrapper(const Ptr<BackendWrapper>& base,
|
||||
const MatShape& shape)
|
||||
: BackendWrapper(DNN_BACKEND_HALIDE, base->targetId)
|
||||
{
|
||||
managesDevMemory = false;
|
||||
Halide::Buffer<float> baseBuffer = halideBuffer(base);
|
||||
buffer = Halide::Buffer<float>((float*)baseBuffer.raw_buffer()->host,
|
||||
getBufferShape(shape));
|
||||
if (baseBuffer.has_device_allocation())
|
||||
{
|
||||
buffer.raw_buffer()->device = baseBuffer.raw_buffer()->device;
|
||||
buffer.raw_buffer()->device_interface = baseBuffer.raw_buffer()->device_interface;
|
||||
buffer.set_device_dirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.set_host_dirty(); // Indicate that data is on CPU.
|
||||
CV_Assert(targetId == DNN_TARGET_CPU);
|
||||
}
|
||||
}
|
||||
|
||||
HalideBackendWrapper::~HalideBackendWrapper()
|
||||
{
|
||||
if (buffer.has_device_allocation() && !managesDevMemory)
|
||||
{
|
||||
buffer.raw_buffer()->device = 0;
|
||||
buffer.raw_buffer()->device_interface = 0;
|
||||
buffer.set_device_dirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
void HalideBackendWrapper::copyToHost()
|
||||
{
|
||||
if (buffer.device_dirty())
|
||||
{
|
||||
buffer.device_sync();
|
||||
buffer.copy_to_host();
|
||||
}
|
||||
}
|
||||
|
||||
void HalideBackendWrapper::setHostDirty()
|
||||
{
|
||||
buffer.set_device_dirty(false);
|
||||
buffer.set_host_dirty();
|
||||
}
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
void getCanonicalSize(const MatSize& size, int* w, int* h, int* c, int* n)
|
||||
{
|
||||
getCanonicalSize(shape(size), w, h, c, n);
|
||||
}
|
||||
|
||||
void getCanonicalSize(const MatShape& shape, int* width, int* height,
|
||||
int* channels, int* batch)
|
||||
{
|
||||
const int dims = shape.size();
|
||||
CV_Assert(dims == 2 || dims == 4);
|
||||
*batch = shape[0];
|
||||
*channels = shape[1];
|
||||
if (dims == 4)
|
||||
{
|
||||
*width = shape[3];
|
||||
*height = shape[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
*width = 1;
|
||||
*height = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void compileHalide(const std::vector<Mat> &outputs, Ptr<BackendNode>& node, int targetId)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
CV_Assert(!node.empty());
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs.back();
|
||||
|
||||
int outW, outH, outC, outN;
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n");
|
||||
getCanonicalSize(outputs[0].size, &outW, &outH, &outC, &outN);
|
||||
top.bound(x, 0, outW).bound(y, 0, outH)
|
||||
.bound(c, 0, outC).bound(n, 0, outN);
|
||||
|
||||
Halide::Target target = Halide::get_host_target();
|
||||
target.set_feature(Halide::Target::NoAsserts);
|
||||
if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
target.set_feature(Halide::Target::OpenCL);
|
||||
}
|
||||
CV_Assert(target.supported());
|
||||
top.compile_jit(target);
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
void forwardHalide(std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
const Ptr<BackendNode>& node)
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
CV_Assert(!node.empty());
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs.back();
|
||||
auto outputBuffers = halideBuffers(outputs);
|
||||
top.realize(Halide::Realization(outputBuffers));
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
bool haveHalide()
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
|
||||
CV__DNN_INLINE_NS_BEGIN
|
||||
|
||||
|
||||
void Layer::applyHalideScheduler(Ptr<BackendNode>& node, const std::vector<Mat*> &inputs,
|
||||
const std::vector<Mat> &outputs, int targetId) const
|
||||
{
|
||||
#ifndef HAVE_HALIDE
|
||||
CV_Error(Error::StsNotImplemented, "");
|
||||
#else
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
Halide::Var x("x"), y("y"), c("c"), n("n"), co("co"), ci("ci"),
|
||||
xo("xo"), xi("xi"), yo("yo"), yi("yi"), tile("tile");
|
||||
Halide::Func& top = node.dynamicCast<HalideBackendNode>()->funcs.back();
|
||||
|
||||
int outW, outH, outC, outN;
|
||||
getCanonicalSize(outputs[0].size, &outW, &outH, &outC, &outN);
|
||||
|
||||
if (targetId == DNN_TARGET_CPU)
|
||||
{
|
||||
if (outW == 1 && outH == 1)
|
||||
{
|
||||
if (outC + outN == 1)
|
||||
return;
|
||||
|
||||
if (outC > 8)
|
||||
top.split(c, co, ci, 8)
|
||||
.fuse(x, y, tile).fuse(co, tile, tile).fuse(n, tile, tile)
|
||||
.parallel(tile)
|
||||
.vectorize(ci, 8);
|
||||
else
|
||||
top.fuse(x, y, tile).fuse(c, tile, tile).fuse(n, tile, tile)
|
||||
.parallel(tile);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outH > 2)
|
||||
{
|
||||
top.reorder(x, c, y)
|
||||
.split(y, yo, yi, 2)
|
||||
.fuse(yo, n, tile)
|
||||
.parallel(tile)
|
||||
.unroll(yi)
|
||||
.vectorize(x, outW >= 16 ? 16 : outW);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (targetId == DNN_TARGET_OPENCL)
|
||||
{
|
||||
if (outW == 1 && outH == 1)
|
||||
{
|
||||
int c_split = outC > 8 ? (outC > 16 ? 8 : 4) : outC;
|
||||
top.split(c, co, ci, c_split)
|
||||
.fuse(x, y, tile).fuse(co, tile, tile).fuse(n, tile, tile)
|
||||
.gpu_blocks(tile)
|
||||
.gpu_threads(ci);
|
||||
}
|
||||
else
|
||||
{
|
||||
int x_split = outW > 8 ? (outW >= 32 ? 16 : 8) : outW;
|
||||
int y_split = outH > 8 ? (outH >= 32 ? 16 : 8) : outH;
|
||||
// Supported vectorization widths: 2, 3, 4, 8, 16
|
||||
int c_split = outC > 8 ? (outC > 16 ? 8 : 4) : std::min(4, outC);
|
||||
top.split(x, xo, xi, x_split).split(y, yo, yi, y_split)
|
||||
.split(c, co, ci, c_split)
|
||||
.gpu_blocks(xo, yo, co)
|
||||
.gpu_threads(xi, yi)
|
||||
.reorder(xi, yi, ci, xo, yo, co)
|
||||
.vectorize(ci);
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsNotImplemented, "Unknown target identifier");
|
||||
#endif // HAVE_HALIDE
|
||||
}
|
||||
|
||||
|
||||
CV__DNN_INLINE_NS_END
|
||||
}} // namespace
|
@ -1,96 +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.
|
||||
//
|
||||
// Copyright (C) 2017, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
|
||||
#ifndef __OPENCV_DNN_OP_HALIDE_HPP__
|
||||
#define __OPENCV_DNN_OP_HALIDE_HPP__
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
#if defined(__GNUC__) && __GNUC__ >= 5
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsuggest-override"
|
||||
#endif
|
||||
#include <Halide.h>
|
||||
#if defined(__GNUC__) && __GNUC__ >= 5
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace dnn
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
// Returns four-dimensional buffer with float32 type that wrap cv::Mat data.
|
||||
// No data copy here.
|
||||
Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat);
|
||||
|
||||
Halide::Buffer<float> wrapToHalideBuffer(const Mat& mat,
|
||||
const std::vector<int>& shape);
|
||||
|
||||
// Extract batch size, number of channels, width and height from buffer.
|
||||
void getCanonicalSize(const Halide::Buffer<>& buffer, int* width, int* height,
|
||||
int* channels, int* batch);
|
||||
|
||||
// Cast pointer and create copy of Halide buffer. No data copy.
|
||||
Halide::Buffer<> halideBuffer(const Ptr<BackendWrapper>& ptr);
|
||||
|
||||
std::vector<Halide::Buffer<> > halideBuffers(const std::vector<Ptr<BackendWrapper> >& ptrs);
|
||||
|
||||
class HalideBackendNode : public BackendNode
|
||||
{
|
||||
public:
|
||||
HalideBackendNode(const Halide::Func& func);
|
||||
|
||||
HalideBackendNode(const std::vector<Halide::Func>& funcs);
|
||||
|
||||
// Initialize from the <base> node but replace last function to <top>.
|
||||
// It's using in case of layers fusing when we want to keep functions of
|
||||
// root layer but replace top by fused one (i.e. conv+padding to relu+padding).
|
||||
HalideBackendNode(const Ptr<HalideBackendNode>& base, const Halide::Func& top);
|
||||
|
||||
std::vector<Halide::Func> funcs;
|
||||
};
|
||||
|
||||
class HalideBackendWrapper : public BackendWrapper
|
||||
{
|
||||
public:
|
||||
HalideBackendWrapper(int targetId, const cv::Mat& m);
|
||||
|
||||
HalideBackendWrapper(const Ptr<BackendWrapper>& base, const MatShape& shape);
|
||||
|
||||
~HalideBackendWrapper() CV_OVERRIDE;
|
||||
|
||||
virtual void copyToHost() CV_OVERRIDE;
|
||||
|
||||
virtual void setHostDirty() CV_OVERRIDE;
|
||||
|
||||
Halide::Buffer<float> buffer;
|
||||
|
||||
private:
|
||||
bool managesDevMemory;
|
||||
};
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
// Extract batch size, number of channels, width and height from MatSize.
|
||||
void getCanonicalSize(const MatSize& size, int* width, int* height,
|
||||
int* channels, int* batch);
|
||||
|
||||
void getCanonicalSize(const MatShape& shape, int* width, int* height,
|
||||
int* channels, int* batch);
|
||||
|
||||
// Realize Halide pipeline into output blobs.
|
||||
void forwardHalide(std::vector<Ptr<BackendWrapper> > &outputs,
|
||||
const Ptr<BackendNode>& node);
|
||||
|
||||
// Compile Halide pipeline to specific target. Use outputs to set bounds of functions.
|
||||
void compileHalide(const std::vector<Mat> &outputs, Ptr<BackendNode>& node, int targetId);
|
||||
|
||||
bool haveHalide();
|
||||
} // namespace dnn
|
||||
} // namespace cv
|
||||
|
||||
#endif // __OPENCV_DNN_OP_HALIDE_HPP__
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include "op_halide.hpp"
|
||||
#include "op_inf_engine.hpp"
|
||||
#include "ie_ngraph.hpp"
|
||||
#include "op_vkcom.hpp"
|
||||
@ -13,8 +12,6 @@
|
||||
#include "op_timvx.hpp"
|
||||
#include "op_cann.hpp"
|
||||
|
||||
#include "halide_scheduler.hpp"
|
||||
|
||||
#include "backend.hpp"
|
||||
#include "factory.hpp"
|
||||
|
||||
@ -38,14 +35,6 @@ public:
|
||||
private:
|
||||
BackendRegistry()
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_CPU));
|
||||
#ifdef HAVE_OPENCL
|
||||
if (cv::ocl::useOpenCL())
|
||||
backends.push_back(std::make_pair(DNN_BACKEND_HALIDE, DNN_TARGET_OPENCL));
|
||||
#endif
|
||||
#endif // HAVE_HALIDE
|
||||
|
||||
bool haveBackendOpenVINO = false;
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
haveBackendOpenVINO = true;
|
||||
|
@ -15,7 +15,6 @@ class DNNTestNetwork : public DNNTestLayer
|
||||
public:
|
||||
void processNet(const std::string& weights, const std::string& proto,
|
||||
Size inpSize, const std::string& outputLayer = "",
|
||||
const std::string& halideScheduler = "",
|
||||
double l1 = 0.0, double lInf = 0.0)
|
||||
{
|
||||
// Create a common input blob.
|
||||
@ -23,12 +22,11 @@ public:
|
||||
Mat inp(4, blobSize, CV_32FC1);
|
||||
randu(inp, 0.0f, 1.0f);
|
||||
|
||||
processNet(weights, proto, inp, outputLayer, halideScheduler, l1, lInf);
|
||||
processNet(weights, proto, inp, outputLayer, l1, lInf);
|
||||
}
|
||||
|
||||
void processNet(std::string weights, std::string proto,
|
||||
Mat inp, const std::string& outputLayer = "",
|
||||
std::string halideScheduler = "",
|
||||
double l1 = 0.0, double lInf = 0.0, double detectionConfThresh = 0.2, bool useWinograd = true)
|
||||
{
|
||||
checkBackend();
|
||||
@ -50,11 +48,6 @@ public:
|
||||
net.setPreferableBackend(backend);
|
||||
net.setPreferableTarget(target);
|
||||
net.enableWinograd(useWinograd);
|
||||
if (backend == DNN_BACKEND_HALIDE && !halideScheduler.empty())
|
||||
{
|
||||
halideScheduler = findDataFile(halideScheduler);
|
||||
net.setHalideScheduler(halideScheduler);
|
||||
}
|
||||
Mat out = net.forward(outputLayer).clone();
|
||||
|
||||
check(outDefault, out, outputLayer, l1, lInf, detectionConfThresh, "First run");
|
||||
@ -103,9 +96,7 @@ TEST_P(DNNTestNetwork, AlexNet)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_1GB);
|
||||
processNet("dnn/bvlc_alexnet.caffemodel", "dnn/bvlc_alexnet.prototxt",
|
||||
Size(227, 227), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_alexnet.yml" :
|
||||
"dnn/halide_scheduler_alexnet.yml");
|
||||
Size(227, 227), "prob");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -118,9 +109,7 @@ TEST_P(DNNTestNetwork, ResNet_50)
|
||||
);
|
||||
|
||||
processNet("dnn/ResNet-50-model.caffemodel", "dnn/ResNet-50-deploy.prototxt",
|
||||
Size(224, 224), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_resnet_50.yml" :
|
||||
"dnn/halide_scheduler_resnet_50.yml");
|
||||
Size(224, 224), "prob");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -128,9 +117,7 @@ TEST_P(DNNTestNetwork, ResNet_50)
|
||||
TEST_P(DNNTestNetwork, SqueezeNet_v1_1)
|
||||
{
|
||||
processNet("dnn/squeezenet_v1.1.caffemodel", "dnn/squeezenet_v1.1.prototxt",
|
||||
Size(227, 227), "prob",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_squeezenet_v1_1.yml" :
|
||||
"dnn/halide_scheduler_squeezenet_v1_1.yml");
|
||||
Size(227, 227), "prob");
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -155,10 +142,7 @@ TEST_P(DNNTestNetwork, Inception_5h)
|
||||
l1 = 1.72e-5;
|
||||
lInf = 8e-4;
|
||||
}
|
||||
processNet("dnn/tensorflow_inception_graph.pb", "", Size(224, 224), "softmax2",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_inception_5h.yml" :
|
||||
"dnn/halide_scheduler_inception_5h.yml",
|
||||
l1, lInf);
|
||||
processNet("dnn/tensorflow_inception_graph.pb", "", Size(224, 224), "softmax2", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -177,32 +161,25 @@ TEST_P(DNNTestNetwork, ENet)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
|
||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_CPU_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU_FP16);
|
||||
processNet("dnn/Enet-model-best.net", "", Size(512, 512), "l367_Deconvolution",
|
||||
target == DNN_TARGET_OPENCL ? "dnn/halide_scheduler_opencl_enet.yml" :
|
||||
"dnn/halide_scheduler_enet.yml",
|
||||
2e-5, 0.15);
|
||||
processNet("dnn/Enet-model-best.net", "", Size(512, 512), "l367_Deconvolution", 2e-5, 0.15);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
|
||||
float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD || target == DNN_TARGET_CPU_FP16) ? 1.5e-2 : 0.0;
|
||||
float iouDiff = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0;
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.262 : FLT_MIN;
|
||||
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh);
|
||||
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt",
|
||||
inp, "detection_out", scoreDiff, iouDiff, detectionConfThresh);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2022010000)
|
||||
// May hang on some configurations
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && (target == DNN_TARGET_OPENCL || target == DNN_TARGET_OPENCL_FP16))
|
||||
@ -238,15 +215,13 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe_Different_Width_Height)
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/MobileNetSSD_deploy_19e3ec3.caffemodel", "dnn/MobileNetSSD_deploy_19e3ec3.prototxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
inp, "detection_out", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
{
|
||||
applyTestTag((target == DNN_TARGET_CPU || target == DNN_TARGET_CPU_FP16) ? "" : CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
@ -263,14 +238,12 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow)
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh);
|
||||
inp, "detection_out", scoreDiff, iouDiff, detectionConfThresh);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LT(2021040000)
|
||||
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 || backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) &&
|
||||
target == DNN_TARGET_MYRIAD && getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@ -295,15 +268,13 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v1_TensorFlow_Different_Width_Height)
|
||||
iouDiff = 0.06;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v1_coco_2017_11_17.pb", "dnn/ssd_mobilenet_v1_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
inp, "detection_out", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
{
|
||||
applyTestTag(target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
@ -319,7 +290,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_v2_TensorFlow)
|
||||
iouDiff = 0.07;
|
||||
}
|
||||
processNet("dnn/ssd_mobilenet_v2_coco_2018_03_29.pb", "dnn/ssd_mobilenet_v2_coco_2018_03_29.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff, 0.25);
|
||||
inp, "detection_out", scoreDiff, iouDiff, 0.25);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
@ -327,8 +298,6 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE && target == DNN_TARGET_CPU)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE); // TODO HALIDE_CPU
|
||||
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
@ -350,7 +319,7 @@ TEST_P(DNNTestNetwork, SSD_VGG16)
|
||||
}
|
||||
|
||||
processNet("dnn/VGG_ILSVRC2016_SSD_300x300_iter_440000.caffemodel",
|
||||
"dnn/ssd_vgg16.prototxt", inp, "detection_out", "", scoreDiff,
|
||||
"dnn/ssd_vgg16.prototxt", inp, "detection_out", scoreDiff,
|
||||
iouDiff, 0.2, false);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
@ -359,8 +328,6 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_LONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@ -370,7 +337,7 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco)
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.009 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
|
||||
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
Size(46, 46), "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -379,8 +346,6 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, (target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_1GB : CV_TEST_TAG_MEMORY_2GB),
|
||||
CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@ -391,7 +356,7 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.02 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CPU_FP16) ? 0.2 : 0.0;
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
Size(46, 46), "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
@ -399,8 +364,6 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
|
||||
TEST_P(DNNTestNetwork, OpenPose_pose_mpi_faster_4_stages)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_LONG, CV_TEST_TAG_MEMORY_1GB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_LE(2018050000)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD
|
||||
&& getInferenceEngineVPUType() == CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
@ -423,19 +386,15 @@ TEST_P(DNNTestNetwork, OpenFace)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0024 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.0071 : 0.0;
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", "", l1, lInf);
|
||||
processNet("dnn/openface_nn4.small2.v1.t7", "", Size(96, 96), "", l1, lInf);
|
||||
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, opencv_face_detector)
|
||||
{
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat img = imread(findDataFile("gpu/lbpcascade/er.png"));
|
||||
Mat inp = blobFromImage(img, 1.0, Size(), Scalar(104.0, 177.0, 123.0), false, false);
|
||||
processNet("dnn/opencv_face_detector.caffemodel", "dnn/opencv_face_detector.prototxt",
|
||||
@ -458,8 +417,6 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
|
||||
#endif
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
Mat sample = imread(findDataFile("dnn/street.png"));
|
||||
Mat inp = blobFromImage(sample, 1.0f, Size(300, 300), Scalar(), false);
|
||||
float scoreDiff = 0.0, iouDiff = 0.0;
|
||||
@ -474,15 +431,13 @@ TEST_P(DNNTestNetwork, Inception_v2_SSD_TensorFlow)
|
||||
iouDiff = 0.08;
|
||||
}
|
||||
processNet("dnn/ssd_inception_v2_coco_2017_11_17.pb", "dnn/ssd_inception_v2_coco_2017_11_17.pbtxt",
|
||||
inp, "detection_out", "", scoreDiff, iouDiff);
|
||||
inp, "detection_out", scoreDiff, iouDiff);
|
||||
expectNoFallbacksFromIE(net);
|
||||
}
|
||||
|
||||
TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
// Reference output values are in range [-3.807, 4.605]
|
||||
float l1 = 0.0, lInf = 0.0;
|
||||
if (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_CPU_FP16)
|
||||
@ -502,7 +457,7 @@ TEST_P(DNNTestNetwork, DenseNet_121)
|
||||
l1 = 0.008;
|
||||
lInf = 0.06;
|
||||
}
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Size(224, 224), "", "", l1, lInf);
|
||||
processNet("dnn/DenseNet_121.caffemodel", "dnn/DenseNet_121.prototxt", Size(224, 224), "", l1, lInf);
|
||||
if (target != DNN_TARGET_MYRIAD || getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||
expectNoFallbacksFromIE(net);
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
@ -512,8 +467,6 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB, CV_TEST_TAG_DEBUG_VERYLONG);
|
||||
|
||||
if (backend == DNN_BACKEND_HALIDE)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
@ -564,14 +517,18 @@ TEST_P(DNNTestNetwork, FastNeuralStyle_eccv16)
|
||||
#endif
|
||||
|
||||
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", "", l1, lInf);
|
||||
processNet("dnn/fast_neural_style_eccv16_starry_night.t7", "", inp, "", l1, lInf);
|
||||
#if defined(HAVE_INF_ENGINE) && INF_ENGINE_VER_MAJOR_GE(2019010000)
|
||||
expectNoFallbacksFromIE(net);
|
||||
#endif
|
||||
expectNoFallbacksFromCUDA(net);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets(true, true, false, true, true));
|
||||
INSTANTIATE_TEST_CASE_P(/*nothing*/, DNNTestNetwork, dnnBackendsAndTargets(/* withInferenceEngine = */ true,
|
||||
/* obsolete_withHalide = */ false,
|
||||
/* withCpuOCV = */ false,
|
||||
/* withVkCom = */ true,
|
||||
/* withCUDA = */ true));
|
||||
|
||||
/*
|
||||
Backend tests of layers
|
||||
|
@ -19,7 +19,6 @@
|
||||
#define INF_ENGINE_VER_MAJOR_EQ(ver) (((INF_ENGINE_RELEASE) / 10000) == ((ver) / 10000))
|
||||
|
||||
#define CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND "dnn_skip_opencv_backend"
|
||||
#define CV_TEST_TAG_DNN_SKIP_HALIDE "dnn_skip_halide"
|
||||
#define CV_TEST_TAG_DNN_SKIP_CPU "dnn_skip_cpu"
|
||||
#define CV_TEST_TAG_DNN_SKIP_CPU_FP16 "dnn_skip_cpu_fp16"
|
||||
#define CV_TEST_TAG_DNN_SKIP_OPENCL "dnn_skip_ocl"
|
||||
@ -137,7 +136,7 @@ bool validateVPUType();
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine = true,
|
||||
bool withHalide = false,
|
||||
bool obsolete_withHalide = false, // this is kept for compatibility
|
||||
bool withCpuOCV = true,
|
||||
bool withVkCom = true,
|
||||
bool withCUDA = true,
|
||||
|
@ -22,7 +22,6 @@ void PrintTo(const cv::dnn::Backend& v, std::ostream* os)
|
||||
{
|
||||
switch (v) {
|
||||
case DNN_BACKEND_DEFAULT: *os << "DEFAULT"; return;
|
||||
case DNN_BACKEND_HALIDE: *os << "HALIDE"; return;
|
||||
case DNN_BACKEND_INFERENCE_ENGINE: *os << "DLIE*"; return;
|
||||
case DNN_BACKEND_VKCOM: *os << "VKCOM"; return;
|
||||
case DNN_BACKEND_OPENCV: *os << "OCV"; return;
|
||||
@ -248,7 +247,7 @@ void readFileContent(const std::string& filename, CV_OUT std::vector<char>& cont
|
||||
|
||||
testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTargets(
|
||||
bool withInferenceEngine /*= true*/,
|
||||
bool withHalide /*= false*/,
|
||||
bool obsolete_withHalide /*= false*/,
|
||||
bool withCpuOCV /*= true*/,
|
||||
bool withVkCom /*= true*/,
|
||||
bool withCUDA /*= true*/,
|
||||
@ -261,12 +260,6 @@ testing::internal::ParamGenerator< tuple<Backend, Target> > dnnBackendsAndTarget
|
||||
|
||||
std::vector< tuple<Backend, Target> > targets;
|
||||
std::vector< Target > available;
|
||||
if (withHalide)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_HALIDE);
|
||||
for (std::vector< Target >::const_iterator i = available.begin(); i != available.end(); ++i)
|
||||
targets.push_back(make_tuple(DNN_BACKEND_HALIDE, *i));
|
||||
}
|
||||
if (withInferenceEngine)
|
||||
{
|
||||
available = getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019);
|
||||
@ -443,11 +436,6 @@ void initDNNTests()
|
||||
CV_TEST_TAG_DNN_SKIP_CPU, CV_TEST_TAG_DNN_SKIP_CPU_FP16,
|
||||
CV_TEST_TAG_DNN_SKIP_OPENCL, CV_TEST_TAG_DNN_SKIP_OPENCL_FP16
|
||||
);
|
||||
#if defined(HAVE_HALIDE)
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_HALIDE
|
||||
);
|
||||
#endif
|
||||
#if defined(INF_ENGINE_RELEASE)
|
||||
registerGlobalSkipTag(
|
||||
CV_TEST_TAG_DNN_SKIP_IE,
|
||||
|
@ -2423,7 +2423,12 @@ public:
|
||||
|
||||
static testing::internal::ParamGenerator<tuple<Backend, Target> > dnnBackendsAndTargetsForFusionTests()
|
||||
{
|
||||
return dnnBackendsAndTargets(false, false, true, false, true, false); // OCV OpenCL + OCV CPU + CUDA
|
||||
return dnnBackendsAndTargets(/* withInferenceEngine = */ false,
|
||||
/* obsolete_withHalide = */ false,
|
||||
/* withCpuOCV = */ true,
|
||||
/* withVkCom = */ false,
|
||||
/* withCUDA = */ true,
|
||||
/* withNgraph = */false); // OCV OpenCL + OCV CPU + CUDA
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -941,9 +941,6 @@ public:
|
||||
static std::set<std::string> opencl_fp16_deny_list;
|
||||
static std::set<std::string> opencl_deny_list;
|
||||
static std::set<std::string> cpu_deny_list;
|
||||
#ifdef HAVE_HALIDE
|
||||
static std::set<std::string> halide_deny_list;
|
||||
#endif
|
||||
#ifdef HAVE_VULKAN
|
||||
static std::set<std::string> vulkan_deny_list;
|
||||
#endif
|
||||
@ -1018,12 +1015,6 @@ public:
|
||||
#include "test_onnx_conformance_layer_filter_opencv_cpu_denylist.inl.hpp"
|
||||
};
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
halide_deny_list = {
|
||||
#include "test_onnx_conformance_layer_filter__halide_denylist.inl.hpp"
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
vulkan_deny_list = {
|
||||
#include "test_onnx_conformance_layer_filter__vulkan_denylist.inl.hpp"
|
||||
@ -1045,9 +1036,6 @@ std::set<std::string> Test_ONNX_conformance::opencv_deny_list;
|
||||
std::set<std::string> Test_ONNX_conformance::opencl_fp16_deny_list;
|
||||
std::set<std::string> Test_ONNX_conformance::opencl_deny_list;
|
||||
std::set<std::string> Test_ONNX_conformance::cpu_deny_list;
|
||||
#ifdef HAVE_HALIDE
|
||||
std::set<std::string> Test_ONNX_conformance::halide_deny_list;
|
||||
#endif
|
||||
#ifdef HAVE_VULKAN
|
||||
std::set<std::string> Test_ONNX_conformance::vulkan_deny_list;
|
||||
#endif
|
||||
@ -1094,15 +1082,6 @@ TEST_P(Test_ONNX_conformance, Layer_Test)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_CPU, CV_TEST_TAG_DNN_SKIP_OPENCV_BACKEND, CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_HALIDE
|
||||
else if (backend == DNN_BACKEND_HALIDE)
|
||||
{
|
||||
if (halide_deny_list.find(name) != halide_deny_list.end())
|
||||
{
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_HALIDE, CV_TEST_TAG_DNN_SKIP_ONNX_CONFORMANCE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INF_ENGINE
|
||||
else if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH)
|
||||
{
|
||||
@ -1252,7 +1231,7 @@ TEST_P(Test_ONNX_conformance, Layer_Test)
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Test_ONNX_conformance,
|
||||
testing::Combine(
|
||||
testing::ValuesIn(testConformanceConfig),
|
||||
dnnBackendsAndTargets(/*withInferenceEngine=*/true, /*withHalide=*/true)
|
||||
dnnBackendsAndTargets(/* withInferenceEngine = */ true)
|
||||
),
|
||||
printOnnxConfParams
|
||||
);
|
||||
|
@ -1,110 +0,0 @@
|
||||
"test_abs",
|
||||
"test_add",
|
||||
"test_add_bcast",
|
||||
"test_add_uint8",
|
||||
"test_argmax_default_axis_example",
|
||||
"test_argmax_default_axis_example_select_last_index",
|
||||
"test_argmax_default_axis_random",
|
||||
"test_argmax_default_axis_random_select_last_index",
|
||||
"test_argmax_keepdims_example",
|
||||
"test_argmax_keepdims_example_select_last_index",
|
||||
"test_argmax_keepdims_random",
|
||||
"test_argmax_keepdims_random_select_last_index",
|
||||
"test_argmax_negative_axis_keepdims_example",
|
||||
"test_argmax_negative_axis_keepdims_example_select_last_index",
|
||||
"test_argmax_negative_axis_keepdims_random",
|
||||
"test_argmax_negative_axis_keepdims_random_select_last_index",
|
||||
"test_argmax_no_keepdims_example",
|
||||
"test_argmax_no_keepdims_example_select_last_index",
|
||||
"test_argmax_no_keepdims_random",
|
||||
"test_argmax_no_keepdims_random_select_last_index",
|
||||
"test_argmin_default_axis_example",
|
||||
"test_argmin_default_axis_example_select_last_index",
|
||||
"test_argmin_default_axis_random",
|
||||
"test_argmin_default_axis_random_select_last_index",
|
||||
"test_argmin_keepdims_example",
|
||||
"test_argmin_keepdims_example_select_last_index",
|
||||
"test_argmin_keepdims_random",
|
||||
"test_argmin_keepdims_random_select_last_index",
|
||||
"test_argmin_negative_axis_keepdims_example",
|
||||
"test_argmin_negative_axis_keepdims_example_select_last_index",
|
||||
"test_argmin_negative_axis_keepdims_random",
|
||||
"test_argmin_negative_axis_keepdims_random_select_last_index",
|
||||
"test_argmin_no_keepdims_example",
|
||||
"test_argmin_no_keepdims_example_select_last_index",
|
||||
"test_argmin_no_keepdims_random",
|
||||
"test_argmin_no_keepdims_random_select_last_index",
|
||||
"test_averagepool_2d_ceil",
|
||||
"test_averagepool_2d_pads_count_include_pad",
|
||||
"test_averagepool_2d_precomputed_pads_count_include_pad",
|
||||
"test_averagepool_2d_precomputed_strides",
|
||||
"test_averagepool_2d_same_lower",
|
||||
"test_averagepool_2d_same_upper",
|
||||
"test_cast_FLOAT_to_STRING",
|
||||
"test_cast_STRING_to_FLOAT",
|
||||
"test_castlike_FLOAT_to_STRING_expanded",
|
||||
"test_castlike_STRING_to_FLOAT_expanded",
|
||||
"test_ceil",
|
||||
"test_concat_1d_axis_negative_1",
|
||||
"test_concat_3d_axis_1",
|
||||
"test_div",
|
||||
"test_div_bcast",
|
||||
"test_div_uint8",
|
||||
"test_elu",
|
||||
"test_elu_default",
|
||||
"test_exp",
|
||||
"test_floor",
|
||||
"test_leakyrelu",
|
||||
"test_leakyrelu_default",
|
||||
"test_log",
|
||||
"test_logsoftmax_axis_1",
|
||||
"test_logsoftmax_axis_1_expanded",
|
||||
"test_logsoftmax_default_axis",
|
||||
"test_logsoftmax_example_1",
|
||||
"test_logsoftmax_large_number",
|
||||
"test_matmul_2d",
|
||||
"test_matmul_3d",
|
||||
"test_matmul_4d",
|
||||
"test_maxpool_2d_dilations",
|
||||
"test_maxpool_2d_same_lower",
|
||||
"test_maxpool_2d_uint8",
|
||||
"test_maxpool_with_argmax_2d_precomputed_pads",
|
||||
"test_maxpool_with_argmax_2d_precomputed_strides",
|
||||
"test_maxunpool_export_with_output_shape",
|
||||
"test_mul",
|
||||
"test_mul_bcast",
|
||||
"test_mul_uint8",
|
||||
"test_neg",
|
||||
"test_reduce_max_default_axes_keepdim_example",
|
||||
"test_reduce_max_default_axes_keepdims_random",
|
||||
"test_reduce_max_do_not_keepdims_example",
|
||||
"test_reduce_max_do_not_keepdims_random",
|
||||
"test_reduce_max_keepdims_example",
|
||||
"test_reduce_max_keepdims_random",
|
||||
"test_reduce_max_negative_axes_keepdims_example",
|
||||
"test_reduce_max_negative_axes_keepdims_random",
|
||||
"test_relu",
|
||||
"test_sigmoid",
|
||||
"test_softmax_axis_1",
|
||||
"test_softmax_axis_1_expanded",
|
||||
"test_softmax_default_axis",
|
||||
"test_softmax_large_number",
|
||||
"test_sqrt",
|
||||
"test_sub",
|
||||
"test_sub_bcast",
|
||||
"test_sub_uint8",
|
||||
"test_tanh",
|
||||
"test_upsample_nearest",
|
||||
"test_scatter_elements_with_axis",
|
||||
"test_scatter_elements_with_duplicate_indices",
|
||||
"test_scatter_elements_with_negative_indices",
|
||||
"test_scatter_elements_with_reduction_max",
|
||||
"test_scatter_elements_with_reduction_min",
|
||||
"test_scatter_elements_without_axis",
|
||||
"test_scatter_with_axis",
|
||||
"test_scatter_without_axis",
|
||||
"test_scatternd",
|
||||
"test_scatternd_add",
|
||||
"test_scatternd_max",
|
||||
"test_scatternd_min",
|
||||
"test_scatternd_multiply",
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
std::string keys =
|
||||
std::string param_keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ @alias | | An alias name of model to extract preprocessing parameters from models.yml file. }"
|
||||
"{ zoo | models.yml | An optional path to file with preprocessing parameters }"
|
||||
@ -19,23 +19,26 @@ std::string keys =
|
||||
"{ crop | false | Preprocess input image by center cropping.}"
|
||||
"{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }"
|
||||
"{ needSoftmax | false | Use Softmax to post-process the output of the net.}"
|
||||
"{ classes | | Optional path to a text file with names of classes. }"
|
||||
"{ classes | | Optional path to a text file with names of classes. }";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA, "
|
||||
"6: WebNN }"
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA, "
|
||||
"%d: WebNN }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA, cv::dnn::DNN_BACKEND_WEBNN);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }";
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
using namespace cv;
|
||||
using namespace dnn;
|
||||
|
@ -6,7 +6,7 @@ from common import *
|
||||
|
||||
|
||||
def get_args_parser(func_args):
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE,
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE,
|
||||
cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA)
|
||||
targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD,
|
||||
cv.dnn.DNN_TARGET_HDDL, cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16)
|
||||
@ -30,7 +30,6 @@ def get_args_parser(func_args):
|
||||
parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int,
|
||||
help="Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
|
@ -17,28 +17,29 @@
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
const char *keys =
|
||||
std::string param_keys =
|
||||
"{ help h | | Print help message }"
|
||||
"{ input i | | Full path to input video folder, the specific camera index. (empty for camera 0) }"
|
||||
"{ net | dasiamrpn_model.onnx | Path to onnx model of net}"
|
||||
"{ kernel_cls1 | dasiamrpn_kernel_cls1.onnx | Path to onnx model of kernel_r1 }"
|
||||
"{ kernel_r1 | dasiamrpn_kernel_r1.onnx | Path to onnx model of kernel_cls1 }"
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA },"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }"
|
||||
;
|
||||
"{ kernel_r1 | dasiamrpn_kernel_r1.onnx | Path to onnx model of kernel_cls1 }";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
static
|
||||
int run(int argc, char** argv)
|
||||
|
@ -70,26 +70,28 @@ static Mat parse_human(const Mat &image, const std::string &model, int backend=d
|
||||
|
||||
int main(int argc, char**argv)
|
||||
{
|
||||
CommandLineParser parser(argc,argv,
|
||||
std::string param_keys =
|
||||
"{help h | | show help screen / args}"
|
||||
"{image i | | person image to process }"
|
||||
"{model m |lip_jppnet_384.pb| network model}"
|
||||
"{backend b | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA }"
|
||||
"{target t | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }"
|
||||
);
|
||||
"{model m |lip_jppnet_384.pb| network model}";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
CommandLineParser parser(argc, argv, keys);
|
||||
if (argc == 1 || parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
|
@ -15,27 +15,28 @@
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
const char *keys =
|
||||
std::string param_keys =
|
||||
"{ help h | | Print help message }"
|
||||
"{ input i | | Full path to input video folder, the specific camera index. (empty for camera 0) }"
|
||||
"{ backbone | backbone.onnx | Path to onnx model of backbone.onnx}"
|
||||
"{ headneck | headneck.onnx | Path to onnx model of headneck.onnx }"
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA },"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }"
|
||||
;
|
||||
"{ headneck | headneck.onnx | Path to onnx model of headneck.onnx }";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
static
|
||||
int run(int argc, char** argv)
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
std::string keys =
|
||||
std::string param_keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ @alias | | An alias name of model to extract preprocessing parameters from models.yml file. }"
|
||||
"{ zoo | models.yml | An optional path to file with preprocessing parameters }"
|
||||
@ -27,23 +27,25 @@ std::string keys =
|
||||
"{ classes | | Optional path to a text file with names of classes to label detected objects. }"
|
||||
"{ thr | .5 | Confidence threshold. }"
|
||||
"{ nms | .4 | Non-maximum suppression threshold. }"
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA }"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }"
|
||||
"{ async | 0 | Number of asynchronous forwards at the same time. "
|
||||
"Choose 0 for synchronous mode }";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
using namespace cv;
|
||||
using namespace dnn;
|
||||
|
@ -11,7 +11,7 @@ from tf_text_graph_common import readTextMessage
|
||||
from tf_text_graph_ssd import createSSDGraph
|
||||
from tf_text_graph_faster_rcnn import createFasterRCNNGraph
|
||||
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA)
|
||||
targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL,
|
||||
cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16)
|
||||
@ -32,7 +32,6 @@ parser.add_argument('--nms', type=float, default=0.4, help='Non-maximum suppress
|
||||
parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int,
|
||||
help="Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
|
@ -22,7 +22,7 @@
|
||||
using namespace cv;
|
||||
using namespace cv::dnn;
|
||||
|
||||
const char* keys =
|
||||
std::string param_keys =
|
||||
"{help h | | show help message}"
|
||||
"{model m | | network model}"
|
||||
"{query_list q | | list of query images}"
|
||||
@ -31,21 +31,24 @@ const char* keys =
|
||||
"{resize_h | 256 | resize input to specific height.}"
|
||||
"{resize_w | 128 | resize input to specific width.}"
|
||||
"{topk k | 5 | number of gallery images showed in visualization}"
|
||||
"{output_dir | | path for visualization(it should be existed)}"
|
||||
"{backend b | 0 | choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA }"
|
||||
"{target t | 0 | choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }";
|
||||
"{output_dir | | path for visualization(it should be existed)}";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
namespace cv{
|
||||
namespace reid{
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
std::string keys =
|
||||
std::string param_keys =
|
||||
"{ help h | | Print help message. }"
|
||||
"{ @alias | | An alias name of model to extract preprocessing parameters from models.yml file. }"
|
||||
"{ zoo | models.yml | An optional path to file with preprocessing parameters }"
|
||||
@ -16,22 +16,24 @@ std::string keys =
|
||||
"{ framework f | | Optional name of an origin framework of the model. Detect it automatically if it does not set. }"
|
||||
"{ classes | | Optional path to a text file with names of classes. }"
|
||||
"{ colors | | Optional path to a text file with colors for an every class. "
|
||||
"An every color is represented with three values from 0 to 255 in BGR channels order. }"
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"0: automatically (by default), "
|
||||
"1: Halide language (http://halide-lang.org/), "
|
||||
"2: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"3: OpenCV implementation, "
|
||||
"4: VKCOM, "
|
||||
"5: CUDA }"
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"0: CPU target (by default), "
|
||||
"1: OpenCL, "
|
||||
"2: OpenCL fp16 (half-float precision), "
|
||||
"3: VPU, "
|
||||
"4: Vulkan, "
|
||||
"6: CUDA, "
|
||||
"7: CUDA fp16 (half-float preprocess) }";
|
||||
"An every color is represented with three values from 0 to 255 in BGR channels order. }";
|
||||
std::string backend_keys = cv::format(
|
||||
"{ backend | 0 | Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
"%d: CUDA }", cv::dnn::DNN_BACKEND_DEFAULT, cv::dnn::DNN_BACKEND_INFERENCE_ENGINE, cv::dnn::DNN_BACKEND_OPENCV, cv::dnn::DNN_BACKEND_VKCOM, cv::dnn::DNN_BACKEND_CUDA);
|
||||
std::string target_keys = cv::format(
|
||||
"{ target | 0 | Choose one of target computation devices: "
|
||||
"%d: CPU target (by default), "
|
||||
"%d: OpenCL, "
|
||||
"%d: OpenCL fp16 (half-float precision), "
|
||||
"%d: VPU, "
|
||||
"%d: Vulkan, "
|
||||
"%d: CUDA, "
|
||||
"%d: CUDA fp16 (half-float preprocess) }", cv::dnn::DNN_TARGET_CPU, cv::dnn::DNN_TARGET_OPENCL, cv::dnn::DNN_TARGET_OPENCL_FP16, cv::dnn::DNN_TARGET_MYRIAD, cv::dnn::DNN_TARGET_VULKAN, cv::dnn::DNN_TARGET_CUDA, cv::dnn::DNN_TARGET_CUDA_FP16);
|
||||
std::string keys = param_keys + backend_keys + target_keys;
|
||||
|
||||
using namespace cv;
|
||||
using namespace dnn;
|
||||
|
@ -5,7 +5,7 @@ import sys
|
||||
|
||||
from common import *
|
||||
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA)
|
||||
targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL,
|
||||
cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16)
|
||||
@ -22,7 +22,6 @@ parser.add_argument('--colors', help='Optional path to a text file with colors f
|
||||
parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int,
|
||||
help="Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
|
@ -327,7 +327,7 @@ def main():
|
||||
""" Sample SiamRPN Tracker
|
||||
"""
|
||||
# Computation backends supported by layers
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA)
|
||||
# Target Devices for computation
|
||||
targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD,
|
||||
@ -342,7 +342,6 @@ def main():
|
||||
parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int,
|
||||
help="Select a computation backend: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Halide, "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV Implementation, "
|
||||
"%d: VKCOM, "
|
||||
|
@ -16,7 +16,7 @@ from numpy import linalg
|
||||
from common import findFile
|
||||
from human_parsing import parse_human
|
||||
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_HALIDE, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
backends = (cv.dnn.DNN_BACKEND_DEFAULT, cv.dnn.DNN_BACKEND_INFERENCE_ENGINE, cv.dnn.DNN_BACKEND_OPENCV,
|
||||
cv.dnn.DNN_BACKEND_VKCOM, cv.dnn.DNN_BACKEND_CUDA)
|
||||
targets = (cv.dnn.DNN_TARGET_CPU, cv.dnn.DNN_TARGET_OPENCL, cv.dnn.DNN_TARGET_OPENCL_FP16, cv.dnn.DNN_TARGET_MYRIAD, cv.dnn.DNN_TARGET_HDDL,
|
||||
cv.dnn.DNN_TARGET_VULKAN, cv.dnn.DNN_TARGET_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16)
|
||||
@ -33,7 +33,6 @@ parser.add_argument('--openpose_model', default='openpose_pose_coco.caffemodel',
|
||||
parser.add_argument('--backend', choices=backends, default=cv.dnn.DNN_BACKEND_DEFAULT, type=int,
|
||||
help="Choose one of computation backends: "
|
||||
"%d: automatically (by default), "
|
||||
"%d: Halide language (http://halide-lang.org/), "
|
||||
"%d: Intel's Deep Learning Inference Engine (https://software.intel.com/openvino-toolkit), "
|
||||
"%d: OpenCV implementation, "
|
||||
"%d: VKCOM, "
|
||||
|
Loading…
Reference in New Issue
Block a user