Subject: Re: [FFC-dev] [DOLFIN-dev] new mesh: quick but somewhat painful :)

From: Anders Logg <[email-masked]>
Date: Wed, 1 Nov 2006 09:49:27 +0100

On Tue, Oct 31, 2006 at 05:16:33PM +0100, Dag Lindbo wrote:
>> Hi all,
>> 
>> I'm seeing really great speedup due to the new mesh class in DOLFIN
>> 0.6.3!
>> Other reaction?
>> 

>Yes, I'm also seeing speedups, the old mesh had overhead which seems
>to be gone now. I haven't done any real benchmarks yet though. The new
>mesh is also a much better abstraction and I really like it.

I'm working on some benchmarks for the new mesh that I will present in
Delft next week. I'm mostly happy with the speed we get but we could
improve in some places. The mesh is designed to be very fast but I
have made absolutely no optimizations (other than by design) so there
is room for improvements.

>> Well, I had to make changes in FFC in order to compile my solvers
>> with
>> 0.6.3. Let me share the problem (and a proposed fix).
>> 
>> As I understand it, there is a consolidation between DOLFIN and SWIG
>> formats in DOLFIN 0.6.3/FFC 0.3.4 (Johan J: isn't this correct?).

>Yes, this is correct, we had two different formats due to SWIG not
>supporting nested classes. We've managed to come up with a workaround
>though.

>> The problem (that is new in 0.6.3) is that if one uses the same
>> form-header in two classes (that are both used in a particular
>> solver)
>> then there will be an error at link-time due to multiple
>> implementation of
>> the form. Take this example:
>>
>> Class GeneralFunctions
>>     *) Includes a form header, formX.h
>>
>> Class LevelSetSolver
>>     *) Uses stuff from GenericFunctions
>>
>> Class FlowSolver
>>      *) Uses stuff from GenericFunctions as well
>>
>> Class TwoPhaseFlowSolver
>>      *) Uses FlowSolver and LevelSetSolver
>>      *) Has main()
>>
>> All classes compile. This means that the code in the formX header is
>> compiled into object code in multiple places. Then linker will fail
>> due to
>> redefinitions of the formX implementation.

>Ok, the idea was that the new format should be semantically equivalent
>to the old format. But it seems we overlooked one thing. The old
>format looked like this:
>
>class A
>{
>  void foo()
>  {
>  }
>}
>
>and the new format looks like this:
>
>class A
>{
>  void foo();
>}
>
>void A::foo()
>{
>}
>
>But apparently this is not equivalent, putting the implementation
>inside the class definition implicitly makes the function inline, so
>it should look like this:
>
>class A
>{
>  void foo();
>}
>
>inline void A::foo()
>{
>}

>> What I did to solve this was to change the output format of FFC so
>> that I
>> get form declarations in .h-files and form implementations in the
>> corresponding .cpp-files. This way the form implementations are only
>> compiled into object code once, so the linkage is fine.

>Yes, this would be the cleanest solution. The question is if we want
>to make such a structural change when we will change to a different
>format soon anyway. It would break all the DOLFIN demos for example,
>which assume only one source file

I'd prefer only one file.

>> If anyone else is has plans to move to 0.6.3 and has forms that are
>> used
>> in multiple classes, then I think the best option is to do this
>> change in
>> FFC. Let me know, and I'll send a simple patch. Coming releases of
>> FFC/DOLFIN will use a new format, and the linkage problem will be
>> dealt
>> with then (according to Anders Logg).
>> 
>> Cheers!
>> /Dag Lindbo
>> 

>I CC:ed this to dolfin-dev and ffc-dev, I hope you don't mind.
>
>  Johan

The new output format from FFC will be UFC - Unified Form-assembly
Code. This is nothing fancy, just an attempt at specifying a fixed
interface for the code that FFC (and other compilers like SyFi)
generates.

We're working on the first draft of UFC that we will present in Delft
next week. After a few rounds of comments and updates, this will be
fixed as "UFC v 1.0". Then you can compile your form with any compiler
(for example FFC and SyFi) and know that you can stick the generated code into
any system that supports UFC 1.0 (like DOLFIN and PyCC).

There's a preview available at

    http://www.fenics.org/hg/ufc

/Anders

---

From: "Dag Lindbo" <[email-masked]>
Date: Wed, 1 Nov 2006 13:14:19 +0100 (MET)

It was never my intention to make this a patch for FFC - such decisions I
leave to the developers. However, let me make a few points that support
having separate files for declarations and implementation:

*) From the compilers point of view I think headers sholuld be 'clean'
(i.e. not even inline functions).

*) Solvers, in my case at least, are changed more often than forms. It
would make sense that the form implementations are not recompiled when the
solver is changed. This actually becomes a real issue when the forms
become complicated. We have dicussed compile time on this list before.

*) Due to compile time it is often neccesary to lower optimization levels
on more complicated forms. Compiling the form separately makes this more
convenient.

/Dag

> _______________________________________________
> FFC-dev mailing list
> [email-masked]
> http://www.fenics.org/mailman/listinfo/ffc-dev
>

---

From: "Garth N. Wells" <[email-masked]>
Date: Wed, 01 Nov 2006 13:36:53 +0100

> (i.e. not even inline functions).

I'm not sure that this is so black and white. Sometimes it can be
convenient to split things, and at others times it is convenient to have
everything in the header file. Also, inline functions in general must be
defined in the header file.

> become complicated. We have dicussed compile time on this list before.

For me, same story as above. Sometimes I change forms more often.
Depends on what I'm looking at. The the blas format helps here (is it
working now if you don't use boundary integrals?).

> on more complicated forms. Compiling the form separately makes this more

This is an issue. Using the blas format improves compile times (vastly
for complicated forms). Also, the situation for complicated forms is
rather subtle as the tensor contraction approach which FFC uses is
probably not the best way and leads to huge header files and long
compilation times.

I generally prefer including just one file. For now, I think in
addressing the compilation time issue, the blas format is the way to go.
To fix the multiple includes, I'd like to see a SWIG workaround if
possible that avoids moving definitions outside of the class body.

Garth

> DOLFIN-dev mailing list
> [email-masked]
> http://www.fenics.org/mailman/listinfo/dolfin-dev
>

---

From: Anders Logg <[email-masked]>
Date: Wed, 1 Nov 2006 13:49:30 +0100

> possible that avoids moving definitions outside of the class body.

The plan is that the new format will not need any special SWIG
workarounds. There are no nested classes that can cause problems in
the new interface.

/Anders

---

From: Anders Logg <[email-masked]>
Date: Wed, 1 Nov 2006 15:00:20 +0100

There is nothing that prevents us from generating two files, one .h
file and one .cpp file. When the new backend is in place, I'll accept
patches to FFC for outputting two different files (if a suitable
compiler flag is specified).

/Anders