Util

#include <poputil/Util.hpp>

General operations on tensors.

namespace poputil

General utility functions for building graphs.

Functions

void mergeAdjacentRegions(std::vector<poplar::Interval> &regions)
void mergeAdjacentRegions(std::vector<std::vector<poplar::Interval>> &mapping)
std::vector<poplar::Interval> flattenIntervals(const std::vector<std::vector<poplar::Interval>> &intervals)

Flatten a vector of vectors of intervals to a vector, maintaining ordering.

std::vector<std::vector<poplar::Interval>> splitRegions(const std::vector<poplar::Interval> &regions, unsigned grainSize, unsigned maxPartitions, unsigned minElementsPerPartition = 0, unsigned maxElementsPerPartition = UINT_MAX, unsigned maxElementsPerRegion = UINT_MAX)

Given a set of contiguous regions, partition these regions while trying to balance the number of elements in each partition and respecting the specified grain size.

At most maxPartitions partitions are created. Regions may be split to achieve a better balance.

std::vector<std::vector<poplar::Interval>> splitRegionsBetweenWorkers(const poplar::Target &target, const std::vector<poplar::Interval> &regions, unsigned grainSize, unsigned minElementsPerPartition = 0, unsigned maxElementsPerPartition = UINT_MAX, unsigned maxElementsPerRegion = UINT_MAX)

Given a set of contiguous regions per tile, partition these regions between workers on that tile while respecting the specified grain size.

Regions may be split to balance the work across workers.

std::vector<std::vector<std::vector<poplar::Interval>>> splitRegions(const std::vector<std::vector<poplar::Interval>> &regions, unsigned grainSize, unsigned maxPartitions, unsigned minElementsPerPartition = 0, unsigned maxElementsPerPartition = UINT_MAX, unsigned maxElementsPerRegion = UINT_MAX)

Given a set of sequences of regions, partition these sequences while trying to balance the number of elements in each partition and respecting the specified grain size.

At most maxPartitions partitions are created. Sequences, and regions within them, may be split to achieve a better balance.

std::vector<std::vector<std::vector<poplar::Interval>>> splitRegionsBetweenWorkers(const poplar::Target &target, const std::vector<std::vector<poplar::Interval>> &regions, unsigned grainSize, unsigned minElementsPerPartition = 0, unsigned maxElementsPerPartition = UINT_MAX, unsigned maxElementsPerRegion = UINT_MAX)

Given a set of sequences of regions per tile, partition these sequences between workers on that tile while respecting the specified grain size.

Regions may be split to balance the work across workers.

template<class T>
std::vector<T> unflattenIndex(const std::vector<T> &shape, std::size_t index)

Given an index into a flattened tensor, returns the indices into the dimensions of the original tensor.

template<class T>
std::size_t flattenIndex(const std::vector<T> &shape, const std::vector<T> &indices)

Given a list of indices into a tensor, return the corresponding index in a flattened version of the tensor.

std::size_t intervalSequenceNumElements(const std::vector<std::vector<poplar::Interval>> &seq)

Return the total number of elements in the interval sequence.

poplar::Tensor duplicate(poplar::Graph &graph, const poplar::Tensor &in, poplar::program::Sequence &p, const poplar::DebugContext &debugContext = {}, poplar::TensorCloneMethod method = poplar::TensorCloneMethod::PRESERVE_ORDER_UNLESS_ALIASES)

Copy a tensor’s data to a new tensor.

The duplicated tensor has the same tile mapping as the original tensor.

poplar::Tensor cloneN(poplar::Graph &graph, const poplar::Tensor &t, unsigned N, const poplar::DebugContext &debugContext = {}, poplar::TensorCloneMethod method = poplar::TensorCloneMethod::PRESERVE_ORDER_UNLESS_ALIASES)

Clone a tensor N times.

Given a tensor of shape [D1, D2, … Dn], this function will create a new tensor of shape [N, D1, D2, …, Dn] where each of the N sub-tensors is a clone of the original tensor (that is, it has the same layout).

Parameters
  • graph – The Poplar graph.

  • t – The tensor to clone.

  • N – The replication factor to clone with.

  • name – The name for the new variables created.

  • method – The tensor cloning method (see Graph::clone()).

