Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b101edc
add c++ wrapper
eparshut Apr 16, 2026
c2f4d71
add support for wchar_t*
eparshut Apr 17, 2026
2699781
fix task/frame/region apis
eparshut Apr 17, 2026
8c8ce26
add id support
eparshut Apr 17, 2026
b7f4cca
add cmake build and tests
eparshut Apr 17, 2026
a0352b8
add readme and samples
eparshut Apr 17, 2026
8ec9545
add gh action
eparshut Apr 17, 2026
6a26302
update README.md
eparshut Apr 17, 2026
fe9d1fc
cleanup
eparshut Apr 17, 2026
a2fe280
improve tests
eparshut Apr 17, 2026
55ba11e
rename test check define
eparshut Apr 17, 2026
309cdee
added back copy and move assignment operators.
eparshut Apr 17, 2026
c5f7d4c
cleanup cmake
eparshut Apr 17, 2026
29ce152
trigger ci
eparshut Apr 17, 2026
e212b7d
cleanup
eparshut Apr 17, 2026
7d7848d
minor fixes
eparshut Apr 17, 2026
612d0b9
Merge branch 'intel:master' into cpp_wrapper
eparshut Apr 17, 2026
00cab16
apply CMakefile changes back
eparshut Apr 17, 2026
f6235a4
cleanup gh action
eparshut Apr 17, 2026
caaf0c7
update main README
eparshut Apr 17, 2026
1ec6e89
simplify gh action
eparshut Apr 17, 2026
92f7a69
ready to merge
eparshut Apr 17, 2026
4a9ec99
add new docomuntation page
eparshut Apr 20, 2026
3fc05df
update documentation copyrigth year
eparshut Apr 20, 2026
593328a
add thread-local cache for string handle lookups
eparshut Apr 21, 2026
5666ea0
rename Domain class member
eparshut Apr 21, 2026
be22985
update the sample with more usage examples
eparshut Apr 21, 2026
847404a
fix windows build
eparshut Apr 21, 2026
ecf6630
add overlapped task api support
eparshut Apr 23, 2026
acec3f4
improve documentation
eparshut Apr 23, 2026
062e262
add itt id auto generation
eparshut Apr 23, 2026
9bbc142
add new overlapped_task() api in domain
eparshut Apr 23, 2026
8512912
add cache for overlapped task id storing
eparshut Apr 23, 2026
5ccf4c5
fix id generation logic, cover more overlapped scenarios
eparshut Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@ jobs:
# doesn't work in case of CMake + VS (https://github.com/fortran-lang/setup-fortran/issues/45)
run: python buildall.py --force_bits 64 -ft ${{ matrix.optional_args }}

cpp_wrapper:
name: Check C++ wrapper
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: windows-latest
steps:
- name: Checkout sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Build C++ wrapper
run: python buildall.py --force_bits 64 -cpp
- name: Test (Linux)
run: ctest --test-dir build_linux/64/cpp --build-config Release --output-on-failure
if: runner.os == 'Linux'
- name: Test (Windows)
run: ctest --test-dir build_win/64/cpp --build-config Release --output-on-failure
if: runner.os == 'Windows'

rust_format:
name: Check Rust formatting
runs-on: ubuntu-latest
Expand Down
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ project(ittapi)
option(FORCE_32 "Force a 32-bit compile on 64-bit" OFF)
option(ITT_API_IPT_SUPPORT "ptmarks support" OFF)
option(ITT_API_FORTRAN_SUPPORT "fortran support" OFF)
option(ITT_API_CPP_SUPPORT "C++ wrapper support" OFF)
option(ITT_API_INSTALL "Enable ITT API installation rules" ON)

if(FORCE_32 AND UNIX)
Expand Down Expand Up @@ -171,13 +172,23 @@ target_include_directories(jitprofiling
PRIVATE src/ittnotify
)

# C++ wrapper
if(ITT_API_CPP_SUPPORT)
add_subdirectory(cpp)
endif()

# install

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

