#!/usr/bin/env python # coding: utf-8 # 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`. # 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 # 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 # 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 # Thus # In[10]: a == b # However, we can verify that these accesses still point to the very same `TimeFunction` object. # In[11]: a.function is b.function # Note also that there is no `data` associated with `Indexed` objects. # In[12]: type(u_i) # u_i.data # This should return an error! # The `data` representing the grid is accessed through the `Function` that the indices point to. # In[13]: u_i.function.data