← Back to team overview

ufl team mailing list archive

Re: JIT compilation

 

Quoting Anders Logg <logg@xxxxxxxxx>:

> ok, but we haven't gotten that far yet (to extract
> 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
 
> -- 
> Anders
> 
> 
> On Wed, Feb 25, 2009 at 10:56:45PM +0100, Martin Sandve Alnæs wrote:
> > Also check out the latest commit message.
> > 
> > Martin
> > 
> > 
> > 
> > On Wed, Feb 25, 2009 at 10:41 PM, Anders Logg <logg@xxxxxxxxx> wrote:
> > > Thanks! This works fine.
> > >
> > >
> > >
> > > On Wed, Feb 25, 2009 at 07:14:29PM +0100, Martin Sandve Alnæs wrote:
> > >> 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
> > >>
> > >>
> > >>
> > >> On Tue, Feb 24, 2009 at 10:51 PM, Martin Sandve Alnæs
> > >> <martinal@xxxxxxxxx> wrote:
> > >> > 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
> > >> >
> > >
> > > -----BEGIN PGP SIGNATURE-----
> > > Version: GnuPG v1.4.9 (GNU/Linux)
> > >
> > > iEYEARECAAYFAkmluwgACgkQTuwUCDsYZdHd+gCbBprjVbqQPkAwZXCkIj5MruKv
> > > McUAn3QVmUkadX3Q4G68ztqE8RWOpNv+
> > > =rgdl
> > > -----END PGP SIGNATURE-----
> > >
> > >
> 




References