66
77#include < raft/core/detail/macros.hpp>
88
9- #include < atomic>
109#include < cstddef>
11- #include < cstdint>
1210#include < memory>
1311#include < mutex>
12+ #include < stack>
1413#include < string>
1514#include < utility>
16- #include < vector>
1715
1816namespace raft {
1917namespace common ::nvtx {
@@ -37,16 +35,6 @@ class current_range {
3735 return {value_, depth_};
3836 }
3937
40- /* *
41- * Read the full nvtx range path with instance ids, formatted as
42- * "name#id > name#id > ..." (empty when no range is active).
43- */
44- auto get_path () const -> std::string
45- {
46- std::lock_guard lock (mu_);
47- return path_;
48- }
49-
5038 operator std::string () const
5139 {
5240 std::lock_guard lock (mu_);
@@ -57,81 +45,35 @@ class current_range {
5745 mutable std::mutex mu_;
5846 std::string value_;
5947 std::size_t depth_{0 };
60- std::string path_;
6148
62- void set (const char * name, std::size_t depth, std::string path )
49+ void set (const char * name, std::size_t depth)
6350 {
6451 std::lock_guard lock (mu_);
6552 value_ = name ? name : " " ;
6653 depth_ = depth;
67- path_ = std::move (path);
6854 }
6955};
7056
7157namespace detail {
7258
73- RAFT_EXPORT inline std::atomic<std::uint64_t > range_instance_counter{0 };
74-
7559struct nvtx_range_name_stack {
7660 void push (const char * name)
7761 {
78- ensure_current ();
79- auto id = range_instance_counter.fetch_add (1 , std::memory_order_relaxed) + 1 ;
80- stack_.emplace_back (id, name ? name : " " );
81- current_->set (stack_.back ().second .c_str (), stack_.size (), build_path ());
62+ stack_.emplace (name);
63+ current_->set (name, stack_.size ());
8264 }
8365
8466 void pop ()
8567 {
86- ensure_current ();
87- if (!stack_.empty ()) { stack_.pop_back (); }
88- current_->set (
89- stack_.empty () ? nullptr : stack_.back ().second .c_str (), stack_.size (), build_path ());
90- }
91-
92- [[nodiscard]] auto current () const -> std::shared_ptr<const current_range>
93- {
94- ensure_current ();
95- return current_;
96- }
97-
98- /* *
99- * Innermost NVTX range name and stack depth.
100- * Mutex-free — ONLY safe to call from the thread that owns this stack.
101- */
102- [[nodiscard]] auto current_name_and_depth () const noexcept -> std::pair<std::string, std::size_t>
103- {
104- if (stack_.empty ()) { return {" " , 0 }; }
105- return {stack_.back ().second , stack_.size ()};
68+ if (!stack_.empty ()) { stack_.pop (); }
69+ current_->set (stack_.empty () ? nullptr : stack_.top ().c_str (), stack_.size ());
10670 }
10771
108- /* *
109- * Full NVTX range path "name#id > name#id > ...".
110- * Mutex-free — ONLY safe to call from the thread that owns this stack.
111- */
112- [[nodiscard]] auto current_path () const -> std::string { return build_path (); }
72+ auto current () const -> std::shared_ptr<const current_range> { return current_; }
11373
11474 private:
115- void ensure_current () const
116- {
117- if (!current_) { current_ = std::make_shared<current_range>(); }
118- }
119-
120- // Serialize the active stack as "name#id > name#id > ..." (outer -> inner).
121- [[nodiscard]] auto build_path () const -> std::string
122- {
123- std::string path;
124- for (auto const & [id, name] : stack_) {
125- if (!path.empty ()) { path += " > " ; }
126- path += name;
127- path += ' #' ;
128- path += std::to_string (id);
129- }
130- return path;
131- }
132-
133- std::vector<std::pair<std::uint64_t , std::string>> stack_{};
134- mutable std::shared_ptr<current_range> current_{std::make_shared<current_range>()};
75+ std::stack<std::string> stack_{};
76+ std::shared_ptr<current_range> current_{std::make_shared<current_range>()};
13577};
13678
13779RAFT_EXPORT inline thread_local nvtx_range_name_stack range_name_stack_instance{};
@@ -148,25 +90,5 @@ RAFT_EXPORT inline auto thread_local_current_range() -> std::shared_ptr<const cu
14890 return detail::range_name_stack_instance.current ();
14991}
15092
151- /* *
152- * Mutex-free read of the current thread's innermost NVTX range name and stack depth.
153- * ONLY safe to call from the thread that owns this range stack (the current thread).
154- * Use instead of thread_local_current_range()->get() when no cross-thread sharing is needed.
155- */
156- RAFT_EXPORT inline auto thread_local_current_name_and_depth () -> std::pair<std::string, std::size_t>
157- {
158- return detail::range_name_stack_instance.current_name_and_depth ();
159- }
160-
161- /* *
162- * Mutex-free read of the current thread's full NVTX range path "name#id > name#id > ...".
163- * ONLY safe to call from the thread that owns this range stack (the current thread).
164- * Use instead of thread_local_current_range()->get_path() when no cross-thread sharing is needed.
165- */
166- RAFT_EXPORT inline auto thread_local_current_path () -> std::string
167- {
168- return detail::range_name_stack_instance.current_path ();
169- }
170-
17193} // namespace common::nvtx
17294} // namespace raft
0 commit comments