-
Notifications
You must be signed in to change notification settings - Fork 118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refine dynamic borrow checking to track data ranges. #299
Conversation
efc5cec
to
fa44ae0
Compare
fa44ae0
to
2d7ce0a
Compare
791ed3c
to
eb7d2f7
Compare
Needs to be rebased after #302 lands... |
eb7d2f7
to
9df369a
Compare
30aaaa8
to
a013e7b
Compare
9df369a
to
a40d371
Compare
To be honest, I don't think the current conservative strategy is not that bad. I don't imagine the situation where we want to handle slices this smartly. |
a40d371
to
4fe1338
Compare
I spent some time thinking about this: I do not personally have a use case where this part - supporting non-overlapping views, but not interleaved ones - would make a difference, but I would certainly want to support the use case of interleaving views. For example three-dimensional arrays which are made up of multiple two-dimensional layers that modified concurrently but as separate components is something that I handle regularly, for example as image data or multi-layered raster GIS data. So I see this primarily as a stepping stone towards handling this even more general case. (If we actually can handle that as it might be NP to prove absence of aliasing in the general case given only the data pointer, strides and dimensions.) My main fear is that once this goes out and people start using At least there is no regression of functionality, i.e. |
4fe1338
to
8e9c17d
Compare
@kngwyu Thanks to the help of @Darksonn, I think we can significantly improve our approximation and are able to handle the "colors channels of an image array" case. I am still pondering whether there actually exist situation which would run awful of this level of checking as I have not yet constructed an example that does not alias, but has neither disjoint data ranges nor fulfils the GCD criterion, i.e. that does alias only out-of-bounds. Note that The MSRV build failed because |
8e9c17d
to
5815d63
Compare
c648b56
to
f2607ef
Compare
f2607ef
to
0b69f76
Compare
ef7a87e
to
4e8a15c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using GCD is a neat trick; I had an inkling that there would be something like that but didn't have the time to think about it. TBH I'd hope that most cases will now be supported by this implementation 👍
As identified in the unit test, cases where the step size does not divide the dimension along the axis which is sliced are not covered. Handling that would mean recursively solve the linear Diophantine equation implied by the strides of the two arrays. Personally, I think for now I would like to get this into the wild as part of version 0.17 and then see what sticks as doing the above has significant engineering costs: But I definitely need to write more unit tests for driving the |
4e8a15c
to
009ac29
Compare
@kngwyu David already had a look, but since we are not in a hurry to release 0.17 (I think we should stick to release in parallel to PyO3.), I would be glad if you could look into this as well now that it hopefully is in good enough shape to do that. Thank you! I think the GCD-check-based solution is good compromise between effort and accuracy. I am not sure how good the tests are and would be glad if anyone had suggestions on what test cases might be missing. |
c23eaee
to
9ce12bf
Compare
…ase in implementation.
9ce12bf
to
f166964
Compare
Thank you for digging the problem this deep! I have two questions:
|
The |
Sorry my question was why we are computing gcd of all strides, but I think I understand now. GCD of all strides should be the minimum (pointer) distance to the next element in most cases where the GCD is equal to the smallest stride. |
I am not sure what you mean exactly? We do have range checking based on the highest and lowest address that is part of the view, so computing If you mean by checking the slice indices themselves which were used to create the views, e.g.
The idea here is that if there are two arrays
has at least one solution that is within bounds, i.e. that fulfils This equation has at least one solution if and only if
This is the condition that the code is checking and if it does not hold considers them non-conflicting. If it is fulfilled, then it considers them conflicting which is an approximation as all solutions could still be out of bounds (which is the case in the third example). One possible extension to the above would be to actually compute these solutions (meaning to actually compute their bounds) by recursively solving the equation via intermediate equations with two-variables. But I think this would add considerable code complexity, runtime (on top of the around 500 ns this currently takes) and memory (we would need to store all strides and dimensions, not just the data range and the GCD of the strides) which is why I would like give this a try and see how many complaints it raises. (Especially since we can release a refinement that allows more cases to pass as a point release as it is not a breaking change.) |
Indeed, and when it is not equal to the smallest stride, this fact can be used to handle interleaving views, e.g. import numpy as np
a = np.zeros((10, 10))
a.strides # (80, 8)
v3 = a[:, ::2]
v3.strides # (80, 16)
v4 = a[:, 1::2]
v4.strides # (80, 16) has a pointer difference of 8 but a GCD of all strides of 16 which implies that those views do not alias. |
Sorry, I just overlooked that part.
Yeah, I think the GCD of all strides covers most cases |
accd531
to
544a0fa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, pretty good job, but it seems like there is still a corner case
4a7164c
to
6072a84
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I just added a few comments on the document.
…imensional arrays.
6072a84
to
9e7bad3
Compare
Thank you for this difficult job, merge this at your own time. |
Follow-up to #274 as discussed in #274 (comment). Should show that this can work, but still needs needs many unit tests to drive the range data structures into various stages...