ConditionalDimension

ConditionalDimension(self, *args, **kwargs)

Symbol defining a non-convex iteration sub-space derived from a parent Dimension, implemented by the compiler generating conditional “if-then” code within the parent Dimension’s iteration space.

Parameters

Name Type Description Default
name str Name of the dimension. required
parent devito.types.dimension.Dimension The parent Dimension. required
factor int The number of iterations between two executions of the if-branch. If None (default), condition must be provided. None
condition expr - like An arbitrary SymPy expression, typically involving the parent Dimension. When it evaluates to True, the if-branch is executed. If None (default), factor must be provided. None
indirect bool If True, use self, rather than the parent Dimension, to index into arrays. A typical use case is when arrays are accessed indirectly via the condition expression. False

Examples

Among the other things, ConditionalDimensions are indicated to implement Function subsampling. In the following example, an Operator evaluates the Function g and saves its content into f every factor=4 iterations.

>>> from devito import Dimension, ConditionalDimension, Function, Eq, Operator
>>> size, factor = 16, 4
>>> i = Dimension(name='i')
>>> ci = ConditionalDimension(name='ci', parent=i, factor=factor)
>>> g = Function(name='g', shape=(size,), dimensions=(i,))
>>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))
>>> op = Operator([Eq(g, 1), Eq(f, g)])

The Operator generates the following for-loop (pseudocode)

.. code-block:: C

for (int i = i_m; i <= i_M; i += 1) {
  g[i] = 1;
  if (i%4 == 0) {
    f[i / 4] = g[i];
  }
}

Another typical use case is when one needs to constrain the execution of loop iterations so that certain conditions are honoured. The following artificial example uses ConditionalDimension to guard against out-of-bounds accesses in indirectly accessed arrays.

>>> from sympy import And
>>> ci = ConditionalDimension(name='ci', parent=i,
...                           condition=And(g[i] > 0, g[i] < 4, evaluate=False))
>>> f = Function(name='f', shape=(int(size/factor),), dimensions=(ci,))
>>> op = Operator(Eq(f[g[i]], f[g[i]] + 1))

The Operator generates the following for-loop (pseudocode)

.. code-block:: C

for (int i = i_m; i <= i_M; i += 1) {
  if (g[i] > 0 && g[i] < 4) {
    f[g[i]] = f[g[i]] + 1;
  }
}

Attributes

Name Description
is_Conditional bool(x) -> bool
is_NonlinearDerived bool(x) -> bool
Back to top