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

Introduce a new abstraction layer over island input/output data

- Port GExecutor to this new interface
This commit is contained in:
Dmitry Matveev
2020-03-16 18:05:41 +03:00
committed by Ruslan Garnov
parent 277f0d270f
commit 1b5730a799
5 changed files with 94 additions and 25 deletions
@@ -12,6 +12,7 @@
#include <unordered_map>
#include <ade/util/checked_cast.hpp>
#include <ade/util/zip_range.hpp> // zip_range, indexed
#include "api/gbackend_priv.hpp" // GBackend::Priv().compile()
#include "compiler/gmodel.hpp"
@@ -319,5 +320,33 @@ ade::NodeHandle GIslandModel::producerOf(const ConstGraph &g, ade::NodeHandle &d
return ade::NodeHandle();
}
void GIslandExecutable::run(GIslandExecutable::IInput &in, GIslandExecutable::IOutput &out)
{
// Default implementation: just reuse the existing old-fashioned run
// Build a single synchronous execution frame for it.
std::vector<InObj> in_objs;
std::vector<OutObj> out_objs;
const auto &in_desc = in.desc();
const auto &out_desc = out.desc();
const auto in_vector = in.get(); // FIXME: passing temporary objects to toRange() leads to issues
in_objs.reserve(in_desc.size());
out_objs.reserve(out_desc.size());
for (auto &&it: ade::util::zip(ade::util::toRange(in_desc),
ade::util::toRange(in_vector)))
{
in_objs.emplace_back(std::get<0>(it), std::get<1>(it));
}
for (auto &&it: ade::util::indexed(ade::util::toRange(out_desc)))
{
out_objs.emplace_back(ade::util::value(it),
out.get(ade::util::checked_cast<int>(ade::util::index(it))));
}
run(std::move(in_objs), std::move(out_objs));
for (auto &&it: out_objs)
{
out.post(std::move(it.second)); // report output objects as "ready" to the executor
}
}
} // namespace cv
} // namespace gimpl
+28 -3
View File
@@ -89,33 +89,58 @@ protected:
util::optional<std::string> m_user_tag;
};
// GIslandExecutable - a backend-specific thing which executes
// contents of an Island
// * Is instantiated by the last step of the Islands fusion procedure;
// * Is orchestrated by a GExecutor instance.
//
class GIslandExecutable
{
public:
using InObj = std::pair<RcDesc, cv::GRunArg>;
using OutObj = std::pair<RcDesc, cv::GRunArgP>;
class IODesc;
struct IInput;
struct IOutput;
// FIXME: now run() requires full input vector to be available.
// actually, parts of subgraph may execute even if there's no all data
// slots in place.
// TODO: Add partial execution capabilities
// TODO: This method is now obsolette and is here for backwards
// compatibility only. Use (implement) the new run instead.
virtual void run(std::vector<InObj> &&input_objs,
std::vector<OutObj> &&output_objs) = 0;
// Let the island execute. I/O data is obtained from/submitted to
// in/out objects.
virtual void run(IInput &in, IOutput &out);
virtual bool canReshape() const = 0;
virtual void reshape(ade::Graph& g, const GCompileArgs& args) = 0;
virtual ~GIslandExecutable() = default;
};
class GIslandExecutable::IODesc {
std::vector<cv::gimpl::RcDesc> d;
public:
void set(std::vector<cv::gimpl::RcDesc> &&newd) { d = std::move(newd); }
void set(const std::vector<cv::gimpl::RcDesc> &newd) { d = newd; }
const std::vector<cv::gimpl::RcDesc> &desc() const { return d; }
};
struct GIslandExecutable::IInput: public GIslandExecutable::IODesc {
virtual ~IInput() = default;
virtual cv::GRunArgs get() = 0; // Get a new input vector (blocking)
virtual cv::GRunArgs try_get() = 0; // Get a new input vector (non-blocking)
};
struct GIslandExecutable::IOutput: public GIslandExecutable::IODesc {
virtual ~IOutput() = default;
virtual GRunArgP get(int idx) = 0; // Allocate (wrap) a new data object for output idx
virtual void post(GRunArgP&&) = 0; // Release the object back to the framework (mark available)
};
// GIslandEmitter - a backend-specific thing which feeds data into
// the pipeline. This one is just an interface, implementations are executor-defined.
class GIslandEmitter