rocprofiler-sdk/cxx/operators.hpp Source File

rocprofiler-sdk/cxx/operators.hpp Source File#

ROCprofiler-SDK developer API: rocprofiler-sdk/cxx/operators.hpp Source File
ROCprofiler-SDK developer API 1.3.5
ROCm Profiling API and tools
operators.hpp
1// MIT License
2//
3// Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22//
23
24#pragma once
25
26#include <rocprofiler-sdk/agent.h>
27#include <rocprofiler-sdk/counters.h>
28#include <rocprofiler-sdk/defines.h>
29#include <rocprofiler-sdk/experimental/thread-trace/trace_decoder.h>
30#include <rocprofiler-sdk/fwd.h>
31#include <rocprofiler-sdk/hsa.h>
32#include <rocprofiler-sdk/internal_threading.h>
33
34#include "rocprofiler-sdk/cxx/details/mpl.hpp"
35
36#include <string_view>
37#include <tuple>
38
39#define ROCPROFILER_CXX_DECLARE_OPERATORS(TYPE) \
40 bool operator==(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure); \
41 bool operator!=(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure); \
42 bool operator<(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure); \
43 bool operator>(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure); \
44 bool operator<=(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure); \
45 bool operator>=(TYPE lhs, TYPE rhs) ROCPROFILER_ATTRIBUTE(pure);
46
47#define ROCPROFILER_CXX_DEFINE_NE_OPERATOR(TYPE) \
48 inline bool operator!=(TYPE lhs, TYPE rhs) { return !(lhs == rhs); }
49
50#define ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(TYPE) \
51 inline bool operator==(TYPE lhs, TYPE rhs) \
52 { \
53 return ::rocprofiler::sdk::operators::equal(lhs, rhs); \
54 }
55
56#define ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(TYPE) \
57 inline bool operator<(TYPE lhs, TYPE rhs) \
58 { \
59 return ::rocprofiler::sdk::operators::less(lhs, rhs); \
60 }
61
62#define ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(TYPE) \
63 inline bool operator>(TYPE lhs, TYPE rhs) { return !(lhs == rhs || lhs < rhs); } \
64 inline bool operator<=(TYPE lhs, TYPE rhs) { return (lhs == rhs || lhs < rhs); } \
65 inline bool operator>=(TYPE lhs, TYPE rhs) { return !(lhs < rhs); }
66
67namespace rocprofiler
68{
69namespace sdk
70{
71namespace operators
72{
73template <typename Tp>
74bool
75equal(Tp lhs, Tp rhs) ROCPROFILER_ATTRIBUTE(pure);
76
77template <typename Tp>
78bool
79less(Tp lhs, Tp rhs) ROCPROFILER_ATTRIBUTE(pure);
80
81template <typename Tp>
82bool
83equal(Tp lhs, Tp rhs)
84{
85 static_assert(sizeof(Tp) == sizeof(uint64_t), "error! only for opaque handle types");
86 return lhs.handle == rhs.handle;
87}
88
89template <typename Tp>
90bool
91less(Tp lhs, Tp rhs)
92{
93 static_assert(sizeof(Tp) == sizeof(uint64_t), "error! only for opaque handle types");
94 return lhs.handle < rhs.handle;
95}
96
97namespace detail
98{
99template <typename Tp>
100struct sv_trait
101{
102 static constexpr auto is_string_type() noexcept
103 {
104 return mpl::is_string_type<mpl::unqualified_identity_t<Tp>>::value;
105 }
106
107 using type = std::conditional_t<is_string_type(), std::string_view, Tp&>;
108
109 constexpr type operator()(Tp& v) noexcept
110 {
111 if constexpr(is_string_type())
112 return std::string_view{v};
113 else
114 return v;
115 }
116};
117} // namespace detail
118
119// tie_sv(): deduce each Tp from your lvalues, then build tuple<...> out of
120// either Tp& or std::string_view, calling operator() on each.
121template <typename... Tp>
122constexpr auto
123tie_sv(Tp&... vs) noexcept
124{
125 return std::make_tuple(detail::sv_trait<Tp>{}(vs)...);
126}
127} // namespace operators
128} // namespace sdk
129} // namespace rocprofiler
130
131// declaration of operator== and operator!=
132ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_context_id_t)
133ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_address_t)
134ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_agent_id_t)
135ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_queue_id_t)
136ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_stream_id_t)
137ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_buffer_id_t)
138ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_counter_id_t)
139ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_counter_config_id_t)
140ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_callback_thread_t)
141ROCPROFILER_CXX_DECLARE_OPERATORS(hsa_agent_t)
142ROCPROFILER_CXX_DECLARE_OPERATORS(hsa_signal_t)
143ROCPROFILER_CXX_DECLARE_OPERATORS(hsa_executable_t)
144ROCPROFILER_CXX_DECLARE_OPERATORS(const rocprofiler_agent_v0_t&)
145ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_dim3_t)
146ROCPROFILER_CXX_DECLARE_OPERATORS(hsa_region_t)
147ROCPROFILER_CXX_DECLARE_OPERATORS(hsa_amd_memory_pool_t)
148ROCPROFILER_CXX_DECLARE_OPERATORS(const rocprofiler_counter_record_dimension_info_t&)
149ROCPROFILER_CXX_DECLARE_OPERATORS(const rocprofiler_counter_record_dimension_instance_info_t&)
150ROCPROFILER_CXX_DECLARE_OPERATORS(const rocprofiler_counter_dimension_info_t&)
151ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_version_triplet_t)
152ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_thread_trace_decoder_id_t)
153ROCPROFILER_CXX_DECLARE_OPERATORS(rocprofiler_thread_trace_decoder_pc_t)
154
155// definitions of operator==
156ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_context_id_t)
157ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_address_t)
158ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_agent_id_t)
159ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_queue_id_t)
160ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_stream_id_t)
161ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_buffer_id_t)
162ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_counter_id_t)
163ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_counter_config_id_t)
164ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_callback_thread_t)
165ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(hsa_agent_t)
166ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(hsa_signal_t)
167ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(hsa_executable_t)
168ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(hsa_region_t)
169ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(hsa_amd_memory_pool_t)
170ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_thread_trace_decoder_id_t)
171ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_graph_exec_id_t)
172ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR(rocprofiler_graph_node_id_t)
173
174inline bool
175operator==(const rocprofiler_agent_v0_t& lhs, const rocprofiler_agent_v0_t& rhs)
176{
177 return (lhs.id == rhs.id);
178}
179
180inline bool
181operator==(rocprofiler_dim3_t lhs, rocprofiler_dim3_t rhs)
182{
183 return std::tie(lhs.x, lhs.y, lhs.z) == std::tie(rhs.x, rhs.y, rhs.z);
184}
185
186inline bool
189{
190 namespace op = ::rocprofiler::sdk::operators;
191 return op::tie_sv(lhs.id, lhs.instance_size, lhs.name) ==
192 op::tie_sv(rhs.id, rhs.instance_size, rhs.name);
193}
194
195inline bool
196operator==(const rocprofiler_counter_dimension_info_t& lhs,
198{
199 namespace op = ::rocprofiler::sdk::operators;
200 return op::tie_sv(lhs.dimension_name, lhs.index, lhs.size) ==
201 op::tie_sv(rhs.dimension_name, rhs.index, rhs.size);
202}
203
204inline bool
207{
208 if(std::tie(lhs.instance_id, lhs.counter_id, lhs.dimensions_count) !=
209 std::tie(rhs.instance_id, rhs.counter_id, rhs.dimensions_count))
210 {
211 return false;
212 }
213
214 for(uint64_t i = 0; i < lhs.dimensions_count; ++i)
215 {
216 if(lhs.dimensions[i] == nullptr && rhs.dimensions[i] == nullptr) continue;
217 if(!lhs.dimensions[i] || !rhs.dimensions[i] || *lhs.dimensions[i] != *rhs.dimensions[i])
218 {
219 return false;
220 }
221 }
222
223 return true;
224}
225
226inline bool
228{
229 return std::tie(lhs.major, lhs.minor, lhs.patch) == std::tie(rhs.major, rhs.minor, rhs.patch);
230}
231
232inline bool
234{
235 return std::tie(lhs.code_object_id, lhs.address) == std::tie(rhs.code_object_id, rhs.address);
236}
237
238// definitions of operator!=
239ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_context_id_t)
240ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_address_t)
241ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_agent_id_t)
242ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_queue_id_t)
243ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_stream_id_t)
244ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_buffer_id_t)
245ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_counter_id_t)
246ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_counter_config_id_t)
247ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_callback_thread_t)
248ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_agent_t)
249ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_signal_t)
250ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_executable_t)
251ROCPROFILER_CXX_DEFINE_NE_OPERATOR(const rocprofiler_agent_v0_t&)
252ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_dim3_t)
253ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_region_t)
254ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_amd_memory_pool_t)
255ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_version_triplet_t)
256ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_thread_trace_decoder_id_t)
257ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_thread_trace_decoder_pc_t)
258ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_graph_exec_id_t)
259ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_graph_node_id_t)
260
261// definitions of operator<
262ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_context_id_t)
263ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_address_t)
264ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_agent_id_t)
265ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_queue_id_t)
266ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_stream_id_t)
267ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_buffer_id_t)
268ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_counter_id_t)
269ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_counter_config_id_t)
270ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_callback_thread_t)
271ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_agent_t)
272ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_signal_t)
273ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_executable_t)
274ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_region_t)
275ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_amd_memory_pool_t)
276ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_thread_trace_decoder_id_t)
277ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_graph_exec_id_t)
278ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_graph_node_id_t)
279
280inline bool
283{
284 namespace op = ::rocprofiler::sdk::operators;
285 return op::tie_sv(lhs.id, lhs.instance_size, lhs.name) <
286 op::tie_sv(rhs.id, rhs.instance_size, rhs.name);
287}
288
289inline bool
290operator<(const rocprofiler_counter_dimension_info_t& lhs,
292{
293 namespace op = ::rocprofiler::sdk::operators;
294 return op::tie_sv(lhs.dimension_name, lhs.index, lhs.size) <
295 op::tie_sv(rhs.dimension_name, rhs.index, rhs.size);
296}
297
298inline bool
301{
302 if(lhs.instance_id != rhs.instance_id) return lhs.instance_id < rhs.instance_id;
303 if(lhs.counter_id != rhs.counter_id) return lhs.counter_id < rhs.counter_id;
305 return lhs.dimensions_count < rhs.dimensions_count;
306
307 for(uint64_t i = 0; i < lhs.dimensions_count; ++i)
308 {
309 if(!lhs.dimensions[i] || !rhs.dimensions[i]) return *lhs.dimensions[i] < *rhs.dimensions[i];
310 }
311
312 return false;
313}
314
315inline bool
316operator<(const rocprofiler_agent_v0_t& lhs, const rocprofiler_agent_v0_t& rhs)
317{
318 return (lhs.id < rhs.id);
319}
320
321inline bool
322operator<(rocprofiler_dim3_t lhs, rocprofiler_dim3_t rhs)
323{
324 const auto magnitude = [](rocprofiler_dim3_t dim_v) { return dim_v.x * dim_v.y * dim_v.z; };
325 auto lhs_m = magnitude(lhs);
326 auto rhs_m = magnitude(rhs);
327
328 return (lhs_m == rhs_m) ? std::tie(lhs.x, lhs.y, lhs.z) < std::tie(rhs.x, rhs.y, rhs.z)
329 : (lhs_m < rhs_m);
330}
331
332inline bool
334{
335 return std::tie(lhs.major, lhs.minor, lhs.patch) < std::tie(rhs.major, rhs.minor, rhs.patch);
336}
337
338inline bool
340{
341 return std::tie(lhs.code_object_id, lhs.address) < std::tie(rhs.code_object_id, rhs.address);
342}
343
344// definitions of operator>, operator<=, operator>=
345ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_context_id_t)
346ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_address_t)
347ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_agent_id_t)
348ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_queue_id_t)
349ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_stream_id_t)
350ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_buffer_id_t)
351ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_counter_id_t)
352ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_counter_config_id_t)
353ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_callback_thread_t)
354ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_agent_t)
355ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_signal_t)
356ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_executable_t)
357ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(const rocprofiler_agent_v0_t&)
358ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_dim3_t)
359ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_region_t)
360ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_amd_memory_pool_t)
361ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_version_triplet_t)
362ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_thread_trace_decoder_id_t)
363ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_thread_trace_decoder_pc_t)
364ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_graph_exec_id_t)
365ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_graph_node_id_t)
366
367// cleanup defines
368#undef ROCPROFILER_CXX_DECLARE_OPERATORS
369#undef ROCPROFILER_CXX_DEFINE_NE_OPERATOR
370#undef ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR
371#undef ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR
372#undef ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS
rocprofiler_agent_id_t id
Internal opaque identifier.
Definition agent.h:134
Stores the properties of an agent (CPU, GPU, etc.)
Definition agent.h:131
rocprofiler_counter_dimension_id_t id
Id for this dimension used by rocprofiler_query_record_dimension_position.
Definition fwd.h:887
Agent Identifier.
Definition fwd.h:743
Context ID.
Definition fwd.h:648
Profile Configurations.
Definition fwd.h:760
Counter ID.
Definition fwd.h:751
(experimental) Details for the dimension, including its size, for a counter record.
Definition fwd.h:884
Multi-dimensional struct of data used to describe GPU workgroup and grid sizes.
Definition fwd.h:768
HIP graph executable instance ID. Process-monotonic identifier assigned by rocprofiler-sdk for each s...
Definition fwd.h:673
Zero-based HIP graph node ordinal within a graph launch. A handle of 0 can be the first node when pai...
Definition fwd.h:682
Versioning info.
Definition fwd.h:638
Stores memory address for profiling.
Definition fwd.h:613
const rocprofiler_counter_dimension_info_t ** dimensions
Array of pointers to dimension info structures, each representing one dimension and the position of t...
Definition counters.h:88
const char * dimension_name
Name of the dimension this instance belongs to.
Definition counters.h:62
uint64_t size
Size of this structure. Used for versioning and validation.
Definition counters.h:61
uint64_t counter_id
Identifier of the counter associated with this instance.
Definition counters.h:86
uint64_t dimensions_count
Number of dimensions associated with this instance.
Definition counters.h:87
rocprofiler_counter_instance_id_t instance_id
Encoded identifier for the instance, which includes the counter ID and all dimension positions.
Definition counters.h:85
unsigned long index
Position (zero-based) of the instance within the specified dimension.
Definition counters.h:63
(experimental) Represents metadata about a single dimension of a counter instance.
Definition counters.h:60
(experimental) Describes a specific counter instance and its position across multiple dimensions.
Definition counters.h:83
(experimental) opaque handle to an internal thread identifier which delivers callbacks for buffers
uint64_t address
Address (code_object_id == 0), or ELF vaddr (code_object_id != 0)
uint64_t code_object_id
Zero if no code object was found.
Handle containing a loaded rocprof-trace-decoder and a decoder state.