if(ITT_API_INSTALL)
install(TARGETS ittnotify EXPORT ittapi-targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(ITT_API_CPP_SUPPORT)
install(TARGETS ittapi-cpp EXPORT ittapi-targets)
install(DIRECTORY cpp/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.hpp")
endif()
install(EXPORT ittapi-targets NAMESPACE ittapi:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ittapi)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.h"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ To build the library:
- To list available build options execute: `python buildall.py -h`

```
usage: buildall.py [-h] [-d] [-c] [-v] [-pt] [-ft] [--force_bits]
usage: buildall.py [-h] [-d] [-c] [-v] [-pt] [-ft] [-cpp] [--force_bits]

optional arguments:
-h, --help show this help message and exit
Expand All @@ -50,6 +50,7 @@ optional arguments:
-v, --verbose enable verbose output from build process
-pt, --ptmark enable anomaly detection support
-ft, --fortran enable fortran support
-cpp, --cpp enable C++ wrapper support
--force_bits specify bit version for the target
--vs specify visual studio version (Windows only)
--cmake_gen specify cmake build generator (Windows only)
Expand Down
5 changes: 4 additions & 1 deletion buildall.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ def main():
"-pt", "--ptmark", help="enable anomaly detection support", action="store_true")
parser.add_argument(
"-ft", "--fortran", help="enable fortran support", action="store_true")
parser.add_argument(
"-cpp", "--cpp", help="enable C++ wrapper support", action="store_true")
parser.add_argument(
"--force_bits", choices=["32", "64"], help="specify bit version for the target")
if sys.platform == 'win32' and vs_versions:
Expand Down Expand Up @@ -177,7 +179,8 @@ def main():
("-DCMAKE_BUILD_TYPE=Debug" if args.debug else ""),
('-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON' if args.verbose else ''),
("-DITT_API_IPT_SUPPORT=1" if args.ptmark else ""),
("-DITT_API_FORTRAN_SUPPORT=1" if args.fortran else "")
("-DITT_API_FORTRAN_SUPPORT=1" if args.fortran else ""),
("-DITT_API_CPP_SUPPORT=ON" if args.cpp else "")
])))

if sys.platform == 'win32':
Expand Down
56 changes: 56 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# Copyright (C) 2026 Intel Corporation
# SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
#

add_library(ittapi-cpp INTERFACE)
add_library(ittapi::cxx ALIAS ittapi-cpp)

target_include_directories(ittapi-cpp
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(ittapi-cpp INTERFACE ittnotify)
target_compile_features(ittapi-cpp INTERFACE cxx_std_17)

if(NOT WIN32)
find_package(Threads)
endif()

# Sample
add_executable(task_sample samples/task_sample.cpp)
target_link_libraries(task_sample PRIVATE ittapi-cpp)
if(NOT WIN32)
target_link_libraries(task_sample PRIVATE ${CMAKE_DL_LIBS})
if(Threads_FOUND)
target_link_libraries(task_sample PRIVATE Threads::Threads)
endif()
endif()

# Tests
enable_testing()

set(CPP_TESTS
test_string_handle
test_domain
test_task
test_region
test_frame
test_collection_control
test_thread_naming
test_ittapi
)

foreach(test_name ${CPP_TESTS})
add_executable(${test_name} tests/${test_name}.cpp)
target_link_libraries(${test_name} PRIVATE ittapi-cpp)
if(NOT WIN32)
target_link_libraries(${test_name} PRIVATE ${CMAKE_DL_LIBS})
if(Threads_FOUND)
target_link_libraries(${test_name} PRIVATE Threads::Threads)
endif()
endif()
add_test(NAME cpp_${test_name} COMMAND ${test_name})
endforeach()
223 changes: 223 additions & 0 deletions cpp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
# ITT API C++ Wrapper

A modern, header-only C++ wrapper for the [ITT API](https://github.com/intel/ittapi) instrumentation library. The wrapper provides RAII-based scoped helpers and type-safe C++ abstractions over the existing C API.

## Supported APIs

| API | C++ Wrapper |
|-----|------------|
| String Handle | `ittapi::StringHandle` |
| Domain | `ittapi::Domain` |
| Task | `ittapi::ScopedTask`, `Domain::task_begin()` / `Domain::task_end()` |
| Region | `ittapi::ScopedRegion` |
| Frame | `ittapi::ScopedFrame` |
| Collection Control | `ittapi::pause()`, `ittapi::resume()`, `ittapi::ScopedPause` |
| Thread Naming | `ittapi::set_thread_name()` |

## Requirements

- C++17 or later
- The existing `ittnotify` static C-library

## Including the Wrapper

Use the umbrella header to get the full API:

```cpp
#include <ittapi.hpp>
```

Or include individual headers:

```cpp
#include <ittapi_domain.hpp>
#include <ittapi_task.hpp>
#include <ittapi_collection_control.hpp>
```

## Example: Task Instrumentation

```cpp
#include <ittapi.hpp>

#include <chrono>
#include <thread>

int main() {
ittapi::set_thread_name("main");
ittapi::Domain domain{"example.task"};
ittapi::StringHandle task_name{"process"};

ittapi::pause();
ittapi::resume();

{
auto task = domain.task(task_name);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

return 0;
}
```

## Linking

### CMake Consumer

```cmake
find_package(ittapi CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE ittapi::cxx)
```

The `ittapi::cxx` target is an `INTERFACE` library that transitively links the existing `ittnotify` static library and adds the C++ wrapper include directories.

### Manual GCC/G++ (Linux)

```bash
g++ -std=c++17 -O2 \
-I<ittapi-install-prefix>/include \
app.cpp \
<ittapi-install-prefix>/lib/libittnotify.a \
-ldl -pthread \
-o app
```

## Building with CMake

From the repository root:

```bash
cmake -B build -DCMAKE_BUILD_TYPE=Release -DITT_API_CPP_SUPPORT=ON
cmake --build build
```

The `ITT_API_CPP_SUPPORT` option is `OFF` by default.

You can also build with the build script:

```bash
python buildall.py --cpp
```

## Running Tests

Tests are registered inside the `cpp/` subdirectory. After building:

```bash
ctest --test-dir build/cpp --output-on-failure
```

## Performance Tips

- **Pre-create `StringHandle` objects** for task/region names used in hot paths. The `StringHandle` overloads pass a raw pointer with no locking — this is the zero-overhead path.
```cpp
// Do this once at startup:
ittapi::StringHandle name{"compute"};

// Then in hot code:
auto task = domain.task(name); // no allocation, no lock
```
- **The `string_view` overloads** are convenient but allocate a `std::string` on cache miss and acquire a lock in the C library. Use them for setup or infrequent tasks, not tight loops.
- **Create `Domain` objects once** and reuse them. Domain creation is a global lookup — store them as class members or globals, not as function locals called repeatedly.
- **Use overlapped tasks** (with IDs) only when you need tasks that end out of order. Stack-based tasks (without IDs) are simpler and carry less internal state.

## API Reference

### Free Functions

- `ittapi::pause()` — Pause collection.
- `ittapi::resume()` — Resume collection.
- `ittapi::set_thread_name(std::string_view name)` — Set the current thread's name.

### Classes

#### `ittapi::StringHandle`

Lightweight wrapper around `__itt_string_handle*`.

```cpp
ittapi::StringHandle h{"my_handle"};
h.valid(); // true if handle was created
h.get(); // underlying __itt_string_handle*
```

#### `ittapi::Domain`

Lightweight wrapper around `__itt_domain*` with convenience factories.

```cpp
ittapi::Domain d{"my.domain"};
auto task = d.task("task_name"); // returns ScopedTask (RAII)
auto region = d.region("region_name"); // returns ScopedRegion
auto frame = d.frame(); // returns ScopedFrame

d.task_begin("work"); // manual task begin (simple stack-based task)
d.task_end(); // manual task end

__itt_id id = __itt_id_make(nullptr, 1);
d.task_begin("overlapped", id, __itt_null); // manual task begin (overlapped task)
d.task_end(id); // manual task end by ID
```

#### `ittapi::ScopedTask`

RAII wrapper for task begin/end. Use `domain.overlapped_task()` to create an overlapped task (tasks that can end in any order). Each overlapped task instance gets a unique `__itt_id` derived from its object address. The `id()` method returns this ID.

```cpp
// Simple task
{
auto task = domain.task("work");
// ... do work ...
task.end(); // optional early end (idempotent)
} // destructor ends task if still active
```

Overlapped tasks — use `overlapped_task()`, optionally pass a parent ID:

```cpp
{
auto parent = domain.overlapped_task("parent"); // overlapped, no parent
auto child = domain.overlapped_task("child", parent.id()); // overlapped, child of parent

parent.end(); // end parent task while child is still running
child.end(); // child task ends
}
```

For manual (non-RAII) control:

```cpp
domain.task_begin("work");
// ... do work ...
domain.task_end();

// overlapped tasks:
__itt_id id = __itt_id_make(nullptr, 1);
domain.task_begin("overlapped_work", id, __itt_null);
// ... do work ...
domain.task_end(id);
```

#### `ittapi::ScopedRegion`

RAII wrapper for region begin/end.

#### `ittapi::ScopedFrame`

RAII wrapper for frame begin/end. Supports explicit timestamp submission.

```cpp
ittapi::ScopedFrame::submit(domain.get(), begin_ts, end_ts);
```

#### `ittapi::ScopedPause`

RAII wrapper for pause/resume. Constructor pauses, destructor resumes.

```cpp
{
ittapi::ScopedPause sp;
// collection is paused
sp.resume_now(); // optional early resume
}
```
17 changes: 17 additions & 0 deletions cpp/include/ittapi.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
Copyright (C) 2026 Intel Corporation
SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
*/

#ifndef ITTAPI_HPP
#define ITTAPI_HPP

#include "ittapi_collection_control.hpp"
#include "ittapi_domain.hpp"
#include "ittapi_frame.hpp"
#include "ittapi_region.hpp"
#include "ittapi_string_handle.hpp"
#include "ittapi_task.hpp"
#include "ittapi_thread_naming.hpp"

#endif // ITTAPI_HPP
Loading
Loading