Intel® Trace Analyzer and Collector User and Reference Guide

ID 767272
Date 3/31/2023
Document Table of Contents

Defining and Recording Counters

Intel® Trace Collector introduces the concept of counters to model numeric performance data that changes over the execution time. Use counters to capture the values of hardware performance counters, or of program variables (iteration counts, convergence rate, etc.) or any other numerical quantity. An Intel Trace Collector counter is identified by its name, the counter class it belongs to (similar to the two-level symbol naming), and the type of its values (integer or floating-point) and the units that the values are quoted in (Example: MFlop/sec).

A counter can be attached to MPI processes to record process-local data, or to arbitrary groups. When using a group, then each member of the group will have its own instance of the counter and when a process logs a value it will only update the counter value of the instance the process belongs to.

Similar to other Intel Trace Collector objects, counters are referred to by integer counter handles that are managed automatically by the library.

To define a counter, the class it belongs to needs to be defined by calling VT_classdef(). Then, call VT_countdef(), and pass the following information:

  • Counter name

  • Data type

enum VT_CountData

Enumerator Description
VT_COUNT_INTEGER Counter measures 64 bit integer value, passed to Intel® Trace Collector API as a pair of high and low 32 bit integers
VT_COUNT_FLOAT Counter measures 64 bit floating point value (native format)
VT_COUNT_INTEGER64 Counter measures 64 bit integer value (native format)
VT_COUNT_DATA Mask to extract the data format
  • Kind of data

enum VT_CountDisplay

Enumerator Description
Counter are displayed with absolute values
First derivative of counter values is displayed
VT_COUNT_DISPLAY Mask to extract the display type
  • Semantic associated with a sample value

enum VT_CountScope

Enumerator Description
The value is valid until and at the current time
The value is valid exactly at the current time, and no value is available before or after it
The value is valid at and after the current time
The value is valid at the current time and samples a curve, so for example, linear interpolation between sample values is possible
Mask to extract the scope
  • Counter target, that is the process or group of processes it belongs to (VT_GROUP_THREAD for a thread-local counter, VT_GROUP_PROCESS for a process-local counter, or an arbitrary previously defined group handle)

  • Lower and upper bounds

  • Counter unit (an arbitrary string like FLOP, Mbytes)


int VT_countdef (const char * name, int classhandle, 
	 int genre, int target, const void * bounds, const char * unit, int 
	 * counterhandle)


Define a counter and get handle for it.

Counters are identified by their name (string) alone.


VTCOUNTDEF(name, classhandle, genre, target, 
	 bounds[], unit, counterhandle, ierr)


name string identifying the counter
classhandle class to group counters, handle must have been retrieved by VT_classdef
genre bitwise or of one value from VT_CountScope, VT_CountDisplay and VT_CountData
target target which the counter refers to (VT_ME, VT_GROUP_THREAD, VT_GROUP_PROCESS, VT_GROUP_CLUSTER or thread/process-id or user-defined group handle).
bounds array of lower and upper bounds (2x 64 bit float, 2x2 32 bit integer, 2x 64 bit integer ->16 byte)
unit string identifying the unit for the counter (like Volt, pints etc.)

Return values

counterhandle handle identifying the defined counter

Returns error code

The integer counters have 64-bit integer values, while the floating-point counters have a value domain of 64-bit IEEE floating point numbers. On systems that have no 64-bit integer type in C, and for Fortran, the 64-bit values are specified using two 32-bit integers. Integers and floats are passed in the native byte order, but for VT_COUNT_INTEGER the integer with the higher 32 bits needs to be given first on all platforms:

Counter Value

32 bit integer (high)

32 bit integer (low)

VT_COUNT_INTEGER64 64 bit integer
VT_COUNT_FLOAT 64 bit float

At any time during execution, a process can record a new value for any of the defined counters by calling one of the Intel® Trace Collector API routines described below. To minimize the overhead, it is possible to set the values of several counters with one call by passing an integer array of counter handles and a corresponding array of values. In C, it is possible to mix 64-bit integers and 64-bit floating point values in one value array; in Fortran, the language requires that the value array contains either all integer or all floating point values.


int VT_countval(int ncounters, int * handles, 
	 void * values)


Record counter values.

Values are expected as two 4-byte integers, one 8-byte integer or one 8-byte double, according to the counter it refers to.


VTCOUNTVAL(ncounters, handles[], values[], 


ncounters number of counters to be recorded
handles array of ncounters many handles (previously defined by VT_countdef)
values array of ncounters many values, value[i] corresponds to handles[i].

Return Values

Returns error code

The online samples resource contains counterscopec.c, which demonstrates all of these facilities.