mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 00:03:03 +04:00
Merge pull request #19112 from rgarnov:rg/generic_copy_kernel
Generic copy kernel * Moved RMat wrapping of cv::Mats to StreamingInput * Generalized GCopy kernel * Generic GCopy kernel: applied review comments
This commit is contained in:
@@ -328,11 +328,6 @@ GMat crop(const GMat& src, const Rect& rect)
|
||||
return core::GCrop::on(src, rect);
|
||||
}
|
||||
|
||||
GMat copy(const GMat& src)
|
||||
{
|
||||
return core::GCopy::on(src);
|
||||
}
|
||||
|
||||
GMat concatHor(const GMat& src1, const GMat& src2)
|
||||
{
|
||||
return core::GConcatHor::on(src1, src2);
|
||||
|
||||
@@ -75,10 +75,6 @@ cv::GMat cv::gapi::streaming::desync(const cv::GMat &g) {
|
||||
// object will feed both branches of the streaming executable.
|
||||
}
|
||||
|
||||
cv::GFrame cv::gapi::streaming::copy(const cv::GFrame& in) {
|
||||
return cv::gapi::streaming::GCopy::on(in);
|
||||
}
|
||||
|
||||
cv::GMat cv::gapi::streaming::BGR(const cv::GFrame& in) {
|
||||
return cv::gapi::streaming::GBGR::on(in);
|
||||
}
|
||||
|
||||
@@ -510,14 +510,6 @@ GAPI_OCV_KERNEL(GCPUCrop, cv::gapi::core::GCrop)
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(GCPUCopy, cv::gapi::core::GCopy)
|
||||
{
|
||||
static void run(const cv::Mat& in, cv::Mat& out)
|
||||
{
|
||||
in.copyTo(out);
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCV_KERNEL(GCPUConcatHor, cv::gapi::core::GConcatHor)
|
||||
{
|
||||
static void run(const cv::Mat& in1, const cv::Mat& in2, cv::Mat& out)
|
||||
@@ -762,7 +754,6 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels()
|
||||
, GCPURemap
|
||||
, GCPUFlip
|
||||
, GCPUCrop
|
||||
, GCPUCopy
|
||||
, GCPUConcatHor
|
||||
, GCPUConcatVert
|
||||
, GCPULUT
|
||||
|
||||
@@ -2675,40 +2675,6 @@ GAPI_FLUID_KERNEL(GFluidSqrt, cv::gapi::core::GSqrt, false)
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_FLUID_KERNEL(GFluidCopy, cv::gapi::core::GCopy, false)
|
||||
{
|
||||
static const int Window = 1;
|
||||
|
||||
static void run(const View &src, Buffer &dst)
|
||||
{
|
||||
const auto *in = src.InLine<uchar>(0);
|
||||
auto *out = dst.OutLine<uchar>();
|
||||
|
||||
GAPI_DbgAssert(dst.length() == src.length());
|
||||
GAPI_DbgAssert(dst.meta().chan == src.meta().chan);
|
||||
GAPI_DbgAssert(dst.meta().depth == src.meta().depth);
|
||||
|
||||
int width = src.length();
|
||||
int elem_size = CV_ELEM_SIZE(CV_MAKETYPE(src.meta().depth, src.meta().chan));
|
||||
|
||||
int w = 0; // cycle counter
|
||||
|
||||
#if CV_SIMD128
|
||||
for (; w <= width*elem_size-16; w+=16)
|
||||
{
|
||||
v_uint8x16 a;
|
||||
a = v_load(&in[w]);
|
||||
v_store(&out[w], a);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; w < width*elem_size; w++)
|
||||
{
|
||||
out[w] = in[w];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace fliud
|
||||
} // namespace gapi
|
||||
} // namespace cv
|
||||
@@ -2768,7 +2734,6 @@ cv::gapi::GKernelPackage cv::gapi::core::fluid::kernels()
|
||||
,GFluidInRange
|
||||
,GFluidResize
|
||||
,GFluidSqrt
|
||||
,GFluidCopy
|
||||
#if 0
|
||||
,GFluidMean -- not fluid
|
||||
,GFluidSum -- not fluid
|
||||
|
||||
@@ -490,14 +490,6 @@ GAPI_OCL_KERNEL(GOCLCrop, cv::gapi::core::GCrop)
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCL_KERNEL(GOCLCopy, cv::gapi::core::GCopy)
|
||||
{
|
||||
static void run(const cv::UMat& in, cv::UMat& out)
|
||||
{
|
||||
in.copyTo(out);
|
||||
}
|
||||
};
|
||||
|
||||
GAPI_OCL_KERNEL(GOCLConcatHor, cv::gapi::core::GConcatHor)
|
||||
{
|
||||
static void run(const cv::UMat& in1, const cv::UMat& in2, cv::UMat& out)
|
||||
@@ -590,7 +582,6 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels()
|
||||
, GOCLRemap
|
||||
, GOCLFlip
|
||||
, GOCLCrop
|
||||
, GOCLCopy
|
||||
, GOCLConcatHor
|
||||
, GOCLConcatVert
|
||||
, GOCLLUT
|
||||
|
||||
@@ -137,7 +137,12 @@ cv::gapi::GBackend cv::gapi::streaming::backend()
|
||||
|
||||
cv::gapi::GKernelPackage cv::gapi::streaming::kernels()
|
||||
{
|
||||
return cv::gapi::kernels<cv::gimpl::Copy, cv::gimpl::BGR>();
|
||||
return cv::gapi::kernels<cv::gimpl::BGR>();
|
||||
}
|
||||
|
||||
cv::gapi::GKernelPackage cv::gimpl::streaming::kernels()
|
||||
{
|
||||
return cv::gapi::kernels<cv::gimpl::Copy>();
|
||||
}
|
||||
|
||||
void cv::gimpl::Copy::Actor::run(cv::gimpl::GIslandExecutable::IInput &in,
|
||||
@@ -153,8 +158,21 @@ void cv::gimpl::Copy::Actor::run(cv::gimpl::GIslandExecutable::IInput &in,
|
||||
const cv::GRunArgs &in_args = cv::util::get<cv::GRunArgs>(in_msg);
|
||||
GAPI_Assert(in_args.size() == 1u);
|
||||
|
||||
cv::GRunArgP out_arg = out.get(0);
|
||||
*cv::util::get<cv::MediaFrame*>(out_arg) = cv::util::get<cv::MediaFrame>(in_args[0]);
|
||||
const auto& in_arg = in_args[0];
|
||||
auto out_arg = out.get(0);
|
||||
using cv::util::get;
|
||||
switch (in_arg.index()) {
|
||||
case cv::GRunArg::index_of<cv::RMat>():
|
||||
*get<cv::RMat*>(out_arg) = get<cv::RMat>(in_arg);
|
||||
break;
|
||||
case cv::GRunArg::index_of<cv::MediaFrame>():
|
||||
*get<cv::MediaFrame*>(out_arg) = get<cv::MediaFrame>(in_arg);
|
||||
break;
|
||||
// FIXME: Add support for remaining types
|
||||
default:
|
||||
GAPI_Assert(false && "Copy: unsupported data type");
|
||||
}
|
||||
out.meta(out_arg, in_arg.meta);
|
||||
out.post(std::move(out_arg));
|
||||
}
|
||||
|
||||
@@ -197,3 +215,11 @@ void cv::gimpl::BGR::Actor::run(cv::gimpl::GIslandExecutable::IInput &in,
|
||||
}
|
||||
out.post(std::move(out_arg));
|
||||
}
|
||||
|
||||
cv::GMat cv::gapi::copy(const cv::GMat& in) {
|
||||
return cv::gimpl::streaming::GCopy::on<cv::GMat>(in);
|
||||
}
|
||||
|
||||
cv::GFrame cv::gapi::copy(const cv::GFrame& in) {
|
||||
return cv::gimpl::streaming::GCopy::on<cv::GFrame>(in);
|
||||
}
|
||||
|
||||
@@ -12,11 +12,37 @@
|
||||
#include "gstreamingkernel.hpp"
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
namespace streaming {
|
||||
|
||||
cv::gapi::GBackend backend();
|
||||
|
||||
}} // namespace gapi::streaming
|
||||
|
||||
namespace gimpl {
|
||||
namespace streaming {
|
||||
|
||||
cv::gapi::GKernelPackage kernels();
|
||||
|
||||
struct GCopy final : public cv::detail::NoTag
|
||||
{
|
||||
static constexpr const char* id() { return "org.opencv.streaming.copy"; }
|
||||
|
||||
static GMetaArgs getOutMeta(const GMetaArgs &in_meta, const GArgs&) {
|
||||
GAPI_Assert(in_meta.size() == 1u);
|
||||
return in_meta;
|
||||
}
|
||||
|
||||
template<typename T> static T on(const T& arg) {
|
||||
return cv::GKernelType<GCopy, std::function<T(T)>>::on(arg);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace streaming
|
||||
|
||||
struct Copy: public cv::detail::KernelTag
|
||||
{
|
||||
using API = cv::gapi::streaming::GCopy;
|
||||
using API = streaming::GCopy;
|
||||
|
||||
static gapi::GBackend backend() { return cv::gapi::streaming::backend(); }
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "executor/gstreamingexecutor.hpp"
|
||||
#include "backends/common/gbackend.hpp"
|
||||
#include "backends/common/gmetabackend.hpp"
|
||||
#include "backends/streaming/gstreamingbackend.hpp"
|
||||
|
||||
// <FIXME:>
|
||||
#if !defined(GAPI_STANDALONE)
|
||||
@@ -60,8 +61,11 @@ namespace
|
||||
for (const auto &b : pkg.backends()) {
|
||||
aux_pkg = combine(aux_pkg, b.priv().auxiliaryKernels());
|
||||
}
|
||||
// Always include built-in meta<> implementation
|
||||
return combine(pkg, aux_pkg, cv::gimpl::meta::kernels());
|
||||
// Always include built-in meta<> and copy implementation
|
||||
return combine(pkg,
|
||||
aux_pkg,
|
||||
cv::gimpl::meta::kernels(),
|
||||
cv::gimpl::streaming::kernels());
|
||||
};
|
||||
|
||||
auto has_use_only = cv::gapi::getCompileArg<cv::gapi::use_only>(args);
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "compiler/gmodel.hpp"
|
||||
#include "compiler/gislandmodel.hpp"
|
||||
#include "compiler/gmodel.hpp"
|
||||
#include "backends/common/gbackend.hpp" // RMatAdapter
|
||||
|
||||
#include "logger.hpp" // GAPI_LOG
|
||||
|
||||
@@ -357,22 +356,7 @@ void GIslandExecutable::run(GIslandExecutable::IInput &in, GIslandExecutable::IO
|
||||
for (auto &&it: ade::util::zip(ade::util::toRange(in_desc),
|
||||
ade::util::toRange(in_vector)))
|
||||
{
|
||||
const cv::GRunArg& in_data_orig = std::get<1>(it);
|
||||
cv::GRunArg in_data;
|
||||
switch (in_data_orig.index())
|
||||
{
|
||||
case cv::GRunArg::index_of<cv::Mat>():
|
||||
// FIXME: This whole construct is ugly, from
|
||||
// its writing to a need in this in general
|
||||
in_data = cv::GRunArg{ cv::make_rmat<cv::gimpl::RMatAdapter>(cv::util::get<cv::Mat>(in_data_orig))
|
||||
, in_data_orig.meta
|
||||
};
|
||||
break;
|
||||
default:
|
||||
in_data = in_data_orig;
|
||||
break;
|
||||
}
|
||||
in_objs.emplace_back(std::get<0>(it), std::move(in_data));
|
||||
in_objs.emplace_back(std::get<0>(it), std::get<1>(it));
|
||||
}
|
||||
for (auto &&it: ade::util::indexed(ade::util::toRange(out_desc)))
|
||||
{
|
||||
|
||||
@@ -146,16 +146,26 @@ void writeBackExec(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg)
|
||||
writeBack(mag, rc, g_arg);
|
||||
return;
|
||||
}
|
||||
auto checkOutArgData = [&](const uchar* out_arg_data) {
|
||||
//simply check that memory was not reallocated, i.e.
|
||||
//both Mat and View pointing to the same memory
|
||||
auto mag_data = mag.template slot<cv::RMat>().at(rc.id).get<RMatAdapter>()->data();
|
||||
GAPI_Assert((out_arg_data == mag_data) && " data for output parameters was reallocated ?");
|
||||
};
|
||||
|
||||
switch (g_arg.index())
|
||||
{
|
||||
case GRunArgP::index_of<cv::Mat*>() : checkOutArgData(util::get<cv::Mat*>(g_arg)->data); break;
|
||||
case GRunArgP::index_of<cv::Mat*>() : {
|
||||
// If there is a copy intrinsic at the end of the graph
|
||||
// we need to actualy copy the data to the user buffer
|
||||
// since output runarg was optimized to simply point
|
||||
// to the input of the copy kernel
|
||||
// FIXME:
|
||||
// Rework, find a better way to check if there should be
|
||||
// a real copy (add a pass to StreamingBackend?)
|
||||
auto& out_mat = *util::get<cv::Mat*>(g_arg);
|
||||
const auto& rmat = mag.template slot<cv::RMat>().at(rc.id);
|
||||
auto mag_data = rmat.get<RMatAdapter>()->data();
|
||||
if (out_mat.data != mag_data) {
|
||||
auto view = rmat.access(RMat::Access::R);
|
||||
asMat(view).copyTo(out_mat);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GRunArgP::index_of<cv::RMat*>() : /* do nothing */ break;
|
||||
default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "api/gproto_priv.hpp" // ptr(GRunArgP)
|
||||
#include "compiler/passes/passes.hpp"
|
||||
#include "backends/common/gbackend.hpp" // createMat
|
||||
#include "backends/streaming/gstreamingbackend.hpp" // GCopy
|
||||
#include "compiler/gcompiler.hpp" // for compileIslands
|
||||
|
||||
#include "executor/gstreamingexecutor.hpp"
|
||||
@@ -535,6 +536,14 @@ class StreamingInput final: public cv::gimpl::GIslandExecutable::IInput
|
||||
// Stop case
|
||||
return cv::gimpl::StreamMsg{cv::gimpl::EndOfStream{}};
|
||||
}
|
||||
// Wrap all input cv::Mats with RMats
|
||||
for (auto& arg : isl_input_args) {
|
||||
if (arg.index() == cv::GRunArg::index_of<cv::Mat>()) {
|
||||
arg = cv::GRunArg{ cv::make_rmat<cv::gimpl::RMatAdapter>(cv::util::get<cv::Mat>(arg))
|
||||
, arg.meta
|
||||
};
|
||||
}
|
||||
}
|
||||
return cv::gimpl::StreamMsg{std::move(isl_input_args)};
|
||||
}
|
||||
virtual cv::gimpl::StreamMsg try_get() override
|
||||
@@ -1000,7 +1009,7 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
|
||||
GAPI_Assert(GModel::Graph(*m_orig_graph)
|
||||
.metadata(*isl->in_ops().begin())
|
||||
.get<cv::gimpl::Op>()
|
||||
.k.name == cv::gapi::core::GCopy::id());
|
||||
.k.name == cv::gimpl::streaming::GCopy::id());
|
||||
#endif // GAPI_STANDALONE
|
||||
for (auto out_nh : nh->outNodes()) {
|
||||
for (auto out_eh : out_nh->outEdges()) {
|
||||
|
||||
Reference in New Issue
Block a user