Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop stream 2024-09-12 #462

Open
wants to merge 45 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9075421
Fixed overflow bug for large sizes in thrust::shuffle
Beanavil Jul 24, 2024
e9397cc
Added definitions of execution space macros
Beanavil Jul 24, 2024
a7a5d20
Add missing overloads for thrust::pow
Beanavil Jul 25, 2024
7006599
Refactors thrust::unique_by_key to use cub::DeviceSelect::UniqueByKey
Beanavil Jul 25, 2024
e5dbdaa
Fix a typo in thrust-config.cmake
Beanavil Jul 25, 2024
bd43018
Check that thrust::pair is trivially copyable
Beanavil Jul 25, 2024
b7b785e
Remove double ignore in discard_iterator.h docs
Beanavil Jul 25, 2024
93b72cd
Replace deprecated _VSTD macro with std
Beanavil Jul 25, 2024
f3e2676
Update mode example to use thrust::unique_count
Beanavil Jul 25, 2024
44d7369
Ensure that thrust fancy iterators are trivially_copy_constructible w…
Beanavil Jul 25, 2024
a32a67c
Use checked allocators in CUB catch2 tests
Beanavil Jul 30, 2024
b741017
Refactors thrust::copy_if to use cub::DeviceSelect
Beanavil Jul 25, 2024
158fa53
Refactor thrust::[stable_]partition[_copy] to use cub::DevicePartition
Beanavil Jul 25, 2024
bc6c83b
Fix include of <thrust/random.h> with NVC++
Beanavil Jul 25, 2024
489c073
Cleanup diagnostic handling
Beanavil Jul 25, 2024
9f5a3ba
Rework config.h
Beanavil Jul 29, 2024
1020a11
Bump version to 2.4.0
Beanavil Jul 25, 2024
917c255
Fix issues with ambiguous calls to addressof in thrust::optional
Beanavil Jul 25, 2024
5af1ef7
Try harder to unwrap nested thrust::tuple_of_iterator_references, CUD…
Beanavil Jul 29, 2024
bd5228c
Added missing element from thrust's tuple implementation
Beanavil Jul 25, 2024
099a901
Ensure that we can run reduce_by_key with const inputs
Beanavil Jul 25, 2024
9508470
Leave definitions of __host__ and __device__
Beanavil Jul 30, 2024
6791366
Patched up CI because of CCCL2.4.0 tests' build failure
Beanavil Jul 30, 2024
9fe0b04
Updated tests and examples for __host__ __device__ use
Beanavil Jul 31, 2024
15a07b0
Updated CHANGELOG
Beanavil Jul 31, 2024
158a1e1
Added operator to transform_reduce benchmark
NB4444 Aug 1, 2024
d0bf50f
Added mem allocator in benchmarks
NB4444 Aug 1, 2024
aa64ae7
Changes for review
NB4444 Aug 8, 2024
0673125
ci: set up sccache
Snektron Jul 26, 2024
75c44cf
Added helper functions for choosing between different custom reporter
NB4444 Aug 8, 2024
a36adac
Added json and csv custom reporter for benchmarks
NB4444 Aug 13, 2024
e00ad3a
Changes for review
NB4444 Aug 15, 2024
1cc4c8b
Added hipstdpar tests
Beanavil Aug 8, 2024
568f6f9
Relocated our ParallelSTL additions
Beanavil Aug 8, 2024
f584551
Fixed several naming issues
Beanavil Aug 8, 2024
387dbcf
Added missing unimplemented algorithms
Beanavil Aug 9, 2024
8aff938
Split hipstdpar_lib.hpp
Beanavil Aug 9, 2024
e2d548f
Added relevant information to README and CHANGELOG regarding HIPSTDPAR
Beanavil Aug 23, 2024
28da1b1
Clarified upstream LLVM offload support
Beanavil Sep 13, 2024
ed35b28
Emit error when HIPSTDPAR macros are not defined
Beanavil Sep 20, 2024
5023555
Move forwarding calls to rocPRIM to thrust's stubs
Beanavil Sep 20, 2024
e340947
Fix path to hipstdpar impl headers
Beanavil Nov 4, 2024
1f060d8
Prevent building hipstdpar tests when no compatible libstdc++ is present
Beanavil Nov 4, 2024
5fdf870
Disable TBB tests build
Beanavil Nov 6, 2024
5be02c2
Merge branch 'develop' into develop-upstream-12-9-2024
NB4444 Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,908 changes: 22 additions & 4,886 deletions thrust/system/hip/hipstdpar/hipstdpar_lib.hpp

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions thrust/system/hip/hipstdpar/impl/batch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*! \file thrust/system/hip/hipstdpar/include/batch.hpp
* \brief <tt>Batch operations</tt> implementation detail header for HIPSTDPAR.
*/

