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