Skip to content

RFC: Index Expression API #126

Open
Open
@fredrikbk

Description

@fredrikbk

This issue requests comments for a new index expression API proposal. It supercedes issues #72 and #111. The index expression module relates to other modules in the following way:

Modules

The API is in the taco namespace. It is designed to be convenient to use by us and by end users directly.

IndexVar

An IndexVar is an index variable in a tensor index expression.

IndexExpr

An IndexExpr is a tensor index expression. It has several subclasses including the standard expressions (e.g., +, - and *), Assign (e.g., a(i) = b(i)), and Access (e.g., A(i,j) where A is a TensorVar).

TensorVar

A TensorVar is either a variable in an index expression (e.g., A(i,j)) or the result of an index expression (e.g., A(i,j) = B(i,j) + C(i,j)).

A TensorVar is a source for tensor data, whether it comes from memory, disk, or a computed index expression. It is different from the Tensor class because it does not actually store data. When computing a compiled expression (using the function API) TensorVar instances must be bound to data.

TensorVar objects must be given a type and a format, or else they will be given defaults. The constructor is:

TensorVar::TensorVar(Type, Format);

Type consist of a component datatype (e.g. double) and the tensor dimensions. Tensor dimensions are given as a vector or initializer list and can either be hard-coded or parametric. E.g.,

Type fixed(Double, {256,256});

Dimension n, m;
Type variable(Double, {n,m});

Type blocked(Double, {n, m, 3, 3});

Lowering Index Expressions

Index expressions can be lowered using the API's in the lower module, which turns them into the imperative IR in the ir module.

We can turn a tensor index expression into a runnable function with the compile function. For example

IndexVar i, j;
TensorVar A(Type(Double, {256,256}), Sparse);
TensorVar B(Type(Double, {256,256}), Sparse);
TensorVar C(Type(Double, {256,256}), Sparse);
A(i,j) = B(i,j) + C(i,j);

Function function = compile(A, {B,C}, Target::C);

TensorStorage myA;
TensorStorage myB = read("B.tns");
TensorStorage myC = read("C.tns");

function.assemble(myA, myB, myC);
function.compute(myA, myB, myC);

, where the arguments to compile are the input and output parameters of the function (in order) as well as the target backend, e.g., C, .

In the future, we may want to simultaneously lower multiple index expressions to take advantage of cross-expression optimization opportunities. Multiple expressions can also be lowered with the lower function by declaring multiple results.

TensorVar D, E;
D(i,j) = A(i,j) * E(i,j);

Function function = compile({A,D}, {B,C,E}, Target::C);

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions