[PSyData] Handling of procedure pointers

Open
#2,437 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Stale
Tech stack
fortran, python
Domain
compilers

Research direction

Start with the PSyData kernel-extraction path and the generated driver handling of the Fortran procedure pointer in chi_transform_mod. Compare the proposed pointer-dispatch, explicit initialisation, direct replacement, and init-routine options, then identify which approach is acceptable. At minimum, the generated driver should warn that the procedure pointer is uninitialised before it can crash; add focused coverage for this case if the relevant test location is found.

Written by the indexing model from the issue text.

Description

PSyData

LFRic's chi_transform_mod uses a procedure pointer, which we can't handle in the kernel extraction, e.g (code somewhat simplified):

subroutine chi2llr_interface(chi_1, chi_2, chi_3, panel_id, lon, lat, r)
...
  end subroutine chi2llr_interface
...
procedure(chi2llr_interface), pointer :: chi2llr => null()
...
case ( coord_system_xyz )
    chi2llr  => xyz2llr_panel
  case ( coord_system_lonlatz )
    chi2llr  => chih2chir
  case ( coord_system_alphabetaz )
    chi2llr  => alphabetaz2llr
 ...
call chi2llr(coords(1), coords(2), coords(3), panel_id, long, lat, r)

The driver compiles, but crashes, because chi2llr is not initialised.

For now this is considered unsupported (and I will see if I can print out a warning), but there might be some options to handle this:

  1. We check to which values a pointer is set (find all write access to the pointer in the module, ands give each of them an index number). At extraction time, we add code to compare this pointer to all possible routines that it can point to, and put the corresponding index into the kernel dump file. The driver will read this index, and set the pointer to the appropriate value. Somewhat complex to do.
  2. Easy: we request the transformation that creates the driver to add initialisation, since these pointers are set once (depending on coord system) and never changed. So we could 'somehow' supply an option to state that 'chi2llrshould be set toxyz2llr_panel` or so. Would work, but pretty annoying.
  3. Similar to above, but just replace chi2llr in the call with the actual routine name - though that would likely require manually specifying which function to use.
  4. In this example, the pointers are all defined in an init function, which can be called (since it takes no parameters, and even if it would take parameters, this routine could be added to the list of routines called, i.e. all its input parameters would be added at extraction time). I have confirmed that just calling this init function fixes the driver. Maybe this could be detected automatically (all write accesses to a procedure pointer come from one subroutine??), or it could be added to an option of the transformation: "if module XYZ is used in the call tree, add a call to ABC after setting all parameters"

At the very least, initially we need to add a warning to the driver that it will crash because of XYZ not being defined

Dominant language
Python
Stars
137
Forks
36
Avg merge
6d 16h
Merged PRs (30d)
18

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from stfc/PSyclone

All issues in stfc/PSyclone

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.