Modifying entities outside of providers
Touch
IRPF90 guarantees that an entity will not be re-provided if its value is
already computed and valid. If the value of an entity is modified by a side
effect outside of its provider, all the entities which are parent of the
modified entity should be invalidated. This is done using the TOUCH
keyword.
In this example, all the entities have been provided (figure (a)). If the user
requests the value of z
, it will be fetched from the memory. Then, the value
of x
is modified by a side effect, so the tree is not valid any more. Using
TOUCH x
(figure (b)), all the parents are invalidated, but the value of x
is set as valid (figure (c)). Requesting z
now will give the correct value of
z
taking account of the modification of x
and re-providing only what is
necessary between x
and z
.
Iterative processes
An iterative process at iteration n
is characterized by :
A(n+1)
needs C(n)
needs B(n)
needs A(n)
needs C(n-1)
etc...
As in IRPF90 the dependence tree is static, we will want to write
the iterative process as: A
needs B
needs C
needs A
...
But this implies a cyclic dependency. In that case, we will violate the
rule that an entity is created only by one provider, and we will allow C
to
be modified from outside of its provider, such that it only depends on C0
, its
initial guess value. The provider of C
will then only describe its
initialization by copying its initial guess value C0
.
BEGIN_PROVIDER [ double precision, C ]
C = C0
END_PROVIDER
The converged value A_converged
of A
will be written as follows:
BEGIN_PROVIDER [ double precision, A_converged ]
logical :: iteration_condition
do while (iteration_condition)
! Modify the value of C depending on
! the current value of A
C = f(A)
TOUCH C
enddo
A_converged = A
END_PROVIDER
Soft touch
When IRPF90 encounters the TOUCH
keyword, it produces the following Fortran code:
! >>> TOUCH x
call touch_x
! <<< END TOUCH
if (.not.a_is_built) then
call provide_a
endif
if (.not.b_is_built) then
call provide_b
endif
After a TOUCH
statement, all the entities in the current variable scope are
provided again to ensure that the program will be correct. This can sometimes
lead to providing entities that will not be needed later, especially in the
cases where the TOUCH
statement is the last statement of a provider.
The SOFT_TOUCH
statement has the same effect as TOUCH
, except that
the entities in the current scope are not re-provided. It can be used as an
optimization of the TOUCH
when all the other entities are no more used in
the current subroutine, function or provider. However, it has to be used with
caution.