DebugContext

#include <poplar/DebugContext.hpp>

Defines

SUPPORTS_LOCATION_BUILTINS
namespace poplar

Poplar classes and functions.

Typedefs

using DebugId = std::uint64_t

A unique identifier for the debug context.

Enums

enum DebugSerializationFormat

Values:

enumerator JSON

Serialise in JSON format.

enumerator CBOR

Serialise in CBOR format.

Functions

std::ostream &operator<<(std::ostream &os, const DebugNameAndId &dnai)

Display the path name of the DebugNameAndId.

Parameters
  • os – The ostream to output to.

  • dnai – The DebugNameAndId to display.

Returns

The ostream written to.

std::ostream &operator<<(std::ostream &os, const DebugContext &dc)

Display the path name of the DebugContext.

Parameters
  • os – The ostream to output to.

  • dc – The DebugContext to display.

Returns

The ostream written to.

class DebugContext
#include <DebugContext.hpp>

DebugContext gathers the common external parameters of the context of an operation.

As an extension to DebugNameAndId, DebugContext bundles a name and a DebugId as well as the file and line in the source code where it is invoked.

Note that to reflect the specific line where an invocation took place, the DebugContext object must be constructed in the same line of the invocation. For instance, if a function foo wants to capture the DebugContext of its invocation, it should be called like this:

foo(DebugContext{});
Rather than:
DebugContext debugContext;
foo(debugContext);
Although typically foo would accept a default argument:
void foo(const DebugContext &debugContext = {});
so that the DebugContext can be automatically captured:
foo();

The ultimate target of DebugContext is to be passed to the constructor of a DebugInfo object. The DebugContext carries the DebugId of the parent DebugInfo to keep a hierarchical relationship. A typical flow would be:

The initial DebugContext is (implicitly) created in foo default argument and used to create the initial DebugInfo. Then foo2 is called:

void foo(const DebugContext &debugContext = {}) {
  DebugInfo debugInfo{debugContext};
  foo2(debugInfo);
}
foo2 captures the DebugContext that contains the parent DebugId:
void foo2(const DebugContext &debugContext) {
  DebugInfo debugInfo{debugContext};
}
In this way, low-level operations and resources can be related to the high-level operation that triggered them.

Public Functions

DebugContext(SourceLocation loc = SourceLocation::Current())
DebugContext(const char *name, SourceLocation loc = SourceLocation::Current())
DebugContext(StringRef name, SourceLocation loc = SourceLocation::Current())
DebugContext(std::string name, SourceLocation loc = SourceLocation::Current())
DebugContext(const DebugInfo &debugInfo, std::string name = "", SourceLocation loc = SourceLocation::Current())
DebugContext(const DebugNameAndId &debugNameAndId, std::string name = "", SourceLocation loc = SourceLocation::Current())
DebugContext(const DebugContext &debugContext, StringRef name = "")
DebugContext(const DebugContext &debugContext, SourceLocation loc)
DebugContext(DebugContext&&) noexcept
~DebugContext()
std::string getPathName() const

Gets the pathname of this object as the concatenation of the parent name received in the constructor via DebugInfo or DebugNameAndId and the name explicitly set for this object.

inline core::DebugContext &getImpl() const

Private Members

std::unique_ptr<core::DebugContext> impl
class DebugInfo
#include <DebugContext.hpp>

DebugInfo stores and persists a set of data that describes the context of an operation.

Some of that data is structured, such as the framework layer name (Poplar, PopLibs, PopART, and so on) or the file and line of the source code. But it can also be custom data set by the user through setValue method.

In turn, the DebugInfo is passed to sub-operations of that operation so that resources (Program, Variable, and other object types) created in lower levels can be hierarchically related to the initial DebugInfo.

After execution, the created DebugInfo has been written to a file. At the same time, the operation resources have been persisted in the graph and execution profile, together with their DebugInfo ID. In this way, tools like PopVision can conveniently present to the user: the operation, its resources, and its DebugInfo.

This class is expected to be derived to adapt to particular use cases (typically, by adding extra mandatory arguments to the constructor). Internally, derived classes can use setValue() to store the extra data to be persisted.

At object destruction, the DebugInfo data is passed to the streamer to be written to a file. Thus, the streamer should be initialized before any DebugInfo object gets destroyed, or it will not be persisted.

Subclassed by poputil::OpDebugInfo

Public Functions

DebugInfo(const DebugContext &debugContext, std::string layer)

Constructor.

Parameters
  • debugContext – Captures the external context of the operation (for example, file and line of invocation).

  • layer – Name of the framework level (for example, Poplar, PopLibs or PopART).

DebugInfo &operator=(const DebugInfo&) = delete
DebugInfo(const DebugInfo&) = delete
virtual ~DebugInfo()
DebugId getId() const

Gets the unique identifier of this DebugInfo object.

std::string getPathName() const

Gets the pathname of this object (as received from DebugContext).

inline core::DebugInfo &getImpl() const
bool setValue(std::string name, ProfileValue value)

Adds custom data to this object if “name” is not already set.

Parameters
  • name – The key name of the data.

  • value – A ProfileValue object containing the custom data.

Returns

true if “name” was not already set, false otherwise.

Public Static Functions

static void initializeStreamer(const std::string &fileName, const DebugSerializationFormat &format = DebugSerializationFormat::CBOR)

Initializes the streamer, unless it is already initialized (for example through env variables).

Parameters
  • fileName – The name of the file where all DebugInfo objects will be persisted.

  • format – The format of the file (JSON or CBOR).

static void closeStreamer()

Closes the streamer: all data is flushed to disk and the file is ready to be read.

DebugInfo objects destroyed after this point will not be persisted.

Private Members

std::unique_ptr<core::DebugInfo> impl
class DebugNameAndId
#include <DebugContext.hpp>

DebugNameAndId bundles a name and a DebugId to facilitate their propagation through function calls.

Public Functions

DebugNameAndId(std::string name = "", DebugId debugId = {}, std::string parentPath = "")
DebugNameAndId(const char *name)
DebugNameAndId(DebugId debugId)
DebugNameAndId(const DebugInfo &debugInfo, std::string name = "")
DebugNameAndId(const DebugNameAndId &DebugNameAndId, StringRef name = "")
DebugNameAndId &operator=(const DebugNameAndId &other)
~DebugNameAndId()
std::string getPathName() const

Gets the pathname of this object as the concatenation of the parent name received in the constructor via DebugInfo or DebugNameAndId and the name explicitly set for this object.

inline core::DebugNameAndId &getImpl() const

Private Members

std::unique_ptr<core::DebugNameAndId> impl
class SourceLocation
#include <DebugContext.hpp>

This class mimics std::source_location that is unavailable as we don’t yet support C++20.

Public Functions

SourceLocation() = default
inline constexpr SourceLocation(const char *functionName, const char *fileName, unsigned lineNumber)
inline constexpr const char *getFunctionName() const
inline constexpr const char *getFileName() const
inline constexpr unsigned getLineNumber() const
inline constexpr bool isValid() const

Public Static Functions

static inline SourceLocation Current()

Private Members

const char *functionName = {""}
const char *fileName = {""}
unsigned lineNumber = {}
bool valid = {false}
namespace core