The first compilation pass is named lowering, and three main tasks are carried out: indexification, substitution, and domain-alignment. In this notebook, we will explore the Indexification step.

Indexification

The indexification consists of converting Functions into Indexeds, that is actual array accesses. An Indexed always keeps a reference to its originating Function. For instance, all accesses to u such as u[t, x + 1] and u[t + 1, x − 2] would store a pointer to the same, user-defined Function u(t, x). This metadata is exploited throughout the various compilation passes.

To see this, let’s create a TimeFunction named u.

from devito import Grid, TimeFunction
u = TimeFunction(name='u', grid=Grid((3,)), save=1)
print(u)
u(time, x)

Note that u has one temporal dimension and one spatial dimension, that we will call time and x here, respectively.

time, x = u.dimensions
time, x
(time, x)

Functions (of type Function, TimeFunction and SparseFunction) can be indexified in two equivalent ways, either via the .indexify() method, as illustrated below, or via explicit indexing, as typically done in user code.

u_i = u.indexify() # For more details about the method `indexify`, see `devito/symbolics/manipulation.py`
print(u_i)
u[time, x]

Now, dimensions are interpreted as indices.

u_i.indices == u.dimensions
True

The explicit indexing mode is when you write

a = u[time,x+1]

and you get exactly (representation shown below)

print(a)
u[time, x + 1]

ie, this is totally equivalent to indexify. Another example, you can write

b = u[time+1,x-2]

and you get

print(b)
u[time + 1, x - 2]

Clearly, we now have that

a.indices == b.indices
False

Thus

a == b
False

However, we can verify that these accesses still point to the very same TimeFunction object.

a.function is b.function 
True

Note also that there is no data associated with Indexed objects.

type(u_i)
# u_i.data   # This should return an error!
devito.types.basic.Indexed

The data representing the grid is accessed through the Function that the indices point to.

u_i.function.data
Data([[0., 0., 0.]], dtype=float32)
Back to top