← Back to team overview

ffc team mailing list archive

Re: Adding code generation backends to FFC and generating C code

 

On Mon, Feb 25, 2013 at 04:07:52PM +0000, Florian Rathgeber wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> FFC generates C++ code, which makes sense given that the UFC interface
> is specified in C++. It is however a limitation when you want to use
> FFC to generate code for another interface/backend, as we do with
> PyOP2 (see our branch https://code.launchpad.net/~mapdes/ffc/pyop2).
>
> We require all kernels (and by kernels I mean basically every UFC
> function that is generated e.g. tabulate_tensor) to be C99 for a
> number of reasons - which are not relevant for this discussion but
> I'll mention some of them for those who are curious:
>
> 1) We target multiple hardware architectures (CUDA and OpenCL among
> others), which have limited support for C++. We want to keep the door
> open for more architectures in the future and the lowest common
> denominator will likely remain to be C.
>
> 2) We rely on pycparser to be able to parse kernels for
> instrumentations s.a. adding memory space attributes for OpenCL. To
> the best of our knowledge there's no reliable and easy to use C++
> parser available in Python.
>
> It turns out that FFC generated code is in fact C99, apart from:
>
> a) Usage of functions like sqrt, abs, pow from the std namespace.
>
> b) Usage of C++ exceptions (only when hitting invalid orientation
> markers).
>
> c) Usage of the static keyword (which has a different meaning in C99).
>
> So far we have overcome this issue by specializing those code snippets
> we were using and which had C99 incompatible code in them. It seems
> this is not a very elegant nor maintainable solution.
>
> At the moment FFC isn't quite set up for adding another code
> generation backend that generates C99 code without introducing lots of
> special cases. So my questions are:
>
> 1) Is there value in restructuring FFC to better accommodate adding
> code generation backends which do not target UFC? If so, where do we
> start? You're welcome to look at how we're doing it at the moment,
> which is an attempt to minimize changes to existing code and the FFC
> pipeline and clearly not very elegant.

Parts of FFC and UFC are currently being redesigned with the goals to

(1) move some of the basic generated code from codesnippets.py in FFC
(being glued into the generated code) to inline functions
ufc_geometry.h in UFC.

(2) merge in Martin's work on uflacs

(3) use flattened arrays for all data structures

So this is a very good point to jump in since changes are happening
anyway.

>From the start, it has been the intention for FFC to be as flexible as
possible in the design to allow for multiple backends, so any
additions or attempts to generalize are welcome.

> 2) Is there an easier way of generating C kernels given the
> constraints a-c we've identified above?

I don't see that it's very important to generate C++ kernels for us
since it is low-level generated code anyway so we should strive to
make as much of the code plain C to make it easier to reuse.

> These questions are related but I think could be treated separately. I
> can think of a few options for 2):
>
> i) Add using declarations to the UFC kernel templates in ufc_utils and
> drop the std:: prefix in the function bodies. This would (mostly)
> allow functions bodies to remain C99 compatible.

Could we move all of the math functions to a utility file called
ufc_math.h or similar to ufc_geometry.h? That could exist in two
different versions, one using std and another one using plain C99.

> ii) Add Python string templates to the code snippets allowing to
> choose between C++ and C99 specific statements where necessary and
> depending on the code generation target i.e. replace "std::sqrt" by
> "%(sqrt)s" and then replace that template depending
> I think ii) is more flexible but more "messy" but i) alone might be
> too limiting and a combination of both might be required.
>
> In our branch we have taken great care to make sure we pass all tests
> and don't break any UFC/DOLFIN functionality and we plan to add
> additional tests exercising the pyop2 code generation backend. We'd
> like to propose our branch for merging into the FFC trunk in the near
> future and are therefore very keen on any ideas how to overcome the
> issues I outlined and any comments and suggestions on the changes we
> propose.

Our current working branches are those named ffc-ufc-geometry and
ffc-uflacs-ufc-geometry-merged, with corresponding branches for UFC
and DOLFIN. I plan to get those merged into trunk this week. Take a
look at those. We are very open to further changes, including
proposals for UFC changes, to make it possible to merge in your
branch.

-- 
Anders


References