mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge pull request #18339 from rgarnov:rg/rmat_integration
[GAPI] RMat integration into the framework * RMat integration * Added initialization of input mat in GArray initialization tests * Fixed klocwork warnings in RMat tests, changed argument order in EXPECT_EQ
This commit is contained in:
@@ -72,7 +72,7 @@ cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
|
||||
const auto orig_data_nh
|
||||
= m_gim.metadata(nh).get<DataSlot>().original_data_node;
|
||||
// (1)
|
||||
initResource(orig_data_nh);
|
||||
initResource(nh, orig_data_nh);
|
||||
m_slots.emplace_back(DataDesc{nh, orig_data_nh});
|
||||
}
|
||||
break;
|
||||
@@ -84,7 +84,82 @@ cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
|
||||
} // for(gim nodes)
|
||||
}
|
||||
|
||||
void cv::gimpl::GExecutor::initResource(const ade::NodeHandle &orig_nh)
|
||||
namespace cv {
|
||||
namespace gimpl {
|
||||
namespace magazine {
|
||||
namespace {
|
||||
|
||||
void bindInArgExec(Mag& mag, const RcDesc &rc, const GRunArg &arg)
|
||||
{
|
||||
if (rc.shape != GShape::GMAT)
|
||||
{
|
||||
bindInArg(mag, rc, arg);
|
||||
return;
|
||||
}
|
||||
auto& mag_rmat = mag.template slot<cv::RMat>()[rc.id];
|
||||
switch (arg.index())
|
||||
{
|
||||
case GRunArg::index_of<Mat>() :
|
||||
mag_rmat = make_rmat<RMatAdapter>(util::get<Mat>(arg)); break;
|
||||
case GRunArg::index_of<cv::RMat>() :
|
||||
mag_rmat = util::get<cv::RMat>(arg); break;
|
||||
default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
|
||||
}
|
||||
}
|
||||
|
||||
void bindOutArgExec(Mag& mag, const RcDesc &rc, const GRunArgP &arg)
|
||||
{
|
||||
if (rc.shape != GShape::GMAT)
|
||||
{
|
||||
bindOutArg(mag, rc, arg);
|
||||
return;
|
||||
}
|
||||
auto& mag_rmat = mag.template slot<cv::RMat>()[rc.id];
|
||||
switch (arg.index())
|
||||
{
|
||||
case GRunArgP::index_of<Mat*>() :
|
||||
mag_rmat = make_rmat<RMatAdapter>(*util::get<Mat*>(arg)); break;
|
||||
case GRunArgP::index_of<cv::RMat*>() :
|
||||
mag_rmat = *util::get<cv::RMat*>(arg); break;
|
||||
default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
|
||||
}
|
||||
}
|
||||
|
||||
cv::GRunArgP getObjPtrExec(Mag& mag, const RcDesc &rc)
|
||||
{
|
||||
if (rc.shape != GShape::GMAT)
|
||||
{
|
||||
return getObjPtr(mag, rc);
|
||||
}
|
||||
return GRunArgP(&mag.template slot<cv::RMat>()[rc.id]);
|
||||
}
|
||||
|
||||
void writeBackExec(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg)
|
||||
{
|
||||
if (rc.shape != GShape::GMAT)
|
||||
{
|
||||
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::RMat*>() : /* do nothing */ break;
|
||||
default: util::throw_error(std::logic_error("content type of the runtime argument does not match to resource description ?"));
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
}}} // namespace cv::gimpl::magazine
|
||||
|
||||
|
||||
void cv::gimpl::GExecutor::initResource(const ade::NodeHandle & nh, const ade::NodeHandle &orig_nh)
|
||||
{
|
||||
const Data &d = m_gm.metadata(orig_nh).get<Data>();
|
||||
|
||||
@@ -99,9 +174,19 @@ void cv::gimpl::GExecutor::initResource(const ade::NodeHandle &orig_nh)
|
||||
{
|
||||
case GShape::GMAT:
|
||||
{
|
||||
// Let island allocate it's outputs if it can,
|
||||
// allocate cv::Mat and wrap it with RMat otherwise
|
||||
GAPI_Assert(!nh->inNodes().empty());
|
||||
const auto desc = util::get<cv::GMatDesc>(d.meta);
|
||||
auto& mat = m_res.slot<cv::Mat>()[d.rc];
|
||||
createMat(desc, mat);
|
||||
auto& exec = m_gim.metadata(nh->inNodes().front()).get<IslandExec>().object;
|
||||
auto& rmat = m_res.slot<cv::RMat>()[d.rc];
|
||||
if (exec->allocatesOutputs()) {
|
||||
rmat = exec->allocate(desc);
|
||||
} else {
|
||||
Mat mat;
|
||||
createMat(desc, mat);
|
||||
rmat = make_rmat<RMatAdapter>(mat);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -146,7 +231,7 @@ public:
|
||||
class cv::gimpl::GExecutor::Output final: public cv::gimpl::GIslandExecutable::IOutput
|
||||
{
|
||||
cv::gimpl::Mag &mag;
|
||||
virtual GRunArgP get(int idx) override { return magazine::getObjPtr(mag, desc()[idx]); }
|
||||
virtual GRunArgP get(int idx) override { return magazine::getObjPtrExec(mag, desc()[idx]); }
|
||||
virtual void post(GRunArgP&&) override { } // Do nothing here
|
||||
virtual void post(EndOfStream&&) override {} // Do nothing here too
|
||||
public:
|
||||
@@ -186,11 +271,10 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
|
||||
using cv::util::get;
|
||||
const auto desc = get<cv::GMatDesc>(d.meta);
|
||||
|
||||
auto check_own_mat = [&desc, &args, &index]()
|
||||
auto check_rmat = [&desc, &args, &index]()
|
||||
{
|
||||
auto& out_mat = *get<cv::Mat*>(args.outObjs.at(index));
|
||||
GAPI_Assert(out_mat.data != nullptr &&
|
||||
desc.canDescribe(out_mat));
|
||||
auto& out_mat = *get<cv::RMat*>(args.outObjs.at(index));
|
||||
GAPI_Assert(desc.canDescribe(out_mat));
|
||||
};
|
||||
|
||||
#if !defined(GAPI_STANDALONE)
|
||||
@@ -202,15 +286,25 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
|
||||
auto& out_mat = *get<cv::Mat*>(args.outObjs.at(index));
|
||||
createMat(desc, out_mat);
|
||||
}
|
||||
// In the case of own::Mat never reallocated, checked to perfectly fit required meta
|
||||
// In the case of RMat check to fit required meta
|
||||
else
|
||||
{
|
||||
check_own_mat();
|
||||
check_rmat();
|
||||
}
|
||||
#else
|
||||
// Building standalone - output buffer should always exist,
|
||||
// and _exact_ match our inferred metadata
|
||||
check_own_mat();
|
||||
if (cv::util::holds_alternative<cv::Mat*>(args.outObjs.at(index)))
|
||||
{
|
||||
auto& out_mat = *get<cv::Mat*>(args.outObjs.at(index));
|
||||
GAPI_Assert(out_mat.data != nullptr &&
|
||||
desc.canDescribe(out_mat));
|
||||
}
|
||||
// In the case of RMat check to fit required meta
|
||||
else
|
||||
{
|
||||
check_rmat();
|
||||
}
|
||||
#endif // !defined(GAPI_STANDALONE)
|
||||
}
|
||||
}
|
||||
@@ -218,12 +312,12 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
|
||||
for (auto it : ade::util::zip(ade::util::toRange(proto.inputs),
|
||||
ade::util::toRange(args.inObjs)))
|
||||
{
|
||||
magazine::bindInArg(m_res, std::get<0>(it), std::get<1>(it));
|
||||
magazine::bindInArgExec(m_res, std::get<0>(it), std::get<1>(it));
|
||||
}
|
||||
for (auto it : ade::util::zip(ade::util::toRange(proto.outputs),
|
||||
ade::util::toRange(args.outObjs)))
|
||||
{
|
||||
magazine::bindOutArg(m_res, std::get<0>(it), std::get<1>(it));
|
||||
magazine::bindOutArgExec(m_res, std::get<0>(it), std::get<1>(it));
|
||||
}
|
||||
|
||||
// Reset internal data
|
||||
@@ -246,7 +340,7 @@ void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
|
||||
for (auto it : ade::util::zip(ade::util::toRange(proto.outputs),
|
||||
ade::util::toRange(args.outObjs)))
|
||||
{
|
||||
magazine::writeBack(m_res, std::get<0>(it), std::get<1>(it));
|
||||
magazine::writeBackExec(m_res, std::get<0>(it), std::get<1>(it));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace gimpl {
|
||||
class GExecutor
|
||||
{
|
||||
protected:
|
||||
Mag m_res;
|
||||
std::unique_ptr<ade::Graph> m_orig_graph;
|
||||
std::shared_ptr<ade::Graph> m_island_graph;
|
||||
|
||||
@@ -80,9 +81,7 @@ protected:
|
||||
class Input;
|
||||
class Output;
|
||||
|
||||
Mag m_res;
|
||||
|
||||
void initResource(const ade::NodeHandle &orig_nh); // FIXME: shouldn't it be RcDesc?
|
||||
void initResource(const ade::NodeHandle &nh, const ade::NodeHandle &orig_nh); // FIXME: shouldn't it be RcDesc?
|
||||
|
||||
public:
|
||||
explicit GExecutor(std::unique_ptr<ade::Graph> &&g_model);
|
||||
|
||||
@@ -109,7 +109,13 @@ void sync_data(cv::GRunArgs &results, cv::GRunArgsP &outputs)
|
||||
switch (out_obj.index())
|
||||
{
|
||||
case T::index_of<cv::Mat*>():
|
||||
*cv::util::get<cv::Mat*>(out_obj) = std::move(cv::util::get<cv::Mat>(res_obj));
|
||||
{
|
||||
auto out_mat_p = cv::util::get<cv::Mat*>(out_obj);
|
||||
auto view = cv::util::get<cv::RMat>(res_obj).access(cv::RMat::Access::R);
|
||||
*out_mat_p = cv::gimpl::asMat(view).clone();
|
||||
} break;
|
||||
case T::index_of<cv::RMat*>():
|
||||
*cv::util::get<cv::RMat*>(out_obj) = std::move(cv::util::get<cv::RMat>(res_obj));
|
||||
break;
|
||||
case T::index_of<cv::Scalar*>():
|
||||
*cv::util::get<cv::Scalar*>(out_obj) = std::move(cv::util::get<cv::Scalar>(res_obj));
|
||||
@@ -408,6 +414,7 @@ class StreamingOutput final: public cv::gimpl::GIslandExecutable::IOutput
|
||||
// These objects are owned externally
|
||||
const cv::GMetaArgs &m_metas;
|
||||
std::vector< std::vector<Q*> > &m_out_queues;
|
||||
std::shared_ptr<cv::gimpl::GIslandExecutable> m_island;
|
||||
|
||||
// Allocate a new data object for output under idx
|
||||
// Prepare this object for posting
|
||||
@@ -430,10 +437,19 @@ class StreamingOutput final: public cv::gimpl::GIslandExecutable::IOutput
|
||||
// FIXME: This is absolutely ugly but seem to work perfectly for its purpose.
|
||||
case cv::GShape::GMAT:
|
||||
{
|
||||
MatType newMat;
|
||||
cv::gimpl::createMat(cv::util::get<cv::GMatDesc>(m_metas[idx]), newMat);
|
||||
out_arg = cv::GRunArg(std::move(newMat));
|
||||
ret_val = cv::GRunArgP(&cv::util::get<MatType>(out_arg));
|
||||
auto desc = cv::util::get<cv::GMatDesc>(m_metas[idx]);
|
||||
if (m_island->allocatesOutputs())
|
||||
{
|
||||
out_arg = cv::GRunArg(m_island->allocate(desc));
|
||||
}
|
||||
else
|
||||
{
|
||||
MatType newMat;
|
||||
cv::gimpl::createMat(desc, newMat);
|
||||
auto rmat = cv::make_rmat<cv::gimpl::RMatAdapter>(newMat);
|
||||
out_arg = cv::GRunArg(std::move(rmat));
|
||||
}
|
||||
ret_val = cv::GRunArgP(&cv::util::get<cv::RMat>(out_arg));
|
||||
}
|
||||
break;
|
||||
case cv::GShape::GSCALAR:
|
||||
@@ -538,9 +554,11 @@ class StreamingOutput final: public cv::gimpl::GIslandExecutable::IOutput
|
||||
public:
|
||||
explicit StreamingOutput(const cv::GMetaArgs &metas,
|
||||
std::vector< std::vector<Q*> > &out_queues,
|
||||
const std::vector<cv::gimpl::RcDesc> &out_descs)
|
||||
const std::vector<cv::gimpl::RcDesc> &out_descs,
|
||||
std::shared_ptr<cv::gimpl::GIslandExecutable> island)
|
||||
: m_metas(metas)
|
||||
, m_out_queues(out_queues)
|
||||
, m_island(island)
|
||||
{
|
||||
set(out_descs);
|
||||
m_postings.resize(out_descs.size());
|
||||
@@ -573,7 +591,7 @@ void islandActorThread(std::vector<cv::gimpl::RcDesc> in_rcs, //
|
||||
GAPI_Assert(out_queues.size() == out_metas.size());
|
||||
QueueReader qr;
|
||||
StreamingInput input(qr, in_queues, in_constants, in_rcs);
|
||||
StreamingOutput output(out_metas, out_queues, out_rcs);
|
||||
StreamingOutput output(out_metas, out_queues, out_rcs, island);
|
||||
while (!output.done())
|
||||
{
|
||||
island->run(input, output);
|
||||
|
||||
Reference in New Issue
Block a user