Ginkgo  Generated from pipelines/2969282958 branch based on develop. Ginkgo version 2.0.0
A numerical linear algebra library targeting many-core architectures
executor.hpp
1 // SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_
6 #define GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_
7 
8 
9 #include <array>
10 #include <atomic>
11 #include <iostream>
12 #include <memory>
13 #include <mutex>
14 #include <sstream>
15 #include <string>
16 #include <tuple>
17 #include <type_traits>
18 #include <vector>
19 
20 #include <ginkgo/core/base/device.hpp>
21 #include <ginkgo/core/base/fwd_decls.hpp>
22 #include <ginkgo/core/base/memory.hpp>
23 #include <ginkgo/core/base/scoped_device_id_guard.hpp>
24 #include <ginkgo/core/base/types.hpp>
25 #include <ginkgo/core/log/logger.hpp>
26 #include <ginkgo/core/synthesizer/containers.hpp>
27 
28 
29 namespace gko {
30 
31 
39  never,
45  automatic
46 };
47 
48 
61 enum class allocation_mode { device, unified_global, unified_host };
62 
63 
64 #ifdef NDEBUG
65 
66 // When in release, prefer device allocations
67 constexpr allocation_mode default_cuda_alloc_mode = allocation_mode::device;
68 
69 constexpr allocation_mode default_hip_alloc_mode = allocation_mode::device;
70 
71 #else
72 
73 // When in debug, always UM allocations.
74 constexpr allocation_mode default_cuda_alloc_mode =
75  allocation_mode::unified_global;
76 
77 #if (GINKGO_HIP_PLATFORM_HCC == 1)
78 
79 // HIP on AMD GPUs does not support UM, so always prefer device allocations.
80 constexpr allocation_mode default_hip_alloc_mode = allocation_mode::device;
81 
82 #else
83 
84 // HIP on NVIDIA GPUs supports UM, so prefer UM allocations.
85 constexpr allocation_mode default_hip_alloc_mode =
86  allocation_mode::unified_global;
87 
88 #endif
89 
90 #endif
91 
92 
93 } // namespace gko
94 
95 
100 enum class dpcpp_queue_property {
104  in_order = 1,
105 
109  enable_profiling = 2
110 };
111 
112 GKO_ATTRIBUTES GKO_INLINE dpcpp_queue_property operator|(dpcpp_queue_property a,
113  dpcpp_queue_property b)
114 {
115  return static_cast<dpcpp_queue_property>(static_cast<int>(a) |
116  static_cast<int>(b));
117 }
118 
119 
120 namespace gko {
121 
122 
123 #define GKO_FORWARD_DECLARE(_type, ...) class _type
124 
125 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_FORWARD_DECLARE);
126 
127 #undef GKO_FORWARD_DECLARE
128 
129 
130 class ReferenceExecutor;
131 
132 
133 namespace detail {
134 
135 
136 template <typename>
137 class ExecutorBase;
138 
139 
140 } // namespace detail
141 
142 
257 class Operation {
258 public:
259  virtual ~Operation() = default;
260 
261 #define GKO_DECLARE_RUN_OVERLOAD(_type, ...) \
262  virtual void run(std::shared_ptr<const _type>) const
263 
264  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_RUN_OVERLOAD);
265 
266 #undef GKO_DECLARE_RUN_OVERLOAD
267 
268  // ReferenceExecutor overload can be defaulted to OmpExecutor's
269  virtual void run(std::shared_ptr<const ReferenceExecutor> executor) const;
270 
276  virtual const char* get_name() const noexcept;
277 };
278 
279 
280 namespace detail {
281 
282 
292 template <typename Closure>
293 class RegisteredOperation : public Operation {
294 public:
301  RegisteredOperation(const char* name, Closure op)
302  : name_(name), op_(std::move(op))
303  {}
304 
305  const char* get_name() const noexcept override { return name_; }
306 
307  void run(std::shared_ptr<const ReferenceExecutor> exec) const override
308  {
309  op_(exec);
310  }
311 
312  void run(std::shared_ptr<const OmpExecutor> exec) const override
313  {
314  op_(exec);
315  }
316 
317  void run(std::shared_ptr<const CudaExecutor> exec) const override
318  {
319  op_(exec);
320  }
321 
322  void run(std::shared_ptr<const HipExecutor> exec) const override
323  {
324  op_(exec);
325  }
326 
327  void run(std::shared_ptr<const DpcppExecutor> exec) const override
328  {
329  op_(exec);
330  }
331 
332 private:
333  const char* name_;
334  Closure op_;
335 };
336 
337 
338 template <typename Closure>
339 RegisteredOperation<Closure> make_register_operation(const char* name,
340  Closure op)
341 {
342  return RegisteredOperation<Closure>{name, std::move(op)};
343 }
344 
345 
346 } // namespace detail
347 
348 
420 #define GKO_REGISTER_OPERATION(_name, _kernel) \
421  template <typename... Args> \
422  auto make_##_name(Args&&... args) \
423  { \
424  return ::gko::detail::make_register_operation( \
425  #_kernel, [&args...](auto exec) { \
426  using exec_type = decltype(exec); \
427  if constexpr (std::is_same< \
428  exec_type, \
429  std::shared_ptr< \
430  const ::gko::ReferenceExecutor>>:: \
431  value) { \
432  ::gko::kernels::reference::_kernel( \
433  std::dynamic_pointer_cast< \
434  const ::gko::ReferenceExecutor>(exec), \
435  std::forward<Args>(args)...); \
436  } else if constexpr ( \
437  std::is_same< \
438  exec_type, \
439  std::shared_ptr<const ::gko::OmpExecutor>>::value) { \
440  ::gko::kernels::omp::_kernel( \
441  std::dynamic_pointer_cast<const ::gko::OmpExecutor>( \
442  exec), \
443  std::forward<Args>(args)...); \
444  } else if constexpr ( \
445  std::is_same< \
446  exec_type, \
447  std::shared_ptr<const ::gko::CudaExecutor>>::value) { \
448  ::gko::kernels::cuda::_kernel( \
449  std::dynamic_pointer_cast<const ::gko::CudaExecutor>( \
450  exec), \
451  std::forward<Args>(args)...); \
452  } else if constexpr ( \
453  std::is_same< \
454  exec_type, \
455  std::shared_ptr<const ::gko::HipExecutor>>::value) { \
456  ::gko::kernels::hip::_kernel( \
457  std::dynamic_pointer_cast<const ::gko::HipExecutor>( \
458  exec), \
459  std::forward<Args>(args)...); \
460  } else if constexpr ( \
461  std::is_same< \
462  exec_type, \
463  std::shared_ptr<const ::gko::DpcppExecutor>>::value) { \
464  ::gko::kernels::dpcpp::_kernel( \
465  std::dynamic_pointer_cast<const ::gko::DpcppExecutor>( \
466  exec), \
467  std::forward<Args>(args)...); \
468  } else { \
469  GKO_NOT_IMPLEMENTED; \
470  } \
471  }); \
472  } \
473  static_assert(true, \
474  "This assert is used to counter the false positive extra " \
475  "semi-colon warnings")
476 
477 
515 #define GKO_REGISTER_HOST_OPERATION(_name, _kernel) \
516  template <typename... Args> \
517  auto make_##_name(Args&&... args) \
518  { \
519  return ::gko::detail::make_register_operation( \
520  #_kernel, \
521  [&args...](auto) { _kernel(std::forward<Args>(args)...); }); \
522  } \
523  static_assert(true, \
524  "This assert is used to counter the false positive extra " \
525  "semi-colon warnings")
526 
527 
528 #define GKO_DECLARE_EXECUTOR_FRIEND(_type, ...) friend class _type
529 
617 class Executor : public log::EnableLogging<Executor> {
618  template <typename T>
619  friend class detail::ExecutorBase;
620 
621  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_EXECUTOR_FRIEND);
622  friend class ReferenceExecutor;
623 
624 public:
625  virtual ~Executor() = default;
626 
627  Executor() = default;
628  Executor(Executor&) = delete;
629  Executor(Executor&&) = delete;
630  Executor& operator=(Executor&) = delete;
631  Executor& operator=(Executor&&) = delete;
632 
638  virtual void run(const Operation& op) const = 0;
639 
654  template <typename ClosureOmp, typename ClosureCuda, typename ClosureHip,
655  typename ClosureDpcpp>
656  GKO_DEPRECATED(
657  "Please use the overload with std::string as first parameter.")
658  void run(const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
659  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp) const
660  {
661  LambdaOperation<ClosureOmp, ClosureOmp, ClosureCuda, ClosureHip,
662  ClosureDpcpp>
663  op(op_omp, op_cuda, op_hip, op_dpcpp);
664  this->run(op);
665  }
666 
683  template <typename ClosureReference, typename ClosureOmp,
684  typename ClosureCuda, typename ClosureHip, typename ClosureDpcpp>
685  void run(std::string name, const ClosureReference& op_ref,
686  const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
687  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp) const
688  {
689  LambdaOperation<ClosureReference, ClosureOmp, ClosureCuda, ClosureHip,
690  ClosureDpcpp>
691  op(std::move(name), op_ref, op_omp, op_cuda, op_hip, op_dpcpp);
692  this->run(op);
693  }
694 
706  template <typename T>
707  T* alloc(size_type num_elems) const
708  {
709  this->template log<log::Logger::allocation_started>(
710  this, num_elems * sizeof(T));
711  T* allocated = static_cast<T*>(this->raw_alloc(num_elems * sizeof(T)));
712  this->template log<log::Logger::allocation_completed>(
713  this, num_elems * sizeof(T), reinterpret_cast<uintptr>(allocated));
714  return allocated;
715  }
716 
724  void free(void* ptr) const noexcept
725  {
726  this->template log<log::Logger::free_started>(
727  this, reinterpret_cast<uintptr>(ptr));
728  this->raw_free(ptr);
729  this->template log<log::Logger::free_completed>(
730  this, reinterpret_cast<uintptr>(ptr));
731  }
732 
745  template <typename T>
747  const T* src_ptr, T* dest_ptr) const
748  {
749  const auto src_loc = reinterpret_cast<uintptr>(src_ptr);
750  const auto dest_loc = reinterpret_cast<uintptr>(dest_ptr);
751  this->template log<log::Logger::copy_started>(
752  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
753  if (this != src_exec.get()) {
754  src_exec->template log<log::Logger::copy_started>(
755  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
756  }
757  try {
758  this->raw_copy_from(src_exec.get(), num_elems * sizeof(T), src_ptr,
759  dest_ptr);
760  } catch (NotSupported&) {
761 #if (GKO_VERBOSE_LEVEL >= 1) && !defined(NDEBUG)
762  // Unoptimized copy. Try to go through the masters.
763  // output to log when verbose >= 1 and debug build
764  std::cerr << "Not direct copy. Try to copy data from the masters."
765  << std::endl;
766 #endif
767  auto src_master = src_exec->get_master().get();
768  if (num_elems > 0 && src_master != src_exec.get()) {
769  auto* master_ptr = src_exec->get_master()->alloc<T>(num_elems);
770  src_master->copy_from<T>(src_exec, num_elems, src_ptr,
771  master_ptr);
772  this->copy_from<T>(src_master, num_elems, master_ptr, dest_ptr);
773  src_master->free(master_ptr);
774  }
775  }
776  this->template log<log::Logger::copy_completed>(
777  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
778  if (this != src_exec.get()) {
779  src_exec->template log<log::Logger::copy_completed>(
780  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
781  }
782  }
783 
795  template <typename T>
796  void copy(size_type num_elems, const T* src_ptr, T* dest_ptr) const
797  {
798  this->copy_from(this, num_elems, src_ptr, dest_ptr);
799  }
800 
810  template <typename T>
811  T copy_val_to_host(const T* ptr) const
812  {
813  T out{};
814  this->get_master()->copy_from(this, 1, ptr, &out);
815  return out;
816  }
817 
822  virtual std::shared_ptr<Executor> get_master() noexcept = 0;
823 
827  virtual std::shared_ptr<const Executor> get_master() const noexcept = 0;
828 
832  virtual void synchronize() const = 0;
833 
840  void add_logger(std::shared_ptr<const log::Logger> logger) override
841  {
842  this->propagating_logger_refcount_.fetch_add(
843  logger->needs_propagation() ? 1 : 0);
844  this->EnableLogging<Executor>::add_logger(logger);
845  }
846 
853  void remove_logger(const log::Logger* logger) override
854  {
855  this->propagating_logger_refcount_.fetch_sub(
856  logger->needs_propagation() ? 1 : 0);
857  this->EnableLogging<Executor>::remove_logger(logger);
858  }
859 
860  using EnableLogging<Executor>::remove_logger;
861 
870  {
871  log_propagation_mode_ = mode;
872  }
873 
881  bool should_propagate_log() const
882  {
883  return this->propagating_logger_refcount_.load() > 0 &&
884  log_propagation_mode_ == log_propagation_mode::automatic;
885  }
886 
894  bool memory_accessible(const std::shared_ptr<const Executor>& other) const
895  {
896  return this->verify_memory_from(other.get());
897  }
898 
899  virtual scoped_device_id_guard get_scoped_device_id_guard() const = 0;
900 
902  virtual std::string get_description() const = 0;
903 
904 protected:
909  struct exec_info {
913  int device_id = -1;
914 
918  std::string device_type;
919 
928  int num_computing_units = -1;
929 
940  int num_pu_per_cu = -1;
941 
950  std::vector<int> subgroup_sizes{};
951 
960  int max_subgroup_size = -1;
961 
972  std::vector<int> max_workitem_sizes{};
973 
983  int max_workgroup_size = -1;
984 
988  int major = -1;
989 
993  int minor = -1;
994 
1000  std::string pci_bus_id = std::string(13, 'x');
1001  };
1002 
1008  const exec_info& get_exec_info() const { return this->exec_info_; }
1009 
1019  virtual void* raw_alloc(size_type size) const = 0;
1020 
1028  virtual void raw_free(void* ptr) const noexcept = 0;
1029 
1040  virtual void raw_copy_from(const Executor* src_exec, size_type n_bytes,
1041  const void* src_ptr, void* dest_ptr) const = 0;
1042 
1052 #define GKO_ENABLE_RAW_COPY_TO(_exec_type, ...) \
1053  virtual void raw_copy_to(const _exec_type* dest_exec, size_type n_bytes, \
1054  const void* src_ptr, void* dest_ptr) const = 0
1055 
1056  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_RAW_COPY_TO);
1057 
1058 #undef GKO_ENABLE_RAW_COPY_TO
1059 
1067  virtual bool verify_memory_from(const Executor* src_exec) const = 0;
1068 
1078 #define GKO_ENABLE_VERIFY_MEMORY_TO(_exec_type, ...) \
1079  virtual bool verify_memory_to(const _exec_type* dest_exec) const = 0
1080 
1081  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_VERIFY_MEMORY_TO);
1082 
1083  GKO_ENABLE_VERIFY_MEMORY_TO(ReferenceExecutor, ref);
1084 
1085 #undef GKO_ENABLE_VERIFY_MEMORY_TO
1086 
1093  virtual void populate_exec_info() = 0;
1094 
1100  exec_info& get_exec_info() { return this->exec_info_; }
1101 
1102  exec_info exec_info_;
1103 
1105 
1106  std::atomic<int> propagating_logger_refcount_{};
1107 
1108 private:
1123  template <typename ClosureReference, typename ClosureOmp,
1124  typename ClosureCuda, typename ClosureHip, typename ClosureDpcpp>
1125  class LambdaOperation : public Operation {
1126  public:
1127  LambdaOperation(std::string name, const ClosureReference& op_ref,
1128  const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
1129  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp)
1130  : name_(std::move(name)),
1131  op_ref_(op_ref),
1132  op_omp_(op_omp),
1133  op_cuda_(op_cuda),
1134  op_hip_(op_hip),
1135  op_dpcpp_(op_dpcpp)
1136  {}
1137 
1148  LambdaOperation(const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
1149  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp)
1150  : LambdaOperation("unnamed", op_omp, op_omp, op_cuda, op_hip,
1151  op_dpcpp)
1152  {}
1153 
1154  void run(std::shared_ptr<const OmpExecutor>) const override
1155  {
1156  op_omp_();
1157  }
1158 
1159  void run(std::shared_ptr<const ReferenceExecutor>) const override
1160  {
1161  op_ref_();
1162  }
1163 
1164  void run(std::shared_ptr<const CudaExecutor>) const override
1165  {
1166  op_cuda_();
1167  }
1168 
1169  void run(std::shared_ptr<const HipExecutor>) const override
1170  {
1171  op_hip_();
1172  }
1173 
1174  void run(std::shared_ptr<const DpcppExecutor>) const override
1175  {
1176  op_dpcpp_();
1177  }
1178 
1179  const char* get_name() const noexcept override { return name_.c_str(); }
1180 
1181  private:
1182  std::string name_;
1183  ClosureReference op_ref_;
1184  ClosureOmp op_omp_;
1185  ClosureCuda op_cuda_;
1186  ClosureHip op_hip_;
1187  ClosureDpcpp op_dpcpp_;
1188  };
1189 };
1190 
1191 
1200 template <typename T>
1202 public:
1203  using pointer = T*;
1204 
1210  explicit executor_deleter(std::shared_ptr<const Executor> exec)
1211  : exec_{exec}
1212  {}
1213 
1219  void operator()(pointer ptr) const
1220  {
1221  if (exec_) {
1222  exec_->free(ptr);
1223  }
1224  }
1225 
1226 private:
1227  std::shared_ptr<const Executor> exec_;
1228 };
1229 
1230 // a specialization for arrays
1231 template <typename T>
1232 class executor_deleter<T[]> {
1233 public:
1234  using pointer = T[];
1235 
1236  explicit executor_deleter(std::shared_ptr<const Executor> exec)
1237  : exec_{exec}
1238  {}
1239 
1240  void operator()(pointer ptr) const
1241  {
1242  if (exec_) {
1243  exec_->free(ptr);
1244  }
1245  }
1246 
1247 private:
1248  std::shared_ptr<const Executor> exec_;
1249 };
1250 
1251 
1252 namespace detail {
1253 
1254 
1255 template <typename ConcreteExecutor>
1256 class ExecutorBase : public Executor {
1257  // friend class is not in the nearest enclosing namesace, so we write the
1258  // full name
1259  friend class ::gko::OmpExecutor;
1260  friend class ::gko::HipExecutor;
1261  friend class ::gko::DpcppExecutor;
1262  friend class ::gko::CudaExecutor;
1263  friend class ::gko::ReferenceExecutor;
1264 
1265 public:
1266  void run(const Operation& op) const override
1267  {
1268  this->template log<log::Logger::operation_launched>(this, &op);
1269  auto scope_guard = get_scoped_device_id_guard();
1270  op.run(self()->shared_from_this());
1271  this->template log<log::Logger::operation_completed>(this, &op);
1272  }
1273 
1274 protected:
1275  void raw_copy_from(const Executor* src_exec, size_type n_bytes,
1276  const void* src_ptr, void* dest_ptr) const override
1277  {
1278  src_exec->raw_copy_to(self(), n_bytes, src_ptr, dest_ptr);
1279  }
1280 
1281  virtual bool verify_memory_from(const Executor* src_exec) const override
1282  {
1283  return src_exec->verify_memory_to(self());
1284  }
1285 
1286 private:
1287  ConcreteExecutor* self() noexcept
1288  {
1289  return static_cast<ConcreteExecutor*>(this);
1290  }
1291 
1292  const ConcreteExecutor* self() const noexcept
1293  {
1294  return static_cast<const ConcreteExecutor*>(this);
1295  }
1296 };
1297 
1298 #undef GKO_DECLARE_EXECUTOR_FRIEND
1299 
1300 
1308 class EnableDeviceReset {
1309 public:
1315  GKO_DEPRECATED(
1316  "device_reset is no longer supported, call "
1317  "cudaDeviceReset/hipDeviceReset manually")
1318  void set_device_reset(bool device_reset) {}
1319 
1325  GKO_DEPRECATED(
1326  "device_reset is no longer supported, call "
1327  "cudaDeviceReset/hipDeviceReset manually")
1328  bool get_device_reset() { return false; }
1329 
1330 protected:
1336  EnableDeviceReset() {}
1337 
1338  GKO_DEPRECATED(
1339  "device_reset is no longer supported, call "
1340  "cudaDeviceReset/hipDeviceReset manually")
1341  EnableDeviceReset(bool device_reset) {}
1342 };
1343 
1344 
1345 } // namespace detail
1346 
1347 
1348 #define GKO_OVERRIDE_RAW_COPY_TO(_executor_type, ...) \
1349  void raw_copy_to(const _executor_type* dest_exec, size_type n_bytes, \
1350  const void* src_ptr, void* dest_ptr) const override
1351 
1352 
1353 #define GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(dest_, bool_) \
1354  virtual bool verify_memory_to(const dest_* other) const override \
1355  { \
1356  return bool_; \
1357  } \
1358  static_assert(true, \
1359  "This assert is used to counter the false positive extra " \
1360  "semi-colon warnings")
1361 
1362 
1370 class OmpExecutor : public detail::ExecutorBase<OmpExecutor>,
1371  public std::enable_shared_from_this<OmpExecutor> {
1372  friend class detail::ExecutorBase<OmpExecutor>;
1373 
1374 public:
1375  using Executor::run;
1376 
1380  static std::shared_ptr<OmpExecutor> create(
1381  std::shared_ptr<CpuAllocatorBase> alloc =
1382  std::make_shared<CpuAllocator>())
1383  {
1384  return std::shared_ptr<OmpExecutor>(new OmpExecutor(std::move(alloc)));
1385  }
1386 
1387  std::shared_ptr<Executor> get_master() noexcept override;
1388 
1389  std::shared_ptr<const Executor> get_master() const noexcept override;
1390 
1391  void synchronize() const override;
1392 
1393  int get_num_cores() const
1394  {
1395  return this->get_exec_info().num_computing_units;
1396  }
1397 
1398  int get_num_threads_per_core() const
1399  {
1400  return this->get_exec_info().num_pu_per_cu;
1401  }
1402 
1403  static int get_num_omp_threads();
1404 
1405  scoped_device_id_guard get_scoped_device_id_guard() const override;
1406 
1407  std::string get_description() const override;
1408 
1409 protected:
1410  OmpExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1411  : alloc_{std::move(alloc)}
1412  {
1413  this->OmpExecutor::populate_exec_info();
1414  }
1415 
1416  void populate_exec_info() override;
1417 
1418  void* raw_alloc(size_type size) const override;
1419 
1420  void raw_free(void* ptr) const noexcept override;
1421 
1422  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1423 
1424  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, true);
1425 
1426  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1427 
1428  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
1429 
1430  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
1431 
1432  bool verify_memory_to(const DpcppExecutor* dest_exec) const override;
1433 
1434  std::shared_ptr<CpuAllocatorBase> alloc_;
1435 };
1436 
1437 
1438 namespace kernels {
1439 namespace omp {
1440 using DefaultExecutor = OmpExecutor;
1441 } // namespace omp
1442 } // namespace kernels
1443 
1444 
1453 public:
1454  using Executor::run;
1455 
1456  static std::shared_ptr<ReferenceExecutor> create(
1457  std::shared_ptr<CpuAllocatorBase> alloc =
1458  std::make_shared<CpuAllocator>())
1459  {
1460  return std::shared_ptr<ReferenceExecutor>(
1461  new ReferenceExecutor(std::move(alloc)));
1462  }
1463 
1464  scoped_device_id_guard get_scoped_device_id_guard() const override
1465  {
1466  return {this, 0};
1467  }
1468 
1469  std::string get_description() const override { return "ReferenceExecutor"; }
1470 
1471  void run(const Operation& op) const override
1472  {
1473  this->template log<log::Logger::operation_launched>(this, &op);
1474  op.run(std::static_pointer_cast<const ReferenceExecutor>(
1475  this->shared_from_this()));
1476  this->template log<log::Logger::operation_completed>(this, &op);
1477  }
1478 
1479 protected:
1480  ReferenceExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1481  : OmpExecutor{std::move(alloc)}
1482  {
1483  this->ReferenceExecutor::populate_exec_info();
1484  }
1485 
1486  void populate_exec_info() override
1487  {
1488  this->get_exec_info().device_id = -1;
1489  this->get_exec_info().num_computing_units = 1;
1490  this->get_exec_info().num_pu_per_cu = 1;
1491  }
1492 
1493  bool verify_memory_from(const Executor* src_exec) const override
1494  {
1495  return src_exec->verify_memory_to(this);
1496  }
1497 
1498  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, true);
1499 
1500  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1501 
1502  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1503 
1504  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
1505 
1506  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
1507 };
1508 
1509 
1510 namespace kernels {
1511 namespace reference {
1512 using DefaultExecutor = ReferenceExecutor;
1513 } // namespace reference
1514 } // namespace kernels
1515 
1516 
1523 class CudaExecutor : public detail::ExecutorBase<CudaExecutor>,
1524  public std::enable_shared_from_this<CudaExecutor>,
1525  public detail::EnableDeviceReset {
1526  friend class detail::ExecutorBase<CudaExecutor>;
1527 
1528 public:
1529  using Executor::run;
1530 
1542  GKO_DEPRECATED(
1543  "calling this CudaExecutor::create method is deprecated, because"
1544  "device_reset no longer has an effect"
1545  "call CudaExecutor::create("
1546  " int device_id, std::shared_ptr<Executor> master,"
1547  " std::shared_ptr<CudaAllocatorBase> alloc,"
1548  " CUstream_st* stream);"
1549  "instead")
1550  static std::shared_ptr<CudaExecutor> create(
1551  int device_id, std::shared_ptr<Executor> master, bool device_reset,
1552  allocation_mode alloc_mode = default_cuda_alloc_mode,
1553  CUstream_st* stream = nullptr);
1554 
1564  static std::shared_ptr<CudaExecutor> create(
1565  int device_id, std::shared_ptr<Executor> master,
1566  std::shared_ptr<CudaAllocatorBase> alloc =
1567  std::make_shared<CudaAllocator>(),
1568  CUstream_st* stream = nullptr);
1569 
1570  std::shared_ptr<Executor> get_master() noexcept override;
1571 
1572  std::shared_ptr<const Executor> get_master() const noexcept override;
1573 
1574  void synchronize() const override;
1575 
1576  scoped_device_id_guard get_scoped_device_id_guard() const override;
1577 
1578  std::string get_description() const override;
1579 
1583  int get_device_id() const noexcept
1584  {
1585  return this->get_exec_info().device_id;
1586  }
1587 
1591  static int get_num_devices();
1592 
1596  int get_num_warps_per_sm() const noexcept
1597  {
1598  return this->get_exec_info().num_pu_per_cu;
1599  }
1600 
1604  int get_num_multiprocessor() const noexcept
1605  {
1606  return this->get_exec_info().num_computing_units;
1607  }
1608 
1612  int get_num_warps() const noexcept
1613  {
1614  return this->get_exec_info().num_computing_units *
1615  this->get_exec_info().num_pu_per_cu;
1616  }
1617 
1621  int get_warp_size() const noexcept
1622  {
1623  return this->get_exec_info().max_subgroup_size;
1624  }
1625 
1629  int get_major_version() const noexcept
1630  {
1631  return this->get_exec_info().major;
1632  }
1633 
1637  int get_minor_version() const noexcept
1638  {
1639  return this->get_exec_info().minor;
1640  }
1641 
1645  int get_compute_capability() const noexcept
1646  {
1647  return this->get_major_version() * 10 + this->get_minor_version();
1648  }
1649 
1655  GKO_DEPRECATED("use get_blas_handle() instead")
1656  cublasContext* get_cublas_handle() const { return get_blas_handle(); }
1657 
1661  cublasContext* get_blas_handle() const { return cublas_handle_.get(); }
1662 
1668  GKO_DEPRECATED("use get_sparselib_handle() instead")
1669  cusparseContext* get_cusparse_handle() const
1670  {
1671  return get_sparselib_handle();
1672  }
1673 
1677  cusparseContext* get_sparselib_handle() const
1678  {
1679  return cusparse_handle_.get();
1680  }
1681 
1688  CUstream_st* get_stream() const { return stream_; }
1689 
1690 protected:
1691  void set_gpu_property();
1692 
1693  void init_handles();
1694 
1695  CudaExecutor(int device_id, std::shared_ptr<Executor> master,
1696  std::shared_ptr<CudaAllocatorBase> alloc, CUstream_st* stream)
1697  : master_(master), alloc_{std::move(alloc)}, stream_{stream}
1698  {
1699  this->get_exec_info().device_id = device_id;
1700  this->get_exec_info().num_computing_units = 0;
1701  this->get_exec_info().num_pu_per_cu = 0;
1702  this->CudaExecutor::populate_exec_info();
1703  this->set_gpu_property();
1704  this->init_handles();
1705  }
1706 
1707  void* raw_alloc(size_type size) const override;
1708 
1709  void raw_free(void* ptr) const noexcept override;
1710 
1711  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1712 
1713  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1714 
1715  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1716 
1717  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1718 
1719  bool verify_memory_to(const HipExecutor* dest_exec) const override;
1720 
1721  bool verify_memory_to(const CudaExecutor* dest_exec) const override;
1722 
1723  void populate_exec_info() override;
1724 
1725 private:
1726  std::shared_ptr<Executor> master_;
1727 
1728  template <typename T>
1729  using handle_manager = std::unique_ptr<T, std::function<void(T*)>>;
1730  handle_manager<cublasContext> cublas_handle_;
1731  handle_manager<cusparseContext> cusparse_handle_;
1732  std::shared_ptr<CudaAllocatorBase> alloc_;
1733  CUstream_st* stream_;
1734 };
1735 
1736 
1737 namespace kernels {
1738 namespace cuda {
1739 using DefaultExecutor = CudaExecutor;
1740 } // namespace cuda
1741 } // namespace kernels
1742 
1743 
1750 class HipExecutor : public detail::ExecutorBase<HipExecutor>,
1751  public std::enable_shared_from_this<HipExecutor>,
1752  public detail::EnableDeviceReset {
1753  friend class detail::ExecutorBase<HipExecutor>;
1754 
1755 public:
1756  using Executor::run;
1757 
1770  GKO_DEPRECATED(
1771  "device_reset is deprecated entirely, call hipDeviceReset directly. "
1772  "alloc_mode was replaced by the Allocator type "
1773  "hierarchy.")
1774  static std::shared_ptr<HipExecutor> create(
1775  int device_id, std::shared_ptr<Executor> master, bool device_reset,
1776  allocation_mode alloc_mode = default_hip_alloc_mode,
1777  GKO_HIP_STREAM_STRUCT* stream = nullptr);
1778 
1779  static std::shared_ptr<HipExecutor> create(
1780  int device_id, std::shared_ptr<Executor> master,
1781  std::shared_ptr<HipAllocatorBase> alloc =
1782  std::make_shared<HipAllocator>(),
1783  GKO_HIP_STREAM_STRUCT* stream = nullptr);
1784 
1785  std::shared_ptr<Executor> get_master() noexcept override;
1786 
1787  std::shared_ptr<const Executor> get_master() const noexcept override;
1788 
1789  void synchronize() const override;
1790 
1791  scoped_device_id_guard get_scoped_device_id_guard() const override;
1792 
1793  std::string get_description() const override;
1794 
1798  int get_device_id() const noexcept
1799  {
1800  return this->get_exec_info().device_id;
1801  }
1802 
1806  static int get_num_devices();
1807 
1811  int get_num_warps_per_sm() const noexcept
1812  {
1813  return this->get_exec_info().num_pu_per_cu;
1814  }
1815 
1819  int get_num_multiprocessor() const noexcept
1820  {
1821  return this->get_exec_info().num_computing_units;
1822  }
1823 
1827  int get_major_version() const noexcept
1828  {
1829  return this->get_exec_info().major;
1830  }
1831 
1835  int get_minor_version() const noexcept
1836  {
1837  return this->get_exec_info().minor;
1838  }
1839 
1843  int get_num_warps() const noexcept
1844  {
1845  return this->get_exec_info().num_computing_units *
1846  this->get_exec_info().num_pu_per_cu;
1847  }
1848 
1852  int get_warp_size() const noexcept
1853  {
1854  return this->get_exec_info().max_subgroup_size;
1855  }
1856 
1862  GKO_DEPRECATED("use get_blas_handle() instead")
1863  hipblasContext* get_hipblas_handle() const { return get_blas_handle(); }
1864 
1868  hipblasContext* get_blas_handle() const { return hipblas_handle_.get(); }
1869 
1875  GKO_DEPRECATED("use get_sparselib_handle() instead")
1876  hipsparseContext* get_hipsparse_handle() const
1877  {
1878  return get_sparselib_handle();
1879  }
1880 
1884  hipsparseContext* get_sparselib_handle() const
1885  {
1886  return hipsparse_handle_.get();
1887  }
1888 
1889  GKO_HIP_STREAM_STRUCT* get_stream() const { return stream_; }
1890 
1891 protected:
1892  void set_gpu_property();
1893 
1894  void init_handles();
1895 
1896  HipExecutor(int device_id, std::shared_ptr<Executor> master,
1897  std::shared_ptr<HipAllocatorBase> alloc,
1898  GKO_HIP_STREAM_STRUCT* stream)
1899  : master_{std::move(master)}, alloc_{std::move(alloc)}, stream_{stream}
1900  {
1901  this->get_exec_info().device_id = device_id;
1902  this->get_exec_info().num_computing_units = 0;
1903  this->get_exec_info().num_pu_per_cu = 0;
1904  this->HipExecutor::populate_exec_info();
1905  this->set_gpu_property();
1906  this->init_handles();
1907  }
1908 
1909  void* raw_alloc(size_type size) const override;
1910 
1911  void raw_free(void* ptr) const noexcept override;
1912 
1913  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1914 
1915  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1916 
1917  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1918 
1919  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1920 
1921  bool verify_memory_to(const CudaExecutor* dest_exec) const override;
1922 
1923  bool verify_memory_to(const HipExecutor* dest_exec) const override;
1924 
1925  void populate_exec_info() override;
1926 
1927 private:
1928  std::shared_ptr<Executor> master_;
1929 
1930  template <typename T>
1931  using handle_manager = std::unique_ptr<T, std::function<void(T*)>>;
1932  handle_manager<hipblasContext> hipblas_handle_;
1933  handle_manager<hipsparseContext> hipsparse_handle_;
1934  std::shared_ptr<HipAllocatorBase> alloc_;
1935  GKO_HIP_STREAM_STRUCT* stream_;
1936 };
1937 
1938 
1939 namespace kernels {
1940 namespace hip {
1941 using DefaultExecutor = HipExecutor;
1942 } // namespace hip
1943 } // namespace kernels
1944 
1945 
1952 class DpcppExecutor : public detail::ExecutorBase<DpcppExecutor>,
1953  public std::enable_shared_from_this<DpcppExecutor> {
1954  friend class detail::ExecutorBase<DpcppExecutor>;
1955 
1956 public:
1957  using Executor::run;
1958 
1971  static std::shared_ptr<DpcppExecutor> create(
1972  int device_id, std::shared_ptr<Executor> master,
1973  std::string device_type = "all",
1974  dpcpp_queue_property property = dpcpp_queue_property::in_order);
1975 
1976  std::shared_ptr<Executor> get_master() noexcept override;
1977 
1978  std::shared_ptr<const Executor> get_master() const noexcept override;
1979 
1980  void synchronize() const override;
1981 
1982  scoped_device_id_guard get_scoped_device_id_guard() const override;
1983 
1984  std::string get_description() const override;
1985 
1991  int get_device_id() const noexcept
1992  {
1993  return this->get_exec_info().device_id;
1994  }
1995 
1996  sycl::queue* get_queue() const { return queue_.get(); }
1997 
2005  static int get_num_devices(std::string device_type);
2006 
2012  const std::vector<int>& get_subgroup_sizes() const noexcept
2013  {
2014  return this->get_exec_info().subgroup_sizes;
2015  }
2016 
2022  int get_num_computing_units() const noexcept
2023  {
2024  return this->get_exec_info().num_computing_units;
2025  }
2026 
2030  int get_num_subgroups() const noexcept
2031  {
2032  return this->get_exec_info().num_computing_units *
2033  this->get_exec_info().num_pu_per_cu;
2034  }
2035 
2041  const std::vector<int>& get_max_workitem_sizes() const noexcept
2042  {
2043  return this->get_exec_info().max_workitem_sizes;
2044  }
2045 
2051  int get_max_workgroup_size() const noexcept
2052  {
2053  return this->get_exec_info().max_workgroup_size;
2054  }
2055 
2061  int get_max_subgroup_size() const noexcept
2062  {
2063  return this->get_exec_info().max_subgroup_size;
2064  }
2065 
2071  std::string get_device_type() const noexcept
2072  {
2073  return this->get_exec_info().device_type;
2074  }
2075 
2076 protected:
2077  void set_device_property(
2078  dpcpp_queue_property property = dpcpp_queue_property::in_order);
2079 
2080  DpcppExecutor(
2081  int device_id, std::shared_ptr<Executor> master,
2082  std::string device_type = "all",
2083  dpcpp_queue_property property = dpcpp_queue_property::in_order)
2084  : master_(master)
2085  {
2086  std::for_each(device_type.begin(), device_type.end(),
2087  [](char& c) { c = std::tolower(c); });
2088  this->get_exec_info().device_type = std::string(device_type);
2089  this->get_exec_info().device_id = device_id;
2090  this->set_device_property(property);
2091  }
2092 
2093  void populate_exec_info() override;
2094 
2095  void* raw_alloc(size_type size) const override;
2096 
2097  void raw_free(void* ptr) const noexcept override;
2098 
2099  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
2100 
2101  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
2102 
2103  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
2104 
2105  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
2106 
2107  bool verify_memory_to(const OmpExecutor* dest_exec) const override;
2108 
2109  bool verify_memory_to(const DpcppExecutor* dest_exec) const override;
2110 
2111 private:
2112  std::shared_ptr<Executor> master_;
2113 
2114  template <typename T>
2115  using queue_manager = std::unique_ptr<T, std::function<void(T*)>>;
2116  queue_manager<sycl::queue> queue_;
2117 };
2118 
2119 
2120 namespace kernels {
2121 namespace dpcpp {
2122 using DefaultExecutor = DpcppExecutor;
2123 } // namespace dpcpp
2124 } // namespace kernels
2125 
2126 
2127 #undef GKO_OVERRIDE_RAW_COPY_TO
2128 
2129 
2130 } // namespace gko
2131 
2132 
2133 #endif // GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_
gko::allocation_mode
allocation_mode
Specify the mode of allocation for CUDA/HIP GPUs.
Definition: executor.hpp:61
gko::CudaExecutor::get_sparselib_handle
cusparseContext * get_sparselib_handle() const
Get the cusparse handle for this executor.
Definition: executor.hpp:1677
gko::CudaExecutor::get_num_warps_per_sm
int get_num_warps_per_sm() const noexcept
Get the number of warps per SM of this executor.
Definition: executor.hpp:1596
gko::executor_deleter
This is a deleter that uses an executor's free method to deallocate the data.
Definition: executor.hpp:1201
gko::HipExecutor::get_num_warps_per_sm
int get_num_warps_per_sm() const noexcept
Get the number of warps per SM of this executor.
Definition: executor.hpp:1811
gko::executor_deleter::executor_deleter
executor_deleter(std::shared_ptr< const Executor > exec)
Creates a new deleter.
Definition: executor.hpp:1210
gko::CudaExecutor::get_stream
CUstream_st * get_stream() const
Returns the CUDA stream used by this executor.
Definition: executor.hpp:1688
gko::Executor::synchronize
virtual void synchronize() const =0
Synchronize the operations launched on the executor with its master.
gko::DpcppExecutor::get_max_workitem_sizes
const std::vector< int > & get_max_workitem_sizes() const noexcept
Get the maximum work item sizes.
Definition: executor.hpp:2041
gko::Executor::free
void free(void *ptr) const noexcept
Frees memory previously allocated with Executor::alloc().
Definition: executor.hpp:724
gko::HipExecutor::get_hipblas_handle
hipblasContext * get_hipblas_handle() const
Get the hipblas handle for this executor.
Definition: executor.hpp:1863
gko::Executor::memory_accessible
bool memory_accessible(const std::shared_ptr< const Executor > &other) const
Verifies whether the executors share the same memory.
Definition: executor.hpp:894
gko::DpcppExecutor::get_device_type
std::string get_device_type() const noexcept
Get a string representing the device type.
Definition: executor.hpp:2071
gko::HipExecutor::get_num_devices
static int get_num_devices()
Get the number of devices present on the system.
gko::scoped_device_id_guard
This move-only class uses RAII to set the device id within a scoped block, if necessary.
Definition: scoped_device_id_guard.hpp:76
gko::DpcppExecutor::get_num_devices
static int get_num_devices(std::string device_type)
Get the number of devices present on the system.
gko::DpcppExecutor::get_num_computing_units
int get_num_computing_units() const noexcept
Get the number of Computing Units of this executor.
Definition: executor.hpp:2022
gko::log_propagation_mode::automatic
Events get reported to loggers attached to the triggering object and propagating loggers (Logger::nee...
gko::Executor::remove_logger
void remove_logger(const log::Logger *logger) override
Definition: executor.hpp:853
gko::DpcppExecutor::get_num_subgroups
int get_num_subgroups() const noexcept
Get the number of subgroups of this executor.
Definition: executor.hpp:2030
gko::ReferenceExecutor::get_description
std::string get_description() const override
Definition: executor.hpp:1469
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:101
gko::Executor::copy_from
void copy_from(ptr_param< const Executor > src_exec, size_type num_elems, const T *src_ptr, T *dest_ptr) const
Copies data from another Executor.
Definition: executor.hpp:746
gko::DpcppExecutor::get_description
std::string get_description() const override
gko::Executor::get_master
virtual std::shared_ptr< Executor > get_master() noexcept=0
Returns the master OmpExecutor of this Executor.
gko::ptr_param::get
T * get() const
Definition: utils_helper.hpp:77
gko::Executor::run
virtual void run(const Operation &op) const =0
Runs the specified Operation using this Executor.
gko::HipExecutor
This is the Executor subclass which represents the HIP enhanced device.
Definition: executor.hpp:1750
gko::CudaExecutor::get_minor_version
int get_minor_version() const noexcept
Get the minor version of compute capability.
Definition: executor.hpp:1637
gko::DpcppExecutor::get_master
std::shared_ptr< Executor > get_master() noexcept override
Returns the master OmpExecutor of this Executor.
gko::log_propagation_mode::never
Events only get reported at loggers attached to the triggering object.
gko::CudaExecutor::get_num_multiprocessor
int get_num_multiprocessor() const noexcept
Get the number of multiprocessor of this executor.
Definition: executor.hpp:1604
gko::ReferenceExecutor
This is a specialization of the OmpExecutor, which runs the reference implementations of the kernels ...
Definition: executor.hpp:1452
gko::CudaExecutor::get_warp_size
int get_warp_size() const noexcept
Get the warp size of this executor.
Definition: executor.hpp:1621
gko::NotSupported
NotSupported is thrown in case it is not possible to perform the requested operation on the given obj...
Definition: exception.hpp:119
gko::HipExecutor::get_device_id
int get_device_id() const noexcept
Get the HIP device id of the device associated to this executor.
Definition: executor.hpp:1798
gko::HipExecutor::get_hipsparse_handle
hipsparseContext * get_hipsparse_handle() const
Get the hipsparse handle for this executor.
Definition: executor.hpp:1876
gko::CudaExecutor
This is the Executor subclass which represents the CUDA device.
Definition: executor.hpp:1523
gko::log_propagation_mode
log_propagation_mode
How Logger events are propagated to their Executor.
Definition: executor.hpp:33
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:19
gko::Executor::add_logger
void add_logger(std::shared_ptr< const log::Logger > logger) override
Definition: executor.hpp:840
gko::HipExecutor::get_master
std::shared_ptr< Executor > get_master() noexcept override
Returns the master OmpExecutor of this Executor.
gko::CudaExecutor::get_blas_handle
cublasContext * get_blas_handle() const
Get the cublas handle for this executor.
Definition: executor.hpp:1661
gko::executor_deleter::operator()
void operator()(pointer ptr) const
Deletes the object.
Definition: executor.hpp:1219
gko::DpcppExecutor::get_max_subgroup_size
int get_max_subgroup_size() const noexcept
Get the maximum subgroup size.
Definition: executor.hpp:2061
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:790
gko::Operation::get_name
virtual const char * get_name() const noexcept
Returns the operation's name.
gko::DpcppExecutor::synchronize
void synchronize() const override
Synchronize the operations launched on the executor with its master.
gko::DpcppExecutor
This is the Executor subclass which represents a DPC++ enhanced device.
Definition: executor.hpp:1952
gko::ptr_param
This class is used for function parameters in the place of raw pointers.
Definition: utils_helper.hpp:43
gko::log::Logger
Definition: logger.hpp:76
gko::Executor::copy_val_to_host
T copy_val_to_host(const T *ptr) const
Retrieves a single element at the given location from executor memory.
Definition: executor.hpp:811
gko::OmpExecutor
This is the Executor subclass which represents the OpenMP device (typically CPU).
Definition: executor.hpp:1370
gko::HipExecutor::get_sparselib_handle
hipsparseContext * get_sparselib_handle() const
Get the hipsparse handle for this executor.
Definition: executor.hpp:1884
gko::Executor::get_description
virtual std::string get_description() const =0
gko::stop::mode
mode
The mode for the residual norm criterion.
Definition: residual_norm.hpp:37
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:1380
gko::HipExecutor::get_description
std::string get_description() const override
gko::Executor::alloc
T * alloc(size_type num_elems) const
Allocates memory in this Executor.
Definition: executor.hpp:707
gko::ReferenceExecutor::run
void run(const Operation &op) const override
Runs the specified Operation using this Executor.
Definition: executor.hpp:1471
gko::Executor::copy
void copy(size_type num_elems, const T *src_ptr, T *dest_ptr) const
Copies data within this Executor.
Definition: executor.hpp:796
gko::HipExecutor::get_num_multiprocessor
int get_num_multiprocessor() const noexcept
Get the number of multiprocessor of this executor.
Definition: executor.hpp:1819
gko::Executor::should_propagate_log
bool should_propagate_log() const
Returns true iff events occurring at an object created on this executor should be logged at propagati...
Definition: executor.hpp:881
gko::DpcppExecutor::get_device_id
int get_device_id() const noexcept
Get the DPCPP device id of the device associated to this executor.
Definition: executor.hpp:1991
gko::DpcppExecutor::get_max_workgroup_size
int get_max_workgroup_size() const noexcept
Get the maximum workgroup size.
Definition: executor.hpp:2051
gko::CudaExecutor::get_major_version
int get_major_version() const noexcept
Get the major version of compute capability.
Definition: executor.hpp:1629
gko::CudaExecutor::get_num_warps
int get_num_warps() const noexcept
Get the number of warps of this executor.
Definition: executor.hpp:1612
gko::log::Logger::needs_propagation
virtual bool needs_propagation() const
Returns true if this logger, when attached to an Executor, needs to be forwarded all events from obje...
Definition: logger.hpp:684
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:617
gko::HipExecutor::get_blas_handle
hipblasContext * get_blas_handle() const
Get the hipblas handle for this executor.
Definition: executor.hpp:1868
gko::HipExecutor::get_num_warps
int get_num_warps() const noexcept
Get the number of warps of this executor.
Definition: executor.hpp:1843
gko::CudaExecutor::get_compute_capability
int get_compute_capability() const noexcept
Get the compute capability.
Definition: executor.hpp:1645
gko::HipExecutor::get_major_version
int get_major_version() const noexcept
Get the major version of compute capability.
Definition: executor.hpp:1827
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.
gko::HipExecutor::synchronize
void synchronize() const override
Synchronize the operations launched on the executor with its master.
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:257
gko::Executor::set_log_propagation_mode
void set_log_propagation_mode(log_propagation_mode mode)
Sets the logger event propagation mode for the executor.
Definition: executor.hpp:869
gko::DpcppExecutor::get_subgroup_sizes
const std::vector< int > & get_subgroup_sizes() const noexcept
Get the available subgroup sizes for this device.
Definition: executor.hpp:2012
gko::HipExecutor::get_warp_size
int get_warp_size() const noexcept
Get the warp size of this executor.
Definition: executor.hpp:1852
gko::HipExecutor::get_minor_version
int get_minor_version() const noexcept
Get the minor version of compute capability.
Definition: executor.hpp:1835
gko::CudaExecutor::get_device_id
int get_device_id() const noexcept
Get the CUDA device id of the device associated to this executor.
Definition: executor.hpp:1583
gko::Executor::run
void run(std::string name, const ClosureReference &op_ref, const ClosureOmp &op_omp, const ClosureCuda &op_cuda, const ClosureHip &op_hip, const ClosureDpcpp &op_dpcpp) const
Runs one of the passed in functors, depending on the Executor type.
Definition: executor.hpp:685