(Towards #3325) Improving .datatype to return size intrinsics instead of DEFERRED#3336
(Towards #3325) Improving .datatype to return size intrinsics instead of DEFERRED#3336LonelyCat124 wants to merge 9 commits intomasterfrom
Conversation
…taining status quo for more unknown types
|
Waiting on coverage to come back, but if its ok this is ready for a first look. I'm not totally convinced by the choice I make in BinaryOperation, so if the reviewer has a better strategy I'm happy to change it.
|
|
I am happy to review this, as I have been thinking what I need to redo WHEREs and it will be something similar. (I will wait for test/coverage to be reported before starting) |
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project check has failed because you have indirect coverage changes. Learn more about Unexpected Coverage Changes and reasons for indirect coverage changes. Additional details and impacted files@@ Coverage Diff @@
## master #3336 +/- ##
==========================================
- Coverage 99.95% 99.95% -0.01%
==========================================
Files 384 384
Lines 54225 54232 +7
==========================================
+ Hits 54203 54208 +5
- Misses 22 24 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
sergisiso
left a comment
There was a problem hiding this comment.
Looks good @LonelyCat124 (although I am not convinced about the new special case - see inline)
I see this is a towards, is the goal of that issue to make "the datatype method should not propagate the DEFERRED attribute when constructing the datatype of an expression". Where are we on this?
src/psyclone/tests/psyir/frontend/fparser2_where_handler_test.py
Outdated
Show resolved
Hide resolved
|
Oh and I forgot about the Coverage indirect changes. It seems they are related to WHEREs, so I would address that comment first and see if they are still there. |
|
@sergisiso Ready for another look now I've updated the array_mixin stuff. |
sergisiso
left a comment
There was a problem hiding this comment.
Thanks for improving the array_mixin._extent behaviour @LonelyCat124 . I still have some questions about the behaviour of the datatype method that probably means we are missing some tests.
| if (isinstance(start, Literal) and start.value_as_python == 1 and | ||
| isinstance(step, Literal) and step.value_as_python == 1): |
There was a problem hiding this comment.
Just for me to understand, what is the difference here? Is that now the precision doesn't matter in the comparison?
Also, I find the "value_as_python" slightly odd, for me it should be the other way around: "as_python_value" or even excluding the python and just being "as_value"
| :param argtypes: the types of the two operands. | ||
| :type argtypes: list[:py:class:`psyclone.psyir.symbols.DataType`, | ||
| :param optypes: the types of the two operands. | ||
| :type optypes: list[:py:class:`psyclone.psyir.symbols.DataType`, |
There was a problem hiding this comment.
typehint, maybe Iterable[DataType]?
| b(widx1) = a(widx1) | ||
| end if | ||
| enddo''' | ||
| print(out) |
| IntrinsicCall.Intrinsic.SIZE, | ||
| [Reference(sym2)]) | ||
| )]) | ||
| print("------------") |
| [Reference(sym2)]) | ||
| )]) | ||
| print("------------") | ||
| binop7 = BinaryOperation.create(oper, ref7.copy(), ref6.copy()) |
There was a problem hiding this comment.
Can you also do another BinOp with the operands switched? I think you are trying to check that the "datatype" prefers the type without the SIZE intrinsic (add a comment saying that this is the purpose), but in this case its the first operand which would also be chosen by default.
| # TODO #1857 - passing base_type as an instance of ArrayType | ||
| # only works because the ArrayType constructor just pulls out | ||
| # the intrinsic and precision properties of the type. |
There was a problem hiding this comment.
Is this the reason the method have the desirable property that "the datatype method should not propagate the DEFERRED attribute when constructing the datatype of an expression". In this case this should not be a TODO, just a comment. And it will be good to add tests with Extent.ATTRIBUTE and Extent.DEFERRED in src/psyclone/tests/psyir/nodes/array_reference_test.py which are the moment there is none.
Also if the above is true can you update the docstring to say:
def datatype(self) -> Datatype:
''' Note that if the resulting datatype is an ArrayType,
this will convert Extent attributes to the appropriate inquiry intrinsic,
which is convenient to directly use the resulting expression as executable
code. Use `node.symbol.datatype` to obtain the type declaration of the
array symbol (with its Extent attributes).
:returns: the resulting datatype of the array access expression.
'''
(We may want the first sentence to be in each node.datatype docstring, as it is true by extension. E.g. operation.datatype must also have this property)
There was a problem hiding this comment.
By the way, if you extend the src/psyclone/tests/psyir/nodes/array_reference_test.py::test_array_datatype I would prefer to have it with a fortran_writer and a bunch of fortran declaration and array_references. I find it much easier to quickly verify it than reading the constructed PSyIR.
| all(self.is_full_range(idx) for idx in range(len(shape))) | ||
| and all(isinstance(idx, ArrayType.ArrayBounds) for idx in | ||
| orig_shape)): | ||
| return self.symbol.datatype |
There was a problem hiding this comment.
I am still usure about this:
- Are not all shapes ArrayType.ArrayBounds?, what is the new condition checking?
- What happens if there is a DEFERRED array bounds e.g.
real, dimension(3:) :: a. There is no tests for this. - Wouldn't we want the same behaviour if it is not the full range, for instance in .
real, dimension(100,100) :: aanda(:,1), the resulting shape should preferable be [100] and not SIZE(a, 1).
| binop7 = BinaryOperation.create(oper, ref7.copy(), ref6.copy()) | ||
| dtype6 = binop7.datatype | ||
| assert dtype6.shape[0].lower.value == "1" | ||
| assert dtype6.shape[0].upper.debug_string() == "5" |
There was a problem hiding this comment.
Another case we could implement/test is UnresolvedType/UnknwonType + ArrayType
In fortran the operand of an ArrayType can only be an array of the same rank or an scalar. But both will always results as an array of the exact same shape than the ArrayType of the known operand.
Still in progress, this so far changes the arrayreference datatype to never give shapes with
ArrayType.Extentin the result if we can resolve the shape.I want to look at binaryoperation and how it chooses what result to use next, as I think we can do better than the current resul.