5 #ifndef GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_
6 #define GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_
17 #include <type_traits>
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>
67 constexpr
allocation_mode default_cuda_alloc_mode = allocation_mode::device;
69 constexpr
allocation_mode default_hip_alloc_mode = allocation_mode::device;
75 allocation_mode::unified_global;
77 #if (GINKGO_HIP_PLATFORM_HCC == 1)
80 constexpr
allocation_mode default_hip_alloc_mode = allocation_mode::device;
86 allocation_mode::unified_global;
100 enum class dpcpp_queue_property {
112 GKO_ATTRIBUTES GKO_INLINE dpcpp_queue_property operator|(dpcpp_queue_property a,
113 dpcpp_queue_property b)
115 return static_cast<dpcpp_queue_property>(static_cast<int>(a) |
116 static_cast<int>(b));
123 #define GKO_FORWARD_DECLARE(_type, ...) class _type
125 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_FORWARD_DECLARE);
127 #undef GKO_FORWARD_DECLARE
130 class ReferenceExecutor;
261 #define GKO_DECLARE_RUN_OVERLOAD(_type, ...) \
262 virtual void run(std::shared_ptr<const _type>) const
264 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_RUN_OVERLOAD);
266 #undef GKO_DECLARE_RUN_OVERLOAD
269 virtual void run(std::shared_ptr<const ReferenceExecutor> executor)
const;
276 virtual const char*
get_name()
const noexcept;
292 template <
typename Closure>
293 class RegisteredOperation :
public Operation {
301 RegisteredOperation(
const char* name, Closure op)
302 : name_(name), op_(std::move(op))
305 const char* get_name() const noexcept
override {
return name_; }
307 void run(std::shared_ptr<const ReferenceExecutor> exec)
const override
312 void run(std::shared_ptr<const OmpExecutor> exec)
const override
317 void run(std::shared_ptr<const CudaExecutor> exec)
const override
322 void run(std::shared_ptr<const HipExecutor> exec)
const override
327 void run(std::shared_ptr<const DpcppExecutor> exec)
const override
338 template <
typename Closure>
339 RegisteredOperation<Closure> make_register_operation(
const char* name,
342 return RegisteredOperation<Closure>{name, std::move(op)};
420 #define GKO_REGISTER_OPERATION(_name, _kernel) \
421 template <typename... Args> \
422 auto make_##_name(Args&&... args) \
424 return ::gko::detail::make_register_operation( \
425 #_kernel, [&args...](auto exec) { \
426 using exec_type = decltype(exec); \
427 if constexpr (std::is_same< \
430 const ::gko::ReferenceExecutor>>:: \
432 ::gko::kernels::reference::_kernel( \
433 std::dynamic_pointer_cast< \
434 const ::gko::ReferenceExecutor>(exec), \
435 std::forward<Args>(args)...); \
436 } else if constexpr ( \
439 std::shared_ptr<const ::gko::OmpExecutor>>::value) { \
440 ::gko::kernels::omp::_kernel( \
441 std::dynamic_pointer_cast<const ::gko::OmpExecutor>( \
443 std::forward<Args>(args)...); \
444 } else if constexpr ( \
447 std::shared_ptr<const ::gko::CudaExecutor>>::value) { \
448 ::gko::kernels::cuda::_kernel( \
449 std::dynamic_pointer_cast<const ::gko::CudaExecutor>( \
451 std::forward<Args>(args)...); \
452 } else if constexpr ( \
455 std::shared_ptr<const ::gko::HipExecutor>>::value) { \
456 ::gko::kernels::hip::_kernel( \
457 std::dynamic_pointer_cast<const ::gko::HipExecutor>( \
459 std::forward<Args>(args)...); \
460 } else if constexpr ( \
463 std::shared_ptr<const ::gko::DpcppExecutor>>::value) { \
464 ::gko::kernels::dpcpp::_kernel( \
465 std::dynamic_pointer_cast<const ::gko::DpcppExecutor>( \
467 std::forward<Args>(args)...); \
469 GKO_NOT_IMPLEMENTED; \
473 static_assert(true, \
474 "This assert is used to counter the false positive extra " \
475 "semi-colon warnings")
515 #define GKO_REGISTER_HOST_OPERATION(_name, _kernel) \
516 template <typename... Args> \
517 auto make_##_name(Args&&... args) \
519 return ::gko::detail::make_register_operation( \
521 [&args...](auto) { _kernel(std::forward<Args>(args)...); }); \
523 static_assert(true, \
524 "This assert is used to counter the false positive extra " \
525 "semi-colon warnings")
528 #define GKO_DECLARE_EXECUTOR_FRIEND(_type, ...) friend class _type
618 template <
typename T>
619 friend class detail::ExecutorBase;
621 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_EXECUTOR_FRIEND);
654 template <
typename ClosureOmp,
typename ClosureCuda,
typename ClosureHip,
655 typename ClosureDpcpp>
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
661 LambdaOperation<ClosureOmp, ClosureOmp, ClosureCuda, ClosureHip,
663 op(op_omp, op_cuda, op_hip, op_dpcpp);
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
689 LambdaOperation<ClosureReference, ClosureOmp, ClosureCuda, ClosureHip,
691 op(std::move(name), op_ref, op_omp, op_cuda, op_hip, op_dpcpp);
706 template <
typename T>
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));
724 void free(
void* ptr)
const noexcept
726 this->
template log<log::Logger::free_started>(
727 this, reinterpret_cast<uintptr>(ptr));
729 this->
template log<log::Logger::free_completed>(
730 this, reinterpret_cast<uintptr>(ptr));
745 template <
typename T>
747 const T* src_ptr, T* dest_ptr)
const
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));
758 this->raw_copy_from(src_exec.
get(), num_elems *
sizeof(T), src_ptr,
761 #if (GKO_VERBOSE_LEVEL >= 1) && !defined(NDEBUG)
764 std::cerr <<
"Not direct copy. Try to copy data from the masters."
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,
772 this->copy_from<T>(src_master, num_elems, master_ptr, dest_ptr);
773 src_master->free(master_ptr);
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));
795 template <
typename T>
798 this->
copy_from(
this, num_elems, src_ptr, dest_ptr);
810 template <
typename T>
814 this->
get_master()->copy_from(
this, 1, ptr, &out);
822 virtual std::shared_ptr<Executor>
get_master() noexcept = 0;
840 void add_logger(std::shared_ptr<const log::Logger> logger)
override
842 this->propagating_logger_refcount_.fetch_add(
843 logger->needs_propagation() ? 1 : 0);
844 this->EnableLogging<Executor>::add_logger(logger);
855 this->propagating_logger_refcount_.fetch_sub(
857 this->EnableLogging<Executor>::remove_logger(logger);
860 using EnableLogging<Executor>::remove_logger;
871 log_propagation_mode_ =
mode;
883 return this->propagating_logger_refcount_.load() > 0 &&
896 return this->verify_memory_from(other.get());
918 std::string device_type;
928 int num_computing_units = -1;
940 int num_pu_per_cu = -1;
950 std::vector<int> subgroup_sizes{};
960 int max_subgroup_size = -1;
972 std::vector<int> max_workitem_sizes{};
983 int max_workgroup_size = -1;
1000 std::string pci_bus_id = std::string(13,
'x');
1008 const exec_info& get_exec_info()
const {
return this->exec_info_; }
1019 virtual void* raw_alloc(
size_type size)
const = 0;
1028 virtual void raw_free(
void* ptr)
const noexcept = 0;
1040 virtual void raw_copy_from(
const Executor* src_exec,
size_type n_bytes,
1041 const void* src_ptr,
void* dest_ptr)
const = 0;
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
1056 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_RAW_COPY_TO);
1058 #undef GKO_ENABLE_RAW_COPY_TO
1067 virtual bool verify_memory_from(
const Executor* src_exec)
const = 0;
1078 #define GKO_ENABLE_VERIFY_MEMORY_TO(_exec_type, ...) \
1079 virtual bool verify_memory_to(const _exec_type* dest_exec) const = 0
1081 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_VERIFY_MEMORY_TO);
1083 GKO_ENABLE_VERIFY_MEMORY_TO(ReferenceExecutor, ref);
1085 #undef GKO_ENABLE_VERIFY_MEMORY_TO
1093 virtual void populate_exec_info() = 0;
1100 exec_info& get_exec_info() {
return this->exec_info_; }
1102 exec_info exec_info_;
1106 std::atomic<int> propagating_logger_refcount_{};
1123 template <
typename ClosureReference,
typename ClosureOmp,
1124 typename ClosureCuda,
typename ClosureHip,
typename ClosureDpcpp>
1125 class LambdaOperation :
public Operation {
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)),
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,
1154 void run(std::shared_ptr<const OmpExecutor>)
const override
1159 void run(std::shared_ptr<const ReferenceExecutor>)
const override
1164 void run(std::shared_ptr<const CudaExecutor>)
const override
1169 void run(std::shared_ptr<const HipExecutor>)
const override
1174 void run(std::shared_ptr<const DpcppExecutor>)
const override
1179 const char* get_name() const noexcept
override {
return name_.c_str(); }
1183 ClosureReference op_ref_;
1185 ClosureCuda op_cuda_;
1187 ClosureDpcpp op_dpcpp_;
1200 template <
typename T>
1227 std::shared_ptr<const Executor> exec_;
1231 template <
typename T>
1234 using pointer = T[];
1248 std::shared_ptr<const Executor> exec_;
1255 template <
typename ConcreteExecutor>
1256 class ExecutorBase :
public Executor {
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;
1266 void run(
const Operation& op)
const override
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);
1275 void raw_copy_from(
const Executor* src_exec,
size_type n_bytes,
1276 const void* src_ptr,
void* dest_ptr)
const override
1278 src_exec->raw_copy_to(
self(), n_bytes, src_ptr, dest_ptr);
1281 virtual bool verify_memory_from(
const Executor* src_exec)
const override
1283 return src_exec->verify_memory_to(
self());
1287 ConcreteExecutor*
self() noexcept
1289 return static_cast<ConcreteExecutor*>(
this);
1292 const ConcreteExecutor*
self()
const noexcept
1294 return static_cast<const ConcreteExecutor*>(
this);
1298 #undef GKO_DECLARE_EXECUTOR_FRIEND
1308 class EnableDeviceReset {
1316 "device_reset is no longer supported, call "
1317 "cudaDeviceReset/hipDeviceReset manually")
1318 void set_device_reset(
bool device_reset) {}
1326 "device_reset is no longer supported, call "
1327 "cudaDeviceReset/hipDeviceReset manually")
1328 bool get_device_reset() {
return false; }
1336 EnableDeviceReset() {}
1339 "device_reset is no longer supported, call "
1340 "cudaDeviceReset/hipDeviceReset manually")
1341 EnableDeviceReset(
bool device_reset) {}
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
1353 #define GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(dest_, bool_) \
1354 virtual bool verify_memory_to(const dest_* other) const override \
1358 static_assert(true, \
1359 "This assert is used to counter the false positive extra " \
1360 "semi-colon warnings")
1371 public std::enable_shared_from_this<OmpExecutor> {
1372 friend class detail::ExecutorBase<OmpExecutor>;
1381 std::shared_ptr<CpuAllocatorBase> alloc =
1382 std::make_shared<CpuAllocator>())
1384 return std::shared_ptr<OmpExecutor>(
new OmpExecutor(std::move(alloc)));
1387 std::shared_ptr<Executor> get_master() noexcept override;
1389 std::shared_ptr<const
Executor> get_master() const noexcept override;
1391 void synchronize() const override;
1393 int get_num_cores()
const
1395 return this->get_exec_info().num_computing_units;
1398 int get_num_threads_per_core()
const
1400 return this->get_exec_info().num_pu_per_cu;
1403 static int get_num_omp_threads();
1405 scoped_device_id_guard get_scoped_device_id_guard()
const override;
1407 std::string get_description()
const override;
1410 OmpExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1411 : alloc_{std::move(alloc)}
1413 this->OmpExecutor::populate_exec_info();
1416 void populate_exec_info()
override;
1418 void* raw_alloc(
size_type size)
const override;
1420 void raw_free(
void* ptr)
const noexcept
override;
1422 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1424 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
true);
1426 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1428 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
1430 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
1432 bool verify_memory_to(
const DpcppExecutor* dest_exec)
const override;
1434 std::shared_ptr<CpuAllocatorBase> alloc_;
1440 using DefaultExecutor = OmpExecutor;
1456 static std::shared_ptr<ReferenceExecutor> create(
1457 std::shared_ptr<CpuAllocatorBase> alloc =
1458 std::make_shared<CpuAllocator>())
1460 return std::shared_ptr<ReferenceExecutor>(
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);
1483 this->ReferenceExecutor::populate_exec_info();
1486 void populate_exec_info()
override
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;
1493 bool verify_memory_from(
const Executor* src_exec)
const override
1495 return src_exec->verify_memory_to(
this);
1498 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
true);
1500 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1502 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1504 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
1506 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
1511 namespace reference {
1512 using DefaultExecutor = ReferenceExecutor;
1524 public std::enable_shared_from_this<CudaExecutor>,
1525 public detail::EnableDeviceReset {
1526 friend class detail::ExecutorBase<CudaExecutor>;
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);"
1550 static std::shared_ptr<CudaExecutor> create(
1551 int device_id, std::shared_ptr<Executor> master,
bool device_reset,
1553 CUstream_st* stream =
nullptr);
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);
1570 std::shared_ptr<Executor> get_master() noexcept
override;
1572 std::shared_ptr<const Executor> get_master()
const noexcept
override;
1574 void synchronize()
const override;
1578 std::string get_description()
const override;
1585 return this->get_exec_info().device_id;
1591 static int get_num_devices();
1598 return this->get_exec_info().num_pu_per_cu;
1606 return this->get_exec_info().num_computing_units;
1614 return this->get_exec_info().num_computing_units *
1615 this->get_exec_info().num_pu_per_cu;
1623 return this->get_exec_info().max_subgroup_size;
1631 return this->get_exec_info().major;
1639 return this->get_exec_info().minor;
1647 return this->get_major_version() * 10 + this->get_minor_version();
1655 GKO_DEPRECATED(
"use get_blas_handle() instead")
1656 cublasContext* get_cublas_handle()
const {
return get_blas_handle(); }
1668 GKO_DEPRECATED(
"use get_sparselib_handle() instead")
1669 cusparseContext* get_cusparse_handle()
const
1671 return get_sparselib_handle();
1679 return cusparse_handle_.get();
1691 void set_gpu_property();
1693 void init_handles();
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}
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();
1707 void* raw_alloc(
size_type size)
const override;
1709 void raw_free(
void* ptr)
const noexcept
override;
1711 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1713 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1715 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1717 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1719 bool verify_memory_to(
const HipExecutor* dest_exec)
const override;
1721 bool verify_memory_to(
const CudaExecutor* dest_exec)
const override;
1723 void populate_exec_info()
override;
1726 std::shared_ptr<Executor> master_;
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_;
1739 using DefaultExecutor = CudaExecutor;
1751 public std::enable_shared_from_this<HipExecutor>,
1752 public detail::EnableDeviceReset {
1771 "device_reset is deprecated entirely, call hipDeviceReset directly. "
1772 "alloc_mode was replaced by the Allocator type "
1774 static std::shared_ptr<HipExecutor>
create(
1775 int device_id, std::shared_ptr<Executor> master,
bool device_reset,
1777 GKO_HIP_STREAM_STRUCT* stream =
nullptr);
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);
1785 std::shared_ptr<Executor>
get_master() noexcept
override;
1787 std::shared_ptr<const Executor>
get_master()
const noexcept
override;
1800 return this->get_exec_info().device_id;
1813 return this->get_exec_info().num_pu_per_cu;
1821 return this->get_exec_info().num_computing_units;
1829 return this->get_exec_info().major;
1837 return this->get_exec_info().minor;
1845 return this->get_exec_info().num_computing_units *
1846 this->get_exec_info().num_pu_per_cu;
1854 return this->get_exec_info().max_subgroup_size;
1862 GKO_DEPRECATED(
"use get_blas_handle() instead")
1875 GKO_DEPRECATED(
"use get_sparselib_handle() instead")
1886 return hipsparse_handle_.get();
1889 GKO_HIP_STREAM_STRUCT* get_stream()
const {
return stream_; }
1892 void set_gpu_property();
1894 void init_handles();
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}
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();
1909 void* raw_alloc(
size_type size)
const override;
1911 void raw_free(
void* ptr)
const noexcept
override;
1913 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1915 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1917 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1919 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1921 bool verify_memory_to(
const CudaExecutor* dest_exec)
const override;
1923 bool verify_memory_to(
const HipExecutor* dest_exec)
const override;
1925 void populate_exec_info()
override;
1928 std::shared_ptr<Executor> master_;
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_;
1941 using DefaultExecutor = HipExecutor;
1953 public std::enable_shared_from_this<DpcppExecutor> {
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);
1976 std::shared_ptr<Executor>
get_master() noexcept
override;
1978 std::shared_ptr<const Executor>
get_master()
const noexcept
override;
1993 return this->get_exec_info().device_id;
1996 sycl::queue* get_queue()
const {
return queue_.get(); }
2014 return this->get_exec_info().subgroup_sizes;
2024 return this->get_exec_info().num_computing_units;
2032 return this->get_exec_info().num_computing_units *
2033 this->get_exec_info().num_pu_per_cu;
2043 return this->get_exec_info().max_workitem_sizes;
2053 return this->get_exec_info().max_workgroup_size;
2063 return this->get_exec_info().max_subgroup_size;
2073 return this->get_exec_info().device_type;
2077 void set_device_property(
2078 dpcpp_queue_property property = dpcpp_queue_property::in_order);
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)
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);
2093 void populate_exec_info()
override;
2095 void* raw_alloc(
size_type size)
const override;
2097 void raw_free(
void* ptr)
const noexcept
override;
2099 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
2101 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
2103 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
2105 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
2107 bool verify_memory_to(
const OmpExecutor* dest_exec)
const override;
2109 bool verify_memory_to(
const DpcppExecutor* dest_exec)
const override;
2112 std::shared_ptr<Executor> master_;
2114 template <
typename T>
2115 using queue_manager = std::unique_ptr<T, std::function<void(T*)>>;
2116 queue_manager<sycl::queue> queue_;
2122 using DefaultExecutor = DpcppExecutor;
2127 #undef GKO_OVERRIDE_RAW_COPY_TO
2133 #endif // GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_