Skip to content

Conversation

@sergisiso
Copy link
Collaborator

Change Ref2ArrayRange behaviour by letting it pass if the provided node is already in the expanded form, but making it fail if for a expression we cannot guarantee if it could be expanded or not. This will bring validations that now need to be done every time its used to inside the transformation.

@codecov
Copy link

codecov bot commented Dec 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.91%. Comparing base (97dd02d) to head (3197baf).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3260      +/-   ##
==========================================
- Coverage   99.91%   99.91%   -0.01%     
==========================================
  Files         376      376              
  Lines       53529    53522       -7     
==========================================
- Hits        53484    53475       -9     
- Misses         45       47       +2     

☔ 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.

@sergisiso sergisiso self-assigned this Dec 17, 2025
@sergisiso sergisiso changed the title (closes #2884) Change Ref2ArrayRange behaviour (closes #2884) Allow WHERE with imported symbols by changing Ref2ArrayRange behaviour to do the validations Dec 17, 2025
@sergisiso
Copy link
Collaborator Author

sergisiso commented Dec 17, 2025

@arporter @LonelyCat124 This is ready for review. It changes the Reference2ArrayReference to fail if the outcome cannot be guaranteed, so thing like WHERE can rely on its validation.

This will be followed by #1858 (structures) and #2722 (dependencies), which can be done in a single location after this PR, but it was to big to do here.

Copy link
Member

@arporter arporter left a comment

Choose a reason for hiding this comment

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

Really nice Sergi, it's good to see the simplification that this has achieved.
I'm worried that we are no longer raising an exception when we see a StructureReference - given that we can't handle them this needs to be flagged?
Apart from that, it's just minor tidying. I'll run the integration tests next time (or you could fire them off perhaps once you're done).

an Array) to a PSyIR Range. For example:
'''
Transformation to convert plain References of array symbols to
ArrayReferances with full-extend ranges if it is semantically equivalent
Copy link
Member

Choose a reason for hiding this comment

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

s/extend/extent/

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed

to do so (e.g. it won't convert call arguments because it would change the
bounds values).
Note that if a node that does not need to be modified is provided (e.g.
Copy link
Member

Choose a reason for hiding this comment

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

"...if the provided node does not need..."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

# TODO issue #1858. Add support for structures containing arrays.
if node and node.parent and isinstance(node.parent, Call):
if node.position == 0:
return
Copy link
Member

Choose a reason for hiding this comment

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

Comment please - I didn't readily understand at first but presumably this is checking that the node isn't the Reference associated with the routine target of a Call?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Exactly. Added comment

if node.parent.is_elemental is None:
raise TransformationError(LazyString(
lambda: f"The supplied node is passed as an argument to a "
f"Call that we don't know if it is elemental or not: "
Copy link
Member

Choose a reason for hiding this comment

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

"...that may or may not be elemental: ...."

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

return

if (
type(node) is ArrayReference or
Copy link
Member

Choose a reason for hiding this comment

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

This probably needs a pylint disable for unidiomatic type check?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, done

:type symbols: List[str]
:param scalars: list of symbol names that must be added to the symbol
table with an scalar datatype.
:type symbols: List[str]
Copy link
Member

Choose a reason for hiding this comment

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

Please replace with typehints.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

with pytest.raises(TransformationError) as info:
trans.validate(Reference(Symbol("x")))
assert ("The supplied node should be a Reference to a symbol of known "
"type, but 'x' is not." in str(info.value))
Copy link
Member

Choose a reason for hiding this comment

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

It might be useful to include str(sym) in the error message so that we can see what PSyclone thinks 'x' is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good idea, done

assert ("The supplied node should be a Reference but found "
"'ArrayReference'." in str(info.value))

trans.validate(None)
Copy link
Member

Choose a reason for hiding this comment

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

Couldn't you have this as the first step in the previous test (i.e. before "If it is not even a Reference")?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh yes, it is already there, removing this one

trans.validate(reference)
assert ("node is passed as an argument to a Call to a non-elemental "
"routine (DEALLOCATE(a)" in str(info.value))
trans.validate(assign.lhs)
Copy link
Member

Choose a reason for hiding this comment

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

The docstring says we test that a StructureReference raises an exception but clearly it doesn't any longer. Given that we don't support them yet, I would argue we should raise an exception as we don't know what to do with them.

Copy link
Collaborator Author

@sergisiso sergisiso Dec 19, 2025

Choose a reason for hiding this comment

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

It felt bad to have the comment that are not supported and then just return the validation.

The reason I did it is because both the WHERE and the ArrayAssignment2Loop already implement and have several tests for structure references (which they happily take at face-value, without checking if they need to be added ranges).
Adding this restriction here, without implementing proper support for letting valid cases pass, and array types extended, makes all of those fail.

Also this is not worse than master, in master it had an exception but it was "except:pass" everywhere it was used.

I suggest I tackle this in a follow up (I attempted starting it but it quickly grows very large), or we can block this for now. Let me know what you prefer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I implemented it in #3266

trans.validate(assign.lhs)


def test_validate_pointer_assignment(fortran_reader):
Copy link
Member

Choose a reason for hiding this comment

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

We probably don't need this test anymore?

Copy link
Collaborator Author

@sergisiso sergisiso Dec 19, 2025

Choose a reason for hiding this comment

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

I added the check back (it was important for NEMOv4 performance because tmask is a pointer) and the check is more precise. So I kept (and extended the test).

@sergisiso sergisiso force-pushed the 2884_change_ref2arrayrange_behaviour branch from 99ab3e0 to 3e1c6b8 Compare December 19, 2025 13:33
@sergisiso
Copy link
Collaborator Author

@arporter This is ready for another look, I just fired the integration test.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants