mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04: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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user