#pragma once
Copy link
Contributor

Choose a reason for hiding this comment

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

Doing the split is fine, since it aligns with Thrust convention, I guess; however, IMHO it'd be better if the master header (this), which is the object of implicit inclusion / is part of the public interface, would do nothing but include the split headers, as opposed to having any actual functionality. We could also probably guard the interpose_allocations.hpp one with its respective macros. Finally, we probably want to error on the impl headers if they're directly included without __HIPSTDPAR__ being defined, as that would indicate user error.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have some questions about these suggestions:

IMHO it'd be better if the master header (this), which is the object of implicit inclusion / is part of the public interface, would do nothing but include the split headers, as opposed to having any actual functionality

Do you mean that we should further split the master headers (the ones named after the C++ Standard Library categories for algorithms)?

We could also probably guard the interpose_allocations.hpp one with its respective macros.

What macros do you refer to? IINM the interpose_allocations.hpp is already guarded by the __HIPSTDPAR__ and
__HIPSTDPAR_INTERPOSE_ALLOC__ macros (as it was before splitting hipstdpar_lib.hpp).

Finally, we probably want to error on the impl headers if they're directly included without HIPSTDPAR being defined, as that would indicate user error.

And for this, I don't fully understand why would we need to error here. Originally there was no error handling in case that macro was not defined in the hipstdpar_lib.hpp, so I'm not sure why it would be done for the impl headers. Also, as I had understood it, the forwarding header was not intended to be included directly by users, but implicitly included by the compiler when specifying the --hipstdpar option (which also triggers the definition of the __HIPSTDPAR__ macro). So if this is true (please correct me if not), then it wouldn't make sense to check for the definition of this macro IMHO.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mean that we should further split the master headers (the ones named after the C++ Standard Library categories for algorithms)?

Not quite, what I meant is that the master header would pretty much be a list of #includes for the impl headers, with no declarations / definitions or, really, any substantive code living there. In essence, the most we'd do here is check for environmental macros / possibly declare some future config macros, if necessary. Does that make sense?

What macros do you refer to? IINM the interpose_allocations.hpp is already guarded by the __HIPSTDPAR__ and __HIPSTDPAR_INTERPOSE_ALLOC__ macros (as it was before splitting hipstdpar_lib.hpp).

What I was suggesting as a possible alternative is to check for __HIPSTDPAR_INTERPOSE_ALLOC__ in the master hipstdpar_lib.hpp header and do conditional include of the impl header in there, rather than guarding within it. This ties both to the point above re: what to do with the master header and to the one below about considering error-ing out.

And for this, I don't fully understand why would we need to error here. Originally there was no error handling in case that macro was not defined in the hipstdpar_lib.hpp, so I'm not sure why it would be done for the impl headers. Also, as I had understood it, the forwarding header was not intended to be included directly by users, but implicitly included by the compiler when specifying the --hipstdpar option (which also triggers the definition of the __HIPSTDPAR__ macro). So if this is true (please correct me if not), then it wouldn't make sense to check for the definition of this macro IMHO.

