mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
Merge pull request #12703 from wzw-intel:vkcom
* dnn: Add a Vulkan based backend This commit adds a new backend "DNN_BACKEND_VKCOM" and a new target "DNN_TARGET_VULKAN". VKCOM means vulkan based computation library. This backend uses Vulkan API and SPIR-V shaders to do the inference computation for layers. The layer types that implemented in DNN_BACKEND_VKCOM include: Conv, Concat, ReLU, LRN, PriorBox, Softmax, MaxPooling, AvePooling, Permute This is just a beginning work for Vulkan in OpenCV DNN, more layer types will be supported and performance tuning is on the way. Signed-off-by: Wu Zhiwen <zhiwen.wu@intel.com> * dnn/vulkan: Add FindVulkan.cmake to detect Vulkan SDK In order to build dnn with Vulkan support, need installing Vulkan SDK and setting environment variable "VULKAN_SDK" and add "-DWITH_VULKAN=ON" to cmake command. You can download Vulkan SDK from: https://vulkan.lunarg.com/sdk/home#linux For how to install, see https://vulkan.lunarg.com/doc/sdk/latest/linux/getting_started.html https://vulkan.lunarg.com/doc/sdk/latest/windows/getting_started.html https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html respectively for linux, windows and mac. To run the vulkan backend, also need installing mesa driver. On Ubuntu, use this command 'sudo apt-get install mesa-vulkan-drivers' To test, use command '$BUILD_DIR/bin/opencv_test_dnn --gtest_filter=*VkCom*' Signed-off-by: Wu Zhiwen <zhiwen.wu@intel.com> * dnn/Vulkan: dynamically load Vulkan runtime No compile-time dependency on Vulkan library. If Vulkan runtime is unavailable, fallback to CPU path. Use environment "OPENCL_VULKAN_RUNTIME" to specify path to your own vulkan runtime library. Signed-off-by: Wu Zhiwen <zhiwen.wu@intel.com> * dnn/Vulkan: Add a python script to compile GLSL shaders to SPIR-V shaders The SPIR-V shaders are in format of text-based 32-bit hexadecimal numbers, and inserted into .cpp files as unsigned int32 array. * dnn/Vulkan: Put Vulkan headers into 3rdparty directory and some other fixes Vulkan header files are copied from https://github.com/KhronosGroup/Vulkan-Docs/tree/master/include/vulkan to 3rdparty/include Fix the Copyright declaration issue. Refine OpenCVDetectVulkan.cmake * dnn/Vulkan: Add vulkan backend tests into existing ones. Also fixed some test failures. - Don't use bool variable as uniform for shader - Fix dispathed group number beyond max issue - Bypass "group > 1" convolution. This should be support in future. * dnn/Vulkan: Fix multiple initialization in one thread.
This commit is contained in:
committed by
Alexander Alekhin
parent
220b278575
commit
6e3ea8b49d
@@ -44,6 +44,7 @@
|
||||
#include "layers_common.hpp"
|
||||
#include "../op_halide.hpp"
|
||||
#include "../op_inf_engine.hpp"
|
||||
#include "../op_vkcom.hpp"
|
||||
#include "opencv2/core/hal/hal.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
#include <iostream>
|
||||
@@ -222,7 +223,9 @@ public:
|
||||
if (backendId == DNN_BACKEND_INFERENCE_ENGINE)
|
||||
return preferableTarget != DNN_TARGET_MYRIAD || dilation.width == dilation.height;
|
||||
else
|
||||
return backendId == DNN_BACKEND_OPENCV || backendId == DNN_BACKEND_HALIDE;
|
||||
return backendId == DNN_BACKEND_OPENCV ||
|
||||
backendId == DNN_BACKEND_HALIDE ||
|
||||
backendId == DNN_BACKEND_VKCOM && haveVulkan();
|
||||
}
|
||||
|
||||
bool getMemoryShapes(const std::vector<MatShape> &inputs,
|
||||
@@ -384,6 +387,73 @@ public:
|
||||
biasvec[outCn] = biasvec[outCn+1] = biasvec[outCn-1];
|
||||
}
|
||||
|
||||
virtual Ptr<BackendNode> initVkCom(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_VULKAN
|
||||
int out_channel = blobs[0].size[0];
|
||||
bool has_bias = hasBias() || fusedBias;
|
||||
int filter_size[2] = {kernel.height, kernel.width};
|
||||
int pad_size[2] = {pad.height, pad.width};
|
||||
int stride_size[2] = {stride.height, stride.width};
|
||||
int dilation_size[2] = {dilation.height, dilation.width};
|
||||
int activation = 0;
|
||||
vkcom::Tensor input_tensor = VkComTensor(inputs[0]);
|
||||
int in_channel = input_tensor.dimSize(1);
|
||||
int group = in_channel / blobs[0].size[1];
|
||||
|
||||
// TODO: support group > 1
|
||||
if (group != 1)
|
||||
return Ptr<BackendNode>();
|
||||
|
||||
int padding_mode;
|
||||
if (padMode.empty())
|
||||
{
|
||||
padding_mode = vkcom::kPaddingModeCaffe;
|
||||
}
|
||||
else if (padMode == "VALID")
|
||||
{
|
||||
padding_mode = vkcom::kPaddingModeValid;
|
||||
}
|
||||
else if (padMode == "SAME")
|
||||
{
|
||||
padding_mode = vkcom::kPaddingModeSame;
|
||||
}
|
||||
else
|
||||
CV_Error(Error::StsError, "Unsupported padding mode " + padMode);
|
||||
|
||||
std::shared_ptr<vkcom::OpBase> op(new vkcom::OpConv(out_channel, has_bias,
|
||||
filter_size, pad_size,
|
||||
stride_size, dilation_size,
|
||||
activation, group,
|
||||
padding_mode));
|
||||
|
||||
std::vector<Ptr<BackendWrapper> > blobsWrapper;
|
||||
|
||||
if (newWeightAndBias)
|
||||
{
|
||||
Mat wm;
|
||||
weightsMat.copyTo(wm); // to handle the case of isContinuous() == false
|
||||
wm.reshape(1, blobs[0].dims, blobs[0].size);
|
||||
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(wm)));
|
||||
}
|
||||
else
|
||||
{
|
||||
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(blobs[0])));
|
||||
}
|
||||
|
||||
if (has_bias)
|
||||
{
|
||||
Mat biasesMat({out_channel}, CV_32F, &biasvec[0]);
|
||||
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(biasesMat)));
|
||||
}
|
||||
|
||||
return Ptr<BackendNode>(new VkComBackendNode(inputs, op, blobsWrapper));
|
||||
#endif // HAVE_VULKAN
|
||||
return Ptr<BackendNode>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual Ptr<BackendNode> initHalide(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
|
||||
{
|
||||
#ifdef HAVE_HALIDE
|
||||
|
||||
Reference in New Issue
Block a user