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

Merge branch 4.x

This commit is contained in:
Alexander Alekhin
2023-01-09 11:08:02 +00:00
880 changed files with 83958 additions and 9368 deletions
@@ -37,7 +37,7 @@ cv::detail::GCompoundContext::GCompoundContext(const cv::GArgs& in_args)
// do nothing - as handled in a special way, see gcompoundkernel.hpp for details
// same applies to GMatP
break;
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
}
}
}
@@ -176,6 +176,13 @@ IIStream& operator>> (IIStream& is, cv::Point2f& pt) {
return is >> pt.x >> pt.y;
}
IOStream& operator<< (IOStream& os, const cv::Point3f &pt) {
return os << pt.x << pt.y << pt.z;
}
IIStream& operator>> (IIStream& is, cv::Point3f& pt) {
return is >> pt.x >> pt.y >> pt.z;
}
IOStream& operator<< (IOStream& os, const cv::Size &sz) {
return os << sz.width << sz.height;
}
@@ -283,7 +290,7 @@ IOStream& operator<< (IOStream& os, const cv::Mat &m) {
case CV_32S: write_mat_data< int32_t>(os, m); break;
case CV_32F: write_mat_data< float>(os, m); break;
case CV_64F: write_mat_data< double>(os, m); break;
default: GAPI_Assert(false && "Unsupported Mat depth");
default: GAPI_Error("Unsupported Mat depth");
}
return os;
}
@@ -299,7 +306,7 @@ IIStream& operator>> (IIStream& is, cv::Mat& m) {
case CV_32S: read_mat_data< int32_t>(is, m); break;
case CV_32F: read_mat_data< float>(is, m); break;
case CV_64F: read_mat_data< double>(is, m); break;
default: GAPI_Assert(false && "Unsupported Mat depth");
default: GAPI_Error("Unsupported Mat depth");
}
return is;
}
@@ -312,10 +319,10 @@ IIStream& operator>> (IIStream& is, cv::gapi::wip::draw::Text &t) {
}
IOStream& operator<< (IOStream&, const cv::gapi::wip::draw::FText &) {
GAPI_Assert(false && "Serialization: Unsupported << for FText");
GAPI_Error("Serialization: Unsupported << for FText");
}
IIStream& operator>> (IIStream&, cv::gapi::wip::draw::FText &) {
GAPI_Assert(false && "Serialization: Unsupported >> for FText");
GAPI_Error("Serialization: Unsupported >> for FText");
}
IOStream& operator<< (IOStream& os, const cv::gapi::wip::draw::Circle &c) {
@@ -391,19 +398,19 @@ IIStream& operator>> (IIStream& is, cv::GArrayDesc &) {return is;}
#if !defined(GAPI_STANDALONE)
IOStream& operator<< (IOStream& os, const cv::UMat &)
{
GAPI_Assert(false && "Serialization: Unsupported << for UMat");
GAPI_Error("Serialization: Unsupported << for UMat");
return os;
}
IIStream& operator >> (IIStream& is, cv::UMat &)
{
GAPI_Assert(false && "Serialization: Unsupported >> for UMat");
GAPI_Error("Serialization: Unsupported >> for UMat");
return is;
}
#endif // !defined(GAPI_STANDALONE)
IOStream& operator<< (IOStream& os, const cv::gapi::wip::IStreamSource::Ptr &)
{
GAPI_Assert(false && "Serialization: Unsupported << for IStreamSource::Ptr");
GAPI_Error("Serialization: Unsupported << for IStreamSource::Ptr");
return os;
}
IIStream& operator >> (IIStream& is, cv::gapi::wip::IStreamSource::Ptr &)
@@ -422,7 +429,7 @@ struct putToStream<Ref, std::tuple<>>
{
static void put(IOStream&, const Ref &)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque serialization");
GAPI_Error("Unsupported type for GArray/GOpaque serialization");
}
};
@@ -447,7 +454,7 @@ struct getFromStream<Ref, std::tuple<>>
{
static void get(IIStream&, Ref &, cv::detail::OpaqueKind)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
GAPI_Error("Unsupported type for GArray/GOpaque deserialization");
}
};
@@ -553,7 +560,7 @@ IOStream& operator<< (IOStream& os, const cv::GArg &arg) {
case cv::detail::OpaqueKind::CV_RECT: os << arg.get<cv::Rect>(); break;
case cv::detail::OpaqueKind::CV_SCALAR: os << arg.get<cv::Scalar>(); break;
case cv::detail::OpaqueKind::CV_MAT: os << arg.get<cv::Mat>(); break;
default: GAPI_Assert(false && "GArg: Unsupported (unknown?) opaque value type");
default: GAPI_Error("GArg: Unsupported (unknown?) opaque value type");
}
}
return os;
@@ -584,12 +591,13 @@ IIStream& operator>> (IIStream& is, cv::GArg &arg) {
HANDLE_CASE(STRING , std::string);
HANDLE_CASE(POINT , cv::Point);
HANDLE_CASE(POINT2F , cv::Point2f);
HANDLE_CASE(POINT3F , cv::Point3f);
HANDLE_CASE(SIZE , cv::Size);
HANDLE_CASE(RECT , cv::Rect);
HANDLE_CASE(SCALAR , cv::Scalar);
HANDLE_CASE(MAT , cv::Mat);
#undef HANDLE_CASE
default: GAPI_Assert(false && "GArg: Unsupported (unknown?) opaque value type");
default: GAPI_Error("GArg: Unsupported (unknown?) opaque value type");
}
}
return is;
@@ -657,7 +665,7 @@ struct initCtor<Ref, std::tuple<>>
{
static void init(cv::gimpl::Data&)
{
GAPI_Assert(false && "Unsupported type for GArray/GOpaque deserialization");
GAPI_Error("Unsupported type for GArray/GOpaque deserialization");
}
};
@@ -18,7 +18,8 @@
#include "opencv2/gapi/render/render_types.hpp"
#include "opencv2/gapi/s11n.hpp" // basic interfaces
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4702)
#endif
@@ -232,4 +233,8 @@ GAPI_EXPORTS std::vector<std::string> vector_of_strings_deserialize(IIStream& is
} // namespace gapi
} // namespace cv
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif // OPENCV_GAPI_COMMON_SERIALIZATION_HPP
+2 -2
View File
@@ -63,9 +63,9 @@ GAPI_OCV_KERNEL_ST(GCPUStereo, cv::gapi::calib3d::GStereo, StereoSetup)
stereoSetup.stereoBM->compute(left, right, out_mat);
break;
case cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_11_5:
GAPI_Assert(false && "This case may be supported in future.");
GAPI_Error("This case may be supported in future.");
default:
GAPI_Assert(false && "Unknown output format!");
GAPI_Error("Unknown output format!");
}
}
};
@@ -313,7 +313,7 @@ static int maxLineConsumption(const cv::GFluidKernel::Kind kind, int window, int
}
} break;
case cv::GFluidKernel::Kind::YUV420toRGB: return inPort == 0 ? 2 : 1; break;
default: GAPI_Assert(false); return 0;
default: GAPI_Error("InternalError"); return 0;
}
}
@@ -325,7 +325,7 @@ static int borderSize(const cv::GFluidKernel::Kind kind, int window)
// Resize never reads from border pixels
case cv::GFluidKernel::Kind::Resize: return 0; break;
case cv::GFluidKernel::Kind::YUV420toRGB: return 0; break;
default: GAPI_Assert(false); return 0;
default: GAPI_Error("InternalError"); return 0;
}
}
@@ -685,7 +685,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
case 0: roi = produced; break;
case 1:
case 2: roi = cv::Rect{ produced.x/2, produced.y/2, produced.width/2, produced.height/2 }; break;
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
}
return roi;
};
@@ -699,7 +699,7 @@ void cv::gimpl::GFluidExecutable::initBufferRois(std::vector<int>& readStarts,
case GFluidKernel::Kind::Filter: resized = produced; break;
case GFluidKernel::Kind::Resize: resized = adjResizeRoi(produced, in_meta.size, meta.size); break;
case GFluidKernel::Kind::YUV420toRGB: resized = adj420Roi(produced, m_gm.metadata(in_edge).get<Input>().port); break;
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
}
// All below transformations affect roi of the writer, preserve read start position here
@@ -814,7 +814,7 @@ cv::gimpl::FluidGraphInputData cv::gimpl::fluidExtractInputDataFromGraph(const a
last_agent++;
break;
}
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
}
}
@@ -844,7 +844,7 @@ cv::gimpl::GFluidExecutable::GFluidExecutable(const ade::Graph
case GFluidKernel::Kind::Filter: agent_ptr.reset(new FluidFilterAgent(g, agent_data.nh)); break;
case GFluidKernel::Kind::Resize: agent_ptr.reset(new FluidResizeAgent(g, agent_data.nh)); break;
case GFluidKernel::Kind::YUV420toRGB: agent_ptr.reset(new Fluid420toRGBAgent(g, agent_data.nh)); break;
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
}
std::tie(agent_ptr->in_buffer_ids, agent_ptr->out_buffer_ids) = std::tie(agent_data.in_buffer_ids, agent_data.out_buffer_ids);
return agent_ptr;
@@ -1388,7 +1388,7 @@ cv::gimpl::GParallelFluidExecutable::GParallelFluidExecutable(const ade::Graph
void cv::gimpl::GParallelFluidExecutable::reshape(ade::Graph&, const GCompileArgs& )
{
//TODO: implement ?
GAPI_Assert(false && "Not Implemented;");
GAPI_Error("Not Implemented;");
}
void cv::gimpl::GParallelFluidExecutable::run(std::vector<InObj> &&input_objs,
@@ -1474,7 +1474,7 @@ void GFluidBackendImpl::addMetaSensitiveBackendPasses(ade::ExecutionEngineSetupC
case NodeKind::EMIT:
case NodeKind::SINK:
break; // do nothing for Streaming nodes
default: GAPI_Assert(false);
default: GAPI_Error("InternalError");
} // switch
} // for (gim.nodes())
});
@@ -90,7 +90,7 @@ void fillBorderConstant(int borderSize, cv::Scalar borderValue, cv::Mat& mat)
case CV_16S: return &fillConstBorderRow< int16_t>; break;
case CV_16U: return &fillConstBorderRow<uint16_t>; break;
case CV_32F: return &fillConstBorderRow< float >; break;
default: GAPI_Assert(false); return &fillConstBorderRow<uint8_t>;
default: GAPI_Error("InternalError"); return &fillConstBorderRow<uint8_t>;
}
};
@@ -231,7 +231,7 @@ void fluid::BufferStorageWithBorder::init(int dtype, int border_size, Border bor
case cv::BORDER_REFLECT_101:
m_borderHandler.reset(new BorderHandlerT<cv::BORDER_REFLECT_101>(border_size, dtype)); break;
default:
GAPI_Assert(false);
GAPI_Error("InternalError");
}
}
+181 -80
View File
@@ -114,7 +114,7 @@ inline IE::Precision toIE(int depth) {
case CV_32S: return IE::Precision::I32;
case CV_32F: return IE::Precision::FP32;
case CV_16F: return IE::Precision::FP16;
default: GAPI_Assert(false && "IE. Unsupported data type");
default: GAPI_Error("IE. Unsupported data type");
}
return IE::Precision::UNSPECIFIED;
}
@@ -125,7 +125,7 @@ inline int toCV(IE::Precision prec) {
case IE::Precision::I32: return CV_32S;
case IE::Precision::I64: return CV_32S;
case IE::Precision::FP16: return CV_16F;
default: GAPI_Assert(false && "IE. Unsupported data type");
default: GAPI_Error("IE. Unsupported data type");
}
return -1;
}
@@ -167,7 +167,7 @@ inline IE::Blob::Ptr wrapIE(const cv::Mat &mat, cv::gapi::ie::TraitAs hint) {
HANDLE(32S, int);
HANDLE(16F, int16_t);
#undef HANDLE
default: GAPI_Assert(false && "IE. Unsupported data type");
default: GAPI_Error("IE. Unsupported data type");
}
return IE::Blob::Ptr{};
}
@@ -190,13 +190,23 @@ inline IE::Blob::Ptr wrapIE(const cv::MediaFrame::View& view,
return wrapIE(gray, cv::gapi::ie::TraitAs::IMAGE);
}
default:
GAPI_Assert(false && "Unsupported media format for IE backend");
GAPI_Error("Unsupported media format for IE backend");
}
GAPI_Assert(false);
GAPI_Error("InternalError");
}
template<class MatType>
inline void copyFromIE(const IE::Blob::Ptr &blob, MatType &mat) {
const auto& desc = blob->getTensorDesc();
const auto ie_type = toCV(desc.getPrecision());
if (ie_type != mat.type()) {
std::stringstream ss;
ss << "Failed to copy blob from IE to OCV: "
<< "Blobs have different data types "
<< "(IE type: " << ie_type
<< " vs OCV type: " << mat.type() << ")." << std::endl;
throw std::logic_error(ss.str());
}
switch (blob->getTensorDesc().getPrecision()) {
#define HANDLE(E,T) \
case IE::Precision::E: std::copy_n(blob->buffer().as<T*>(), \
@@ -215,7 +225,7 @@ inline void copyFromIE(const IE::Blob::Ptr &blob, MatType &mat) {
mat.total());
break;
}
default: GAPI_Assert(false && "IE. Unsupported data type");
default: GAPI_Error("IE. Unsupported data type");
}
}
@@ -365,6 +375,13 @@ struct IEUnit {
cv::util::throw_error(std::logic_error("Unsupported ParamDesc::Kind"));
}
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import &&
!cv::util::holds_alternative<cv::util::monostate>(params.output_precision)) {
cv::util::throw_error(
std::logic_error("Setting output precision isn't supported for imported network"));
}
using namespace cv::gapi::wip::onevpl;
if (params.vpl_preproc_device.has_value() && params.vpl_preproc_ctx.has_value()) {
using namespace cv::gapi::wip;
@@ -375,6 +392,12 @@ struct IEUnit {
params.vpl_preproc_ctx.value());
GAPI_LOG_INFO(nullptr, "VPP preproc created successfuly");
}
if (params.mode == cv::gapi::ie::InferMode::Sync &&
params.nireq != 1u) {
throw std::logic_error(
"Failed: cv::gapi::ie::InferMode::Sync works only with nireq equal to 1.");
}
}
// This method is [supposed to be] called at Island compilation stage
@@ -416,7 +439,7 @@ void IEUnit::InputFramesDesc::set_param(const input_name_type &input,
if (layout != InferenceEngine::NHWC && layout != InferenceEngine::NCHW) {
GAPI_LOG_WARNING(nullptr, "Unsupported layout for VPP preproc: " << layout <<
", input name: " << input);
GAPI_Assert(false && "Unsupported layout for VPP preproc");
GAPI_Error("Unsupported layout for VPP preproc");
}
GAPI_Assert(inDims.size() == 4u);
ret.size.width = static_cast<int>(inDims[3]);
@@ -731,7 +754,7 @@ inline IE::Blob::Ptr extractBlob(IECallContext& ctx,
NV12ParamType* blob_params = cv::util::any_cast<NV12ParamType>(&any_blob_params);
if (blob_params == nullptr) {
GAPI_Assert(false && "Incorrect type of blobParams:"
GAPI_Error("Incorrect type of blobParams:"
"expected std::pair<ParamType, ParamType>,"
"with ParamType std::pair<InferenceEngine::TensorDesc,"
"InferenceEngine::ParamMap >>");
@@ -759,7 +782,7 @@ inline IE::Blob::Ptr extractBlob(IECallContext& ctx,
default:
GAPI_Assert("Unsupported input shape for IE backend");
}
GAPI_Assert(false);
GAPI_Error("InternalError");
}
@@ -826,40 +849,130 @@ std::vector<InferenceEngine::InferRequest> cv::gimpl::ie::IECompiled::createInfe
return requests;
}
class cv::gimpl::ie::RequestPool {
class IInferExecutor {
public:
using RunF = std::function<void(InferenceEngine::InferRequest&)>;
using CallbackF = std::function<void(InferenceEngine::InferRequest&, InferenceEngine::StatusCode)>;
using Ptr = std::shared_ptr<IInferExecutor>;
using NotifyCallbackF = std::function<void()>;
using SetInputDataF = std::function<void(InferenceEngine::InferRequest&)>;
using ReadOutputDataF = std::function<void(InferenceEngine::InferRequest&, InferenceEngine::StatusCode)>;
// NB: The task is represented by:
// RunF - function which is set blobs and run async inference.
// CallbackF - function which is obtain output blobs and post it to output.
// SetInputDataF - function which set input data.
// ReadOutputDataF - function which read output data.
struct Task {
RunF run;
CallbackF callback;
SetInputDataF set_input_data;
ReadOutputDataF read_output_data;
};
explicit RequestPool(std::vector<InferenceEngine::InferRequest>&& requests);
IInferExecutor(IE::InferRequest request, NotifyCallbackF notify)
: m_request(std::move(request)),
m_notify(std::move(notify)) {
};
void execute(Task&& t);
void waitAll();
virtual void execute(const Task& task) = 0;
virtual ~IInferExecutor() = default;
protected:
IE::InferRequest m_request;
NotifyCallbackF m_notify;
};
class SyncInferExecutor : public IInferExecutor {
using IInferExecutor::IInferExecutor;
virtual void execute(const IInferExecutor::Task& task) override;
};
void SyncInferExecutor::execute(const IInferExecutor::Task& task) {
try {
task.set_input_data(m_request);
m_request.Infer();
task.read_output_data(m_request, IE::StatusCode::OK);
} catch (...) {
m_notify();
throw;
}
// NB: Notify pool that executor has finished.
m_notify();
}
class AsyncInferExecutor : public IInferExecutor {
public:
using IInferExecutor::IInferExecutor;
virtual void execute(const IInferExecutor::Task& task) override;
private:
void callback(Task task,
size_t id,
IE::InferRequest request,
IE::StatusCode code) noexcept;
void setup();
QueueClass<size_t> m_idle_ids;
std::vector<InferenceEngine::InferRequest> m_requests;
};
// RequestPool implementation //////////////////////////////////////////////
cv::gimpl::ie::RequestPool::RequestPool(std::vector<InferenceEngine::InferRequest>&& requests)
: m_requests(std::move(requests)) {
setup();
void AsyncInferExecutor::execute(const IInferExecutor::Task& task) {
using namespace std::placeholders;
using callback_t = std::function<void(IE::InferRequest, IE::StatusCode)>;
m_request.SetCompletionCallback(
static_cast<callback_t>(
std::bind(&AsyncInferExecutor::callback, this, task, _1, _2)));
try {
task.set_input_data(m_request);
m_request.StartAsync();
} catch (...) {
m_request.SetCompletionCallback([](){});
m_notify();
throw;
}
}
void AsyncInferExecutor::callback(IInferExecutor::Task task,
IE::InferRequest request,
IE::StatusCode code) noexcept {
task.read_output_data(request, code);
request.SetCompletionCallback([](){});
// NB: Notify pool that executor has finished.
m_notify();
}
class cv::gimpl::ie::RequestPool {
public:
explicit RequestPool(cv::gapi::ie::InferMode mode,
std::vector<InferenceEngine::InferRequest>&& requests);
IInferExecutor::Ptr getIdleRequest();
void waitAll();
private:
void setup();
void release(const size_t id);
QueueClass<size_t> m_idle_ids;
std::vector<IInferExecutor::Ptr> m_requests;
};
void cv::gimpl::ie::RequestPool::release(const size_t id) {
m_idle_ids.push(id);
}
// RequestPool implementation //////////////////////////////////////////////
cv::gimpl::ie::RequestPool::RequestPool(cv::gapi::ie::InferMode mode,
std::vector<InferenceEngine::InferRequest>&& requests) {
for (size_t i = 0; i < requests.size(); ++i) {
IInferExecutor::Ptr iexec = nullptr;
switch (mode) {
case cv::gapi::ie::InferMode::Async:
iexec = std::make_shared<AsyncInferExecutor>(std::move(requests[i]),
std::bind(&RequestPool::release, this, i));
break;
case cv::gapi::ie::InferMode::Sync:
iexec = std::make_shared<SyncInferExecutor>(std::move(requests[i]),
std::bind(&RequestPool::release, this, i));
break;
default:
GAPI_Error("Unsupported cv::gapi::ie::InferMode");
}
m_requests.emplace_back(std::move(iexec));
}
setup();
}
void cv::gimpl::ie::RequestPool::setup() {
for (size_t i = 0; i < m_requests.size(); ++i) {
@@ -867,40 +980,10 @@ void cv::gimpl::ie::RequestPool::setup() {
}
}
void cv::gimpl::ie::RequestPool::execute(cv::gimpl::ie::RequestPool::Task&& t) {
IInferExecutor::Ptr cv::gimpl::ie::RequestPool::getIdleRequest() {
size_t id = 0u;
m_idle_ids.pop(id);
auto& request = m_requests[id];
using namespace std::placeholders;
using callback_t = std::function<void(IE::InferRequest, IE::StatusCode)>;
request.SetCompletionCallback(
static_cast<callback_t>(
std::bind(&cv::gimpl::ie::RequestPool::callback, this,
t, id, _1, _2)));
// NB: InferRequest is already marked as busy
// in case of exception need to return it back to the idle.
try {
t.run(request);
} catch (...) {
request.SetCompletionCallback([](){});
m_idle_ids.push(id);
throw;
}
}
void cv::gimpl::ie::RequestPool::callback(cv::gimpl::ie::RequestPool::Task task,
size_t id,
IE::InferRequest request,
IE::StatusCode code) noexcept {
// NB: Inference is over.
// 1. Run callback
// 2. Destroy callback to free resources.
// 3. Mark InferRequest as idle.
task.callback(request, code);
request.SetCompletionCallback([](){});
m_idle_ids.push(id);
return m_requests[id];
}
// NB: Not thread-safe.
@@ -927,7 +1010,7 @@ cv::gimpl::ie::GIEExecutable::GIEExecutable(const ade::Graph &g,
if (this_nh == nullptr) {
this_nh = nh;
this_iec = iem.metadata(this_nh).get<IEUnit>().compile();
m_reqPool.reset(new RequestPool(this_iec.createInferRequests()));
m_reqPool.reset(new RequestPool(this_iec.params.mode, this_iec.createInferRequests()));
}
else
util::throw_error(std::logic_error("Multi-node inference is not supported!"));
@@ -1061,7 +1144,7 @@ static void configureInputReshapeByImage(const IE::InputInfo::Ptr& ii,
auto input_dims = ii->getTensorDesc().getDims();
const auto size = input_dims.size();
if (size <= 1) {
GAPI_Assert(false && "Unsupported number of dimensions for reshape by image");
GAPI_Error("Unsupported number of dimensions for reshape by image");
}
input_dims.at(size - 2) = static_cast<size_t>(image_sz.height);
input_dims.at(size - 1) = static_cast<size_t>(image_sz.width);
@@ -1090,7 +1173,7 @@ static void configureInputInfo(const IE::InputInfo::Ptr& ii, const cv::GMetaArg
// NB: Do nothing
break;
default:
GAPI_Assert(false && "Unsupported media format for IE backend");
GAPI_Error("Unsupported media format for IE backend");
}
ii->setPrecision(toIE(CV_8U));
break;
@@ -1122,6 +1205,28 @@ static IE::PreProcessInfo configurePreProcInfo(const IE::InputInfo::CPtr& ii,
return info;
}
using namespace cv::gapi::ie::detail;
static void configureOutputPrecision(const IE::OutputsDataMap &outputs_info,
const ParamDesc::PrecisionVariantT &output_precision) {
cv::util::visit(cv::util::overload_lambdas(
[&outputs_info](ParamDesc::PrecisionT cvdepth) {
auto precision = toIE(cvdepth);
for (auto it : outputs_info) {
it.second->setPrecision(precision);
}
},
[&outputs_info](const ParamDesc::PrecisionMapT& precision_map) {
for (auto it : precision_map) {
outputs_info.at(it.first)->setPrecision(toIE(it.second));
}
},
[&outputs_info](cv::util::monostate) {
// Do nothing.
}
), output_precision
);
}
// NB: This is a callback used by async infer
// to post outputs blobs (cv::GMat's).
static void PostOutputs(InferenceEngine::InferRequest &request,
@@ -1241,7 +1346,7 @@ struct Infer: public cv::detail::KernelTag {
GAPI_Assert(uu.params.input_names.size() == in_metas.size()
&& "Known input layers count doesn't match input meta count");
// NB: Configuring input precision and network reshape must be done
// NB: Configuring input/output precision and network reshape must be done
// only in the loadNetwork case.
using namespace cv::gapi::ie::detail;
if (uu.params.kind == ParamDesc::Kind::Load) {
@@ -1275,6 +1380,7 @@ struct Infer: public cv::detail::KernelTag {
if (!input_reshape_table.empty()) {
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
}
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
} else {
GAPI_Assert(uu.params.kind == ParamDesc::Kind::Import);
auto inputs = uu.this_network.GetInputsInfo();
@@ -1316,8 +1422,8 @@ struct Infer: public cv::detail::KernelTag {
static void run(std::shared_ptr<IECallContext> ctx,
cv::gimpl::ie::RequestPool &reqPool) {
using namespace std::placeholders;
reqPool.execute(
cv::gimpl::ie::RequestPool::Task {
reqPool.getIdleRequest()->execute(
IInferExecutor::Task {
[ctx](InferenceEngine::InferRequest &req) {
// non-generic version for now:
// - assumes all inputs/outputs are always Mats
@@ -1335,9 +1441,6 @@ struct Infer: public cv::detail::KernelTag {
cv::util::optional<cv::Rect>{});
setBlob(req, layer_name, this_blob, *ctx);
}
// FIXME: Should it be done by kernel ?
// What about to do that in RequestPool ?
req.StartAsync();
},
std::bind(PostOutputs, _1, _2, ctx)
}
@@ -1393,6 +1496,7 @@ struct InferROI: public cv::detail::KernelTag {
const_cast<IEUnit::InputFramesDesc &>(uu.net_input_params)
.set_param(input_name, ii->getTensorDesc());
}
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
} else {
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
auto inputs = uu.this_network.GetInputsInfo();
@@ -1429,8 +1533,8 @@ struct InferROI: public cv::detail::KernelTag {
static void run(std::shared_ptr<IECallContext> ctx,
cv::gimpl::ie::RequestPool &reqPool) {
using namespace std::placeholders;
reqPool.execute(
cv::gimpl::ie::RequestPool::Task {
reqPool.getIdleRequest()->execute(
IInferExecutor::Task {
[ctx](InferenceEngine::InferRequest &req) {
GAPI_Assert(ctx->uu.params.num_in == 1);
auto&& this_roi = ctx->inArg<cv::detail::OpaqueRef>(0).rref<cv::Rect>();
@@ -1455,9 +1559,6 @@ struct InferROI: public cv::detail::KernelTag {
*(ctx->uu.params.input_names.begin()),
this_blob, *ctx);
}
// FIXME: Should it be done by kernel ?
// What about to do that in RequestPool ?
req.StartAsync();
},
std::bind(PostOutputs, _1, _2, ctx)
}
@@ -1513,6 +1614,7 @@ struct InferList: public cv::detail::KernelTag {
if (!input_reshape_table.empty()) {
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
}
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
} else {
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
std::size_t idx = 1u;
@@ -1571,11 +1673,10 @@ struct InferList: public cv::detail::KernelTag {
for (auto&& it : ade::util::indexed(in_roi_vec)) {
auto pos = ade::util::index(it);
const auto& rc = ade::util::value(it);
reqPool.execute(
cv::gimpl::ie::RequestPool::Task {
reqPool.getIdleRequest()->execute(
IInferExecutor::Task {
[ctx, rc, this_blob](InferenceEngine::InferRequest &req) {
setROIBlob(req, ctx->uu.params.input_names[0u], this_blob, rc, *ctx);
req.StartAsync();
},
std::bind(callback, std::placeholders::_1, std::placeholders::_2, pos)
}
@@ -1667,6 +1768,7 @@ struct InferList2: public cv::detail::KernelTag {
if (!input_reshape_table.empty()) {
const_cast<IE::CNNNetwork *>(&uu.net)->reshape(input_reshape_table);
}
configureOutputPrecision(uu.net.getOutputsInfo(), uu.params.output_precision);
} else {
GAPI_Assert(uu.params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import);
auto inputs = uu.this_network.GetInputsInfo();
@@ -1727,8 +1829,8 @@ struct InferList2: public cv::detail::KernelTag {
PostOutputsList callback(list_size, ctx, std::move(cached_dims));
for (const auto &list_idx : ade::util::iota(list_size)) {
reqPool.execute(
cv::gimpl::ie::RequestPool::Task {
reqPool.getIdleRequest()->execute(
IInferExecutor::Task {
[ctx, list_idx, list_size, blob_0](InferenceEngine::InferRequest &req) {
for (auto in_idx : ade::util::iota(ctx->uu.params.num_in)) {
const auto &this_vec = ctx->inArg<cv::detail::VectorRef>(in_idx+1u);
@@ -1748,7 +1850,6 @@ struct InferList2: public cv::detail::KernelTag {
"Only Rect and Mat types are supported for infer list 2!");
}
}
req.StartAsync();
},
std::bind(callback, std::placeholders::_1, std::placeholders::_2, list_idx)
} // task
+2 -2
View File
@@ -62,12 +62,12 @@ public:
virtual inline bool canReshape() const override { return false; }
virtual inline void reshape(ade::Graph&, const GCompileArgs&) override {
GAPI_Assert(false); // Not implemented yet
GAPI_Error("InternalError"); // Not implemented yet
}
virtual void run(std::vector<InObj> &&,
std::vector<OutObj> &&) override {
GAPI_Assert(false && "Not implemented");
GAPI_Error("Not implemented");
}
virtual void run(GIslandExecutable::IInput &in,
+9 -12
View File
@@ -39,7 +39,7 @@ class GOAKExecutable final: public GIslandExecutable {
friend class OAKKernelParams;
virtual void run(std::vector<InObj>&&,
std::vector<OutObj>&&) override {
GAPI_Assert(false && "Not implemented");
GAPI_Error("Not implemented");
}
virtual void run(GIslandExecutable::IInput &in,
@@ -121,7 +121,7 @@ public:
// FIXME: could it reshape?
virtual bool canReshape() const override { return false; }
virtual void reshape(ade::Graph&, const GCompileArgs&) override {
GAPI_Assert(false && "GOAKExecutable::reshape() is not supported");
GAPI_Error("GOAKExecutable::reshape() is not supported");
}
virtual void handleNewStream() override;
@@ -391,7 +391,7 @@ void cv::gimpl::GOAKExecutable::linkCopy(ade::NodeHandle handle) {
for (const auto& copy_next_op : copy_out.front().get()->outNodes()) {
const auto& op = m_gm.metadata(copy_next_op).get<Op>();
if (op.k.name == "org.opencv.oak.copy") {
GAPI_Assert(false && "Back-to-back Copy operations are not supported in graph");
GAPI_Error("Back-to-back Copy operations are not supported in graph");
}
}
@@ -701,14 +701,14 @@ cv::gimpl::GOAKExecutable::GOAKExecutable(const ade::Graph& g,
[](ExtractTypeHelper::InputPtr ptr) {
return ptr == nullptr;
})) {
GAPI_Assert(false && "DAI input are not set");
GAPI_Error("DAI input are not set");
}
if (std::any_of(node_info.outputs.cbegin(), node_info.outputs.cend(),
[](ExtractTypeHelper::OutputPtr ptr) {
return ptr == nullptr;
})) {
GAPI_Assert(false && "DAI outputs are not set");
GAPI_Error("DAI outputs are not set");
}
}
}
@@ -907,7 +907,7 @@ void cv::gimpl::GOAKExecutable::run(GIslandExecutable::IInput &in,
}
// FIXME: Add support for remaining types
default:
GAPI_Assert(false && "Unsupported type in OAK backend");
GAPI_Error("Unsupported type in OAK backend");
}
out.meta(out_arg, meta);
@@ -1080,7 +1080,7 @@ class GOAKBackendImpl final : public cv::gapi::GBackend::Priv {
// NB: how could we have non-OAK source in streaming mode, then OAK backend in
// streaming mode but without camera input?
if (!gm.metadata().contains<cv::gimpl::Streaming>()) {
GAPI_Assert(false && "OAK backend only supports Streaming mode for now");
GAPI_Error("OAK backend only supports Streaming mode for now");
}
return EPtr{new cv::gimpl::GOAKExecutable(graph, args, nodes, ins_data, outs_data)};
}
@@ -1118,14 +1118,11 @@ namespace gapi {
namespace oak {
cv::gapi::GKernelPackage kernels() {
GAPI_Assert(false && "Built without OAK support");
return {};
GAPI_Error("Built without OAK support");
}
cv::gapi::GBackend backend() {
GAPI_Assert(false && "Built without OAK support");
static cv::gapi::GBackend this_backend(nullptr);
return this_backend;
GAPI_Error("Built without OAK support");
}
} // namespace oak
@@ -114,7 +114,8 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
GAPI_Assert( arg.kind != cv::detail::ArgKind::GMAT
&& arg.kind != cv::detail::ArgKind::GSCALAR
&& arg.kind != cv::detail::ArgKind::GARRAY
&& arg.kind != cv::detail::ArgKind::GOPAQUE);
&& arg.kind != cv::detail::ArgKind::GOPAQUE
&& arg.kind != cv::detail::ArgKind::GFRAME);
if (arg.kind != cv::detail::ArgKind::GOBJREF)
{
@@ -136,6 +137,7 @@ cv::GArg cv::gimpl::GOCLExecutable::packArg(const GArg &arg)
// Note: .at() is intentional for GOpaque as object MUST be already there
// (and constructed by either bindIn/Out or resetInternal)
case GShape::GOPAQUE: return GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id));
case GShape::GFRAME: return GArg(m_res.slot<cv::MediaFrame>().at(ref.id));
default:
util::throw_error(std::logic_error("Unsupported GShape type"));
break;
@@ -6,11 +6,32 @@
#include "precomp.hpp"
#include "logger.hpp"
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/ocl/core.hpp>
#include <opencv2/gapi/util/throw.hpp>
#include "backends/ocl/goclcore.hpp"
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#pragma comment(lib,"d3d11.lib")
// get rid of generate macro max/min/etc from DX side
#define D3D11_NO_HELPERS
#define NOMINMAX
#include <d3d11.h>
#pragma comment(lib, "dxgi")
#undef NOMINMAX
#undef D3D11_NO_HELPERS
#include <opencv2/core/directx.hpp>
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
#include <opencv2/core/ocl.hpp>
#include "streaming/onevpl/accelerators/surface/dx11_frame_adapter.hpp"
GAPI_OCL_KERNEL(GOCLAdd, cv::gapi::core::GAdd)
{
static void run(const cv::UMat& a, const cv::UMat& b, int dtype, cv::UMat& out)
@@ -523,6 +544,79 @@ GAPI_OCL_KERNEL(GOCLTranspose, cv::gapi::core::GTranspose)
}
};
GAPI_OCL_KERNEL(GOCLBGR, cv::gapi::streaming::GBGR)
{
static void run(const cv::MediaFrame& in, cv::UMat& out)
{
cv::util::suppress_unused_warning(in);
cv::util::suppress_unused_warning(out);
#ifdef HAVE_DIRECTX
#ifdef HAVE_D3D11
#ifdef HAVE_ONEVPL
auto d = in.desc();
if (d.fmt != cv::MediaFormat::NV12)
{
GAPI_LOG_FATAL(nullptr, "Unsupported format provided: " << static_cast<int>(d.fmt) <<
". Expected cv::MediaFormat::NV12.");
cv::util::throw_error(std::logic_error("Unsupported MediaFrame format provided"));
}
// FIXME: consider a better solution.
// Current approach cannot be easily extended for other adapters (getHandle).
auto adapterPtr = in.get<cv::gapi::wip::onevpl::VPLMediaFrameDX11Adapter>();
if (adapterPtr == nullptr)
{
GAPI_LOG_FATAL(nullptr, "Unsupported adapter type. Only VPLMediaFrameDX11Adapter is supported");
cv::util::throw_error(std::logic_error("Unsupported adapter type. Only VPLMediaFrameDX11Adapter is supported"));
}
auto params = adapterPtr->getHandle();
auto handle = cv::util::any_cast<mfxHDLPair>(params);
ID3D11Texture2D* texture = reinterpret_cast<ID3D11Texture2D*>(handle.first);
if (texture == nullptr)
{
GAPI_LOG_FATAL(nullptr, "mfxHDLPair contains ID3D11Texture2D that is nullptr. Handle address" <<
reinterpret_cast<uint64_t>(handle.first));
cv::util::throw_error(std::logic_error("mfxHDLPair contains ID3D11Texture2D that is nullptr"));
}
// FIXME: Assuming here that we only have 1 device
// TODO: Textures are reusable, so to improve the peroformance here
// consider creating a hash map texture <-> device/ctx
static thread_local ID3D11Device* pD3D11Device = nullptr;
if (pD3D11Device == nullptr)
{
texture->GetDevice(&pD3D11Device);
}
if (pD3D11Device == nullptr)
{
GAPI_LOG_FATAL(nullptr, "D3D11Texture2D::GetDevice returns pD3D11Device that is nullptr");
cv::util::throw_error(std::logic_error("D3D11Texture2D::GetDevice returns pD3D11Device that is nullptr"));
}
// FIXME: assuming here that the context is always the same
// TODO: Textures are reusable, so to improve the peroformance here
// consider creating a hash map texture <-> device/ctx
static thread_local cv::ocl::Context ctx = cv::directx::ocl::initializeContextFromD3D11Device(pD3D11Device);
if (ctx.ptr() == nullptr)
{
GAPI_LOG_FATAL(nullptr, "initializeContextFromD3D11Device returned null context");
cv::util::throw_error(std::logic_error("initializeContextFromD3D11Device returned null context"));
}
cv::directx::convertFromD3D11Texture2D(texture, out);
#else
GAPI_LOG_FATAL(nullptr, "HAVE_ONEVPL is not set. Please, check your cmake flags");
cv::util::throw_error(std::logic_error("HAVE_ONEVPL is not set. Please, check your cmake flags"));
#endif // HAVE_ONEVPL
#else
GAPI_LOG_FATAL(nullptr, "HAVE_D3D11 or HAVE_DIRECTX is not set. Please, check your cmake flags");
cv::util::throw_error(std::logic_error("HAVE_D3D11 or HAVE_DIRECTX is not set. Please, check your cmake flags"));
#endif // HAVE_D3D11
#endif // HAVE_DIRECTX
}
};
cv::GKernelPackage cv::gapi::core::ocl::kernels()
{
static auto pkg = cv::gapi::kernels
@@ -587,6 +681,7 @@ cv::GKernelPackage cv::gapi::core::ocl::kernels()
, GOCLLUT
, GOCLConvertTo
, GOCLTranspose
, GOCLBGR
>();
return pkg;
}
@@ -0,0 +1,24 @@
// 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.
#include <opencv2/gapi/infer/bindings_onnx.hpp>
cv::gapi::onnx::PyParams::PyParams(const std::string& tag,
const std::string& model_path)
: m_priv(std::make_shared<Params<cv::gapi::Generic>>(tag, model_path)) {}
cv::gapi::GBackend cv::gapi::onnx::PyParams::backend() const {
return m_priv->backend();
}
std::string cv::gapi::onnx::PyParams::tag() const { return m_priv->tag(); }
cv::util::any cv::gapi::onnx::PyParams::params() const {
return m_priv->params();
}
cv::gapi::onnx::PyParams cv::gapi::onnx::params(
const std::string& tag, const std::string& model_path) {
return {tag, model_path};
}
+36 -10
View File
@@ -171,7 +171,7 @@ inline int toCV(ONNXTensorElementDataType prec) {
case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT: return CV_32F;
case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32: return CV_32S;
case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64: return CV_32S;
default: GAPI_Assert(false && "ONNX. Unsupported data type");
default: GAPI_Error("ONNX. Unsupported data type");
}
return -1;
}
@@ -207,7 +207,7 @@ inline void copyFromONNX(Ort::Value &v, cv::Mat& mat) {
mat.total());
break;
}
default: GAPI_Assert(false && "ONNX. Unsupported data type");
default: GAPI_Error("ONNX. Unsupported data type");
}
}
@@ -233,7 +233,7 @@ inline void preprocess(const cv::Mat& src,
"32F tensor dimensions should match with all non-dynamic NN input dimensions");
}
} else {
GAPI_Assert(false && "32F tensor size should match with NN input");
GAPI_Error("32F tensor size should match with NN input");
}
dst = src;
@@ -338,7 +338,7 @@ void preprocess(const cv::MediaFrame::View& view,
break;
}
default:
GAPI_Assert(false && "Unsupported media format for ONNX backend");
GAPI_Error("Unsupported media format for ONNX backend");
}
}
@@ -367,7 +367,7 @@ inline Ort::Value createTensor(const Ort::MemoryInfo& memory_info,
case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32:
return createTensor<int32_t>(memory_info, tensor_params, data);
default:
GAPI_Assert(false && "ONNX. Unsupported data type");
GAPI_Error("ONNX. Unsupported data type");
}
return Ort::Value{nullptr};
}
@@ -735,7 +735,8 @@ void ONNXCompiled::extractMat(ONNXCallContext &ctx, const size_t in_idx, Views&
}
}
void ONNXCompiled::setOutput(int i, cv::Mat &m) {
void ONNXCompiled::setOutput(int i, cv::Mat &m)
{
// FIXME: No need in double-indexing?
out_data[i] = m;
}
@@ -857,7 +858,7 @@ static void checkInputMeta(const cv::GMetaArg mm) {
case cv::MediaFormat::NV12: break;
case cv::MediaFormat::BGR: break;
default:
GAPI_Assert(false && "Unsupported media format for ONNX backend");
GAPI_Error("Unsupported media format for ONNX backend");
} break;
} break;
default:
@@ -1100,7 +1101,7 @@ struct InferList2: public cv::detail::KernelTag {
const auto &vec = this_vec.rref<cv::Mat>();
uu.oc->setInput(in_idx, vec[list_idx]);
} else {
GAPI_Assert(false && "Only Rect and Mat types are supported for infer list 2!");
GAPI_Error("Only Rect and Mat types are supported for infer list 2!");
}
// }}} (Prepare input)
} // }}} (For every input of the net)
@@ -1133,9 +1134,34 @@ namespace {
// FIXME: Introduce a DNNBackend interface which'd specify
// the framework for this???
GONNXModel gm(gr);
const auto &np = gm.metadata(nh).get<NetworkParams>();
const auto &pp = cv::util::any_cast<cv::gapi::onnx::detail::ParamDesc>(np.opaque);
auto &np = gm.metadata(nh).get<NetworkParams>();
auto &pp = cv::util::any_cast<cv::gapi::onnx::detail::ParamDesc>(np.opaque);
const auto &ki = cv::util::any_cast<KImpl>(ii.opaque);
GModel::Graph model(gr);
auto& op = model.metadata(nh).get<Op>();
if (pp.is_generic) {
auto& info = cv::util::any_cast<cv::detail::InOutInfo>(op.params);
for (const auto& a : info.in_names)
{
pp.input_names.push_back(a);
}
// Adding const input is necessary because the definition of input_names
// includes const input.
for (const auto& a : pp.const_inputs)
{
pp.input_names.push_back(a.first);
}
pp.num_in = info.in_names.size();
for (const auto& a : info.out_names)
{
pp.output_names.push_back(a);
}
pp.num_out = info.out_names.size();
}
gm.metadata(nh).set(ONNXUnit{pp});
gm.metadata(nh).set(ONNXCallable{ki.run});
gm.metadata(nh).set(CustomMetaFunction{ki.customMetaFunc});
@@ -43,7 +43,7 @@ public:
virtual inline bool canReshape() const override { return false; }
virtual inline void reshape(ade::Graph&, const GCompileArgs&) override {
GAPI_Assert(false); // Not implemented yet
GAPI_Error("InternalError"); // Not implemented yet
}
virtual void run(std::vector<InObj> &&input_objs,
@@ -6,26 +6,25 @@
#include <ade/util/zip_range.hpp> // zip_range, indexed
#include "compiler/gmodel.hpp"
#include <opencv2/gapi/garg.hpp>
#include <opencv2/gapi/util/throw.hpp> // throw_error
#include <opencv2/gapi/python/python.hpp>
#include "api/gbackend_priv.hpp"
#include "backends/common/gbackend.hpp"
cv::gapi::python::GPythonKernel::GPythonKernel(cv::gapi::python::Impl run)
: m_run(run)
cv::gapi::python::GPythonKernel::GPythonKernel(cv::gapi::python::Impl runf,
cv::gapi::python::Setup setupf)
: run(runf), setup(setupf), is_stateful(setup != nullptr)
{
}
cv::GRunArgs cv::gapi::python::GPythonKernel::operator()(const cv::gapi::python::GPythonContext& ctx)
{
return m_run(ctx);
}
cv::gapi::python::GPythonFunctor::GPythonFunctor(const char* id,
const cv::gapi::python::GPythonFunctor::Meta &meta,
const cv::gapi::python::Impl& impl)
: gapi::GFunctor(id), impl_{GPythonKernel{impl}, meta}
const cv::gapi::python::GPythonFunctor::Meta& meta,
const cv::gapi::python::Impl& impl,
const cv::gapi::python::Setup& setup)
: gapi::GFunctor(id), impl_{GPythonKernel{impl, setup}, meta}
{
}
@@ -68,6 +67,7 @@ class GPythonExecutable final: public cv::gimpl::GIslandExecutable
virtual cv::RMat allocate(const cv::GMatDesc&) const override { return {}; }
virtual bool canReshape() const override { return true; }
virtual void handleNewStream() override;
virtual void reshape(ade::Graph&, const cv::GCompileArgs&) override {
// Do nothing here
}
@@ -80,6 +80,7 @@ public:
cv::gimpl::GModel::ConstGraph m_gm;
cv::gapi::python::GPythonKernel m_kernel;
ade::NodeHandle m_op;
cv::GArg m_node_state;
cv::GTypesInfo m_out_info;
cv::GMetaArgs m_in_metas;
@@ -149,10 +150,19 @@ static void writeBack(cv::GRunArg& arg, cv::GRunArgP& out)
break;
}
default:
GAPI_Assert(false && "Unsupported output type");
GAPI_Error("Unsupported output type");
}
}
void GPythonExecutable::handleNewStream()
{
if (!m_kernel.is_stateful)
return;
m_node_state = m_kernel.setup(cv::gimpl::GModel::collectInputMeta(m_gm, m_op),
m_gm.metadata(m_op).get<cv::gimpl::Op>().args);
}
void GPythonExecutable::run(std::vector<InObj> &&input_objs,
std::vector<OutObj> &&output_objs)
{
@@ -165,9 +175,15 @@ void GPythonExecutable::run(std::vector<InObj> &&input_objs,
std::back_inserter(inputs),
std::bind(&packArg, std::ref(m_res), _1));
cv::gapi::python::GPythonContext ctx{inputs, m_in_metas, m_out_info, /*state*/{}};
cv::gapi::python::GPythonContext ctx{inputs, m_in_metas, m_out_info};
auto outs = m_kernel(ctx);
// NB: For stateful kernel add state to its execution context
if (m_kernel.is_stateful)
{
ctx.m_state = cv::optional<cv::GArg>(m_node_state);
}
auto outs = m_kernel.run(ctx);
for (auto&& it : ade::util::zip(outs, output_objs))
{
@@ -225,6 +241,12 @@ GPythonExecutable::GPythonExecutable(const ade::Graph& g,
m_op = *it;
m_kernel = cag.metadata(m_op).get<PythonUnit>().kernel;
// If kernel is stateful then prepare storage for its state.
if (m_kernel.is_stateful)
{
m_node_state = cv::GArg{ };
}
// Ensure this the only op in the graph
if (std::any_of(it+1, nodes.end(), is_op))
{
@@ -42,7 +42,7 @@ class GStreamingIntrinExecutable final: public cv::gimpl::GIslandExecutable
{
virtual void run(std::vector<InObj> &&,
std::vector<OutObj> &&) override {
GAPI_Assert(false && "Not implemented");
GAPI_Error("Not implemented");
}
virtual void run(GIslandExecutable::IInput &in,
@@ -188,7 +188,7 @@ void Copy::Actor::run(cv::gimpl::GIslandExecutable::IInput &in,
break;
// FIXME: Add support for remaining types
default:
GAPI_Assert(false && "Copy: unsupported data type");
GAPI_Error("Copy: unsupported data type");
}
out.meta(out_arg, in_arg.meta);
out.post(std::move(out_arg));