(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?
| else: | ||
| base_type = self.symbol.datatype | ||
| # Create a copy of the base datatype. | ||
| base_type = self.symbol.datatype.datatype.copy() |
There was a problem hiding this comment.
Not the fault of this PR but I always find the datatype.datatype very confusing and I have to dig into it to understand what it tries to do (and we have it in several places). I propose renaming the ArrayType property as "elemental_type", I think it would make it more readable everywhere we use it? @arporter any opinions?
(I would also remove the comment then as is the same as the statement)
There was a problem hiding this comment.
I think we already have an issue about ArrayType's subtypes so I think the improvement should be suggested there probably @sergisiso
There was a problem hiding this comment.
What is the issue number, I am not able to find it.
There was a problem hiding this comment.
#1857 I was thinking it sounded related to this.
| # Special case for UnsupportedFortranType to match previous | ||
| # behaviour expected by lfric tests. | ||
| if (orig_shape and len(orig_shape) == len(shape) and isinstance( | ||
| self.symbol.datatype, UnsupportedFortranType) and | ||
| all(self.is_full_range(idx) for | ||
| idx in range(len(shape)))): | ||
| return self.symbol.datatype | ||
| if (orig_shape and len(orig_shape) == len(shape) and | ||
| all(self.is_full_range(idx) for idx in range(len(shape))) | ||
| and all(isinstance(idx, ArrayType.ArrayBounds) for idx in | ||
| orig_shape)): | ||
| # Although this access has a shape, it is for the | ||
| # whole array, and the original array has no ArrayType.Extent | ||
| # elements, so we should return the original shape as its | ||
| # fully defined without using size intrinsics. |
There was a problem hiding this comment.
I don't agree with this special-case, at least not for the reason in the comment.
Only 1 lfric test fails and is probably due to a wrong assert, if we want to test the symbol declaration type we need to do isinstance(psyir_args[4].symbol.datatype, ....
As now ref.datatype (resulting reference datatype) and ref.symbol.datatype (declaration datatype ) have slightly different meanings.
I notice there are also differences in WHERE tests that I haven't looked at, are this the same reason?
There was a problem hiding this comment.
I fixed the test for the LFRic test to use symbol.datatype.
I've not looked at the WHERE tests, I don't think I changed any of those? Or if I did I missed it.
There was a problem hiding this comment.
To clarify, when I tried commenting out this special case code something in the frontend where tests failed. But maybe it was unrelated - no worries if you don't see it.
There was a problem hiding this comment.
The second block is needed as otherwise you get:
do widx1 = 1, SIZE(a, dim=1), 1
instead of just
do widx1 = 1, 100, 1
There was a problem hiding this comment.
Oh yeah these are the tests where you now get SIZE instead of just 100 because the second block isn't the special case the original comment is referring to - its just the basic case for a full range where we have a non-allocatable array. I'll fix the comment.
| # FIXME We can do better here, pick whichever we have more information | ||
| # about, where information is literal > reference > intrinsiccall | ||
|
|
||
| # If only one of the argtypes is an ArrayType then we return that |
There was a problem hiding this comment.
Not yours but I am confused by the use of "argtypes" in this method, can we rename it to "operand_types"
There was a problem hiding this comment.
I changed it to optype, I can expand it still if you'd prefer but I'd like it to be a bit concise as a name.
| shape = (argtypes[0].shape if isinstance(argtypes[0], ArrayType) | ||
| else argtypes[1].shape) |
There was a problem hiding this comment.
Is the else in this statement ever used? the parent if already tells us that all are ArrayType. If not the comment on top should say "... the first"
There was a problem hiding this comment.
I don't think it can be any more since I added the if statement so I'll remove it.
| shape = (argtypes[0].shape if isinstance(argtypes[0], ArrayType) else | ||
| argtypes[1].shape) | ||
| # FIXME We can do better here, pick whichever we have more information | ||
| # about, where information is literal > reference > intrinsiccall |
There was a problem hiding this comment.
Remove the FIXME and this comment may be better inside the else block below
There was a problem hiding this comment.
Removed the whole block, the commont in the else already describes what we're doing.
| else argtypes[1].shape) | ||
| else: | ||
| # Otherwise we try to work out the best. Find out how many | ||
| # or non-intrinsic DataNodes shape definitions each |
There was a problem hiding this comment.
Yeah, it remained from a previous implementation where it was a bit more conditional, but I decided this was sufficient.
| end if | ||
| enddo''' | ||
| out = fortran_writer(psyir) | ||
| print(out) |
| # Otherwise use the default. | ||
| shape = (argtypes[0].shape if isinstance(argtypes[0], ArrayType) | ||
| else argtypes[1].shape) | ||
| return ArrayType(base_type, shape=shape) |
There was a problem hiding this comment.
Add tests in src/psyclone/tests/psyir/nodes/operation_test.py to show/test this functionality
There was a problem hiding this comment.
This has shown up a slight issue where I will often get 1 + SIZE(blah) - 1 as the .upper, which doesn't show the behaviour I want so I need to add some slight improvement to the check I think.
There was a problem hiding this comment.
Fixed this to get the correct behaviour. I don't love that the upper shape is "5-1+1", but I think that's a more fundamental issue with _extent and using integer types that aren't exactly INTEGER_TYPE. This test (for whatever reason) uses INTEGER_SINGLE_TYPE (which I just copied), but then this fails at comparing to "one" in ArrayMixin._extent because the precisions are different.
@sergisiso @arporter I discussed adding a "get_python_representation" (more concise name is appreciated) to the Literal class - can I add that into this PR and use it in _extent to check start/step being one? Or would you rather I make a separate PR and come back to this later.
There was a problem hiding this comment.
The new implementation is a little more verbose but doesn't care about precision any more.
|
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. |
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.