diff --git a/projects/rocprofiler-sdk/source/bin/rocprofv3.py b/projects/rocprofiler-sdk/source/bin/rocprofv3.py index 31eb815e8a..5797cdefe0 100755 --- a/projects/rocprofiler-sdk/source/bin/rocprofv3.py +++ b/projects/rocprofiler-sdk/source/bin/rocprofv3.py @@ -542,6 +542,12 @@ For MPI applications (or other job launchers such as SLURM), place rocprofv3 ins help="List available PC sampling configurations and metrics for counter collection. Backed by a valid YAML file. In earlier rocprof versions, this was known as --list-basic, --list-derived and --list-counters", ) + add_parser_bool_argument( + display_options, + "--group-by-queue", + help="For displaying the HIP streams that kernels and memory copy operations are submitted to rather than HSA queues.", + ) + advanced_options = parser.add_argument_group("Advanced options") advanced_options.add_argument( @@ -1043,6 +1049,7 @@ def run(app_args, args, **kwargs): ["memory_copy_trace", "MEMORY_COPY_TRACE"], ["memory_allocation_trace", "MEMORY_ALLOCATION_TRACE"], ["scratch_memory_trace", "SCRATCH_MEMORY_TRACE"], + ["group_by_queue", "GROUP_BY_QUEUE"], ] ).items(): val = getattr(args, f"{opt}") diff --git a/projects/rocprofiler-sdk/source/docs/data/kernel_trace.csv b/projects/rocprofiler-sdk/source/docs/data/kernel_trace.csv index b0725387aa..5ac9bfc003 100644 --- a/projects/rocprofiler-sdk/source/docs/data/kernel_trace.csv +++ b/projects/rocprofiler-sdk/source/docs/data/kernel_trace.csv @@ -1,9 +1,9 @@ -"Kind","Agent_Id","Queue_Id","Thread_Id","Dispatch_Id","Kernel_Id","Kernel_Name","Correlation_Id","Start_Timestamp","End_Timestamp","Private_Segment_Size","Group_Segment_Size","Workgroup_Size_X","Workgroup_Size_Y","Workgroup_Size_Z","Grid_Size_X","Grid_Size_Y","Grid_Size_Z" -"KERNEL_DISPATCH",1,1,69,1,16,"void addition_kernel(float*, float const*, float const*, int, int)",1451,8819330200067564,8819330200116308,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,2,69,5,16,"void addition_kernel(float*, float const*, float const*, int, int)",1484,8819330200118678,8819330200219573,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,1,69,2,19,"subtract_kernel(float*, float const*, float const*, int, int)",1459,8819330200120456,8819330200223721,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,3,69,9,16,"void addition_kernel(float*, float const*, float const*, int, int)",1517,8819330200152902,8819330200283428,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,4,69,13,16,"void addition_kernel(float*, float const*, float const*, int, int)",1550,8819330200187127,8819330200320468,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,2,69,6,19,"subtract_kernel(float*, float const*, float const*, int, int)",1492,8819330200225499,8819330200364618,0,0,64,1,1,1024,1024,1 -"KERNEL_DISPATCH",1,1,69,3,18,"multiply_kernel(float*, float const*, float const*, int, int)",1467,8819330200229796,8819330200369359,0,0,64,1,1,1024,1024,1 - +"Kind","Agent_Id","Queue_Id","Stream_Id","Thread_Id","Dispatch_Id","Kernel_Id","Kernel_Name","Correlation_Id","Start_Timestamp","End_Timestamp","Private_Segment_Size","Group_Segment_Size","Workgroup_Size_X","Workgroup_Size_Y","Workgroup_Size_Z","Grid_Size_X","Grid_Size_Y","Grid_Size_Z" +"KERNEL_DISPATCH",2,1,1,21228,1,11,"void addition_kernel(float*, float const*, float const*, int, int)",1937,2414192765353337,2414192765369494,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,1,1,21228,2,14,"subtract_kernel(float*, float const*, float const*, int, int)",1945,2414192765424862,2414192765435326,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,1,1,21228,3,13,"multiply_kernel(float*, float const*, float const*, int, int)",1953,2414192765487486,2414192765497669,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,1,1,21228,4,12,"divide_kernel(float*, float const*, float const*, int, int)",1961,2414192765545619,2414192765555722,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,2,2,21228,5,11,"void addition_kernel(float*, float const*, float const*, int, int)",1969,2414192765608844,2414192765621674,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,2,2,21228,6,14,"subtract_kernel(float*, float const*, float const*, int, int)",1977,2414192765658519,2414192765669424,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,2,2,21228,7,13,"multiply_kernel(float*, float const*, float const*, int, int)",1985,2414192765715650,2414192765726795,0,0,64,1,1,1024,1024,1 +"KERNEL_DISPATCH",2,2,2,21228,8,12,"divide_kernel(float*, float const*, float const*, int, int)",1993,2414192765773422,2414192765784969,0,0,64,1,1,1024,1024,1 diff --git a/projects/rocprofiler-sdk/source/docs/data/memory_copy_trace.csv b/projects/rocprofiler-sdk/source/docs/data/memory_copy_trace.csv index 49f7e4a730..90ab0151d6 100644 --- a/projects/rocprofiler-sdk/source/docs/data/memory_copy_trace.csv +++ b/projects/rocprofiler-sdk/source/docs/data/memory_copy_trace.csv @@ -1,3 +1,5 @@ -"Kind","Direction","Source_Agent_Id","Destination_Agent_Id","Correlation_Id","Start_Timestamp","End_Timestamp" -"MEMORY_COPY","MEMORY_COPY_HOST_TO_DEVICE",0,1,0,14955949675563,14955950239443 -"MEMORY_COPY","MEMORY_COPY_DEVICE_TO_HOST",1,0,0,14955952733485,14955953315285 \ No newline at end of file +"Kind","Direction","Stream_Id","Source_Agent_Id","Destination_Agent_Id","Correlation_Id","Start_Timestamp","End_Timestamp" +"MEMORY_COPY","MEMORY_COPY_HOST_TO_DEVICE",1,0,2,952,2414192684609085,2414192684710679 +"MEMORY_COPY","MEMORY_COPY_HOST_TO_DEVICE",1,0,2,960,2414192684873841,2414192684973470 +"MEMORY_COPY","MEMORY_COPY_HOST_TO_DEVICE",2,0,2,1066,2414192706436949,2414192706538622 +"MEMORY_COPY","MEMORY_COPY_HOST_TO_DEVICE",2,0,2,1074,2414192706592442,2414192706692312 diff --git a/projects/rocprofiler-sdk/source/docs/how-to/using-rocprofv3.rst b/projects/rocprofiler-sdk/source/docs/how-to/using-rocprofv3.rst index e93929f526..dd1688a79a 100644 --- a/projects/rocprofiler-sdk/source/docs/how-to/using-rocprofv3.rst +++ b/projects/rocprofiler-sdk/source/docs/how-to/using-rocprofv3.rst @@ -354,7 +354,7 @@ Here are the contents of ``kernel_trace.csv`` file: .. csv-table:: Kernel trace :file: /data/kernel_trace.csv - :widths: 10,10,10,10,10,10,10,10,20,20,10,10,10,10,10,10,10,10 + :widths: 10,10,10,10,10,10,10,10,10,20,20,10,10,10,10,10,10,10,10 :header-rows: 1 For the description of the fields in the output file, see :ref:`output-file-fields`. @@ -378,7 +378,7 @@ Here are the contents of ``memory_copy_trace.csv`` file: .. csv-table:: Memory copy trace :file: /data/memory_copy_trace.csv - :widths: 10,10,10,10,10,20,20 + :widths: 10,10,10,10,10,10,20,20 :header-rows: 1 For the description of the fields in the output file, see :ref:`output-file-fields`. @@ -1086,6 +1086,9 @@ The following table lists the various fields or the columns in the output CSV fi * - Queue_Id - ROCm queue unique identifier to which the kernel was submitted. + * - Stream_Id + - Identifies HIP stream ID to which kernel or memory copy operation was submitted. Defaults to 0 if the hip-stream-display option is not enabled + * - Private_Segment_Size - The amount of memory required in bytes for the combined private, spill, and arg segments for a work item. diff --git a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/callback_tracing.h b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/callback_tracing.h index cbbf8e7640..aa98d03232 100644 --- a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/callback_tracing.h +++ b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/callback_tracing.h @@ -78,7 +78,12 @@ typedef struct { uint64_t size; ///< size of this struct rocprofiler_hip_api_args_t args; - rocprofiler_hip_api_retval_t retval; + rocprofiler_hip_api_retval_t retval; ///< return value of function call + + /// @var args + /// @brief Arguments of the function call. @see + /// ::rocprofiler_iterate_callback_tracing_kind_operation_args for generic + /// access/stringification of the arguments. } rocprofiler_callback_tracing_hip_api_data_t; /** @@ -329,6 +334,15 @@ typedef struct rocprofiler_callback_tracing_runtime_initialization_data_t /// Version number is encoded as: (10000 * MAJOR) + (100 * MINOR) + PATCH } rocprofiler_callback_tracing_runtime_initialization_data_t; +/** + * @brief ROCProfiler Stream Handle Callback Data. + */ +typedef struct +{ + uint64_t size; ///< size of this struct + rocprofiler_stream_id_t stream_id; ///< HIP stream ID +} rocprofiler_callback_tracing_stream_handle_data_t; + /** * @brief API Tracing callback function. This function is invoked twice per API function: once * before the function is invoked and once after the function is invoked. The external correlation diff --git a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/hash.hpp b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/hash.hpp index bee05546ee..6fd1ea1868 100644 --- a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/hash.hpp +++ b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/hash.hpp @@ -60,6 +60,7 @@ ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_context_id_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_agent_id_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_address_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_queue_id_t) +ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_stream_id_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_buffer_id_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_counter_id_t) ROCPROFILER_CXX_SPECIALIZE_HANDLE_HASHER(rocprofiler_profile_config_id_t) diff --git a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/operators.hpp b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/operators.hpp index 37c3c6655e..67ee89c11d 100644 --- a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/operators.hpp +++ b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/operators.hpp @@ -97,6 +97,7 @@ ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_context_id_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_address_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_agent_id_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_queue_id_t) +ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_stream_id_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_buffer_id_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_counter_id_t) ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_profile_config_id_t) @@ -114,6 +115,7 @@ ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_context_id_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_address_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_agent_id_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_queue_id_t) +ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_stream_id_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_buffer_id_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_counter_id_t) ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_profile_config_id_t) @@ -141,6 +143,7 @@ ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_context_id_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_address_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_agent_id_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_queue_id_t) +ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_stream_id_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_buffer_id_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_counter_id_t) ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_profile_config_id_t) @@ -158,6 +161,7 @@ ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_context_id_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_address_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_agent_id_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_queue_id_t) +ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_stream_id_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_buffer_id_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_counter_id_t) ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_profile_config_id_t) @@ -190,6 +194,7 @@ ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_context_id_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_address_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_agent_id_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_queue_id_t) +ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_stream_id_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_buffer_id_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_counter_id_t) ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_profile_config_id_t) diff --git a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/serialization.hpp b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/serialization.hpp index ab4b634565..cd159e50c6 100644 --- a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/serialization.hpp +++ b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/cxx/serialization.hpp @@ -114,6 +114,13 @@ save(ArchiveT& ar, rocprofiler_queue_id_t data) ROCP_SDK_SAVE_DATA_FIELD(handle); } +template +void +save(ArchiveT& ar, rocprofiler_stream_id_t data) +{ + ROCP_SDK_SAVE_DATA_FIELD(handle); +} + template void save(ArchiveT& ar, rocprofiler_counter_id_t data) diff --git a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/fwd.h b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/fwd.h index 593994b4cb..40d6876fac 100644 --- a/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/fwd.h +++ b/projects/rocprofiler-sdk/source/include/rocprofiler-sdk/fwd.h @@ -178,6 +178,8 @@ typedef enum // NOLINT(performance-enum-size) ///< library has been initialized ROCPROFILER_CALLBACK_TRACING_ROCDECODE_API, ///< rocDecode API Tracing ROCPROFILER_CALLBACK_TRACING_ROCJPEG_API, ///< rocJPEG API Tracing + ROCPROFILER_CALLBACK_TRACING_HIP_STREAM_API, ///< @see + ///< ::rocprofiler_hip_stream_operation_t ROCPROFILER_CALLBACK_TRACING_LAST, } rocprofiler_callback_tracing_kind_t; @@ -209,8 +211,9 @@ typedef enum // NOLINT(performance-enum-size) ROCPROFILER_BUFFER_TRACING_RUNTIME_INITIALIZATION, ///< Record indicating a runtime library has ///< been initialized. @see ///< ::rocprofiler_runtime_initialization_operation_t - ROCPROFILER_BUFFER_TRACING_ROCDECODE_API, ///< rocDecode tracing - ROCPROFILER_BUFFER_TRACING_ROCJPEG_API, ///< rocJPEG tracing + ROCPROFILER_BUFFER_TRACING_ROCDECODE_API, ///< rocDecode tracing + ROCPROFILER_BUFFER_TRACING_ROCJPEG_API, ///< rocJPEG tracing + ROCPROFILER_BUFFER_TRACING_HIP_STREAM_API, ///< Display HIP Stream ROCPROFILER_BUFFER_TRACING_LAST, } rocprofiler_buffer_tracing_kind_t; @@ -226,6 +229,23 @@ typedef enum // NOLINT(performance-enum-size) ROCPROFILER_CODE_OBJECT_LAST, } rocprofiler_code_object_operation_t; +/** + * @brief ROCProfiler Stream Handle Operations. + */ +typedef enum // NOLINT(performance-enum-size) +{ + ROCPROFILER_HIP_STREAM_NONE = 0, ///< Unknown stream handle operation + ROCPROFILER_HIP_STREAM_CREATE, ///< A stream handle is created + ROCPROFILER_HIP_STREAM_DESTROY, ///< A stream handle is destroyed + ROCPROFILER_HIP_STREAM_SET, + ROCPROFILER_HIP_STREAM_LAST, + + /// @var ROCPROFILER_HIP_STREAM_SET + /// @brief Invokes callbacks before and after a HIP API, kernel dispatch, or memory copy + /// operation that has a stream handle associated with it. HIP API calls will always have a + /// stream, but kernel dispatches and memory copy operations may or may not. +} rocprofiler_hip_stream_operation_t; + /** * @brief Memory Copy Operations. */ @@ -556,7 +576,7 @@ typedef union rocprofiler_uuid_t /** * @brief Context ID. */ -typedef struct +typedef struct rocprofiler_context_id_t { uint64_t handle; } rocprofiler_context_id_t; @@ -564,15 +584,23 @@ typedef struct /** * @brief Queue ID. */ -typedef struct +typedef struct rocprofiler_queue_id_t { uint64_t handle; } rocprofiler_queue_id_t; +/** + * @brief Stream ID. + */ +typedef struct rocprofiler_stream_id_t +{ + uint64_t handle; +} rocprofiler_stream_id_t; + /** * @brief ROCProfiler Record Correlation ID. */ -typedef struct +typedef struct rocprofiler_correlation_id_t { uint64_t internal; rocprofiler_user_data_t external; @@ -587,7 +615,7 @@ typedef struct * @struct rocprofiler_buffer_id_t * @brief Buffer ID. */ -typedef struct +typedef struct rocprofiler_buffer_id_t { uint64_t handle; } rocprofiler_buffer_id_t; @@ -595,7 +623,7 @@ typedef struct /** * @brief Agent Identifier */ -typedef struct +typedef struct rocprofiler_agent_id_t { uint64_t handle; } rocprofiler_agent_id_t; @@ -603,7 +631,7 @@ typedef struct /** * @brief Counter ID. */ -typedef struct +typedef struct rocprofiler_counter_id_t { uint64_t handle; } rocprofiler_counter_id_t; @@ -612,7 +640,7 @@ typedef struct * @brief Profile Configurations * @see rocprofiler_create_profile_config for how to create. */ -typedef struct +typedef struct rocprofiler_profile_config_id_t { uint64_t handle; // Opaque handle } rocprofiler_profile_config_id_t; diff --git a/projects/rocprofiler-sdk/source/lib/common/CMakeLists.txt b/projects/rocprofiler-sdk/source/lib/common/CMakeLists.txt index bb43bc28c8..81e1c83773 100644 --- a/projects/rocprofiler-sdk/source/lib/common/CMakeLists.txt +++ b/projects/rocprofiler-sdk/source/lib/common/CMakeLists.txt @@ -52,3 +52,5 @@ target_link_libraries( set_target_properties(rocprofiler-sdk-common-library PROPERTIES OUTPUT_NAME rocprofiler-sdk-common) + +add_subdirectory(details) diff --git a/projects/rocprofiler-sdk/source/lib/common/details/CMakeLists.txt b/projects/rocprofiler-sdk/source/lib/common/details/CMakeLists.txt new file mode 100644 index 0000000000..cbfd615421 --- /dev/null +++ b/projects/rocprofiler-sdk/source/lib/common/details/CMakeLists.txt @@ -0,0 +1,8 @@ +# +# add details sources and headers to common library target +# +set(details_headers mpl.hpp) +set(details_sources) + +target_sources(rocprofiler-sdk-common-library PRIVATE ${details_sources} + ${details_headers}) diff --git a/projects/rocprofiler-sdk/source/lib/common/details/mpl.hpp b/projects/rocprofiler-sdk/source/lib/common/details/mpl.hpp new file mode 100644 index 0000000000..dcc6bd48dd --- /dev/null +++ b/projects/rocprofiler-sdk/source/lib/common/details/mpl.hpp @@ -0,0 +1,211 @@ +// MIT License +// +// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace rocprofiler +{ +namespace common +{ +namespace mpl +{ +namespace impl +{ +template +struct type_list +{ + static constexpr auto size() { return sizeof...(Tp); } +}; + +template +struct reverse; + +template