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.0.0
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)
171
172inline bool
173operator==(const rocprofiler_agent_v0_t& lhs, const rocprofiler_agent_v0_t& rhs)
174{
175 return (lhs.id == rhs.id);
176}
177
178inline bool
179operator==(rocprofiler_dim3_t lhs, rocprofiler_dim3_t rhs)
180{
181 return std::tie(lhs.x, lhs.y, lhs.z) == std::tie(rhs.x, rhs.y, rhs.z);
182}
183
184inline bool
187{
188 namespace op = ::rocprofiler::sdk::operators;
189 return op::tie_sv(lhs.id, lhs.instance_size, lhs.name) ==
190 op::tie_sv(rhs.id, rhs.instance_size, rhs.name);
191}
192
193inline bool
194operator==(const rocprofiler_counter_dimension_info_t& lhs,
196{
197 namespace op = ::rocprofiler::sdk::operators;
198 return op::tie_sv(lhs.dimension_name, lhs.index, lhs.size) ==
199 op::tie_sv(rhs.dimension_name, rhs.index, rhs.size);
200}
201
202inline bool
205{
206 if(std::tie(lhs.instance_id, lhs.counter_id, lhs.dimensions_count) !=
207 std::tie(rhs.instance_id, rhs.counter_id, rhs.dimensions_count))
208 {
209 return false;
210 }
211
212 for(uint64_t i = 0; i < lhs.dimensions_count; ++i)
213 {
214 if(lhs.dimensions[i] == nullptr && rhs.dimensions[i] == nullptr) continue;
215 if(!lhs.dimensions[i] || !rhs.dimensions[i] || *lhs.dimensions[i] != *rhs.dimensions[i])
216 {
217 return false;
218 }
219 }
220
221 return true;
222}
223
224inline bool
226{
227 return std::tie(lhs.major, lhs.minor, lhs.patch) == std::tie(rhs.major, rhs.minor, rhs.patch);
228}
229
230inline bool
232{
233 return std::tie(lhs.code_object_id, lhs.address) == std::tie(rhs.code_object_id, rhs.address);
234}
235
236// definitions of operator!=
237ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_context_id_t)
238ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_address_t)
239ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_agent_id_t)
240ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_queue_id_t)
241ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_stream_id_t)
242ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_buffer_id_t)
243ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_counter_id_t)
244ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_counter_config_id_t)
245ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_callback_thread_t)
246ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_agent_t)
247ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_signal_t)
248ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_executable_t)
249ROCPROFILER_CXX_DEFINE_NE_OPERATOR(const rocprofiler_agent_v0_t&)
250ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_dim3_t)
251ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_region_t)
252ROCPROFILER_CXX_DEFINE_NE_OPERATOR(hsa_amd_memory_pool_t)
253ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_version_triplet_t)
254ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_thread_trace_decoder_id_t)
255ROCPROFILER_CXX_DEFINE_NE_OPERATOR(rocprofiler_thread_trace_decoder_pc_t)
256
257// definitions of operator<
258ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_context_id_t)
259ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_address_t)
260ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_agent_id_t)
261ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_queue_id_t)
262ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_stream_id_t)
263ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_buffer_id_t)
264ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_counter_id_t)
265ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_counter_config_id_t)
266ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_callback_thread_t)
267ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_agent_t)
268ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_signal_t)
269ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_executable_t)
270ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_region_t)
271ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(hsa_amd_memory_pool_t)
272ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR(rocprofiler_thread_trace_decoder_id_t)
273
274inline bool
277{
278 namespace op = ::rocprofiler::sdk::operators;
279 return op::tie_sv(lhs.id, lhs.instance_size, lhs.name) <
280 op::tie_sv(rhs.id, rhs.instance_size, rhs.name);
281}
282
283inline bool
284operator<(const rocprofiler_counter_dimension_info_t& lhs,
286{
287 namespace op = ::rocprofiler::sdk::operators;
288 return op::tie_sv(lhs.dimension_name, lhs.index, lhs.size) <
289 op::tie_sv(rhs.dimension_name, rhs.index, rhs.size);
290}
291
292inline bool
295{
296 if(lhs.instance_id != rhs.instance_id) return lhs.instance_id < rhs.instance_id;
297 if(lhs.counter_id != rhs.counter_id) return lhs.counter_id < rhs.counter_id;
299 return lhs.dimensions_count < rhs.dimensions_count;
300
301 for(uint64_t i = 0; i < lhs.dimensions_count; ++i)
302 {
303 if(!lhs.dimensions[i] || !rhs.dimensions[i]) return *lhs.dimensions[i] < *rhs.dimensions[i];
304 }
305
306 return false;
307}
308
309inline bool
310operator<(const rocprofiler_agent_v0_t& lhs, const rocprofiler_agent_v0_t& rhs)
311{
312 return (lhs.id < rhs.id);
313}
314
315inline bool
316operator<(rocprofiler_dim3_t lhs, rocprofiler_dim3_t rhs)
317{
318 const auto magnitude = [](rocprofiler_dim3_t dim_v) { return dim_v.x * dim_v.y * dim_v.z; };
319 auto lhs_m = magnitude(lhs);
320 auto rhs_m = magnitude(rhs);
321
322 return (lhs_m == rhs_m) ? std::tie(lhs.x, lhs.y, lhs.z) < std::tie(rhs.x, rhs.y, rhs.z)
323 : (lhs_m < rhs_m);
324}
325
326inline bool
328{
329 return std::tie(lhs.major, lhs.minor, lhs.patch) < std::tie(rhs.major, rhs.minor, rhs.patch);
330}
331
332inline bool
334{
335 return std::tie(lhs.code_object_id, lhs.address) < std::tie(rhs.code_object_id, rhs.address);
336}
337
338// definitions of operator>, operator<=, operator>=
339ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_context_id_t)
340ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_address_t)
341ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_agent_id_t)
342ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_queue_id_t)
343ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_stream_id_t)
344ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_buffer_id_t)
345ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_counter_id_t)
346ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_counter_config_id_t)
347ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_callback_thread_t)
348ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_agent_t)
349ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_signal_t)
350ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_executable_t)
351ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(const rocprofiler_agent_v0_t&)
352ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_dim3_t)
353ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_region_t)
354ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(hsa_amd_memory_pool_t)
355ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_version_triplet_t)
356ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_thread_trace_decoder_id_t)
357ROCPROFILER_CXX_DEFINE_COMPARE_OPERATORS(rocprofiler_thread_trace_decoder_pc_t)
358
359// cleanup defines
360#undef ROCPROFILER_CXX_DECLARE_OPERATORS
361#undef ROCPROFILER_CXX_DEFINE_NE_OPERATOR
362#undef ROCPROFILER_CXX_DEFINE_EQ_HANDLE_OPERATOR
363#undef ROCPROFILER_CXX_DEFINE_LT_HANDLE_OPERATOR
364#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:821
Agent Identifier.
Definition fwd.h:677
Context ID.
Definition fwd.h:600
Profile Configurations.
Definition fwd.h:694
Counter ID.
Definition fwd.h:685
(experimental) Details for the dimension, including its size, for a counter record.
Definition fwd.h:818
Multi-dimensional struct of data used to describe GPU workgroup and grid sizes.
Definition fwd.h:702
Versioning info.
Definition fwd.h:590
Stores memory address for profiling.
Definition fwd.h:565
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.