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:
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user