(Closes #3334 #1013) Permit only module-inlined Kernels to be transformed#3294
(Closes #3334 #1013) Permit only module-inlined Kernels to be transformed#3294
Conversation
|
Possibly I need to store the RoutineSymbol associated with a Kernel within the Kernel class (c.f. Call.reference). That way, I can tell whether it has been module-inlined or not and can get rid of the special flag for that. |
|
Note to self: I will need to remove the EDIT: can't do this because we do still output OpenCL versions of kernels in some tests. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3294 +/- ##
==========================================
- Coverage 99.95% 99.95% -0.01%
==========================================
Files 384 385 +1
Lines 54225 54087 -138
==========================================
- Hits 54203 54065 -138
Misses 22 22 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Coverage is now all good but the LFRic extraction integration test failed :-( |
|
In lfric/eg17/full_example_extract: $ diff main_psy.f90 on_main/main_psy.f90
4d3
< use testkern_w0_kernel_mod, only : testkern_w0_code
74a74
> use testkern_w0_kernel_mod, only : some_other_var, testkern_w0_codeso it appears the |
|
This turned out to be due to the fact that I've moved the import of Kernel routines up into the Container and then the ExtractNode was falling foul of #1734 |
|
Doc failure was a timeout on the NVIDIA web site. It works OK for me though. |
| # Flag that the kernel has been modified | ||
| node.modified = True |
There was a problem hiding this comment.
There is one more use in:
tutorial/practicals/LFRic/single_node/3_sequential/matvec_opt.py
67: kernel.modified = True
Which made me realise this example will also need the ModuleInlining (and the kernel_schedule.walk(IntrinsicCall) is also broken because kernel.get_callees() returns a list now)
(also the Makefile commands have the --psykal-dsl lfric missing)
There was a problem hiding this comment.
Grepping Matmul2CodeTrans, also examples/lfric/eg15/matvec_opt.py may be missing ModuleInling
There was a problem hiding this comment.
Oh, eg15 shows up a bit of a problem: there's nothing stopping a user getting the kernel schedule and then applying transformations to it themselves. However, those transformations will now have no effect as the modified PSyIR will never be written to file :-(
There was a problem hiding this comment.
Anyway, I've now fixed-up the example and the tutorial.
| use quadrature_xyoz_mod, only : quadrature_xyoz_proxy_type, \ | ||
| quadrature_xyoz_type | ||
| use testkern_qr_mod, only : testkern_qr_code""" in output) | ||
| quadrature_xyoz_type""" in output) |
There was a problem hiding this comment.
pylint says "superfluous-parens"
|
|
||
| """ | ||
| if not isinstance(node, CodedKern): | ||
| return |
There was a problem hiding this comment.
When I first saw that I though this is to let Builtins pass, but then I found somewhere that this is provided with a call_node as returns None. But then I realised there is nothing here specific to kernels. If this a transfomration is provided a call and its callee is being modified, the same check must be done. Maybe it's worth it doing this generic: class CalleeTransformationMixin and _check_callee_implementation_is_local ?
Then I would do this more strict and not return None for everything else, if somewhere a builtin is valid I would do:
if not isinstance(node, Builtin):
node.check_callee_implementation_is_local(node)
What do you think?
(I have not look everywhere this is used, it could be good to check is applicable everywhere before doing the change)
There was a problem hiding this comment.
Oh I also see that the KernelModuleInlineTrans that the error message suggest is only applicable to kernels. So maybe this can be left with a TODO together with the plans to make KernelModuleInlineTrans generic which we have discussed in the past (maybe we could repurpose #2683 to include this?)
(I would still rename the method to check_callee_implementation_is_local and make it stricter now)
There was a problem hiding this comment.
Good points. I have generalised it, renamed it and moved it into psyir.transformations. In some places a Routine is valid so I've added checks for those.
| global_variables = set(sym.name for sym in | ||
| ksched.symbol_table.imported_symbols) | ||
| prec_sym_names = set(sym.name for sym in | ||
| ksched.symbol_table.precision_datasymbols) | ||
| non_prec_vars = global_variables.difference(prec_sym_names) | ||
| if non_prec_vars: | ||
| names = sorted(non_prec_vars) |
There was a problem hiding this comment.
Why was this change needed?
There was a problem hiding this comment.
SymbolTable.precision_datasymbols collects the Symbols referred to by the precision property (if any) of all Symbols in the table. This problem must have arisen because we have added new symbols that refer to a precision symbol from another table. I will investigate as it would be better if those references were updated.
There was a problem hiding this comment.
Probably we're missing a call to update_symbols_using or similar.
There was a problem hiding this comment.
I have 'fixed' this within KernelModuleInlineTrans but I'm still not happy - I suspect the problem is originating earlier so I will do some further investigation.
| @pytest.mark.usefixtures("kernel_outputdir") | ||
| def test_kernelimportstoargumentstrans(monkeypatch): | ||
| def test_kernelimportstoargumentstrans(monkeypatch, fortran_writer): | ||
| ''' Check the KernelImportsToArguments transformation with a single kernel |
There was a problem hiding this comment.
The monkeypatch argument is unused now
| assert isinstance(kschedule.symbol_table.lookup("xstart").interface, | ||
| ArgumentInterface) | ||
| assert isinstance(kschedule.symbol_table.lookup("xstop").interface, | ||
| assert isinstance(kschedule.symbol_table.lookup("xstop_1").interface, |
There was a problem hiding this comment.
Why has this changed? I am a bit worried about this one because if the call had argument names, this would not match anymore.
| @pytest.fixture(name="mod_inline_trans") | ||
| def make_mod_inline_trans() -> KernelModuleInlineTrans: | ||
| '''Creates and returns a KernelModuleInlineTrans transformation.''' | ||
| return KernelModuleInlineTrans() |
| [-l {off,all,output}] [-p {invokes,routines,kernels}] | ||
| [-o OUTPUT_FILE] [-api DSL] [-oalg OUTPUT_ALGORITHM_FILE] [-opsy OUTPUT_PSY_FILE] | ||
| [-okern OUTPUT_KERNEL_PATH] [-dm] [-nodm] | ||
| [--kernel-renaming {multiple,single}] |
There was a problem hiding this comment.
Also clean these please:
doc/user_guide/transformations.rst
582:two different kernel-renaming schemes: "multiple" and "single"
583:(specified via the ``--kernel-renaming`` command-line flag). In the
doc/user_guide/getting_going.rst
179: [--kernel-renaming {multiple,single}]
223: --kernel-renaming {multiple,single}
| ''' | ||
| :returns: whether or not this kernel is being module-inlined. | ||
| :rtype: bool | ||
| def module_inline(self) -> bool: |
There was a problem hiding this comment.
Maybe another TODO for 2054 saying that it subclasses Call, this probably should live in the super class
| kernel.symbol_table.swap(imported_var, updated_sym) | ||
|
|
||
| if updated_sym in kernel.symbol_table.precision_datasymbols: | ||
| if updated_sym.name.lower() in precision_sym_names: |
|
Unfortunately, my change to |
Require that all kernel transformations act only on module-inlined Kernels.
Do away with the 'rename-and-write' functionality currently used for modified kernels.
We have to keep the
-okerncommand-line flag as that is used when creating OpenCL versions of Kernels.