Whilst the vote of confidence is highly appreciated, I'd not take the original header to necessarily be complete / the best way to do things:) To wit, whilst the forwarding header was / is not meant to be included by users, that does not mean users won't do it (accidentally / intentionally). Error-ing out if the macro is not defined i.e. compilation for hipstdpar was not desired would guard against accidents, and will at least force intentional abusers to manually define the macro, which'd help with eventual debugging. I suggested it because I think it might be a time saver / inform users about things potentially going awry. Ultimately, it's up to you if you want to go in this direction.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not quite, what I meant is that the master header would pretty much be a list of #includes for the impl headers, with no declarations / definitions or, really, any substantive code living there. In essence, the most we'd do here is check for environmental macros / possibly declare some future config macros, if necessary. Does that make sense?

Oh alright, I was confused because the comment was made on impl/batch.hpp. But then, the master header hipstdpar_lib.hpp is already just a macro definition check (__HIPSTDPAR__) and a bunch of includes (for the impl/ headers)

What I was suggesting as a possible alternative is to check for HIPSTDPAR_INTERPOSE_ALLOC in the master hipstdpar_lib.hpp header and do conditional include of the impl header in there, rather than guarding within it. This ties both to the point above re: what to do with the master header and to the one below about considering error-ing out.

Whilst the vote of confidence is highly appreciated, I'd not take the original header to necessarily be complete / the best way to do things:) To wit, whilst the forwarding header was / is not meant to be included by users, that does not mean users won't do it (accidentally / intentionally). Error-ing out if the macro is not defined i.e. compilation for hipstdpar was not desired would guard against accidents, and will at least force intentional abusers to manually define the macro, which'd help with eventual debugging. I suggested it because I think it might be a time saver / inform users about things potentially going awry. Ultimately, it's up to you if you want to go in this direction.

Regarding those two points, the final logic should be then:

  • Check in hipstdpar_lib.hpp if __HIPSTDPAR__ is defined and include the impl headers if so, except interpose_allocations.hpp which only will be included if __HIPSTDPAR_INTERPOSE_ALLOC__ is also defined.
  • Inside each implementation header, check if __HIPSTDPAR__ is defined and err if it's not.
  • Additionally, in interpose_allocations.hpp, check if __HIPSTDPAR_INTERPOSE_ALLOC__ is defined and err if not.

If that sounds good I'll add a commit with the changes

Copy link
Contributor

Choose a reason for hiding this comment

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

This sounds great, thanks and apologies for adding work.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also added the err logic discussed before


#if defined(__HIPSTDPAR__)

#include "hipstd.hpp"

#include <thrust/execution_policy.h>
#include <thrust/for_each.h>

#include <algorithm>
#include <execution>
#include <utility>

namespace std
{
// BEGIN FOR_EACH
template<
typename I,
typename F,
enable_if_t<
::hipstd::is_offloadable_iterator<I>() &&
::hipstd::is_offloadable_callable<F>()>* = nullptr>
inline
void for_each(execution::parallel_unsequenced_policy, I f, I l, F fn)
{
::thrust::for_each(::thrust::device, f, l, ::std::move(fn));
}

template<
typename I,
typename F,
enable_if_t<
!::hipstd::is_offloadable_iterator<I>() ||
!::hipstd::is_offloadable_callable<F>()>* = nullptr>
inline
void for_each(execution::parallel_unsequenced_policy, I f, I l, F fn)
{
if constexpr (!::hipstd::is_offloadable_iterator<I>()) {
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category>();
}
if constexpr (!::hipstd::is_offloadable_callable<F>()) {
::hipstd::unsupported_callable_type<F>();
}

return
::std::for_each(::std::execution::par, f, l, ::std::move(fn));
}
// END FOR_EACH

// BEGIN FOR_EACH_N
template<
typename I,
typename N,
typename F,
enable_if_t<
::hipstd::is_offloadable_iterator<I>() &&
::hipstd::is_offloadable_callable<F>()>* = nullptr>
inline
I for_each_n(execution::parallel_unsequenced_policy, I f, N n, F fn)
{
return
::thrust::for_each_n(::thrust::device, f, n, ::std::move(fn));
}

template<
typename I,
typename N,
typename F,
enable_if_t<
!::hipstd::is_offloadable_iterator<I>() ||
!::hipstd::is_offloadable_callable<F>()>* = nullptr>
inline
I for_each_n(execution::parallel_unsequenced_policy, I f, N n, F fn)
{
if constexpr (!::hipstd::is_offloadable_iterator<I>()) {
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category>();
}
if constexpr (!::hipstd::is_offloadable_callable<F>()) {
::hipstd::unsupported_callable_type<F>();
}

return
::std::for_each_n(::std::execution::par, f, n, ::std::move(fn));
}
// END FOR_EACH_N
}
#endif // __HIPSTDPAR__
157 changes: 157 additions & 0 deletions thrust/system/hip/hipstdpar/impl/copy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*! \file thrust/system/hip/hipstdpar/copy.hpp
* \brief <tt>Copy operations</tt> implementation detail header for HIPSTDPAR.
*/

