Skip to content

(Towards #2577) Add pointer and target attributes in datatypes, frontend and backend#2822

Open
JulienRemy wants to merge 12 commits intomasterfrom
2577_pointer_target_attrs
Open

(Towards #2577) Add pointer and target attributes in datatypes, frontend and backend#2822
JulienRemy wants to merge 12 commits intomasterfrom
2577_pointer_target_attrs

Conversation

@JulienRemy
Copy link
Collaborator

This starts implementing point 2 of Sergi's list in #2577 by adding new attributes to datatypes, as well as frontend and backend support for them.

Note that is_potentially_aliased is not used anywhere, except to fix an existing Matmul2CodeTrans test.
So this does not check for aliasing anywhere else for now. Stated differently, this might be dangerous to merge as it effectively supports pointers in PSyIR but does not yet restrict transformations to non-aliased variables.

@codecov
Copy link

codecov bot commented Dec 9, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.88%. Comparing base (1e6b095) to head (32d451b).
Report is 184 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2822      +/-   ##
==========================================
- Coverage   99.88%   99.88%   -0.01%     
==========================================
  Files         357      357              
  Lines       49742    49960     +218     
==========================================
+ Hits        49686    49903     +217     
- Misses         56       57       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it 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.

Very nicely done, thanks Julien. Implementation is good, tests good (just need a bit more coverage). As you say in a previous comment, I am concerned about putting this onto master as is as it opens the door to potential problems. Therefore, I think we do have to tackle making sure that transformations that care about this do the right thing (at this stage, that can simply be refuse to do anything). I suggest going through the list in the Reference Guide:
image
and checking whether or not they should care about aliasing.

has_pointer_attr = True
elif normalized_string == "target":
has_target_attr = True
elif isinstance(attr, (Fortran2003.Attr_Spec,
Copy link
Member

Choose a reason for hiding this comment

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

Since you do normalized_string = str(attr).lower().replace(' ', '') in both cases, can you now remove the elif isinstance(attr, (Fortran2003.xxxxx)) and hoist the if normalized_string == "save": up a level?

f"SAVE and PARAMETER attributes are not compatible but "
f"found:\n {decl}")

# TODO check these are needed
Copy link
Member

Choose a reason for hiding this comment

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

I think they are. I bet fparser doesn't check. Please update the comment.

f"found:\n {decl}")
if has_pointer_attr and has_constant_value:
raise GenerationError(
f"POINTER and PARAMETER attributes are not compatible but "
Copy link
Member

Choose a reason for hiding this comment

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

Probably also true for TARGET and PARAMETER?


# 2: Remove any unsupported attributes
unsupported_attribute_names = ["pointer", "target", "optional"]
unsupported_attribute_names = ["asynchronous", "volatile", "optional"]
Copy link
Member

Choose a reason for hiding this comment

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

Possibly "contiguous" too although @hiker wants to add support for that soon I think.

:param is_target: whether this is a target symbol.
:type is_target: bool

'''
Copy link
Member

Choose a reason for hiding this comment

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

Please document the new :raises: that you've added.

# Test that when it is part of an UnsupportedType (target attribute in
# this case) it becomes an UnknownInterface.
reader = FortranStringReader("integer, target :: var5")
# Test that when it is part of an UnsupportedType (asynchronous attribute
Copy link
Member

Choose a reason for hiding this comment

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

s/asynchronous/volatile/

"INTEGER, PRIVATE, DIMENSION(3), POINTER :: g")
"INTEGER, PRIVATE, DIMENSION(3), ASYNCHRONOUS :: g")

# Test with unsupported intrinsic type. Note the space before complex
Copy link
Member

Choose a reason for hiding this comment

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

Please add/extend tests that the partial datatype of an UnsupportedFortranType correctly captures the new is_pointer/is_target properties of a declaration.

with pytest.raises(ValueError) as err:
_ = DataTypeSymbol("my_type", UnresolvedType(), is_pointer=True,
is_target=True)
assert ("A symbol cannot be both a pointer and a target" in str(err.value))
Copy link
Member

Choose a reason for hiding this comment

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

Useful to include the name of the proposed symbol in this error message.

assert ("__str__" in msg)


def test_datatype_is_pointer_is_target():
Copy link
Member

Choose a reason for hiding this comment

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

As commented on in the source, an unresolved type is just that - if we have any information on it then that goes in its partial_datatype (although I think only an UnsupportedFortranType has that).

f"Expected result and operands of MATMUL IntrinsicCall to "
f"be references to arrays that are not potentially aliased "
f"but found '{result.symbol}', '{matrix1.symbol}' and "
f"'{matrix2.symbol}'.")
Copy link
Member

Choose a reason for hiding this comment

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

probably worth adding "...symbol}' in '{node.debug_string()}'." to give more information.

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.

I see @arporter already reviewed it, so I will let him continue being the reviewer for this, but I had some comments already stored in github so I will push them anyway (even though some are the same as @arporter ). The reason I never finished this review is that it was unclear to me if the "is a pointer" attribute had to be part of the symbol itself or the datatype of the symbol. And I think it would be good to discuss this before we commit to a solution.

Comment on lines +1692 to +1699
# NOTE: for a routine declaration, 'POINTER' or 'TARGET' is
# an Attr_Spec, but in a derived type declaration component
# it is not.
normalized_string = str(attr).lower().replace(' ', '')
if normalized_string == "pointer":
has_pointer_attr = True
elif normalized_string == "target":
has_target_attr = True
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this not be part of the normalized_string checks inside the:
if isinstance(attr, (Fortran2003.Attr_Spec, Fortran2003.Component_Attr_Spec)

Looking at the standard for derived type it should be in "Component_Attr_Spec" so I don't know why this is different than "save", "parameter", ...

f"SAVE and PARAMETER attributes are not compatible but "
f"found:\n {decl}")

# TODO check these are needed
Copy link
Collaborator

Choose a reason for hiding this comment

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

I tried with 'gfortran' and they are both errors, but fparser does not report them, so it is good to have them here. You can remove the TODO.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Target and parameter together also fails, can you add it here?

Comment on lines +288 to +290
:raises TransformationError: if any of the arrays are potentially \
aliased.
:raises TransformationError: if sub-sections of an array are present \
Copy link
Collaborator

Choose a reason for hiding this comment

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

You don't need the backslashes

Comment on lines +360 to +372

@property
def is_unresolved(self):
'''
:returns: whether the Symbol has an UnresolvedInterface or its
datatype is an UnresolvedType.
:rtype: bool
'''
# Import here to avoid circular dependencies
# pylint: disable=import-outside-toplevel
from psyclone.psyir.symbols.datatypes import UnresolvedType
return (super().is_unresolved
or isinstance(self.datatype, UnresolvedType))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would prefer to remove this, as it changes the definition of the super class which is that this only checks for UnresolvedInterface.

I suppose you needed this in some place that then checks for properties of the datatype (e.g. symbol.datatype. ...), I think you will need to do this check there. Would that work?

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