-
Notifications
You must be signed in to change notification settings - Fork 103
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
Draft: Valloc Interface for New Reducer #1690
Changes from 3 commits
4281dd5
ffe64f3
c74150e
9f3b68e
928a5a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,8 @@ | |
#include "RAJA/policy/sycl/MemUtils_SYCL.hpp" | ||
#endif | ||
|
||
#include "RAJA/pattern/params/refloc_base.hpp" | ||
|
||
namespace RAJA | ||
{ | ||
|
||
|
@@ -23,29 +25,115 @@ struct ValLoc { | |
using index_type = RAJA::Index_type; | ||
using value_type = T; | ||
|
||
RAJA_HOST_DEVICE ValLoc() {} | ||
RAJA_HOST_DEVICE ValLoc(value_type v) : val(v) {} | ||
RAJA_HOST_DEVICE ValLoc(value_type v, RAJA::Index_type l) : val(v), loc(l) {} | ||
|
||
RAJA_HOST_DEVICE void min(value_type v, index_type l) { if (v < val) { val = v; loc = l; } } | ||
RAJA_HOST_DEVICE void max(value_type v, index_type l) { if (v > val) { val = v; loc = l; } } | ||
RAJA_HOST_DEVICE constexpr ValLoc() {} | ||
RAJA_HOST_DEVICE constexpr explicit ValLoc(value_type v) : val(v) {} | ||
RAJA_HOST_DEVICE constexpr ValLoc(value_type v, RAJA::Index_type l) : val(v), loc(l) {} | ||
|
||
bool constexpr operator<(const ValLoc& rhs) const { return val < rhs.val; } | ||
bool constexpr operator>(const ValLoc& rhs) const { return val > rhs.val; } | ||
RAJA_HOST_DEVICE constexpr bool operator<(const ValLoc& rhs) const { return val < rhs.val; } | ||
RAJA_HOST_DEVICE constexpr bool operator>(const ValLoc& rhs) const { return val > rhs.val; } | ||
|
||
value_type getVal() {return val;} | ||
RAJA::Index_type getLoc() {return loc;} | ||
RAJA_HOST_DEVICE constexpr value_type getVal() const {return val;} | ||
MrBurmark marked this conversation as resolved.
Show resolved
Hide resolved
|
||
RAJA_HOST_DEVICE constexpr RAJA::Index_type getLoc() const {return loc;} | ||
|
||
private: | ||
value_type val; | ||
index_type loc = -1; | ||
}; | ||
|
||
template<typename T, template <typename, typename, typename> class Op> | ||
struct ValOp { | ||
using value_type = T; | ||
using op_type = Op<T,T,T>; | ||
|
||
RAJA_HOST_DEVICE constexpr ValOp() {} | ||
RAJA_HOST_DEVICE constexpr explicit ValOp(value_type v) : val(v) {} | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::minimum<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & min(value_type v) { if (v < val) { val = v; } return *this; } | ||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::maximum<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & max(value_type v) { if (v > val) { val = v; } return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::plus<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & operator+=(const value_type& rhs) { val += rhs; return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::bit_and<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & operator&=(const value_type& rhs) { val &= rhs; return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::bit_or<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & operator|=(const value_type& rhs) { val |= rhs; return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::bit_and<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE ValOp & operator&=(value_type& rhs) { val &= rhs; return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::bit_or<T,T,T>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE ValOp & operator|=(value_type& rhs) { val |= rhs; return *this; } | ||
rchen20 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
RAJA_HOST_DEVICE constexpr bool operator<(const ValOp& rhs) const { val < rhs.val; return *this; } | ||
RAJA_HOST_DEVICE constexpr bool operator>(const ValOp& rhs) const { val > rhs.val; return *this; } | ||
|
||
RAJA_HOST_DEVICE constexpr value_type get() const {return val;} | ||
|
||
//private: | ||
value_type val; | ||
}; | ||
|
||
template<typename T, template <typename, typename, typename> class Op> | ||
struct ValOp <ValLoc<T>, Op> { | ||
using index_type = RAJA::Index_type; | ||
using value_type = ValLoc<T>; | ||
using op_type = Op<value_type,value_type,value_type>; | ||
using valloc_value_type = typename value_type::value_type; | ||
using valloc_index_type = typename value_type::index_type; | ||
|
||
RAJA_HOST_DEVICE constexpr ValOp() {} | ||
RAJA_HOST_DEVICE constexpr explicit ValOp(value_type v) : val(v) {} | ||
RAJA_HOST_DEVICE constexpr explicit ValOp(valloc_value_type v) : val(v) {} | ||
RAJA_HOST_DEVICE constexpr ValOp(valloc_value_type v, valloc_index_type l) : val(v, l) {} | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::minimum<value_type,value_type,value_type>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & min(value_type v) { if (v < val) { val = v; } return *this; } | ||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::maximum<value_type,value_type,value_type>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & max(value_type v) { if (v > val) { val = v; } return *this; } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::minimum<value_type,value_type,value_type>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & minloc(valloc_value_type v, valloc_index_type l) { return min(value_type(v,l)); } | ||
|
||
template <typename U = op_type, std::enable_if_t<std::is_same<U, RAJA::operators::maximum<value_type,value_type,value_type>>::value> * = nullptr> | ||
RAJA_HOST_DEVICE constexpr ValOp & maxloc(valloc_value_type v, valloc_index_type l) { return max(value_type(v,l)); } | ||
|
||
RAJA_HOST_DEVICE constexpr bool operator<(const ValOp& rhs) const { return val < rhs.val; } | ||
RAJA_HOST_DEVICE constexpr bool operator>(const ValOp& rhs) const { return val > rhs.val; } | ||
|
||
RAJA_HOST_DEVICE constexpr value_type get() const {return val;} | ||
RAJA_HOST_DEVICE constexpr valloc_value_type getVal() const {return val.getVal();} | ||
RAJA_HOST_DEVICE constexpr valloc_index_type getLoc() const {return val.getLoc();} | ||
|
||
private: | ||
value_type val; | ||
}; | ||
|
||
template<typename T, template <typename, typename, typename> class Op> | ||
using ValLocOp = ValOp<ValLoc<T>, Op>; | ||
|
||
} // namespace expt | ||
|
||
namespace operators | ||
{ | ||
|
||
template <typename T, template <typename, typename, typename> class Op> | ||
struct limits<RAJA::expt::ValOp<T, Op>, void> { | ||
RAJA_INLINE RAJA_HOST_DEVICE static constexpr RAJA::expt::ValOp<T, Op> min() | ||
{ | ||
return RAJA::expt::ValOp<T, Op>(RAJA::operators::limits<T>::min()); | ||
} | ||
|
||
RAJA_INLINE RAJA_HOST_DEVICE static constexpr RAJA::expt::ValOp<T, Op> max() | ||
{ | ||
return RAJA::expt::ValOp<T, Op>(RAJA::operators::limits<T>::max()); | ||
} | ||
}; | ||
|
||
|
||
template <typename T> | ||
struct limits<RAJA::expt::ValLoc<T>> { | ||
RAJA_INLINE RAJA_HOST_DEVICE static constexpr RAJA::expt::ValLoc<T> min() | ||
|
@@ -85,14 +173,19 @@ namespace detail | |
// | ||
template <typename Op, typename T> | ||
struct Reducer : public ForallParamBase { | ||
//using op = Op<T,T,T>; | ||
using op = Op; | ||
using value_type = T; | ||
//using value_op = ValOp<T, Op>; | ||
|
||
RAJA_HOST_DEVICE Reducer() {} | ||
Reducer(value_type *target_in) : target(target_in), val(op::identity()) {} | ||
//Reducer(value_type *target_in) : target(target_in), val(op::identity()), vop(value_op(*target_in)) {} | ||
//Reducer(value_op *target_in) : target(target_in->get()), val(op::identity()), vop(value_op(*target_in)) {} | ||
|
||
value_type *target = nullptr; | ||
value_type val = op::identity(); | ||
//value_op *vop = nullptr; | ||
|
||
#if defined(RAJA_CUDA_ACTIVE) || defined(RAJA_HIP_ACTIVE) || defined(RAJA_SYCL_ACTIVE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reminds me that we should specialize SoAPtr on ValLoc, etc. |
||
// Device related attributes. | ||
|
@@ -106,10 +199,23 @@ namespace detail | |
|
||
using ARG_LIST_T = typename ARG_TUP_T::TList; | ||
static constexpr size_t num_lambda_args = camp::tuple_size<ARG_TUP_T>::value ; | ||
|
||
}; | ||
|
||
} // namespace detail | ||
|
||
template <template <typename, typename, typename> class Op, typename T> | ||
auto constexpr Reduce(ValOp<ValLoc<T>,Op> *target) | ||
{ | ||
return detail::Reducer<Op<ValOp<ValLoc<T>,Op>, ValOp<ValLoc<T>,Op>, ValOp<ValLoc<T>,Op>>, ValOp<ValLoc<T>,Op>>(target); | ||
} | ||
|
||
template <template <typename, typename, typename> class Op, typename T> | ||
auto constexpr Reduce(ValOp<T,Op> *target) | ||
{ | ||
return detail::Reducer<Op<ValOp<T,Op>, ValOp<T,Op>, ValOp<T,Op>>, ValOp<T,Op>>(target); | ||
} | ||
|
||
template <template <typename, typename, typename> class Op, typename T> | ||
auto constexpr Reduce(T *target) | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,50 @@ namespace RAJA { | |
namespace expt { | ||
namespace detail { | ||
|
||
// Init | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
init(Reducer<OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>, ValOp<ValLoc<T>,OP>>& red) { | ||
red.val = OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>::identity(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should figure out why using |
||
} | ||
// Combine | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
combine(Reducer<OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>, ValOp<ValLoc<T>,OP>>& out, const Reducer<OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>, ValOp<ValLoc<T>,OP>>& in) { | ||
out.val = OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>{}(out.val, in.val); | ||
} | ||
// Resolve | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
resolve(Reducer<OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>, ValOp<ValLoc<T>,OP>>& red) { | ||
*red.target = OP<ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>, ValOp<ValLoc<T>,OP>>{}(*red.target, red.val); | ||
} | ||
|
||
// Init | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
init(Reducer<OP<ValOp<T,OP>, ValOp<T,OP>, ValOp<T,OP>>, ValOp<T,OP>>& red) { | ||
// RCC trying to understand what these types are | ||
//decltype(red.val)::nothing; | ||
//decltype(OP<T,T,T>::identity())::nothing; | ||
//red.val comes from include/RAJA/pattern/params/reducer.hpp struct Reducer{value_type val = op::identity()} | ||
// RCC doesn't work red.val = ValOp<T,OP>::identity(); // need to get OP<T,T,T>::identity() | ||
// CHANGE THIS TO USE A set() function for val in ValOp | ||
red.val.val = OP<T,T,T>::identity(); | ||
} | ||
// Combine | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
combine(Reducer<OP<ValOp<T,OP>, ValOp<T,OP>, ValOp<T,OP>>, ValOp<T,OP>>& out, const Reducer<OP<ValOp<T,OP>, ValOp<T,OP>, ValOp<T,OP>>, ValOp<T,OP>>& in) { | ||
out.val.val = OP<T,T,T>{}(out.val.val, in.val.val); | ||
} | ||
// Resolve | ||
template<typename EXEC_POL, template <typename, typename, typename> class OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
resolve(Reducer<OP<ValOp<T,OP>, ValOp<T,OP>, ValOp<T,OP>>, ValOp<T,OP>>& red) { | ||
red.target->val = OP<T,T,T>{}(red.target->val, red.val.val); | ||
} | ||
|
||
// Init | ||
template<typename EXEC_POL, typename OP, typename T> | ||
camp::concepts::enable_if< std::is_same< EXEC_POL, RAJA::seq_exec> > | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an option to change the loc type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean you want something like
ValLocOp<double, int, minimum>
, whereint
represents the loc type? I don't think we've had that in the past.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, and we always should have had it.