stfc / PSyclone

Domain-specific compiler and code transformation system for Finite Difference/Volume/Element Earth-system models in Fortran
BSD 3-Clause "New" or "Revised" License
102 stars 27 forks source link

CallTreeUtils - failure if routine is imported but not used #2657

Open hiker opened 1 month ago

hiker commented 1 month ago

While working on UKCA files:

MODULE ukca_api_mod
  USE ukca_setup_mod, ONLY: ukca_setup
  USE ukca_step_control_mod, ONLY: ukca_step_control

But ukca_step_control is not used in ukca_api_mod. When trying to run kernel extraction, call_tree_utils fails in _resolve_calls_and_unknowns. The following patch avoids the crash:

diff --git a/src/psyclone/psyir/tools/call_tree_utils.py b/src/psyclone/psyir/tools/call_tree_utils.py
index f941c80b2..4765f3058 100644
--- a/src/psyclone/psyir/tools/call_tree_utils.py
+++ b/src/psyclone/psyir/tools/call_tree_utils.py
@@ -400,6 +400,12 @@ class CallTreeUtils():
                 # Check that we find at least one valid routine (several
                 # could be found in case of a generic interface):
                 at_least_one_routine_found = False
+                try:
+                    all_possible_routines = cntr.resolve_routine(signature[0])
+                except TypeError:
+                    print(f"[CallTreeUtils] Cannot find routine "
+                          f"'{signature[0]}' in module '{cntr.name}' - ignored")
+                    continue
                 for routine_name in cntr.resolve_routine(signature[0]):

The error message is:

[CallTreeUtils] Cannot find routine 'ukca_step_control' in module 'ukca_api_mod' - ignored

Not sure why it seems to look in the wrong module for that subroutine :(

hiker commented 1 month ago

The full explanation: Kernel aerosol_ukca_kernel_mod uses:

    USE ukca_api_mod, ONLY: ukca_step_control, ukca_maxlen_message, ukca_maxlen_procname

And in ukca_api_mod there is:

MODULE ukca_api_mod
  USE ukca_step_control_mod, ONLY: ukca_step_control

So it compiles, because ukca_api_mod imports the module and makes it available, to be imported elsewhere. I don't know if this is done on purpose, but it appears ugly.

CallTreeUtils could test if a symbol cannot be found, if this symbol is imported (till the routine is found).

Or we can just fix the code :P But it appears that the api module is only created to import (and rename) a long list of symbols, so we might have to follow the import tree, including potential renaming, e.g. from the ukca_api_mod:

  USE ukca_ddepaer_coeff_mod, ONLY: ukca_zhg_eg_nedleaf => zhg_eg_nedleaf, ukca_zhg_eg_brdleaf => zhg_eg_brdleaf, &
&ukca_zhg_dec_nedleaf => zhg_dec_nedleaf, ukca_zhg_dec_brdleaf => zhg_dec_brdleaf, &