-
-
Notifications
You must be signed in to change notification settings - Fork 541
Description
While reviewing:
libs/core/algorithms/include/hpx/parallel/util/detail/chunk_size.hpp
I found two silent correctness bugs affecting bulk iteration shape handling.
Bug 1 — Swapped arguments in next_or_subrange (variable chunk path)
Location:
get_bulk_iteration_shape_variable (around line 320)
Signature:
constexpr auto next_or_subrange(IterOrR const& target,
std::size_t offset, std::size_t size)
Current code:
std::size_t chunk = (std::min)(chunk_size, count);
shape.emplace_back(it_or_r, chunk);
chunk = (std::min)(count, chunk);
count -= chunk;
it_or_r = next_or_subrange(it_or_r, count, chunk); // BUG
Issue:
At this point count has already been decremented and represents the
remaining elements, not the advance distance.
The iterator should advance by chunk, but instead advances by the
remaining count, leading to incorrect range progression.
Correct form:
it_or_r = next_or_subrange(it_or_r, chunk, count);
This matches the correct usage in the other overload (line ~214).
Impact:
- Any algorithm using the variable-chunk-size path (std::true_type)
- Multi-chunk scenarios silently process incorrect ranges
- No compile-time warning
Proposed Fix:
- Swap the two arguments at line ~320
- Add a unit test ensuring multi-chunk iteration visits all elements exactly once
Bug 2 — Parameter order mismatch in add_ready_future_idx
Location:
Overloads for add_ready_future_idx (lines ~366–380)
Correct overload (future):
void add_ready_future_idx(std::vector<hpx::future<void>>& workitems,
F&& f, FwdIter first, std::size_t base_idx, std::size_t count)
Incorrect overload (shared_future):
void add_ready_future_idx(
std::vector<hpx::shared_future<void>>& workitems,
F&& f, std::size_t base_idx, FwdIter first, std::size_t count)
// base_idx and first swapped
Problem:
Call sites pass arguments in the order:
(first, base_idx, count)
This matches the future overload, but in the shared_future
case the parameters are reversed, potentially binding:
first → base_idx
base_idx → first
This leads to undefined behavior passed silently into the kernel.
Corrected version:
void add_ready_future_idx(
std::vector<hpx::shared_future<void>>& workitems,
F&& f, FwdIter first, std::size_t base_idx, std::size_t count)
{
HPX_FORWARD(F, f)(first, count, base_idx);
workitems.push_back(hpx::make_ready_future());
}
Impact:
- Silent UB when shared_future workitems are used
- Incorrect base_idx propagation in indexed iteration shapes
Proposed Fix:
- Reorder parameters of the shared_future overload
- Add test covering shared_future path via
get_bulk_iteration_shape_idx - Optionally document required parameter order to prevent recurrence
Recommendation
Both issues affect correctness and should be fixed before further
refactoring in this area. These are silent runtime errors without
diagnostics.