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 #ifdef KVIKIO_CUDA_FOUND
21 #include <nvtx3/nvtx3.hpp>
22 #endif
23 
24 #include <kvikio/shim/cuda.hpp>
25 #include <kvikio/utils.hpp>
26 
27 namespace kvikio {
28 
29 #ifdef KVIKIO_CUDA_FOUND
33 struct libkvikio_domain {
34  static constexpr char const* name{"libkvikio"};
35 };
36 
37 using nvtx_scoped_range_type = nvtx3::scoped_range_in<libkvikio_domain>;
38 using nvtx_registered_string_type = nvtx3::registered_string_in<libkvikio_domain>;
39 
40 // Macro to concatenate two tokens x and y.
41 #define KVIKIO_CONCAT_HELPER(x, y) x##y
42 #define KVIKIO_CONCAT(x, y) KVIKIO_CONCAT_HELPER(x, y)
43 
44 // Macro to create a static, registered string that will not have a name conflict with any
45 // registered string defined in the same scope.
46 #define KVIKIO_REGISTER_STRING(message) \
47  [](const char* a_message) -> auto& { \
48  static kvikio::nvtx_registered_string_type a_reg_str{a_message}; \
49  return a_reg_str; \
50  }(message)
51 
52 // Implementation of KVIKIO_NVTX_FUNC_RANGE()
53 // todo: Although supported by many compilers, __PRETTY_FUNCTION__ is non-standard. Replacement may
54 // be considered once reflection is standardized.
55 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_0() KVIKIO_NVTX_SCOPED_RANGE_IMPL_1(__PRETTY_FUNCTION__)
56 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_1(payload) \
57  KVIKIO_NVTX_SCOPED_RANGE_IMPL_2(__PRETTY_FUNCTION__, payload)
58 #define KVIKIO_NVTX_FUNC_RANGE_IMPL_2(payload, color) \
59  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(__PRETTY_FUNCTION__, payload, color)
60 #define KVIKIO_NVTX_FUNC_RANGE_SELECTOR(_0, _1, _2, NAME, ...) NAME
61 // todo: Although supported by gcc and clang, ##__VA_ARGS__ is non-standard, and should be replaced
62 // by __VA_OPT__ (since C++20) in the future.
63 #define KVIKIO_NVTX_FUNC_RANGE_IMPL(...) \
64  KVIKIO_NVTX_FUNC_RANGE_SELECTOR(_0, \
65  ##__VA_ARGS__, \
66  KVIKIO_NVTX_FUNC_RANGE_IMPL_2, \
67  KVIKIO_NVTX_FUNC_RANGE_IMPL_1, \
68  KVIKIO_NVTX_FUNC_RANGE_IMPL_0) \
69  (__VA_ARGS__)
70 
71 // Implementation of KVIKIO_NVTX_SCOPED_RANGE(...)
72 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_1(message) \
73  kvikio::nvtx_scoped_range_type KVIKIO_CONCAT(_kvikio_nvtx_range, __LINE__) \
74  { \
75  nvtx3::event_attributes \
76  { \
77  KVIKIO_REGISTER_STRING(message), kvikio::NvtxManager::default_color() \
78  } \
79  }
80 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(message, payload_v, color) \
81  kvikio::nvtx_scoped_range_type KVIKIO_CONCAT(_kvikio_nvtx_range, __LINE__) \
82  { \
83  nvtx3::event_attributes \
84  { \
85  KVIKIO_REGISTER_STRING(message), nvtx3::payload{kvikio::convert_to_64bit(payload_v)}, color \
86  } \
87  }
88 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL_2(message, payload) \
89  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3(message, payload, kvikio::NvtxManager::default_color())
90 #define KVIKIO_NVTX_SCOPED_RANGE_SELECTOR(_1, _2, _3, NAME, ...) NAME
91 #define KVIKIO_NVTX_SCOPED_RANGE_IMPL(...) \
92  KVIKIO_NVTX_SCOPED_RANGE_SELECTOR(__VA_ARGS__, \
93  KVIKIO_NVTX_SCOPED_RANGE_IMPL_3, \
94  KVIKIO_NVTX_SCOPED_RANGE_IMPL_2, \
95  KVIKIO_NVTX_SCOPED_RANGE_IMPL_1) \
96  (__VA_ARGS__)
97 
98 // Implementation of KVIKIO_NVTX_MARKER(message, payload)
99 #define KVIKIO_NVTX_MARKER_IMPL(message, payload_v) \
100  nvtx3::mark_in<kvikio::libkvikio_domain>(nvtx3::event_attributes{ \
101  KVIKIO_REGISTER_STRING(message), nvtx3::payload{kvikio::convert_to_64bit(payload_v)}})
102 
103 #endif
104 
105 #ifdef KVIKIO_CUDA_FOUND
106 using nvtx_color_type = nvtx3::color;
107 #else
108 using nvtx_color_type = int;
109 #endif
110 
114 class NvtxManager {
115  public:
116  static NvtxManager& instance() noexcept;
117 
123  static const nvtx_color_type& default_color() noexcept;
124 
133  static const nvtx_color_type& get_color_by_index(std::uint64_t idx) noexcept;
134 
141  static void rename_current_thread(std::string_view new_name) noexcept;
142 
143  NvtxManager(NvtxManager const&) = delete;
144  NvtxManager& operator=(NvtxManager const&) = delete;
145  NvtxManager(NvtxManager&&) = delete;
146  NvtxManager& operator=(NvtxManager&&) = delete;
147 
148  private:
149  NvtxManager() = default;
150 };
151 
184 #ifdef KVIKIO_CUDA_FOUND
185 #define KVIKIO_NVTX_FUNC_RANGE(...) KVIKIO_NVTX_FUNC_RANGE_IMPL(__VA_ARGS__)
186 #else
187 #define KVIKIO_NVTX_FUNC_RANGE(...) \
188  do { \
189  } while (0)
190 #endif
191 
209 #ifdef KVIKIO_CUDA_FOUND
210 #define KVIKIO_NVTX_SCOPED_RANGE(...) KVIKIO_NVTX_SCOPED_RANGE_IMPL(__VA_ARGS__)
211 #else
212 #define KVIKIO_NVTX_SCOPED_RANGE(message, payload, ...) \
213  do { \
214  } while (0)
215 #endif
216 
235 #ifdef KVIKIO_CUDA_FOUND
236 #define KVIKIO_NVTX_MARKER(message, payload) KVIKIO_NVTX_MARKER_IMPL(message, payload)
237 #else
238 #define KVIKIO_NVTX_MARKER(message, payload) \
239  do { \
240  } while (0)
241 #endif
242 
243 } // namespace kvikio
Utility singleton class for NVTX annotation.
Definition: nvtx.hpp:114
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