Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mshabunin
Copy link
Contributor

@mshabunin mshabunin commented Apr 24, 2024

This PR is intended to fix #25265. In order to do it we should:

  1. Add proper reproducer as a test (done)
  2. Fix implementation to use correct vector types (done)

Test for boundingRect has been converted to modern scheme and parametrized. Also increased test boundaries and added separate alignment test. In order to reproduce the issue one needs to build and run this test on ARMv7 board or emulate using C++ intrinsics with alignment checks (-DOPENCV_EXTRA_CXX_FLAGS="-DCV_STRONG_ALIGNMENT=1 -DCV_FORCE_SIMD128_CPP=1"). To activate second changed block (#if CV_SIMD_WIDTH > 16) use -DCPU_BASELINE=AVX2.

@asmorkalov
Copy link
Contributor

@mshabunin please close PRs with other solutions as soon as your is ready.

for (int i = 0; i < 10; ++i)
{
SCOPED_TRACE(cv::format("i=%d", i));
Mat sub(40, 1, CV_32SC2, data + i * 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i * 2

step should be one integer (4 bytes) to reproduce alignment issue.

@mshabunin mshabunin force-pushed the bounding-rect-alignment branch 2 times, most recently from 82c4a37 to 0eee06a Compare April 27, 2024 10:46
@mshabunin mshabunin marked this pull request as ready for review April 27, 2024 12:18
@asmorkalov asmorkalov added this to the 4.10.0 milestone Apr 29, 2024
@asmorkalov
Copy link
Contributor

@opencv-alalek could you take a look again?

if( !is_float )
{
const int32_t* pts = points.ptr<int32_t>();
firstval.vali32[0] = pts[0];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if using std::memcpy instead of union would be better in this case:

memcpy(&vali64, pts, 2 * sizeof(pts[0]));

firstval.vali32[1] = pts[1];
v_int32 minval, maxval;
minval = maxval = v_reinterpret_as_s32(vx_setall_s64(*pts)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
minval = maxval = v_reinterpret_as_s32(vx_setall_s64(firstval.vali64)); //min[0]=pt.x, min[1]=pt.y, min[2]=pt.x, min[3]=pt.y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without unions: vx_setall_s64((int64_t)pts[0] | (int64_t)((uint64_t)pts[1] << 32)) ?

@mshabunin mshabunin force-pushed the bounding-rect-alignment branch from 6d64587 to c4ce942 Compare May 3, 2024 18:26
@mshabunin
Copy link
Contributor Author

Hmm.. something was wrong with bit-shift approach, so I decided to use std::memcpy.

@asmorkalov asmorkalov merged commit 8bc90a4 into opencv:4.x May 7, 2024
@mshabunin mshabunin deleted the bounding-rect-alignment branch May 7, 2024 08:55
@mshabunin mshabunin mentioned this pull request Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SIGBUS crash in pointSetBoundingRect() on ARMv7-A (armeabi-v7a) due to unaligned NEON load

3 participants