-
Notifications
You must be signed in to change notification settings - Fork 25
wence/better type inference #215
base: master
Are you sure you want to change the base?
Conversation
Will be used for type inference of return variable.
Will be used to allocate correct type of 0-form output variables. This is necessary in complex mode where if we explicitly ask for a real functional we need the type to match.
Only in the case of 0-forms, where we can control the allocated scalar type.
0eb0af9
to
03f59a9
Compare
Considering only 0-forms, it may (or may not) be simpler to do this in Firedrake assembly based on UFL type inference, but in general, I think, TSFC is the right place for this kind of inference, since TSFC has the most information naturally available: UFL knows very little about the basis functions, FIAT/FInAT knows only the basis functions and nothing about the form, TSFC has all in one place. Additionally, doing inference after optimization may naturally yield better results with no extra effort, whereas doing type inference earlier (e.g. on UFL) may give more conservative estimates in some cases, or needs more effort and special casing to retain precision. TSFC is also in the right position to infer other things that could potentially affect the kernel interface: not just whether the result is complex-valued or not, but also for example whether the resulting matrix is diagonal or not (e.g., underintegration). |
With respect to complex mode and type inference (e.g. real, complex, or logical), I think the right way to go forward is a kind of typed GEM. That is, all GEM nodes should be able to tell their types, whether they are real, complex, or Boolean valued. The basis could be the existing
In effect, complex mode would be the internally presumed default and real mode the special case. Furthermore, the current profusion of These complex mode branches could also be eliminated from |
That seems like a reasonable approach. One could plausibly do type assignation on construction at O(1) cost by always ensuring that nodes are typed (rather than the on-demand approach of hashing). |
If you look at I think a similar approach could work for GEM node types. |
|
||
|
||
def infer_dtype(assignments, scalar_type): | ||
from tsfc.loopy import assign_dtypes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is just a draft pull request, but this line would create a circularity in package dependency, by making gem
depend on tsfc
. This in undesirable: gem
should not depend on anything other than the Python standard library and quasi-standard packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's easy to fix by doing the more general gem typing approach.
Do we not need to merge this before complex? |
No, we worked around it. To do this more generally I think miklos' comment is the right way to handle this more cleanly. |
Assembly of 0-forms in complex mode needs to correctly infer the type of the return variable. This is necessary so that if we're adjointing, a real-valued functional is actually returned as a real.
This is kind of a complicated patch. One other way of doing this would be to augment UFL's form preprocessing to attach a flag about the realness of the form and we then cast to real in firedrake assembly.
I think the reification of terms in the gem DAG is still good, but maybe the impero_c changes are unnecessary and the UFL-approach is TRTTD.