Skip to content

Fix parallel find_end comparing the wrong elements - #7767

Merged
hkaiser merged 2 commits into
TheHPXProject:masterfrom
Ishaan400:fix/parallel-find-end
Oct 21, 2026
Merged

hkaiser merged 2 commits into
TheHPXProject:masterfrom
Ishaan400:fix/parallel-find-end

Conversation

@Ishaan400

Copy link
Copy Markdown
Contributor

Fixes #7766

Proposed Changes

  • In the partitioned overload of sequential_find_end_t, keep an iterator (curr) in step with the element that util::loop_idx_n passes to the callback, and compare the rest of the subsequence through it (*mid). Before, the callback incremented a copy of the element itself, so the rest of the subsequence was compared with t + 1, t + 2, ... This is the same approach the parallel search already uses in detail/search.hpp.
  • The callback now takes the element as std::iterator_traits<Iter1>::reference instead of auto, so it is not copied.
  • Add test_find_end5 to the findend unit test for seq, par and par_unseq with random access and forward iterators. It uses the subsequence {2, 1} in the middle of the vector, followed by a lone 2 that must not be taken for a match, then again at the very end, and finally the same data as std::strings.

Any background context you want to provide?

The existing findend tests only use {1, 2} and std::iota subsequences, where t + 1 happens to be the next element of the subsequence, so they passed. Any other subsequence could be missed or matched falsely ({1, 5} matched {1, 2}), and element types without operator++ such as std::string did not compile.

Testing (GCC 13.3, Ubuntu 24.04, local-only build):

  • findend, findend_sender, find_end_range, find_end_range2 and minimal_findend pass, findend also with --hpx:threads=1.
  • Without the fix, the std::string part of the new test fails to compile (no match for 'operator++'), and without that part 8 of the new checks fail.
  • Compared hpx::find_end with par, par_unseq, par(task), hpx::ranges::find_end (with and without projections), std::forward_list and std::string elements against std::find_end on 400 random inputs of up to 20000 elements: 2800 of 2800 identical, against 813 of 2400 on master (the std::string case excluded there, as it does not compile).
  • clang-format-20 makes no changes.

Checklist

Not all points below apply to all pull requests.

  • I have added a new feature and have added tests to go along with it.
  • I have fixed a bug and have added a regression test.
  • I have added a test using random numbers; I have made sure it uses a seed, and that random numbers generated are valid inputs for the tests.

@Ishaan400
Ishaan400 requested a review from hkaiser as a code owner October 18, 2026 14:27
@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: bdb748f1-a789-4e67-bf63-2266c5077d39
📥 Commits

Reviewing files that changed from the base of the PR and between cba138f and d1f516f.

📒 Files selected for processing: 3
  • libs/core/algorithms/include/hpx/parallel/algorithms/detail/find.hpp
  • libs/core/algorithms/tests/unit/algorithms/findend.cpp
  • libs/core/algorithms/tests/unit/algorithms/findend_tests.hpp

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Summary

Summary by CodeRabbit

  • Bug Fixes
    • Fixed find_end so it correctly locates the last matching subsequence across sequential and parallel execution policies, including when searching elements that cannot be incremented.
  • Tests
    • Added coverage for forward and random-access iterators, multiple execution policies, and matches near the end of a range.

The partitioned find_end implementation now tracks candidate positions with an iterator. New tests compare results with std::find_end for nonconsecutive patterns and string elements across execution policies and iterator tags.

Changes: Parallel find_end

Layer / File(s) Summary
Track candidate positions
libs/core/algorithms/include/hpx/parallel/algorithms/detail/find.hpp
sequential_find_end_t::invoke_default advances a tracked iterator with each candidate and uses it to check subsequent elements.
Add policy-based regression tests
libs/core/algorithms/tests/unit/algorithms/findend_tests.hpp, libs/core/algorithms/tests/unit/algorithms/findend.cpp
Tests compare HPX and standard find_end results for nonconsecutive vector patterns and string elements. The test group runs with seq, par, and par_unseq policies for random-access and forward iterator tags.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to d1f51

The candidate-tracking change has no identified merge-blocking issue. Merge after normal checks.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed The change addresses #7766. In the partitioned sequential_find_end_t overload, curr advances with the element passed by loop_idx_n, and the remaining pattern elements are read through *mid. Th…
Out of Scope Changes check Passed The changes stay within #7766. The production change fixes the identified partitioned find_end comparison. The added test covers the reported non-consecutive-value and non-incrementable-element case…
Title check Passed The title clearly and concisely describes the primary fix to parallel find_end behavior.
Description check Passed The description directly explains the bug, implementation, regression tests, affected policies, and validation results.
Full details: Linked Issues check

Explanation

The change addresses #7766. In the partitioned sequential_find_end_t overload, curr advances with the element passed by loop_idx_n, and the remaining pattern elements are read through *mid. The callback uses std::iterator_traits&lt;Iter1&gt;::reference, so element types such as std::string are not incremented. test_find_end5 compares HPX results with std::find_end for {2, 1} and string elements under seq, par, and par_unseq, using random-access and forward iterators.

Full details: Out of Scope Changes check

Explanation

The changes stay within #7766. The production change fixes the identified partitioned find_end comparison. The added test covers the reported non-consecutive-value and non-incrementable-element cases. The direct &lt;algorithm&gt; include supports the new std::find_end comparison.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@StellarBot

Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

@hkaiser hkaiser left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM, thanks!

@hkaiser hkaiser added this to the 2.0.0 milestone Oct 18, 2026
util::loop_idx_n passes each element to the callback, not an iterator to
it, but the partitioned find_end treated it as an iterator: after the
first element of the subsequence matched, it incremented a copy of that
element instead of moving to the next one, and compared the rest of the
subsequence against those incremented values.

So the parallel overloads only found subsequences of consecutive values
such as {1, 2}, which is what the existing tests use. For other
subsequences they missed matches or reported false ones, and they did
not compile for element types without operator++, such as std::string.

Keep an iterator in step with the current element, as the parallel
search does, and compare the rest of the subsequence through it. Add a
test with a non-consecutive subsequence, a lone first element that does
not start a match, a match at the very end, and std::string elements.

Signed-off-by: Ishaan400 <[email protected]>
@Ishaan400
Ishaan400 force-pushed the fix/parallel-find-end branch from d1f516f to d9fe428 Compare October 19, 2026 03:25
@Ishaan400

Copy link
Copy Markdown
Contributor Author

Added the missing DCO sign-off; the code is unchanged. The other failing jobs (queuing_options_7743, min_tasks_to_steal_staged, partitioned_vector_inclusive_scan2, rnd_future_reduce) also fail on other open PRs such as #7787 and #7782, so they look unrelated to this change.

@hkaiser
hkaiser merged commit 742ff6f into TheHPXProject:master Oct 21, 2026
82 of 132 checks passed
@hkaiser hkaiser mentioned this pull request Oct 21, 2026
1 of 2 tasks
hkaiser added a commit that referenced this pull request Oct 22, 2026
Restore the release notes update that was lost when release-2.0.X was rebuilt on master eaff5b9, and describe the PRs merged since the previous rebuild (#6514, #7767, #7816, #7817, #7819, #7821, #7824, #7831). Regenerate the closed issue and pull request lists for release-2.0.X at 4cb902e against the v1.11.0 tag (775 PRs, 167 issues).

Signed-off-by: Hartmut Kaiser <[email protected]>
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.

Parallel hpx::find_end compares against incremented copies of the first element

3 participants