提交 c394847c 编写于 作者: A Anna Khakimova

GAPI Fluid: Dynamic window size

上级 055ffc04
...@@ -68,19 +68,21 @@ public: ...@@ -68,19 +68,21 @@ public:
// This function is a generic "getBorder" callback (extracts border-related data from kernel's input parameters) // This function is a generic "getBorder" callback (extracts border-related data from kernel's input parameters)
using B = std::function<gapi::fluid::BorderOpt(const GMetaArgs&, const GArgs&)>; using B = std::function<gapi::fluid::BorderOpt(const GMetaArgs&, const GArgs&)>;
// This function is a generic "getWindow" callback (extracts window-related data from kernel's input parameters)
using GW = std::function<int(const GMetaArgs&, const GArgs&)>;
// FIXME: move implementations out of header file // FIXME: move implementations out of header file
GFluidKernel() {} GFluidKernel() {}
GFluidKernel(int w, Kind k, int l, bool scratch, const F& f, const IS &is, const RS &rs, const B& b) GFluidKernel(Kind k, int l, bool scratch, const F& f, const IS &is, const RS &rs, const B& b, const GW& win)
: m_window(w) : m_kind(k)
, m_kind(k)
, m_lpi(l) , m_lpi(l)
, m_scratch(scratch) , m_scratch(scratch)
, m_f(f) , m_f(f)
, m_is(is) , m_is(is)
, m_rs(rs) , m_rs(rs)
, m_b(b) {} , m_b(b)
, m_gw(win) {}
int m_window = -1;
Kind m_kind; Kind m_kind;
const int m_lpi = -1; const int m_lpi = -1;
const bool m_scratch = false; const bool m_scratch = false;
...@@ -89,6 +91,7 @@ public: ...@@ -89,6 +91,7 @@ public:
const IS m_is; const IS m_is;
const RS m_rs; const RS m_rs;
const B m_b; const B m_b;
const GW m_gw;
}; };
// FIXME!!! // FIXME!!!
...@@ -255,6 +258,67 @@ struct get_border_helper<false, Impl, Ins...> ...@@ -255,6 +258,67 @@ struct get_border_helper<false, Impl, Ins...>
} }
}; };
template<bool CallCustomGetWindow, typename, typename... Ins>
struct get_window_helper;
template<typename Impl, typename... Ins>
struct get_window_helper<true, Impl, Ins...>
{
template<int... IIs>
static int get_window_impl(const GMetaArgs &metas,
const cv::GArgs &in_args,
cv::detail::Seq<IIs...>)
{
return Impl::getWindow(cv::detail::get_in_meta<Ins>(metas, in_args, IIs)...);
}
static int help(const GMetaArgs &metas, const cv::GArgs &in_args)
{
return get_window_impl(metas, in_args, typename detail::MkSeq<sizeof...(Ins)>::type());
}
};
template<typename Impl, typename... Ins>
struct get_window_helper<false, Impl, Ins...>
{
static int help(const cv::GMetaArgs &,
const cv::GArgs &)
{
return Impl::Window;
}
};
template<typename C, typename T>
struct has_Window
{
private:
template<class U>
static constexpr auto Check(U*) -> typename std::is_same<decltype(U::Window), T>::type;
template<typename>
static constexpr std::false_type Check(...);
typedef decltype(Check<C>(0)) Result;
public:
static constexpr bool value = Result::value;
};
template<bool hasWindow, typename Impl>
struct callCustomGetBorder;
template<typename Impl>
struct callCustomGetBorder<true, Impl>
{
static constexpr bool value = (Impl::Window != 1);
};
template<typename Impl>
struct callCustomGetBorder<false, Impl>
{
static constexpr bool value = true;
};
template<typename, typename, typename, bool UseScratch> template<typename, typename, typename, bool UseScratch>
struct FluidCallHelper; struct FluidCallHelper;
...@@ -299,10 +363,17 @@ struct FluidCallHelper<Impl, std::tuple<Ins...>, std::tuple<Outs...>, UseScratch ...@@ -299,10 +363,17 @@ struct FluidCallHelper<Impl, std::tuple<Ins...>, std::tuple<Outs...>, UseScratch
static gapi::fluid::BorderOpt getBorder(const GMetaArgs &metas, const cv::GArgs &in_args) static gapi::fluid::BorderOpt getBorder(const GMetaArgs &metas, const cv::GArgs &in_args)
{ {
constexpr bool hasWindow = has_Window<Impl, const int>::value;
// User must provide "init" callback if Window != 1 // User must provide "init" callback if Window != 1
// TODO: move to constexpr if when we enable C++17 // TODO: move to constexpr if when we enable C++17
constexpr bool callCustomGetBorder = (Impl::Window != 1); return get_border_helper<callCustomGetBorder<hasWindow, Impl>::value, Impl, Ins...>::help(metas, in_args);
return get_border_helper<callCustomGetBorder, Impl, Ins...>::help(metas, in_args); }
static int getWindow(const GMetaArgs &metas, const cv::GArgs &in_args)
{
constexpr bool callCustomGetWindow = !(has_Window<Impl, const int>::value);
return get_window_helper<callCustomGetWindow, Impl, Ins...>::help(metas, in_args);
} }
}; };
} // namespace detail } // namespace detail
...@@ -322,9 +393,9 @@ public: ...@@ -322,9 +393,9 @@ public:
{ {
// FIXME: call() and getOutMeta() needs to be renamed so it is clear these // FIXME: call() and getOutMeta() needs to be renamed so it is clear these
// functions are internal wrappers, not user API // functions are internal wrappers, not user API
return GFluidKernel(Impl::Window, Impl::Kind, Impl::LPI, return GFluidKernel(Impl::Kind, Impl::LPI,
UseScratch, UseScratch,
&P::call, &P::init_scratch, &P::reset_scratch, &P::getBorder); &P::call, &P::init_scratch, &P::reset_scratch, &P::getBorder, &P::getWindow);
} }
static cv::gapi::GBackend backend() { return cv::gapi::fluid::backend(); } static cv::gapi::GBackend backend() { return cv::gapi::fluid::backend(); }
......
...@@ -69,7 +69,7 @@ namespace ...@@ -69,7 +69,7 @@ namespace
{ {
GFluidModel fm(graph); GFluidModel fm(graph);
auto fluid_impl = cv::util::any_cast<cv::GFluidKernel>(impl.opaque); auto fluid_impl = cv::util::any_cast<cv::GFluidKernel>(impl.opaque);
fm.metadata(op_node).set(cv::gimpl::FluidUnit{fluid_impl, {}, 0, {}, 0.0}); fm.metadata(op_node).set(cv::gimpl::FluidUnit{fluid_impl, {}, 0, -1, {}, 0.0});
} }
virtual EPtr compile(const ade::Graph &graph, virtual EPtr compile(const ade::Graph &graph,
...@@ -178,6 +178,12 @@ private: ...@@ -178,6 +178,12 @@ private:
virtual void setRatio(double) override { /* nothing */ } virtual void setRatio(double) override { /* nothing */ }
public: public:
using FluidAgent::FluidAgent; using FluidAgent::FluidAgent;
int m_window;
FluidFilterAgent(const ade::Graph &g, ade::NodeHandle nh)
: FluidAgent(g, nh)
, m_window(GConstFluidModel(g).metadata(nh).get<FluidUnit>().window)
{}
}; };
struct FluidResizeAgent : public FluidAgent struct FluidResizeAgent : public FluidAgent
...@@ -287,11 +293,11 @@ static int calcResizeWindow(int inH, int outH) ...@@ -287,11 +293,11 @@ static int calcResizeWindow(int inH, int outH)
} }
} }
static int maxLineConsumption(const cv::GFluidKernel& k, int inH, int outH, int lpi, std::size_t inPort) static int maxLineConsumption(const cv::GFluidKernel::Kind kind, int window, int inH, int outH, int lpi, std::size_t inPort)
{ {
switch (k.m_kind) switch (kind)
{ {
case cv::GFluidKernel::Kind::Filter: return k.m_window + lpi - 1; break; case cv::GFluidKernel::Kind::Filter: return window + lpi - 1; break;
case cv::GFluidKernel::Kind::Resize: case cv::GFluidKernel::Kind::Resize:
{ {
if (inH >= outH) if (inH >= outH)
...@@ -312,11 +318,11 @@ static int maxLineConsumption(const cv::GFluidKernel& k, int inH, int outH, int ...@@ -312,11 +318,11 @@ static int maxLineConsumption(const cv::GFluidKernel& k, int inH, int outH, int
} }
} }
static int borderSize(const cv::GFluidKernel& k) static int borderSize(const cv::GFluidKernel::Kind kind, int window)
{ {
switch (k.m_kind) switch (kind)
{ {
case cv::GFluidKernel::Kind::Filter: return (k.m_window - 1) / 2; break; case cv::GFluidKernel::Kind::Filter: return (window - 1) / 2; break;
// Resize never reads from border pixels // Resize never reads from border pixels
case cv::GFluidKernel::Kind::Resize: return 0; break; case cv::GFluidKernel::Kind::Resize: return 0; break;
case cv::GFluidKernel::Kind::NV12toRGB: return 0; break; case cv::GFluidKernel::Kind::NV12toRGB: return 0; break;
...@@ -406,13 +412,13 @@ std::pair<int,int> cv::gimpl::FluidUpscaleMapper::linesReadAndNextWindow(int out ...@@ -406,13 +412,13 @@ std::pair<int,int> cv::gimpl::FluidUpscaleMapper::linesReadAndNextWindow(int out
int cv::gimpl::FluidFilterAgent::firstWindow(std::size_t) const int cv::gimpl::FluidFilterAgent::firstWindow(std::size_t) const
{ {
int lpi = std::min(k.m_lpi, m_outputLines - m_producedLines); int lpi = std::min(k.m_lpi, m_outputLines - m_producedLines);
return k.m_window + lpi - 1; return m_window + lpi - 1;
} }
std::pair<int,int> cv::gimpl::FluidFilterAgent::linesReadAndnextWindow(std::size_t) const std::pair<int,int> cv::gimpl::FluidFilterAgent::linesReadAndnextWindow(std::size_t) const
{ {
int lpi = std::min(k.m_lpi, m_outputLines - m_producedLines - k.m_lpi); int lpi = std::min(k.m_lpi, m_outputLines - m_producedLines - k.m_lpi);
return std::make_pair(k.m_lpi, k.m_window - 1 + lpi); return std::make_pair(k.m_lpi, m_window - 1 + lpi);
} }
int cv::gimpl::FluidResizeAgent::firstWindow(std::size_t) const int cv::gimpl::FluidResizeAgent::firstWindow(std::size_t) const
...@@ -1016,14 +1022,14 @@ namespace ...@@ -1016,14 +1022,14 @@ namespace
if (d.shape == cv::GShape::GMAT) if (d.shape == cv::GShape::GMAT)
{ {
auto port = g.metadata(in_edge).get<Input>().port; auto port = g.metadata(in_edge).get<Input>().port;
fu.line_consumption[port] = maxLineConsumption(fu.k, in_h, out_h, fu.k.m_lpi, port); fu.line_consumption[port] = maxLineConsumption(fu.k.m_kind, fu.window, in_h, out_h, fu.k.m_lpi, port);
GModel::log(g, node, "Line consumption (port " + std::to_string(port) + "): " GModel::log(g, node, "Line consumption (port " + std::to_string(port) + "): "
+ std::to_string(fu.line_consumption[port])); + std::to_string(fu.line_consumption[port]));
} }
} }
fu.border_size = borderSize(fu.k); fu.border_size = borderSize(fu.k.m_kind, fu.window);
GModel::log(g, node, "Border size: " + std::to_string(fu.border_size)); GModel::log(g, node, "Border size: " + std::to_string(fu.border_size));
} }
} }
...@@ -1489,7 +1495,7 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx) ...@@ -1489,7 +1495,7 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx)
// FIXME: // FIXME:
// move to unpackKernel method // move to unpackKernel method
// when https://gitlab-icv.inn.intel.com/G-API/g-api/merge_requests/66 is merged // when https://gitlab-icv.inn.intel.com/G-API/g-api/merge_requests/66 is merged
ectx.addPass("exec", "init_fluid_unit_borders", [](ade::passes::PassContext &ctx) ectx.addPass("exec", "init_fluid_unit_windows_and_borders", [](ade::passes::PassContext &ctx)
{ {
GModel::Graph g(ctx.graph); GModel::Graph g(ctx.graph);
if (!GModel::isActive(g, cv::gapi::fluid::backend())) // FIXME: Rearchitect this! if (!GModel::isActive(g, cv::gapi::fluid::backend())) // FIXME: Rearchitect this!
...@@ -1505,9 +1511,13 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx) ...@@ -1505,9 +1511,13 @@ void GFluidBackendImpl::addBackendPasses(ade::ExecutionEngineSetupContext &ectx)
// FIXME: check that op has only one data node on input // FIXME: check that op has only one data node on input
auto &fu = fg.metadata(node).get<FluidUnit>(); auto &fu = fg.metadata(node).get<FluidUnit>();
const auto &op = g.metadata(node).get<Op>(); const auto &op = g.metadata(node).get<Op>();
auto inputMeta = GModel::collectInputMeta(fg, node);
// Trigger user-defined "getWindow" callback
fu.window = fu.k.m_gw(inputMeta, op.args);
// Trigger user-defined "getBorder" callback // Trigger user-defined "getBorder" callback
fu.border = fu.k.m_b(GModel::collectInputMeta(fg, node), op.args); fu.border = fu.k.m_b(inputMeta, op.args);
} }
} }
}); });
......
...@@ -27,6 +27,7 @@ struct FluidUnit ...@@ -27,6 +27,7 @@ struct FluidUnit
GFluidKernel k; GFluidKernel k;
gapi::fluid::BorderOpt border; gapi::fluid::BorderOpt border;
int border_size; int border_size;
int window;
std::vector<int> line_consumption; std::vector<int> line_consumption;
double ratio; double ratio;
}; };
......
...@@ -778,7 +778,6 @@ GAPI_FLUID_KERNEL(GFluidSepFilter, cv::gapi::imgproc::GSepFilter, true) ...@@ -778,7 +778,6 @@ GAPI_FLUID_KERNEL(GFluidSepFilter, cv::gapi::imgproc::GSepFilter, true)
GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true) GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true)
{ {
// TODO: support kernel height 3, 5, 7, 9, ... // TODO: support kernel height 3, 5, 7, 9, ...
static const int Window = 3;
static void run(const View & src, static void run(const View & src,
const cv::Size & ksize, const cv::Size & ksize,
...@@ -828,6 +827,7 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true) ...@@ -828,6 +827,7 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true)
const cv::Scalar & /* borderValue */, const cv::Scalar & /* borderValue */,
Buffer & scratch) Buffer & scratch)
{ {
GAPI_Assert(ksize.height == ksize.width);
int kxsize = ksize.width; int kxsize = ksize.width;
int kysize = ksize.height; int kysize = ksize.height;
...@@ -835,7 +835,7 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true) ...@@ -835,7 +835,7 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true)
int chan = in.chan; int chan = in.chan;
int buflen = kxsize + kysize + // x, y kernels int buflen = kxsize + kysize + // x, y kernels
width * chan * Window; // work buffers width * chan * ksize.height; // work buffers
cv::gapi::own::Size bufsize(buflen, 1); cv::gapi::own::Size bufsize(buflen, 1);
GMatDesc bufdesc = {CV_32F, 1, bufsize}; GMatDesc bufdesc = {CV_32F, 1, bufsize};
...@@ -876,6 +876,17 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true) ...@@ -876,6 +876,17 @@ GAPI_FLUID_KERNEL(GFluidGaussBlur, cv::gapi::imgproc::GGaussBlur, true)
{ {
return { borderType, borderValue}; return { borderType, borderValue};
} }
static int getWindow(const cv::GMatDesc& /* src */,
const cv::Size& ksize,
double /* sigmaX */,
double /* sigmaY */,
int /* borderType */,
const cv::Scalar& /* borderValue */)
{
GAPI_Assert(ksize.height == ksize.width);
return ksize.height;
}
}; };
//--------------------- //---------------------
...@@ -1688,8 +1699,8 @@ GAPI_FLUID_KERNEL(GFluidRGB2YUV422, cv::gapi::imgproc::GRGB2YUV422, false) ...@@ -1688,8 +1699,8 @@ GAPI_FLUID_KERNEL(GFluidRGB2YUV422, cv::gapi::imgproc::GRGB2YUV422, false)
static const int Window = 1; static const int Window = 1;
static const auto Kind = cv::GFluidKernel::Kind::Filter; static const auto Kind = cv::GFluidKernel::Kind::Filter;
static void run(const cv::gapi::fluid::View& in, static void run(const cv::gapi::fluid::View& in,
cv::gapi::fluid::Buffer& out) cv::gapi::fluid::Buffer& out)
{ {
const auto *src = in.InLine<uchar>(0); const auto *src = in.InLine<uchar>(0);
auto *dst = out.OutLine<uchar>(); auto *dst = out.OutLine<uchar>();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册