An IET Expression wraps a SymPy equation. Below, DummyEq is a subclass of sympy.Eq with some metadata attached. What, when and how metadata are attached is here irrelevant.
from devito.ir.iet import Expressionfrom devito.ir.equations import DummyEqfrom devito.tools import pprintdef get_exprs(a, b, c, d, e, f):return [Expression(DummyEq(a, b + c +5.)), Expression(DummyEq(d, e - f)), Expression(DummyEq(a, 4* (b * a))), Expression(DummyEq(a, (6./ b) + (8.* a)))]exprs = get_exprs(symbs['a'], symbs['b'], symbs['c'], symbs['d'], symbs['e'], symbs['f'])pprint(exprs)
<Expression a = b + c[i] + 5.0>
<Expression d[j, k] = e[t0, t1, i] - f[t, x, y]>
<Expression a = 4*b*a>
<Expression a = 8.0*a + 6.0/b>
An Iteration typically wraps one or more Expressions.
kernel no.1:
void foo()
{
for (int i = 0; i <= 3; i += 1)
{
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
a = b + c[i] + 5.0F;
}
}
}
}
kernel no.2:
void foo()
{
for (int i = 0; i <= 3; i += 1)
{
a = b + c[i] + 5.0F;
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
d[j][k] = e[t0][t1][i] - f[t][x][y];
}
}
}
}
kernel no.3:
void foo()
{
for (int i = 0; i <= 3; i += 1)
{
for (int t0 = 0; t0 <= 4; t0 += 1)
{
a = b + c[i] + 5.0F;
}
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
d[j][k] = e[t0][t1][i] - f[t][x][y];
a = 4*b*a;
}
}
for (int t1 = 0; t1 <= 4; t1 += 1)
{
a = 8.0F*a + 6.0F/b;
}
}
}
An IET is immutable. It can be “transformed” by replacing or dropping some of its inner nodes, but what this actually means is that a new IET is created. IETs are transformed by Transformer visitors. A Transformer takes in input a dictionary encoding replacement rules.
from devito.ir.iet import Transformer# Replaces a Function's body with anothertransformer = Transformer({block1: block2})kernel_alt = transformer.visit(kernels[0])print(kernel_alt)
void foo()
{
for (int i = 0; i <= 3; i += 1)
{
a = b + c[i] + 5.0F;
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
d[j][k] = e[t0][t1][i] - f[t][x][y];
}
}
}
}
Specific Expressions within the loop nest can also be substituted.
# Replaces an expression with anothertransformer = Transformer({exprs[0]: exprs[1]})newblock = transformer.visit(block1)newcode =str(newblock.ccode)print(newcode)
for (int i = 0; i <= 3; i += 1)
{
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
d[j][k] = e[t0][t1][i] - f[t][x][y];
}
}
}
from devito.ir.iet import Blockimport cgen as c# Creates a replacer for replacing an expressionline1 ='// Replaced expression'replacer = Block(c.Line(line1))transformer = Transformer({exprs[1]: replacer})newblock = transformer.visit(block2)newcode =str(newblock.ccode)print(newcode)
for (int i = 0; i <= 3; i += 1)
{
a = b + c[i] + 5.0F;
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
// Replaced expression
{
}
}
}
}
# Wraps an expression in commentsline1 ='// This is the opening comment'line2 ='// This is the closing comment'wrapper =lambda n: Block(c.Line(line1), n, c.Line(line2))transformer = Transformer({exprs[0]: wrapper(exprs[0])})newblock = transformer.visit(block1)newcode =str(newblock.ccode)print(newcode)
for (int i = 0; i <= 3; i += 1)
{
for (int j = 0; j <= 5; j += 1)
{
for (int k = 0; k <= 7; k += 1)
{
// This is the opening comment
{
a = b + c[i] + 5.0F;
}
// This is the closing comment
}
}
}