1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge pull request #18127 from smirnov-alexey:as/gapi_serialization

[G-API]: Add GOpaque and GArray serialization support

* Add GOpaque and GArray serialization support

* Address review comments

* Remove holds() method

* Address review comments

* Remove comments

* Align streaming with kind changes

* Fix kind in kernel

* Address review comments
This commit is contained in:
Alexey Smirnov
2020-09-07 20:10:03 +03:00
committed by GitHub
parent 620629593b
commit a3e8c6e866
26 changed files with 648 additions and 228 deletions
@@ -292,25 +292,85 @@ I::IStream& operator >> (I::IStream& is, cv::gapi::wip::IStreamSource::Ptr &)
return is;
}
I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef &)
namespace
{
GAPI_Assert(false && "Serialization: Unsupported << for cv::detail::VectorRef &");
template<typename Ref, typename T, typename... Ts>
struct putToStream;
template<typename Ref>
struct putToStream<Ref, std::tuple<>>
{
static void put(I::OStream&, const Ref &)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque serialization");
}
};
template<typename Ref, typename T, typename... Ts>
struct putToStream<Ref, std::tuple<T, Ts...>>
{
static void put(I::OStream& os, const Ref &r)
{
if (r.getKind() == cv::detail::GOpaqueTraits<T>::kind) {
os << r.template rref<T>();
} else {
putToStream<Ref, std::tuple<Ts...> >::put(os, r);
}
}
};
template<typename Ref, typename T, typename... Ts>
struct getFromStream;
template<typename Ref>
struct getFromStream<Ref, std::tuple<>>
{
static void get(I::IStream&, Ref &, cv::detail::OpaqueKind)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
}
};
template<typename Ref, typename T, typename... Ts>
struct getFromStream<Ref, std::tuple<T, Ts...>>
{
static void get(I::IStream& is, Ref &r, cv::detail::OpaqueKind kind) {
if (kind == cv::detail::GOpaqueTraits<T>::kind) {
r.template reset<T>();
auto& val = r.template wref<T>();
is >> val;
} else {
getFromStream<Ref, std::tuple<Ts...> >::get(is, r, kind);
}
}
};
}
I::OStream& operator<< (I::OStream& os, const cv::detail::VectorRef& ref)
{
os << ref.getKind();
putToStream<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::put(os, ref);
return os;
}
I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef &)
I::IStream& operator >> (I::IStream& is, cv::detail::VectorRef& ref)
{
GAPI_Assert(false && "Serialization: Unsupported >> for cv::detail::VectorRef &");
cv::detail::OpaqueKind kind;
is >> kind;
getFromStream<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::get(is, ref, kind);
return is;
}
I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef &)
I::OStream& operator<< (I::OStream& os, const cv::detail::OpaqueRef& ref)
{
GAPI_Assert(false && "Serialization: Unsupported << for cv::detail::OpaqueRef &");
os << ref.getKind();
putToStream<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::put(os, ref);
return os;
}
I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef &)
I::IStream& operator >> (I::IStream& is, cv::detail::OpaqueRef& ref)
{
GAPI_Assert(false && "Serialization: Unsupported >> for cv::detail::OpaqueRef &");
cv::detail::OpaqueKind kind;
is >> kind;
getFromStream<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::get(is, ref, kind);
return is;
}
// Enums and structures
@@ -350,7 +410,6 @@ I::IStream& operator>> (I::IStream& is, cv::gimpl::Data::Storage &s) {
return get_enum<cv::gimpl::Data::Storage>(is, s);
}
I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) {
// Only GOBJREF and OPAQUE_VAL kinds can be serialized/deserialized
GAPI_Assert( arg.kind == cv::detail::ArgKind::OPAQUE_VAL
@@ -376,6 +435,7 @@ I::OStream& operator<< (I::OStream& os, const cv::GArg &arg) {
}
return os;
}
I::IStream& operator>> (I::IStream& is, cv::GArg &arg) {
is >> arg.kind >> arg.opaque_kind;
@@ -447,12 +507,50 @@ I::IStream& operator>> (I::IStream& is, cv::gimpl::Op &op) {
I::OStream& operator<< (I::OStream& os, const cv::gimpl::Data &d) {
// FIXME: HostCtor is not stored here!!
// FIXME: Storage may be incorrect for subgraph-to-graph process
return os << d.shape << d.rc << d.meta << d.storage;
return os << d.shape << d.rc << d.meta << d.storage << d.kind;
}
namespace
{
template<typename Ref, typename T, typename... Ts>
struct initCtor;
template<typename Ref>
struct initCtor<Ref, std::tuple<>>
{
static void init(cv::gimpl::Data&)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
}
};
template<typename Ref, typename T, typename... Ts>
struct initCtor<Ref, std::tuple<T, Ts...>>
{
static void init(cv::gimpl::Data& d) {
if (d.kind == cv::detail::GOpaqueTraits<T>::kind) {
static std::function<void(Ref&)> ctor = [](Ref& ref){ref.template reset<T>();};
d.ctor = ctor;
} else {
initCtor<Ref, std::tuple<Ts...> >::init(d);
}
}
};
} // anonymous namespace
I::IStream& operator>> (I::IStream& is, cv::gimpl::Data &d) {
// FIXME: HostCtor is not stored here!!
// FIXME: Storage may be incorrect for subgraph-to-graph process
return is >> d.shape >> d.rc >> d.meta >> d.storage;
is >> d.shape >> d.rc >> d.meta >> d.storage >> d.kind;
if (d.shape == cv::GShape::GARRAY)
{
initCtor<cv::detail::VectorRef, cv::detail::GOpaqueTraitsArrayTypes>::init(d);
}
else if (d.shape == cv::GShape::GOPAQUE)
{
initCtor<cv::detail::OpaqueRef, cv::detail::GOpaqueTraitsOpaqueTypes>::init(d);
}
return is;
}
@@ -478,6 +576,14 @@ void serialize( I::OStream& os
, const ade::Graph &g
, const std::vector<ade::NodeHandle> &nodes) {
cv::gimpl::GModel::ConstGraph cg(g);
serialize(os, g, cg.metadata().get<cv::gimpl::Protocol>(), nodes);
}
void serialize( I::OStream& os
, const ade::Graph &g
, const cv::gimpl::Protocol &p
, const std::vector<ade::NodeHandle> &nodes) {
cv::gimpl::GModel::ConstGraph cg(g);
GSerialized s;
for (auto &nh : nodes) {
switch (cg.metadata(nh).get<NodeType>().t)
@@ -488,7 +594,7 @@ void serialize( I::OStream& os
}
}
s.m_counter = cg.metadata().get<cv::gimpl::DataObjectCounter>();
s.m_proto = cg.metadata().get<cv::gimpl::Protocol>();
s.m_proto = p;
os << s.m_ops << s.m_datas << s.m_counter << s.m_proto;
}
@@ -121,7 +121,6 @@ GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GArg &arg);
//I::OStream& operator<< (I::OStream& os, const cv::GRunArg &arg);
//I::IStream& operator>> (I::IStream& is, cv::GRunArg &arg);
GAPI_EXPORTS I::OStream& operator<< (I::OStream& os, const cv::GKernel &k);
GAPI_EXPORTS I::IStream& operator>> (I::IStream& is, cv::GKernel &k);
@@ -167,6 +166,14 @@ GAPI_EXPORTS void serialize( I::OStream& os
, const ade::Graph &g
, const std::vector<ade::NodeHandle> &nodes);
// The top-level serialization routine.
// Note it is just a single function which takes a GModel and a list of nodes
// and writes the data to the stream (recursively)
GAPI_EXPORTS void serialize( I::OStream& os
, const ade::Graph &g
, const cv::gimpl::Protocol &p
, const std::vector<ade::NodeHandle> &nodes);
// The top-level deserialization routineS.
// Unfortunately the deserialization is a two-step process:
// 1. First we decode a stream into some intermediate representation
@@ -194,7 +194,7 @@ void cv::gimpl::GCPUExecutable::run(std::vector<InObj> &&input_objs,
{
const auto &desc = gm.metadata(nh).get<Data>();
if ( desc.storage == Data::Storage::INTERNAL
if ( desc.storage == Data::Storage::INTERNAL // FIXME: to reconsider
&& !util::holds_alternative<util::monostate>(desc.ctor))
{
// FIXME: Note that compile-time constant data objects (like
+4 -4
View File
@@ -614,7 +614,7 @@ struct InferList2: public cv::detail::KernelTag {
GAPI_Assert(util::holds_alternative<cv::GArrayDesc>(mm)
&& "Non-array inputs are not supported");
if (op.k.inSpecs[idx] == cv::detail::ArgSpec::RECT) {
if (op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_RECT) {
// This is a cv::Rect -- configure the IE preprocessing
ii->setPrecision(toIE(meta_0.depth));
ii->getPreProcess().setResizeAlgorithm(IE::RESIZE_BILINEAR);
@@ -622,7 +622,7 @@ struct InferList2: public cv::detail::KernelTag {
// This is a cv::GMat (equals to: cv::Mat)
// Just validate that it is really the type
// (other types are prohibited here)
GAPI_Assert(op.k.inSpecs[idx] == cv::detail::ArgSpec::GMAT);
GAPI_Assert(op.k.inKinds[idx] == cv::detail::OpaqueKind::CV_MAT);
}
idx++; // NB: Never forget to increment the counter
}
@@ -666,11 +666,11 @@ struct InferList2: public cv::detail::KernelTag {
GAPI_Assert(this_vec.size() == list_size);
// Prepare input {{{
IE::Blob::Ptr this_blob;
if (this_vec.spec() == cv::detail::TypeSpec::RECT) {
if (this_vec.getKind() == cv::detail::OpaqueKind::CV_RECT) {
// ROI case - create an ROI blob
const auto &vec = this_vec.rref<cv::Rect>();
this_blob = IE::make_shared_blob(blob_0, toIE(vec[list_idx]));
} else if (this_vec.spec() == cv::detail::TypeSpec::MAT) {
} else if (this_vec.getKind() == cv::detail::OpaqueKind::CV_MAT) {
// Mat case - create a regular blob
// FIXME: NOW Assume Mats are always BLOBS (not
// images)