Poplar and PopLibs
poplar::program::WriteUndef Class Reference

A program to mark a tensor as containing an undefined value. More...

#include <Program.hpp>

Inheritance diagram for poplar::program::WriteUndef:
poplar::program::Program

Detailed Description

A program to mark a tensor as containing an undefined value.

This can be used to improve the liveness analysis of tensors and save memory in some situations.

Poplar does liveness analysis using the standard algorithm, except that Poplar's variables are not scalar values; they are arrays (tensors). In the standard analysis, a variable is "killed" when it is written to with a new value. This means that it is dead immediately before that point because its value there can never be read.

int a = 1;
// a is dead here because its current value (1) can never be read.
a = 2; // a is killed here, which makes it dead on the line above.

In Poplar, a variable is killed when all of its elements are written in the same compute set. Consider the pseudo-code:

var = graph.addVariable(FLOAT, {2}, ...);
seq.add(Execute( var[0] = 1, var[1] = 2 ));
// var is dead here (it is killed on the line below) because none of its
// element values (1, 2) can ever be read.
seq.add(Execute( var[0] = 3, var[1] = 4 ));
Type FLOAT
Device type: float

If only some of the elements are written then the entire variable is still live before the write because we may still need the values of the elements that were not written to.

seq.add(Execute( var[0] = 1, var[1] = 2 ));
// var is alive here because the value 2 might be read later.
seq.add(Execute( var[0] = 3 ));

var is still alive because no compute set writes to every element. If the entire variable is overwritten but in separate compute sets, then it will still be considered to be live because Poplar does not track the liveness of each variable element, only the entire variable.

seq.add(Execute( var[0] = 1, var[1] = 2 ));
// var is alive here even though 1 and 2 can never be read.
seq.add(Execute( var[0] = 3 ));
seq.add(Execute( var[1] = 4 ));

This means var is alive more than necessary which may lead to increased memory use. One solution is for Poplar to track the liveness of every variable element separately, but that would be prohibitively expensive.

Instead, this program provides a way to manually mark a tensor as being dead by writing an undefined value to it. Changing the above code to the following results in the correct liveness.

seq.add(Execute( var[0] = 1, var[1] = 2 ));
// Manually kill var because we know - even if Poplar does not - that
// it is about to be completely overwritten.
seq.add(WriteUndef(var));
seq.add(Execute( var[0] = 3 ));
seq.add(Execute( var[1] = 4 ));

For more information about liveness analysis see https://en.wikipedia.org/wiki/Live_variable_analysis and https://www.cl.cam.ac.uk/teaching/2006/OptComp/slides/lecture03.pdf

Parameters
tThe tensor to mark as undefined.
debugContextOptional DebugId and program name.

The documentation for this class was generated from the following file: