Merge pull request #20372 from sivanov-work:serialize

GAPI: Implement ConstValue serialize/deserialize

* Implement ConstValue ser/deser

* Fix MacOs compile issue

* Fix Docs compile

* Change uint32 -> uint64 for serialize tag
pull/20387/head
Sergey Ivanov 3 years ago committed by GitHub
parent b928ebdd53
commit 3f3c5de851
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 48
      modules/gapi/src/backends/common/serialization.cpp
  2. 6
      modules/gapi/src/backends/common/serialization.hpp
  3. 29
      modules/gapi/test/s11n/gapi_sample_pipelines_s11n.cpp

@ -32,6 +32,14 @@ void putData(GSerialized& s, const cv::gimpl::GModel::ConstGraph& cg, const ade:
});
if (s.m_datas.end() == it) {
s.m_datas.push_back(gdata);
if (cg.metadata(nh).contains<gimpl::ConstValue>()) {
size_t datas_num = s.m_datas.size() - 1;
GAPI_DbgAssert(datas_num <= static_cast<size_t>(std::numeric_limits<GSerialized::data_tag_t>::max()));
GSerialized::data_tag_t tag = static_cast<GSerialized::data_tag_t>(datas_num);
s.m_const_datas.emplace(tag,
cg.metadata(nh).get<gimpl::ConstValue>());
}
}
}
@ -42,11 +50,20 @@ void putOp(GSerialized& s, const cv::gimpl::GModel::ConstGraph& cg, const ade::N
s.m_ops.push_back(op);
}
void mkDataNode(ade::Graph& g, const cv::gimpl::Data& data) {
ade::NodeHandle mkDataNode(ade::Graph& g, const cv::gimpl::Data& data) {
cv::gimpl::GModel::Graph gm(g);
auto nh = gm.createNode();
gm.metadata(nh).set(cv::gimpl::NodeType{cv::gimpl::NodeType::DATA});
gm.metadata(nh).set(data);
return nh;
}
ade::NodeHandle mkConstDataNode(ade::Graph& g, const cv::gimpl::Data& data, const cv::gimpl::ConstValue& const_data) {
auto nh = mkDataNode(g, data);
cv::gimpl::GModel::Graph gm(g);
gm.metadata(nh).set(const_data);
return nh;
}
void mkOpNode(ade::Graph& g, const cv::gimpl::Op& op) {
@ -624,6 +641,10 @@ IOStream& operator<< (IOStream& os, const cv::gimpl::Data &d) {
return os << d.shape << d.rc << d.meta << d.storage << d.kind;
}
IOStream& operator<< (IOStream& os, const cv::gimpl::ConstValue &cd) {
return os << cd.arg;
}
namespace
{
template<typename Ref, typename T, typename... Ts>
@ -667,6 +688,9 @@ IIStream& operator>> (IIStream& is, cv::gimpl::Data &d) {
return is;
}
IIStream& operator>> (IIStream& is, cv::gimpl::ConstValue &cd) {
return is >> cd.arg;
}
IOStream& operator<< (IOStream& os, const cv::gimpl::DataObjectCounter &c) {
return os << c.m_next_data_id;
@ -709,18 +733,34 @@ void serialize( IOStream& os
}
s.m_counter = cg.metadata().get<cv::gimpl::DataObjectCounter>();
s.m_proto = p;
os << s.m_ops << s.m_datas << s.m_counter << s.m_proto;
os << s.m_ops << s.m_datas << s.m_counter << s.m_proto << s.m_const_datas;
}
GSerialized deserialize(IIStream &is) {
GSerialized s;
is >> s.m_ops >> s.m_datas >> s.m_counter >> s.m_proto;
is >> s.m_ops >> s.m_datas >> s.m_counter >> s.m_proto >> s.m_const_datas;
return s;
}
void reconstruct(const GSerialized &s, ade::Graph &g) {
GAPI_Assert(g.nodes().empty());
for (const auto& d : s.m_datas) cv::gapi::s11n::mkDataNode(g, d);
GSerialized::data_tag_t tag = 0;
for (const auto& d : s.m_datas) {
if (d.storage == gimpl::Data::Storage::CONST_VAL) {
auto cit = s.m_const_datas.find(tag);
if (cit == s.m_const_datas.end()) {
util::throw_error(std::logic_error("Cannot reconstruct graph: Data::Storage::CONST_VAL by tag: " +
std::to_string(tag) + " requires ConstValue"));
}
mkConstDataNode(g, d, cit->second);
} else {
cv::gapi::s11n::mkDataNode(g, d);
}
tag ++;
}
for (const auto& op : s.m_ops) cv::gapi::s11n::mkOpNode(g, op);
cv::gapi::s11n::linkNodes(g);

@ -31,6 +31,9 @@ struct GSerialized {
std::vector<cv::gimpl::Data> m_datas;
cv::gimpl::DataObjectCounter m_counter;
cv::gimpl::Protocol m_proto;
using data_tag_t = uint64_t;
std::map<data_tag_t, cv::gimpl::ConstValue> m_const_datas;
};
////////////////////////////////////////////////////////////////////////////////
@ -97,6 +100,9 @@ GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Op &op);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::Data &op);
GAPI_EXPORTS IIStream& operator>> (IIStream& is, cv::gimpl::Data &op);
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gimpl::ConstValue &cd);
GAPI_EXPORTS IIStream& operator>> (IIStream& os, cv::gimpl::ConstValue &cd);
// Render types ////////////////////////////////////////////////////////////////
GAPI_EXPORTS IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Text &t);

@ -806,4 +806,33 @@ TEST(S11N, Pipeline_Render_RGB)
EXPECT_EQ(cv::norm(input, ref_mat), 0);
}
TEST(S11N, Pipeline_Const_GScalar)
{
static constexpr auto in_scalar = 10;
cv::GMat a;
cv::GScalar s;
cv::GComputation computation(GIn(a), GOut(cv::gapi::addC(a, in_scalar)));
auto p = cv::gapi::serialize(computation);
auto deserialized_computation = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Mat ref_mat;
cv::add(in_mat, in_scalar, ref_mat);
cv::Mat out_mat;
computation.apply(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
deserialized_computation.apply(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
auto cc = deserialized_computation.compile(cv::descr_of(in_mat));
cc(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
}
} // namespace opencv_test

Loading…
Cancel
Save