Subject: [UFL-dev] [HG UFL] Added __hash__ to Form, and caching of hash, repr and str so they are only

From: [email-masked] (UFL)
Date: Fri, 5 Sep 2008 10:58:08 +0200 (CEST)

One or more new changesets pushed to the primary ufl repository.
A short summary of the last three changesets is included below.

changeset:   224:4df4ffa5de1be81ed07fdea22569beb39e2e75f0
tag:         tip
user:        "Martin Sandve Alnæs <[email-masked]>"
date:        Fri Sep 05 10:58:06 2008 +0200
files:       ufl/form.py
description:
Added __hash__ to Form, and caching of hash, repr and str so they are only
computed the first time str(form), repr(form) or hash(form) is called.

changeset:   223:ba9e5885326d923e2c64e38da65be9208d98c22d
user:        "Martin Sandve Alnæs <[email-masked]>"
date:        Thu Sep 04 14:50:28 2008 +0200
files:       ufl/finiteelement.py
description:
Bugfix: Always using the common long family name in VectorElement and TensorElement as well.

changeset:   222:c4a84a10764934c9c0434b6b1d72efb3759ab5b8
user:        "Martin Sandve Alnæs <[email-masked]>"
date:        Thu Sep 04 13:40:09 2008 +0200
files:       test/swiginac_eval.py test/test.py ufl/__init__.py ufl/algebra.py ufl/algorithms/ad.py ufl/algorithms/analysis.py ufl/algorithms/checks.py ufl/algorithms/swiginac_eval.py ufl/algorithms/transformations.py ufl/base.py ufl/baseoperators.py ufl/classes.py ufl/conditional.py ufl/objects.py ufl/tensoralgebra.py
description:
Renamed Scalar (formerly known as Number) to FloatValue.

Minor bugfix in analysis.py.

----------------------------------------------------------------------
For more details, visit http://www.fenics.org/hg/ufl

---

From: Anders Logg <[email-masked]>
Date: Sat, 6 Sep 2008 12:47:10 +0200

> computed the first time str(form), repr(form) or hash(form) is called.

Very nice. I have the same thing in FFC (JITObject) which wraps a form
and remembers the signature for later reuse.

One thing is that JITObject also includes the compiler flags
(quadrature or tensor representation etc) in the signature. Would it
be possible to add a mechanism like this to a Form so that it would
already be included in the signature? It would amount to attaching
a signature (for something else like compiler flags) to a Form that
gets included in the signature for the Form itself.

-- 
Anders

---

From: "Martin Sandve Alnæs" <[email-masked]>
Date: Sat, 6 Sep 2008 13:02:29 +0200

> gets included in the signature for the Form itself.

Done. I guess adding a variable "_metadata" to Form which
UFL doesn't really care about doesn't hurt anyone.
But I guess the __hash__ would need to include _metadata
as well? What have you done about that?

--
Martin

---

From: Anders Logg <[email-masked]>
Date: Sat, 6 Sep 2008 13:09:02 +0200

On Sat, Sep 06, 2008 at 01:02:29PM +0200, Martin Sandve Alnæs wrote:
> Done.

Nice!

> I guess adding a variable "_metadata" to Form which

I just include str(_metadata) in the string that generates the
signature. Here's the code for signature() in JITObject:

    def signature(self):
        "Return signature"

        # Check if we have computed the signature before
        if not self._signature is None:
            return self._signature

        # Compute signature
        self.form_data = analyze.analyze(algebra.Form(self.form), simplify_form=False)
        form_signature = str(self.form)
        element_signature = ";".join([element.signature() for element in self.form_data.elements])
        options_signature = str(self.options)
        s = ";".join([form_signature, element_signature, options_signature])
        self._signature = "form_" + sha1(s).hexdigest()
        
        return self._signature

-- 
Anders

---

From: "Martin Sandve Alnæs" <[email-masked]>
Date: Sat, 6 Sep 2008 13:30:04 +0200

>        self._signature = "form_" + sha1(s).hexdigest()

Two questions.

Why all the analysis? Isn't the "original" state of the form enough?
With UFL I'd probably just do repr(form) + str(_metadata).
But maybe there are some transformations that makes
the comparison more robust, e.g. renumbering of objects
like Function and BasisFunction.

You're using a checksum as the returned signature.
Why not just return s?

Currently, Instant computes its own checksum of the given signature,
which it uses for the module name in the disk cache.
Either we can require the signature given to Instant to be
a checksum already (or at least a valid part of a filename),
and skip the checksum computation in Instant, or you can
drop this checksum computation and just pass s to Instant.

--
Martin

---

From: Anders Logg <[email-masked]>
Date: Sat, 6 Sep 2008 13:46:54 +0200

> like Function and BasisFunction.

I need to extract the elements for inclusion in the signature and they
are not available in str(form). It could be added to a .signature()
function in the form objects.

> You're using a checksum as the returned signature.

It's too long and it won't work as a class name or file name. FFC uses
the signature as the name of the ufc:: classes it generates.

> drop this checksum computation and just pass s to Instant.

That would be good. I'd prefer that Instant assumed it gets a hash
since FFC needs to generate a name for the ufc:: classes.

-- 
Anders

---

From: "Martin Sandve Alnæs" <[email-masked]>
Date: Sat, 6 Sep 2008 13:51:25 +0200

> since FFC needs to generate a name for the ufc:: classes.

Ok. I forgot I also do that in SFC now (in the upcoming UFL-based version).

Even better: Instant can check the signature string and take the
checksum of it if it doesn't meet certain requirements like being a
valid filename and shorter than some constant limit.

--
Martin

---

From: Anders Logg <[email-masked]>
Date: Sat, 6 Sep 2008 13:56:45 +0200

> valid filename and shorter than some constant limit.

Sounds good.

-- 
Anders