mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 07:13:02 +04:00
Merge pull request #12608 from dmatveev:gapi
* G-API Initial code upload * Update G-API code base to Sep-24-2018 * The majority of OpenCV buildbot problems was addressed * Update G-API code base to 24-Sep-18 EOD * G-API code base update 25-Sep-2018 * Linux warnings should be resolved * Documentation build should become green * Number of Windows warnings should be reduced * Update G-API code base to 25-Sep-18 EOD * ARMv7 build issue should be resolved * ADE is bumped to latest version and should fix Clang builds for macOS/iOS * Remaining Windows warnings should be resolved * New Linux32 / ARMv7 warnings should be resolved * G-API code base update 25-Sep-2018-EOD2 * Final Windows warnings should be resolved now * G-API code base update 26-Sep-2018 * Fixed issues with precompiled headers in module and its tests
This commit is contained in:
committed by
Alexander Alekhin
parent
852f061b26
commit
29e88e50ff
@@ -0,0 +1,211 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <ade/util/zip_range.hpp>
|
||||
|
||||
#include "opencv2/core/types.hpp"
|
||||
#include "executor/gexecutor.hpp"
|
||||
|
||||
cv::gimpl::GExecutor::GExecutor(std::unique_ptr<ade::Graph> &&g_model)
|
||||
: m_orig_graph(std::move(g_model))
|
||||
, m_island_graph(GModel::Graph(*m_orig_graph).metadata()
|
||||
.get<IslandModel>().model)
|
||||
, m_gm(*m_orig_graph)
|
||||
, m_gim(*m_island_graph)
|
||||
{
|
||||
// NB: Right now GIslandModel is acyclic, so for a naive execution,
|
||||
// simple unrolling to a list of triggers is enough
|
||||
|
||||
// Naive execution model is similar to current CPU (OpenCV) plugin
|
||||
// execution model:
|
||||
// 1. Allocate all internal resources first (NB - CPU plugin doesn't do it)
|
||||
// 2. Put input/output GComputation arguments to the storage
|
||||
// 3. For every Island, prepare vectors of input/output parameter descs
|
||||
// 4. Iterate over a list of operations (sorted in the topological order)
|
||||
// 5. For every operation, form a list of input/output data objects
|
||||
// 6. Run GIslandExecutable
|
||||
// 7. writeBack
|
||||
|
||||
m_ops.reserve(m_gim.nodes().size());
|
||||
auto sorted = m_gim.metadata().get<ade::passes::TopologicalSortData>();
|
||||
for (auto nh : sorted.nodes())
|
||||
{
|
||||
switch (m_gim.metadata(nh).get<NodeKind>().k)
|
||||
{
|
||||
case NodeKind::ISLAND:
|
||||
{
|
||||
std::vector<RcDesc> input_rcs;
|
||||
std::vector<RcDesc> output_rcs;
|
||||
input_rcs.reserve(nh->inNodes().size());
|
||||
output_rcs.reserve(nh->outNodes().size());
|
||||
|
||||
auto xtract = [&](ade::NodeHandle slot_nh, std::vector<RcDesc> &vec) {
|
||||
const auto orig_data_nh
|
||||
= m_gim.metadata(slot_nh).get<DataSlot>().original_data_node;
|
||||
const auto &orig_data_info
|
||||
= m_gm.metadata(orig_data_nh).get<Data>();
|
||||
vec.emplace_back(RcDesc{ orig_data_info.rc
|
||||
, orig_data_info.shape
|
||||
, orig_data_info.ctor});
|
||||
};
|
||||
// (3)
|
||||
for (auto in_slot_nh : nh->inNodes()) xtract(in_slot_nh, input_rcs);
|
||||
for (auto out_slot_nh : nh->outNodes()) xtract(out_slot_nh, output_rcs);
|
||||
m_ops.emplace_back(OpDesc{ std::move(input_rcs)
|
||||
, std::move(output_rcs)
|
||||
, m_gim.metadata(nh).get<IslandExec>().object});
|
||||
}
|
||||
break;
|
||||
|
||||
case NodeKind::SLOT:
|
||||
{
|
||||
const auto orig_data_nh
|
||||
= m_gim.metadata(nh).get<DataSlot>().original_data_node;
|
||||
// (1)
|
||||
initResource(orig_data_nh);
|
||||
m_slots.emplace_back(DataDesc{nh, orig_data_nh});
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GAPI_Assert(false);
|
||||
break;
|
||||
} // switch(kind)
|
||||
} // for(gim nodes)
|
||||
}
|
||||
|
||||
void cv::gimpl::GExecutor::initResource(const ade::NodeHandle &orig_nh)
|
||||
{
|
||||
const Data &d = m_gm.metadata(orig_nh).get<Data>();
|
||||
|
||||
if ( d.storage != Data::Storage::INTERNAL
|
||||
&& d.storage != Data::Storage::CONST)
|
||||
return;
|
||||
|
||||
// INTERNALS+CONST only! no need to allocate/reset output objects
|
||||
// to as it is bound externally (e.g. already in the m_res)
|
||||
|
||||
switch (d.shape)
|
||||
{
|
||||
case GShape::GMAT:
|
||||
{
|
||||
const auto desc = util::get<cv::GMatDesc>(d.meta);
|
||||
const auto type = CV_MAKETYPE(desc.depth, desc.chan);
|
||||
m_res.slot<cv::gapi::own::Mat>()[d.rc].create(desc.size, type);
|
||||
}
|
||||
break;
|
||||
|
||||
case GShape::GSCALAR:
|
||||
if (d.storage == Data::Storage::CONST)
|
||||
{
|
||||
auto rc = RcDesc{d.rc, d.shape, d.ctor};
|
||||
magazine::bindInArg(m_res, rc, m_gm.metadata(orig_nh).get<ConstValue>().arg);
|
||||
}
|
||||
break;
|
||||
|
||||
case GShape::GARRAY:
|
||||
// Constructed on Reset, do nothing here
|
||||
break;
|
||||
|
||||
default:
|
||||
GAPI_Assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs &&args)
|
||||
{
|
||||
// (2)
|
||||
const auto proto = m_gm.metadata().get<Protocol>();
|
||||
|
||||
// Basic check if input/output arguments are correct
|
||||
// FIXME: Move to GCompiled (do once for all GExecutors)
|
||||
if (proto.inputs.size() != args.inObjs.size()) // TODO: Also check types
|
||||
{
|
||||
util::throw_error(std::logic_error
|
||||
("Computation's input protocol doesn\'t "
|
||||
"match actual arguments!"));
|
||||
}
|
||||
if (proto.outputs.size() != args.outObjs.size()) // TODO: Also check types
|
||||
{
|
||||
util::throw_error(std::logic_error
|
||||
("Computation's output protocol doesn\'t "
|
||||
"match actual arguments!"));
|
||||
}
|
||||
|
||||
namespace util = ade::util;
|
||||
|
||||
//ensure that output Mat parameters are correctly allocated
|
||||
for (auto index : util::iota(proto.out_nhs.size()) ) //FIXME: avoid copy of NodeHandle and GRunRsltComp ?
|
||||
{
|
||||
auto& nh = proto.out_nhs.at(index);
|
||||
const Data &d = m_gm.metadata(nh).get<Data>();
|
||||
if (d.shape == GShape::GMAT)
|
||||
{
|
||||
using cv::util::get;
|
||||
const auto desc = get<cv::GMatDesc>(d.meta);
|
||||
const auto type = CV_MAKETYPE(desc.depth, desc.chan);
|
||||
auto& out_mat = *get<cv::Mat*>(args.outObjs.at(index));
|
||||
out_mat.create(cv::gapi::own::to_ocv(desc.size), type);
|
||||
}
|
||||
}
|
||||
// Update storage with user-passed objects
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
// Reset internal data
|
||||
for (auto &sd : m_slots)
|
||||
{
|
||||
const auto& data = m_gm.metadata(sd.data_nh).get<Data>();
|
||||
magazine::resetInternalData(m_res, data);
|
||||
}
|
||||
|
||||
// Run the script
|
||||
for (auto &op : m_ops)
|
||||
{
|
||||
// (5)
|
||||
using InObj = GIslandExecutable::InObj;
|
||||
using OutObj = GIslandExecutable::OutObj;
|
||||
std::vector<InObj> in_objs;
|
||||
std::vector<OutObj> out_objs;
|
||||
in_objs.reserve (op.in_objects.size());
|
||||
out_objs.reserve(op.out_objects.size());
|
||||
|
||||
for (const auto &rc : op.in_objects)
|
||||
{
|
||||
in_objs.emplace_back(InObj{rc, magazine::getArg(m_res, rc)});
|
||||
}
|
||||
for (const auto &rc : op.out_objects)
|
||||
{
|
||||
out_objs.emplace_back(OutObj{rc, magazine::getObjPtr(m_res, rc)});
|
||||
}
|
||||
|
||||
// (6)
|
||||
op.isl_exec->run(std::move(in_objs), std::move(out_objs));
|
||||
}
|
||||
|
||||
// (7)
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
const cv::gimpl::GModel::Graph& cv::gimpl::GExecutor::model() const
|
||||
{
|
||||
return m_gm;
|
||||
}
|
||||
Reference in New Issue
Block a user