OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nvtx_helpers.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
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 
17 #include "Shared/nvtx_helpers.h"
18 
19 #include <array>
20 #include <sstream>
21 
22 #ifdef _WIN32
23 #include <processthreadsapi.h>
24 #else // _WIN32
25 #include <sys/syscall.h>
26 #include <unistd.h>
27 #endif // _WIN32
28 
29 #include <boost/filesystem/path.hpp>
30 
31 #include "Logger/Logger.h"
32 
33 namespace nvtx_helpers {
34 struct CategoryInfo {
35  uint32_t category;
36  uint32_t color;
37 };
38 
39 #define NUM_CATEGORIES 4u
40 static std::array<CategoryInfo, NUM_CATEGORIES> g_category_infos = {};
42 
43 // Control whether or not to set the event category when using the Omnisci domain
44 // Setting the category can clutter the timeline event names. Colors will still be
45 // used though so the visual organization remains
46 #define SET_OMNISCI_EVENT_CATEGORY 0
47 
48 void init() {
49  // The domain will be null if NVTX profiling is not enabled by the nsys launcher
50  g_omnisci_domain = nvtxDomainCreateA("Omnisci");
51  if (g_omnisci_domain) {
52  auto create_category = [](Category c, const char* name, uint32_t color) {
53  auto category_index = static_cast<uint32_t>(c);
54  CHECK_LT(category_index, NUM_CATEGORIES);
55  g_category_infos[category_index] = {category_index, color};
56  nvtxDomainNameCategoryA(g_omnisci_domain, category_index, name);
57  };
58  // skip category 0 (none), as trying to modify it triggers errors during nsight
59  // analysis
60  create_category(Category::kDebugTimer, "DebugTimer", 0xFFB0E0E6);
61  create_category(Category::kQueryStateTimer, "QueryStateTimer", 0xFF98FB98);
62  create_category(Category::kRenderLogger, "RenderLogger", 0xFFEE8AA);
63  }
64 }
65 
66 void shutdown() {
67  if (g_omnisci_domain) {
68  nvtxDomainDestroy(g_omnisci_domain);
69  g_omnisci_domain = nullptr;
70  }
71 }
72 
74  return g_omnisci_domain;
75 }
76 
77 namespace {
78 inline nvtxEventAttributes_t make_omnisci_event(Category c, const char* name) {
79  auto category_index = static_cast<uint32_t>(c);
80  CHECK_LT(category_index, NUM_CATEGORIES);
81  auto const& info = g_category_infos[category_index];
82  nvtxEventAttributes_t event_attrib = {};
83  event_attrib.version = NVTX_VERSION;
84  event_attrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
85  event_attrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
86  event_attrib.message.ascii = name;
87  if (info.color != 0) {
88  event_attrib.colorType = NVTX_COLOR_ARGB;
89  event_attrib.color = info.color;
90  }
91 #if SET_OMNISCI_EVENT_CATEGORY
92  event_attrib.category = info.category;
93 #endif
94  return event_attrib;
95 }
96 
97 // Return last component of path
98 std::string filename(char const* path) {
99  return boost::filesystem::path(path).filename().string();
100 }
101 } // namespace
102 
103 void omnisci_range_push(Category c, const char* name, const char* file) {
104  if (g_omnisci_domain) {
105  if (file) {
106  std::stringstream ss;
107  ss << name;
108  ss << " | " << filename(file);
109  auto str = ss.str();
110  auto event = make_omnisci_event(c, str.c_str());
111  nvtxDomainRangePushEx(g_omnisci_domain, &event);
112  } else {
113  auto event = make_omnisci_event(c, name);
114  nvtxDomainRangePushEx(g_omnisci_domain, &event);
115  }
116  }
117 }
118 
120  if (g_omnisci_domain) {
121  nvtxDomainRangePop(g_omnisci_domain);
122  }
123 }
124 
126  if (g_omnisci_domain) {
127  auto event = make_omnisci_event(c, name);
128  return nvtxDomainRangeStartEx(g_omnisci_domain, &event);
129  } else {
130  return nvtxRangeId_t{};
131  }
132 }
133 
135  if (g_omnisci_domain) {
136  nvtxDomainRangeEnd(g_omnisci_domain, r);
137  }
138 }
139 
140 void omnisci_set_mark(Category c, const char* name) {
141  if (g_omnisci_domain) {
142  auto event = make_omnisci_event(c, name);
143  nvtxDomainMarkEx(g_omnisci_domain, &event);
144  }
145 }
146 
147 void name_current_thread(const char* name) {
148 #ifdef _WIN32
149  uint32_t thread_id = GetCurrentThreadId();
150 #else
151 #ifdef SYS_gettid
152  uint32_t thread_id = static_cast<uint32_t>(syscall(SYS_gettid));
153 #else // SYS_gettid
154 #error "SYS_gettid unavailable on this system"
155 #endif // SYS_gettid
156 #endif // _WIN32
157  nvtxNameOsThreadA(thread_id, name);
158 }
159 
160 } // namespace nvtx_helpers
const nvtxDomainHandle_t get_omnisci_domain()
void omnisci_range_end(nvtxRangeId_t r)
void omnisci_range_pop()
void omnisci_range_push(Category c, const char *name, const char *file)
static std::array< CategoryInfo, NUM_CATEGORIES > g_category_infos
static nvtxDomainHandle_t g_omnisci_domain
void name_current_thread(const char *name)
#define CHECK_LT(x, y)
Definition: Logger.h:232
void omnisci_set_mark(Category c, const char *name)
uint64_t nvtxRangeId_t
Definition: nvtx_helpers.h:26
ThreadId thread_id()
Definition: Logger.cpp:820
nvtxEventAttributes_t make_omnisci_event(Category c, const char *name)
#define NUM_CATEGORIES
string name
Definition: setup.in.py:72
nvtxRangeId_t omnisci_range_start(Category c, const char *name)
void * nvtxDomainHandle_t
Definition: nvtx_helpers.h:25