-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Avoid unalias()
for matching Array{T}
when broadcasting
#52286
Conversation
`Base.mightalias` considers two arrays to be aliased iff they have the same base pointer in memory, which is exactly the case where it is safe to not make a defensive copy due to the traversal mentioned above
This seems wrong? Theoretically, we can |
You're right: julia> A = collect(reshape(1.0:9.0, (3,3)))
3×3 Matrix{Float64}:
1.0 4.0 7.0
2.0 5.0 8.0
3.0 6.0 9.0
julia> B = unsafe_wrap(Matrix{Float64}, pointer(A), (1,1))
1×1 Matrix{Float64}:
1.0 With this PR this incorrectly gives: julia> @. A = A + B
3×3 Matrix{Float64}:
2.0 6.0 9.0
4.0 7.0 10.0
5.0 8.0 11.0 It is pretty unsatisfying, since the only real source of |
That is |
That is true, but it's also pretty unexpected that julia> x = ones(1,5)
1×5 Matrix{Float64}:
1.0 1.0 1.0 1.0 1.0
julia> y = reshape(x, (5,)); pop!(y); pop!(y); pop!(y); pop!(y); push!(y, -Inf)
2-element Vector{Float64}:
1.0
-Inf
julia> x
1×5 Matrix{Float64}:
1.0 -Inf 1.0 1.0 1.0 I don't think it's specified (1) whether Which means that if I want to write code that does I think our aliasing guarantees for |
That is somewhat true, but that why there is the |
You might want to look at #26237, #50820, and #51753, #26865. A more general version of that would also be able to check if the bounds and direction of access are compatible (e.g. what some of the |
It would be good to some review of the reasoning here.
I am assuming that:
Base.mightalias
considers twoArray{T}
to be aliased iff they have the same base pointer in memorybroadcast!(f, A, ..., A, ...)
enforces that the two arrays have the same dimensionsThis implies that when we do an
unaliascopy()
for arrays of the same type, the arrays were aligned element-for-element in memory anyway, which is exactly the case where it is safe to not make a defensive copy due to the traversal mentioned just above.