RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
scan.hpp
Go to the documentation of this file.
1 
11 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
12 // Copyright (c) Lawrence Livermore National Security, LLC and other
13 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
14 // files for dates and other details. No copyright assignment is required
15 // to contribute to RAJA.
16 //
17 // SPDX-License-Identifier: (BSD-3-Clause)
18 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
19 
20 #ifndef RAJA_scan_openmp_HPP
21 #define RAJA_scan_openmp_HPP
22 
23 #include "RAJA/config.hpp"
24 
25 #include <algorithm>
26 #include <functional>
27 #include <iterator>
28 #include <type_traits>
29 #include <vector>
30 
31 #include <omp.h>
32 
36 
37 namespace RAJA
38 {
39 namespace impl
40 {
41 namespace scan
42 {
43 
48 template<typename Policy, typename Iter, typename BinFn>
49 RAJA_INLINE concepts::enable_if_t<resources::EventProxy<resources::Host>,
51 inclusive_inplace(resources::Host host_res,
52  const Policy&,
53  Iter begin,
54  Iter end,
55  BinFn f)
56 {
58  using std::distance;
59  using Value = typename ::std::iterator_traits<Iter>::value_type;
60  const auto n = distance(begin, end);
61  using DistanceT = typename std::remove_const<decltype(n)>::type;
62  const int p0 = std::min(n, static_cast<DistanceT>(omp_get_max_threads()));
63  ::std::vector<Value> sums(p0, Value());
64 #pragma omp parallel num_threads(p0)
65  {
66  const int p = omp_get_num_threads();
67  const int pid = omp_get_thread_num();
68  const DistanceT idx_begin = firstIndex(n, p, pid);
69  const DistanceT idx_end = firstIndex(n, p, pid + 1);
70  if (idx_begin != idx_end)
71  {
72  inclusive_inplace(host_res, ::RAJA::seq_exec {}, begin + idx_begin,
73  begin + idx_end, f);
74  sums[pid] = begin[idx_end - 1];
75  }
76 #pragma omp barrier
77 #pragma omp single
78  exclusive_inplace(host_res, ::RAJA::seq_exec {}, sums.data(),
79  sums.data() + p, f, BinFn::identity());
80  for (auto i = idx_begin; i < idx_end; ++i)
81  {
82  begin[i] = f(begin[i], sums[pid]);
83  }
84  }
85 
86  return resources::EventProxy<resources::Host>(host_res);
87 }
88 
93 template<typename Policy, typename Iter, typename BinFn, typename ValueT>
94 RAJA_INLINE concepts::enable_if_t<resources::EventProxy<resources::Host>,
96 exclusive_inplace(resources::Host host_res,
97  const Policy&,
98  Iter begin,
99  Iter end,
100  BinFn f,
101  ValueT v)
102 {
104  using std::distance;
105  using Value = typename ::std::iterator_traits<Iter>::value_type;
106  const auto n = distance(begin, end);
107  using DistanceT = typename std::remove_const<decltype(n)>::type;
108  const int p0 = std::min(n, static_cast<DistanceT>(omp_get_max_threads()));
109  ::std::vector<Value> sums(p0, v);
110 #pragma omp parallel num_threads(p0)
111  {
112  const int p = omp_get_num_threads();
113  const int pid = omp_get_thread_num();
114  const DistanceT idx_begin = firstIndex(n, p, pid);
115  const DistanceT idx_end = firstIndex(n, p, pid + 1);
116  const Value init = ((pid == 0) ? v : *(begin + idx_begin - 1));
117 #pragma omp barrier
118  if (idx_begin != idx_end)
119  {
120  exclusive_inplace(host_res, seq_exec {}, begin + idx_begin,
121  begin + idx_end, f, init);
122  sums[pid] = begin[idx_end - 1];
123  }
124 #pragma omp barrier
125 #pragma omp single
126  exclusive_inplace(host_res, seq_exec {}, sums.data(), sums.data() + p, f,
127  BinFn::identity());
128  for (auto i = idx_begin; i < idx_end; ++i)
129  {
130  begin[i] = f(begin[i], sums[pid]);
131  }
132  }
133 
134  return resources::EventProxy<resources::Host>(host_res);
135 }
136 
141 template<typename Policy, typename Iter, typename OutIter, typename BinFn>
142 RAJA_INLINE concepts::enable_if_t<resources::EventProxy<resources::Host>,
144 inclusive(resources::Host host_res,
145  const Policy& exec,
146  Iter begin,
147  Iter end,
148  OutIter out,
149  BinFn f)
150 {
151  using std::distance;
152  ::std::copy(begin, end, out);
153  return inclusive_inplace(host_res, exec, out, out + distance(begin, end), f);
154 }
155 
160 template<typename Policy,
161  typename Iter,
162  typename OutIter,
163  typename BinFn,
164  typename ValueT>
165 RAJA_INLINE concepts::enable_if_t<resources::EventProxy<resources::Host>,
167 exclusive(resources::Host host_res,
168  const Policy& exec,
169  Iter begin,
170  Iter end,
171  OutIter out,
172  BinFn f,
173  ValueT v)
174 {
175  using std::distance;
176  ::std::copy(begin, end, out);
177  return exclusive_inplace(host_res, exec, out, out + distance(begin, end), f,
178  v);
179 }
180 
181 } // namespace scan
182 
183 } // namespace impl
184 
185 } // namespace RAJA
186 
187 #endif
Header file for RAJA algorithm definitions.
RAJA_INLINE DiffType firstIndex(DiffType n, CountType num_threads, CountType thread_id)
Definition: algorithm.hpp:62
RAJA_INLINE concepts::enable_if_t< resources::EventProxy< resources::Host >, type_traits::is_openmp_policy< Policy > > inclusive(resources::Host host_res, const Policy &exec, Iter begin, Iter end, OutIter out, BinFn f)
Definition: scan.hpp:144
RAJA_INLINE concepts::enable_if_t< resources::EventProxy< resources::Host >, type_traits::is_openmp_policy< Policy > > exclusive(resources::Host host_res, const Policy &exec, Iter begin, Iter end, OutIter out, BinFn f, ValueT v)
Definition: scan.hpp:167
RAJA_INLINE concepts::enable_if_t< resources::EventProxy< resources::Host >, type_traits::is_openmp_policy< Policy > > inclusive_inplace(resources::Host host_res, const Policy &, Iter begin, Iter end, BinFn f)
Definition: scan.hpp:51
RAJA_INLINE concepts::enable_if_t< resources::EventProxy< resources::Host >, type_traits::is_openmp_policy< Policy > > exclusive_inplace(resources::Host host_res, const Policy &, Iter begin, Iter end, BinFn f, ValueT v)
Definition: scan.hpp:96
Definition: AlignedRangeIndexSetBuilders.cpp:35
RAJA_HOST_DEVICE constexpr RAJA_INLINE Result min(Args... args)
Definition: foldl.hpp:161
Policy
Definition: PolicyBase.hpp:32
Header file containing RAJA OpenMP policy definitions.
Header file providing RAJA scan declarations.
Definition: policy.hpp:78
Definition: PolicyBase.hpp:215