std::vector<int> balancedPartition(int rangeUpperBound, int splitCount)

Split a range.

Utility function to split a range [0, rangeUpperBound] into splitCount slices as evenly as possible. If splitCount does not divide rangeUpperBound evenly then output slices are assigned more units in round-robin.

double castToDeviceHalfValue(const poplar::Target &target, double input)

Cast a double precision value to a value exactly representable in device HALF type.

Parameters
  • target – The target device that the cast will be performed on.

  • input – Input value.

Returns

Value cast to HALF type on device.

bool checkAccuracyWhenCast(const poplar::Target &target, double input, poplar::Type inputType, poplar::Type outputType, double tolerance)

Check accuracy of a cast operation.

Utility function to check if input can be cast from inputType to outputType without an error in its accuracy, or causing an overflow.

Parameters
  • target – The target device that the cast will be performed on.

  • input – Input value.

  • inputType – Input type before the cast operation.

  • outputType – Output type after the cast operation.

  • tolerance – Allowed tolerance in error from cast operation.

Throws

poputil::poplibs_error – If either inputType or outputType are not either half or float.

Returns

Boolean tensor indicating the error will be less than tolerance.

poplar::Tensor factorDims(const poplar::Tensor &t, const std::vector<std::size_t> &factors, unsigned startDim = 0)

Factors the outermost dimensions of tensor t by the values given in factors.

For each value f in factors, the corresponding outer dimension is split into two parts of sizes size(dim)/f and f. The second of these becomes a dimension inside all the factored dimensions. For example, given a tensor with shape [4,6,4] and factors [1,2], we first divide the shape into [4/1,1,6/2,2,4] and then shuffle it to [4/1,6/2,1,2,4].

Parameters
  • t – The tensor to be factored.

  • factors – The values to factor each dimension by.

  • startDim – The outermost dimension to start at.

Returns

The refactored tensor.

poplar::Tensor unfactorDims(const poplar::Tensor &t, unsigned numDims, unsigned startDim = 0)

The opposite of factorDims().

This does not need information for each dimension because that is present in the tensor. It just needs the number of dimensions.

Parameters
  • t – The tensor to be refactored.

  • numDims – The number of dimensions to be refactored.

  • startDim – The outermost dimension to start at.

Returns

The refactored tensor.

poplar::Tensor createConstantMetadataTensor(poplar::Graph &graph, poplar::QuarterMetadata::Format fp8Format, int fp8Scale)

Deprecated:

deprecated Use poplar::createConstantMetadataTensor() instead

Create a QUARTER_METADATA tensor for use with tensors with data type = QUARTER

Parameters
  • graph – The graph that the tensor will be added to.

  • fp8Format – The format (F143 or F152) to write to the output QUARTER_METADATA tensor.

  • fp8Scale – The value of the scale which will be written to the output QUARTER_METADATA tensor.

Returns

A constant tensor of type QUARTER_METADATA initialised with the format and scale provided.

poplar::Tensor createVariableMetadataTensor(poplar::Graph &graph, poplar::QuarterMetadata::Format fp8Format, int fp8Scale)

Deprecated:

deprecated Use poplar::createVariableMetadataTensor() instead

Create a QUARTER_METADATA tensor for use with tensors with data type = QUARTER

Parameters
  • graph – The graph that the tensor will be added to.

  • fp8Format – The format (F143 or F152) to write to the output QUARTER_METADATA tensor.

  • fp8Scale – The value of the scale which will be written to the output QUARTER_METADATA tensor.

Returns

A variable tensor of type QUARTER_METADATA initialised with the format and scale provided.

std::vector<poplar::Interval> calculateUnshufflingIntervals(const std::vector<poplar::Interval> &intervals)

Calculate the un-shuffling intervals based on the given intervals.

Given a vector of intervals, one could use these intervals to shuffle a tensor. For example:

poplar::Tensor shuffled = poplar::concat(tensor.slices(intervals));

Another vector of intervals exists that can be applied in the same way to the shuffled tensor to undo the shuffling. This function calculates these intervals. The time complexity is nlog(n) with n the number of intervals.

Note: This function assumes that the intervals are non-overlapping and form one contiguous interval.

Parameters

intervals – A vector of intervals that shuffle a tensor.

Returns

A vector of intervals that unshuffle a tensor.