Skip to content

Size the builtin operations from the types of their arguments - #7946

Merged
hkaiser merged 2 commits into
masterfrom
task-size-for-args
Oct 31, 2026
Merged

hkaiser merged 2 commits into
masterfrom
task-size-for-args

Conversation

@hkaiser

@hkaiser hkaiser commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

This builds on #7926 and should be merged after it.

A transparent function object such as std::less<> names no operand type, so its task size can be known only from the arguments it is called with. This adds hpx::traits::get_task_size_for<F, Args...>, which gives the size of a call of f with arguments of the types Args. Unless it is specialized, it is the size of f itself (get_task_size), so a size given to f by nano_task(f), with_task_size<Size>(f), etc. always wins.

The function objects of the standard library (std::plus, std::minus, std::multiplies, std::divides, std::modulus, std::negate, the comparisons, the logical and the bitwise operations) and the comparisons in std::ranges are registered as builtin operations. So are the predicates in hpx::parallel::detail (equal_to, less, plus, ..., min_of, max_of). A transparent operation called with arithmetic, enum or pointer arguments is a nano task. A typed operation (std::less<int>, min_of<int>, ...) is a nano task if the type it names is such a type. In all other cases the size stays unknown, for instance std::plus<> on std::complex<double>.

detail::with_task_size_of takes the argument types. reduce, transform_reduce and merge now pass them, merge only if both projections are hpx::identity, since a projection may do any amount of work.

transform gives its iterations the size of the transformation of one or two elements, sized the same way through the new task_size_argument_t<Iter, Proj>: the reference of the element if it is not projected, a type of unknown size otherwise. merge uses it too.

Other algorithms are to follow, as are the sizes for datapar execution policies, where the function is called once per pack.

Tests: new compile-time and run-time checks in sized_function.cpp. The checks of the sizes the algorithms pass to the scheduler move from task_size_hint.cpp to the new libs/core/algorithms/tests/unit/task_sizes, with the counting scheduler in task_size_checks.hpp, so that the following PRs for the other algorithms can add their checks in files of their own.

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Caution

Review failed

The pull request is closed.

  • 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

@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.

A transparent function object such as std::less<> names no operand type,
so its size depends on the arguments it is called with. Add
get_task_size_for<F, Args...>, which gives the size of a call of f with
arguments of the types Args. Unless it is specialized, it is the size of
f itself, so a size given to f always wins.

The standard function objects (std::plus, std::less, ..., and the
std::ranges comparisons) and the predicates in
hpx::parallel::detail are registered as builtin operations. A transparent
one called with arithmetic, enum or pointer arguments is a nano task. A
typed one (std::less<int>, min_of<int>, ...) is a nano task if it names
such a type. In all other cases the size stays unknown.

detail::with_task_size_of takes the argument types, which reduce,
transform_reduce and merge now pass. merge does that only if both
projections are hpx::identity.

Signed-off-by: Hartmut Kaiser <[email protected]>
@hkaiser
hkaiser force-pushed the task-size-for-args branch from bf27831 to ba9d496 Compare October 31, 2026 01:31
…ecks

Add task_size_argument_t<Iter, Proj>, the type of the argument an
algorithm calls its function with for an element of Iter: the reference
of the element if it is not projected, and a type of unknown size if it
is, since a projection may do any amount of work. merge uses it instead
of distinguishing the projections itself.

transform gives its iterations the size of the transformation of one or
two elements. The get_task_size specializations of the transform
iterations are no longer used and removed.

The checks of the task sizes of the algorithms move from the
threading_base tests to the new algorithms/tests/unit/task_sizes, with
the counting scheduler in task_size_checks.hpp, so that the checks of
further algorithms can be added in files of their own.

Signed-off-by: Hartmut Kaiser <[email protected]>
Base automatically changed from task-size-runtime to master October 31, 2026 11:39
@hkaiser
hkaiser merged commit 5401785 into master Oct 31, 2026
75 of 77 checks passed
@hkaiser
hkaiser deleted the task-size-for-args branch October 31, 2026 11:40
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.

1 participant