#pragma once

#if defined(__HIPSTDPAR__)

#include "hipstd.hpp"

#include <thrust/copy.h>
#include <thrust/execution_policy.h>

#include <algorithm>
#include <execution>
#include <utility>

namespace std
{
// BEGIN COPY
template<
typename I,
typename O,
enable_if_t<::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O copy(execution::parallel_unsequenced_policy, I fi, I li, O fo)
{
return ::thrust::copy(::thrust::device, fi, li, fo);
}

template<
typename I,
typename O,
enable_if_t<!::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O copy(execution::parallel_unsequenced_policy, I fi, I li, O fo)
{
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category,
typename iterator_traits<O>::iterator_category>();

return ::std::copy(::std::execution::par, fi, li, fo);
}
// END COPY

// BEGIN COPY_IF
template<
typename I,
typename O,
typename P,
enable_if_t<
::hipstd::is_offloadable_iterator<I, O>() &&
::hipstd::is_offloadable_callable<P>()>* = nullptr>
inline
O copy_if(execution::parallel_unsequenced_policy, I fi, I li, O fo, P p)
{
return
::thrust::copy_if(::thrust::device, fi, li, fo, ::std::move(p));
}

template<
typename I,
typename O,
typename P,
enable_if_t<
!::hipstd::is_offloadable_iterator<I, O>() ||
!::hipstd::is_offloadable_callable<P>()>* = nullptr>
inline
O copy_if(execution::parallel_unsequenced_policy, I fi, I li, O fo, P p)
{
if constexpr (!::hipstd::is_offloadable_iterator<I, O>()) {
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category,
typename iterator_traits<O>::iterator_category>();
}
if constexpr (!::hipstd::is_offloadable_callable<P>()) {
::hipstd::unsupported_callable_type<P>();
}

return ::std::copy_if(
::std::execution::par, fi, li, fo, ::std::move(p));
}
// END COPY_IF

// BEGIN COPY_N
template<
typename I,
typename N,
typename O,
enable_if_t<::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O copy_n(execution::parallel_unsequenced_policy, I fi, N n, O fo)
{
return ::thrust::copy_n(::thrust::device, fi, n, fo);
}

template<
typename I,
typename N,
typename O,
enable_if_t<!::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O copy_n(execution::parallel_unsequenced_policy, I fi, N n, O fo)
{
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category,
typename iterator_traits<O>::iterator_category>();

return ::std::copy_n(::std::execution::par, fi, n, fo);
}
// END COPY_N

// BEGIN MOVE
template<
typename I,
typename O,
enable_if_t<::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O move(execution::parallel_unsequenced_policy, I fi, I li, O fo)
{
return ::thrust::copy(
::thrust::device,
make_move_iterator(fi),
make_move_iterator(li),
fo);
}

template<
typename I,
typename O,
enable_if_t<!::hipstd::is_offloadable_iterator<I, O>()>* = nullptr>
inline
O move(execution::parallel_unsequenced_policy, I fi, I li, O fo)
{
::hipstd::unsupported_iterator_category<
typename iterator_traits<I>::iterator_category,
typename iterator_traits<O>::iterator_category>();

return ::std::move(::std::execution::par, fi, li, fo);
}
// END MOVE
}
#endif // __HIPSTDPAR__
Loading