Subject: [UFL-dev] JIT compilation

From: Anders Logg <[email-masked]>
Date: Tue, 24 Feb 2009 22:12:38 +0100

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.

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.

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.

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
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).

-- 
Anders

---

From: Martin Sandve Alnæs <[email-masked]>
Date: Tue, 24 Feb 2009 22:51:53 +0100

> uses this to extract coefficients and elements.

Agreed.

> the compiled form and the JIT compiler returns the form + form data to

So far so good.

> Instant returns the compiled form. This means that the form data is

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

> 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.

> 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

---

From: Martin Sandve Alnæs <[email-masked]>
Date: Wed, 25 Feb 2009 19:14:29 +0100

I've implemented this in UFL such that:

    a = ...*dx
    ...
    fd = a.form_data()

ensures that a FormData object is
computed once and only once.
So jit can do this:

def jit(form):
    formdata = form.form_data()
    ...

Martin

---

From: Anders Logg <[email-masked]>
Date: Wed, 25 Feb 2009 22:41:30 +0100

Thanks! This works fine.

-- 
Anders

---

From: Martin Sandve Alnæs <[email-masked]>
Date: Wed, 25 Feb 2009 22:56:45 +0100

Also check out the latest commit message.

Martin

On Wed, Feb 25, 2009 at 10:41 PM, Anders Logg <[email-masked]> wrote:
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
>
> iEYEARECAAYFAkmluwgACgkQTuwUCDsYZdHd+gCbBprjVbqQPkAwZXCkIj5MruKv
> McUAn3QVmUkadX3Q4G68ztqE8RWOpNv+
> =rgdl
> -----END PGP SIGNATURE-----
>
>

---

From: Anders Logg <[email-masked]>
Date: Wed, 25 Feb 2009 23:12:23 +0100

ok, but we haven't gotten that far yet (to extract
functions/coefficients in DOLFIN), unless Kristian has looked at it.

-- 
Anders

---

From: Kristian Oelgaard <[email-masked]>
Date: Wed, 25 Feb 2009 23:39:14 +0100

> functions/coefficients in DOLFIN), unless Kristian has looked at it.

No, I just generate pure UFC code. That is, when things are not broken....

Kristian