← Back to team overview

ufl team mailing list archive

Re: JIT compilation

 

On Tue, Feb 24, 2009 at 10:12 PM, Anders Logg <logg@xxxxxxxxx> wrote:
> The FFC JIT compiler (and any other JIT compiler that DOLFIN uses)
> must be able to return FormData as well as the compiled form. DOLFIN
> uses this to extract coefficients and elements.

Agreed.

> Without caching, the JIT compiler gets the form, generates form data,
> generates the C++ code which is sent to Instant. Instant then returns
> the compiled form and the JIT compiler returns the form + form data to
> DOLFIN.

So far so good.

> With caching, the JIT compiler gets the form, sends it to Instant (or
> rather a wrapper that returns an appropriate hash and signature). Then
> Instant returns the compiled form. This means that the form data is
> missing.

Which is the way it has to be for Instant to be an independent project.

> FFC solves this by attaching the form data to the form:
>
>  form.form_data = form_data
>
> This way, the form data is available both when the in-memory cache is
> used and when the disk cache is used. In the first case, the form has
> been JIT compiled before so the object has form_data attached to
> it. In the second case, the signature needs to be computed which means
> that also the form data will be computed.
>
> Would it be possible/desirable to attach form data to a UFL form? Or
> will it be necessary to keep a separate form data cache in the JIT

Let me just think loudly.

The thing is, the Form that the user passes in to jit won't be
the same Form as Formdata contains. Derivatives must be
expanded to know the right number of form arguments,
and indices and arguments are renumbered to get a canonical
repr independent of the order which forms are defined in the
application.

Unless this behaviour is changed, attaching form data to
the form will mean that "a.form_data.form != a", but
a.form_data.form still represents the same form, and
FormData does nothing compiler- or representation-specific.

What does this mean? Take this pseudocode:

# make some form:
a = ...*dx

# compile some times with jit and then with different options to make
it interesting:
form1, formdata1 = jit(a)
form2, formdata2 = jit(a)
form3, formdata3 = jit(a, options = non_default_options)
form2, formdata2 = jit(a)

# instant ensures this:
form1.__module__ == form2.__module__
form1.__module__ == form4.__module__

# and the different options should lead to this:
form3.__module__ != form2.__module__

# you want this:
a.form_data == formdata1 # computed and attached to a in first jit call
a.form_data == formdata2 # reused in second jit call
a.form_data == formdata3 # if not, we'll get major problems
a.form_data == formdata4


I was sceptical at first, but I think this will work out.
As long as "fd = FormData(a)" is a completely deterministic
operation with no options that can change the result,
attaching it to a poses no problems. In particular, FormData
must be independent of any dolfin or form compiler options.

> compiler. It sort of makes the in-memory cache of Instant pointless
> (for form compilation) since the JIT compiler might then as well cache
> the compiled form (as it did before this was added to Instant).

Not true. In PyDOLFIN, forms with different coefficients will
have different formdata (which dolfin may or may not keep
a cache of as we discuss now), but still be the same
compiled form, which instant caches separately.

Martin


Follow ups

References