Skip to content

Conversation

@arporter
Copy link
Member

@arporter arporter commented Dec 18, 2025

This is a step towards both #2381 (generalising global reductions) and #2674 (new field_min_max builtin). It attempts to reduce the size of #3222 by only adding the two new access types for reductions as well as the skeletons for the new builtins.

arporter and others added 30 commits October 3, 2025 21:56
@codecov
Copy link

codecov bot commented Dec 18, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.91%. Comparing base (470e0f7) to head (7a0d563).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3263   +/-   ##
=======================================
  Coverage   99.91%   99.91%           
=======================================
  Files         376      376           
  Lines       53522    53555   +33     
=======================================
+ Hits        53477    53510   +33     
  Misses         45       45           

☔ View full report in Codecov by Sentry.
📢 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.

@arporter arporter self-assigned this Dec 18, 2025
@arporter arporter added LFRic Issue relates to the LFRic domain LFRic PSyKAl-lite Issue related to removal of PSyKAl-lite code in LFRic labels Dec 18, 2025
@arporter arporter changed the title (Towards #2381 #2674) add min max LFRic builtins (Towards #2381 #2674) add min max access types and new LFRic builtins Dec 18, 2025
@arporter
Copy link
Member Author

Ready for a first look from anyone still working @sergisiso or @hiker ?
It shouldn't affect the IT but I'll fire them off to be on the safe side.

Copy link
Collaborator

@sergisiso sergisiso left a comment

Choose a reason for hiding this comment

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

@arporter Most of the PR looks good but I am getting confused by the need of these specific access types, these seem regular writes to me. It would be good to clarify if these are really needed before continuing.

access_mapping = gh_read: read, gh_write: write, gh_readwrite: readwrite,
gh_inc: inc, gh_readinc: readinc, gh_sum: sum
gh_inc: inc, gh_readinc: readinc, gh_sum: sum,
gh_min: min, gh_max: max
Copy link
Collaborator

Choose a reason for hiding this comment

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

tab to spaces :)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah! Done.

Comment on lines +2800 to +2801
| GH_SCALAR | GH_REAL | n/a | GH_READ, GH_SUM, |
| | | | GH_MIN, GH_MAX |
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand why do we need GH_SUM, GH_MIN or GH_MAX. These is the output scalar of the built-in which will only be written to, Why not GH_WRITE?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a good point. Currently, we rely on knowing the type of reduction being performed by a built-in when creating the Invoke (in lfric_invoke.py):
image
At this point, we don't have the PSyIR for the built-in - just its name and metadata. Therefore, if the scalar argument was just GH_WRITE we would know that it was a reduction but could not determine the type. I feel we may have conflated DSL metadata "access" information with PSyIR access concepts.

Comment on lines +79 to +82
#: Is the output of a MIN reduction (i.e. global minimum value).
MIN = 11
#: Is the output of a MAX reduction (i.e. global maximum value).
MAX = 12
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again MIN/MAX is not an AccessType (same with the pre-existing SUM). It is even more confusing that this refer to the output scalar, which is just written to. So why do we differentiate them?

Copy link
Member Author

Choose a reason for hiding this comment

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

As commented elsewhere, I agree. I'll look to see if I can restrict the MIN/MAX/SUM concept to the kernel metadata.

@arporter
Copy link
Member Author

arporter commented Jan 6, 2026

I thought the best way to solve this would be to have class LFRicAccessType(AccessType) which would add the API-specific access types. Unfortunately, one cannot extend an Enum (https://stackoverflow.com/questions/33679930/how-to-extend-python-enum) so this simply doesn't work.

@sergisiso
Copy link
Collaborator

sergisiso commented Jan 6, 2026

At this point, we don't have the PSyIR for the built-in - just its name and metadata. Therefore, if the scalar argument was just GH_WRITE we would know that it was a reduction but could not determine the type

Could we not just determine the type using its name?

I thought the best way to solve this would be to have class LFRicAccessType(AccessType) which would add the API-specific access types.

I am not sure if this would be just moving the problem, I don't feel it is information that belong to the AccessType. Looking at the code snippet that you shared is the reason for not being GH_WRITE the validation? So we don't allow scalar GH_WRITE because they would be a race condition, but we allow scalar reduction writes because the synchronisation is built-in in the operation? In this case, could we add a GH_SAFE_WRITE/GH_ATOMIC_WRITE, this could be the metadata of the reduction built-ins but also for kernels where the race condition is handled inside the kernel (although we may not want to advertise this feature).

This would be useful in the generic AccessType because in the future we may want to identify these safe_writes in generic code as they have less dependencies that what we give them now.

@arporter
Copy link
Member Author

arporter commented Jan 6, 2026

My feeling is that we currently have quite a lot of domain-specific information in AccessType which should not be there (e.g. INC). All of the generic PSyIR should, as you say, use READ/WRITE/READWRITE. The concept of a reduction or INC access belongs with a domain. I was therefore planning on separating the two out and ensuring that the domain-specific access types are only referred to in appropriate places in the code.

I'm not that keen on the idea of having a mapping of particular built-ins to the type of reduction they perform - it feels more natural to keep that information as part of the metadata associated with the kernel.

The potential future re-use of ATOMIC_WRITE is attractive but I'd be concerned about letting that out into the wild, even unadvertised (we could have it as an internal access type but not as kernel metadata perhaps?).

@arporter
Copy link
Member Author

arporter commented Jan 7, 2026

LFRicConstants already has e.g. VALID_ACCESS_TYPES:
image

@arporter
Copy link
Member Author

arporter commented Jan 7, 2026

Having now realised that we also have AccessType.INC and AccessType.READINC, it's going to be no small matter to attempt to unpick this (see e.g. #3272). I therefore propose that we keep things as they are for the moment and have a more in-depth discussion about whether we want to tackle this.

@arporter
Copy link
Member Author

arporter commented Jan 7, 2026

@sergisiso ready for another look and/or continued discussion.

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

Labels

LFRic PSyKAl-lite Issue related to removal of PSyKAl-lite code in LFRic LFRic Issue relates to the LFRic domain ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants