CARVIEW |
Navigation Menu
-
-
Notifications
You must be signed in to change notification settings - Fork 56.2k
dnn: support ONNX Slice with negative steps by adding and using cv::flipND #22898
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
Conversation
6fa9abd
to
0a12d7d
Compare
@alalek I have added tests for both flipND and Slice with negative steps. Any test is missing here? |
@fengyuentau Labels |
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.
Thank you for your contribution! I think in the future we should split this kind of PRs in two. One in core only, and another one to dnn.
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.
LGTM! 👍
789a0b2
to
a9ea876
Compare
@alalek May we merge this patch? |
} | ||
else | ||
{ | ||
flipNDImpl(src.ptr(), shape, step, dst.ptr(), axis); |
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.
dst step is not handled and not checked.
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 you mean I should check whether dst steps are the same with src steps?
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, btw in case of ROI we could just overlap not from the beggining. @alalek do we have a method that checks if mats are non-overlapping?
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.
Perhaps there is no such method.
We could do simple check overlap between .data
/ .dataend
here (it is not fully accurate, e.g. for 1d cases)
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 think we should just check if .data
s are equal (if it's the start of the allocation, might be .datastart
instead). It's not ideal for roi-to-roi in the same matrix without overlaps, but I'm not sure there is a platform-independent solution to check if memory regions overlap(without UB).
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.
Ideally speaking, we should check ROI overlaps but who would do that intentionally? Such operations do not make sense. Or if we are talking about unintentionally mis-operation, it is what it is as long as it does not trigger crashing.
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.
Generally I agree, but in this case it doesn't cost us anything to change ptr() to datastart.
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 re-implemented with dst in-place flip and also ensuring both src and dst are continuous. In this case, I suppose we can skip checking whether steps are equal, can't we?
INSTANTIATE_TEST_CASE_P(Arithm, FlipND, testing::Combine( | ||
testing::Values(std::vector<int>{5, 10}, std::vector<int>{2, 3, 4}), | ||
testing::Values(perf::MatType(CV_8UC1), CV_32FC1) | ||
)); |
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.
ROI handing of src/dst/src+dst should be added.
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 don't quite understand what ROI handling is here. Examples?
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.
Take a look on OCL_TEST_P(Transpose, Mat)
test design (input data generation).
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.
So if I understand correctly, case of non continuous input mat should be tested. Correct me if I am wrong.
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.
Right. ROI means region of interest
- it is a sub-matrix from larger matrix.
However, for ND case this may be not really useful. In 2D case we have flip()
.
Anyway, we still need to provide checks for that (contiguous data assumption) in the source code of implementation.
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.
Anyway, we still need to provide checks for that (contiguous data assumption) in the source code of implementation.
I don't think the implementation assumes that data is contiguous.
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 still need checks for ROI handling since in the latest impl src and dst are assumed to be continuous?
fb493b5
to
3526072
Compare
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.
Nothing major, looks good.
size_t offset = 0; | ||
size_t offset_increment = axis == 0 ? 0 : step[axis - 1]; | ||
for (int i = 0; i < total; ++i, offset += offset_increment) | ||
for (int j = 0, k = shape_at_axis - 1; j < (shape_at_axis + 1) / 2; ++j, --k) |
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.
Isn't +1 redundant? In case of shape [A, 3, B]: (3+1)/2=2, but we need only 1 swap.
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 are right. +1 is removed in the latest commit.
int axis = (_axis + ndim) % ndim; | ||
|
||
// return the src if it has only one element on the flip axis | ||
if (shape[axis] == 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.
We don't need this special case, I think.
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 serves like an early stop to improve efficiency, doesn't it?
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.
To be honest, I don't know what we are winning here - one function frame that will do exactly this? I think copying is much slower than calling a function. @alalek can you elaborate?
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 think copying is much slower than calling a function
function itself is heavier than simple copying.
There is no problem with that part. Refer to convertTo()
implementation.
CV_INSTRUMENT_REGION(); | ||
|
||
Mat src = _src.getMat(); | ||
CV_Assert(src.isContinuous()); |
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 believe we can lift that restriction.
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 think so. I also lifted the restriction for dst since it will be covered by calling src.copyTo(dst)
and be continuous in the end.
02268cd
to
d7d0ddd
Compare
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.
core
part looks good to merge 👍
@fengyuentau please squash commits before merge. |
d1a7318
to
34a0897
Compare
@asmorkalov Commits are squashed. Ready to be merged. |
Fixes #22794
Merge with opencv/opencv_extra#1023.
Current workaround for negative steps is computing the forward indexing range for slice and flip at axis with negative step:
We can also extend
Range
to support backward indexing and steps like Pythonlist
, which needs more effort to do so I think.Pull Request Readiness Checklist
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.