Skip to content

Give Runtime Policy Information to Reducers - #2061

Merged
rhornung67 merged 65 commits into
developfrom
feature/burmark1/reduce_platform
Jul 30, 2026
Merged

Give Runtime Policy Information to Reducers#2061
rhornung67 merged 65 commits into
developfrom
feature/burmark1/reduce_platform

Conversation

@MrBurmark

@MrBurmark MrBurmark commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

Add Policy enum to constructor/reset of reducers/multi-reducers to allow them to optimize their resource usage based on the backend they will actually be used with. Constructing/resetting a reducer/multi-reducer to a different policy than the reducer/multi-reducer is subsequently used with is undefined behavior. This is based on the idea from #2059 that was aimed at fixing #1756.

//before
RAJA::ReduceSum<RAJA::cuda_reduce, double> sum(0.0);
RAJA::forall<RAJA::seq_exec>(RAJA::Range(0, N) [=](int i) { sum += i; });

// after
RAJA::ReduceSum<RAJA::cuda_reduce, double> sum(RAJA::Policy::sequential, 0.0);
RAJA::forall<RAJA::seq_exec>(RAJA::Range(0, N) [=](int i) { sum += i; });

// alternatively
RAJA::ReduceSum<RAJA::cuda_reduce, double> sum(RAJA::policy_of<RAJA::seq_exec>::value, 0.0);
RAJA::forall<RAJA::seq_exec>(RAJA::Range(0, N) [=](int i) { sum += i; });

TODO:

  • Support seq, omp, cuda, hip Reduction objects
  • Support omp_target, sycl Reduction objects
  • Support sequential exec policies with omp_target and sycl reduction objects
  • Test reduction correctness with other supported backends (cuda/hip supports seq, openmp, and cuda/hip)
  • Document these changes

Breaking change

Some reducers like sequential and openmp when not given a default value would default construct their value, so min reductions would start with a 0 instead of the max of that type. This was changed so reducers now consistently use the identity value instead, fixing min and max reductions when constructed without explicit initial values. Note that we consider using the default constructor and not supplying an initial value to be deprecated.

  • This PR is a refactoring, bugfix
  • It does the following (modify list as needed):
    • Modifies/refactors reducer to take a Policy enum arg

@MrBurmark
MrBurmark force-pushed the feature/burmark1/reduce_platform branch from e72308f to f1a93e2 Compare July 17, 2026 21:45
@MrBurmark MrBurmark changed the title Give Runtime Policy Informatio to Reducers Give Runtime Policy Information to Reducers Jul 17, 2026
@MrBurmark
MrBurmark force-pushed the feature/burmark1/reduce_platform branch from f1a93e2 to 134e35d Compare July 17, 2026 21:48
@MrBurmark
MrBurmark marked this pull request as ready for review July 17, 2026 21:49
@MrBurmark

Copy link
Copy Markdown
Member Author

I re-enabled some sycl and openmp target tests, we'll see if we have to disable them again.

@rhornung67

Copy link
Copy Markdown
Member

Unfortunately, we don't have an OpenMP target CI check at the moment. @rchen20 is working on build scripts for that. Then we can re-enable the CI check.

@MrBurmark
MrBurmark requested review from a team, adayton1, artv3, rchen20 and rhornung67 July 20, 2026 17:59
@MrBurmark

Copy link
Copy Markdown
Member Author

I discovered why the forall openmp target reduction tests were not created, they do not get correct answers. I disabled them again.

@rhornung67

Copy link
Copy Markdown
Member

I discovered why the forall openmp target reduction tests were not created, they do not get correct answers. I disabled them again.

Was this all omp target reduction tests, or just the ones that used the "old-style" reductions (reduction object captured by value)?

@MrBurmark
MrBurmark force-pushed the feature/burmark1/reduce_platform branch 2 times, most recently from 64db237 to 4ad1093 Compare July 27, 2026 18:31
The multi-reduction policy specifies how the multi-reduction is done and must
support the execution policy. For example, ``RAJA::seq_multi_reduce`` does a
sequential multi-reduction and can only be used with sequential execution
policies. The ``RAJA::cuda_multi_reduce_atomic`` policy uses atomics and

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The detail that cuda_reducers also supports, omp, and sequential can take a double look when first reading it. Should we just call it auto_*?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Well its not exactly auto if you have to tell it which Policy to support otherwise it allocates cuda memory.


