RAJA
RAJA provides a collection of platform portability abstractions for C++ HPC applications.
SyclKernel.hpp
Go to the documentation of this file.
1 
12 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
13 // Copyright (c) Lawrence Livermore National Security, LLC and other
14 // RAJA Project Developers. See top-level LICENSE and COPYRIGHT
15 // files for dates and other details. No copyright assignment is required
16 // to contribute to RAJA.
17 //
18 // SPDX-License-Identifier: (BSD-3-Clause)
19 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
20 
21 #ifndef RAJA_policy_sycl_kernel_SyclKernel_HPP
22 #define RAJA_policy_sycl_kernel_SyclKernel_HPP
23 
24 #include "RAJA/config.hpp"
25 
26 #if defined(RAJA_ENABLE_SYCL)
27 
28 #include <cassert>
29 #include <climits>
30 
31 #include "camp/camp.hpp"
32 
33 #include "RAJA/util/macros.hpp"
34 #include "RAJA/util/types.hpp"
35 
36 #include "RAJA/pattern/kernel.hpp"
39 
42 
44 
45 namespace RAJA
46 {
47 
52 template<bool async0>
53 struct sycl_launch : public RAJA::make_policy_pattern_launch_platform_t<
54  RAJA::Policy::sycl,
55  RAJA::Pattern::forall,
56  detail::get_launch<async0>::value,
57  RAJA::Platform::sycl>
58 {};
59 
60 namespace statement
61 {
62 
63 /*
64  * ! RAJA::kernel statement that launches a SYCL kernel.
65  */
66 template<typename LaunchConfig, typename... EnclosedStmts>
67 struct SyclKernelExt
68  : public internal::Statement<LaunchConfig, EnclosedStmts...>
69 {};
70 
71 /*
72  * A RAJA::kernel statement that launches a SYCL kernel.
73  * The kernel launch is synchronous.
74  */
75 template<typename... EnclosedStmts>
76 using SyclKernel = SyclKernelExt<sycl_launch<false>, EnclosedStmts...>;
77 
82 template<typename... EnclosedStmts>
83 using SyclKernelAsync = SyclKernelExt<sycl_launch<true>, EnclosedStmts...>;
84 
85 } // namespace statement
86 
87 namespace internal
88 {
89 
93 template<typename Data, typename Exec>
94 void SyclKernelLauncher(Data data, ::sycl::nd_item<3> item)
95 {
96 
97  using data_t = camp::decay<Data>;
98  data_t private_data = data;
99 
100  // execute the the object
101  Exec::exec(private_data, item, true);
102 }
103 
108 template<bool IsTriviallyCopyable,
109  typename LaunchPolicy,
110  typename StmtList,
111  typename Data,
112  typename Types>
113 struct SyclLaunchHelper;
114 
120 template<bool async0, typename StmtList, typename Data, typename Types>
121 struct SyclLaunchHelper<false, sycl_launch<async0>, StmtList, Data, Types>
122 {
123  using Self = SyclLaunchHelper;
124 
125  static constexpr bool async = async0;
126 
127  using executor_t =
128  internal::sycl_statement_list_executor_t<StmtList, Data, Types>;
129  using data_t = camp::decay<Data>;
130 
131  static void launch(Data&& data,
132  internal::LaunchDims launch_dims,
133  size_t RAJA_UNUSED_ARG(shmem),
134  ::sycl::queue* qu)
135  {
136 
137  //
138  // Setup shared memory buffers
139  // Kernel body is nontrivially copyable, create space on device and copy to
140  // Workaround until "is_device_copyable" is supported
141  //
142  data_t* m_data = (data_t*)::sycl::malloc_device(sizeof(data_t), *qu);
143  qu->memcpy(m_data, &data, sizeof(data_t)).wait();
144 
145  qu->submit([&](::sycl::handler& h) {
146  h.parallel_for(launch_dims.fit_nd_range(qu),
147  [=](::sycl::nd_item<3> item) {
148  SyclKernelLauncher<Data, executor_t>(*m_data, item);
149  });
150  }).wait(); // Need to wait to free memory
151 
152  ::sycl::free(m_data, *qu);
153  }
154 };
155 
161 template<bool async0, typename StmtList, typename Data, typename Types>
162 struct SyclLaunchHelper<true, sycl_launch<async0>, StmtList, Data, Types>
163 {
164  using Self = SyclLaunchHelper;
165 
166  static constexpr bool async = async0;
167 
168  using executor_t =
169  internal::sycl_statement_list_executor_t<StmtList, Data, Types>;
170  using data_t = camp::decay<Data>;
171 
172  static void launch(Data&& data,
173  internal::LaunchDims launch_dims,
174  size_t RAJA_UNUSED_ARG(shmem),
175  ::sycl::queue* qu)
176  {
177 
178  qu->submit([&](::sycl::handler& h) {
179  h.parallel_for(launch_dims.fit_nd_range(qu),
180  [=](::sycl::nd_item<3> item) {
181  SyclKernelLauncher<Data, executor_t>(data, item);
182  });
183  });
184 
185  if (!async)
186  {
187  qu->wait();
188  };
189  }
190 };
191 
195 template<typename LaunchConfig, typename... EnclosedStmts, typename Types>
196 struct StatementExecutor<
197  statement::SyclKernelExt<LaunchConfig, EnclosedStmts...>,
198  Types>
199 {
200 
201  using stmt_list_t = StatementList<EnclosedStmts...>;
202  using StatementType =
203  statement::SyclKernelExt<LaunchConfig, EnclosedStmts...>;
204 
205  template<typename Data>
206  static inline void exec(Data&& data)
207  {
208 
209  using data_t = camp::decay<Data>;
210  using executor_t =
211  sycl_statement_list_executor_t<stmt_list_t, data_t, Types>;
212  using launch_t = SyclLaunchHelper<std::is_trivially_copyable<data_t>::value,
213  LaunchConfig, stmt_list_t, data_t, Types>;
214 
215  camp::resources::Sycl res = data.get_resource();
216  ::sycl::queue* q = res.get_queue();
217  ;
218 
219  //
220  // Compute the requested kernel dimensions
221  //
222  LaunchDims launch_dims = executor_t::calculateDimensions(data);
223 
224  int shmem = 0;
225 
226  //
227  // Launch the kernels
228  //
229  launch_t::launch(std::move(data), launch_dims, shmem, q);
230  }
231 };
232 
233 
234 } // namespace internal
235 } // namespace RAJA
236 
237 #endif // closing endif for RAJA_ENABLE_SYCL guard
238 
239 #endif // closing endif for header file include guard
Header file defining prototypes for routines used to manage memory for SYCL reductions and other oper...
Header file for common RAJA internal macro definitions.
#define RAJA_UNUSED_ARG(x)
Definition: macros.hpp:97
camp::list< Stmts... > StatementList
Definition: StatementList.hpp:41
Definition: AlignedRangeIndexSetBuilders.cpp:35
void launch(LaunchParams const &launch_params, ReduceParams &&... rest_of_launch_args)
Definition: launch_core.hpp:268
Header file for statement wrappers and executors.
Header file for kernel lambda executor.
RAJA header file containing user interface for RAJA::kernel.
RAJA header file containing constructs used to run kernel traversals on GPU with SYCL.
Definition: PolicyBase.hpp:75
Header file containing RAJA SYCL policy definitions.
Header file for RAJA type definitions.