Ginkgo  Generated from pipelines/2779843039 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 #define GKO_DECLARE_RUN_OVERLOAD(_type, ...) \
260  virtual void run(std::shared_ptr<const _type>) const
261 
262  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_RUN_OVERLOAD);
263 
264 #undef GKO_DECLARE_RUN_OVERLOAD
265 
266  // ReferenceExecutor overload can be defaulted to OmpExecutor's
267  virtual void run(std::shared_ptr<const ReferenceExecutor> executor) const;
268 
274  virtual const char* get_name() const noexcept;
275 };
276 
277 
278 namespace detail {
279 
280 
290 template <typename Closure>
291 class RegisteredOperation : public Operation {
292 public:
299  RegisteredOperation(const char* name, Closure op)
300  : name_(name), op_(std::move(op))
301  {}
302 
303  const char* get_name() const noexcept override { return name_; }
304 
305  void run(std::shared_ptr<const ReferenceExecutor> exec) const override
306  {
307  op_(exec);
308  }
309 
310  void run(std::shared_ptr<const OmpExecutor> exec) const override
311  {
312  op_(exec);
313  }
314 
315  void run(std::shared_ptr<const CudaExecutor> exec) const override
316  {
317  op_(exec);
318  }
319 
320  void run(std::shared_ptr<const HipExecutor> exec) const override
321  {
322  op_(exec);
323  }
324 
325  void run(std::shared_ptr<const DpcppExecutor> exec) const override
326  {
327  op_(exec);
328  }
329 
330 private:
331  const char* name_;
332  Closure op_;
333 };
334 
335 
336 template <typename Closure>
337 RegisteredOperation<Closure> make_register_operation(const char* name,
338  Closure op)
339 {
340  return RegisteredOperation<Closure>{name, std::move(op)};
341 }
342 
343 
344 } // namespace detail
345 
346 
418 #define GKO_REGISTER_OPERATION(_name, _kernel) \
419  template <typename... Args> \
420  auto make_##_name(Args&&... args) \
421  { \
422  return ::gko::detail::make_register_operation( \
423  #_kernel, [&args...](auto exec) { \
424  using exec_type = decltype(exec); \
425  if constexpr (std::is_same< \
426  exec_type, \
427  std::shared_ptr< \
428  const ::gko::ReferenceExecutor>>:: \
429  value) { \
430  ::gko::kernels::reference::_kernel( \
431  std::dynamic_pointer_cast< \
432  const ::gko::ReferenceExecutor>(exec), \
433  std::forward<Args>(args)...); \
434  } else if constexpr ( \
435  std::is_same< \
436  exec_type, \
437  std::shared_ptr<const ::gko::OmpExecutor>>::value) { \
438  ::gko::kernels::omp::_kernel( \
439  std::dynamic_pointer_cast<const ::gko::OmpExecutor>( \
440  exec), \
441  std::forward<Args>(args)...); \
442  } else if constexpr ( \
443  std::is_same< \
444  exec_type, \
445  std::shared_ptr<const ::gko::CudaExecutor>>::value) { \
446  ::gko::kernels::cuda::_kernel( \
447  std::dynamic_pointer_cast<const ::gko::CudaExecutor>( \
448  exec), \
449  std::forward<Args>(args)...); \
450  } else if constexpr ( \
451  std::is_same< \
452  exec_type, \
453  std::shared_ptr<const ::gko::HipExecutor>>::value) { \
454  ::gko::kernels::hip::_kernel( \
455  std::dynamic_pointer_cast<const ::gko::HipExecutor>( \
456  exec), \
457  std::forward<Args>(args)...); \
458  } else if constexpr ( \
459  std::is_same< \
460  exec_type, \
461  std::shared_ptr<const ::gko::DpcppExecutor>>::value) { \
462  ::gko::kernels::dpcpp::_kernel( \
463  std::dynamic_pointer_cast<const ::gko::DpcppExecutor>( \
464  exec), \
465  std::forward<Args>(args)...); \
466  } else { \
467  GKO_NOT_IMPLEMENTED; \
468  } \
469  }); \
470  } \
471  static_assert(true, \
472  "This assert is used to counter the false positive extra " \
473  "semi-colon warnings")
474 
475 
513 #define GKO_REGISTER_HOST_OPERATION(_name, _kernel) \
514  template <typename... Args> \
515  auto make_##_name(Args&&... args) \
516  { \
517  return ::gko::detail::make_register_operation( \
518  #_kernel, \
519  [&args...](auto) { _kernel(std::forward<Args>(args)...); }); \
520  } \
521  static_assert(true, \
522  "This assert is used to counter the false positive extra " \
523  "semi-colon warnings")
524 
525 
526 #define GKO_DECLARE_EXECUTOR_FRIEND(_type, ...) friend class _type
527 
615 class Executor : public log::EnableLogging<Executor> {
616  template <typename T>
617  friend class detail::ExecutorBase;
618 
619  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_EXECUTOR_FRIEND);
620  friend class ReferenceExecutor;
621 
622 public:
623  virtual ~Executor() = default;
624 
625  Executor() = default;
626  Executor(Executor&) = delete;
627  Executor(Executor&&) = delete;
628  Executor& operator=(Executor&) = delete;
629  Executor& operator=(Executor&&) = delete;
630 
636  virtual void run(const Operation& op) const = 0;
637 
652  template <typename ClosureOmp, typename ClosureCuda, typename ClosureHip,
653  typename ClosureDpcpp>
654  GKO_DEPRECATED(
655  "Please use the overload with std::string as first parameter.")
656  void run(const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
657  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp) const
658  {
659  LambdaOperation<ClosureOmp, ClosureOmp, ClosureCuda, ClosureHip,
660  ClosureDpcpp>
661  op(op_omp, op_cuda, op_hip, op_dpcpp);
662  this->run(op);
663  }
664 
681  template <typename ClosureReference, typename ClosureOmp,
682  typename ClosureCuda, typename ClosureHip, typename ClosureDpcpp>
683  void run(std::string name, const ClosureReference& op_ref,
684  const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
685  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp) const
686  {
687  LambdaOperation<ClosureReference, ClosureOmp, ClosureCuda, ClosureHip,
688  ClosureDpcpp>
689  op(std::move(name), op_ref, op_omp, op_cuda, op_hip, op_dpcpp);
690  this->run(op);
691  }
692 
704  template <typename T>
705  T* alloc(size_type num_elems) const
706  {
707  this->template log<log::Logger::allocation_started>(
708  this, num_elems * sizeof(T));
709  T* allocated = static_cast<T*>(this->raw_alloc(num_elems * sizeof(T)));
710  this->template log<log::Logger::allocation_completed>(
711  this, num_elems * sizeof(T), reinterpret_cast<uintptr>(allocated));
712  return allocated;
713  }
714 
722  void free(void* ptr) const noexcept
723  {
724  this->template log<log::Logger::free_started>(
725  this, reinterpret_cast<uintptr>(ptr));
726  this->raw_free(ptr);
727  this->template log<log::Logger::free_completed>(
728  this, reinterpret_cast<uintptr>(ptr));
729  }
730 
743  template <typename T>
745  const T* src_ptr, T* dest_ptr) const
746  {
747  const auto src_loc = reinterpret_cast<uintptr>(src_ptr);
748  const auto dest_loc = reinterpret_cast<uintptr>(dest_ptr);
749  this->template log<log::Logger::copy_started>(
750  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
751  if (this != src_exec.get()) {
752  src_exec->template log<log::Logger::copy_started>(
753  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
754  }
755  try {
756  this->raw_copy_from(src_exec.get(), num_elems * sizeof(T), src_ptr,
757  dest_ptr);
758  } catch (NotSupported&) {
759 #if (GKO_VERBOSE_LEVEL >= 1) && !defined(NDEBUG)
760  // Unoptimized copy. Try to go through the masters.
761  // output to log when verbose >= 1 and debug build
762  std::cerr << "Not direct copy. Try to copy data from the masters."
763  << std::endl;
764 #endif
765  auto src_master = src_exec->get_master().get();
766  if (num_elems > 0 && src_master != src_exec.get()) {
767  auto* master_ptr = src_exec->get_master()->alloc<T>(num_elems);
768  src_master->copy_from<T>(src_exec, num_elems, src_ptr,
769  master_ptr);
770  this->copy_from<T>(src_master, num_elems, master_ptr, dest_ptr);
771  src_master->free(master_ptr);
772  }
773  }
774  this->template log<log::Logger::copy_completed>(
775  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
776  if (this != src_exec.get()) {
777  src_exec->template log<log::Logger::copy_completed>(
778  src_exec.get(), this, src_loc, dest_loc, num_elems * sizeof(T));
779  }
780  }
781 
793  template <typename T>
794  void copy(size_type num_elems, const T* src_ptr, T* dest_ptr) const
795  {
796  this->copy_from(this, num_elems, src_ptr, dest_ptr);
797  }
798 
808  template <typename T>
809  T copy_val_to_host(const T* ptr) const
810  {
811  T out{};
812  this->get_master()->copy_from(this, 1, ptr, &out);
813  return out;
814  }
815 
820  virtual std::shared_ptr<Executor> get_master() noexcept = 0;
821 
825  virtual std::shared_ptr<const Executor> get_master() const noexcept = 0;
826 
830  virtual void synchronize() const = 0;
831 
838  void add_logger(std::shared_ptr<const log::Logger> logger) override
839  {
840  this->propagating_logger_refcount_.fetch_add(
841  logger->needs_propagation() ? 1 : 0);
842  this->EnableLogging<Executor>::add_logger(logger);
843  }
844 
851  void remove_logger(const log::Logger* logger) override
852  {
853  this->propagating_logger_refcount_.fetch_sub(
854  logger->needs_propagation() ? 1 : 0);
855  this->EnableLogging<Executor>::remove_logger(logger);
856  }
857 
858  using EnableLogging<Executor>::remove_logger;
859 
868  {
869  log_propagation_mode_ = mode;
870  }
871 
879  bool should_propagate_log() const
880  {
881  return this->propagating_logger_refcount_.load() > 0 &&
882  log_propagation_mode_ == log_propagation_mode::automatic;
883  }
884 
892  bool memory_accessible(const std::shared_ptr<const Executor>& other) const
893  {
894  return this->verify_memory_from(other.get());
895  }
896 
897  virtual scoped_device_id_guard get_scoped_device_id_guard() const = 0;
898 
900  virtual std::string get_description() const = 0;
901 
902 protected:
907  struct exec_info {
911  int device_id = -1;
912 
916  std::string device_type;
917 
926  int num_computing_units = -1;
927 
938  int num_pu_per_cu = -1;
939 
948  std::vector<int> subgroup_sizes{};
949 
958  int max_subgroup_size = -1;
959 
970  std::vector<int> max_workitem_sizes{};
971 
981  int max_workgroup_size;
982 
986  int major = -1;
987 
991  int minor = -1;
992 
998  std::string pci_bus_id = std::string(13, 'x');
999  };
1000 
1006  const exec_info& get_exec_info() const { return this->exec_info_; }
1007 
1017  virtual void* raw_alloc(size_type size) const = 0;
1018 
1026  virtual void raw_free(void* ptr) const noexcept = 0;
1027 
1038  virtual void raw_copy_from(const Executor* src_exec, size_type n_bytes,
1039  const void* src_ptr, void* dest_ptr) const = 0;
1040 
1050 #define GKO_ENABLE_RAW_COPY_TO(_exec_type, ...) \
1051  virtual void raw_copy_to(const _exec_type* dest_exec, size_type n_bytes, \
1052  const void* src_ptr, void* dest_ptr) const = 0
1053 
1054  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_RAW_COPY_TO);
1055 
1056 #undef GKO_ENABLE_RAW_COPY_TO
1057 
1065  virtual bool verify_memory_from(const Executor* src_exec) const = 0;
1066 
1076 #define GKO_ENABLE_VERIFY_MEMORY_TO(_exec_type, ...) \
1077  virtual bool verify_memory_to(const _exec_type* dest_exec) const = 0
1078 
1079  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_VERIFY_MEMORY_TO);
1080 
1081  GKO_ENABLE_VERIFY_MEMORY_TO(ReferenceExecutor, ref);
1082 
1083 #undef GKO_ENABLE_VERIFY_MEMORY_TO
1084 
1091  virtual void populate_exec_info() = 0;
1092 
1098  exec_info& get_exec_info() { return this->exec_info_; }
1099 
1100  exec_info exec_info_;
1101 
1103 
1104  std::atomic<int> propagating_logger_refcount_{};
1105 
1106 private:
1121  template <typename ClosureReference, typename ClosureOmp,
1122  typename ClosureCuda, typename ClosureHip, typename ClosureDpcpp>
1123  class LambdaOperation : public Operation {
1124  public:
1125  LambdaOperation(std::string name, const ClosureReference& op_ref,
1126  const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
1127  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp)
1128  : name_(std::move(name)),
1129  op_ref_(op_ref),
1130  op_omp_(op_omp),
1131  op_cuda_(op_cuda),
1132  op_hip_(op_hip),
1133  op_dpcpp_(op_dpcpp)
1134  {}
1135 
1146  LambdaOperation(const ClosureOmp& op_omp, const ClosureCuda& op_cuda,
1147  const ClosureHip& op_hip, const ClosureDpcpp& op_dpcpp)
1148  : LambdaOperation("unnamed", op_omp, op_omp, op_cuda, op_hip,
1149  op_dpcpp)
1150  {}
1151 
1152  void run(std::shared_ptr<const OmpExecutor>) const override
1153  {
1154  op_omp_();
1155  }
1156 
1157  void run(std::shared_ptr<const ReferenceExecutor>) const override
1158  {
1159  op_ref_();
1160  }
1161 
1162  void run(std::shared_ptr<const CudaExecutor>) const override
1163  {
1164  op_cuda_();
1165  }
1166 
1167  void run(std::shared_ptr<const HipExecutor>) const override
1168  {
1169  op_hip_();
1170  }
1171 
1172  void run(std::shared_ptr<const DpcppExecutor>) const override
1173  {
1174  op_dpcpp_();
1175  }
1176 
1177  const char* get_name() const noexcept override { return name_.c_str(); }
1178 
1179  private:
1180  std::string name_;
1181  ClosureReference op_ref_;
1182  ClosureOmp op_omp_;
1183  ClosureCuda op_cuda_;
1184  ClosureHip op_hip_;
1185  ClosureDpcpp op_dpcpp_;
1186  };
1187 };
1188 
1189 
1198 template <typename T>
1200 public:
1201  using pointer = T*;
1202 
1208  explicit executor_deleter(std::shared_ptr<const Executor> exec)
1209  : exec_{exec}
1210  {}
1211 
1217  void operator()(pointer ptr) const
1218  {
1219  if (exec_) {
1220  exec_->free(ptr);
1221  }
1222  }
1223 
1224 private:
1225  std::shared_ptr<const Executor> exec_;
1226 };
1227 
1228 // a specialization for arrays
1229 template <typename T>
1230 class executor_deleter<T[]> {
1231 public:
1232  using pointer = T[];
1233 
1234  explicit executor_deleter(std::shared_ptr<const Executor> exec)
1235  : exec_{exec}
1236  {}
1237 
1238  void operator()(pointer ptr) const
1239  {
1240  if (exec_) {
1241  exec_->free(ptr);
1242  }
1243  }
1244 
1245 private:
1246  std::shared_ptr<const Executor> exec_;
1247 };
1248 
1249 
1250 namespace detail {
1251 
1252 
1253 template <typename ConcreteExecutor>
1254 class ExecutorBase : public Executor {
1255  // friend class is not in the nearest enclosing namesace, so we write the
1256  // full name
1257  friend class ::gko::OmpExecutor;
1258  friend class ::gko::HipExecutor;
1259  friend class ::gko::DpcppExecutor;
1260  friend class ::gko::CudaExecutor;
1261  friend class ::gko::ReferenceExecutor;
1262 
1263 public:
1264  void run(const Operation& op) const override
1265  {
1266  this->template log<log::Logger::operation_launched>(this, &op);
1267  auto scope_guard = get_scoped_device_id_guard();
1268  op.run(self()->shared_from_this());
1269  this->template log<log::Logger::operation_completed>(this, &op);
1270  }
1271 
1272 protected:
1273  void raw_copy_from(const Executor* src_exec, size_type n_bytes,
1274  const void* src_ptr, void* dest_ptr) const override
1275  {
1276  src_exec->raw_copy_to(self(), n_bytes, src_ptr, dest_ptr);
1277  }
1278 
1279  virtual bool verify_memory_from(const Executor* src_exec) const override
1280  {
1281  return src_exec->verify_memory_to(self());
1282  }
1283 
1284 private:
1285  ConcreteExecutor* self() noexcept
1286  {
1287  return static_cast<ConcreteExecutor*>(this);
1288  }
1289 
1290  const ConcreteExecutor* self() const noexcept
1291  {
1292  return static_cast<const ConcreteExecutor*>(this);
1293  }
1294 };
1295 
1296 #undef GKO_DECLARE_EXECUTOR_FRIEND
1297 
1298 
1306 class EnableDeviceReset {
1307 public:
1313  GKO_DEPRECATED(
1314  "device_reset is no longer supported, call "
1315  "cudaDeviceReset/hipDeviceReset manually")
1316  void set_device_reset(bool device_reset) {}
1317 
1323  GKO_DEPRECATED(
1324  "device_reset is no longer supported, call "
1325  "cudaDeviceReset/hipDeviceReset manually")
1326  bool get_device_reset() { return false; }
1327 
1328 protected:
1334  EnableDeviceReset() {}
1335 
1336  GKO_DEPRECATED(
1337  "device_reset is no longer supported, call "
1338  "cudaDeviceReset/hipDeviceReset manually")
1339  EnableDeviceReset(bool device_reset) {}
1340 };
1341 
1342 
1343 } // namespace detail
1344 
1345 
1346 #define GKO_OVERRIDE_RAW_COPY_TO(_executor_type, ...) \
1347  void raw_copy_to(const _executor_type* dest_exec, size_type n_bytes, \
1348  const void* src_ptr, void* dest_ptr) const override
1349 
1350 
1351 #define GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(dest_, bool_) \
1352  virtual bool verify_memory_to(const dest_* other) const override \
1353  { \
1354  return bool_; \
1355  } \
1356  static_assert(true, \
1357  "This assert is used to counter the false positive extra " \
1358  "semi-colon warnings")
1359 
1360 
1368 class OmpExecutor : public detail::ExecutorBase<OmpExecutor>,
1369  public std::enable_shared_from_this<OmpExecutor> {
1370  friend class detail::ExecutorBase<OmpExecutor>;
1371 
1372 public:
1373  using Executor::run;
1374 
1378  static std::shared_ptr<OmpExecutor> create(
1379  std::shared_ptr<CpuAllocatorBase> alloc =
1380  std::make_shared<CpuAllocator>())
1381  {
1382  return std::shared_ptr<OmpExecutor>(new OmpExecutor(std::move(alloc)));
1383  }
1384 
1385  std::shared_ptr<Executor> get_master() noexcept override;
1386 
1387  std::shared_ptr<const Executor> get_master() const noexcept override;
1388 
1389  void synchronize() const override;
1390 
1391  int get_num_cores() const
1392  {
1393  return this->get_exec_info().num_computing_units;
1394  }
1395 
1396  int get_num_threads_per_core() const
1397  {
1398  return this->get_exec_info().num_pu_per_cu;
1399  }
1400 
1401  static int get_num_omp_threads();
1402 
1403  scoped_device_id_guard get_scoped_device_id_guard() const override;
1404 
1405  std::string get_description() const override;
1406 
1407 protected:
1408  OmpExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1409  : alloc_{std::move(alloc)}
1410  {
1411  this->OmpExecutor::populate_exec_info();
1412  }
1413 
1414  void populate_exec_info() override;
1415 
1416  void* raw_alloc(size_type size) const override;
1417 
1418  void raw_free(void* ptr) const noexcept override;
1419 
1420  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1421 
1422  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, true);
1423 
1424  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1425 
1426  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
1427 
1428  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
1429 
1430  bool verify_memory_to(const DpcppExecutor* dest_exec) const override;
1431 
1432  std::shared_ptr<CpuAllocatorBase> alloc_;
1433 };
1434 
1435 
1436 namespace kernels {
1437 namespace omp {
1438 using DefaultExecutor = OmpExecutor;
1439 } // namespace omp
1440 } // namespace kernels
1441 
1442 
1451 public:
1452  using Executor::run;
1453 
1454  static std::shared_ptr<ReferenceExecutor> create(
1455  std::shared_ptr<CpuAllocatorBase> alloc =
1456  std::make_shared<CpuAllocator>())
1457  {
1458  return std::shared_ptr<ReferenceExecutor>(
1459  new ReferenceExecutor(std::move(alloc)));
1460  }
1461 
1462  scoped_device_id_guard get_scoped_device_id_guard() const override
1463  {
1464  return {this, 0};
1465  }
1466 
1467  std::string get_description() const override { return "ReferenceExecutor"; }
1468 
1469  void run(const Operation& op) const override
1470  {
1471  this->template log<log::Logger::operation_launched>(this, &op);
1472  op.run(std::static_pointer_cast<const ReferenceExecutor>(
1473  this->shared_from_this()));
1474  this->template log<log::Logger::operation_completed>(this, &op);
1475  }
1476 
1477 protected:
1478  ReferenceExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1479  : OmpExecutor{std::move(alloc)}
1480  {
1481  this->ReferenceExecutor::populate_exec_info();
1482  }
1483 
1484  void populate_exec_info() override
1485  {
1486  this->get_exec_info().device_id = -1;
1487  this->get_exec_info().num_computing_units = 1;
1488  this->get_exec_info().num_pu_per_cu = 1;
1489  }
1490 
1491  bool verify_memory_from(const Executor* src_exec) const override
1492  {
1493  return src_exec->verify_memory_to(this);
1494  }
1495 
1496  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, true);
1497 
1498  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1499 
1500  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1501 
1502  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
1503 
1504  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
1505 };
1506 
1507 
1508 namespace kernels {
1509 namespace reference {
1510 using DefaultExecutor = ReferenceExecutor;
1511 } // namespace reference
1512 } // namespace kernels
1513 
1514 
1521 class CudaExecutor : public detail::ExecutorBase<CudaExecutor>,
1522  public std::enable_shared_from_this<CudaExecutor>,
1523  public detail::EnableDeviceReset {
1524  friend class detail::ExecutorBase<CudaExecutor>;
1525 
1526 public:
1527  using Executor::run;
1528 
1540  GKO_DEPRECATED(
1541  "calling this CudaExecutor::create method is deprecated, because"
1542  "device_reset no longer has an effect"
1543  "call CudaExecutor::create("
1544  " int device_id, std::shared_ptr<Executor> master,"
1545  " std::shared_ptr<CudaAllocatorBase> alloc,"
1546  " CUstream_st* stream);"
1547  "instead")
1548  static std::shared_ptr<CudaExecutor> create(
1549  int device_id, std::shared_ptr<Executor> master, bool device_reset,
1550  allocation_mode alloc_mode = default_cuda_alloc_mode,
1551  CUstream_st* stream = nullptr);
1552 
1562  static std::shared_ptr<CudaExecutor> create(
1563  int device_id, std::shared_ptr<Executor> master,
1564  std::shared_ptr<CudaAllocatorBase> alloc =
1565  std::make_shared<CudaAllocator>(),
1566  CUstream_st* stream = nullptr);
1567 
1568  std::shared_ptr<Executor> get_master() noexcept override;
1569 
1570  std::shared_ptr<const Executor> get_master() const noexcept override;
1571 
1572  void synchronize() const override;
1573 
1574  scoped_device_id_guard get_scoped_device_id_guard() const override;
1575 
1576  std::string get_description() const override;
1577 
1581  int get_device_id() const noexcept
1582  {
1583  return this->get_exec_info().device_id;
1584  }
1585 
1589  static int get_num_devices();
1590 
1594  int get_num_warps_per_sm() const noexcept
1595  {
1596  return this->get_exec_info().num_pu_per_cu;
1597  }
1598 
1602  int get_num_multiprocessor() const noexcept
1603  {
1604  return this->get_exec_info().num_computing_units;
1605  }
1606 
1610  int get_num_warps() const noexcept
1611  {
1612  return this->get_exec_info().num_computing_units *
1613  this->get_exec_info().num_pu_per_cu;
1614  }
1615 
1619  int get_warp_size() const noexcept
1620  {
1621  return this->get_exec_info().max_subgroup_size;
1622  }
1623 
1627  int get_major_version() const noexcept
1628  {
1629  return this->get_exec_info().major;
1630  }
1631 
1635  int get_minor_version() const noexcept
1636  {
1637  return this->get_exec_info().minor;
1638  }
1639 
1643  int get_compute_capability() const noexcept
1644  {
1645  return this->get_major_version() * 10 + this->get_minor_version();
1646  }
1647 
1653  GKO_DEPRECATED("use get_blas_handle() instead")
1654  cublasContext* get_cublas_handle() const { return get_blas_handle(); }
1655 
1659  cublasContext* get_blas_handle() const { return cublas_handle_.get(); }
1660 
1666  GKO_DEPRECATED("use get_sparselib_handle() instead")
1667  cusparseContext* get_cusparse_handle() const
1668  {
1669  return get_sparselib_handle();
1670  }
1671 
1675  cusparseContext* get_sparselib_handle() const
1676  {
1677  return cusparse_handle_.get();
1678  }
1679 
1686  CUstream_st* get_stream() const { return stream_; }
1687 
1688 protected:
1689  void set_gpu_property();
1690 
1691  void init_handles();
1692 
1693  CudaExecutor(int device_id, std::shared_ptr<Executor> master,
1694  std::shared_ptr<CudaAllocatorBase> alloc, CUstream_st* stream)
1695  : master_(master), alloc_{std::move(alloc)}, stream_{stream}
1696  {
1697  this->get_exec_info().device_id = device_id;
1698  this->get_exec_info().num_computing_units = 0;
1699  this->get_exec_info().num_pu_per_cu = 0;
1700  this->CudaExecutor::populate_exec_info();
1701  this->set_gpu_property();
1702  this->init_handles();
1703  }
1704 
1705  void* raw_alloc(size_type size) const override;
1706 
1707  void raw_free(void* ptr) const noexcept override;
1708 
1709  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1710 
1711  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1712 
1713  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1714 
1715  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1716 
1717  bool verify_memory_to(const HipExecutor* dest_exec) const override;
1718 
1719  bool verify_memory_to(const CudaExecutor* dest_exec) const override;
1720 
1721  void populate_exec_info() override;
1722 
1723 private:
1724  std::shared_ptr<Executor> master_;
1725 
1726  template <typename T>
1727  using handle_manager = std::unique_ptr<T, std::function<void(T*)>>;
1728  handle_manager<cublasContext> cublas_handle_;
1729  handle_manager<cusparseContext> cusparse_handle_;
1730  std::shared_ptr<CudaAllocatorBase> alloc_;
1731  CUstream_st* stream_;
1732 };
1733 
1734 
1735 namespace kernels {
1736 namespace cuda {
1737 using DefaultExecutor = CudaExecutor;
1738 } // namespace cuda
1739 } // namespace kernels
1740 
1741 
1748 class HipExecutor : public detail::ExecutorBase<HipExecutor>,
1749  public std::enable_shared_from_this<HipExecutor>,
1750  public detail::EnableDeviceReset {
1751  friend class detail::ExecutorBase<HipExecutor>;
1752 
1753 public:
1754  using Executor::run;
1755 
1767  GKO_DEPRECATED(
1768  "device_reset is deprecated entirely, call hipDeviceReset directly. "
1769  "alloc_mode was replaced by the Allocator type "
1770  "hierarchy.")
1771  static std::shared_ptr<HipExecutor> create(
1772  int device_id, std::shared_ptr<Executor> master, bool device_reset,
1773  allocation_mode alloc_mode = default_hip_alloc_mode,
1774  GKO_HIP_STREAM_STRUCT* stream = nullptr);
1775 
1776  static std::shared_ptr<HipExecutor> create(
1777  int device_id, std::shared_ptr<Executor> master,
1778  std::shared_ptr<HipAllocatorBase> alloc =
1779  std::make_shared<HipAllocator>(),
1780  GKO_HIP_STREAM_STRUCT* stream = nullptr);
1781 
1782  std::shared_ptr<Executor> get_master() noexcept override;
1783 
1784  std::shared_ptr<const Executor> get_master() const noexcept override;
1785 
1786  void synchronize() const override;
1787 
1788  scoped_device_id_guard get_scoped_device_id_guard() const override;
1789 
1790  std::string get_description() const override;
1791 
1795  int get_device_id() const noexcept
1796  {
1797  return this->get_exec_info().device_id;
1798  }
1799 
1803  static int get_num_devices();
1804 
1808  int get_num_warps_per_sm() const noexcept
1809  {
1810  return this->get_exec_info().num_pu_per_cu;
1811  }
1812 
1816  int get_num_multiprocessor() const noexcept
1817  {
1818  return this->get_exec_info().num_computing_units;
1819  }
1820 
1824  int get_major_version() const noexcept
1825  {
1826  return this->get_exec_info().major;
1827  }
1828 
1832  int get_minor_version() const noexcept
1833  {
1834  return this->get_exec_info().minor;
1835  }
1836 
1840  int get_num_warps() const noexcept
1841  {
1842  return this->get_exec_info().num_computing_units *
1843  this->get_exec_info().num_pu_per_cu;
1844  }
1845 
1849  int get_warp_size() const noexcept
1850  {
1851  return this->get_exec_info().max_subgroup_size;
1852  }
1853 
1859  GKO_DEPRECATED("use get_blas_handle() instead")
1860  hipblasContext* get_hipblas_handle() const { return get_blas_handle(); }
1861 
1865  hipblasContext* get_blas_handle() const { return hipblas_handle_.get(); }
1866 
1872  GKO_DEPRECATED("use get_sparselib_handle() instead")
1873  hipsparseContext* get_hipsparse_handle() const
1874  {
1875  return get_sparselib_handle();
1876  }
1877 
1881  hipsparseContext* get_sparselib_handle() const
1882  {
1883  return hipsparse_handle_.get();
1884  }
1885 
1886  GKO_HIP_STREAM_STRUCT* get_stream() const { return stream_; }
1887 
1888 protected:
1889  void set_gpu_property();
1890 
1891  void init_handles();
1892 
1893  HipExecutor(int device_id, std::shared_ptr<Executor> master,
1894  std::shared_ptr<HipAllocatorBase> alloc,
1895  GKO_HIP_STREAM_STRUCT* stream)
1896  : master_{std::move(master)}, alloc_{std::move(alloc)}, stream_{stream}
1897  {
1898  this->get_exec_info().device_id = device_id;
1899  this->get_exec_info().num_computing_units = 0;
1900  this->get_exec_info().num_pu_per_cu = 0;
1901  this->HipExecutor::populate_exec_info();
1902  this->set_gpu_property();
1903  this->init_handles();
1904  }
1905 
1906  void* raw_alloc(size_type size) const override;
1907 
1908  void raw_free(void* ptr) const noexcept override;
1909 
1910  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1911 
1912  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor, false);
1913 
1914  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
1915 
1916  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor, false);
1917 
1918  bool verify_memory_to(const CudaExecutor* dest_exec) const override;
1919 
1920  bool verify_memory_to(const HipExecutor* dest_exec) const override;
1921 
1922  void populate_exec_info() override;
1923 
1924 private:
1925  std::shared_ptr<Executor> master_;
1926 
1927  template <typename T>
1928  using handle_manager = std::unique_ptr<T, std::function<void(T*)>>;
1929  handle_manager<hipblasContext> hipblas_handle_;
1930  handle_manager<hipsparseContext> hipsparse_handle_;
1931  std::shared_ptr<HipAllocatorBase> alloc_;
1932  GKO_HIP_STREAM_STRUCT* stream_;
1933 };
1934 
1935 
1936 namespace kernels {
1937 namespace hip {
1938 using DefaultExecutor = HipExecutor;
1939 } // namespace hip
1940 } // namespace kernels
1941 
1942 
1949 class DpcppExecutor : public detail::ExecutorBase<DpcppExecutor>,
1950  public std::enable_shared_from_this<DpcppExecutor> {
1951  friend class detail::ExecutorBase<DpcppExecutor>;
1952 
1953 public:
1954  using Executor::run;
1955 
1965  static std::shared_ptr<DpcppExecutor> create(
1966  int device_id, std::shared_ptr<Executor> master,
1967  std::string device_type = "all",
1968  dpcpp_queue_property property = dpcpp_queue_property::in_order);
1969 
1970  std::shared_ptr<Executor> get_master() noexcept override;
1971 
1972  std::shared_ptr<const Executor> get_master() const noexcept override;
1973 
1974  void synchronize() const override;
1975 
1976  scoped_device_id_guard get_scoped_device_id_guard() const override;
1977 
1978  std::string get_description() const override;
1979 
1985  int get_device_id() const noexcept
1986  {
1987  return this->get_exec_info().device_id;
1988  }
1989 
1990  sycl::queue* get_queue() const { return queue_.get(); }
1991 
1999  static int get_num_devices(std::string device_type);
2000 
2006  const std::vector<int>& get_subgroup_sizes() const noexcept
2007  {
2008  return this->get_exec_info().subgroup_sizes;
2009  }
2010 
2016  int get_num_computing_units() const noexcept
2017  {
2018  return this->get_exec_info().num_computing_units;
2019  }
2020 
2024  int get_num_subgroups() const noexcept
2025  {
2026  return this->get_exec_info().num_computing_units *
2027  this->get_exec_info().num_pu_per_cu;
2028  }
2029 
2035  const std::vector<int>& get_max_workitem_sizes() const noexcept
2036  {
2037  return this->get_exec_info().max_workitem_sizes;
2038  }
2039 
2045  int get_max_workgroup_size() const noexcept
2046  {
2047  return this->get_exec_info().max_workgroup_size;
2048  }
2049 
2055  int get_max_subgroup_size() const noexcept
2056  {
2057  return this->get_exec_info().max_subgroup_size;
2058  }
2059 
2065  std::string get_device_type() const noexcept
2066  {
2067  return this->get_exec_info().device_type;
2068  }
2069 
2070 protected:
2071  void set_device_property(
2072  dpcpp_queue_property property = dpcpp_queue_property::in_order);
2073 
2074  DpcppExecutor(
2075  int device_id, std::shared_ptr<Executor> master,
2076  std::string device_type = "all",
2077  dpcpp_queue_property property = dpcpp_queue_property::in_order)
2078  : master_(master)
2079  {
2080  std::for_each(device_type.begin(), device_type.end(),
2081  [](char& c) { c = std::tolower(c); });
2082  this->get_exec_info().device_type = std::string(device_type);
2083  this->get_exec_info().device_id = device_id;
2084  this->set_device_property(property);
2085  }
2086 
2087  void populate_exec_info() override;
2088 
2089  void* raw_alloc(size_type size) const override;
2090 
2091  void raw_free(void* ptr) const noexcept override;
2092 
2093  GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
2094 
2095  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor, false);
2096 
2097  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor, false);
2098 
2099  GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor, false);
2100 
2101  bool verify_memory_to(const OmpExecutor* dest_exec) const override;
2102 
2103  bool verify_memory_to(const DpcppExecutor* dest_exec) const override;
2104 
2105 private:
2106  std::shared_ptr<Executor> master_;
2107 
2108  template <typename T>
2109  using queue_manager = std::unique_ptr<T, std::function<void(T*)>>;
2110  queue_manager<sycl::queue> queue_;
2111 };
2112 
2113 
2114 namespace kernels {
2115 namespace dpcpp {
2116 using DefaultExecutor = DpcppExecutor;
2117 } // namespace dpcpp
2118 } // namespace kernels
2119 
2120 
2121 #undef GKO_OVERRIDE_RAW_COPY_TO
2122 
2123 
2124 } // namespace gko
2125 
2126 
2127 #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:1675
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:1594
gko::executor_deleter
This is a deleter that uses an executor's free method to deallocate the data.
Definition: executor.hpp:1199
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:1808
gko::executor_deleter::executor_deleter
executor_deleter(std::shared_ptr< const Executor > exec)
Creates a new deleter.
Definition: executor.hpp:1208
gko::CudaExecutor::get_stream
CUstream_st * get_stream() const
Returns the CUDA stream used by this executor.
Definition: executor.hpp:1686
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:2035
gko::Executor::free
void free(void *ptr) const noexcept
Frees memory previously allocated with Executor::alloc().
Definition: executor.hpp:722
gko::HipExecutor::get_hipblas_handle
hipblasContext * get_hipblas_handle() const
Get the hipblas handle for this executor.
Definition: executor.hpp:1860
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:892
gko::DpcppExecutor::get_device_type
std::string get_device_type() const noexcept
Get a string representing the device type.
Definition: executor.hpp:2065
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:2016
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:851
gko::DpcppExecutor::get_num_subgroups
int get_num_subgroups() const noexcept
Get the number of subgroups of this executor.
Definition: executor.hpp:2024
gko::ReferenceExecutor::get_description
std::string get_description() const override
Definition: executor.hpp:1467
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:744
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:1748
gko::CudaExecutor::get_minor_version
int get_minor_version() const noexcept
Get the minor version of compute capability.
Definition: executor.hpp:1635
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:1602
gko::ReferenceExecutor
This is a specialization of the OmpExecutor, which runs the reference implementations of the kernels ...
Definition: executor.hpp:1450
gko::CudaExecutor::get_warp_size
int get_warp_size() const noexcept
Get the warp size of this executor.
Definition: executor.hpp:1619
gko::NotSupported
NotSupported is thrown in case it is not possible to perform the requested operation on the given obj...
Definition: exception.hpp:127
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:1795
gko::HipExecutor::get_hipsparse_handle
hipsparseContext * get_hipsparse_handle() const
Get the hipsparse handle for this executor.
Definition: executor.hpp:1873
gko::CudaExecutor
This is the Executor subclass which represents the CUDA device.
Definition: executor.hpp:1521
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:20
gko::Executor::add_logger
void add_logger(std::shared_ptr< const log::Logger > logger) override
Definition: executor.hpp:838
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:1659
gko::executor_deleter::operator()
void operator()(pointer ptr) const
Deletes the object.
Definition: executor.hpp:1217
gko::DpcppExecutor::get_max_subgroup_size
int get_max_subgroup_size() const noexcept
Get the maximum subgroup size.
Definition: executor.hpp:2055
gko::log::EnableLogging
EnableLogging is a mixin which should be inherited by any class which wants to enable logging.
Definition: logger.hpp:788
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:1949
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:809
gko::OmpExecutor
This is the Executor subclass which represents the OpenMP device (typically CPU).
Definition: executor.hpp:1368
gko::HipExecutor::get_sparselib_handle
hipsparseContext * get_sparselib_handle() const
Get the hipsparse handle for this executor.
Definition: executor.hpp:1881
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:1378
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:705
gko::ReferenceExecutor::run
void run(const Operation &op) const override
Runs the specified Operation using this Executor.
Definition: executor.hpp:1469
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:794
gko::HipExecutor::get_num_multiprocessor
int get_num_multiprocessor() const noexcept
Get the number of multiprocessor of this executor.
Definition: executor.hpp:1816
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:879
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:1985
gko::DpcppExecutor::get_max_workgroup_size
int get_max_workgroup_size() const noexcept
Get the maximum workgroup size.
Definition: executor.hpp:2045
gko::CudaExecutor::get_major_version
int get_major_version() const noexcept
Get the major version of compute capability.
Definition: executor.hpp:1627
gko::CudaExecutor::get_num_warps
int get_num_warps() const noexcept
Get the number of warps of this executor.
Definition: executor.hpp:1610
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:682
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:615
gko::HipExecutor::get_blas_handle
hipblasContext * get_blas_handle() const
Get the hipblas handle for this executor.
Definition: executor.hpp:1865
gko::HipExecutor::get_num_warps
int get_num_warps() const noexcept
Get the number of warps of this executor.
Definition: executor.hpp:1840
gko::CudaExecutor::get_compute_capability
int get_compute_capability() const noexcept
Get the compute capability.
Definition: executor.hpp:1643
gko::HipExecutor::get_major_version
int get_major_version() const noexcept
Get the major version of compute capability.
Definition: executor.hpp:1824
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:867
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:2006
gko::HipExecutor::get_warp_size
int get_warp_size() const noexcept
Get the warp size of this executor.
Definition: executor.hpp:1849
gko::HipExecutor::get_minor_version
int get_minor_version() const noexcept
Get the minor version of compute capability.
Definition: executor.hpp:1832
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:1581
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:683