diff --git a/CMakeLists.txt b/CMakeLists.txt index b07f874..303c322 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,6 @@ add_library(simsycl include/CL/sycl.hpp include/simsycl/sycl.hh include/simsycl/detail/allocation.hh - include/simsycl/detail/async_handler.hh include/simsycl/detail/check.hh include/simsycl/detail/config.hh include/simsycl/detail/coordinate.hh @@ -51,6 +50,7 @@ add_library(simsycl include/simsycl/detail/utils.hh include/simsycl/sycl/accessor.hh include/simsycl/sycl/allocator.hh + include/simsycl/sycl/async_handler.hh include/simsycl/sycl/atomic_ref.hh include/simsycl/sycl/backend.hh include/simsycl/sycl/buffer.hh @@ -90,6 +90,7 @@ add_library(simsycl src/simsycl/context.cc src/simsycl/device.cc src/simsycl/platform.cc + src/simsycl/queue.cc src/simsycl/system.cc src/simsycl/templates.cc ) diff --git a/include/simsycl/detail/reference_type.hh b/include/simsycl/detail/reference_type.hh index b4b11b1..542a72c 100644 --- a/include/simsycl/detail/reference_type.hh +++ b/include/simsycl/detail/reference_type.hh @@ -18,6 +18,19 @@ struct std::hash> { namespace simsycl::detail { +template +class weak_ref { + public: + weak_ref() = default; + + weak_ref(std::weak_ptr &&state) : m_state(std::move(state)) {} + + Derived lock() const { return Derived(m_state.lock()); } + + private: + std::weak_ptr m_state; +}; + template class reference_type { public: @@ -29,6 +42,10 @@ class reference_type { reference_type() = default; + reference_type(std::shared_ptr &&state) : m_state(std::move(state)) { + SIMSYCL_CHECK(m_state != nullptr); + } + template explicit reference_type(std::in_place_t /* tag */, CtorParams &&...ctor_args) : m_state(std::make_shared(std::forward(ctor_args)...)) { @@ -45,8 +62,17 @@ class reference_type { return *m_state; } + detail::weak_ref weak_ref() { + SIMSYCL_CHECK(m_state != nullptr); + return detail::weak_ref(std::weak_ptr(m_state)); + } + private: friend struct std::hash>; + + template + friend class weak_ref; + std::shared_ptr m_state; }; diff --git a/include/simsycl/sycl/accessor.hh b/include/simsycl/sycl/accessor.hh index 3216ec6..c0dc873 100644 --- a/include/simsycl/sycl/accessor.hh +++ b/include/simsycl/sycl/accessor.hh @@ -16,6 +16,10 @@ #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // access::placeholder, access_mode::atomic + + namespace simsycl::detail { template @@ -311,11 +315,8 @@ class accessor : public simsycl::detail::property_interface { return m_buffer[detail::get_linear_index(m_access_range, index)]; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" [[deprecated]] atomic operator[](id index) const requires(AccessMode == access_mode::atomic); -#pragma GCC diagnostic pop decltype(auto) operator[](size_t index) const requires(Dimensions > 1) @@ -535,11 +536,8 @@ class accessor : public simsy return *this; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" [[deprecated]] operator atomic() const requires(AccessMode == access_mode::atomic); -#pragma GCC diagnostic pop std::add_pointer_t get_pointer() const noexcept { SIMSYCL_CHECK(m_buffer != nullptr); @@ -932,6 +930,9 @@ class host_accessor : public simsycl::detail::property_int bool empty() const noexcept { return false; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // access_mode::atomic + operator reference() const requires(AccessMode != access_mode::atomic) { @@ -955,6 +956,8 @@ class host_accessor : public simsycl::detail::property_int return *this; } +#pragma GCC diagnostic pop + std::add_pointer_t get_pointer() const noexcept { SIMSYCL_CHECK(m_buffer != nullptr); return m_buffer; @@ -982,4 +985,6 @@ class host_accessor : public simsycl::detail::property_int DataT *m_buffer = nullptr; }; +#pragma GCC diagnostic pop + } // namespace simsycl::sycl diff --git a/include/simsycl/sycl/async_handler.hh b/include/simsycl/sycl/async_handler.hh index fac2417..02adf33 100644 --- a/include/simsycl/sycl/async_handler.hh +++ b/include/simsycl/sycl/async_handler.hh @@ -26,3 +26,11 @@ class exception_list : private std::vector { using async_handler = std::function; } + +namespace simsycl::detail { + +[[noreturn]] void default_async_handler(sycl::exception_list exceptions); + +void call_async_handler(const sycl::async_handler &handler_opt, sycl::exception_list exceptions); + +} diff --git a/include/simsycl/sycl/buffer.hh b/include/simsycl/sycl/buffer.hh index 962a2cf..1bddf0b 100644 --- a/include/simsycl/sycl/buffer.hh +++ b/include/simsycl/sycl/buffer.hh @@ -198,19 +198,22 @@ class buffer final template accessor get_access(handler &command_group_handler); - // Deprecated - template - accessor get_access(); - template accessor get_access( handler &command_group_handler, range access_range, id access_offset = {}); - // Deprecated +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + + template + [[deprecated]] accessor get_access(); + template - accessor get_access( + [[deprecated]] accessor get_access( range access_range, id access_offset = {}); +#pragma GCC diagnostic pop + template auto get_access(Ts...); diff --git a/include/simsycl/sycl/context.hh b/include/simsycl/sycl/context.hh index 2e45d73..014a59c 100644 --- a/include/simsycl/sycl/context.hh +++ b/include/simsycl/sycl/context.hh @@ -6,6 +6,8 @@ #include "../detail/reference_type.hh" +#include + namespace simsycl::detail { @@ -18,7 +20,7 @@ namespace simsycl::sycl { class context final : public detail::reference_type, public detail::property_interface { private: using reference_type = detail::reference_type; - using property_compatibilty + using property_compatibility = detail::property_compatibility_with; public: @@ -35,21 +37,23 @@ class context final : public detail::reference_type &device_list, async_handler async_handler, const property_list &prop_list = {}); - backend get_backend() const noexcept; + backend get_backend() const noexcept { return backend::simsycl; } platform get_platform() const; std::vector get_devices() const; template - typename Param::return_type get_info() const { - return {}; - } + typename Param::return_type get_info() const; template - typename Param::return_type get_backend_info() const { - return {}; - } + typename Param::return_type get_backend_info() const; + + private: + struct internal_t { + } inline static constexpr internal{}; + + explicit context(internal_t, const std::vector &devices, const async_handler &async_handler, const property_list &prop_list); }; } // namespace simsycl::sycl diff --git a/include/simsycl/sycl/device.hh b/include/simsycl/sycl/device.hh index 598b164..9901814 100644 --- a/include/simsycl/sycl/device.hh +++ b/include/simsycl/sycl/device.hh @@ -6,6 +6,7 @@ #include "../detail/reference_type.hh" +#include #include #include @@ -16,16 +17,25 @@ struct device_config; sycl::device create_device(sycl::platform &platform, const device_config &config); -} +} // namespace simsycl namespace simsycl::detail { struct default_selector { - int operator()(const sycl::device & /* TODO */) const { return 0; } + int operator()(const sycl::device &device) const; +}; + +struct cpu_selector { + int operator()(const sycl::device &device) const; +}; + +struct gpu_selector { + int operator()(const sycl::device &device) const; +}; + +struct accelerator_selector { + int operator()(const sycl::device &device) const; }; -struct cpu_selector : public default_selector {}; // TODO -struct gpu_selector : public default_selector {}; // TODO -struct accelerator_selector : public default_selector {}; // TODO struct device_state; @@ -62,7 +72,7 @@ class device final : public detail::reference_type device(); template - explicit device(const DeviceSelector &device_selector); + explicit device(const DeviceSelector &device_selector) : device(detail::device_selector(device_selector)) {} bool is_cpu() const { return has(aspect::cpu); } @@ -100,6 +110,7 @@ class device final : public detail::reference_type friend device simsycl::create_device(sycl::platform &platform, const device_config &config); device(detail::device_state state); + device(const detail::device_selector &selector); }; template diff --git a/include/simsycl/sycl/enums.hh b/include/simsycl/sycl/enums.hh index 44a30ac..e82024b 100644 --- a/include/simsycl/sycl/enums.hh +++ b/include/simsycl/sycl/enums.hh @@ -18,9 +18,9 @@ enum class access_mode { read, write, read_write, - discard_write, // Deprecated in SYCL 2020 - discard_read_write, // Deprecated in SYCL 2020 - atomic // Deprecated in SYCL 2020 + discard_write [[deprecated]], + discard_read_write [[deprecated]], + atomic [[deprecated]] }; enum class aspect { @@ -42,7 +42,7 @@ enum class aspect { usm_atomic_host_allocations, usm_shared_allocations, usm_atomic_shared_allocations, - usm_system_allocations + usm_system_allocations, }; enum class backend { simsycl }; @@ -64,7 +64,7 @@ enum class errc { profiling, feature_not_supported, kernel_not_supported, - backend_mismatch + backend_mismatch, }; enum class image_format { @@ -114,42 +114,31 @@ enum class stream_manipulator { fixed, scientific, hexfloat, - defaultfloat + defaultfloat, }; enum class target { device, host_task, - constant_buffer, // Deprecated - local, // Deprecated - host_buffer, // Deprecated - global_buffer = device // Deprecated + constant_buffer [[deprecated]], + local [[deprecated]], + host_buffer [[deprecated]], + global_buffer [[deprecated]] = device, }; } // namespace simsycl::sycl namespace simsycl::sycl::access { -enum class address_space { - global_space, - local_space, - constant_space, // Deprecated in SYCL 2020 - private_space, - generic_space -}; +enum class address_space { global_space, local_space, constant_space [[deprecated]], private_space, generic_space }; enum class decorated { no, yes, legacy }; -// The legacy type "access::mode" is deprecated. -using mode = sycl::access_mode; +using mode [[deprecated]] = sycl::access_mode; -// The legacy type "access::target" is deprecated. -using sycl::target; +using target [[deprecated]] = sycl::target; -enum class placeholder { // Deprecated - false_t, - true_t -}; +enum class [[deprecated]] placeholder { false_t, true_t }; enum class fence_space { local_space, global_space, global_and_local }; diff --git a/include/simsycl/sycl/event.hh b/include/simsycl/sycl/event.hh index 3515b56..3b5b7fb 100644 --- a/include/simsycl/sycl/event.hh +++ b/include/simsycl/sycl/event.hh @@ -1,6 +1,7 @@ #pragma once #include "forward.hh" +#include "info.hh" #include "type_traits.hh" #include "../detail/reference_type.hh" diff --git a/include/simsycl/sycl/forward.hh b/include/simsycl/sycl/forward.hh index c0b95cc..06cf020 100644 --- a/include/simsycl/sycl/forward.hh +++ b/include/simsycl/sycl/forward.hh @@ -16,11 +16,16 @@ struct system_config; namespace simsycl::sycl { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // access::placeholder + template ? access_mode::read : access_mode::read_write), target AccessTarget = target::device, access::placeholder IsPlaceholder = access::placeholder::false_t> class accessor; +#pragma GCC diagnostic pop + template class atomic; @@ -116,6 +121,8 @@ struct nd_item_impl; struct group_impl; struct sub_group_impl; +using device_selector = std::function; + sycl::sub_group make_sub_group( const sycl::id<1> &, const sycl::range<1> &, const sycl::id<1> &, const sycl::range<1> &, sub_group_impl *); @@ -134,6 +141,4 @@ struct execution_status; sycl::event make_event(const execution_status &status); -void setup(); - } // namespace simsycl::detail diff --git a/include/simsycl/sycl/group.hh b/include/simsycl/sycl/group.hh index fd1ed85..401bd17 100644 --- a/include/simsycl/sycl/group.hh +++ b/include/simsycl/sycl/group.hh @@ -89,7 +89,7 @@ class group { SIMSYCL_NOT_IMPLEMENTED_UNUSED_ARGS(flexible_range, func); } - template + template void mem_fence(typename std::enable_if_t diff --git a/include/simsycl/sycl/handler.hh b/include/simsycl/sycl/handler.hh index 1364f35..9c4d7db 100644 --- a/include/simsycl/sycl/handler.hh +++ b/include/simsycl/sycl/handler.hh @@ -207,8 +207,12 @@ void parallel_for(sycl::nd_range execution_range, const std::vector< } // namespace simsycl::detail + namespace simsycl::sycl { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // placeholder + class handler { public: handler(const handler &) = delete; @@ -299,7 +303,7 @@ class handler { void mem_advise(void * /* ptr */, size_t /* num_bytes */, int /* advice */) {} //------ Explicit memory operation APIs - // + template void copy(accessor src, std::shared_ptr dest); @@ -327,6 +331,8 @@ class handler { template void fill(accessor dest, const T &src); +#pragma GCC diagnostic pop + void use_kernel_bundle(const kernel_bundle &exec_bundle); template @@ -344,6 +350,8 @@ class handler { handler() = default; }; +#pragma GCC diagnostic pop + } // namespace simsycl::sycl namespace simsycl::detail { diff --git a/include/simsycl/sycl/multi_ptr.hh b/include/simsycl/sycl/multi_ptr.hh index 222d658..75e5681 100644 --- a/include/simsycl/sycl/multi_ptr.hh +++ b/include/simsycl/sycl/multi_ptr.hh @@ -24,6 +24,9 @@ struct remove_decoration { template using remove_decoration_t = typename remove_decoration::type; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // target::local, ... + template class multi_ptr { public: @@ -337,4 +340,6 @@ using decorated_local_ptr = multi_ptr using decorated_private_ptr = multi_ptr; +#pragma GCC diagnostic pop + } // namespace simsycl::sycl diff --git a/include/simsycl/sycl/nd_item.hh b/include/simsycl/sycl/nd_item.hh index b0366bd..a395840 100644 --- a/include/simsycl/sycl/nd_item.hh +++ b/include/simsycl/sycl/nd_item.hh @@ -86,14 +86,17 @@ class nd_item { size_t get_local_range(int dimension) const { return m_local_item.get_range(dimension); } - [[deprecated("offsets are deprecated in SYCL 2020")]] id get_offset() const { - return m_global_item.get_offset(); - } - nd_range get_nd_range() const { return nd_range(get_global_range(), get_local_range(), m_global_item.get_offset()); } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + + [[deprecated("offsets are deprecated in SYCL 2020")]] id get_offset() const { + return m_global_item.get_offset(); + } + [[deprecated("use sycl::group_barrier() free function instead")]] void barrier( access::fence_space access_space = access::fence_space::global_and_local) const { (void)access_space; @@ -110,26 +113,24 @@ class nd_item { SIMSYCL_NOT_IMPLEMENTED(access_space); } - // Deprecated in SYCL 2020. template [[deprecated]] device_event async_work_group_copy( local_ptr dest, global_ptr src, size_t num_elements) const; - // Deprecated in SYCL 2020. template [[deprecated]] device_event async_work_group_copy( global_ptr dest, local_ptr src, size_t num_elements) const; - // Deprecated in SYCL 2020. template [[deprecated]] device_event async_work_group_copy( local_ptr dest, global_ptr src, size_t num_elements, size_t src_stride) const; - // Deprecated in SYCL 2020. template [[deprecated]] device_event async_work_group_copy( global_ptr dest, local_ptr src, size_t num_elements, size_t dest_stride) const; + #pragma GCC diagnostic pop + template requires(std::is_same_v>) device_event async_work_group_copy( diff --git a/include/simsycl/sycl/platform.hh b/include/simsycl/sycl/platform.hh index 6040527..ee90dc4 100644 --- a/include/simsycl/sycl/platform.hh +++ b/include/simsycl/sycl/platform.hh @@ -6,6 +6,7 @@ #include "../detail/reference_type.hh" +#include #include #include @@ -35,7 +36,7 @@ class platform final : public detail::reference_type - explicit platform(const DeviceSelector &device_selector); + explicit platform(const DeviceSelector &device_selector) : platform(detail::device_selector(device_selector)) {} backend get_backend() const noexcept { return backend::simsycl; } @@ -54,10 +55,15 @@ class platform final : public detail::reference_type get_platforms(); private: + template + friend class detail::weak_ref; + friend sycl::platform simsycl::create_platform(const platform_config &config); friend device simsycl::create_device(platform &platform, const device_config &config); platform(detail::platform_state state); + platform(const detail::device_selector &selector); + platform(std::shared_ptr &&state); void add_device(const device &dev); }; diff --git a/include/simsycl/sycl/queue.hh b/include/simsycl/sycl/queue.hh index 354a8bc..09f727f 100644 --- a/include/simsycl/sycl/queue.hh +++ b/include/simsycl/sycl/queue.hh @@ -1,9 +1,8 @@ #pragma once +#include "async_handler.hh" #include "event.hh" -#include "exception.hh" #include "handler.hh" -#include "info.hh" #include "property.hh" #include "../detail/reference_type.hh" @@ -32,12 +31,7 @@ struct is_property_of : std::true_type {}; namespace simsycl::detail { -struct queue_state { - sycl::async_handler async_handler; - - queue_state() : async_handler([](sycl::exception_list) {}) {} - queue_state(sycl::async_handler async_handler) : async_handler(std::move(async_handler)) {} -}; +struct queue_state; } // namespace simsycl::detail @@ -51,18 +45,18 @@ class queue final : public detail::reference_type, property::queue::enable_profiling, property::queue::in_order>; public: - explicit queue(const property_list &prop_list = {}) - : reference_type(std::in_place), property_interface(prop_list, property_compatibility()) {} + explicit queue(const property_list &prop_list = {}); - explicit queue(const async_handler &async_handler, const property_list &prop_list = {}) - : reference_type(std::in_place, async_handler), property_interface(prop_list, property_compatibility()) {} + explicit queue(const async_handler &async_handler, const property_list &prop_list = {}); template - explicit queue(const DeviceSelector &device_selector, const property_list &prop_list = {}); + explicit queue(const DeviceSelector &device_selector, const property_list &prop_list = {}) + : queue(internal, detail::device_selector(device_selector), async_handler{}, prop_list) {} template explicit queue( - const DeviceSelector &device_selector, const async_handler &async_handler, const property_list &prop_list = {}); + const DeviceSelector &device_selector, const async_handler &async_handler, const property_list &prop_list = {}) + : queue(internal, detail::device_selector(device_selector), async_handler, prop_list) {} explicit queue(const device &sycl_device, const property_list &prop_list = {}); @@ -90,14 +84,10 @@ class queue final : public detail::reference_type, bool is_in_order() const { return has_property(); } template - typename Param::return_type get_info() const { - return {}; - } + typename Param::return_type get_info() const; template - typename Param::return_type get_backend_info() const { - return {}; - } + typename Param::return_type get_backend_info() const; template event submit(T cgf) { @@ -292,6 +282,9 @@ class queue final : public detail::reference_type, // Explicit copy functions +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // access::placeholder + template event copy(accessor src, std::shared_ptr dest); @@ -318,6 +311,21 @@ class queue final : public detail::reference_type, template event fill(accessor dest, const T &src); + +#pragma GCC diagnostic pop + + private: + struct internal_t { + } inline static constexpr internal{}; + + explicit queue(internal_t /* tag */, const detail::device_selector &selector, const async_handler &async_handler, + const property_list &prop_list); + + explicit queue(internal_t /* tag */, const device &sycl_device, + const async_handler &async_handler, const property_list &prop_list); + + explicit queue(internal_t /* tag */, const context &sycl_context, const device &sycl_device, + const async_handler &async_handler, const property_list &prop_list); }; } // namespace simsycl::sycl diff --git a/include/simsycl/system.hh b/include/simsycl/system.hh index dcba75a..32fc9ca 100644 --- a/include/simsycl/system.hh +++ b/include/simsycl/system.hh @@ -79,7 +79,6 @@ struct device_config { bool queue_profiling{}; std::vector built_in_kernels{}; std::vector built_in_kernel_ids{}; - sycl::platform platform{}; std::string name{}; std::string vendor{}; std::string driver_version{}; @@ -90,7 +89,7 @@ struct device_config { std::vector extensions{}; size_t printf_buffer_size{}; bool preferred_interop_user_sync{}; - sycl::device parent_device{}; + std::optional parent_device{}; uint32_t partition_max_sub_devices{}; std::vector partition_properties{}; std::vector partition_affinity_domains{}; @@ -110,24 +109,13 @@ struct system_config { std::vector devices{}; }; -extern system_config system; +const system_config &get_system(); +void set_system(system_config system); } // namespace simsycl namespace simsycl::detail { -template -sycl::device select_device(const DeviceSelector &selector) { - SIMSYCL_CHECK(!system.devices.empty()); - int max_rating = INT_MIN; - for(const auto &device : system.devices) { - if(int rating = selector(device); rating > max_rating) { max_rating = rating; } - } - if(max_rating < 0) { throw sycl::exception(sycl::errc::runtime, "No suitable device found"); } - const auto device = std::find_if(system.devices.begin(), system.devices.end(), - [&](const auto &device) { return selector(device) == max_rating; }); - assert(device != system.devices.end()); - return *device; -} +sycl::device select_device(const device_selector &selector); } // namespace simsycl::detail diff --git a/src/simsycl/context.cc b/src/simsycl/context.cc index 64ac16b..f333fd0 100644 --- a/src/simsycl/context.cc +++ b/src/simsycl/context.cc @@ -1,8 +1,112 @@ #include "simsycl/sycl/context.hh" +#include "simsycl/sycl/device.hh" +#include "simsycl/sycl/info.hh" +#include "simsycl/sycl/platform.hh" namespace simsycl::detail { -struct context_state {}; +template +typename Info::return_type common_capabilities(const std::vector &devices) { + SIMSYCL_CHECK(!devices.empty()); // TODO throw instead + auto common_caps = devices[0].get_info(); + for(size_t i = 1; i < devices.size(); ++i) { + const auto caps = devices[i].get_info(); + const auto last = std::remove_if(common_caps.begin(), common_caps.end(), + [&](const auto c) { return std::find(caps.begin(), caps.end(), c) == caps.end(); }); + common_caps.erase(last, common_caps.end()); + } + return common_caps; +} + +struct context_state { + sycl::platform platform; + std::vector devices; + sycl::async_handler async_handler; + + std::vector atomic_memory_order_capabilities; + std::vector atomic_fence_order_capabilities; + std::vector atomic_memory_scope_capabilities; + std::vector atomic_fence_scope_capabilities; + + context_state(const sycl::platform &platform, const std::vector &devices, + const sycl::async_handler &async_handler) + : platform(platform), devices(devices), async_handler(async_handler), + atomic_memory_order_capabilities( + common_capabilities(devices)), + atomic_fence_order_capabilities( + common_capabilities(devices)), + atomic_memory_scope_capabilities( + common_capabilities(devices)), + atomic_fence_scope_capabilities( + common_capabilities(devices)) {} +}; + +sycl::platform get_common_platform(const std::vector &devices) { + SIMSYCL_CHECK(!devices.empty()); // TODO throw instead + const auto common = devices[0].get_platform(); + for(size_t i = 1; i < devices.size(); ++i) { SIMSYCL_CHECK(devices[i].get_platform() == common); } + return common; +} } // namespace simsycl::detail + + +namespace simsycl::sycl { + +context::context(internal_t /* tag */, const std::vector &devices, const async_handler &async_handler, + const property_list &prop_list) + : reference_type(std::in_place, get_common_platform(devices), devices, async_handler), + property_interface(prop_list, property_compatibility{}) {} + +context::context(const property_list &prop_list) : context(internal, {}, {}, prop_list) {} + +context::context(async_handler async_handler, const property_list &prop_list) + : context(internal, {}, async_handler, prop_list) {} + +context::context(const device &dev, const property_list &prop_list) : context(internal, {dev}, {}, prop_list) {} + +context::context(const device &dev, async_handler async_handler, const property_list &prop_list) + : context(internal, {dev}, async_handler, prop_list) {} + +context::context(const std::vector &device_list, const property_list &prop_list) + : context(internal, device_list, {}, prop_list) {} + +context::context(const std::vector &device_list, async_handler async_handler, const property_list &prop_list) + : context(internal, device_list, async_handler, prop_list) {} + +template<> +platform context::get_info() const { + return state().platform; +} + +template<> +std::vector context::get_info() const { + return state().devices; +} + +template<> +std::vector context::get_info() const { + return state().atomic_memory_order_capabilities; +} + +template<> +std::vector context::get_info() const { + return state().atomic_fence_order_capabilities; +} + +template<> +std::vector context::get_info() const { + return state().atomic_memory_scope_capabilities; +} + +template<> +std::vector context::get_info() const { + return state().atomic_fence_scope_capabilities; +} + +platform context::get_platform() const { return get_info(); } + +std::vector context::get_devices() const { return state().devices; } + +} // namespace simsycl::sycl diff --git a/src/simsycl/device.cc b/src/simsycl/device.cc index 33b7c22..6192cb9 100644 --- a/src/simsycl/device.cc +++ b/src/simsycl/device.cc @@ -7,8 +7,19 @@ namespace simsycl::detail { struct device_state { device_config config; + weak_ref platform; }; +int default_selector::operator()(const sycl::device &device) const { + return device.is_gpu() || device.is_accelerator() ? 1 : 0; +} + +int cpu_selector::operator()(const sycl::device &device) const { return device.is_cpu() ? 0 : -1; } + +int gpu_selector ::operator()(const sycl::device &device) const { return device.is_gpu() ? 0 : -1; } + +int accelerator_selector::operator()(const sycl::device &device) const { return device.is_accelerator() ? 0 : -1; } + } // namespace simsycl::detail namespace simsycl::sycl { @@ -17,8 +28,7 @@ device::device(detail::device_state state) : reference_type(std::in_place, std:: device::device() : device(default_selector_v) {} -template -device::device(const DeviceSelector &device_selector) : device(detail::select_device(device_selector)) {} +device::device(const detail::device_selector &device_selector) : device(detail::select_device(device_selector)) {} template<> info::device_type device::get_info() const { @@ -365,7 +375,7 @@ std::vector device::get_info template<> sycl::platform device::get_info() const { - return state().config.platform; + return state().platform.lock(); } template<> @@ -423,7 +433,7 @@ bool device::get_info() const { template<> sycl::device device::get_info() const { - return state().config.parent_device; + return state().config.parent_device.value(); } template<> @@ -463,6 +473,7 @@ bool device::has(aspect asp) const { } std::vector device::get_devices(info::device_type type) { + auto &system = get_system(); std::vector result; std::copy_if(system.devices.begin(), system.devices.end(), std::back_inserter(result), [type](const device &dev) { return dev.get_info() == type; }); @@ -477,7 +488,7 @@ namespace simsycl { sycl::device create_device(sycl::platform &platform, const device_config &config) { detail::device_state state; state.config = config; - state.config.platform = platform; + state.platform = platform.weak_ref(); sycl::device device(state); platform.add_device(device); return device; diff --git a/src/simsycl/platform.cc b/src/simsycl/platform.cc index d9544a5..6a1095f 100644 --- a/src/simsycl/platform.cc +++ b/src/simsycl/platform.cc @@ -1,4 +1,5 @@ #include "simsycl/sycl/platform.hh" +#include "simsycl/sycl/device.hh" #include "simsycl/system.hh" #include @@ -19,8 +20,10 @@ platform::platform(detail::platform_state state) : reference_type(std::in_place, platform::platform() : platform(default_selector_v) {} -template -platform::platform(const DeviceSelector &device_selector) : platform(select_device(device_selector).get_platform()) {} +platform::platform(const detail::device_selector &selector) + : platform(detail::select_device(selector).get_platform()) {} + +platform::platform(std::shared_ptr &&state) : reference_type(std::move(state)) {} std::vector platform::get_devices(info::device_type type) const { std::vector result; @@ -62,7 +65,7 @@ bool platform::has_extension(const std::string &extension) const { != state().config.extensions.end(); } -std::vector platform::get_platforms() { return system.platforms; } +std::vector platform::get_platforms() { return get_system().platforms; } void platform::add_device(const device &dev) { state().devices.push_back(dev); } diff --git a/src/simsycl/queue.cc b/src/simsycl/queue.cc new file mode 100644 index 0000000..45b6288 --- /dev/null +++ b/src/simsycl/queue.cc @@ -0,0 +1,87 @@ +#include "simsycl/sycl/queue.hh" +#include "simsycl/sycl/context.hh" +#include "simsycl/sycl/device.hh" +#include "simsycl/sycl/info.hh" + +#include "simsycl/system.hh" + + +namespace simsycl::detail { + +struct queue_state { + sycl::device device; + sycl::context context; + sycl::async_handler async_handler; + + queue_state(const device_selector &selector, const sycl::async_handler &async_handler) + : device(select_device(selector)), context(device, async_handler), async_handler(async_handler) {} + + queue_state(const sycl::device &device, const sycl::async_handler &async_handler) + : device(device), context(device, async_handler), async_handler(async_handler) {} + + queue_state(const sycl::device &device, const sycl::context &context, const sycl::async_handler &async_handler) + : device(device), context(context), async_handler(async_handler) {} +}; + +} // namespace simsycl::detail + +namespace simsycl::sycl { + +queue::queue(internal_t /* tag */, const detail::device_selector &selector, const async_handler &async_handler, + const property_list &prop_list) + : reference_type(std::in_place, selector, async_handler), property_interface(prop_list, property_compatibility()) {} + +queue::queue( + internal_t /* tag */, const device &sycl_device, const async_handler &async_handler, const property_list &prop_list) + : reference_type(std::in_place, sycl_device, async_handler), + property_interface(prop_list, property_compatibility()) {} + +queue::queue(internal_t /* tag */, const context &sycl_context, const device &sycl_device, + const async_handler &async_handler, const property_list &prop_list) + : reference_type(std::in_place, sycl_device, sycl_context, async_handler), + property_interface(prop_list, property_compatibility()) {} + +queue::queue(const property_list &prop_list) : queue(internal, default_selector_v, async_handler{}, prop_list) {} + +queue::queue(const async_handler &async_handler, const property_list &prop_list) + : queue(internal, default_selector_v, async_handler, prop_list) {} + +queue::queue(const device &sycl_device, const property_list &prop_list) + : queue(internal, sycl_device, async_handler{}, prop_list) {} + +queue::queue(const device &sycl_device, const async_handler &async_handler, const property_list &prop_list) + : queue(internal, sycl_device, async_handler, prop_list) {} + +template +queue::queue(const context &sycl_context, const DeviceSelector &device_selector, const property_list &prop_list) + : queue(internal, device_selector, async_handler{}, prop_list) {} + +template +queue::queue(const context &sycl_context, const DeviceSelector &device_selector, const async_handler &async_handler, + const property_list &prop_list) + : queue(internal, device_selector, async_handler, prop_list) {} + +queue::queue(const context &sycl_context, const device &sycl_device, const property_list &prop_list) + : queue(internal, sycl_context, sycl_device, async_handler{}, prop_list) {} + +queue::queue(const context &sycl_context, const device &sycl_device, const async_handler &async_handler, + const property_list &prop_list) + : queue(internal, sycl_context, sycl_device, async_handler, prop_list) {} + +template<> +context queue::get_info() const { + return state().context; +} + +template<> +device queue::get_info() const { + return state().device; +} + +backend queue::get_backend() const noexcept { return backend::simsycl; } + +context queue::get_context() const { return state().context; } + +device queue::get_device() const { return state().device; } + +} // namespace simsycl::sycl diff --git a/src/simsycl/system.cc b/src/simsycl/system.cc index ff989ae..9c0715b 100644 --- a/src/simsycl/system.cc +++ b/src/simsycl/system.cc @@ -4,21 +4,22 @@ #include "simsycl/templates.hh" -namespace simsycl { +namespace simsycl::detail { -system_config system = [] { - system_config system; // gpuc3 - auto platform = system.platforms.emplace_back(create_platform(simsycl::templates::platform::cuda_12_2)); - for(int i = 0; i < 4; ++i) { - system.devices.push_back(create_device(platform, simsycl::templates::device::nvidia::rtx_3090)); +sycl::device select_device(const device_selector &selector) { + auto &system = simsycl::get_system(); + SIMSYCL_CHECK(!system.devices.empty()); + int max_rating = INT_MIN; + for(const auto &device : system.devices) { + if(int rating = selector(device); rating > max_rating) { max_rating = rating; } } - return system; -}(); // IIFE - + if(max_rating < 0) { throw sycl::exception(sycl::errc::runtime, "No suitable device found"); } + const auto device = std::find_if(system.devices.begin(), system.devices.end(), + [&](const auto &device) { return selector(device) == max_rating; }); + assert(device != system.devices.end()); + return *device; } -namespace simsycl::detail { - class error_category : public std::error_category { const char *name() const noexcept override { return "sycl"; } @@ -46,6 +47,29 @@ class error_category : public std::error_category { const error_category error_category_v; +void default_async_handler(sycl::exception_list exceptions) { + fprintf(stderr, "SimSYCL default async exception handler called for\n"); + for(const auto &exception : exceptions) { + try { + std::rethrow_exception(exception); + } catch(const sycl::exception &e) { // + fprintf(stderr, " - sycl::exception: %s\n", e.what()); + } catch(const std::exception &e) { // + fprintf(stderr, " - std::exception: %s\n", e.what()); + } catch(...) { // + fprintf(stderr, " - unknown exception\n"); + } + } + fprintf(stderr, "terminating.\n"); + std::terminate(); +} + +void call_async_handler(const sycl::async_handler &handler_opt, sycl::exception_list exceptions) { + handler_opt ? handler_opt(exceptions) : default_async_handler(exceptions); +} + +std::optional system; + } // namespace simsycl::detail namespace simsycl::sycl { @@ -55,3 +79,22 @@ std::error_code make_error_code(errc e) noexcept { return {static_cast(e), const std::error_category &sycl_category() noexcept { return detail::error_category_v; } } // namespace simsycl::sycl + +namespace simsycl { + +const system_config &get_system() { + if(!detail::system.has_value()) { + auto &system = detail::system.emplace(); // gpuc3 + auto platform = system.platforms.emplace_back(create_platform(simsycl::templates::platform::cuda_12_2)); + for(int i = 0; i < 4; ++i) { + system.devices.push_back(create_device(platform, simsycl::templates::device::nvidia::rtx_3090)); + } + } + return *detail::system; +} + +void set_system(system_config system) { + detail::system = std::move(system); +} + +} // namespace simsycl