Strange behavior of @views with reverse indexing

I’ve noticed a strange behavior using @views with reverse indexing. When I execute the following code:

using LinearAlgebra
A=[1.0; 2.0]; B=[3.0; 4.0]; C = zeros(1); D = zeros(1);
mul!(C, A[1:end]', B[end:-1:1])
@views mul!(D, A[1:end]', B[end:-1:1])

I get C=10.0 (which is expected) and D=8.0 (which is strange).
The same code with integers does not lead to such surprises:

A=[1; 2]; B=[3; 4]; C = zeros(Int64, 1); D = zeros(Int64, 1);
mul!(C, A[1:end]', B[end:-1:1])
@views mul!(D, A[1:end]', B[end:-1:1])

leads to C=10 and D=10 (expected).
Does anyone know what happens here?

mul!(D, (@view A[1:end]'), (@view B[end:-1:1]))

yields

ERROR: LoadError: ArgumentError: Invalid use of @view macro: argument must be a reference expression A[...].

With

mul!(D, A[1:end]', (@view B[end:-1:1]))

the result is wrong. This looks like bug in @view.

Edit: @BioTurboNick double checked with parentheses, the analysis still holds.
Edit: corrected my misunderstanding regarding @views.

You have to wrap @view in parentheses so it knows not to continue past the end bracket.

 mul!(D, (@view A[1:end])', (@view B[end:-1:1]))

@BioTurboNick Thanks for your message. I just tried it:

julia> mul!(D, (@view A[1:end])', (@view B[end:-1:1]))
1-element Vector{Float64}:
 8.0

so it’s executing but the result is not correct (we expect 10.0)

@goerch Thanks, I also suspect a bug but it’s good to hear it from someone else

Yeah, the invalid use of @view thing is a non-sequitur. This is a true bug; the MWE is simply:

julia> B = [3.0; 4.0];

julia> [1. 2.]*B[end:-1:1]
1-element Vector{Float64}:
 10.0

julia> [1. 2.]*(@view B[end:-1:1])
1-element Vector{Float64}:
 8.0
2 Likes

This is #30765, which is fixed on master.

2 Likes

The fix didn’t find its way into Julia 1.7.1? Hm, this is silent data corruption…

@sostock thanks, I think that’s what I was looking for though the bug is still present in Julia 1.7.1. Any idea when this will be fixed in stable?

I just flagged its fix for backporting. The next patch release is under testing; it’ll probably be in the subsequent one, but we probably should fix accompanying regression first and ensure they come together. @sostock could you make it clearer why one might prefer #42054 to #42012?

3 Likes

#42054 allows the matrix to have negative strides as well (in the second dimension), not just the vector. #42012 allows this only in trivial cases (the ones that worked correctly before #41513, i.e., if the matrix is empty or has only one column) and otherwise errors for matrices with negative stride(A, 2).

1 Like