4. PopVision trace instrumentation library

The PopVision trace instrumentation library (libpvti) provides functions to control the capture of profiling information for the host-code of your IPU application. This data can then be explored with the PopVision System Analyser.

4.1. Overview

The program will create a single trace file if tracing is enabled (see Section 1.3, Configuring trace options. The file is named using the current date, time and process number. The name of the trace file can be retrieved as follows:

>>> import libpvti as pvti
>>> pvti.getCurrentTraceFilename()
'Thu_Aug_27_09:46:55_2020_BST_2341.pvti'

4.1.1. Tracepoints

The trace file will contain an event for each entry logged using pvti::Tracepoint::begin(), pvti::Tracepoint::end() or pvti::Tracepoint::event()

>>> pvti.Tracepoint.begin(pvti.traceDrivers, "begin event")

4.1.2. Channels

There are three default trace channels that log events from the drivers, Poplar and frameworks (such as TensorFlow or PopART). You can enable these channels individually.

>>> pvti.listTraceChannel()
[['Drivers', True], ['Poplar', True], ['Framework', True]]

Or you can create a custom channel and send specific trace events to it, from your program:

>>> traceCustom = createTraceChannel("Custom channel")

4.1.3. Configuring trace options

You can enable trace globally by setting the PVTI_OPTIONS environment variable:

export PVTI_OPTIONS='{"enable":"true"}'

If the environment variable is not set, no trace file is created and no events are logged. If the environment variable is set but cannot be parsed, trace will be enabled with all default options.

You can further configure trace behaviour using the following options:

  • enable : Enable trace: true or false. Defaults to true if not set.

  • directory : Directory where trace files should be stored. Defaults to the current directory if not set.

  • channels : List of trace channels to enable. If empty or not set, all channels are enabled.

4.1.4. Enabling and disabling trace

You can enable individual trace channels at runtime. Events logged to disabled channels will not appear in the trace file

>>> pvti.disableTraceChannel(traceCustom)
>>> pvti.Tracepoint.event(traceCustom, "channel disabled: this event should not appear")

When you re-enable the channel, events will again be logged to the trace file as normal:

>>> pvti.enableTraceChannel(traceCustom)
>>> pvti.Tracepoint.end(traceCustom, "now events will be logged as normal")

4.1.5. Closing the trace file

The trace file will be closed when the program ends.

You can also call pvti::closeTrace() to close the trace file during execution. The program should not log any further events after this.

4.1.6. Python

Python has two additional approaches to instrument code. You can use a context manager or a decorator, as shown below.

Context manager:

>>> with pvti.Tracepoint(channel, "flowers"):
>>>    ...

Decorator:

>>> @pvti.instrument_fn(channel)
>>> def test_fn():
>>>    pass

4.1.7. C++ API

The C++ API is similar to the Python API. Channels are created as follows:

pvti::TraceChannel channel = {"Tests Channel"};

The following example produces a similar trace file to the Python examples above:

#include "pvti.hpp"
#include <iostream>

pvti::TraceChannel channel = {"C custom channel"};
int main(int argc, char **argv) {

  auto filename = pvti::getCurrentTraceFilename();

  std::cout << "Trace file is " << filename << std::endl;

  pvti::Tracepoint::begin(&pvti::traceDrivers, "begin");

  pvti::Tracepoint::begin(&channel, "begin on custom channel");

  pvti::Tracepoint::event(&channel, "another event on custom channel");

  pvti::disableTraceChannel(&channel);

  pvti::Tracepoint::event(&channel, "event while disabled, not logged");

  pvti::enableTraceChannel(&channel);

  pvti::Tracepoint::end(&channel, "now events are logged again");

  pvti::closeTrace();
}

4.2. API reference

namespace pvti

TraceChannels

PVTI library predefined trace categories.

These predefined channels can be enabled or disabled at runtime. Tracepoints can be created using these channels, or custom channels can be added.

TraceChannel traceDrivers
TraceChannel tracePoplar
TraceChannel traceFramework

Typedefs

typedef struct pvti::TraceChannel TraceChannel

PVTI trace categories type definition.

Use for defining custom channels.

Functions

void enableTraceChannel(TraceChannel *channel)

Enable tracing channel for the session.

PVTI_OPTIONS environment variable must be set, and trace enabled. See “Configuring trace options” for more information.

Parameters
  • channel: A pointer to the channel to be enabled.

void disableTraceChannel(TraceChannel *channel)

Disable tracing channel for the session.

Parameters
  • channel: A pointer to the channel to be disabled.

bool checkTraceChannel(TraceChannel *channel)

Check if tracing channel is enabled.

Return

True if the channel is enabled, false if it is disabled.

Parameters
  • channel: A pointer to the channel to check.

std::vector<TraceChannel*> listTraceChannel(void)

Get a list of all traceChannels in the session.

Return

A vector of pointers to the traceChannels in the session.

std::string getCurrentTraceFilename(void)

Get the current trace session filename.

Return

The current trace session filename.

void closeTrace()

Close the current trace session.

No Tracepoint events should be invoked following this function call.

struct TraceChannel
#include <pvti.hpp>

PVTI trace categories type definition.

Use for defining custom channels.

Public Functions

TraceChannel(const char *name, bool enabled = true)

Construct a TraceChannel object, and add it to the current session.

Parameters

Public Members

const char *name
bool enabled
class Tracepoint
#include <pvti.hpp>

Class for managing tracing of events.

Public Functions

Tracepoint(TraceChannel *traceChannel, const std::string traceLabel)

Profile a function or a scope by creating a named stack object of Tracepoint type.

Parameters
  • traceChannel: The channel to create the tracepoint for

  • traceLabel: A unique user-friendly string for this scope’s trace.

Tracepoint(TraceChannel *traceChannel, const char *traceLabel, const int32_t traceLabelLen = -1)

Profile a function or a scope by creating a named stack object of Tracepoint type.

Parameters
  • traceChannel: The channel to create the tracepoint for.

  • traceLabel: A unique user-friendly string for this scope’s trace.

  • traceLabelLen: The number of characters to use from the traceLabel (-1 indicates all).

~Tracepoint()

Invoked on Tracepoint function exit.

Tracepoint(const Tracepoint&) = delete
Tracepoint &operator=(const Tracepoint&) = delete

Public Static Functions

void begin(TraceChannel *traceChannel, const std::string traceLabel)

Start profiling a region using this function.

Should be complemented with an end() to profile between the two.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this region’s trace.

void begin(TraceChannel *traceChannel, const char *traceLabel, const int32_t traceLabelLen = -1)

Start profiling a region using this function.

Should be complemented with with an end() to profile between the two.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this region’s trace.

  • traceLabelLen: The number of characters to use from the traceLabel (-1 indicates all).

void end(TraceChannel *traceChannel, const std::string traceLabel)

End profiling a region using this function.

Should be the complement to a begin() to profile between the two.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this region’s trace.

void end(TraceChannel *traceChannel, const char *traceLabel, const int32_t traceLabelLen = -1)

End profiling a region using this function.

Should be the complement to a begin() to profile between the two.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this region’s trace.

  • traceLabelLen: The number of characters to use from the traceLabel (-1 indicates all).

void event(TraceChannel *traceChannel, const std::string traceLabel)

Mark an occurrence to be instrumented.

Can be used to compute duration between two events of the same or different type.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this event.

void event(TraceChannel *traceChannel, const char *traceLabel, const int32_t len = -1)

Mark an occurrence to be instrumented.

Can be used to compute duration between two events of same or different type.

Parameters
  • traceChannel: The channel to create tracepoints for.

  • traceLabel: A unique user-friendly string for this event.

  • traceLabelLen: The number of characters to use from the traceLabel (-1 indicates all).