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;
259 #define GKO_DECLARE_RUN_OVERLOAD(_type, ...) \
260 virtual void run(std::shared_ptr<const _type>) const
262 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_RUN_OVERLOAD);
264 #undef GKO_DECLARE_RUN_OVERLOAD
267 virtual void run(std::shared_ptr<const ReferenceExecutor> executor)
const;
274 virtual const char*
get_name()
const noexcept;
290 template <
typename Closure>
291 class RegisteredOperation :
public Operation {
299 RegisteredOperation(
const char* name, Closure op)
300 : name_(name), op_(std::move(op))
303 const char* get_name() const noexcept
override {
return name_; }
305 void run(std::shared_ptr<const ReferenceExecutor> exec)
const override
310 void run(std::shared_ptr<const OmpExecutor> exec)
const override
315 void run(std::shared_ptr<const CudaExecutor> exec)
const override
320 void run(std::shared_ptr<const HipExecutor> exec)
const override
325 void run(std::shared_ptr<const DpcppExecutor> exec)
const override
336 template <
typename Closure>
337 RegisteredOperation<Closure> make_register_operation(
const char* name,
340 return RegisteredOperation<Closure>{name, std::move(op)};
418 #define GKO_REGISTER_OPERATION(_name, _kernel) \
419 template <typename... Args> \
420 auto make_##_name(Args&&... args) \
422 return ::gko::detail::make_register_operation( \
423 #_kernel, [&args...](auto exec) { \
424 using exec_type = decltype(exec); \
425 if constexpr (std::is_same< \
428 const ::gko::ReferenceExecutor>>:: \
430 ::gko::kernels::reference::_kernel( \
431 std::dynamic_pointer_cast< \
432 const ::gko::ReferenceExecutor>(exec), \
433 std::forward<Args>(args)...); \
434 } else if constexpr ( \
437 std::shared_ptr<const ::gko::OmpExecutor>>::value) { \
438 ::gko::kernels::omp::_kernel( \
439 std::dynamic_pointer_cast<const ::gko::OmpExecutor>( \
441 std::forward<Args>(args)...); \
442 } else if constexpr ( \
445 std::shared_ptr<const ::gko::CudaExecutor>>::value) { \
446 ::gko::kernels::cuda::_kernel( \
447 std::dynamic_pointer_cast<const ::gko::CudaExecutor>( \
449 std::forward<Args>(args)...); \
450 } else if constexpr ( \
453 std::shared_ptr<const ::gko::HipExecutor>>::value) { \
454 ::gko::kernels::hip::_kernel( \
455 std::dynamic_pointer_cast<const ::gko::HipExecutor>( \
457 std::forward<Args>(args)...); \
458 } else if constexpr ( \
461 std::shared_ptr<const ::gko::DpcppExecutor>>::value) { \
462 ::gko::kernels::dpcpp::_kernel( \
463 std::dynamic_pointer_cast<const ::gko::DpcppExecutor>( \
465 std::forward<Args>(args)...); \
467 GKO_NOT_IMPLEMENTED; \
471 static_assert(true, \
472 "This assert is used to counter the false positive extra " \
473 "semi-colon warnings")
513 #define GKO_REGISTER_HOST_OPERATION(_name, _kernel) \
514 template <typename... Args> \
515 auto make_##_name(Args&&... args) \
517 return ::gko::detail::make_register_operation( \
519 [&args...](auto) { _kernel(std::forward<Args>(args)...); }); \
521 static_assert(true, \
522 "This assert is used to counter the false positive extra " \
523 "semi-colon warnings")
526 #define GKO_DECLARE_EXECUTOR_FRIEND(_type, ...) friend class _type
616 template <
typename T>
617 friend class detail::ExecutorBase;
619 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_DECLARE_EXECUTOR_FRIEND);
652 template <
typename ClosureOmp,
typename ClosureCuda,
typename ClosureHip,
653 typename ClosureDpcpp>
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
659 LambdaOperation<ClosureOmp, ClosureOmp, ClosureCuda, ClosureHip,
661 op(op_omp, op_cuda, op_hip, op_dpcpp);
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
687 LambdaOperation<ClosureReference, ClosureOmp, ClosureCuda, ClosureHip,
689 op(std::move(name), op_ref, op_omp, op_cuda, op_hip, op_dpcpp);
704 template <
typename T>
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));
722 void free(
void* ptr)
const noexcept
724 this->
template log<log::Logger::free_started>(
725 this, reinterpret_cast<uintptr>(ptr));
727 this->
template log<log::Logger::free_completed>(
728 this, reinterpret_cast<uintptr>(ptr));
743 template <
typename T>
745 const T* src_ptr, T* dest_ptr)
const
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));
756 this->raw_copy_from(src_exec.
get(), num_elems *
sizeof(T), src_ptr,
759 #if (GKO_VERBOSE_LEVEL >= 1) && !defined(NDEBUG)
762 std::cerr <<
"Not direct copy. Try to copy data from the masters."
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,
770 this->copy_from<T>(src_master, num_elems, master_ptr, dest_ptr);
771 src_master->free(master_ptr);
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));
793 template <
typename T>
796 this->
copy_from(
this, num_elems, src_ptr, dest_ptr);
808 template <
typename T>
812 this->
get_master()->copy_from(
this, 1, ptr, &out);
820 virtual std::shared_ptr<Executor>
get_master() noexcept = 0;
838 void add_logger(std::shared_ptr<const log::Logger> logger)
override
840 this->propagating_logger_refcount_.fetch_add(
841 logger->needs_propagation() ? 1 : 0);
842 this->EnableLogging<Executor>::add_logger(logger);
853 this->propagating_logger_refcount_.fetch_sub(
855 this->EnableLogging<Executor>::remove_logger(logger);
858 using EnableLogging<Executor>::remove_logger;
869 log_propagation_mode_ =
mode;
881 return this->propagating_logger_refcount_.load() > 0 &&
894 return this->verify_memory_from(other.get());
916 std::string device_type;
926 int num_computing_units = -1;
938 int num_pu_per_cu = -1;
948 std::vector<int> subgroup_sizes{};
958 int max_subgroup_size = -1;
970 std::vector<int> max_workitem_sizes{};
981 int max_workgroup_size;
998 std::string pci_bus_id = std::string(13,
'x');
1006 const exec_info& get_exec_info()
const {
return this->exec_info_; }
1017 virtual void* raw_alloc(
size_type size)
const = 0;
1026 virtual void raw_free(
void* ptr)
const noexcept = 0;
1038 virtual void raw_copy_from(
const Executor* src_exec,
size_type n_bytes,
1039 const void* src_ptr,
void* dest_ptr)
const = 0;
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
1054 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_RAW_COPY_TO);
1056 #undef GKO_ENABLE_RAW_COPY_TO
1065 virtual bool verify_memory_from(
const Executor* src_exec)
const = 0;
1076 #define GKO_ENABLE_VERIFY_MEMORY_TO(_exec_type, ...) \
1077 virtual bool verify_memory_to(const _exec_type* dest_exec) const = 0
1079 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_ENABLE_VERIFY_MEMORY_TO);
1081 GKO_ENABLE_VERIFY_MEMORY_TO(ReferenceExecutor, ref);
1083 #undef GKO_ENABLE_VERIFY_MEMORY_TO
1091 virtual void populate_exec_info() = 0;
1098 exec_info& get_exec_info() {
return this->exec_info_; }
1100 exec_info exec_info_;
1104 std::atomic<int> propagating_logger_refcount_{};
1121 template <
typename ClosureReference,
typename ClosureOmp,
1122 typename ClosureCuda,
typename ClosureHip,
typename ClosureDpcpp>
1123 class LambdaOperation :
public Operation {
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)),
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,
1152 void run(std::shared_ptr<const OmpExecutor>)
const override
1157 void run(std::shared_ptr<const ReferenceExecutor>)
const override
1162 void run(std::shared_ptr<const CudaExecutor>)
const override
1167 void run(std::shared_ptr<const HipExecutor>)
const override
1172 void run(std::shared_ptr<const DpcppExecutor>)
const override
1177 const char* get_name() const noexcept
override {
return name_.c_str(); }
1181 ClosureReference op_ref_;
1183 ClosureCuda op_cuda_;
1185 ClosureDpcpp op_dpcpp_;
1198 template <
typename T>
1225 std::shared_ptr<const Executor> exec_;
1229 template <
typename T>
1232 using pointer = T[];
1246 std::shared_ptr<const Executor> exec_;
1253 template <
typename ConcreteExecutor>
1254 class ExecutorBase :
public Executor {
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;
1264 void run(
const Operation& op)
const override
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);
1273 void raw_copy_from(
const Executor* src_exec,
size_type n_bytes,
1274 const void* src_ptr,
void* dest_ptr)
const override
1276 src_exec->raw_copy_to(
self(), n_bytes, src_ptr, dest_ptr);
1279 virtual bool verify_memory_from(
const Executor* src_exec)
const override
1281 return src_exec->verify_memory_to(
self());
1285 ConcreteExecutor*
self() noexcept
1287 return static_cast<ConcreteExecutor*>(
this);
1290 const ConcreteExecutor*
self()
const noexcept
1292 return static_cast<const ConcreteExecutor*>(
this);
1296 #undef GKO_DECLARE_EXECUTOR_FRIEND
1306 class EnableDeviceReset {
1314 "device_reset is no longer supported, call "
1315 "cudaDeviceReset/hipDeviceReset manually")
1316 void set_device_reset(
bool device_reset) {}
1324 "device_reset is no longer supported, call "
1325 "cudaDeviceReset/hipDeviceReset manually")
1326 bool get_device_reset() {
return false; }
1334 EnableDeviceReset() {}
1337 "device_reset is no longer supported, call "
1338 "cudaDeviceReset/hipDeviceReset manually")
1339 EnableDeviceReset(
bool device_reset) {}
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
1351 #define GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(dest_, bool_) \
1352 virtual bool verify_memory_to(const dest_* other) const override \
1356 static_assert(true, \
1357 "This assert is used to counter the false positive extra " \
1358 "semi-colon warnings")
1369 public std::enable_shared_from_this<OmpExecutor> {
1370 friend class detail::ExecutorBase<OmpExecutor>;
1379 std::shared_ptr<CpuAllocatorBase> alloc =
1380 std::make_shared<CpuAllocator>())
1382 return std::shared_ptr<OmpExecutor>(
new OmpExecutor(std::move(alloc)));
1385 std::shared_ptr<Executor> get_master() noexcept override;
1387 std::shared_ptr<const
Executor> get_master() const noexcept override;
1389 void synchronize() const override;
1391 int get_num_cores()
const
1393 return this->get_exec_info().num_computing_units;
1396 int get_num_threads_per_core()
const
1398 return this->get_exec_info().num_pu_per_cu;
1401 static int get_num_omp_threads();
1403 scoped_device_id_guard get_scoped_device_id_guard()
const override;
1405 std::string get_description()
const override;
1408 OmpExecutor(std::shared_ptr<CpuAllocatorBase> alloc)
1409 : alloc_{std::move(alloc)}
1411 this->OmpExecutor::populate_exec_info();
1414 void populate_exec_info()
override;
1416 void* raw_alloc(
size_type size)
const override;
1418 void raw_free(
void* ptr)
const noexcept
override;
1420 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1422 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
true);
1424 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1426 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
1428 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
1430 bool verify_memory_to(
const DpcppExecutor* dest_exec)
const override;
1432 std::shared_ptr<CpuAllocatorBase> alloc_;
1438 using DefaultExecutor = OmpExecutor;
1454 static std::shared_ptr<ReferenceExecutor> create(
1455 std::shared_ptr<CpuAllocatorBase> alloc =
1456 std::make_shared<CpuAllocator>())
1458 return std::shared_ptr<ReferenceExecutor>(
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);
1481 this->ReferenceExecutor::populate_exec_info();
1484 void populate_exec_info()
override
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;
1491 bool verify_memory_from(
const Executor* src_exec)
const override
1493 return src_exec->verify_memory_to(
this);
1496 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
true);
1498 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1500 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1502 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
1504 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
1509 namespace reference {
1510 using DefaultExecutor = ReferenceExecutor;
1522 public std::enable_shared_from_this<CudaExecutor>,
1523 public detail::EnableDeviceReset {
1524 friend class detail::ExecutorBase<CudaExecutor>;
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);"
1548 static std::shared_ptr<CudaExecutor> create(
1549 int device_id, std::shared_ptr<Executor> master,
bool device_reset,
1551 CUstream_st* stream =
nullptr);
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);
1568 std::shared_ptr<Executor> get_master() noexcept
override;
1570 std::shared_ptr<const Executor> get_master()
const noexcept
override;
1572 void synchronize()
const override;
1576 std::string get_description()
const override;
1583 return this->get_exec_info().device_id;
1589 static int get_num_devices();
1596 return this->get_exec_info().num_pu_per_cu;
1604 return this->get_exec_info().num_computing_units;
1612 return this->get_exec_info().num_computing_units *
1613 this->get_exec_info().num_pu_per_cu;
1621 return this->get_exec_info().max_subgroup_size;
1629 return this->get_exec_info().major;
1637 return this->get_exec_info().minor;
1645 return this->get_major_version() * 10 + this->get_minor_version();
1653 GKO_DEPRECATED(
"use get_blas_handle() instead")
1654 cublasContext* get_cublas_handle()
const {
return get_blas_handle(); }
1666 GKO_DEPRECATED(
"use get_sparselib_handle() instead")
1667 cusparseContext* get_cusparse_handle()
const
1669 return get_sparselib_handle();
1677 return cusparse_handle_.get();
1689 void set_gpu_property();
1691 void init_handles();
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}
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();
1705 void* raw_alloc(
size_type size)
const override;
1707 void raw_free(
void* ptr)
const noexcept
override;
1709 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1711 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1713 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1715 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1717 bool verify_memory_to(
const HipExecutor* dest_exec)
const override;
1719 bool verify_memory_to(
const CudaExecutor* dest_exec)
const override;
1721 void populate_exec_info()
override;
1724 std::shared_ptr<Executor> master_;
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_;
1737 using DefaultExecutor = CudaExecutor;
1749 public std::enable_shared_from_this<HipExecutor>,
1750 public detail::EnableDeviceReset {
1768 "device_reset is deprecated entirely, call hipDeviceReset directly. "
1769 "alloc_mode was replaced by the Allocator type "
1771 static std::shared_ptr<HipExecutor>
create(
1772 int device_id, std::shared_ptr<Executor> master,
bool device_reset,
1774 GKO_HIP_STREAM_STRUCT* stream =
nullptr);
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);
1782 std::shared_ptr<Executor>
get_master() noexcept
override;
1784 std::shared_ptr<const Executor>
get_master()
const noexcept
override;
1797 return this->get_exec_info().device_id;
1810 return this->get_exec_info().num_pu_per_cu;
1818 return this->get_exec_info().num_computing_units;
1826 return this->get_exec_info().major;
1834 return this->get_exec_info().minor;
1842 return this->get_exec_info().num_computing_units *
1843 this->get_exec_info().num_pu_per_cu;
1851 return this->get_exec_info().max_subgroup_size;
1859 GKO_DEPRECATED(
"use get_blas_handle() instead")
1872 GKO_DEPRECATED(
"use get_sparselib_handle() instead")
1883 return hipsparse_handle_.get();
1886 GKO_HIP_STREAM_STRUCT* get_stream()
const {
return stream_; }
1889 void set_gpu_property();
1891 void init_handles();
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}
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();
1906 void* raw_alloc(
size_type size)
const override;
1908 void raw_free(
void* ptr)
const noexcept
override;
1910 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
1912 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(OmpExecutor,
false);
1914 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
1916 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(DpcppExecutor,
false);
1918 bool verify_memory_to(
const CudaExecutor* dest_exec)
const override;
1920 bool verify_memory_to(
const HipExecutor* dest_exec)
const override;
1922 void populate_exec_info()
override;
1925 std::shared_ptr<Executor> master_;
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_;
1938 using DefaultExecutor = HipExecutor;
1950 public std::enable_shared_from_this<DpcppExecutor> {
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);
1970 std::shared_ptr<Executor>
get_master() noexcept
override;
1972 std::shared_ptr<const Executor>
get_master()
const noexcept
override;
1987 return this->get_exec_info().device_id;
1990 sycl::queue* get_queue()
const {
return queue_.get(); }
2008 return this->get_exec_info().subgroup_sizes;
2018 return this->get_exec_info().num_computing_units;
2026 return this->get_exec_info().num_computing_units *
2027 this->get_exec_info().num_pu_per_cu;
2037 return this->get_exec_info().max_workitem_sizes;
2047 return this->get_exec_info().max_workgroup_size;
2057 return this->get_exec_info().max_subgroup_size;
2067 return this->get_exec_info().device_type;
2071 void set_device_property(
2072 dpcpp_queue_property property = dpcpp_queue_property::in_order);
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)
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);
2087 void populate_exec_info()
override;
2089 void* raw_alloc(
size_type size)
const override;
2091 void raw_free(
void* ptr)
const noexcept
override;
2093 GKO_ENABLE_FOR_ALL_EXECUTORS(GKO_OVERRIDE_RAW_COPY_TO);
2095 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(CudaExecutor,
false);
2097 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(HipExecutor,
false);
2099 GKO_DEFAULT_OVERRIDE_VERIFY_MEMORY(ReferenceExecutor,
false);
2101 bool verify_memory_to(
const OmpExecutor* dest_exec)
const override;
2103 bool verify_memory_to(
const DpcppExecutor* dest_exec)
const override;
2106 std::shared_ptr<Executor> master_;
2108 template <
typename T>
2109 using queue_manager = std::unique_ptr<T, std::function<void(T*)>>;
2110 queue_manager<sycl::queue> queue_;
2116 using DefaultExecutor = DpcppExecutor;
2121 #undef GKO_OVERRIDE_RAW_COPY_TO
2127 #endif // GKO_PUBLIC_CORE_BASE_EXECUTOR_HPP_