On 26 February 2013 15:26, Florian Rathgeber <florian.rathge...@gmail.com> wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On 26/02/13 09:33, Martin Sandve Aln₩s wrote: >> Just want to chip in here. FYI I'm currently adding a new >> representation to ffc based on lp:uflacs, where I reuse some of the >> quadrature representation code and new generate tabulate_tensor >> bodies with completely separate code. I'm using my own code >> formatting utilities, which probably has its pros and cons. I've >> also done some minor refactoring in ffc, so there will be a merge >> soonish (when Anders gets the dolfin-ufc-geometry branch up to >> speed). Hopefully this won't be difficult for you to merge with >> your branch, I don't think it's too extensive. > > Thanks for the heads up, it sounds like once your branch gets merged > things will be a bit easier for us. Is it the > ffc-uflacs-ufc-geometry-merged branch? > >> As for the language differences, I think it will be practical to >> generate code kernels that are both C99 and C++ compatible: >> >> a) Usage of functions like sqrt, abs, pow from the std namespace. >> >> - Instead of using std::foo in the code, we can add "using >> std::foo;" in code targeted for C++. Makes the generated code >> cleaner as well. > > Where do you think the right place for this would be? FFC or ufc_utils? > >> b) Usage of C++ exceptions (only when hitting invalid orientation >> markers). >> >> - This can be removed and checked on the dolfin side like >> everything else, as I see it it's mainly there for a safe gradual >> introduction of the orientation markers. > > We're not hitting this kernel in our code at the moment, so we could > just ignore it for now. > >> c) Usage of the static keyword (which has a different meaning in >> C99). >> >> - Are you sure? >> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1012 I >> think we can wrap global static declarations in an unnamed >> namespace if the code is target for C++, and otherwise use the same >> declarations. > > I think I was wrong about that, static seems to be a perfectly legal > keyword also in C99 the way it's used in FFC generated code. It's a > bug in pycparser failing to parse that statement, I'll look into > fixing it. > >> These should all be simple changes. Adding fortran support however >> will not be as simple, because the code formatting framework is >> quite low level and close to the structure of C/C++ code, so that's >> a completely different project. Probably easier to generate C and >> call from fortran then :) > > We don't have any plans to support Fortran at the moment, but I can > see how it would be an issue as the FFC code generation is modeled > quite closely around C/C++. > >> Martin >> >> >> On 26 February 2013 08:00, Kristian lgaard >> <k.b.oelga...@gmail.com <mailto:k.b.oelga...@gmail.com>> wrote: >> >> On 25 February 2013 17:07, Florian Rathgeber >> <florian.rathge...@gmail.com <mailto:florian.rathge...@gmail.com>> >> wrote: 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: >> >>> The idea is that code formatting for C++ is handled by the >>> module cpp.py which implements the format dictionary. To generate >>> code for a different target language, you should implement a new >>> format dictionary in c.py (or fortran.py). > > I understanding where this design is coming from. However, the point I > was trying to make is that C++ and C99 are sufficiently close to be > handled by the same code generator.
But wouldn't it just be a matter of importing the format from cpp.py to your c.py and then call update on the relevant entries? (I'm only talking pure FFC here, not ufc_utils) Then it will work with the solution you devise below for the imports. > >>> Then in modules like codegeneration.py where we currently do: >> >>> from ffc.cpp import format, indent >> >>> the import shold be depending on the target language. At least, >>> that's how the design was intended. However, as C++ has been the >>> only target language available in FFC since the beginning, the >>> concept has never been tested and there are probably many cases, >>> like the above, which are C++ spefic. > > Conditional imports in module scope are a massive pita when depending > on runtime values as would be the case here. You'd probably want to > either add another level to the existing dictionaries and index by > language and item, or wrap the format dictionary in a class which you > instantiate with a backend and then do the conditional import to > populate it. Sure, I just meant to point to where the issues might be. Either of you proposed methods sound good to me. Kristian >>> The above approach would be the _correct_ way as I see it, but >>> might require a bit of work initially. However, I think it will >>> worthwhile in the end, particularly if you want to merge your >>> code back into FFC. > > I hope I can convince you we shouldn't be crossing that bridge just yet. > > Florian > >>> Kristian >> >> 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. >> >> 2) Is there an easier way of generating C kernels given the >> constraints a-c we've identified above? >> >> 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. >> >> 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. >> >> Florian >>> >>> >>> _______________________________________________ Mailing list: >>> https://launchpad.net/~ffc Post to : ffc@lists.launchpad.net >>> <mailto:ffc@lists.launchpad.net> Unsubscribe : >>> https://launchpad.net/~ffc More help : >>> https://help.launchpad.net/ListHelp >>> >> >> _______________________________________________ Mailing list: >> https://launchpad.net/~ffc Post to : ffc@lists.launchpad.net >> <mailto:ffc@lists.launchpad.net> Unsubscribe : >> https://launchpad.net/~ffc More help : >> https://help.launchpad.net/ListHelp >> >> >> >> >> _______________________________________________ Mailing list: >> https://launchpad.net/~ffc Post to : ffc@lists.launchpad.net >> Unsubscribe : https://launchpad.net/~ffc More help : >> https://help.launchpad.net/ListHelp >> > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v1.4.11 (GNU/Linux) > Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ > > iEYEARECAAYFAlEsxhsACgkQ8Z6llsctAxZTTACfelbvWxRY8SF3QQp9EPEuEQoG > Dq4AoMGb9Gju7JTrl7eYL+FQ6AH3TybB > =MolL > -----END PGP SIGNATURE----- > _______________________________________________ Mailing list: https://launchpad.net/~ffc Post to : ffc@lists.launchpad.net Unsubscribe : https://launchpad.net/~ffc More help : https://help.launchpad.net/ListHelp