NVTX C++ API Reference 1.0
C++ convenience wrappers for NVTX v3 C API
Loading...
Searching...
No Matches
nvtx3.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020-2022, 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
17/* Temporary helper #defines, #undef'ed at end of header */
18#define NVTX3_CPP_VERSION_MAJOR 1
19#define NVTX3_CPP_VERSION_MINOR 0
20
21/* This section handles the decision of whether to provide unversioned symbols.
22 * If NVTX3_CPP_REQUIRE_EXPLICIT_VERSION is #defined, unversioned symbols are
23 * not provided, and explicit-version symbols such as nvtx3::v1::scoped_range
24 * and NVTX3_V1_FUNC_RANGE must be used. By default, the first #include of this
25 * header will define the unversioned symbols such as nvtx3::scoped_range and
26 * NVTX3_FUNC_RANGE. Subsequently including a different major version of this
27 * header without #defining NVTX3_CPP_REQUIRE_EXPLICIT_VERSION triggers an error
28 * since the symbols would conflict. Subsequently including of a different
29 * minor version within the same major version is allowed. Functionality of
30 * minor versions is cumulative, regardless of include order.
31 *
32 * Since NVTX3_CPP_REQUIRE_EXPLICIT_VERSION allows all combinations of versions
33 * to coexist without problems within a translation unit, the recommended best
34 * practice for instrumenting header-based libraries with NVTX C++ Wrappers is
35 * is to #define NVTX3_CPP_REQUIRE_EXPLICIT_VERSION before including nvtx3.hpp,
36 * #undef it afterward, and only use explicit-version symbols. This is not
37 * necessary in common cases, such as instrumenting a standalone application, or
38 * static/shared libraries in .cpp files or headers private to those projects.
39 */
40/* clang-format off */
41#if !defined(NVTX3_CPP_REQUIRE_EXPLICIT_VERSION)
42 /* Define macro used by all definitions in this header to indicate the
43 * unversioned symbols should be defined in addition to the versioned ones.
44 */
45 #define NVTX3_INLINE_THIS_VERSION
46
47 #if !defined(NVTX3_CPP_INLINED_VERSION_MAJOR)
48 /* First occurrence of this header in the translation unit. Define macros
49 * indicating which version shall be used for unversioned symbols.
50 */
51
62 #define NVTX3_CPP_INLINED_VERSION_MAJOR 1 // NVTX3_CPP_VERSION_MAJOR
63
74 #define NVTX3_CPP_INLINED_VERSION_MINOR 0 // NVTX3_CPP_VERSION_MINOR
75 #elif NVTX3_CPP_INLINED_VERSION_MAJOR != NVTX3_CPP_VERSION_MAJOR
76 /* Unsupported case -- cannot define unversioned symbols for different major versions
77 * in the same translation unit.
78 */
79 #error \
80 "Two different major versions of the NVTX C++ Wrappers are being included in a single .cpp file, with unversioned symbols enabled in both. Only one major version can enable unversioned symbols in a .cpp file. To disable unversioned symbols, #define NVTX3_CPP_REQUIRE_EXPLICIT_VERSION before #including nvtx3.hpp, and use the explicit-version symbols instead -- this is the preferred way to use nvtx3.hpp from a header file."
81 #elif (NVTX3_CPP_INLINED_VERSION_MAJOR == NVTX3_CPP_VERSION_MAJOR) && \
82 (NVTX3_CPP_INLINED_VERSION_MINOR < NVTX3_CPP_VERSION_MINOR)
83 /* An older minor version of the same major version already defined unversioned
84 * symbols. The new features provided in this header will be inlined
85 * redefine the minor version macro to this header's version.
86 */
87 #undef NVTX3_CPP_INLINED_VERSION_MINOR
88 #define NVTX3_CPP_INLINED_VERSION_MINOR 0 // NVTX3_CPP_VERSION_MINOR
89 // else, already have this version or newer, nothing to do
90 #endif
91#endif
92/* clang-format on */
93
562/* Temporary helper #defines, removed with #undef at end of header */
563
564#if !defined(NVTX3_USE_CHECKED_OVERLOADS_FOR_GET)
565#if defined(_MSC_VER) && _MSC_VER < 1914
566/* Microsoft's compiler prior to VS2017 Update 7 (15.7) uses an older parser
567 * that does not work with domain::get's specialization for domain::global,
568 * and would require extra conditions to make SFINAE work for the overloaded
569 * get() functions. This macro disables use of overloaded get() in order to
570 * work with VS2015 and versions of VS2017 below 15.7, without penalizing
571 * users of newer compilers. Building with this flag set to 0 means errors
572 * when defining tag structs (see documentation for domain, named_category,
573 * and registered_string) will have more complex compiler error messages
574 * instead of the clear static_assert messages from the get() overloads.
575 */
576#define NVTX3_USE_CHECKED_OVERLOADS_FOR_GET 0
577#else
578#define NVTX3_USE_CHECKED_OVERLOADS_FOR_GET 1
579#endif
580#define NVTX3_USE_CHECKED_OVERLOADS_FOR_GET_DEFINED_HERE
581#endif
582
583/* Within this header, nvtx3::NVTX3_VERSION_NAMESPACE resolves to nvtx3::vX,
584 * where "X" is the major version number. */
585#define NVTX3_CONCAT(A, B) A##B
586#define NVTX3_NAMESPACE_FOR(VERSION) NVTX3_CONCAT(v, VERSION)
587#define NVTX3_VERSION_NAMESPACE NVTX3_NAMESPACE_FOR(NVTX3_CPP_VERSION_MAJOR)
588
589/* Avoid duplicating #if defined(NVTX3_INLINE_THIS_VERSION) for namespaces
590 * in each minor version by making a macro to use unconditionally, which
591 * resolves to "inline" or nothing as appropriate. */
592#if defined(NVTX3_INLINE_THIS_VERSION)
593#define NVTX3_INLINE_IF_REQUESTED inline
594#else
595#define NVTX3_INLINE_IF_REQUESTED
596#endif
597
598/* Enables the use of constexpr when support for C++14 constexpr is present.
599 *
600 * Initialization of a class member that is a union to a specific union member
601 * can only be done in the body of a constructor, not in a member initializer
602 * list. A constexpr constructor must have an empty body until C++14, so there
603 * is no way to make an initializer of a member union constexpr in C++11. This
604 * macro allows making functions constexpr in C++14 or newer, but non-constexpr
605 * in C++11 compilation. It is used here on constructors that initialize their
606 * member unions.
607 */
608#if __cpp_constexpr >= 201304L
609#define NVTX3_CONSTEXPR_IF_CPP14 constexpr
610#else
611#define NVTX3_CONSTEXPR_IF_CPP14
612#endif
613
614 /* Use a macro for static asserts, which defaults to static_assert, but that
615 * testing tools can replace with a logging function. For example:
616 * #define NVTX3_STATIC_ASSERT(c, m) \
617 * do { if (!(c)) printf("static_assert would fail: %s\n", m); } while (0)
618 */
619#if !defined(NVTX3_STATIC_ASSERT)
620#define NVTX3_STATIC_ASSERT(condition, message) static_assert(condition, message);
621#define NVTX3_STATIC_ASSERT_DEFINED_HERE
622#endif
623
624/* Implementation sections, enclosed in guard macros for each minor version */
625
626#ifndef NVTX3_CPP_DEFINITIONS_V1_0
627#define NVTX3_CPP_DEFINITIONS_V1_0
628
629#include "nvToolsExt.h"
630
631#include <memory>
632#include <string>
633#include <type_traits>
634#include <utility>
635#include <cstddef>
636
637namespace nvtx3 {
638
639NVTX3_INLINE_IF_REQUESTED namespace NVTX3_VERSION_NAMESPACE
640{
641
642namespace detail {
643
644template <typename Unused>
645struct always_false : std::false_type {};
646
647template <typename T, typename = void>
648struct has_name : std::false_type {};
649template <typename T>
650struct has_name<T, decltype((void)T::name, void())> : std::true_type {};
651
652template <typename T, typename = void>
653struct has_id : std::false_type {};
654template <typename T>
655struct has_id<T, decltype((void)T::id, void())> : std::true_type {};
656
657template <typename T, typename = void>
658struct has_message : std::false_type {};
659template <typename T>
660struct has_message<T, decltype((void)T::message, void())> : std::true_type {};
661
662template <typename T, typename = void>
663struct is_c_string : std::false_type {};
664template <typename T>
665struct is_c_string<T, typename std::enable_if<
666 std::is_convertible<T, char const* >::value ||
667 std::is_convertible<T, wchar_t const*>::value
668>::type> : std::true_type {};
669
670template <typename T>
671using is_uint32 = std::is_same<typename std::decay<T>::type, uint32_t>;
672
673} // namespace detail
674
728class domain {
729 public:
730 domain(domain const&) = delete;
731 domain& operator=(domain const&) = delete;
732 domain(domain&&) = delete;
733 domain& operator=(domain&&) = delete;
734
746 struct global {
747 };
748
749#if NVTX3_USE_CHECKED_OVERLOADS_FOR_GET
794 template <typename D = global,
795 typename std::enable_if<
796 detail::is_c_string<decltype(D::name)>::value
797 , int>::type = 0>
798 static domain const& get() noexcept
799 {
800 static domain const d(D::name);
801 return d;
802 }
803
809 template <typename D = global,
810 typename std::enable_if<
811 !detail::is_c_string<decltype(D::name)>::value
812 , int>::type = 0>
813 static domain const& get() noexcept
814 {
815 NVTX3_STATIC_ASSERT(detail::always_false<D>::value,
816 "Type used to identify an NVTX domain must contain a static constexpr member "
817 "called 'name' of type const char* or const wchar_t* -- 'name' member is not "
818 "convertible to either of those types");
819 static domain const unused;
820 return unused; // Function must compile for static_assert to be triggered
821 }
822
827 template <typename D = global,
828 typename std::enable_if<
829 !detail::has_name<D>::value
830 , int>::type = 0>
831 static domain const& get() noexcept
832 {
833 NVTX3_STATIC_ASSERT(detail::always_false<D>::value,
834 "Type used to identify an NVTX domain must contain a static constexpr member "
835 "called 'name' of type const char* or const wchar_t* -- 'name' member is missing");
836 static domain const unused;
837 return unused; // Function must compile for static_assert to be triggered
838 }
839#else
840 template <typename D = global>
841 static domain const& get() noexcept
842 {
843 static domain const d(D::name);
844 return d;
845 }
846#endif
847
854 operator nvtxDomainHandle_t() const noexcept { return _domain; }
855
856 private:
865 explicit domain(char const* name) noexcept : _domain{nvtxDomainCreateA(name)} {}
866
875 explicit domain(wchar_t const* name) noexcept : _domain{nvtxDomainCreateW(name)} {}
876
885 explicit domain(std::string const& name) noexcept : domain{name.c_str()} {}
886
895 explicit domain(std::wstring const& name) noexcept : domain{name.c_str()} {}
896
905 domain() noexcept {}
906
921 ~domain() = default;
922
923 private:
924 nvtxDomainHandle_t const _domain{};
925};
926
940template <>
941inline domain const& domain::get<domain::global>() noexcept
942{
943 static domain const d{};
944 return d;
945}
946
952struct rgb {
954 using component_type = uint8_t;
955
966 constexpr rgb(
967 component_type red_,
968 component_type green_,
969 component_type blue_) noexcept
970 : red{red_}, green{green_}, blue{blue_}
971 {
972 }
973
977};
978
984struct argb final : rgb {
997 constexpr argb(
998 component_type alpha_,
999 component_type red_,
1000 component_type green_,
1001 component_type blue_) noexcept
1002 : rgb{red_, green_, blue_}, alpha{alpha_}
1003 {
1004 }
1005
1007};
1008
1018class color {
1019 public:
1021 using value_type = uint32_t;
1022
1040 constexpr explicit color(value_type hex_code) noexcept : _value{hex_code} {}
1041
1048 constexpr color(argb argb_) noexcept
1049 : color{from_bytes_msb_to_lsb(argb_.alpha, argb_.red, argb_.green, argb_.blue)}
1050 {
1051 }
1052
1061 constexpr color(rgb rgb_) noexcept
1062 : color{from_bytes_msb_to_lsb(0xFF, rgb_.red, rgb_.green, rgb_.blue)}
1063 {
1064 }
1065
1070 constexpr value_type get_value() const noexcept { return _value; }
1071
1076 constexpr nvtxColorType_t get_type() const noexcept { return _type; }
1077
1078 color() = delete;
1079 ~color() = default;
1080 color(color const&) = default;
1081 color& operator=(color const&) = default;
1082 color(color&&) = default;
1083 color& operator=(color&&) = default;
1084
1085 private:
1091 constexpr static value_type from_bytes_msb_to_lsb(
1092 uint8_t byte3,
1093 uint8_t byte2,
1094 uint8_t byte1,
1095 uint8_t byte0) noexcept
1096 {
1097 return uint32_t{byte3} << 24 | uint32_t{byte2} << 16 | uint32_t{byte1} << 8 | uint32_t{byte0};
1098 }
1099
1100 value_type _value{};
1101 nvtxColorType_t _type{NVTX_COLOR_ARGB};
1102};
1103
1126 public:
1128 using id_type = uint32_t;
1129
1139 constexpr explicit category(id_type id) noexcept : id_{id} {}
1140
1145 constexpr id_type get_id() const noexcept { return id_; }
1146
1147 category() = delete;
1148 ~category() = default;
1149 category(category const&) = default;
1150 category& operator=(category const&) = default;
1151 category(category&&) = default;
1152 category& operator=(category&&) = default;
1153
1154 private:
1155 id_type id_{};
1156};
1157
1207template <typename D = domain::global>
1208class named_category_in final : public category {
1209 public:
1210#if NVTX3_USE_CHECKED_OVERLOADS_FOR_GET
1245 template <typename C,
1246 typename std::enable_if<
1247 detail::is_c_string<decltype(C::name)>::value &&
1248 detail::is_uint32<decltype(C::id)>::value
1249 , int>::type = 0>
1250 static named_category_in const& get() noexcept
1251 {
1252 static named_category_in const cat(C::id, C::name);
1253 return cat;
1254 }
1255
1262 template <typename C,
1263 typename std::enable_if<
1264 !detail::is_c_string<decltype(C::name)>::value ||
1265 !detail::is_uint32<decltype(C::id)>::value
1266 , int>::type = 0>
1267 static named_category_in const& get() noexcept
1268 {
1269 NVTX3_STATIC_ASSERT(detail::is_c_string<decltype(C::name)>::value,
1270 "Type used to name an NVTX category must contain a static constexpr member "
1271 "called 'name' of type const char* or const wchar_t* -- 'name' member is not "
1272 "convertible to either of those types");
1273 NVTX3_STATIC_ASSERT(detail::is_uint32<decltype(C::id)>::value,
1274 "Type used to name an NVTX category must contain a static constexpr member "
1275 "called 'id' of type uint32_t -- 'id' member is the wrong type");
1276 static named_category_in const unused;
1277 return unused; // Function must compile for static_assert to be triggered
1278 }
1279
1284 template <typename C,
1285 typename std::enable_if<
1286 !detail::has_name<C>::value ||
1287 !detail::has_id<C>::value
1288 , int>::type = 0>
1289 static named_category_in const& get() noexcept
1290 {
1291 NVTX3_STATIC_ASSERT(detail::has_name<C>::value,
1292 "Type used to name an NVTX category must contain a static constexpr member "
1293 "called 'name' of type const char* or const wchar_t* -- 'name' member is missing");
1294 NVTX3_STATIC_ASSERT(detail::has_id<C>::value,
1295 "Type used to name an NVTX category must contain a static constexpr member "
1296 "called 'id' of type uint32_t -- 'id' member is missing");
1297 static named_category_in const unused;
1298 return unused; // Function must compile for static_assert to be triggered
1299 }
1300#else
1301 template <typename C>
1302 static named_category_in const& get() noexcept
1303 {
1304 static named_category_in const cat(C::id, C::name);
1305 return cat;
1306 }
1307#endif
1308
1309 private:
1310 // Default constructor is only used internally for static_assert(false) cases.
1311 named_category_in() noexcept : category{0} {}
1312
1313 public:
1324 named_category_in(id_type id, char const* name) noexcept : category{id}
1325 {
1326#ifndef NVTX_DISABLE
1327 nvtxDomainNameCategoryA(domain::get<D>(), get_id(), name);
1328#else
1329 (void)id;
1330 (void)name;
1331#endif
1332 };
1333
1344 named_category_in(id_type id, wchar_t const* name) noexcept : category{id}
1345 {
1346#ifndef NVTX_DISABLE
1347 nvtxDomainNameCategoryW(domain::get<D>(), get_id(), name);
1348#else
1349 (void)id;
1350 (void)name;
1351#endif
1352 };
1353};
1354
1360
1407template <typename D = domain::global>
1409 public:
1410#if NVTX3_USE_CHECKED_OVERLOADS_FOR_GET
1444 template <typename M,
1445 typename std::enable_if<
1446 detail::is_c_string<decltype(M::message)>::value
1447 , int>::type = 0>
1448 static registered_string_in const& get() noexcept
1449 {
1450 static registered_string_in const regstr(M::message);
1451 return regstr;
1452 }
1453
1459 template <typename M,
1460 typename std::enable_if<
1461 !detail::is_c_string<decltype(M::message)>::value
1462 , int>::type = 0>
1463 static registered_string_in const& get() noexcept
1464 {
1465 NVTX3_STATIC_ASSERT(detail::always_false<M>::value,
1466 "Type used to register an NVTX string must contain a static constexpr member "
1467 "called 'message' of type const char* or const wchar_t* -- 'message' member is "
1468 "not convertible to either of those types");
1469 static registered_string_in const unused;
1470 return unused; // Function must compile for static_assert to be triggered
1471 }
1472
1477 template <typename M,
1478 typename std::enable_if<
1479 !detail::has_message<M>::value
1480 , int>::type = 0>
1481 static registered_string_in const& get() noexcept
1482 {
1483 NVTX3_STATIC_ASSERT(detail::always_false<M>::value,
1484 "Type used to register an NVTX string must contain a static constexpr member "
1485 "called 'message' of type const char* or const wchar_t* -- 'message' member "
1486 "is missing");
1487 static registered_string_in const unused;
1488 return unused; // Function must compile for static_assert to be triggered
1489 }
1490#else
1491 template <typename M>
1492 static registered_string_in const& get() noexcept
1493 {
1494 static registered_string_in const regstr(M::message);
1495 return regstr;
1496 }
1497#endif
1498
1510 explicit registered_string_in(char const* msg) noexcept
1511 : handle_{nvtxDomainRegisterStringA(domain::get<D>(), msg)}
1512 {
1513 }
1514
1526 explicit registered_string_in(std::string const& msg) noexcept
1527 : registered_string_in{msg.c_str()} {}
1528
1540 explicit registered_string_in(wchar_t const* msg) noexcept
1541 : handle_{nvtxDomainRegisterStringW(domain::get<D>(), msg)}
1542 {
1543 }
1544
1556 explicit registered_string_in(std::wstring const& msg) noexcept
1557 : registered_string_in{msg.c_str()} {}
1558
1563 nvtxStringHandle_t get_handle() const noexcept { return handle_; }
1564
1565private:
1566 // Default constructor is only used internally for static_assert(false) cases.
1567 registered_string_in() noexcept {};
1568public:
1569 ~registered_string_in() = default;
1571 registered_string_in& operator=(registered_string_in const&) = default;
1573 registered_string_in& operator=(registered_string_in&&) = default;
1574
1575 private:
1576 nvtxStringHandle_t handle_{};
1578};
1579
1585
1623class message {
1624 public:
1625 using value_type = nvtxMessageValue_t;
1626
1632 NVTX3_CONSTEXPR_IF_CPP14 message(char const* msg) noexcept : type_{NVTX_MESSAGE_TYPE_ASCII}
1633 {
1634 value_.ascii = msg;
1635 }
1636
1642 message(std::string const& msg) noexcept : message{msg.c_str()} {}
1643
1652 message(std::string&&) = delete;
1653
1659 NVTX3_CONSTEXPR_IF_CPP14 message(wchar_t const* msg) noexcept : type_{NVTX_MESSAGE_TYPE_UNICODE}
1660 {
1661 value_.unicode = msg;
1662 }
1663
1669 message(std::wstring const& msg) noexcept : message{msg.c_str()} {}
1670
1679 message(std::wstring&&) = delete;
1680
1689 template <typename D>
1690 NVTX3_CONSTEXPR_IF_CPP14 message(registered_string_in<D> const& msg) noexcept
1691 : type_{NVTX_MESSAGE_TYPE_REGISTERED}
1692 {
1693 value_.registered = msg.get_handle();
1694 }
1695
1702 constexpr message(
1703 nvtxMessageType_t const& type,
1704 nvtxMessageValue_t const& value) noexcept
1705 : type_{type}, value_(value)
1706 {
1707 }
1708
1714 NVTX3_CONSTEXPR_IF_CPP14 message(nvtxStringHandle_t handle) noexcept
1715 : type_{NVTX_MESSAGE_TYPE_REGISTERED}
1716 {
1717 value_.registered = handle;
1718 }
1719
1724 constexpr value_type get_value() const noexcept { return value_; }
1725
1730 constexpr nvtxMessageType_t get_type() const noexcept { return type_; }
1731
1732 private:
1733 nvtxMessageType_t type_{};
1734 nvtxMessageValue_t value_{};
1735};
1736
1753class payload {
1754 public:
1755 using value_type = typename nvtxEventAttributes_v2::payload_t;
1756
1762 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(int64_t value) noexcept
1763 : type_{NVTX_PAYLOAD_TYPE_INT64}, value_{}
1764 {
1765 value_.llValue = value;
1766 }
1767
1773 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(int32_t value) noexcept
1774 : type_{NVTX_PAYLOAD_TYPE_INT32}, value_{}
1775 {
1776 value_.iValue = value;
1777 }
1778
1784 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(uint64_t value) noexcept
1785 : type_{NVTX_PAYLOAD_TYPE_UNSIGNED_INT64}, value_{}
1786 {
1787 value_.ullValue = value;
1788 }
1789
1795 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(uint32_t value) noexcept
1796 : type_{NVTX_PAYLOAD_TYPE_UNSIGNED_INT32}, value_{}
1797 {
1798 value_.uiValue = value;
1799 }
1800
1807 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(float value) noexcept
1808 : type_{NVTX_PAYLOAD_TYPE_FLOAT}, value_{}
1809 {
1810 value_.fValue = value;
1811 }
1812
1819 NVTX3_CONSTEXPR_IF_CPP14 explicit payload(double value) noexcept
1820 : type_{NVTX_PAYLOAD_TYPE_DOUBLE}, value_{}
1821 {
1822 value_.dValue = value;
1823 }
1824
1831 constexpr payload(
1832 nvtxPayloadType_t const& type,
1833 value_type const& value) noexcept
1834 : type_{type}, value_(value)
1835 {
1836 }
1837
1842 constexpr value_type get_value() const noexcept { return value_; }
1843
1848 constexpr nvtxPayloadType_t get_type() const noexcept { return type_; }
1849
1850 private:
1851 nvtxPayloadType_t type_;
1852 value_type value_;
1853};
1854
1914 public:
1915 using value_type = nvtxEventAttributes_t;
1916
1921 constexpr event_attributes() noexcept
1922 : attributes_{
1923 NVTX_VERSION, // version
1924 sizeof(nvtxEventAttributes_t), // size
1925 0, // category
1926 NVTX_COLOR_UNKNOWN, // color type
1927 0, // color value
1928 NVTX_PAYLOAD_UNKNOWN, // payload type
1929 0, // reserved 4B
1930 0, // payload value (union)
1931 NVTX_MESSAGE_UNKNOWN, // message type
1932 0 // message value (union)
1933 }
1934 {
1935 }
1936
1944 template <typename... Args>
1945 NVTX3_CONSTEXPR_IF_CPP14 explicit event_attributes(category const& c, Args const&... args) noexcept
1946 : event_attributes(args...)
1947 {
1948 attributes_.category = c.get_id();
1949 }
1950
1958 template <typename... Args>
1959 NVTX3_CONSTEXPR_IF_CPP14 explicit event_attributes(color const& c, Args const&... args) noexcept
1960 : event_attributes(args...)
1961 {
1962 attributes_.color = c.get_value();
1963 attributes_.colorType = c.get_type();
1964 }
1965
1973 template <typename... Args>
1974 NVTX3_CONSTEXPR_IF_CPP14 explicit event_attributes(payload const& p, Args const&... args) noexcept
1975 : event_attributes(args...)
1976 {
1977 attributes_.payload = p.get_value();
1978 attributes_.payloadType = p.get_type();
1979 }
1980
1988 template <typename... Args>
1989 NVTX3_CONSTEXPR_IF_CPP14 explicit event_attributes(message const& m, Args const&... args) noexcept
1990 : event_attributes(args...)
1991 {
1992 attributes_.message = m.get_value();
1993 attributes_.messageType = m.get_type();
1994 }
1995
1996 ~event_attributes() = default;
1997 event_attributes(event_attributes const&) = default;
1998 event_attributes& operator=(event_attributes const&) = default;
2000 event_attributes& operator=(event_attributes&&) = default;
2001
2006 constexpr value_type const* get() const noexcept { return &attributes_; }
2007
2008 private:
2009 value_type attributes_{};
2010};
2011
2059template <class D = domain::global>
2061 public:
2076 explicit scoped_range_in(event_attributes const& attr) noexcept
2077 {
2078#ifndef NVTX_DISABLE
2079 nvtxDomainRangePushEx(domain::get<D>(), attr.get());
2080#else
2081 (void)attr;
2082#endif
2083 }
2084
2105 template <typename... Args>
2106 explicit scoped_range_in(Args const&... args) noexcept
2108 {
2109 }
2110
2117
2124 void* operator new(std::size_t) = delete;
2125
2126 scoped_range_in(scoped_range_in const&) = delete;
2127 scoped_range_in& operator=(scoped_range_in const&) = delete;
2128 scoped_range_in(scoped_range_in&&) = delete;
2129 scoped_range_in& operator=(scoped_range_in&&) = delete;
2130
2135 {
2136#ifndef NVTX_DISABLE
2137 nvtxDomainRangePop(domain::get<D>());
2138#endif
2139 }
2140};
2141
2147
2148namespace detail {
2149
2151template <typename D = domain::global>
2152class optional_scoped_range_in
2153{
2154public:
2155 optional_scoped_range_in() = default;
2156
2157 void begin(event_attributes const& attr) noexcept
2158 {
2159#ifndef NVTX_DISABLE
2160 // This class is not meant to be part of the public NVTX C++ API and should
2161 // only be used in the `NVTX3_FUNC_RANGE_IF` and `NVTX3_FUNC_RANGE_IF_IN`
2162 // macros. However, to prevent developers from misusing this class, make
2163 // sure to not start multiple ranges.
2164 if (initialized) { return; }
2165
2166 nvtxDomainRangePushEx(domain::get<D>(), attr.get());
2167 initialized = true;
2168#endif
2169 }
2170
2171 ~optional_scoped_range_in() noexcept
2172 {
2173#ifndef NVTX_DISABLE
2174 if (initialized) { nvtxDomainRangePop(domain::get<D>()); }
2175#endif
2176 }
2177
2178 void* operator new(std::size_t) = delete;
2179 optional_scoped_range_in(optional_scoped_range_in const&) = delete;
2180 optional_scoped_range_in& operator=(optional_scoped_range_in const&) = delete;
2181 optional_scoped_range_in(optional_scoped_range_in&&) = delete;
2182 optional_scoped_range_in& operator=(optional_scoped_range_in&&) = delete;
2183
2184private:
2185#ifndef NVTX_DISABLE
2186 bool initialized = false;
2187#endif
2188};
2190
2191} // namespace detail
2192
2201 using value_type = nvtxRangeId_t;
2202
2203
2208 constexpr explicit range_handle(value_type id) noexcept : _range_id{id} {}
2209
2217 constexpr range_handle() noexcept = default;
2218
2230 constexpr explicit operator bool() const noexcept { return get_value() != null_range_id; };
2231
2238 constexpr range_handle(std::nullptr_t) noexcept {}
2239
2245 constexpr value_type get_value() const noexcept { return _range_id; }
2246
2247 private:
2249 static constexpr value_type null_range_id = nvtxRangeId_t{0};
2250
2251 value_type _range_id{null_range_id};
2252};
2253
2260inline constexpr bool operator==(range_handle lhs, range_handle rhs) noexcept
2261{
2262 return lhs.get_value() == rhs.get_value();
2263}
2264
2271inline constexpr bool operator!=(range_handle lhs, range_handle rhs) noexcept { return !(lhs == rhs); }
2272
2302template <typename D = domain::global>
2304{
2305#ifndef NVTX_DISABLE
2306 return range_handle{nvtxDomainRangeStartEx(domain::get<D>(), attr.get())};
2307#else
2308 (void)attr;
2309 return {};
2310#endif
2311}
2312
2343template <typename D = domain::global, typename... Args>
2344inline range_handle start_range_in(Args const&... args) noexcept
2345{
2346#ifndef NVTX_DISABLE
2347 return start_range_in<D>(event_attributes{args...});
2348#else
2349 return {};
2350#endif
2351}
2352
2379inline range_handle start_range(event_attributes const& attr) noexcept
2380{
2381#ifndef NVTX_DISABLE
2382 return start_range_in<domain::global>(attr);
2383#else
2384 (void)attr;
2385 return {};
2386#endif
2387}
2388
2416template <typename... Args>
2417inline range_handle start_range(Args const&... args) noexcept
2418{
2419#ifndef NVTX_DISABLE
2420 return start_range_in<domain::global>(args...);
2421#else
2422 return {};
2423#endif
2424}
2425
2441template <typename D = domain::global>
2442inline void end_range_in(range_handle r) noexcept
2443{
2444#ifndef NVTX_DISABLE
2445 nvtxDomainRangeEnd(domain::get<D>(), r.get_value());
2446#else
2447 (void)r;
2448#endif
2449}
2450
2464inline void end_range(range_handle r) noexcept
2465{
2466#ifndef NVTX_DISABLE
2467 end_range_in<domain::global>(r);
2468#else
2469 (void)r;
2470#endif
2471}
2472
2494template <typename D = domain::global>
2496 public:
2510 explicit unique_range_in(event_attributes const& attr) noexcept
2511 : handle_{start_range_in<D>(attr)}
2512 {
2513 }
2514
2534 template <typename... Args>
2535 explicit unique_range_in(Args const&... args) noexcept
2537 {
2538 }
2539
2546
2551 ~unique_range_in() noexcept = default;
2552
2559 unique_range_in(unique_range_in&& other) noexcept = default;
2560
2567 unique_range_in& operator=(unique_range_in&& other) noexcept = default;
2568
2572
2575 unique_range_in& operator=(unique_range_in const&) = delete;
2576
2577 private:
2578
2579 struct end_range_handle {
2580 using pointer = range_handle;
2581 void operator()(range_handle h) const noexcept { end_range_in<D>(h); }
2582 };
2583
2585 std::unique_ptr<range_handle, end_range_handle> handle_;
2586};
2587
2593
2617template <typename D = domain::global>
2618inline void mark_in(event_attributes const& attr) noexcept
2619{
2620#ifndef NVTX_DISABLE
2621 nvtxDomainMarkEx(domain::get<D>(), attr.get());
2622#else
2623 (void)(attr);
2624#endif
2625}
2626
2654template <typename D = domain::global, typename... Args>
2655inline void mark_in(Args const&... args) noexcept
2656{
2657#ifndef NVTX_DISABLE
2658 mark_in<D>(event_attributes{args...});
2659#endif
2660}
2661
2682inline void mark(event_attributes const& attr) noexcept
2683{
2684#ifndef NVTX_DISABLE
2685 mark_in<domain::global>(attr);
2686#endif
2687}
2688
2713template <typename... Args>
2714inline void mark(Args const&... args) noexcept
2715{
2716#ifndef NVTX_DISABLE
2717 mark_in<domain::global>(args...);
2718#endif
2719}
2720
2721} // namespace NVTX3_VERSION_NAMESPACE
2722
2723} // namespace nvtx3
2724
2725#ifndef NVTX_DISABLE
2754#define NVTX3_V1_FUNC_RANGE_IN(D) \
2755 static ::nvtx3::v1::registered_string_in<D> const nvtx3_func_name__{__func__}; \
2756 static ::nvtx3::v1::event_attributes const nvtx3_func_attr__{nvtx3_func_name__}; \
2757 ::nvtx3::v1::scoped_range_in<D> const nvtx3_range__{nvtx3_func_attr__};
2758
2775#define NVTX3_V1_FUNC_RANGE_IF_IN(D, C) \
2776 ::nvtx3::v1::detail::optional_scoped_range_in<D> optional_nvtx3_range__; \
2777 if (C) { \
2778 static ::nvtx3::v1::registered_string_in<D> const nvtx3_func_name__{__func__}; \
2779 static ::nvtx3::v1::event_attributes const nvtx3_func_attr__{nvtx3_func_name__}; \
2780 optional_nvtx3_range__.begin(nvtx3_func_attr__); \
2781 }
2782#else
2783#define NVTX3_V1_FUNC_RANGE_IN(D)
2784#define NVTX3_V1_FUNC_RANGE_IF_IN(D, C)
2785#endif // NVTX_DISABLE
2786
2809#define NVTX3_V1_FUNC_RANGE() NVTX3_V1_FUNC_RANGE_IN(::nvtx3::v1::domain::global)
2810
2822#define NVTX3_V1_FUNC_RANGE_IF(C) NVTX3_V1_FUNC_RANGE_IF_IN(::nvtx3::v1::domain::global, C)
2823
2824/* When inlining this version, versioned macros must have unversioned aliases.
2825 * For each NVTX3_Vx_ #define, make an NVTX3_ alias of it here.*/
2826#if defined(NVTX3_INLINE_THIS_VERSION)
2827/* clang format off */
2828#define NVTX3_FUNC_RANGE NVTX3_V1_FUNC_RANGE
2829#define NVTX3_FUNC_RANGE_IF NVTX3_V1_FUNC_RANGE_IF
2830#define NVTX3_FUNC_RANGE_IN NVTX3_V1_FUNC_RANGE_IN
2831#define NVTX3_FUNC_RANGE_IF_IN NVTX3_V1_FUNC_RANGE_IF_IN
2832/* clang format on */
2833#endif
2834
2835#endif // NVTX3_CPP_DEFINITIONS_V1_0
2836
2837/* Add functionality for new minor versions here, by copying the above section enclosed
2838 * in #ifndef NVTX3_CPP_DEFINITIONS_Vx_y, and incrementing the minor version. This code
2839 * is an example of how additions for version 1.2 would look, indented for clarity. Note
2840 * that the versioned symbols and macros are always provided, and the unversioned symbols
2841 * are only provided if NVTX3_INLINE_THIS_VERSION was defined at the top of this header.
2842 *
2843 * \code{.cpp}
2844 * #ifndef NVTX3_CPP_DEFINITIONS_V1_2
2845 * #define NVTX3_CPP_DEFINITIONS_V1_2
2846 * namespace nvtx3 {
2847 * NVTX3_INLINE_IF_REQUESTED namespace NVTX3_VERSION_NAMESPACE {
2848 * class new_class {};
2849 * inline void new_function() {}
2850 * }
2851 * }
2852 *
2853 * // Macros must have the major version in their names:
2854 * #define NVTX3_V1_NEW_MACRO_A() ...
2855 * #define NVTX3_V1_NEW_MACRO_B() ...
2856 *
2857 * // If inlining, make aliases for the macros with the version number omitted
2858 * #if defined(NVTX3_INLINE_THIS_VERSION)
2859 * #define NVTX3_NEW_MACRO_A NVTX3_V1_NEW_MACRO_A
2860 * #define NVTX3_NEW_MACRO_B NVTX3_V1_NEW_MACRO_B
2861 * #endif
2862 * #endif // NVTX3_CPP_DEFINITIONS_V1_2
2863 * \endcode
2864 */
2865
2866/* Undefine all temporarily-defined unversioned macros, which would conflict with
2867 * subsequent includes of different versions of this header. */
2868#undef NVTX3_CPP_VERSION_MAJOR
2869#undef NVTX3_CPP_VERSION_MINOR
2870#undef NVTX3_CONCAT
2871#undef NVTX3_NAMESPACE_FOR
2872#undef NVTX3_VERSION_NAMESPACE
2873#undef NVTX3_INLINE_IF_REQUESTED
2874#undef NVTX3_CONSTEXPR_IF_CPP14
2875
2876#if defined(NVTX3_INLINE_THIS_VERSION)
2877#undef NVTX3_INLINE_THIS_VERSION
2878#endif
2879
2880#if defined(NVTX3_USE_CHECKED_OVERLOADS_FOR_GET_DEFINED_HERE)
2881#undef NVTX3_USE_CHECKED_OVERLOADS_FOR_GET_DEFINED_HERE
2882#undef NVTX3_USE_CHECKED_OVERLOADS_FOR_GET
2883#endif
2884
2885#if defined(NVTX3_STATIC_ASSERT_DEFINED_HERE)
2886#undef NVTX3_STATIC_ASSERT_DEFINED_HERE
2887#undef NVTX3_STATIC_ASSERT
2888#endif
Object for intra-domain grouping of NVTX events.
Definition: nvtx3.hpp:1125
constexpr category(id_type id) noexcept
Construct a category with the specified id.
Definition: nvtx3.hpp:1139
constexpr id_type get_id() const noexcept
Returns the id of the category.
Definition: nvtx3.hpp:1145
uint32_t id_type
Type used for categorys integer id.
Definition: nvtx3.hpp:1128
Represents a custom color that can be associated with an NVTX event via it's event_attributes.
Definition: nvtx3.hpp:1018
constexpr value_type get_value() const noexcept
Returns the colors argb hex code.
Definition: nvtx3.hpp:1070
constexpr color(rgb rgb_) noexcept
Construct a color using the red, green, blue components in rgb.
Definition: nvtx3.hpp:1061
uint32_t value_type
Type used for the color's value.
Definition: nvtx3.hpp:1021
constexpr color(value_type hex_code) noexcept
Constructs a color using the value provided by hex_code.
Definition: nvtx3.hpp:1040
constexpr color(argb argb_) noexcept
Construct a color using the alpha, red, green, blue components in argb.
Definition: nvtx3.hpp:1048
constexpr nvtxColorType_t get_type() const noexcept
Return the NVTX color type of the color.
Definition: nvtx3.hpp:1076
domains allow for grouping NVTX events into a single scope to differentiate them from events in other...
Definition: nvtx3.hpp:728
static domain const & get() noexcept
Returns reference to an instance of a function local static domain object.
Definition: nvtx3.hpp:798
Describes the attributes of a NVTX event.
Definition: nvtx3.hpp:1913
event_attributes(color const &c, Args const &... args) noexcept
Variadic constructor where the first argument is a color.
Definition: nvtx3.hpp:1959
event_attributes(category const &c, Args const &... args) noexcept
Variadic constructor where the first argument is a category.
Definition: nvtx3.hpp:1945
constexpr value_type const * get() const noexcept
Get raw pointer to underlying NVTX attributes object.
Definition: nvtx3.hpp:2006
event_attributes(payload const &p, Args const &... args) noexcept
Variadic constructor where the first argument is a payload.
Definition: nvtx3.hpp:1974
event_attributes(message const &m, Args const &... args) noexcept
Variadic constructor where the first argument is a message.
Definition: nvtx3.hpp:1989
constexpr event_attributes() noexcept
Default constructor creates an event_attributes with no category, color, payload, nor message.
Definition: nvtx3.hpp:1921
Allows associating a message string with an NVTX event via its EventAttributes.
Definition: nvtx3.hpp:1623
message(std::string const &msg) noexcept
Construct a message whose contents are specified by msg.
Definition: nvtx3.hpp:1642
message(wchar_t const *msg) noexcept
Construct a message whose contents are specified by msg.
Definition: nvtx3.hpp:1659
constexpr value_type get_value() const noexcept
Return the union holding the value of the message.
Definition: nvtx3.hpp:1724
message(registered_string_in< D > const &msg) noexcept
Construct a message from a registered_string_in.
Definition: nvtx3.hpp:1690
message(std::wstring &&)=delete
Disallow construction for std::wstring r-value.
constexpr nvtxMessageType_t get_type() const noexcept
Return the type information about the value the union holds.
Definition: nvtx3.hpp:1730
message(nvtxStringHandle_t handle) noexcept
Construct a message from NVTX C API registered string handle.
Definition: nvtx3.hpp:1714
message(char const *msg) noexcept
Construct a message whose contents are specified by msg.
Definition: nvtx3.hpp:1632
constexpr message(nvtxMessageType_t const &type, nvtxMessageValue_t const &value) noexcept
Construct a message from NVTX C API type and value.
Definition: nvtx3.hpp:1702
message(std::string &&)=delete
Disallow construction for std::string r-value.
message(std::wstring const &msg) noexcept
Construct a message whose contents are specified by msg.
Definition: nvtx3.hpp:1669
A category with an associated name string.
Definition: nvtx3.hpp:1208
named_category_in(id_type id, wchar_t const *name) noexcept
Construct a named_category_in with the specified id and name.
Definition: nvtx3.hpp:1344
static named_category_in const & get() noexcept
Returns a global instance of a named_category_in as a function-local static.
Definition: nvtx3.hpp:1250
named_category_in(id_type id, char const *name) noexcept
Construct a named_category_in with the specified id and name.
Definition: nvtx3.hpp:1324
A numerical value that can be associated with an NVTX event via its event_attributes.
Definition: nvtx3.hpp:1753
payload(int32_t value) noexcept
Construct a payload from a signed, 4 byte integer.
Definition: nvtx3.hpp:1773
constexpr payload(nvtxPayloadType_t const &type, value_type const &value) noexcept
Construct a payload from NVTX C API type and value.
Definition: nvtx3.hpp:1831
payload(uint32_t value) noexcept
Construct a payload from an unsigned, 4 byte integer.
Definition: nvtx3.hpp:1795
payload(int64_t value) noexcept
Construct a payload from a signed, 8 byte integer.
Definition: nvtx3.hpp:1762
payload(float value) noexcept
Construct a payload from a single-precision floating point value.
Definition: nvtx3.hpp:1807
payload(double value) noexcept
Construct a payload from a double-precision floating point value.
Definition: nvtx3.hpp:1819
constexpr value_type get_value() const noexcept
Return the union holding the value of the payload.
Definition: nvtx3.hpp:1842
constexpr nvtxPayloadType_t get_type() const noexcept
Return the information about the type the union holds.
Definition: nvtx3.hpp:1848
payload(uint64_t value) noexcept
Construct a payload from an unsigned, 8 byte integer.
Definition: nvtx3.hpp:1784
A message registered with NVTX.
Definition: nvtx3.hpp:1408
registered_string_in(char const *msg) noexcept
Constructs a registered_string_in from the specified msg string.
Definition: nvtx3.hpp:1510
nvtxStringHandle_t get_handle() const noexcept
Returns the registered string's handle.
Definition: nvtx3.hpp:1563
registered_string_in(std::string const &msg) noexcept
Constructs a registered_string_in from the specified msg string.
Definition: nvtx3.hpp:1526
registered_string_in(std::wstring const &msg) noexcept
Constructs a registered_string_in from the specified msg string.
Definition: nvtx3.hpp:1556
registered_string_in(wchar_t const *msg) noexcept
Constructs a registered_string_in from the specified msg string.
Definition: nvtx3.hpp:1540
static registered_string_in const & get() noexcept
Returns a global instance of a registered_string_in as a function local static.
Definition: nvtx3.hpp:1448
A RAII object for creating a NVTX range local to a thread within a domain.
Definition: nvtx3.hpp:2060
scoped_range_in(event_attributes const &attr) noexcept
Construct a scoped_range_in with the specified event_attributes
Definition: nvtx3.hpp:2076
scoped_range_in(Args const &... args) noexcept
Constructs a scoped_range_in from the constructor arguments of an event_attributes.
Definition: nvtx3.hpp:2106
scoped_range_in() noexcept
Default constructor creates a scoped_range_in with no message, color, payload, nor category.
Definition: nvtx3.hpp:2116
~scoped_range_in() noexcept
Destroy the scoped_range_in, ending the NVTX range event.
Definition: nvtx3.hpp:2134
A RAII object for creating a NVTX range within a domain that can be created and destroyed on differen...
Definition: nvtx3.hpp:2495
constexpr unique_range_in() noexcept
Default constructor creates a unique_range_in with no message, color, payload, nor category.
Definition: nvtx3.hpp:2545
~unique_range_in() noexcept=default
Destroy the unique_range_in ending the range.
unique_range_in(Args const &... args) noexcept
Constructs a unique_range_in from the constructor arguments of an event_attributes.
Definition: nvtx3.hpp:2535
unique_range_in(event_attributes const &attr) noexcept
Construct a new unique_range_in object with the specified event attributes.
Definition: nvtx3.hpp:2510
void end_range_in(range_handle r) noexcept
Manually end the range associated with the handle r in domain D.
Definition: nvtx3.hpp:2442
void mark_in(event_attributes const &attr) noexcept
Annotates an instantaneous point in time with a "marker", using the attributes specified by attr.
Definition: nvtx3.hpp:2618
range_handle start_range_in(event_attributes const &attr) noexcept
Manually begin an NVTX range.
Definition: nvtx3.hpp:2303
range_handle start_range(event_attributes const &attr) noexcept
Manually begin an NVTX range in the global domain.
Definition: nvtx3.hpp:2379
constexpr bool operator==(range_handle lhs, range_handle rhs) noexcept
Compares two range_handles for equality.
Definition: nvtx3.hpp:2260
void mark(event_attributes const &attr) noexcept
Annotates an instantaneous point in time with a "marker", using the attributes specified by attr,...
Definition: nvtx3.hpp:2682
constexpr bool operator!=(range_handle lhs, range_handle rhs) noexcept
Compares two range_handles for inequality.
Definition: nvtx3.hpp:2271
void end_range(range_handle r) noexcept
Manually end the range associated with the handle r in the global domain.
Definition: nvtx3.hpp:2464
Indicates the value of the alpha, red, green, and blue color channels for an ARGB color to use as an ...
Definition: nvtx3.hpp:984
constexpr argb(component_type alpha_, component_type red_, component_type green_, component_type blue_) noexcept
Construct an argb with alpha, red, green, and blue channels specified by alpha_, red_,...
Definition: nvtx3.hpp:997
Tag type for the "global" NVTX domain.
Definition: nvtx3.hpp:746
Handle used for correlating explicit range start and end events.
Definition: nvtx3.hpp:2199
constexpr range_handle(value_type id) noexcept
Construct a range_handle from the given id.
Definition: nvtx3.hpp:2208
constexpr value_type get_value() const noexcept
Returns the range_handle's value.
Definition: nvtx3.hpp:2245
constexpr range_handle() noexcept=default
Constructs a null range handle.
nvtxRangeId_t value_type
Type used for the handle's value.
Definition: nvtx3.hpp:2201
constexpr range_handle(std::nullptr_t) noexcept
Implicit conversion from nullptr constructs a null handle.
Definition: nvtx3.hpp:2238
Indicates the values of the red, green, and blue color channels for an RGB color to use as an event a...
Definition: nvtx3.hpp:952
constexpr rgb(component_type red_, component_type green_, component_type blue_) noexcept
Construct a rgb with red, green, and blue channels specified by red_, green_, and blue_,...
Definition: nvtx3.hpp:966
uint8_t component_type
Type used for component values.
Definition: nvtx3.hpp:954