CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
[G-API] Implement OpenVINO 2.0 backend #23595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[G-API] Implement OpenVINO 2.0 backend #23595
Conversation
EXPECT_LE(normInf, lInf) << comment; | ||
} | ||
|
||
ov::Core getCore() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it fine to use the different ov::Core
than it's in GOVBackend
? (I think so)
static constexpr const char* tag = "age-gender-generic"; | ||
using Params = cv::gapi::ov::Params<cv::gapi::Generic>; | ||
|
||
static Params params(const std::string &xml, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be variadic with by passing all parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cosmetic, ignore so far
explicit OVUnit(const ParamDesc &pd) | ||
: params(pd) { | ||
|
||
if (cv::util::holds_alternative<ParamDesc::IR>(params.kind)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we need this logic encapsulated somewhere not to check it everywhere!!!
for (auto i : ade::util::iota(ctx->uu.params.num_in)) { | ||
const auto& input_name = ctx->uu.params.input_names[i]; | ||
auto input_tensor = infer_request.get_tensor(input_name); | ||
copyToOV(ctx->inMat(i), input_tensor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in fact it might be faster for "some" plugins to copy to pre-allocated buffer instead of creating another one over the cv::Mat
memory without copy. The same for output - let plugin write to its own buffer and them copy from there.
They way of how to set/get data from openvino
can be the strategy... (worth to add TODO at least)
@dmatveev, @smirnov-alexey Folks! Could you have a look, please? |
c992b85
to
fce1678
Compare
Could you help me to understand what exactly goes wrong with that error: /build/precommit_docs/4.x/opencv/modules/python/src2/typing_stubs_generator.py:52: UserWarning: Typing stubs generation has failed. Reason: Failed to resolve "cv2" namespace against "None". Errors: ['Failed to resolve "cv2.gapi" namespace against "cv2". Errors: ['Failed to resolve "cv2.gapi.ov" namespace against "cv2". Errors: [\'Failed to resolve "cv2.gapi.ov.PyParams" class against "cv2". Errors: [\\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgPluginConfig" function against "cv2". Errors: [0]: Failed to resolve "config" argument: Failed to resolve "map_string_and_string" exposed as "map_string_and_string"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgInputTensorLayout" function against "cv2". Errors: [0]: Failed to resolve "layout_map" argument: Failed to resolve "map_string_and_string" exposed as "map_string_and_string"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgInputModelLayout" function against "cv2". Errors: [0]: Failed to resolve "layout_map" argument: Failed to resolve "map_string_and_string" exposed as "map_string_and_string"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgOutputTensorLayout" function against "cv2". Errors: [0]: Failed to resolve "layout_map" argument: Failed to resolve "map_string_and_string" exposed as "map_string_and_string"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgOutputModelLayout" function against "cv2". Errors: [0]: Failed to resolve "layout_map" argument: Failed to resolve "map_string_and_string" exposed as "map_string_and_string"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgOutputTensorPrecision" function against "cv2". Errors: [0]: Failed to resolve "precision_map" argument: Failed to resolve "map_string_and_int" exposed as "map_string_and_int"\\\', \\\'Failed to resolve "cv2.gapi.ov.PyParams.cfgReshape" function against "cv2". Errors: [0]: Failed to resolve "new_shape_map" argument: Failed to resolve "map_string_and_vector_size_t" exposed as "map_string_and_vector_size_t"\\\']\']']'] |
@TolyaTalamanov, seems related to #20370 (probably, need to be added something here: https://github.com/opencv/opencv/pull/20370/files#diff-d7f280d2a075f044f0b9720fa39e3fff9a6346c3a8eccb0cf588f0b7e52a9f6bR132-R138) |
auto batch_layout = (matdesc.dims[1] == 3 || matdesc.dims[1] == 1) | ||
? ::ov::Layout("NCHW") : ::ov::Layout("NHWC"); | ||
|
||
cv::Size spatial_size = (matdesc.dims[1] == 3 || matdesc.dims[1] == 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or spatial_size can be obtained from tensor_layout
if such explicitly specified by user
Supported algorithms: #INTER_NEAREST, #INTER_LINEAR, #INTER_CUBIC. | ||
@return reference to this parameter structure. | ||
*/ | ||
Params<Net>& cfgResize(int interpolation) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a default value here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, probably but then there won't be any default value for map
case?
} | ||
|
||
/** @see ov::Params::cfgPluginConfig. */ | ||
Params& cfgPluginConfig(const detail::ParamDesc::PluginConfigT &config) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, is there a way to avoid copy-paste for generic params?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find, template specialization or inheritance won't work there because it returns Params&
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CRTP would?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But don't do it now to expedite merge, just leave a TODO.
skip_if_openvino_not_available() | ||
|
||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013' | ||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we utilize other models here? E.g. .onnx
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're using a couple of them for ONNX
backend tests.
# Check | ||
self.assertEqual(0.0, cv.norm(ov_gender, gapi_gender, cv.NORM_INF)) | ||
self.assertEqual(0.0, cv.norm(ov_age, gapi_age, cv.NORM_INF)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about testing invalid cases? Where we get G-API or OV throwing an exception
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, there is not much invalid
cases. The validation is only happens for Image
case where the layout is being validated to be NHWC
for other case there should be check that mat
dims matches to tensor
dims I added TODO
for that
if (desc.planar) os << "p"; | ||
os << " "; | ||
os << desc.size.width << "x" << desc.size.height; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't it break our serialization? Is there a >>
operator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, as S11N is not using i/ostream as LHS operand for <<.
} | ||
|
||
cv::gapi::ov::PyParams& | ||
cv::gapi::ov::PyParams::cfgPluginConfig( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we have both general params and generic ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What stands for general
?
In C++
we have templated params and their specialization for generic
case.
For python there is only generic
params are relevant.
// NB: These functions are EXPORTed to make them accessible by the | ||
// test suite only. | ||
GAPI_EXPORTS std::vector<int> to_ocv(const ::ov::Shape &shape); | ||
GAPI_EXPORTS int to_ocv(const ::ov::element::Type &type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest implementing those in utils.cpp
or hiding if it's not being used outside
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only for our tests. Is there any difference in terms of where implementation should be placed?
govbackend.cpp
our sources
that are not exposed to user.
@@ -227,6 +227,12 @@ inline void convertInt64ToInt32(const int64_t* src, int* dst, size_t size) | |||
[](int64_t el) { return static_cast<int>(el); }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggesting int32_t
here2, just in case
// (and constructed by either bindIn/Out or resetInternal) | ||
case cv::GShape::GOPAQUE: return cv::GArg(m_res.slot<cv::detail::OpaqueRef>().at(ref.id)); | ||
|
||
case cv::GShape::GFRAME: return cv::GArg(m_res.slot<cv::MediaFrame>().at(ref.id)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove it from here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, make sense
|
||
const cv::MediaFrame& OVCallContext::inFrame(std::size_t input) const { | ||
return inArg<cv::MediaFrame>(input); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove it for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea
m_request.set_callback([](std::exception_ptr){}); | ||
m_notify(); | ||
throw; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we notify in the end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually we notify in the callback
but here execution failed earlier
|
||
IInferExecutor::Ptr cv::gimpl::ov::RequestPool::getIdleRequest() { | ||
size_t id = 0u; | ||
m_idle_ids.pop(id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we set those to 0
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setup()
fills m_idle_ids
return (model_shape.size() == 4u) && | ||
(!desc.isND()) /* dims == 2 */ && | ||
(desc.chan == 1 || desc.chan == 3) && | ||
(desc.size.height != 1 && desc.size.width != 1) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw do you remember if we might have any non-1 dims in some of our cases which are still tensors? (e.g. 2, 3, other small numbers which are definitely are not images)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can have Mat({15, 14}, CV_8UC1)
but in this case model apparently will have 2D
dimensions for that input so that it would be TENSOR
for us
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is that 2D
mats may work with 4D
model shape only in case of IMAGE
.
For TENSOR
number of dims must match model shape size. (good point for comment)
|
||
static bool isImage(const cv::GMatDesc &desc, | ||
const ::ov::Shape &model_shape) { | ||
return (model_shape.size() == 4u) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it be 3? Let's say if users/opencv doesn't provide N somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User doesn't provide anything. model_shape
comes from IR
/ ov::Model
and in all cases for real image
models have 4D
layout in OpenVINO
.
// NB: Double check that user provided correct layout. | ||
// In fact, there is only one correct for image. | ||
if (explicit_in_tensor_layout) { | ||
if (*explicit_in_tensor_layout != "NHWC") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can combine those 2 if
s
? ::ov::Layout(*explicit_in_tensor_layout) : model_layout; | ||
const auto H_idx = ::ov::layout::height_idx(layout); | ||
const auto W_idx = ::ov::layout::width_idx(layout); | ||
// NB: It still possible if layout is "??HW". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document that in our doc and/or code
input_info.preprocess().resize(toOVInterp(*explicit_resize)); | ||
} | ||
} else { | ||
// NB: 2D case - know exactly where H and W... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add some debug messages here other that throws? I mean what we assume in which case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here = part with image/tensor logic. Messages = at least comments you put here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks great! Although, please answer my comments
I hope I addressed everthing... |
@asmorkalov could you please have a look at this one? The CI failure looks irrelevant
|
Restarted the failed build. Looks like we need to tune limits. Windows host is overbooked time to time. |
Yay! Thanks & congrats! A big step forward! |
…vino-backend [G-API] Implement OpenVINO 2.0 backend opencv#23595 ### Pull Request Readiness Checklist Implemented basic functionality for `OpenVINO` 2.0 G-API backend. #### Overview - [x] Implement `Infer` kernel with some of essential configurable parameters + IR/Blob models format support. - [ ] Implement the rest of kernels: `InferList`, `InferROI`, `Infer2` + other configurable params (e.g reshape) - [x] Asyncrhonous execution support - [ ] Remote context support See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
…vino-backend [G-API] Implement OpenVINO 2.0 backend opencv#23595 ### Pull Request Readiness Checklist Implemented basic functionality for `OpenVINO` 2.0 G-API backend. #### Overview - [x] Implement `Infer` kernel with some of essential configurable parameters + IR/Blob models format support. - [ ] Implement the rest of kernels: `InferList`, `InferROI`, `Infer2` + other configurable params (e.g reshape) - [x] Asyncrhonous execution support - [ ] Remote context support See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
Pull Request Readiness Checklist
Implemented basic functionality for
OpenVINO
2.0 G-API backend.Overview
Infer
kernel with some of essential configurable parameters + IR/Blob models format support.InferList
,InferROI
,Infer2
+ other configurable params (e.g reshape)See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.