Context Metadata API

Use the Context Metadata API to define custom counters in your code with special attributes. You can also get a set of metrics for the collected data in any classical form of data representation (bandwidth/latency/utilization metrics) in Intel® VTune™ Profiler.

You can use Context Metadata API to collect counter-based metrics and attribute these metrics to hardware topology like:

  • PCIe devices

  • Block devices

  • CPU cores

  • Threads

Define and create a counter object

Use this structure to store context metadata:

__itt_context_metadata
{
    __itt_context_type type;    /*!< Type of the context metadata value */
    void* value;                /*!< Pointer to context metadata value itself */
}

The structure accepts the following types of context metadata:

__itt_context_type

Value

Description

__itt_context_name

ASCII string char* / Unicode string wchar_t*

The name of the counter-based metric. This value is required.

__itt_context_device

ASCII string char* / Unicode string wchar_t*

Statistics subdomain to break down the counter samples (for example, network port ID, disk partition, etc.)

__itt_context_units

ASCII string char* / Unicode string wchar_t*

Units of measurement. For measurement of time, use the ns/us/ms/s units to correct data representation in VTune Profiler.

__itt_context_pci_addr

ASCII string char* / Unicode string wchar_t*

PCI address of device to associate with the counter.

__itt_context_tid

Unsigned 64-bit integer type

Thread ID to associate with the counter.

__itt_context_bandwidth_flag

Unsigned 64-bit integer type (0,1)

If this flag is set to 1, calculate latency histogram and counter/sec timeline distribution.

__itt_context_latency_flag

Unsigned 64-bit integer type (0,1)

If this flag is set to 1, calculate the throughput histogram and counter/sec timeline distribution.

__itt_context_on_thread_flag

Unsigned 64-bit integer type (0,1)

If this flag is set to 1, show the counter on top of the Thread graph as percentage of the CPU Time distribution.

Before you associate context metadata with a counter, make sure to create an ITT API Domain and ITT API Counter Instances first.

The domain name provides a heading for the section of metrics for the counters in the results of VTune Profiler. A single domain can combine data from any number of counters. However, the name of the counters must be unique within the same domain.

You can combine different counters under a single metric of the Context Metadata.

Add context information

Once you have created all objects, you can add context information for the selected counters. Use these primitives:

__itt_bind_context_metadata_to_counter(
     __itt_counter counter, size_t length, __itt_context_metadata* metadata);

Parameters of the primitive:

Type

Parameter

Description

[in]

__itt_counter counter

Pointer to the counter instance associated with the

context metadata

[in]

size_t length

Number of elements in the array of context metadata

[in]

__itt_context_metadata*
metadata

Pointer to the array of context metadata

To create counter instances and submit counter data, use:

__itt_counter_create_v3(__itt_domain* domain, const char* name, __itt_metadata_type type);
__itt_counter_set_value_v3(__itt_counter counter, void *value_ptr);

Usage Example

This example creates counters with context metadata that measures random read operation metrics for an SSD NVMe device:

#include "ittnotify.h"
#include "ittnotify_types.h"


// Create domain and counters:
__itt_domain* domain =
 __itt_domain_create("ITT API collected data");
__itt_counter counter_read_op =
 __itt_counter_create_v3(domain, "Read Operations", __itt_metadata_u64);
__itt_counter counter_read_mb =
 __itt_counter_create_v3(domain, "Read Megabytes", __itt_metadata_u64);
__itt_counter counter_spin_time =
 __itt_counter_create_v3(domain, "Spin Time", __itt_metadata_u64);


// Create context metadata:
__itt_context_metadata metadata_read_op[] = {
        {__itt_context_name, "Reads"},
        {__itt_context_device, "NVMe SSD Intel DC 660p"},
        {__itt_context_units, "Operations"},
        {__itt_context_pci_addr, "0001:10:00.1"},
        {__itt_context_latency_flag, &true_flag}
};
__itt_context_metadata metadata_read_mb[] = {
        {__itt_context_name, "Read"},
        {__itt_context_device, "NVMe SSD Intel DC 660p"},
        {__itt_context_units, "MB"},
        {__itt_context_pci_addr, "0001:10:00.1"},
        {__itt_context_bandwidth_flag, &true_flag}
};
__itt_context_metadata metadata_spin_time[] = {
        {__itt_context_name, "Spin Time"},
        {__itt_context_device, "NVMe SSD Intel DC 660p"},
        {__itt_context_units, "ms"},
        {__itt_context_tid, &thread_id}
};


// Bind context metadata to counters:
__itt_bind_context_metadata_to_counter(counter_read_op, n, metadata_read_op);
__itt_bind_context_metadata_to_counter(counter_read_mb, n, metadata_read_mb);
__itt_bind_context_metadata_to_counter(counter_spin_time, n, metadata_spin_time);


while(1)
{
    // Get collected data:
    uint64_t read_op   = get_user_read_operation_num();
    uint64_t read_mb   = get_user_read_megabytes_num();
    uint64_t spin_time = get_user_spin_time();


    // Dump collected data:
    __itt_counter_set_value_v3(counter_read_op, &read_op);
    __itt_counter_set_value_v3(counter_read_mb, &read_mb);
    __itt_counter_set_value_v3(counter_spin_time, &spin_time);
}