If the same multi-reducer object will later be used with CUDA or HIP loops,
call ``reset(RAJA::Policy::cuda, ...)`` or ``reset(RAJA::Policy::hip, ...)``
before that use. Use ``RAJA::Policy::undefined`` only when the object

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
before that use. Use ``RAJA::Policy::undefined`` only when the object
before that use. Use ``RAJA::Policy::auto`` only when the object

what about calling it auto?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I tend to associate undefined behavior as something that I generally don't want

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That was just keeping the existing naming. We may have places where we want the undefined vs the "auto" meaning, we'll have to think about that. Thinking about the name all_supported would be more specific than auto though auto is shorter and less awkward.

@artv3 artv3 Jul 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

could all_compat work?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I also like: support_all

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

or inspired by raja, the forall policy

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I went with all_supported before I saw these suggestions.

sycl
};

constexpr const char* get_policy_name(Policy p)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This could also be a std::string_view if you choose

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

and mark the function noexcept

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The unfortunate thing about string_view is that you can't assume that its null-terminated. I think some things are better left const char* for that reason, but it depends on how its used.

Comment thread include/RAJA/policy/PolicyBase.hpp
Comment thread test/include/RAJA_test-reducer-api.hpp
Comment thread include/RAJA/policy/sycl/reduce.hpp

@artv3 artv3 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

looks good to me!

MrBurmark added 13 commits July 29, 2026 09:34
Only have a non-defaulted constructor and reset.
This affects the base, seq, and omp combiners.
This allows you to pass a RAJA::Policy enum that indicates
which type of policies the reducer will be used with.
For example cuda reducers may be used with cuda, openmp, and
sequential loop policies. If you pass in RAJA::Policy::sequential
then the reducer only supports sequential policy types and can
avoid allocating resources required for openmp or cuda.

Note that passing in Policy::undefined is an explicit way to get the
current behavior where the reducer may be used with any of the
policies it supports.

Note that using a reducer with different loop policy types than the
Policy type passing in results in undefined behavior.
Identify which objects are user facing and which are not.
Note that we've only done this for seq, omp, cuda, and hip.
This also makes the tests more ugly by having to use API_TAG
when constructing and resetting reducer objects.
MrBurmark and others added 20 commits July 29, 2026 09:37
The current support is not correct and the old reducer
is deprecated with sycl so I'm trying to make it work correctly
with the default sycl resource at least as it did previously.
instead of openmp policy header
It was missing the defaulted identity arg
Using get_queue by ref was an issue as Sycl::get_default
returns by value.
Add Policy enum that specifies that all the policies that
the reducer should be able to be used with all of the policies
that it supports.
from policy_supported
@MrBurmark
MrBurmark force-pushed the feature/burmark1/reduce_platform branch from 3f4f90d to 74b2618 Compare July 29, 2026 16:38
concepts::enable_if_t<
type_traits::is_range<Container>,
concepts::negate<std::is_convertible<Container, size_t>>,
concepts::negate<std::is_base_of<BaseMultiReduce, Container>>>* =

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.

(minor) Do we want this using C++20 concepts instead of the old enable_if_t style?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We are moving in that direction. @johnbowen42 did a lot of transformation already, but I suspect that there is more to do. We can continue to push on that after the release. IMO, this should not hold up the release.

@rhornung67

Copy link
Copy Markdown
Member

FYI, tuo is down for maintenance. We have the same CI checks on tioga and tuo. tioga checks are green. @MrBurmark to maintain momentum, we can merge this while tuo is down. It's your call.

@MrBurmark

MrBurmark commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

FYI, tuo is down for maintenance. We have the same CI checks on tioga and tuo. tioga checks are green. @MrBurmark to maintain momentum, we can merge this while tuo is down. It's your call.

@rhornung67 Go ahead and merge it.

@rhornung67

Copy link
Copy Markdown
Member

@MrBurmark you don't want the honors?

@rhornung67
rhornung67 merged commit 81fe792 into develop Jul 30, 2026
18 of 20 checks passed
@rhornung67
rhornung67 deleted the feature/burmark1/reduce_platform branch July 30, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants