Ginkgo  Generated from pipelines/1330831941 branch based on master. Ginkgo version 1.8.0
A numerical linear algebra library targeting many-core architectures
spaces.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GINKGO_EXTENSIONS_KOKKOS_SPACES_HPP
6 #define GINKGO_EXTENSIONS_KOKKOS_SPACES_HPP
7 
8 #include <Kokkos_Core.hpp>
9 
10 
11 #include <ginkgo/config.hpp>
12 #include <ginkgo/core/base/exception.hpp>
13 #include <ginkgo/core/base/exception_helpers.hpp>
14 #include <ginkgo/core/base/executor.hpp>
15 
16 
17 namespace gko {
18 namespace ext {
19 namespace kokkos {
20 namespace detail {
21 
22 
29 template <typename MemorySpace, typename ExecType>
30 struct compatible_space
31  : std::integral_constant<bool, Kokkos::has_shared_space ||
32  Kokkos::has_shared_host_pinned_space> {};
33 
34 template <>
35 struct compatible_space<Kokkos::HostSpace, ReferenceExecutor> : std::true_type {
36 };
37 
38 template <typename MemorySpace>
39 struct compatible_space<MemorySpace, ReferenceExecutor> {
40  // need manual implementation of std::integral_constant because,
41  // while compiling for cuda, somehow bool is replaced by __nv_bool
42  static constexpr bool value =
43  Kokkos::SpaceAccessibility<Kokkos::HostSpace, MemorySpace>::accessible;
44 };
45 
46 #ifdef KOKKOS_ENABLE_OPENMP
47 template <typename MemorySpace>
48 struct compatible_space<MemorySpace, OmpExecutor>
49  : compatible_space<MemorySpace, ReferenceExecutor> {};
50 #endif
51 
52 #ifdef KOKKOS_ENABLE_CUDA
53 template <typename MemorySpace>
54 struct compatible_space<MemorySpace, CudaExecutor> {
55  static constexpr bool value =
56  Kokkos::SpaceAccessibility<Kokkos::Cuda, MemorySpace>::accessible;
57 };
58 #endif
59 
60 #ifdef KOKKOS_ENABLE_HIP
61 template <typename MemorySpace>
62 struct compatible_space<MemorySpace, HipExecutor> {
63  static constexpr bool value =
64  Kokkos::SpaceAccessibility<Kokkos::HIP, MemorySpace>::accessible;
65 };
66 #endif
67 
68 #ifdef KOKKOS_ENABLE_SYCL
69 template <typename MemorySpace>
70 struct compatible_space<MemorySpace, DpcppExecutor> {
71  static constexpr bool value =
72  Kokkos::SpaceAccessibility<Kokkos::Experimental::SYCL,
73  MemorySpace>::accessible;
74 };
75 #endif
76 
77 
86 template <typename MemorySpace, typename ExecType>
87 inline bool check_compatibility(std::shared_ptr<const ExecType>)
88 {
89  return compatible_space<MemorySpace, ExecType>::value;
90 }
91 
92 
102 template <typename MemorySpace>
103 inline bool check_compatibility(std::shared_ptr<const Executor> exec)
104 {
105  if (auto p = std::dynamic_pointer_cast<const ReferenceExecutor>(exec)) {
106  return check_compatibility<MemorySpace>(p);
107  }
108  if (auto p = std::dynamic_pointer_cast<const OmpExecutor>(exec)) {
109  return check_compatibility<MemorySpace>(p);
110  }
111  if (auto p = std::dynamic_pointer_cast<const CudaExecutor>(exec)) {
112  return check_compatibility<MemorySpace>(p);
113  }
114  if (auto p = std::dynamic_pointer_cast<const HipExecutor>(exec)) {
115  return check_compatibility<MemorySpace>(p);
116  }
117  if (auto p = std::dynamic_pointer_cast<const DpcppExecutor>(exec)) {
118  return check_compatibility<MemorySpace>(p);
119  }
120  GKO_NOT_IMPLEMENTED;
121 }
122 
123 
134 template <typename MemorySpace, typename T>
135 inline void assert_compatibility(T&& obj)
136 {
137  GKO_THROW_IF_INVALID(check_compatibility<MemorySpace>(obj.get_executor()),
138  "Executor type and memory space are incompatible");
139 }
140 
141 
142 } // namespace detail
143 
144 
152 inline std::shared_ptr<Executor> create_default_host_executor()
153 {
154 #ifdef KOKKOS_ENABLE_SERIAL
155  if constexpr (std::is_same_v<Kokkos::DefaultHostExecutionSpace,
156  Kokkos::Serial>) {
157  return ReferenceExecutor::create();
158  }
159 #endif
160 #ifdef KOKKOS_ENABLE_OPENMP
161  if constexpr (std::is_same_v<Kokkos::DefaultHostExecutionSpace,
162  Kokkos::OpenMP>) {
163  return OmpExecutor::create();
164  }
165 #endif
166  GKO_NOT_IMPLEMENTED;
167 }
168 
169 
191 template <typename ExecSpace,
192  typename MemorySpace = typename ExecSpace::memory_space>
193 inline std::shared_ptr<Executor> create_executor(ExecSpace ex, MemorySpace = {})
194 {
195  static_assert(
196  Kokkos::SpaceAccessibility<ExecSpace, MemorySpace>::accessible);
197 #ifdef KOKKOS_ENABLE_SERIAL
198  if constexpr (std::is_same_v<ExecSpace, Kokkos::Serial>) {
199  return ReferenceExecutor::create();
200  }
201 #endif
202 #ifdef KOKKOS_ENABLE_OPENMP
203  if constexpr (std::is_same_v<ExecSpace, Kokkos::OpenMP>) {
204  return OmpExecutor::create();
205  }
206 #endif
207 #ifdef KOKKOS_ENABLE_CUDA
208  if constexpr (std::is_same_v<ExecSpace, Kokkos::Cuda>) {
209  if constexpr (std::is_same_v<MemorySpace, Kokkos::CudaSpace>) {
210  return CudaExecutor::create(
211  Kokkos::device_id(), create_default_host_executor(),
212  std::make_shared<CudaAllocator>(), ex.cuda_stream());
213  }
214  if constexpr (std::is_same_v<MemorySpace, Kokkos::CudaUVMSpace>) {
215  return CudaExecutor::create(
216  Kokkos::device_id(), create_default_host_executor(),
217  std::make_shared<CudaUnifiedAllocator>(Kokkos::device_id()),
218  ex.cuda_stream());
219  }
220  if constexpr (std::is_same_v<MemorySpace,
221  Kokkos::CudaHostPinnedSpace>) {
222  return CudaExecutor::create(
223  Kokkos::device_id(), create_default_host_executor(),
224  std::make_shared<CudaHostAllocator>(Kokkos::device_id()),
225  ex.cuda_stream());
226  }
227  }
228 #endif
229 #ifdef KOKKOS_ENABLE_HIP
230  if constexpr (std::is_same_v<ExecSpace, Kokkos::HIP>) {
231  if constexpr (std::is_same_v<MemorySpace, Kokkos::HIPSpace>) {
232  return HipExecutor::create(
233  Kokkos::device_id(), create_default_host_executor(),
234  std::make_shared<HipAllocator>(), ex.hip_stream());
235  }
236  if constexpr (std::is_same_v<MemorySpace, Kokkos::HIPManagedSpace>) {
237  return HipExecutor::create(
238  Kokkos::device_id(), create_default_host_executor(),
239  std::make_shared<HipUnifiedAllocator>(Kokkos::device_id()),
240  ex.hip_stream());
241  }
242  if constexpr (std::is_same_v<MemorySpace, Kokkos::HIPHostPinnedSpace>) {
243  return HipExecutor::create(
244  Kokkos::device_id(), create_default_host_executor(),
245  std::make_shared<HipHostAllocator>(Kokkos::device_id()),
246  ex.hip_stream());
247  }
248  }
249 #endif
250 #ifdef KOKKOS_ENABLE_SYCL
251  if constexpr (std::is_same_v<ExecSpace, Kokkos::Experimental::SYCL>) {
252  static_assert(
253  std::is_same_v<MemorySpace, Kokkos::Experimental::SYCLSpace>,
254  "Ginkgo doesn't support shared memory space allocation for SYCL");
255  return DpcppExecutor::create(Kokkos::device_id(),
256  create_default_host_executor());
257  }
258 #endif
259  GKO_NOT_IMPLEMENTED;
260 }
261 
262 
268 inline std::shared_ptr<Executor> create_default_executor(
269  Kokkos::DefaultExecutionSpace ex = {})
270 {
271  return create_executor(std::move(ex));
272 }
273 
274 
275 } // namespace kokkos
276 } // namespace ext
277 } // namespace gko
278 
279 
280 #endif // GINKGO_EXTENSIONS_KOKKOS_SPACES_HPP
gko::HipExecutor::create
static std::shared_ptr< HipExecutor > create(int device_id, std::shared_ptr< Executor > master, bool device_reset, allocation_mode alloc_mode=default_hip_alloc_mode, CUstream_st *stream=nullptr)
Creates a new HipExecutor.
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::CudaExecutor::create
static std::shared_ptr< CudaExecutor > create(int device_id, std::shared_ptr< Executor > master, bool device_reset, allocation_mode alloc_mode=default_cuda_alloc_mode, CUstream_st *stream=nullptr)
Creates a new CudaExecutor.
gko::OmpExecutor::create
static std::shared_ptr< OmpExecutor > create(std::shared_ptr< CpuAllocatorBase > alloc=std::make_shared< CpuAllocator >())
Creates a new OmpExecutor.
Definition: executor.hpp:1345
gko::DpcppExecutor::create
static std::shared_ptr< DpcppExecutor > create(int device_id, std::shared_ptr< Executor > master, std::string device_type="all", dpcpp_queue_property property=dpcpp_queue_property::in_order)
Creates a new DpcppExecutor.