nvtx.hpp
1 /*
2  * Copyright (c) 2025, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <cstdint>
19 
20 #include <nvtx3/nvtx3.hpp>
21 
22 #include <kvikio/shim/cuda.hpp>
23 #include <kvikio/utils.hpp>
24 
25 namespace kvikio {
26 
31  static constexpr char const* name{"libkvikio"};
32 };
33 
34 using nvtx_scoped_range_type = nvtx3::scoped_range_in<libkvikio_domain>;
35 using nvtx_registered_string_type = nvtx3::registered_string_in<libkvikio_domain>;
36 
37 // Macro to concatenate two tokens x and y.
38 #define KVIKIO_CONCAT_HELPER(x, y) x##y
39 #define KVIKIO_CONCAT(x, y) KVIKIO_CONCAT_HELPER(x, y)
40 
41 // Macro to create a static, registered string that will not have a name conflict with any
42 // registered string defined in the same scope.
43 #define KVIKIO_REGISTER_STRING(message) \
44  [](const char* a_message) -> auto& { \
45  static kvikio::nvtx_registered_string_type a_reg_str{a_message}; \
46  return a_reg_str; \
47  }(message)
48 
49 // Implementation of KVIKIO_NVTX_FUNC_RANGE()
50 // todo: Although supported by many compilers, __PRETTY_FUNCTION__ is non-standard. Replacement may
51 // be considered once reflection is standardized.
52 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_0() KVIKIO_NVTX_SCOPED_RANGE_IMPL_1(__PRETTY_FUNCTION__)
53 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_1(payload) \
54  KVIKIO_NVTX_SCOPED_RANGE_IMPL_2(__PRETTY_FUNCTION__, payload)
55 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_2(payload, color) \
56  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(__PRETTY_FUNCTION__, payload, color)
57 #define KVIKIO_NVTX_FUNC_RANGE_SELECTOR(_0, _1, _2, NAME, ...) NAME
58 // todo: Although supported by gcc and clang, ##__VA_ARGS__ is non-standard, and should be replaced
59 // by __VA_OPT__ (since C++20) in the future.
60 #define KVIKIO_NVTX_FUNC_RANGE_IMPL(...) \
61  KVIKIO_NVTX_FUNC_RANGE_SELECTOR(_0, \
62  ##__VA_ARGS__, \
63  KVIKIO_NVTX_FUNC_RANGE_IMPL_2, \
64  KVIKIO_NVTX_FUNC_RANGE_IMPL_1, \
65  KVIKIO_NVTX_FUNC_RANGE_IMPL_0) \
66  (__VA_ARGS__)
67 
68 // Implementation of KVIKIO_NVTX_SCOPED_RANGE(...)
69 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_1(message) \
70  kvikio::nvtx_scoped_range_type KVIKIO_CONCAT(_kvikio_nvtx_range, __LINE__) \
71  { \
72  nvtx3::event_attributes \
73  { \
74  KVIKIO_REGISTER_STRING(message), kvikio::NvtxManager::default_color() \
75  } \
76  }
77 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(message, payload_v, color) \
78  kvikio::nvtx_scoped_range_type KVIKIO_CONCAT(_kvikio_nvtx_range, __LINE__) \
79  { \
80  nvtx3::event_attributes \
81  { \
82  KVIKIO_REGISTER_STRING(message), nvtx3::payload{kvikio::convert_to_64bit(payload_v)}, color \
83  } \
84  }
85 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_2(message, payload) \
86  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(message, payload, kvikio::NvtxManager::default_color())
87 #define KVIKIO_NVTX_SCOPED_RANGE_SELECTOR(_1, _2, _3, NAME, ...) NAME
88 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL(...) \
89  KVIKIO_NVTX_SCOPED_RANGE_SELECTOR(__VA_ARGS__, \
90  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3, \
91  KVIKIO_NVTX_SCOPED_RANGE_IMPL_2, \
92  KVIKIO_NVTX_SCOPED_RANGE_IMPL_1) \
93  (__VA_ARGS__)
94 
95 // Implementation of KVIKIO_NVTX_MARKER(message, payload)
96 #define KVIKIO_NVTX_MARKER_IMPL(message, payload_v) \
97  nvtx3::mark_in<kvikio::libkvikio_domain>(nvtx3::event_attributes{ \
98  KVIKIO_REGISTER_STRING(message), nvtx3::payload{kvikio::convert_to_64bit(payload_v)}})
99 
100 using nvtx_color_type = nvtx3::color;
101 
105 class NvtxManager {
106  public:
107  static NvtxManager& instance() noexcept;
108 
114  static const nvtx_color_type& default_color() noexcept;
115 
124  static const nvtx_color_type& get_color_by_index(std::uint64_t idx) noexcept;
125 
132  static void rename_current_thread(std::string_view new_name) noexcept;
133 
134  NvtxManager(NvtxManager const&) = delete;
135  NvtxManager& operator=(NvtxManager const&) = delete;
136  NvtxManager(NvtxManager&&) = delete;
137  NvtxManager& operator=(NvtxManager&&) = delete;
138 
139  private:
140  NvtxManager() = default;
141 };
142 
175 #define KVIKIO_NVTX_FUNC_RANGE(...) KVIKIO_NVTX_FUNC_RANGE_IMPL(__VA_ARGS__)
176 
194 #define KVIKIO_NVTX_SCOPED_RANGE(...) KVIKIO_NVTX_SCOPED_RANGE_IMPL(__VA_ARGS__)
195 
214 #define KVIKIO_NVTX_MARKER(message, payload) KVIKIO_NVTX_MARKER_IMPL(message, payload)
215 
216 } // namespace kvikio
Utility singleton class for NVTX annotation.
Definition: nvtx.hpp:105
static void rename_current_thread(std::string_view new_name) noexcept
Rename the current thread under the KvikIO NVTX domain.
static const nvtx_color_type & get_color_by_index(std::uint64_t idx) noexcept
Return the color at the given index from the internal color palette whose size n is a power of 2....
static const nvtx_color_type & default_color() noexcept
Return the default color.
KvikIO namespace.
Definition: batch.hpp:27
Tag type for libkvikio's NVTX domain.
Definition: nvtx.hpp:30