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.
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.
In [1]:
from devito import Grid, TimeFunction
u = TimeFunction(name='u', grid=Grid((3,)), save=1)
print(u)
Note that u has one temporal dimension and one spatial dimension, that we will call time and x here, respectively.
In [2]:
time, x = u.dimensions
time, x
Out[2]:
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.
In [3]:
u_i = u.indexify() # For more details about the method `indexify`, see `devito/symbolics/manipulation.py`
print(u_i)
Now, dimensions are interpreted as indices.
In [4]:
u_i.indices == u.dimensions
Out[4]:
The explicit indexing mode is when you write
In [5]:
a = u[time,x+1]
and you get exactly (representation shown below)
In [6]:
print(a)
ie, this is totally equivalent to indexify. Another example, you can write
In [7]:
b = u[time+1,x-2]
and you get
In [8]:
print(b)
Clearly, we now have that
In [9]:
a.indices == b.indices
Out[9]:
Thus
In [10]:
a == b
Out[10]:
However, we can verify that these accesses still point to the very same TimeFunction object.
In [11]:
a.function is b.function
Out[11]:
Note also that there is no data associated with Indexed objects.
In [12]:
type(u_i)
# u_i.data # This should return an error!
Out[12]:
The data representing the grid is accessed through the Function that the indices point to.
In [13]:
u_i.function.data
Out[13]: