Skip to content

(Closes #3503) add LFRic meta-transformation for colouring and OpenMP - #3593

Open
haanahfrost wants to merge 6 commits into
masterfrom
3503_colour_omp_metatrans
Open

haanahfrost wants to merge 6 commits into
masterfrom
3503_colour_omp_metatrans

Conversation

@haanahfrost

@haanahfrost haanahfrost commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Adds LFRicColourAndOMPTrans, a meta-transformation that colours the loops
in an LFRic Routine and then applies OpenMP parallelism to them. This
replaces colour_loops and openmp_parallelise_loops from the Met Office's
psyclone_tools.py, so that the functionality lives in PSyclone and is
properly tested.

WIP:

  • Colouring half
  • OpenMP half
  • Full test coverage

@haanahfrost haanahfrost self-assigned this Sep 10, 2026
@haanahfrost haanahfrost added enhancement LFRic Issue relates to the LFRic domain in progress labels Sep 10, 2026
@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (34206b0) to head (3867ebe).

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #3593   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          401       402    +1     
  Lines        56540     56581   +41     
=========================================
+ Hits         56540     56581   +41     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@haanahfrost
haanahfrost marked this pull request as ready for review September 10, 2026 13:52

@LonelyCat124 LonelyCat124 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haanahfrost Couple of change, most are just documentation or type hint related.
I've asked for one additional thing in the tests because I'm not entirely sure I know what will happen and I'd like it to be explicit in the tests as well.


def validate(self, node: Routine,
reprod: Union[bool, None] = None, **kwargs):
# pylint: disable=arguments-renamed

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a TODO around this pylint as if options are removed it should no longer be necessary.


:param node: the Routine node to transform
:param reprod: whether to use reproducible form of OpenMP reduction.
If none, the default value from the configuration is used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line of docstring should be indented.

continuous function space.

:param node: the Routine whose loops are to be coloured.
:param colour_kwargs: keyword arguments for the LFRicColourTrans

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're documenting this it needs to be type hinted - I think it should be dict[str, Any] but double check. Also for _parallelise_loops

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checked this with mypy. For **kwargs the annotation applies to each value rather than the dict itself so **colour_kwargs: Any reveals as dict[str, Any]
Annotating it dict[str, Any] gives dict[str, dict[str, Any]] and mypy rejects passing tiling=True.
Gone with Any for both _colour_loops and _parallelise_loops which also matches lfric_invoke_schedule.py


:param node: the Routine whose loops are to be parallelised.
:param reprod: whether to use reproducible form of OpenMP reduction.
If none, the default value from the configuration is used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent this line please.

oregtrans = OMPParallelTrans()

# TODO #2668: LFRicOMPLoopTrans has not yet been migrated to kwargs. It
# it gives options inherrited from OMPLoopTrans but discards any

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/inherrited/inherited

'''
:param node: the Routine node to transform
:param reprod: whether to use reproducible form of OpenMP reduction.
If none, the default value from the configuration is used.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent this line.

dist_mem=False)
sched = invoke.schedule
# w3 is discontinuous so no colouring happens. Parallelise the loop by
# hand first so that the transformation finds it already in a directive.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we have a continuous space and we already parallelise the loop? Can you test that behaviour as well?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested this and it silently does nothing. Once OMPParallelTrans has been applied the loop is no longer a direct child of the Routine (children go from ['LFRicLoop'] to ['OMPParallelDirective']), so _colour_loops never sees it, and _parallelise_loops skips it because it has a Directive ancestor. This results in an uncoloured loop on a continuous space inside a parallel region, which is the race condition colouring is there to prevent.

Do you want validate to reject this? (raise if any loop with a Directive ancestor is on a continuous space)
Or should the test just document current behaviour?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement in progress LFRic Issue relates to the LFRic domain

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants