1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

speed up vulkan dnn, and support ios and apple m1 chip. (#23349)

This commit is contained in:
Zihao Mu
2023-05-19 01:02:27 +08:00
committed by GitHub
parent 435ccfdd51
commit 5025f29378
117 changed files with 16867 additions and 9436 deletions
+38 -56
View File
@@ -134,11 +134,11 @@ public:
CV_Assert(inputs[0].dims == outputs[0].dims);
if (weightShape.dims() == 3)
{
kernel_size.assign(1, kernel_size[0]);
strides.assign(1, strides[0]);
dilations.assign(1, dilations[0]);
pads_begin.assign(1, pads_begin[0]);
pads_end.assign(1, pads_end[0]);
kernel_size.resize(1, kernel_size[0]);
strides.resize(1, strides[0]);
dilations.resize(1, dilations[0]);
pads_begin.resize(1, pads_begin[0]);
pads_end.resize(1, pads_end[0]);
}
CV_Assert(weightShape.dims() == kernel_size.size() + 2);
for (int i = 0; i < kernel_size.size(); i++) {
@@ -665,68 +665,50 @@ public:
biasvec[outCn] = biasvec[outCn+1] = biasvec[outCn-1];
}
virtual Ptr<BackendNode> initVkCom(const std::vector<Ptr<BackendWrapper> > &inputs) CV_OVERRIDE
virtual Ptr<BackendNode> initVkCom(const std::vector<Ptr<BackendWrapper> > &inputs, std::vector<Ptr<BackendWrapper> > &outputs) CV_OVERRIDE
{
#ifdef HAVE_VULKAN
CV_Assert(!blobs.empty());
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];
int activationType = transFusedActivType(activ);
// TODO: support group > 1
if (group != 1)
CV_Assert(inputs.size() == 1 && outputs.size() == 1);
Ptr<VkComBackendWrapper> inputWrap = inputs[0].dynamicCast<VkComBackendWrapper>();
Ptr<VkComBackendWrapper> outputWrap = outputs[0].dynamicCast<VkComBackendWrapper>();
CV_Assert(inputWrap && outputWrap);
MatShape inpShape = shape(*inputWrap->getMat());
MatShape outShape = shape(*outputWrap->getMat());
CV_Assert(inpShape.size() == 4 && inpShape.size() == outShape.size());
if (activationType == -1)
{
CV_LOG_WARNING(NULL, "Unsupported fused Active type in Conv layer!!!");
return Ptr<BackendNode>();
}
const int inpGroupCn = blobs[0].size[1];
int ngroups = inpShape[1] / inpGroupCn;
CV_Assert(outShape[1] % ngroups == 0);
if (ngroups != 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;
Mat weightVK;
if (fusedWeights)
{
Mat wm;
weightsMat.copyTo(wm); // to handle the case of isContinuous() == false
wm = wm.reshape(1, blobs[0].dims, blobs[0].size);
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(wm)));
weightsMat.copyTo(weightVK); // to handle the case of isContinuous() == false
weightVK = weightVK.reshape(1, blobs[0].dims, blobs[0].size);
}
else
{
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(blobs[0])));
}
weightVK = blobs[0];
if (has_bias)
{
Mat biasesMat({out_channel}, CV_32F, &biasvec[0]);
blobsWrapper.push_back(Ptr<BackendWrapper>(new VkComBackendWrapper(biasesMat)));
}
CV_Assert(weightVK.isContinuous());
CV_Assert(pads_begin.size() == 2);
CV_Assert(fusedAdd == false && "Vulkan Backend can not support the Conv_Add optimization.");
Ptr<vkcom::OpBase> op(new vkcom::OpConv(weightVK, biasvec, activationType, ngroups, outShape[1], inpShape[1],
kernel.height, kernel.width, stride.height, stride.width,
dilation.height, dilation.width, pads_begin[1], pads_begin[0]));
return Ptr<BackendNode>(new VkComBackendNode(inputs, op, blobsWrapper));
return Ptr<BackendNode>(new VkComBackendNode(inputs, op, outputs));
#endif // HAVE_VULKAN
return Ptr<BackendNode>();
}