From ad32adaaf2b7f7c8d2935cb0d23e024adda00e6a Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Sat, 19 Jun 2021 19:05:52 +0300 Subject: [PATCH 01/24] Initial argument handling implementation --- sycl/include/CL/sycl/detail/common.hpp | 3 + sycl/include/CL/sycl/detail/pi.hpp | 2 + sycl/include/CL/sycl/detail/pi_api_id.hpp | 56 ++ sycl/source/detail/pi.cpp | 10 + sycl/source/detail/plugin.hpp | 74 +++ sycl/tools/CMakeLists.txt | 1 + sycl/tools/pi-trace/CMakeLists.txt | 14 + sycl/tools/pi-trace/pi_trace.cpp | 73 +++ sycl/tools/xpti_helpers/pi_args.hpp | 517 ++++++++++++++++++ .../xpti_helpers/pi_arguments_handler.hpp | 46 ++ sycl/tools/xpti_helpers/tuple_view.hpp | 73 +++ xpti/include/xpti_data_types.h | 9 + xptifw/src/xpti_trace_framework.cpp | 6 +- 13 files changed, 883 insertions(+), 1 deletion(-) create mode 100644 sycl/include/CL/sycl/detail/pi_api_id.hpp create mode 100644 sycl/tools/pi-trace/CMakeLists.txt create mode 100644 sycl/tools/pi-trace/pi_trace.cpp create mode 100644 sycl/tools/xpti_helpers/pi_args.hpp create mode 100644 sycl/tools/xpti_helpers/pi_arguments_handler.hpp create mode 100644 sycl/tools/xpti_helpers/tuple_view.hpp diff --git a/sycl/include/CL/sycl/detail/common.hpp b/sycl/include/CL/sycl/detail/common.hpp index 67eedca888f15..166f84cc4dbc9 100644 --- a/sycl/include/CL/sycl/detail/common.hpp +++ b/sycl/include/CL/sycl/detail/common.hpp @@ -31,6 +31,9 @@ namespace detail { constexpr const char *SYCL_STREAM_NAME = "sycl"; // Stream name being used for traces generated from the SYCL plugin layer constexpr const char *SYCL_PICALL_STREAM_NAME = "sycl.pi"; +// Stream name being used for traces generated from PI calls. This stream +// contains information about function arguments. +constexpr const char *SYCL_PIARGCALL_STREAM_NAME = "sycl.pi.arg"; // Data structure that captures the user code location information using the // builtin capabilities of the compiler struct code_location { diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index 3b82ff2bc658d..78da0edb482cb 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -391,3 +391,5 @@ namespace RT = cl::sycl::detail::pi; } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) + +#undef _PI_API diff --git a/sycl/include/CL/sycl/detail/pi_api_id.hpp b/sycl/include/CL/sycl/detail/pi_api_id.hpp new file mode 100644 index 0000000000000..481b2085c5db9 --- /dev/null +++ b/sycl/include/CL/sycl/detail/pi_api_id.hpp @@ -0,0 +1,56 @@ +//==---------- pi_api_id.hpp - PI API function IDs -------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +/// \file pi_api_id.hpp +/// This file contains mapping between PI API functions and their IDs. A hash +/// function is used to generate IDs. The reason for usage of a hash function +/// instead of raw values of PiApiKind is ABI stability. New functions can be +/// added to PiApiKind, and there's no reliable way for external XPTI users to +/// know when to update the values. Hashes are calculated from API function +/// name, so it will remain the same after update to pi.def. +/// +/// \ingroup sycl_pi + +#pragma once + +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace detail { +constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { + uint32_t Res = Base; + for (uint32_t I = 1; I < Pow; I++) + Res *= Base; + return Res; +} + +constexpr uint32_t cxhash(const char *Str) { + constexpr uint32_t p = 53; + constexpr uint32_t m = 1051; + uint32_t Hash = 0; + uint32_t Len = 0; + while (Str[Len++] != '\0') + Hash += Str[Len - 1] * cxpow(p, Len - 1); + return Hash % m; +} + +template struct PiApiID {}; + +#define _PI_API(api) \ + template <> struct PiApiID { \ + static constexpr uint32_t id = cxhash(#api); \ + static constexpr auto name = #api; \ + }; + +#include + +#undef _PI_API +} // namespace detail +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index fc7ede340d616..f2dba17049514 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -46,6 +46,8 @@ namespace detail { xpti_td *GSYCLGraphEvent = nullptr; /// Event to be used by PI layer related activities xpti_td *GPICallEvent = nullptr; +/// Event to be used by PI layer calls with arguments +xpti_td *GPIArgCallEvent = nullptr; /// Constants being used as placeholder until one is able to reliably get the /// version of the SYCL runtime constexpr uint32_t GMajVer = 1; @@ -419,6 +421,14 @@ static void initializePlugins(vector_class *Plugins) { GPICallEvent = xptiMakeEvent("PI Layer", &PIPayload, xpti::trace_algorithm_event, xpti_at::active, &PiInstanceNo); + + xptiInitialize(SYCL_PIARGCALL_STREAM_NAME, GMajVer, GMinVer, GVerStr); + xpti::payload_t PIArgPayload( + "Plugin Interface Layer (with function arguments)"); + uint64_t PiArgInstanceNo; + GPIArgCallEvent = xptiMakeEvent("PI Layer with arguments", &PIArgPayload, + xpti::trace_algorithm_event, xpti_at::active, + &PiArgInstanceNo); #endif } diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 3480ac81f643e..ef4efd9ba492e 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,76 @@ namespace sycl { namespace detail { #ifdef XPTI_ENABLE_INSTRUMENTATION extern xpti::trace_event_data_t *GPICallEvent; +extern xpti::trace_event_data_t *GPIArgCallEvent; #endif + +template struct total_size; + +template struct total_size { + static constexpr size_t value = sizeof(T); +}; + +template struct total_size { + static constexpr size_t value = sizeof(T) + total_size::value; +}; + +template struct array_fill_helper; + +template struct array_fill_helper { + static void fill(unsigned char *Dst, size_t Offset, T &Arg) { + auto *Begin = reinterpret_cast(&Arg); + auto *End = Begin + sizeof(T); + std::uninitialized_copy(Begin, End, Dst + Offset); + } +}; + +template struct array_fill_helper { + static void fill(unsigned char *Dst, size_t Offset, T &Arg, Args &...Rest) { + auto *Begin = reinterpret_cast(&Arg); + auto *End = Begin + sizeof(T); + std::uninitialized_copy(Begin, End, Dst + Offset); + array_fill_helper::fill(Dst, Offset + sizeof(T), Rest...); + } +}; + +template +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &...Args) { + uint64_t CorrelationID = 0; +#ifdef XPTI_ENABLE_INSTRUMENTATION + if (xptiTraceEnabled()) { + uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + CorrelationID = xptiGetUniqueId(); + + std::array::value> ArgsData; + array_fill_helper::fill(ArgsData.data(), 0, Args...); + + xpti::function_with_args_t Payload{FuncID, ArgsData.data(), nullptr, + nullptr}; + + xptiNotifySubscribers( + StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin, + GPIArgCallEvent, nullptr, CorrelationID, &Payload); + } +#endif + return CorrelationID; +} + +template +void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, + pi_result Result) { +#ifdef XPTI_ENABLE_INSTRUMENTATION + if (xptiTraceEnabled()) { + uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + + xpti::function_with_args_t Payload{FuncID, nullptr, &Result, nullptr}; + + xptiNotifySubscribers( + StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, + GPIArgCallEvent, nullptr, CorrelationID, &Payload); + } +#endif +} + /// The plugin class provides a unified interface to the underlying low-level /// runtimes for the device-agnostic SYCL runtime. /// @@ -75,6 +145,8 @@ class plugin { // the per_instance_user_data field. std::string PIFnName = PiCallInfo.getFuncName(); uint64_t CorrelationID = pi::emitFunctionBeginTrace(PIFnName.c_str()); + uint64_t CorrelationIDWithArgs = + emitFunctionWithArgsBeginTrace(PiApiID::id, Args...); #endif RT::PiResult R; if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) { @@ -93,6 +165,8 @@ class plugin { #ifdef XPTI_ENABLE_INSTRUMENTATION // Close the function begin with a call to function end pi::emitFunctionEndTrace(CorrelationID, PIFnName.c_str()); + emitFunctionWithArgsEndTrace(CorrelationIDWithArgs, + PiApiID::id, R); #endif return R; } diff --git a/sycl/tools/CMakeLists.txt b/sycl/tools/CMakeLists.txt index eb724c70a5c58..cba01f1d62630 100644 --- a/sycl/tools/CMakeLists.txt +++ b/sycl/tools/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(sycl-ls) +add_subdirectory(pi-trace) # TODO: move each tool in its own sub-directory add_executable(get_device_count_by_type get_device_count_by_type.cpp) diff --git a/sycl/tools/pi-trace/CMakeLists.txt b/sycl/tools/pi-trace/CMakeLists.txt new file mode 100644 index 0000000000000..5e81d6ee6a3d1 --- /dev/null +++ b/sycl/tools/pi-trace/CMakeLists.txt @@ -0,0 +1,14 @@ +add_library(pi_trace SHARED pi_trace.cpp) +target_link_libraries(pi_trace PRIVATE xptifw) +target_include_directories(pi_trace PRIVATE "${XPTI_SOURCE_DIR}/include") +target_include_directories(pi_trace PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../xpti_helpers/") +target_include_directories(pi_trace PRIVATE "${sycl_inc_dir}") +target_include_directories(pi_trace PRIVATE "${sycl_src_dir}") + +if(UNIX) + target_link_libraries(pi_trace PRIVATE dl) +endif() + +if (XPTI_ENABLE_TBB) + target_link_libraries(pi_trace PRIVATE tbb) +endif() diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp new file mode 100644 index 0000000000000..f1b0aa054c880 --- /dev/null +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -0,0 +1,73 @@ +#include "xpti_trace_framework.h" + +#include "pi_arguments_handler.hpp" + +#include + +#include +#include +#include +#include + +static uint8_t GStreamID = 0; +std::mutex GIOMutex; + +sycl::xpti_helpers::PiArgumentsHandler ArgHandler; + +// The lone callback function we are going to use to demonstrate how to attach +// the collector to the running executable +XPTI_CALLBACK_API void tpCallback(uint16_t trace_type, + xpti::trace_event_data_t *parent, + xpti::trace_event_data_t *event, + uint64_t instance, const void *user_data); + +// Based on the documentation, every subscriber MUST implement the +// xptiTraceInit() and xptiTraceFinish() APIs for their subscriber collector to +// be loaded successfully. +XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, + unsigned int minor_version, + const char *version_str, + const char *stream_name) { + if (std::string_view(stream_name) == "sycl.pi.arg") { + GStreamID = xptiRegisterStream(stream_name); + xptiRegisterCallback( + GStreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin, + tpCallback); + xptiRegisterCallback( + GStreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, + tpCallback); + +#define _PI_API(api) \ + ArgHandler.set##_##api([](auto &&...Args) { \ + std::cout << "--->" << #api << "(" \ + << "\n"; \ + sycl::detail::pi::printArgs(Args...); \ + std::cout << ")\n"; \ + }); +#include +#undef _PI_API + ArgHandler.set_piProgramBuild([](auto &&...) {}); + ArgHandler.set_piEnqueueMemBufferRead([](auto &&...) {}); + ArgHandler.set_piEventsWait([](auto &&...) {}); + } +} + +XPTI_CALLBACK_API void xptiTraceFinish(const char *stream_name) { + // NOP +} + +XPTI_CALLBACK_API void tpCallback(uint16_t TraceType, + xpti::trace_event_data_t *Parent, + xpti::trace_event_data_t *Event, + uint64_t Instance, const void *UserData) { + auto Type = static_cast(TraceType); + if (Type == xpti::trace_point_type_t::function_with_args_begin) { + // Lock while we print information + std::lock_guard Lock(GIOMutex); + + const auto *Data = + static_cast(UserData); + + ArgHandler.handle(Data->function_id, Data->args_data); + } +} diff --git a/sycl/tools/xpti_helpers/pi_args.hpp b/sycl/tools/xpti_helpers/pi_args.hpp new file mode 100644 index 0000000000000..04275b6a218f4 --- /dev/null +++ b/sycl/tools/xpti_helpers/pi_args.hpp @@ -0,0 +1,517 @@ +#pragma once + +#include "tuple_view.hpp" +#include +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace xpti_helpers { +template struct PiApiArgTuple; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> +struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = + tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; + +template <> struct PiApiArgTuple { + using type = tuple_view; +}; +} // namespace xpti_helpers +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp new file mode 100644 index 0000000000000..95ed5eed7340c --- /dev/null +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "pi_args.hpp" +#include +#include + +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace xpti_helpers { +class PiArgumentsHandler { +public: + void handle(uint32_t ID, void *ArgsData) { +#define _PI_API(api) \ + if (ID == sycl::detail::PiApiID::id) { \ + MHandler##_##api(ArgsData); \ + return; \ + } +#include +#undef _PI_API + } + +#define _PI_API(api) \ + void set##_##api( \ + const typename as_function< \ + void, typename PiApiArgTuple::type>::type \ + &Handler) { \ + MHandler##_##api = [Handler](void *Data) { \ + typename PiApiArgTuple::type TV{ \ + static_cast(Data)}; \ + xpti_helpers::apply(Handler, TV); \ + }; \ + } +#include +#undef _PI_API + +private: +#define _PI_API(api) \ + std::function MHandler##_##api = [](void *) {}; +#include +#undef _PI_API +}; +} // namespace xpti_helpers +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/tools/xpti_helpers/tuple_view.hpp b/sycl/tools/xpti_helpers/tuple_view.hpp new file mode 100644 index 0000000000000..6d612cc57dd57 --- /dev/null +++ b/sycl/tools/xpti_helpers/tuple_view.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include + +#include +#include + +__SYCL_INLINE_NAMESPACE(cl) { +namespace sycl { +namespace xpti_helpers { +template struct tuple_view { unsigned char *data; }; + +template struct tuple_view_element; + +template +struct tuple_view_element> + : tuple_view_element> {}; + +template +struct tuple_view_element<0, tuple_view> { + using type = Head; +}; + +template struct tuple_view_offset; + +template +struct tuple_view_offset> { + static constexpr size_t value = + sizeof(typename tuple_view_element>::type) + + tuple_view_offset>::value; +}; + +template +struct tuple_view_offset<0, tuple_view> { + static constexpr size_t value = 0; +}; + +template +typename tuple_view_element>::type +get(tuple_view &t) { + return *reinterpret_cast>::type>>( + t.data + tuple_view_offset>::value); +} + +template struct tuple_view_size {}; + +template +struct tuple_view_size> + : std::integral_constant {}; + +template +decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence) { + return std::invoke(std::forward(f), + xpti_helpers::get(std::forward(t))...); +} + +template decltype(auto) apply(F &&f, Tuple &&t) { + return apply_impl( + std::forward(f), std::forward(t), + std::make_index_sequence< + tuple_view_size>::value>{}); +} + +template struct as_function; + +template struct as_function> { + using type = std::function; +}; + +} // namespace xpti_helpers +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/xpti/include/xpti_data_types.h b/xpti/include/xpti_data_types.h index 7ed10832bb7c6..0851ce301241e 100644 --- a/xpti/include/xpti_data_types.h +++ b/xpti/include/xpti_data_types.h @@ -162,6 +162,13 @@ struct payload_t { } }; +struct function_with_args_t { + uint32_t function_id; + void *args_data; + void *ret_data; + void *user_data; +}; + /// @brief Enumerator defining the global/basic trace point types /// @details The frame work defines the global/basic trace point types /// that are necessary for modeling parallel runtimes. A helper macro @@ -257,6 +264,8 @@ enum class trace_point_type_t : uint16_t { metadata = XPTI_TRACE_POINT_BEGIN(13), /// Indicates that the trace point is user defined and only the tool defined /// for a stream will be able to handle it + function_with_args_begin = XPTI_TRACE_POINT_BEGIN(14), + function_with_args_end = XPTI_TRACE_POINT_END(15), user_defined = 1 << 7 }; diff --git a/xptifw/src/xpti_trace_framework.cpp b/xptifw/src/xpti_trace_framework.cpp index 6dae0dbe81c28..9f7fef6070717 100644 --- a/xptifw/src/xpti_trace_framework.cpp +++ b/xptifw/src/xpti_trace_framework.cpp @@ -1028,7 +1028,11 @@ class Framework { // to trace function calls without too much effort. if (!(UserData && (TraceType == (uint16_t)trace_point_type_t::function_begin || - TraceType == (uint16_t)trace_point_type_t::function_end))) { + TraceType == (uint16_t)trace_point_type_t::function_end || + TraceType == + (uint16_t)trace_point_type_t::function_with_args_begin || + TraceType == + (uint16_t)trace_point_type_t::function_with_args_end))) { return xpti::result_t::XPTI_RESULT_INVALIDARG; } } From 81a134e6bbb39b0edb7f8ca269d9d2fdcf3252d8 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:15:02 +0300 Subject: [PATCH 02/24] A bit refined implementation --- .../CL/sycl/detail/pi_args_helper.hpp} | 253 ++++++++++-------- sycl/source/detail/plugin.hpp | 56 ++-- sycl/tools/pi-trace/CMakeLists.txt | 2 + sycl/tools/pi-trace/pi_trace.cpp | 4 +- .../xpti_helpers/pi_arguments_handler.hpp | 36 ++- sycl/tools/xpti_helpers/tuple_view.hpp | 25 +- xpti/include/xpti_data_types.h | 13 +- 7 files changed, 242 insertions(+), 147 deletions(-) rename sycl/{tools/xpti_helpers/pi_args.hpp => include/CL/sycl/detail/pi_args_helper.hpp} (61%) diff --git a/sycl/tools/xpti_helpers/pi_args.hpp b/sycl/include/CL/sycl/detail/pi_args_helper.hpp similarity index 61% rename from sycl/tools/xpti_helpers/pi_args.hpp rename to sycl/include/CL/sycl/detail/pi_args_helper.hpp index 04275b6a218f4..6cd43a83c0bf4 100644 --- a/sycl/tools/xpti_helpers/pi_args.hpp +++ b/sycl/include/CL/sycl/detail/pi_args_helper.hpp @@ -1,384 +1,408 @@ +//==---------- pi_args_helper.hpp - PI call arguments helper ---------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +/// \file pi_args_helper.hpp +/// Utilities to enable PI call arguments packing for XPTI. +/// +/// C++ wrapper for PI does not take real function argument type into account. +/// As a result, when Plugin.call<>() is invoked, there might be type mismatch +/// between deduced type and real call argument type (e.g. when there's +/// std::vector::size() or an integer literal in call expression). This leads to +/// unstable data exchange format between SYCL runtime and XPTI. To workaround +/// the problem, SYCL runtime must explicitly cast template-deduced types to +/// real types before packing arguments for XPTI. This file contains mappings +/// between PiApiKind and tuples of argument types. +/// +/// \ingroup sycl_pi + #pragma once -#include "tuple_view.hpp" #include #include +#include + __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { -namespace xpti_helpers { -template struct PiApiArgTuple; +namespace detail { +template struct PiApiArgTuple; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; @@ -386,132 +410,131 @@ struct PiApiArgTuple { template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { - using type = - tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; }; template <> struct PiApiArgTuple { using type = - tuple_view; + std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; template <> struct PiApiArgTuple { - using type = tuple_view; + using type = std::tuple; }; -} // namespace xpti_helpers +} // namespace detail } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index ef4efd9ba492e..4ab5bae6cb662 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -11,10 +11,12 @@ #include #include #include +#include #include #include #include #include +#include #ifdef XPTI_ENABLE_INSTRUMENTATION // Include the headers necessary for emitting traces using the trace framework @@ -39,35 +41,56 @@ template struct total_size { static constexpr size_t value = sizeof(T) + total_size::value; }; -template struct array_fill_helper; - -template struct array_fill_helper { - static void fill(unsigned char *Dst, size_t Offset, T &Arg) { - auto *Begin = reinterpret_cast(&Arg); - auto *End = Begin + sizeof(T); +template +struct array_fill_helper; + +template +struct array_fill_helper { + static void fill(unsigned char *Dst, size_t Offset, T &&Arg) { + using ArgsTuple = typename PiApiArgTuple::type; + // C-style cast is required here. + auto RealArg = (typename std::tuple_element::type)(Arg); + auto *Begin = reinterpret_cast(&RealArg); + auto *End = Begin + sizeof(decltype(RealArg)); std::uninitialized_copy(Begin, End, Dst + Offset); } }; -template struct array_fill_helper { - static void fill(unsigned char *Dst, size_t Offset, T &Arg, Args &...Rest) { - auto *Begin = reinterpret_cast(&Arg); - auto *End = Begin + sizeof(T); +template +struct array_fill_helper { + static void fill(unsigned char *Dst, size_t Offset, const T &&Arg, + Args &&...Rest) { + using ArgsTuple = typename PiApiArgTuple::type; + // C-style cast is required here. + auto RealArg = (typename std::tuple_element::type)(Arg); + auto *Begin = reinterpret_cast(&RealArg); + auto *End = Begin + sizeof(decltype(RealArg)); std::uninitialized_copy(Begin, End, Dst + Offset); - array_fill_helper::fill(Dst, Offset + sizeof(T), Rest...); + array_fill_helper::fill( + Dst, Offset + sizeof(decltype(RealArg)), std::forward(Rest)...); } }; -template -uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &...Args) { +template +constexpr size_t totalSize(const std::tuple &) { + return (sizeof(Ts) + ...); +} + +template +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&...Args) { uint64_t CorrelationID = 0; #ifdef XPTI_ENABLE_INSTRUMENTATION if (xptiTraceEnabled()) { uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); CorrelationID = xptiGetUniqueId(); - std::array::value> ArgsData; - array_fill_helper::fill(ArgsData.data(), 0, Args...); + using ArgsTuple = typename PiApiArgTuple::type; + + constexpr size_t TotalSize = totalSize(ArgsTuple{}); + + std::array ArgsData; + array_fill_helper::fill(ArgsData.data(), 0, + std::forward(Args)...); xpti::function_with_args_t Payload{FuncID, ArgsData.data(), nullptr, nullptr}; @@ -146,7 +169,8 @@ class plugin { std::string PIFnName = PiCallInfo.getFuncName(); uint64_t CorrelationID = pi::emitFunctionBeginTrace(PIFnName.c_str()); uint64_t CorrelationIDWithArgs = - emitFunctionWithArgsBeginTrace(PiApiID::id, Args...); + emitFunctionWithArgsBeginTrace( + PiApiID::id, std::forward(Args)...); #endif RT::PiResult R; if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) { diff --git a/sycl/tools/pi-trace/CMakeLists.txt b/sycl/tools/pi-trace/CMakeLists.txt index 5e81d6ee6a3d1..fb75398edc7f0 100644 --- a/sycl/tools/pi-trace/CMakeLists.txt +++ b/sycl/tools/pi-trace/CMakeLists.txt @@ -5,6 +5,8 @@ target_include_directories(pi_trace PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../xpti target_include_directories(pi_trace PRIVATE "${sycl_inc_dir}") target_include_directories(pi_trace PRIVATE "${sycl_src_dir}") +target_compile_options(pi_trace PRIVATE -g -O0) + if(UNIX) target_link_libraries(pi_trace PRIVATE dl) endif() diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index f1b0aa054c880..19b8c24c20267 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -8,6 +8,7 @@ #include #include #include +#include static uint8_t GStreamID = 0; std::mutex GIOMutex; @@ -46,9 +47,6 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, }); #include #undef _PI_API - ArgHandler.set_piProgramBuild([](auto &&...) {}); - ArgHandler.set_piEnqueueMemBufferRead([](auto &&...) {}); - ArgHandler.set_piEventsWait([](auto &&...) {}); } } diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 95ed5eed7340c..3fadb485ea0e6 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -1,14 +1,37 @@ +//==---------- pi_arguments_handler.hpp - PI call arguments handler --------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #pragma once -#include "pi_args.hpp" #include #include +#include + +#include "tuple_view.hpp" #include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace xpti_helpers { +/// PiArgumentsHandler is a helper class to process incoming XPTI function call +/// events and unpack contained arguments. +/// +/// Usage: +/// +/// PiArgumentsHandler provides set_ member functions, that accept a +/// lambda with the same arguments as target PI API. Use it to set up handling +/// for particular API. By default an empty lambda is used. +/// +/// When an event is signaled, use PiArgumentsHandler::handle() member function +/// to process the incoming event and call necessary handler. +/// +/// See sycl/tools/pi-trace/ for an example. class PiArgumentsHandler { public: void handle(uint32_t ID, void *ArgsData) { @@ -23,12 +46,13 @@ class PiArgumentsHandler { #define _PI_API(api) \ void set##_##api( \ - const typename as_function< \ - void, typename PiApiArgTuple::type>::type \ - &Handler) { \ + typename as_function::type>::type \ + Handler) { \ MHandler##_##api = [Handler](void *Data) { \ - typename PiApiArgTuple::type TV{ \ - static_cast(Data)}; \ + typename as_tuple_view< \ + typename detail::PiApiArgTuple::type>::type \ + TV{static_cast(Data)}; \ xpti_helpers::apply(Handler, TV); \ }; \ } diff --git a/sycl/tools/xpti_helpers/tuple_view.hpp b/sycl/tools/xpti_helpers/tuple_view.hpp index 6d612cc57dd57..d029955f1fba3 100644 --- a/sycl/tools/xpti_helpers/tuple_view.hpp +++ b/sycl/tools/xpti_helpers/tuple_view.hpp @@ -3,6 +3,7 @@ #include #include +#include #include __SYCL_INLINE_NAMESPACE(cl) { @@ -23,15 +24,23 @@ struct tuple_view_element<0, tuple_view> { template struct tuple_view_offset; +/* template struct tuple_view_offset> { static constexpr size_t value = - sizeof(typename tuple_view_element>::type) + - tuple_view_offset>::value; + sizeof(typename tuple_view_element<0, tuple_view>::type) + + tuple_view_offset>::value; }; +*/ -template -struct tuple_view_offset<0, tuple_view> { +template +struct tuple_view_offset> { + static constexpr size_t value = + sizeof(typename tuple_view_element>::type) + + tuple_view_offset>::value; +}; + +template struct tuple_view_offset<0, tuple_view> { static constexpr size_t value = 0; }; @@ -64,10 +73,16 @@ template decltype(auto) apply(F &&f, Tuple &&t) { template struct as_function; -template struct as_function> { +template struct as_function> { using type = std::function; }; +template struct as_tuple_view; + +template struct as_tuple_view> { + using type = tuple_view; +}; + } // namespace xpti_helpers } // namespace sycl } // __SYCL_INLINE_NAMESPACE(cl) diff --git a/xpti/include/xpti_data_types.h b/xpti/include/xpti_data_types.h index 0851ce301241e..6717a092fc48d 100644 --- a/xpti/include/xpti_data_types.h +++ b/xpti/include/xpti_data_types.h @@ -162,10 +162,17 @@ struct payload_t { } }; +/// A data structure that holds information about an API function call and its +/// arguments. struct function_with_args_t { + /// A stable API function ID. It is a contract between the profiled system and + /// subscribers. uint32_t function_id; + /// Pointer to packed function arguments. void *args_data; + /// Pointer to the return value of the function. void *ret_data; + /// [Provisional] Additional data, generated by the profiled system. void *user_data; }; @@ -262,10 +269,12 @@ enum class trace_point_type_t : uint16_t { function_end = XPTI_TRACE_POINT_END(12), /// Use to notify that a new metadata entry is available for a given event metadata = XPTI_TRACE_POINT_BEGIN(13), - /// Indicates that the trace point is user defined and only the tool defined - /// for a stream will be able to handle it + /// Used to trace function call begin and its arguments. function_with_args_begin = XPTI_TRACE_POINT_BEGIN(14), + /// Used to trace function call end. function_with_args_end = XPTI_TRACE_POINT_END(15), + /// Indicates that the trace point is user defined and only the tool defined + /// for a stream will be able to handle it user_defined = 1 << 7 }; From 9b6d5a138ca4811b53038b066e9152e6c9f311d9 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:19:17 +0300 Subject: [PATCH 03/24] improved comment --- sycl/include/CL/sycl/detail/pi_api_id.hpp | 55 ++++++++++++----------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi_api_id.hpp b/sycl/include/CL/sycl/detail/pi_api_id.hpp index 481b2085c5db9..b83f7ce3ff081 100644 --- a/sycl/include/CL/sycl/detail/pi_api_id.hpp +++ b/sycl/include/CL/sycl/detail/pi_api_id.hpp @@ -23,34 +23,37 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace detail { -constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { - uint32_t Res = Base; - for (uint32_t I = 1; I < Pow; I++) - Res *= Base; - return Res; -} - -constexpr uint32_t cxhash(const char *Str) { - constexpr uint32_t p = 53; - constexpr uint32_t m = 1051; - uint32_t Hash = 0; - uint32_t Len = 0; - while (Str[Len++] != '\0') - Hash += Str[Len - 1] * cxpow(p, Len - 1); - return Hash % m; -} - -template struct PiApiID {}; - -#define _PI_API(api) \ - template <> struct PiApiID { \ - static constexpr uint32_t id = cxhash(#api); \ - static constexpr auto name = #api; \ + constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { + uint32_t Res = Base; + for (uint32_t I = 1; I < Pow; Ri++) Rres *= Base; + return Res; + } + + /// This is a simple implementation of polynomial rolling hash function. + /// + /// The general formula for the hash is Sum(s[i] * p^i) mod m. + /// Since only English characters are used for PI function names, p = 53 is + /// chosen. m = 1051 is a fairly big prime number for the task. + constexpr uint32_t cxhash(const char *Str) { + constexpr uint32_t p = 53; + constexpr uint32_t m = 1051; + uint32_t Hash = 0; + uint32_t Len = 0; + while(Str[Len++] != '\0') Hash += Str[Len - 1] * cxpow(p, Len - 1); + return Hash % m; + } + + template + struct PiApiID {}; + +#define _PI_API(api) \ + template <> struct PiApiID { \ + static constexpr uint32_t id = cxhash(#api); \ }; #include #undef _PI_API -} // namespace detail -} // namespace sycl -} // __SYCL_INLINE_NAMESPACE(cl) +} +} +} From ae4c35d99400de92ced2983d16625c7871ddfbaa Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:22:03 +0300 Subject: [PATCH 04/24] Minor cleanup --- sycl/source/detail/plugin.hpp | 12 ++---------- sycl/tools/xpti_helpers/tuple_view.hpp | 9 --------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 4ab5bae6cb662..b4725e562cd1a 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -31,16 +31,6 @@ extern xpti::trace_event_data_t *GPICallEvent; extern xpti::trace_event_data_t *GPIArgCallEvent; #endif -template struct total_size; - -template struct total_size { - static constexpr size_t value = sizeof(T); -}; - -template struct total_size { - static constexpr size_t value = sizeof(T) + total_size::value; -}; - template struct array_fill_helper; @@ -76,6 +66,7 @@ constexpr size_t totalSize(const std::tuple &) { return (sizeof(Ts) + ...); } +/// Notifies XPTI subscribers about PI function calls and packs call arguments. template uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&...Args) { uint64_t CorrelationID = 0; @@ -103,6 +94,7 @@ uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&...Args) { return CorrelationID; } +/// Notifies XPTI subscribers about PI function call result. template void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, pi_result Result) { diff --git a/sycl/tools/xpti_helpers/tuple_view.hpp b/sycl/tools/xpti_helpers/tuple_view.hpp index d029955f1fba3..fa20a572b32bf 100644 --- a/sycl/tools/xpti_helpers/tuple_view.hpp +++ b/sycl/tools/xpti_helpers/tuple_view.hpp @@ -24,15 +24,6 @@ struct tuple_view_element<0, tuple_view> { template struct tuple_view_offset; -/* -template -struct tuple_view_offset> { - static constexpr size_t value = - sizeof(typename tuple_view_element<0, tuple_view>::type) + - tuple_view_offset>::value; -}; -*/ - template struct tuple_view_offset> { static constexpr size_t value = From 0d3a58086ffde25d030f9312f383f494d67579ae Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:23:44 +0300 Subject: [PATCH 05/24] more cleanup --- sycl/tools/pi-trace/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/sycl/tools/pi-trace/CMakeLists.txt b/sycl/tools/pi-trace/CMakeLists.txt index fb75398edc7f0..5e81d6ee6a3d1 100644 --- a/sycl/tools/pi-trace/CMakeLists.txt +++ b/sycl/tools/pi-trace/CMakeLists.txt @@ -5,8 +5,6 @@ target_include_directories(pi_trace PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../xpti target_include_directories(pi_trace PRIVATE "${sycl_inc_dir}") target_include_directories(pi_trace PRIVATE "${sycl_src_dir}") -target_compile_options(pi_trace PRIVATE -g -O0) - if(UNIX) target_link_libraries(pi_trace PRIVATE dl) endif() From a5792a200d756f3df5c2fb5d5e73892d4bed46e1 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:26:42 +0300 Subject: [PATCH 06/24] more stylistic changes --- sycl/tools/xpti_helpers/tuple_view.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sycl/tools/xpti_helpers/tuple_view.hpp b/sycl/tools/xpti_helpers/tuple_view.hpp index fa20a572b32bf..08805792be8c6 100644 --- a/sycl/tools/xpti_helpers/tuple_view.hpp +++ b/sycl/tools/xpti_helpers/tuple_view.hpp @@ -1,3 +1,11 @@ +//==---------- tuple_view.hpp - Tuple View ---------------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + #pragma once #include @@ -9,6 +17,7 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace xpti_helpers { +/// A helper class to provide tuple-like access to a contiguous chunk of memory. template struct tuple_view { unsigned char *data; }; template struct tuple_view_element; From a283c03bb7da9f36655cb30ea50866f2148fabc8 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:29:32 +0300 Subject: [PATCH 07/24] more file headers --- sycl/tools/pi-trace/pi_trace.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index 19b8c24c20267..2f5213c058fd6 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -1,3 +1,15 @@ +//==----------- pi_trace.cpp.cpp -------------------------------------------==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +/// \file pi_trace.cpp +/// A sample XPTI subscriber to demonstrate how to collect PI function call +/// arguments. + #include "xpti_trace_framework.h" #include "pi_arguments_handler.hpp" From 08702b5b65ed462ec90576b002e68525e70f334d Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:30:17 +0300 Subject: [PATCH 08/24] clang-format --- sycl/include/CL/sycl/detail/pi_api_id.hpp | 59 ++++++++++++----------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi_api_id.hpp b/sycl/include/CL/sycl/detail/pi_api_id.hpp index b83f7ce3ff081..953d168b48b81 100644 --- a/sycl/include/CL/sycl/detail/pi_api_id.hpp +++ b/sycl/include/CL/sycl/detail/pi_api_id.hpp @@ -23,37 +23,38 @@ __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace detail { - constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { - uint32_t Res = Base; - for (uint32_t I = 1; I < Pow; Ri++) Rres *= Base; - return Res; - } - - /// This is a simple implementation of polynomial rolling hash function. - /// - /// The general formula for the hash is Sum(s[i] * p^i) mod m. - /// Since only English characters are used for PI function names, p = 53 is - /// chosen. m = 1051 is a fairly big prime number for the task. - constexpr uint32_t cxhash(const char *Str) { - constexpr uint32_t p = 53; - constexpr uint32_t m = 1051; - uint32_t Hash = 0; - uint32_t Len = 0; - while(Str[Len++] != '\0') Hash += Str[Len - 1] * cxpow(p, Len - 1); - return Hash % m; - } - - template - struct PiApiID {}; - -#define _PI_API(api) \ - template <> struct PiApiID { \ - static constexpr uint32_t id = cxhash(#api); \ +constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { + uint32_t Res = Base; + for (uint32_t I = 1; I < Pow; Ri++) + Rres *= Base; + return Res; +} + +/// This is a simple implementation of polynomial rolling hash function. +/// +/// The general formula for the hash is Sum(s[i] * p^i) mod m. +/// Since only English characters are used for PI function names, p = 53 is +/// chosen. m = 1051 is a fairly big prime number for the task. +constexpr uint32_t cxhash(const char *Str) { + constexpr uint32_t p = 53; + constexpr uint32_t m = 1051; + uint32_t Hash = 0; + uint32_t Len = 0; + while (Str[Len++] != '\0') + Hash += Str[Len - 1] * cxpow(p, Len - 1); + return Hash % m; +} + +template struct PiApiID {}; + +#define _PI_API(api) \ + template <> struct PiApiID { \ + static constexpr uint32_t id = cxhash(#api); \ }; #include #undef _PI_API -} -} -} +} // namespace detail +} // namespace sycl +} // __SYCL_INLINE_NAMESPACE(cl) From df846f9c917ddd3bceb5704d48df44015c7b2be6 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:30:59 +0300 Subject: [PATCH 09/24] remove unused include --- sycl/source/detail/plugin.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index b4725e562cd1a..27217c79bbdca 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -16,7 +16,6 @@ #include #include #include -#include #ifdef XPTI_ENABLE_INSTRUMENTATION // Include the headers necessary for emitting traces using the trace framework From 3603bdab8140c79fdbdf91158f792a60c16e5a00 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:36:43 +0300 Subject: [PATCH 10/24] fix build --- sycl/include/CL/sycl/detail/pi_api_id.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi_api_id.hpp b/sycl/include/CL/sycl/detail/pi_api_id.hpp index 953d168b48b81..366f50203ffee 100644 --- a/sycl/include/CL/sycl/detail/pi_api_id.hpp +++ b/sycl/include/CL/sycl/detail/pi_api_id.hpp @@ -25,8 +25,8 @@ namespace sycl { namespace detail { constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { uint32_t Res = Base; - for (uint32_t I = 1; I < Pow; Ri++) - Rres *= Base; + for (uint32_t I = 1; I < Pow; I++) + Res *= Base; return Res; } From ab7fba682e71ff0daf9a1bcd308700143670b9fc Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 13:44:56 +0300 Subject: [PATCH 11/24] More clang-format --- sycl/source/detail/plugin.hpp | 4 ++-- sycl/tools/pi-trace/pi_trace.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 27217c79bbdca..4172b28c66c6f 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -48,7 +48,7 @@ struct array_fill_helper { template struct array_fill_helper { static void fill(unsigned char *Dst, size_t Offset, const T &&Arg, - Args &&...Rest) { + Args &&... Rest) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. auto RealArg = (typename std::tuple_element::type)(Arg); @@ -67,7 +67,7 @@ constexpr size_t totalSize(const std::tuple &) { /// Notifies XPTI subscribers about PI function calls and packs call arguments. template -uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&...Args) { +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&... Args) { uint64_t CorrelationID = 0; #ifdef XPTI_ENABLE_INSTRUMENTATION if (xptiTraceEnabled()) { diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index 2f5213c058fd6..a29b3a2ac7906 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -51,7 +51,7 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, tpCallback); #define _PI_API(api) \ - ArgHandler.set##_##api([](auto &&...Args) { \ + ArgHandler.set##_##api([](auto &&... Args) { \ std::cout << "--->" << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ From cb248c1b7d447f1e1d2cd5fb68a69777486baa8d Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 22 Jun 2021 14:28:56 +0300 Subject: [PATCH 12/24] Add arguments for function end as well --- sycl/include/CL/sycl/detail/pi.hpp | 17 +++++++++ sycl/source/detail/pi.cpp | 33 +++++++++++++++++ sycl/source/detail/plugin.hpp | 57 +++++++----------------------- sycl/tools/pi-trace/pi_trace.cpp | 9 ++--- 4 files changed, 68 insertions(+), 48 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index 78da0edb482cb..35b4674b49615 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -182,6 +182,23 @@ uint64_t emitFunctionBeginTrace(const char *FName); /// \param FName The name of the PI API call void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName); +/// Notifies XPTI subscribers about PI function calls and packs call arguments. +/// +/// \param FuncID is the API hash ID from PiApiID type trait. +/// \param ArgsData is a pointer to packed function call arguments. +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, + unsigned char *ArgsData); + +/// Notifies XPTI subscribers about PI function call result. +/// +/// \param CorrelationID The correlation ID for the API call generated by the +/// emitFunctionWithArgsBeginTrace() call. +/// \param FuncID is the API hash ID from PiApiID type trait. +/// \param ArgsData is a pointer to packed function call arguments. +/// \param Result is function call result value. +void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, + unsigned char *ArgsData, pi_result Result); + // A wrapper for passing around byte array properties class ByteArray { public: diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index f2dba17049514..85ec6f6d3c611 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -137,6 +137,39 @@ void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName) { #endif // XPTI_ENABLE_INSTRUMENTATION } +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, + unsigned char *ArgsData) { + uint64_t CorrelationID = 0; +#ifdef XPTI_ENABLE_INSTRUMENTATION + if (xptiTraceEnabled()) { + uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + CorrelationID = xptiGetUniqueId(); + + xpti::function_with_args_t Payload{FuncID, ArgsData, nullptr, nullptr}; + + xptiNotifySubscribers( + StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin, + GPIArgCallEvent, nullptr, CorrelationID, &Payload); + } +#endif + return CorrelationID; +} + +void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, + unsigned char *ArgsData, pi_result Result) { +#ifdef XPTI_ENABLE_INSTRUMENTATION + if (xptiTraceEnabled()) { + uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + + xpti::function_with_args_t Payload{FuncID, ArgsData, &Result, nullptr}; + + xptiNotifySubscribers( + StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, + GPIArgCallEvent, nullptr, CorrelationID, &Payload); + } +#endif +} + void contextSetExtendedDeleter(const cl::sycl::context &context, pi_context_extended_deleter func, void *user_data) { diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 4172b28c66c6f..fd507f0680573 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -65,49 +65,17 @@ constexpr size_t totalSize(const std::tuple &) { return (sizeof(Ts) + ...); } -/// Notifies XPTI subscribers about PI function calls and packs call arguments. template -uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, ArgsT &&... Args) { - uint64_t CorrelationID = 0; -#ifdef XPTI_ENABLE_INSTRUMENTATION - if (xptiTraceEnabled()) { - uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); - CorrelationID = xptiGetUniqueId(); - - using ArgsTuple = typename PiApiArgTuple::type; - - constexpr size_t TotalSize = totalSize(ArgsTuple{}); +auto packCallArguments(ArgsT &&...Args) { + using ArgsTuple = typename PiApiArgTuple::type; - std::array ArgsData; - array_fill_helper::fill(ArgsData.data(), 0, - std::forward(Args)...); + constexpr size_t TotalSize = totalSize(ArgsTuple{}); - xpti::function_with_args_t Payload{FuncID, ArgsData.data(), nullptr, - nullptr}; + std::array ArgsData; + array_fill_helper::fill(ArgsData.data(), 0, + std::forward(Args)...); - xptiNotifySubscribers( - StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin, - GPIArgCallEvent, nullptr, CorrelationID, &Payload); - } -#endif - return CorrelationID; -} - -/// Notifies XPTI subscribers about PI function call result. -template -void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, - pi_result Result) { -#ifdef XPTI_ENABLE_INSTRUMENTATION - if (xptiTraceEnabled()) { - uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); - - xpti::function_with_args_t Payload{FuncID, nullptr, &Result, nullptr}; - - xptiNotifySubscribers( - StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, - GPIArgCallEvent, nullptr, CorrelationID, &Payload); - } -#endif + return ArgsData; } /// The plugin class provides a unified interface to the underlying low-level @@ -159,9 +127,10 @@ class plugin { // the per_instance_user_data field. std::string PIFnName = PiCallInfo.getFuncName(); uint64_t CorrelationID = pi::emitFunctionBeginTrace(PIFnName.c_str()); - uint64_t CorrelationIDWithArgs = - emitFunctionWithArgsBeginTrace( - PiApiID::id, std::forward(Args)...); + auto ArgsData = + packCallArguments(std::forward(Args)...); + uint64_t CorrelationIDWithArgs = pi::emitFunctionWithArgsBeginTrace( + PiApiID::id, ArgsData.data()); #endif RT::PiResult R; if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) { @@ -180,8 +149,8 @@ class plugin { #ifdef XPTI_ENABLE_INSTRUMENTATION // Close the function begin with a call to function end pi::emitFunctionEndTrace(CorrelationID, PIFnName.c_str()); - emitFunctionWithArgsEndTrace(CorrelationIDWithArgs, - PiApiID::id, R); + pi::emitFunctionWithArgsEndTrace( + CorrelationIDWithArgs, PiApiID::id, ArgsData.data(), R); #endif return R; } diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index a29b3a2ac7906..45fe7dc24e976 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -51,11 +51,11 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, tpCallback); #define _PI_API(api) \ - ArgHandler.set##_##api([](auto &&... Args) { \ - std::cout << "--->" << #api << "(" \ + ArgHandler.set##_##api([](auto &&...Args) { \ + std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ - std::cout << ")\n"; \ + std::cout << ") ---> "; \ }); #include #undef _PI_API @@ -71,7 +71,7 @@ XPTI_CALLBACK_API void tpCallback(uint16_t TraceType, xpti::trace_event_data_t *Event, uint64_t Instance, const void *UserData) { auto Type = static_cast(TraceType); - if (Type == xpti::trace_point_type_t::function_with_args_begin) { + if (Type == xpti::trace_point_type_t::function_with_args_end) { // Lock while we print information std::lock_guard Lock(GIOMutex); @@ -79,5 +79,6 @@ XPTI_CALLBACK_API void tpCallback(uint16_t TraceType, static_cast(UserData); ArgHandler.handle(Data->function_id, Data->args_data); + std::cout << *static_cast(Data->ret_data) << "\n"; } } From 3118d0cea4f1876204a1721d2a77dc84b291e21f Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Wed, 23 Jun 2021 10:08:20 +0300 Subject: [PATCH 13/24] get rid of piapiid --- sycl/include/CL/sycl/detail/pi_api_id.hpp | 60 ------------------- sycl/source/detail/plugin.hpp | 8 +-- .../xpti_helpers/pi_arguments_handler.hpp | 3 +- 3 files changed, 5 insertions(+), 66 deletions(-) delete mode 100644 sycl/include/CL/sycl/detail/pi_api_id.hpp diff --git a/sycl/include/CL/sycl/detail/pi_api_id.hpp b/sycl/include/CL/sycl/detail/pi_api_id.hpp deleted file mode 100644 index 366f50203ffee..0000000000000 --- a/sycl/include/CL/sycl/detail/pi_api_id.hpp +++ /dev/null @@ -1,60 +0,0 @@ -//==---------- pi_api_id.hpp - PI API function IDs -------------------------==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -/// \file pi_api_id.hpp -/// This file contains mapping between PI API functions and their IDs. A hash -/// function is used to generate IDs. The reason for usage of a hash function -/// instead of raw values of PiApiKind is ABI stability. New functions can be -/// added to PiApiKind, and there's no reliable way for external XPTI users to -/// know when to update the values. Hashes are calculated from API function -/// name, so it will remain the same after update to pi.def. -/// -/// \ingroup sycl_pi - -#pragma once - -#include - -__SYCL_INLINE_NAMESPACE(cl) { -namespace sycl { -namespace detail { -constexpr uint32_t cxpow(uint32_t Base, uint32_t Pow) { - uint32_t Res = Base; - for (uint32_t I = 1; I < Pow; I++) - Res *= Base; - return Res; -} - -/// This is a simple implementation of polynomial rolling hash function. -/// -/// The general formula for the hash is Sum(s[i] * p^i) mod m. -/// Since only English characters are used for PI function names, p = 53 is -/// chosen. m = 1051 is a fairly big prime number for the task. -constexpr uint32_t cxhash(const char *Str) { - constexpr uint32_t p = 53; - constexpr uint32_t m = 1051; - uint32_t Hash = 0; - uint32_t Len = 0; - while (Str[Len++] != '\0') - Hash += Str[Len - 1] * cxpow(p, Len - 1); - return Hash % m; -} - -template struct PiApiID {}; - -#define _PI_API(api) \ - template <> struct PiApiID { \ - static constexpr uint32_t id = cxhash(#api); \ - }; - -#include - -#undef _PI_API -} // namespace detail -} // namespace sycl -} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index fd507f0680573..b64e331a7beca 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -130,7 +129,7 @@ class plugin { auto ArgsData = packCallArguments(std::forward(Args)...); uint64_t CorrelationIDWithArgs = pi::emitFunctionWithArgsBeginTrace( - PiApiID::id, ArgsData.data()); + static_cast(PiApiOffset), ArgsData.data()); #endif RT::PiResult R; if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) { @@ -149,8 +148,9 @@ class plugin { #ifdef XPTI_ENABLE_INSTRUMENTATION // Close the function begin with a call to function end pi::emitFunctionEndTrace(CorrelationID, PIFnName.c_str()); - pi::emitFunctionWithArgsEndTrace( - CorrelationIDWithArgs, PiApiID::id, ArgsData.data(), R); + pi::emitFunctionWithArgsEndTrace(CorrelationIDWithArgs, + static_cast(PiApiOffset), + ArgsData.data(), R); #endif return R; } diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 3fadb485ea0e6..3fadd91310470 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -9,7 +9,6 @@ #pragma once #include -#include #include #include "tuple_view.hpp" @@ -36,7 +35,7 @@ class PiArgumentsHandler { public: void handle(uint32_t ID, void *ArgsData) { #define _PI_API(api) \ - if (ID == sycl::detail::PiApiID::id) { \ + if (ID == static_cast(detail::PiApiKind::api)) { \ MHandler##_##api(ArgsData); \ return; \ } From 571b6c49eacdc7b990b82cd7f70d308875321cac Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Wed, 23 Jun 2021 10:09:13 +0300 Subject: [PATCH 14/24] clang-format --- sycl/source/detail/plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index b64e331a7beca..0a816b65e45db 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -47,7 +47,7 @@ struct array_fill_helper { template struct array_fill_helper { static void fill(unsigned char *Dst, size_t Offset, const T &&Arg, - Args &&... Rest) { + Args &&...Rest) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. auto RealArg = (typename std::tuple_element::type)(Arg); From 71805c19a5614e12878960ff82bd6930d5de1c6a Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Wed, 23 Jun 2021 10:19:51 +0300 Subject: [PATCH 15/24] more clang-format --- sycl/source/detail/plugin.hpp | 4 ++-- sycl/tools/pi-trace/pi_trace.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 0a816b65e45db..34578c00460cc 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -47,7 +47,7 @@ struct array_fill_helper { template struct array_fill_helper { static void fill(unsigned char *Dst, size_t Offset, const T &&Arg, - Args &&...Rest) { + Args &&... Rest) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. auto RealArg = (typename std::tuple_element::type)(Arg); @@ -65,7 +65,7 @@ constexpr size_t totalSize(const std::tuple &) { } template -auto packCallArguments(ArgsT &&...Args) { +auto packCallArguments(ArgsT &&... Args) { using ArgsTuple = typename PiApiArgTuple::type; constexpr size_t TotalSize = totalSize(ArgsTuple{}); diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index 45fe7dc24e976..3fee6fd9f13e3 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -51,7 +51,7 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, tpCallback); #define _PI_API(api) \ - ArgHandler.set##_##api([](auto &&...Args) { \ + ArgHandler.set##_##api([](auto &&... Args) { \ std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ From 3151a63c3746372d20990ccc72791ff48a3a1aee Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 24 Jun 2021 10:16:04 +0300 Subject: [PATCH 16/24] address more feedback --- sycl/include/CL/sycl/detail/pi.def | 290 ++++++---- sycl/include/CL/sycl/detail/pi.h | 2 +- sycl/include/CL/sycl/detail/pi.hpp | 4 +- .../include/CL/sycl/detail/pi_args_helper.hpp | 540 ------------------ sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp | 2 +- sycl/plugins/level_zero/pi_level_zero.cpp | 2 +- sycl/source/detail/plugin.hpp | 11 +- sycl/tools/pi-trace/pi_trace.cpp | 4 +- .../xpti_helpers/pi_arguments_handler.hpp | 16 +- sycl/unittests/helpers/PiMock.hpp | 2 +- 10 files changed, 208 insertions(+), 665 deletions(-) delete mode 100644 sycl/include/CL/sycl/detail/pi_args_helper.hpp diff --git a/sycl/include/CL/sycl/detail/pi.def b/sycl/include/CL/sycl/detail/pi.def index 5133ed2fa9210..a758674091dac 100644 --- a/sycl/include/CL/sycl/detail/pi.def +++ b/sycl/include/CL/sycl/detail/pi.def @@ -10,127 +10,207 @@ #error Undefined _PI_API macro expansion #endif -// The list of all PI interfaces wrapped with _PI_API macro. +// The list of all PI interfaces and their arguments wrapped with _PI_API macro. // This is for convinience of doing same thing for all interfaces, e.g. // declare, define, initialize. // +// This list is used to define PiApiKind enum, which is part of external +// interface. To avoid ABI breakage, please, add new entries to the end of the +// list. +// // Platform -_PI_API(piPlatformsGet) -_PI_API(piPlatformGetInfo) -_PI_API(piextPlatformGetNativeHandle) -_PI_API(piextPlatformCreateWithNativeHandle) +_PI_API(piPlatformsGet, pi_uint32, pi_platform *, pi_uint32 *) +_PI_API(piPlatformGetInfo, pi_platform, pi_platform_info, size_t, void *, + size_t *) +_PI_API(piextPlatformGetNativeHandle, pi_platform, pi_native_handle *) +_PI_API(piextPlatformCreateWithNativeHandle, pi_native_handle, pi_platform *) // Device -_PI_API(piDevicesGet) -_PI_API(piDeviceGetInfo) -_PI_API(piDevicePartition) -_PI_API(piDeviceRetain) -_PI_API(piDeviceRelease) -_PI_API(piextDeviceSelectBinary) -_PI_API(piextGetDeviceFunctionPointer) -_PI_API(piextDeviceGetNativeHandle) -_PI_API(piextDeviceCreateWithNativeHandle) +_PI_API(piDevicesGet, pi_platform, pi_device_type, pi_uint32, pi_device *, + pi_uint32 *) +_PI_API(piDeviceGetInfo, pi_device, pi_device_info, size_t, void *, size_t *) +_PI_API(piDevicePartition, pi_device, const pi_device_partition_property *, + pi_uint32, pi_device *, pi_uint32 *) +_PI_API(piDeviceRetain, pi_device) +_PI_API(piDeviceRelease, pi_device) +_PI_API(piextDeviceSelectBinary, pi_device, pi_device_binary *, pi_uint32, + pi_uint32 *) +_PI_API(piextGetDeviceFunctionPointer, pi_device, pi_program, const char *, + pi_uint64 *) +_PI_API(piextDeviceGetNativeHandle, pi_device, pi_native_handle *) +_PI_API(piextDeviceCreateWithNativeHandle, pi_native_handle, pi_platform, + pi_device *) // Context -_PI_API(piContextCreate) -_PI_API(piContextGetInfo) -_PI_API(piContextRetain) -_PI_API(piContextRelease) -_PI_API(piextContextSetExtendedDeleter) -_PI_API(piextContextGetNativeHandle) -_PI_API(piextContextCreateWithNativeHandle) +_PI_API(piContextCreate, const pi_context_properties *, pi_uint32, + const pi_device *, + void (*)(const char *, const void *, size_t, void *), + void *, pi_context *) +_PI_API(piContextGetInfo, pi_context, pi_context_info, size_t, void *, size_t *) +_PI_API(piContextRetain, pi_context) +_PI_API(piContextRelease, pi_context) +_PI_API(piextContextSetExtendedDeleter, pi_context, pi_context_extended_deleter, + void *) +_PI_API(piextContextGetNativeHandle, pi_context, pi_native_handle *) +_PI_API(piextContextCreateWithNativeHandle, pi_native_handle, pi_uint32, + const pi_device *, bool, + pi_context *) // Queue -_PI_API(piQueueCreate) -_PI_API(piQueueGetInfo) -_PI_API(piQueueFinish) -_PI_API(piQueueRetain) -_PI_API(piQueueRelease) -_PI_API(piextQueueGetNativeHandle) -_PI_API(piextQueueCreateWithNativeHandle) +_PI_API(piQueueCreate, pi_context, pi_device, pi_queue_properties, pi_queue *) +_PI_API(piQueueGetInfo, pi_queue, pi_queue_info, size_t, void *, size_t *) +_PI_API(piQueueFinish, pi_queue) +_PI_API(piQueueRetain, pi_queue) +_PI_API(piQueueRelease, pi_queue) +_PI_API(piextQueueGetNativeHandle, pi_queue, pi_native_handle *) +_PI_API(piextQueueCreateWithNativeHandle, pi_native_handle, pi_context, + pi_queue *) // Memory -_PI_API(piMemBufferCreate) -_PI_API(piMemImageCreate) -_PI_API(piMemGetInfo) -_PI_API(piMemImageGetInfo) -_PI_API(piMemRetain) -_PI_API(piMemRelease) -_PI_API(piMemBufferPartition) -_PI_API(piextMemGetNativeHandle) -_PI_API(piextMemCreateWithNativeHandle) +_PI_API(piMemBufferCreate, pi_context, pi_mem_flags, size_t, void *, pi_mem *, + const pi_mem_properties *) +_PI_API(piMemImageCreate, pi_context, pi_mem_flags, const pi_image_format *, + const pi_image_desc *, void *, pi_mem *) +_PI_API(piMemGetInfo, pi_mem, cl_mem_info, size_t, void *, size_t *) +_PI_API(piMemImageGetInfo, pi_mem, pi_image_info, size_t, void *, size_t *) +_PI_API(piMemRetain, pi_mem) +_PI_API(piMemRelease, pi_mem) +_PI_API(piMemBufferPartition, pi_mem, pi_mem_flags, pi_buffer_create_type, + void *, pi_mem *) +_PI_API(piextMemGetNativeHandle, pi_mem, pi_native_handle *) +_PI_API(piextMemCreateWithNativeHandle, pi_native_handle, pi_mem *) // Program -_PI_API(piProgramCreate) -_PI_API(piclProgramCreateWithSource) -_PI_API(piProgramCreateWithBinary) -_PI_API(piProgramGetInfo) -_PI_API(piProgramCompile) -_PI_API(piProgramBuild) -_PI_API(piProgramLink) -_PI_API(piProgramGetBuildInfo) -_PI_API(piProgramRetain) -_PI_API(piProgramRelease) -_PI_API(piextProgramSetSpecializationConstant) -_PI_API(piextProgramGetNativeHandle) -_PI_API(piextProgramCreateWithNativeHandle) +_PI_API(piProgramCreate, pi_context, const void *, size_t, pi_program *) +_PI_API(piclProgramCreateWithSource, pi_context, pi_uint32, const char **, + const size_t, pi_program *) +_PI_API(piProgramCreateWithBinary, pi_context, pi_uint32, const pi_device *, + const size_t *, const unsigned char **, + pi_uint32 *, pi_program *) +_PI_API(piProgramGetInfo, pi_program, pi_program_info, size_t, void *, size_t *) +_PI_API(piProgramCompile, pi_program, pi_uint32, const pi_device *, + const char *, pi_uint32, const pi_program *, + const char **, void (*)(pi_program, void *), void *) +_PI_API(piProgramBuild, pi_program, pi_uint32, const pi_device *, + const char *, void (*)(pi_program, void *), void *) +_PI_API(piProgramLink, pi_context, pi_uint32, const pi_device *, + const char *, pi_uint32, const pi_program *, + void (*)(pi_program, void *), void *, pi_program *) +_PI_API(piProgramGetBuildInfo, pi_program, pi_device, cl_program_build_info, + size_t, void *, size_t *) +_PI_API(piProgramRetain, pi_program) +_PI_API(piProgramRelease, pi_program) +_PI_API(piextProgramSetSpecializationConstant, pi_program, pi_uint32, size_t, + const void *) +_PI_API(piextProgramGetNativeHandle, pi_program, pi_native_handle *) +_PI_API(piextProgramCreateWithNativeHandle, pi_native_handle, pi_context, + pi_program *) // Kernel -_PI_API(piKernelCreate) -_PI_API(piKernelSetArg) -_PI_API(piKernelGetInfo) -_PI_API(piKernelGetGroupInfo) -_PI_API(piKernelGetSubGroupInfo) -_PI_API(piKernelRetain) -_PI_API(piKernelRelease) -_PI_API(piextKernelSetArgPointer) -_PI_API(piKernelSetExecInfo) -_PI_API(piextKernelCreateWithNativeHandle) -_PI_API(piextKernelGetNativeHandle) +_PI_API(piKernelCreate, pi_program, const char *, pi_kernel *) +_PI_API(piKernelSetArg, pi_kernel, pi_uint32, size_t, const void *) +_PI_API(piKernelGetInfo, pi_kernel, pi_kernel_info, size_t, void *, size_t *) +_PI_API(piKernelGetGroupInfo, pi_kernel, pi_device, pi_kernel_group_info, size_t, + void *, size_t *) +_PI_API(piKernelGetSubGroupInfo, pi_kernel, pi_device, pi_kernel_sub_group_info, + size_t, const void *, size_t, void *, size_t *) +_PI_API(piKernelRetain, pi_kernel) +_PI_API(piKernelRelease, pi_kernel) +_PI_API(piextKernelSetArgPointer, pi_kernel, pi_uint32, size_t, const void *) +_PI_API(piKernelSetExecInfo, pi_kernel, pi_kernel_exec_info, size_t, + const void *) +_PI_API(piextKernelCreateWithNativeHandle, pi_native_handle, pi_context, bool, + pi_kernel *) +_PI_API(piextKernelGetNativeHandle, pi_kernel, pi_native_handle *) // Event -_PI_API(piEventCreate) -_PI_API(piEventGetInfo) -_PI_API(piEventGetProfilingInfo) -_PI_API(piEventsWait) -_PI_API(piEventSetCallback) -_PI_API(piEventSetStatus) -_PI_API(piEventRetain) -_PI_API(piEventRelease) -_PI_API(piextEventGetNativeHandle) -_PI_API(piextEventCreateWithNativeHandle) +_PI_API(piEventCreate, pi_context, pi_event *) +_PI_API(piEventGetInfo, pi_event, pi_event_info, size_t, void *, size_t *) +_PI_API(piEventGetProfilingInfo, pi_event, pi_profiling_info, size_t, void *, + size_t *) +_PI_API(piEventsWait, pi_uint32, const pi_event *) +_PI_API(piEventSetCallback, pi_event, pi_int32, + void (*)(pi_event, pi_int32, void *), void *) +_PI_API(piEventSetStatus, pi_event, pi_int32) +_PI_API(piEventRetain, pi_event) +_PI_API(piEventRelease, pi_event) +_PI_API(piextEventGetNativeHandle, pi_event, pi_native_handle *) +_PI_API(piextEventCreateWithNativeHandle, pi_native_handle, pi_event *) // Sampler -_PI_API(piSamplerCreate) -_PI_API(piSamplerGetInfo) -_PI_API(piSamplerRetain) -_PI_API(piSamplerRelease) +_PI_API(piSamplerCreate, pi_context, const pi_sampler_properties *, + pi_sampler *) +_PI_API(piSamplerGetInfo, pi_sampler, pi_sampler_info, size_t, void *, size_t *) +_PI_API(piSamplerRetain, pi_sampler) +_PI_API(piSamplerRelease, pi_sampler) // Queue commands -_PI_API(piEnqueueKernelLaunch) -_PI_API(piEnqueueNativeKernel) -_PI_API(piEnqueueEventsWait) -_PI_API(piEnqueueEventsWaitWithBarrier) -_PI_API(piEnqueueMemBufferRead) -_PI_API(piEnqueueMemBufferReadRect) -_PI_API(piEnqueueMemBufferWrite) -_PI_API(piEnqueueMemBufferWriteRect) -_PI_API(piEnqueueMemBufferCopy) -_PI_API(piEnqueueMemBufferCopyRect) -_PI_API(piEnqueueMemBufferFill) -_PI_API(piEnqueueMemImageRead) -_PI_API(piEnqueueMemImageWrite) -_PI_API(piEnqueueMemImageCopy) -_PI_API(piEnqueueMemImageFill) -_PI_API(piEnqueueMemBufferMap) -_PI_API(piEnqueueMemUnmap) +_PI_API(piEnqueueKernelLaunch, pi_queue, pi_kernel, pi_uint32, const size_t *, + const size_t *, const size_t *, pi_uint32, + const pi_event *, pi_event *) +_PI_API(piEnqueueNativeKernel, pi_queue, void (*)(void *), void *, size_t, + pi_uint32, const pi_mem *, const void **, + pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueEventsWait, pi_queue, pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueEventsWaitWithBarrier, pi_queue, pi_uint32, const pi_event *, + pi_event *) +_PI_API(piEnqueueMemBufferRead, pi_queue, pi_mem, pi_bool, size_t, size_t, + void *, pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueMemBufferReadRect, pi_queue, pi_mem, pi_bool, + pi_buff_rect_offset, pi_buff_rect_offset, + pi_buff_rect_region, size_t, size_t, size_t, + size_t, void *, pi_uint32, const pi_event *, + pi_event *) +_PI_API(piEnqueueMemBufferWrite, pi_queue, pi_mem, pi_bool, size_t, size_t, + const void *, pi_uint32, const pi_event *, + pi_event *) +_PI_API(piEnqueueMemBufferWriteRect, pi_queue, pi_mem, pi_bool, + pi_buff_rect_offset, pi_buff_rect_offset, + pi_buff_rect_region, size_t, size_t, + size_t, size_t, const void *, pi_uint32, + const pi_event *, pi_event *) +_PI_API(piEnqueueMemBufferCopy, pi_queue, pi_mem, pi_mem, size_t, size_t, + size_t, pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueMemBufferCopyRect, pi_queue, pi_mem, pi_mem, + pi_buff_rect_offset, pi_buff_rect_offset, + pi_buff_rect_region, size_t, size_t, + size_t, size_t, pi_uint32, const pi_event *, + pi_event *) +_PI_API(piEnqueueMemBufferFill, pi_queue, pi_mem, const void *, size_t, size_t, + size_t, pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueMemImageRead, pi_queue, pi_mem, pi_bool, pi_image_offset, + pi_image_region, size_t, size_t, void *, + pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueMemImageWrite, pi_queue, pi_mem, pi_bool, pi_image_offset, + pi_image_region, size_t, size_t, const void *, + pi_uint32, const pi_event *, pi_event *) +_PI_API(piEnqueueMemImageCopy, pi_queue, pi_mem, pi_mem, pi_image_offset, + pi_image_offset, pi_image_region, pi_uint32, + const pi_event *, pi_event *) +_PI_API(piEnqueueMemImageFill, pi_queue, pi_mem, const void *, const size_t *, + const size_t *, pi_uint32, const pi_event *, + pi_event *) +_PI_API(piEnqueueMemBufferMap, pi_queue, pi_mem, pi_bool, pi_map_flags, size_t, + size_t, pi_uint32, const pi_event *, pi_event *, + void **) +_PI_API(piEnqueueMemUnmap, pi_queue, pi_mem, void *, pi_uint32, const pi_event *, + pi_event *) // USM -_PI_API(piextUSMHostAlloc) -_PI_API(piextUSMDeviceAlloc) -_PI_API(piextUSMSharedAlloc) -_PI_API(piextUSMFree) -_PI_API(piextUSMEnqueueMemset) -_PI_API(piextUSMEnqueueMemcpy) -_PI_API(piextUSMEnqueuePrefetch) -_PI_API(piextUSMEnqueueMemAdvise) -_PI_API(piextUSMGetMemAllocInfo) +_PI_API(piextUSMHostAlloc, void **, pi_context, pi_usm_mem_properties *, size_t, + pi_uint32) +_PI_API(piextUSMDeviceAlloc, void **, pi_context, pi_device, + pi_usm_mem_properties *, size_t, pi_uint32) +_PI_API(piextUSMSharedAlloc, void **, pi_context, pi_device, + pi_usm_mem_properties *, size_t, pi_uint32) +_PI_API(piextUSMFree, pi_context, void *) +_PI_API(piextUSMEnqueueMemset, pi_queue, void *, pi_int32, size_t, pi_uint32, + const pi_event *, pi_event *) +_PI_API(piextUSMEnqueueMemcpy, pi_queue, pi_bool, void *, const void *, size_t, + pi_uint32, const pi_event *, pi_event *) +_PI_API(piextUSMEnqueuePrefetch, pi_queue, const void *, size_t, + pi_usm_migration_flags, pi_uint32, + const pi_event *, pi_event *) +_PI_API(piextUSMEnqueueMemAdvise, pi_queue, const void *, size_t, pi_mem_advice, + pi_event *) +_PI_API(piextUSMGetMemAllocInfo, pi_context, const void *, pi_mem_info, size_t, + void *, size_t *) -_PI_API(piextKernelSetArgMemObj) -_PI_API(piextKernelSetArgSampler) +_PI_API(piextKernelSetArgMemObj, pi_kernel, pi_uint32, const pi_mem *) +_PI_API(piextKernelSetArgSampler, pi_kernel, pi_uint32, const pi_sampler *) -_PI_API(piextPluginGetOpaqueData) +_PI_API(piextPluginGetOpaqueData, void *, void **) -_PI_API(piTearDown) +_PI_API(piTearDown, void *) #undef _PI_API diff --git a/sycl/include/CL/sycl/detail/pi.h b/sycl/include/CL/sycl/detail/pi.h index 46f42c32bb704..c926774fb639b 100644 --- a/sycl/include/CL/sycl/detail/pi.h +++ b/sycl/include/CL/sycl/detail/pi.h @@ -1661,7 +1661,7 @@ struct _pi_plugin { char PluginVersion[4]; char *Targets; struct FunctionPointers { -#define _PI_API(api) decltype(::api) *api; +#define _PI_API(api, ...) decltype(::api) *api; #include } PiFunctionTable; }; diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index 35b4674b49615..fed12f13e4e68 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -40,7 +40,7 @@ class context; namespace detail { enum class PiApiKind { -#define _PI_API(api) api, +#define _PI_API(api, ...) api, #include }; class plugin; @@ -160,7 +160,7 @@ template __SYCL_EXPORT const plugin &getPlugin(); // Utility Functions to get Function Name for a PI Api. template struct PiFuncInfo {}; -#define _PI_API(api) \ +#define _PI_API(api, ...) \ template <> struct PiFuncInfo { \ using FuncPtrT = decltype(&::api); \ inline std::string getFuncName() { return #api; } \ diff --git a/sycl/include/CL/sycl/detail/pi_args_helper.hpp b/sycl/include/CL/sycl/detail/pi_args_helper.hpp deleted file mode 100644 index 6cd43a83c0bf4..0000000000000 --- a/sycl/include/CL/sycl/detail/pi_args_helper.hpp +++ /dev/null @@ -1,540 +0,0 @@ -//==---------- pi_args_helper.hpp - PI call arguments helper ---------------==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -/// \file pi_args_helper.hpp -/// Utilities to enable PI call arguments packing for XPTI. -/// -/// C++ wrapper for PI does not take real function argument type into account. -/// As a result, when Plugin.call<>() is invoked, there might be type mismatch -/// between deduced type and real call argument type (e.g. when there's -/// std::vector::size() or an integer literal in call expression). This leads to -/// unstable data exchange format between SYCL runtime and XPTI. To workaround -/// the problem, SYCL runtime must explicitly cast template-deduced types to -/// real types before packing arguments for XPTI. This file contains mappings -/// between PiApiKind and tuples of argument types. -/// -/// \ingroup sycl_pi - -#pragma once - -#include -#include - -#include - -__SYCL_INLINE_NAMESPACE(cl) { -namespace sycl { -namespace detail { -template struct PiApiArgTuple; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> -struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = - std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; - -template <> struct PiApiArgTuple { - using type = std::tuple; -}; -} // namespace detail -} // namespace sycl -} // __SYCL_INLINE_NAMESPACE(cl) diff --git a/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp b/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp index 63fc720f49eee..932bda81c2819 100644 --- a/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp +++ b/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp @@ -1245,7 +1245,7 @@ pi_result piPluginInit(pi_plugin *PluginInit) { PiESimdDeviceAccess->data = reinterpret_cast(new sycl::detail::ESIMDDeviceInterface()); -#define _PI_API(api) \ +#define _PI_API(api, ...) \ (PluginInit->PiFunctionTable).api = (decltype(&::api))(&api); #include diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index fb156d60f185d..7e03ebde9565a 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -6401,7 +6401,7 @@ pi_result piPluginInit(pi_plugin *PluginInit) { strncpy(PluginInit->PluginVersion, _PI_H_VERSION_STRING, PluginVersionSize); -#define _PI_API(api) \ +#define _PI_API(api, ...) \ (PluginInit->PiFunctionTable).api = (decltype(&::api))(&api); #include diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 34578c00460cc..fc363892ee67e 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -32,6 +31,16 @@ extern xpti::trace_event_data_t *GPIArgCallEvent; template struct array_fill_helper; +template struct PiApiArgTuple; + +#define _PI_API(api, ...) \ + template <> struct PiApiArgTuple { \ + using type = std::tuple<__VA_ARGS__>; \ + }; + +#include +#undef _PI_API + template struct array_fill_helper { static void fill(unsigned char *Dst, size_t Offset, T &&Arg) { diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index 3fee6fd9f13e3..e8913dc5c044c 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -50,8 +50,8 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, GStreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, tpCallback); -#define _PI_API(api) \ - ArgHandler.set##_##api([](auto &&... Args) { \ +#define _PI_API(api, ...) \ + ArgHandler.set##_##api([](auto &&...Args) { \ std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 3fadd91310470..310dcbede11b0 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -9,7 +9,6 @@ #pragma once #include -#include #include "tuple_view.hpp" @@ -34,7 +33,7 @@ namespace xpti_helpers { class PiArgumentsHandler { public: void handle(uint32_t ID, void *ArgsData) { -#define _PI_API(api) \ +#define _PI_API(api, ...) \ if (ID == static_cast(detail::PiApiKind::api)) { \ MHandler##_##api(ArgsData); \ return; \ @@ -43,15 +42,10 @@ class PiArgumentsHandler { #undef _PI_API } -#define _PI_API(api) \ - void set##_##api( \ - typename as_function::type>::type \ - Handler) { \ +#define _PI_API(api, ...) \ + void set##_##api(std::function Handler) { \ MHandler##_##api = [Handler](void *Data) { \ - typename as_tuple_view< \ - typename detail::PiApiArgTuple::type>::type \ - TV{static_cast(Data)}; \ + tuple_view<__VA_ARGS__> TV{static_cast(Data)}; \ xpti_helpers::apply(Handler, TV); \ }; \ } @@ -59,7 +53,7 @@ class PiArgumentsHandler { #undef _PI_API private: -#define _PI_API(api) \ +#define _PI_API(api, ...) \ std::function MHandler##_##api = [](void *) {}; #include #undef _PI_API diff --git a/sycl/unittests/helpers/PiMock.hpp b/sycl/unittests/helpers/PiMock.hpp index fa415a3b26f6c..0954b9d03af2d 100644 --- a/sycl/unittests/helpers/PiMock.hpp +++ b/sycl/unittests/helpers/PiMock.hpp @@ -45,7 +45,7 @@ namespace RT = detail::pi; /// \param MPlugin is a pointer to the PiPlugin instance that will be modified. /// \param FuncPtr is a pointer to the function that will override the original. /// function table entry -#define _PI_API(api) \ +#define _PI_API(api, ...) \ template \ inline void setFuncPtr(RT::PiPlugin *MPlugin, decltype(&::api) FuncPtr); \ template <> \ From 9775db16cf25d7de3fe6d4d06ce49d6a292f72c3 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 24 Jun 2021 12:02:46 +0300 Subject: [PATCH 17/24] make CI a bit happier --- sycl/tools/pi-trace/pi_trace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index e8913dc5c044c..a4e43382b34bf 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -51,7 +51,7 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, tpCallback); #define _PI_API(api, ...) \ - ArgHandler.set##_##api([](auto &&...Args) { \ + ArgHandler.set##_##api([](auto &&... Args) { \ std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ From 22ded674a3dd7c75539db3667abb94319c361313 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 24 Jun 2021 15:22:36 +0300 Subject: [PATCH 18/24] more review feedback --- sycl/source/detail/plugin.hpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index 13dc0614548fc..fd78072288672 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -43,28 +43,23 @@ template struct PiApiArgTuple; template struct array_fill_helper { - static void fill(unsigned char *Dst, size_t Offset, T &&Arg) { + static void fill(unsigned char *Dst, T &&Arg) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. - auto RealArg = (typename std::tuple_element::type)(Arg); - auto *Begin = reinterpret_cast(&RealArg); - auto *End = Begin + sizeof(decltype(RealArg)); - std::uninitialized_copy(Begin, End, Dst + Offset); + auto RealArg = (std::tuple_element_t)(Arg); + *(std::remove_cv_t> *)Dst = RealArg; } }; template struct array_fill_helper { - static void fill(unsigned char *Dst, size_t Offset, const T &&Arg, - Args &&... Rest) { + static void fill(unsigned char *Dst, const T &&Arg, Args &&...Rest) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. - auto RealArg = (typename std::tuple_element::type)(Arg); - auto *Begin = reinterpret_cast(&RealArg); - auto *End = Begin + sizeof(decltype(RealArg)); - std::uninitialized_copy(Begin, End, Dst + Offset); + auto RealArg = (std::tuple_element_t)(Arg); + *(std::remove_cv_t> *)Dst = RealArg; array_fill_helper::fill( - Dst, Offset + sizeof(decltype(RealArg)), std::forward(Rest)...); + Dst + sizeof(decltype(RealArg)), std::forward(Rest)...); } }; @@ -80,7 +75,7 @@ auto packCallArguments(ArgsT &&... Args) { constexpr size_t TotalSize = totalSize(ArgsTuple{}); std::array ArgsData; - array_fill_helper::fill(ArgsData.data(), 0, + array_fill_helper::fill(ArgsData.data(), std::forward(Args)...); return ArgsData; From 0b6a5bbcf9fb60d5f3d9057e49c04427059d8a8e Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 24 Jun 2021 15:25:50 +0300 Subject: [PATCH 19/24] why local and remote clang-format do it differently? --- sycl/source/detail/plugin.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index fd78072288672..b16d425f8ef1b 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -53,7 +53,7 @@ struct array_fill_helper { template struct array_fill_helper { - static void fill(unsigned char *Dst, const T &&Arg, Args &&...Rest) { + static void fill(unsigned char *Dst, const T &&Arg, Args &&... Rest) { using ArgsTuple = typename PiApiArgTuple::type; // C-style cast is required here. auto RealArg = (std::tuple_element_t)(Arg); From 7a3cde1aa81b4ddc7481a3958f835569a539b7b8 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Wed, 30 Jun 2021 08:57:52 +0300 Subject: [PATCH 20/24] remove tuple_view --- .../xpti_helpers/pi_arguments_handler.hpp | 30 ++++++- sycl/tools/xpti_helpers/tuple_view.hpp | 88 ------------------- 2 files changed, 26 insertions(+), 92 deletions(-) delete mode 100644 sycl/tools/xpti_helpers/tuple_view.hpp diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 310dcbede11b0..069a7d7c79416 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -10,13 +10,32 @@ #include -#include "tuple_view.hpp" - #include +#include __SYCL_INLINE_NAMESPACE(cl) { namespace sycl { namespace xpti_helpers { + +template +inline auto get(char *Data, const std::index_sequence &) { + // Our type should be last in Is sequence + using TargetType = + typename std::tuple_element::type; + + // Calculate sizeof all elements before target + target element then substract + // sizeof target element + size_t Res = (sizeof(typename std::tuple_element::type) + ...) - + sizeof(TargetType); + return *(typename std::decay::type *)(Data + Res); +} + +template +inline TupleT unpack(char *Data, + const std::index_sequence & /*1..TupleSize*/) { + return {get(Data, std::make_index_sequence{})...}; +} + /// PiArgumentsHandler is a helper class to process incoming XPTI function call /// events and unpack contained arguments. /// @@ -45,8 +64,11 @@ class PiArgumentsHandler { #define _PI_API(api, ...) \ void set##_##api(std::function Handler) { \ MHandler##_##api = [Handler](void *Data) { \ - tuple_view<__VA_ARGS__> TV{static_cast(Data)}; \ - xpti_helpers::apply(Handler, TV); \ + using TupleT = std::tuple<__VA_ARGS__>; \ + TupleT Tuple = unpack( \ + (char *)Data, \ + std::make_index_sequence::value>{}); \ + std::apply(Handler, Tuple); \ }; \ } #include diff --git a/sycl/tools/xpti_helpers/tuple_view.hpp b/sycl/tools/xpti_helpers/tuple_view.hpp deleted file mode 100644 index 08805792be8c6..0000000000000 --- a/sycl/tools/xpti_helpers/tuple_view.hpp +++ /dev/null @@ -1,88 +0,0 @@ -//==---------- tuple_view.hpp - Tuple View ---------------------------------==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#pragma once - -#include - -#include -#include -#include - -__SYCL_INLINE_NAMESPACE(cl) { -namespace sycl { -namespace xpti_helpers { -/// A helper class to provide tuple-like access to a contiguous chunk of memory. -template struct tuple_view { unsigned char *data; }; - -template struct tuple_view_element; - -template -struct tuple_view_element> - : tuple_view_element> {}; - -template -struct tuple_view_element<0, tuple_view> { - using type = Head; -}; - -template struct tuple_view_offset; - -template -struct tuple_view_offset> { - static constexpr size_t value = - sizeof(typename tuple_view_element>::type) + - tuple_view_offset>::value; -}; - -template struct tuple_view_offset<0, tuple_view> { - static constexpr size_t value = 0; -}; - -template -typename tuple_view_element>::type -get(tuple_view &t) { - return *reinterpret_cast>::type>>( - t.data + tuple_view_offset>::value); -} - -template struct tuple_view_size {}; - -template -struct tuple_view_size> - : std::integral_constant {}; - -template -decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence) { - return std::invoke(std::forward(f), - xpti_helpers::get(std::forward(t))...); -} - -template decltype(auto) apply(F &&f, Tuple &&t) { - return apply_impl( - std::forward(f), std::forward(t), - std::make_index_sequence< - tuple_view_size>::value>{}); -} - -template struct as_function; - -template struct as_function> { - using type = std::function; -}; - -template struct as_tuple_view; - -template struct as_tuple_view> { - using type = tuple_view; -}; - -} // namespace xpti_helpers -} // namespace sycl -} // __SYCL_INLINE_NAMESPACE(cl) From 47ee4c4be3009a95a6b85bb6f37f84e67eba56ff Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Fri, 2 Jul 2021 11:09:58 +0300 Subject: [PATCH 21/24] more feedback --- .../xpti_helpers/pi_arguments_handler.hpp | 7 ++-- sycl/unittests/pi/CMakeLists.txt | 2 + sycl/unittests/pi/pi_arguments_handler.cpp | 40 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 sycl/unittests/pi/pi_arguments_handler.cpp diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 069a7d7c79416..698992a4583f6 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -25,9 +25,10 @@ inline auto get(char *Data, const std::index_sequence &) { // Calculate sizeof all elements before target + target element then substract // sizeof target element - size_t Res = (sizeof(typename std::tuple_element::type) + ...) - - sizeof(TargetType); - return *(typename std::decay::type *)(Data + Res); + const size_t Offset = + (sizeof(typename std::tuple_element::type) + ...) - + sizeof(TargetType); + return *(typename std::decay::type *)(Data + Offset); } template diff --git a/sycl/unittests/pi/CMakeLists.txt b/sycl/unittests/pi/CMakeLists.txt index 93a958850f9d8..53c69f5cae2fa 100644 --- a/sycl/unittests/pi/CMakeLists.txt +++ b/sycl/unittests/pi/CMakeLists.txt @@ -6,10 +6,12 @@ add_sycl_unittest(PiTests OBJECT EnqueueMemTest.cpp PiMock.cpp PlatformTest.cpp + pi_arguments_handler.cpp ) add_dependencies(PiTests sycl) target_include_directories(PiTests PRIVATE SYSTEM ${sycl_inc_dir}) +target_include_directories(PiTests PRIVATE ${sycl_src_dir}/../tools/xpti_helpers) if(SYCL_BUILD_PI_CUDA) add_subdirectory(cuda) diff --git a/sycl/unittests/pi/pi_arguments_handler.cpp b/sycl/unittests/pi/pi_arguments_handler.cpp new file mode 100644 index 0000000000000..ce9d817b8a628 --- /dev/null +++ b/sycl/unittests/pi/pi_arguments_handler.cpp @@ -0,0 +1,40 @@ +//==------- pi_arguments_handler.cpp --- A test for XPTI PI args helper ---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include + +#include "pi_arguments_handler.hpp" + +#include + +#include + +TEST(PiArgumentsHandlerTest, CanUnpackArguments) { + sycl::xpti_helpers::PiArgumentsHandler Handler; + + const pi_uint32 NumPlatforms = 42; + pi_platform *Platforms = new pi_platform[NumPlatforms]; + + Handler.set_piPlatformsGet( + [&](pi_uint32 NP, pi_platform *Plts, pi_uint32 *Ret) { + EXPECT_EQ(NP, NumPlatforms); + EXPECT_EQ(Platforms, Plts); + EXPECT_EQ(Ret, nullptr); + }); + + constexpr size_t Size = sizeof(pi_uint32) + 2 * sizeof(void *); + std::array Data{0}; + *reinterpret_cast(Data.data()) = NumPlatforms; + *reinterpret_cast(Data.data() + sizeof(pi_uint32)) = + Platforms; + + uint32_t ID = static_cast(sycl::detail::PiApiKind::piPlatformsGet); + Handler.handle(ID, Data.data()); + + delete[] Platforms; +} From 57e287f3a31be112634d76af2b869aafa6157d9d Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 6 Jul 2021 21:14:40 +0300 Subject: [PATCH 22/24] use template magic instead of changing pi.def --- sycl/include/CL/sycl/detail/pi.def | 286 +++++++----------- sycl/include/CL/sycl/detail/pi.h | 2 +- sycl/include/CL/sycl/detail/pi.hpp | 4 +- sycl/include/CL/sycl/detail/type_traits.hpp | 7 + sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp | 2 +- sycl/plugins/level_zero/pi_level_zero.cpp | 2 +- sycl/source/detail/plugin.hpp | 5 +- sycl/tools/pi-trace/pi_trace.cpp | 4 +- .../xpti_helpers/pi_arguments_handler.hpp | 21 +- sycl/unittests/helpers/PiMock.hpp | 2 +- 10 files changed, 139 insertions(+), 196 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi.def b/sycl/include/CL/sycl/detail/pi.def index a758674091dac..730b4afa50c0c 100644 --- a/sycl/include/CL/sycl/detail/pi.def +++ b/sycl/include/CL/sycl/detail/pi.def @@ -10,7 +10,7 @@ #error Undefined _PI_API macro expansion #endif -// The list of all PI interfaces and their arguments wrapped with _PI_API macro. +// The list of all PI interfaces wrapped with _PI_API macro. // This is for convinience of doing same thing for all interfaces, e.g. // declare, define, initialize. // @@ -19,198 +19,122 @@ // list. // // Platform -_PI_API(piPlatformsGet, pi_uint32, pi_platform *, pi_uint32 *) -_PI_API(piPlatformGetInfo, pi_platform, pi_platform_info, size_t, void *, - size_t *) -_PI_API(piextPlatformGetNativeHandle, pi_platform, pi_native_handle *) -_PI_API(piextPlatformCreateWithNativeHandle, pi_native_handle, pi_platform *) +_PI_API(piPlatformsGet) +_PI_API(piPlatformGetInfo) +_PI_API(piextPlatformGetNativeHandle) +_PI_API(piextPlatformCreateWithNativeHandle) // Device -_PI_API(piDevicesGet, pi_platform, pi_device_type, pi_uint32, pi_device *, - pi_uint32 *) -_PI_API(piDeviceGetInfo, pi_device, pi_device_info, size_t, void *, size_t *) -_PI_API(piDevicePartition, pi_device, const pi_device_partition_property *, - pi_uint32, pi_device *, pi_uint32 *) -_PI_API(piDeviceRetain, pi_device) -_PI_API(piDeviceRelease, pi_device) -_PI_API(piextDeviceSelectBinary, pi_device, pi_device_binary *, pi_uint32, - pi_uint32 *) -_PI_API(piextGetDeviceFunctionPointer, pi_device, pi_program, const char *, - pi_uint64 *) -_PI_API(piextDeviceGetNativeHandle, pi_device, pi_native_handle *) -_PI_API(piextDeviceCreateWithNativeHandle, pi_native_handle, pi_platform, - pi_device *) +_PI_API(piDevicesGet) +_PI_API(piDeviceGetInfo) +_PI_API(piDevicePartition) +_PI_API(piDeviceRetain) +_PI_API(piDeviceRelease) +_PI_API(piextDeviceSelectBinary) +_PI_API(piextGetDeviceFunctionPointer) +_PI_API(piextDeviceGetNativeHandle) +_PI_API(piextDeviceCreateWithNativeHandle) // Context -_PI_API(piContextCreate, const pi_context_properties *, pi_uint32, - const pi_device *, - void (*)(const char *, const void *, size_t, void *), - void *, pi_context *) -_PI_API(piContextGetInfo, pi_context, pi_context_info, size_t, void *, size_t *) -_PI_API(piContextRetain, pi_context) -_PI_API(piContextRelease, pi_context) -_PI_API(piextContextSetExtendedDeleter, pi_context, pi_context_extended_deleter, - void *) -_PI_API(piextContextGetNativeHandle, pi_context, pi_native_handle *) -_PI_API(piextContextCreateWithNativeHandle, pi_native_handle, pi_uint32, - const pi_device *, bool, - pi_context *) +_PI_API(piContextCreate) +_PI_API(piContextGetInfo) +_PI_API(piContextRetain) +_PI_API(piContextRelease) +_PI_API(piextContextSetExtendedDeleter) +_PI_API(piextContextGetNativeHandle) +_PI_API(piextContextCreateWithNativeHandle) // Queue -_PI_API(piQueueCreate, pi_context, pi_device, pi_queue_properties, pi_queue *) -_PI_API(piQueueGetInfo, pi_queue, pi_queue_info, size_t, void *, size_t *) -_PI_API(piQueueFinish, pi_queue) -_PI_API(piQueueRetain, pi_queue) -_PI_API(piQueueRelease, pi_queue) -_PI_API(piextQueueGetNativeHandle, pi_queue, pi_native_handle *) -_PI_API(piextQueueCreateWithNativeHandle, pi_native_handle, pi_context, - pi_queue *) +_PI_API(piQueueCreate) +_PI_API(piQueueGetInfo) +_PI_API(piQueueFinish) +_PI_API(piQueueRetain) +_PI_API(piQueueRelease) +_PI_API(piextQueueGetNativeHandle) +_PI_API(piextQueueCreateWithNativeHandle) // Memory -_PI_API(piMemBufferCreate, pi_context, pi_mem_flags, size_t, void *, pi_mem *, - const pi_mem_properties *) -_PI_API(piMemImageCreate, pi_context, pi_mem_flags, const pi_image_format *, - const pi_image_desc *, void *, pi_mem *) -_PI_API(piMemGetInfo, pi_mem, cl_mem_info, size_t, void *, size_t *) -_PI_API(piMemImageGetInfo, pi_mem, pi_image_info, size_t, void *, size_t *) -_PI_API(piMemRetain, pi_mem) -_PI_API(piMemRelease, pi_mem) -_PI_API(piMemBufferPartition, pi_mem, pi_mem_flags, pi_buffer_create_type, - void *, pi_mem *) -_PI_API(piextMemGetNativeHandle, pi_mem, pi_native_handle *) -_PI_API(piextMemCreateWithNativeHandle, pi_native_handle, pi_mem *) +_PI_API(piMemBufferCreate) +_PI_API(piMemImageCreate) +_PI_API(piMemGetInfo) +_PI_API(piMemImageGetInfo) +_PI_API(piMemRetain) +_PI_API(piMemRelease) +_PI_API(piMemBufferPartition) +_PI_API(piextMemGetNativeHandle) +_PI_API(piextMemCreateWithNativeHandle) // Program -_PI_API(piProgramCreate, pi_context, const void *, size_t, pi_program *) -_PI_API(piclProgramCreateWithSource, pi_context, pi_uint32, const char **, - const size_t, pi_program *) -_PI_API(piProgramCreateWithBinary, pi_context, pi_uint32, const pi_device *, - const size_t *, const unsigned char **, - pi_uint32 *, pi_program *) -_PI_API(piProgramGetInfo, pi_program, pi_program_info, size_t, void *, size_t *) -_PI_API(piProgramCompile, pi_program, pi_uint32, const pi_device *, - const char *, pi_uint32, const pi_program *, - const char **, void (*)(pi_program, void *), void *) -_PI_API(piProgramBuild, pi_program, pi_uint32, const pi_device *, - const char *, void (*)(pi_program, void *), void *) -_PI_API(piProgramLink, pi_context, pi_uint32, const pi_device *, - const char *, pi_uint32, const pi_program *, - void (*)(pi_program, void *), void *, pi_program *) -_PI_API(piProgramGetBuildInfo, pi_program, pi_device, cl_program_build_info, - size_t, void *, size_t *) -_PI_API(piProgramRetain, pi_program) -_PI_API(piProgramRelease, pi_program) -_PI_API(piextProgramSetSpecializationConstant, pi_program, pi_uint32, size_t, - const void *) -_PI_API(piextProgramGetNativeHandle, pi_program, pi_native_handle *) -_PI_API(piextProgramCreateWithNativeHandle, pi_native_handle, pi_context, - pi_program *) +_PI_API(piProgramCreate) +_PI_API(piclProgramCreateWithSource) +_PI_API(piProgramCreateWithBinary) +_PI_API(piProgramGetInfo) +_PI_API(piProgramCompile) +_PI_API(piProgramBuild) +_PI_API(piProgramLink) +_PI_API(piProgramGetBuildInfo) +_PI_API(piProgramRetain) +_PI_API(piProgramRelease) +_PI_API(piextProgramSetSpecializationConstant) +_PI_API(piextProgramGetNativeHandle) +_PI_API(piextProgramCreateWithNativeHandle) // Kernel -_PI_API(piKernelCreate, pi_program, const char *, pi_kernel *) -_PI_API(piKernelSetArg, pi_kernel, pi_uint32, size_t, const void *) -_PI_API(piKernelGetInfo, pi_kernel, pi_kernel_info, size_t, void *, size_t *) -_PI_API(piKernelGetGroupInfo, pi_kernel, pi_device, pi_kernel_group_info, size_t, - void *, size_t *) -_PI_API(piKernelGetSubGroupInfo, pi_kernel, pi_device, pi_kernel_sub_group_info, - size_t, const void *, size_t, void *, size_t *) -_PI_API(piKernelRetain, pi_kernel) -_PI_API(piKernelRelease, pi_kernel) -_PI_API(piextKernelSetArgPointer, pi_kernel, pi_uint32, size_t, const void *) -_PI_API(piKernelSetExecInfo, pi_kernel, pi_kernel_exec_info, size_t, - const void *) -_PI_API(piextKernelCreateWithNativeHandle, pi_native_handle, pi_context, bool, - pi_kernel *) -_PI_API(piextKernelGetNativeHandle, pi_kernel, pi_native_handle *) +_PI_API(piKernelCreate) +_PI_API(piKernelSetArg) +_PI_API(piKernelGetInfo) +_PI_API(piKernelGetGroupInfo) +_PI_API(piKernelGetSubGroupInfo) +_PI_API(piKernelRetain) +_PI_API(piKernelRelease) +_PI_API(piextKernelSetArgPointer) +_PI_API(piKernelSetExecInfo) +_PI_API(piextKernelCreateWithNativeHandle) +_PI_API(piextKernelGetNativeHandle) // Event -_PI_API(piEventCreate, pi_context, pi_event *) -_PI_API(piEventGetInfo, pi_event, pi_event_info, size_t, void *, size_t *) -_PI_API(piEventGetProfilingInfo, pi_event, pi_profiling_info, size_t, void *, - size_t *) -_PI_API(piEventsWait, pi_uint32, const pi_event *) -_PI_API(piEventSetCallback, pi_event, pi_int32, - void (*)(pi_event, pi_int32, void *), void *) -_PI_API(piEventSetStatus, pi_event, pi_int32) -_PI_API(piEventRetain, pi_event) -_PI_API(piEventRelease, pi_event) -_PI_API(piextEventGetNativeHandle, pi_event, pi_native_handle *) -_PI_API(piextEventCreateWithNativeHandle, pi_native_handle, pi_event *) +_PI_API(piEventCreate) +_PI_API(piEventGetInfo) +_PI_API(piEventGetProfilingInfo) +_PI_API(piEventsWait) +_PI_API(piEventSetCallback) +_PI_API(piEventSetStatus) +_PI_API(piEventRetain) +_PI_API(piEventRelease) +_PI_API(piextEventGetNativeHandle) +_PI_API(piextEventCreateWithNativeHandle) // Sampler -_PI_API(piSamplerCreate, pi_context, const pi_sampler_properties *, - pi_sampler *) -_PI_API(piSamplerGetInfo, pi_sampler, pi_sampler_info, size_t, void *, size_t *) -_PI_API(piSamplerRetain, pi_sampler) -_PI_API(piSamplerRelease, pi_sampler) +_PI_API(piSamplerCreate) +_PI_API(piSamplerGetInfo) +_PI_API(piSamplerRetain) +_PI_API(piSamplerRelease) // Queue commands -_PI_API(piEnqueueKernelLaunch, pi_queue, pi_kernel, pi_uint32, const size_t *, - const size_t *, const size_t *, pi_uint32, - const pi_event *, pi_event *) -_PI_API(piEnqueueNativeKernel, pi_queue, void (*)(void *), void *, size_t, - pi_uint32, const pi_mem *, const void **, - pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueEventsWait, pi_queue, pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueEventsWaitWithBarrier, pi_queue, pi_uint32, const pi_event *, - pi_event *) -_PI_API(piEnqueueMemBufferRead, pi_queue, pi_mem, pi_bool, size_t, size_t, - void *, pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueMemBufferReadRect, pi_queue, pi_mem, pi_bool, - pi_buff_rect_offset, pi_buff_rect_offset, - pi_buff_rect_region, size_t, size_t, size_t, - size_t, void *, pi_uint32, const pi_event *, - pi_event *) -_PI_API(piEnqueueMemBufferWrite, pi_queue, pi_mem, pi_bool, size_t, size_t, - const void *, pi_uint32, const pi_event *, - pi_event *) -_PI_API(piEnqueueMemBufferWriteRect, pi_queue, pi_mem, pi_bool, - pi_buff_rect_offset, pi_buff_rect_offset, - pi_buff_rect_region, size_t, size_t, - size_t, size_t, const void *, pi_uint32, - const pi_event *, pi_event *) -_PI_API(piEnqueueMemBufferCopy, pi_queue, pi_mem, pi_mem, size_t, size_t, - size_t, pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueMemBufferCopyRect, pi_queue, pi_mem, pi_mem, - pi_buff_rect_offset, pi_buff_rect_offset, - pi_buff_rect_region, size_t, size_t, - size_t, size_t, pi_uint32, const pi_event *, - pi_event *) -_PI_API(piEnqueueMemBufferFill, pi_queue, pi_mem, const void *, size_t, size_t, - size_t, pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueMemImageRead, pi_queue, pi_mem, pi_bool, pi_image_offset, - pi_image_region, size_t, size_t, void *, - pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueMemImageWrite, pi_queue, pi_mem, pi_bool, pi_image_offset, - pi_image_region, size_t, size_t, const void *, - pi_uint32, const pi_event *, pi_event *) -_PI_API(piEnqueueMemImageCopy, pi_queue, pi_mem, pi_mem, pi_image_offset, - pi_image_offset, pi_image_region, pi_uint32, - const pi_event *, pi_event *) -_PI_API(piEnqueueMemImageFill, pi_queue, pi_mem, const void *, const size_t *, - const size_t *, pi_uint32, const pi_event *, - pi_event *) -_PI_API(piEnqueueMemBufferMap, pi_queue, pi_mem, pi_bool, pi_map_flags, size_t, - size_t, pi_uint32, const pi_event *, pi_event *, - void **) -_PI_API(piEnqueueMemUnmap, pi_queue, pi_mem, void *, pi_uint32, const pi_event *, - pi_event *) +_PI_API(piEnqueueKernelLaunch) +_PI_API(piEnqueueNativeKernel) +_PI_API(piEnqueueEventsWait) +_PI_API(piEnqueueEventsWaitWithBarrier) +_PI_API(piEnqueueMemBufferRead) +_PI_API(piEnqueueMemBufferReadRect) +_PI_API(piEnqueueMemBufferWrite) +_PI_API(piEnqueueMemBufferWriteRect) +_PI_API(piEnqueueMemBufferCopy) +_PI_API(piEnqueueMemBufferCopyRect) +_PI_API(piEnqueueMemBufferFill) +_PI_API(piEnqueueMemImageRead) +_PI_API(piEnqueueMemImageWrite) +_PI_API(piEnqueueMemImageCopy) +_PI_API(piEnqueueMemImageFill) +_PI_API(piEnqueueMemBufferMap) +_PI_API(piEnqueueMemUnmap) // USM -_PI_API(piextUSMHostAlloc, void **, pi_context, pi_usm_mem_properties *, size_t, - pi_uint32) -_PI_API(piextUSMDeviceAlloc, void **, pi_context, pi_device, - pi_usm_mem_properties *, size_t, pi_uint32) -_PI_API(piextUSMSharedAlloc, void **, pi_context, pi_device, - pi_usm_mem_properties *, size_t, pi_uint32) -_PI_API(piextUSMFree, pi_context, void *) -_PI_API(piextUSMEnqueueMemset, pi_queue, void *, pi_int32, size_t, pi_uint32, - const pi_event *, pi_event *) -_PI_API(piextUSMEnqueueMemcpy, pi_queue, pi_bool, void *, const void *, size_t, - pi_uint32, const pi_event *, pi_event *) -_PI_API(piextUSMEnqueuePrefetch, pi_queue, const void *, size_t, - pi_usm_migration_flags, pi_uint32, - const pi_event *, pi_event *) -_PI_API(piextUSMEnqueueMemAdvise, pi_queue, const void *, size_t, pi_mem_advice, - pi_event *) -_PI_API(piextUSMGetMemAllocInfo, pi_context, const void *, pi_mem_info, size_t, - void *, size_t *) +_PI_API(piextUSMHostAlloc) +_PI_API(piextUSMDeviceAlloc) +_PI_API(piextUSMSharedAlloc) +_PI_API(piextUSMFree) +_PI_API(piextUSMEnqueueMemset) +_PI_API(piextUSMEnqueueMemcpy) +_PI_API(piextUSMEnqueuePrefetch) +_PI_API(piextUSMEnqueueMemAdvise) +_PI_API(piextUSMGetMemAllocInfo) -_PI_API(piextKernelSetArgMemObj, pi_kernel, pi_uint32, const pi_mem *) -_PI_API(piextKernelSetArgSampler, pi_kernel, pi_uint32, const pi_sampler *) +_PI_API(piextKernelSetArgMemObj) +_PI_API(piextKernelSetArgSampler) -_PI_API(piextPluginGetOpaqueData, void *, void **) +_PI_API(piextPluginGetOpaqueData) -_PI_API(piTearDown, void *) +_PI_API(piTearDown) #undef _PI_API diff --git a/sycl/include/CL/sycl/detail/pi.h b/sycl/include/CL/sycl/detail/pi.h index 08aafa6357a84..d682e35ef8f47 100644 --- a/sycl/include/CL/sycl/detail/pi.h +++ b/sycl/include/CL/sycl/detail/pi.h @@ -1666,7 +1666,7 @@ struct _pi_plugin { char PluginVersion[4]; char *Targets; struct FunctionPointers { -#define _PI_API(api, ...) decltype(::api) *api; +#define _PI_API(api) decltype(::api) *api; #include } PiFunctionTable; }; diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index 7afb4b39f45bd..a5e626329c28b 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -40,7 +40,7 @@ class context; namespace detail { enum class PiApiKind { -#define _PI_API(api, ...) api, +#define _PI_API(api) api, #include }; class plugin; @@ -162,7 +162,7 @@ template __SYCL_EXPORT const plugin &getPlugin(); // Utility Functions to get Function Name for a PI Api. template struct PiFuncInfo {}; -#define _PI_API(api, ...) \ +#define _PI_API(api) \ template <> struct PiFuncInfo { \ using FuncPtrT = decltype(&::api); \ inline const char *getFuncName() { return #api; } \ diff --git a/sycl/include/CL/sycl/detail/type_traits.hpp b/sycl/include/CL/sycl/detail/type_traits.hpp index d1f45601c500f..c70347bb4826f 100644 --- a/sycl/include/CL/sycl/detail/type_traits.hpp +++ b/sycl/include/CL/sycl/detail/type_traits.hpp @@ -14,6 +14,7 @@ #include #include +#include #include __SYCL_INLINE_NAMESPACE(cl) { @@ -344,6 +345,12 @@ template using const_if_const_AS = DataT; #endif +template struct function_traits {}; + +template struct function_traits { + using ret_type = Ret; + using args_type = std::tuple; +}; } // namespace detail } // namespace sycl diff --git a/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp b/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp index 932bda81c2819..63fc720f49eee 100644 --- a/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp +++ b/sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp @@ -1245,7 +1245,7 @@ pi_result piPluginInit(pi_plugin *PluginInit) { PiESimdDeviceAccess->data = reinterpret_cast(new sycl::detail::ESIMDDeviceInterface()); -#define _PI_API(api, ...) \ +#define _PI_API(api) \ (PluginInit->PiFunctionTable).api = (decltype(&::api))(&api); #include diff --git a/sycl/plugins/level_zero/pi_level_zero.cpp b/sycl/plugins/level_zero/pi_level_zero.cpp index b2c520c8b9e98..f0ac45704d08a 100644 --- a/sycl/plugins/level_zero/pi_level_zero.cpp +++ b/sycl/plugins/level_zero/pi_level_zero.cpp @@ -6452,7 +6452,7 @@ pi_result piPluginInit(pi_plugin *PluginInit) { strncpy(PluginInit->PluginVersion, _PI_H_VERSION_STRING, PluginVersionSize); -#define _PI_API(api, ...) \ +#define _PI_API(api) \ (PluginInit->PiFunctionTable).api = (decltype(&::api))(&api); #include diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index b16d425f8ef1b..a5161d3457a0c 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -33,9 +34,9 @@ struct array_fill_helper; template struct PiApiArgTuple; -#define _PI_API(api, ...) \ +#define _PI_API(api) \ template <> struct PiApiArgTuple { \ - using type = std::tuple<__VA_ARGS__>; \ + using type = typename function_traits::args_type; \ }; #include diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index a4e43382b34bf..45fe7dc24e976 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -50,8 +50,8 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, GStreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, tpCallback); -#define _PI_API(api, ...) \ - ArgHandler.set##_##api([](auto &&... Args) { \ +#define _PI_API(api) \ + ArgHandler.set##_##api([](auto &&...Args) { \ std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 698992a4583f6..4551ad04b87bd 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -9,6 +9,7 @@ #pragma once #include +#include #include #include @@ -37,6 +38,12 @@ inline TupleT unpack(char *Data, return {get(Data, std::make_index_sequence{})...}; } +template struct to_function {}; + +template struct to_function> { + using type = std::function; +}; + /// PiArgumentsHandler is a helper class to process incoming XPTI function call /// events and unpack contained arguments. /// @@ -53,7 +60,7 @@ inline TupleT unpack(char *Data, class PiArgumentsHandler { public: void handle(uint32_t ID, void *ArgsData) { -#define _PI_API(api, ...) \ +#define _PI_API(api) \ if (ID == static_cast(detail::PiApiKind::api)) { \ MHandler##_##api(ArgsData); \ return; \ @@ -62,10 +69,14 @@ class PiArgumentsHandler { #undef _PI_API } -#define _PI_API(api, ...) \ - void set##_##api(std::function Handler) { \ +#define _PI_API(api) \ + void set##_##api( \ + const typename to_function< \ + typename detail::function_traits::args_type>::type \ + &Handler) { \ MHandler##_##api = [Handler](void *Data) { \ - using TupleT = std::tuple<__VA_ARGS__>; \ + using TupleT = \ + typename detail::function_traits::args_type; \ TupleT Tuple = unpack( \ (char *)Data, \ std::make_index_sequence::value>{}); \ @@ -76,7 +87,7 @@ class PiArgumentsHandler { #undef _PI_API private: -#define _PI_API(api, ...) \ +#define _PI_API(api) \ std::function MHandler##_##api = [](void *) {}; #include #undef _PI_API diff --git a/sycl/unittests/helpers/PiMock.hpp b/sycl/unittests/helpers/PiMock.hpp index 1a1c83895e8b5..9d08a01cd53d8 100644 --- a/sycl/unittests/helpers/PiMock.hpp +++ b/sycl/unittests/helpers/PiMock.hpp @@ -47,7 +47,7 @@ namespace RT = detail::pi; /// \param MPlugin is a pointer to the PiPlugin instance that will be modified. /// \param FuncPtr is a pointer to the function that will override the original. /// function table entry -#define _PI_API(api, ...) \ +#define _PI_API(api) \ template \ inline void setFuncPtr(RT::PiPlugin *MPlugin, decltype(&::api) FuncPtr); \ template <> \ From 2e3321b8763747277eb20cc96a47e6c5d5ea87ff Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Tue, 6 Jul 2021 21:40:59 +0300 Subject: [PATCH 23/24] clang-format --- sycl/tools/pi-trace/pi_trace.cpp | 2 +- sycl/tools/xpti_helpers/pi_arguments_handler.hpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sycl/tools/pi-trace/pi_trace.cpp b/sycl/tools/pi-trace/pi_trace.cpp index 45fe7dc24e976..3fee6fd9f13e3 100644 --- a/sycl/tools/pi-trace/pi_trace.cpp +++ b/sycl/tools/pi-trace/pi_trace.cpp @@ -51,7 +51,7 @@ XPTI_CALLBACK_API void xptiTraceInit(unsigned int major_version, tpCallback); #define _PI_API(api) \ - ArgHandler.set##_##api([](auto &&...Args) { \ + ArgHandler.set##_##api([](auto &&... Args) { \ std::cout << "---> " << #api << "(" \ << "\n"; \ sycl::detail::pi::printArgs(Args...); \ diff --git a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp index 4551ad04b87bd..4cad50ba90c66 100644 --- a/sycl/tools/xpti_helpers/pi_arguments_handler.hpp +++ b/sycl/tools/xpti_helpers/pi_arguments_handler.hpp @@ -71,9 +71,8 @@ class PiArgumentsHandler { #define _PI_API(api) \ void set##_##api( \ - const typename to_function< \ - typename detail::function_traits::args_type>::type \ - &Handler) { \ + const typename to_function::args_type>::type &Handler) { \ MHandler##_##api = [Handler](void *Data) { \ using TupleT = \ typename detail::function_traits::args_type; \ From 0b08a096d347a173457e6c7a14cfc2b6381fec54 Mon Sep 17 00:00:00 2001 From: Alexander Batashev Date: Thu, 8 Jul 2021 20:48:10 +0300 Subject: [PATCH 24/24] slight changes to xpti interfaces --- sycl/include/CL/sycl/detail/common.hpp | 2 +- sycl/include/CL/sycl/detail/pi.hpp | 7 +++++-- sycl/source/detail/pi.cpp | 17 ++++++++++------- sycl/source/detail/plugin.hpp | 4 ++-- xpti/include/xpti_data_types.h | 2 ++ 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/sycl/include/CL/sycl/detail/common.hpp b/sycl/include/CL/sycl/detail/common.hpp index 166f84cc4dbc9..f277f470c2e77 100644 --- a/sycl/include/CL/sycl/detail/common.hpp +++ b/sycl/include/CL/sycl/detail/common.hpp @@ -33,7 +33,7 @@ constexpr const char *SYCL_STREAM_NAME = "sycl"; constexpr const char *SYCL_PICALL_STREAM_NAME = "sycl.pi"; // Stream name being used for traces generated from PI calls. This stream // contains information about function arguments. -constexpr const char *SYCL_PIARGCALL_STREAM_NAME = "sycl.pi.arg"; +constexpr const char *SYCL_PIDEBUGCALL_STREAM_NAME = "sycl.pi.debug"; // Data structure that captures the user code location information using the // builtin capabilities of the compiler struct code_location { diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index a5e626329c28b..4d621d2e33113 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -187,8 +187,9 @@ void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName); /// Notifies XPTI subscribers about PI function calls and packs call arguments. /// /// \param FuncID is the API hash ID from PiApiID type trait. +/// \param FName The name of the PI API call. /// \param ArgsData is a pointer to packed function call arguments. -uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FName, unsigned char *ArgsData); /// Notifies XPTI subscribers about PI function call result. @@ -196,10 +197,12 @@ uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, /// \param CorrelationID The correlation ID for the API call generated by the /// emitFunctionWithArgsBeginTrace() call. /// \param FuncID is the API hash ID from PiApiID type trait. +/// \param FName The name of the PI API call. /// \param ArgsData is a pointer to packed function call arguments. /// \param Result is function call result value. void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, - unsigned char *ArgsData, pi_result Result); + const char *FName, unsigned char *ArgsData, + pi_result Result); // A wrapper for passing around byte array properties class ByteArray { diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 8bd7dd667420a..7549a0195c0df 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -137,15 +137,16 @@ void emitFunctionEndTrace(uint64_t CorrelationID, const char *FName) { #endif // XPTI_ENABLE_INSTRUMENTATION } -uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, +uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, const char *FuncName, unsigned char *ArgsData) { uint64_t CorrelationID = 0; #ifdef XPTI_ENABLE_INSTRUMENTATION if (xptiTraceEnabled()) { - uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + uint8_t StreamID = xptiRegisterStream(SYCL_PIDEBUGCALL_STREAM_NAME); CorrelationID = xptiGetUniqueId(); - xpti::function_with_args_t Payload{FuncID, ArgsData, nullptr, nullptr}; + xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData, nullptr, + nullptr}; xptiNotifySubscribers( StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_begin, @@ -156,12 +157,14 @@ uint64_t emitFunctionWithArgsBeginTrace(uint32_t FuncID, } void emitFunctionWithArgsEndTrace(uint64_t CorrelationID, uint32_t FuncID, - unsigned char *ArgsData, pi_result Result) { + const char *FuncName, unsigned char *ArgsData, + pi_result Result) { #ifdef XPTI_ENABLE_INSTRUMENTATION if (xptiTraceEnabled()) { - uint8_t StreamID = xptiRegisterStream(SYCL_PIARGCALL_STREAM_NAME); + uint8_t StreamID = xptiRegisterStream(SYCL_PIDEBUGCALL_STREAM_NAME); - xpti::function_with_args_t Payload{FuncID, ArgsData, &Result, nullptr}; + xpti::function_with_args_t Payload{FuncID, FuncName, ArgsData, &Result, + nullptr}; xptiNotifySubscribers( StreamID, (uint16_t)xpti::trace_point_type_t::function_with_args_end, @@ -466,7 +469,7 @@ static void initializePlugins(std::vector *Plugins) { xptiMakeEvent("PI Layer", &PIPayload, xpti::trace_algorithm_event, xpti_at::active, &PiInstanceNo); - xptiInitialize(SYCL_PIARGCALL_STREAM_NAME, GMajVer, GMinVer, GVerStr); + xptiInitialize(SYCL_PIDEBUGCALL_STREAM_NAME, GMajVer, GMinVer, GVerStr); xpti::payload_t PIArgPayload( "Plugin Interface Layer (with function arguments)"); uint64_t PiArgInstanceNo; diff --git a/sycl/source/detail/plugin.hpp b/sycl/source/detail/plugin.hpp index a5161d3457a0c..c7933c86db554 100644 --- a/sycl/source/detail/plugin.hpp +++ b/sycl/source/detail/plugin.hpp @@ -134,7 +134,7 @@ class plugin { auto ArgsData = packCallArguments(std::forward(Args)...); uint64_t CorrelationIDWithArgs = pi::emitFunctionWithArgsBeginTrace( - static_cast(PiApiOffset), ArgsData.data()); + static_cast(PiApiOffset), PIFnName, ArgsData.data()); #endif RT::PiResult R; if (pi::trace(pi::TraceLevel::PI_TRACE_CALLS)) { @@ -155,7 +155,7 @@ class plugin { pi::emitFunctionEndTrace(CorrelationID, PIFnName); pi::emitFunctionWithArgsEndTrace(CorrelationIDWithArgs, static_cast(PiApiOffset), - ArgsData.data(), R); + PIFnName, ArgsData.data(), R); #endif return R; } diff --git a/xpti/include/xpti_data_types.h b/xpti/include/xpti_data_types.h index 6717a092fc48d..82a845b51138e 100644 --- a/xpti/include/xpti_data_types.h +++ b/xpti/include/xpti_data_types.h @@ -168,6 +168,8 @@ struct function_with_args_t { /// A stable API function ID. It is a contract between the profiled system and /// subscribers. uint32_t function_id; + /// A null-terminated string, containing human-readable function name. + const char *function_name; /// Pointer to packed function arguments. void *args_data; /// Pointer to the return value of the function.