JuliaLang / AllocCheck.jl

AllocCheck
Other
209 stars 8 forks source link

Inconsistent with `@allocations` (Bug?) #57

Closed carstenbauer closed 8 months ago

carstenbauer commented 8 months ago
julia> function mycopy!(A, B)
           @. A = B
           return nothing
       end
mycopy! (generic function with 1 method)

julia> A = zeros(10,10);

julia> B = zeros(10,10);

julia> @allocations mycopy!(A,B);

julia> @allocations mycopy!(A,B)
0

julia> check_allocs(mycopy!, typeof.((A,B)))
1-element Vector{Any}:
 Allocation of Array in ./array.jl:409
  | copy(a::T) where {T<:Array} = ccall(:jl_array_copy, Ref{T}, (Any,), a)

Stacktrace:
  [1] copy
    @ ./array.jl:409 [inlined]
  [2] unaliascopy
    @ ./abstractarray.jl:1490 [inlined]
  [3] unalias
    @ ./abstractarray.jl:1474 [inlined]
  [4] broadcast_unalias
    @ ./broadcast.jl:977 [inlined]
  [5] preprocess
    @ ./broadcast.jl:984 [inlined]
  [6] preprocess_args
    @ ./broadcast.jl:987 [inlined]
  [7] preprocess
    @ ./broadcast.jl:983 [inlined]
  [8] copyto!
    @ ./broadcast.jl:1000 [inlined]
  [9] copyto!
    @ ./broadcast.jl:956 [inlined]
 [10] materialize!
    @ ./broadcast.jl:914 [inlined]
 [11] materialize!
    @ ./broadcast.jl:911 [inlined]
 [12] mycopy!(A::Matrix{Float64}, B::Matrix{Float64})
    @ Main ./REPL[12]:2

Note that @allocated gives 0 whereas check_allocs highlights an allocation.

topolarity commented 8 months ago

The stack trace gives us a useful hint here.

AllocCheck.jl is highlighting a rare but valid allocation that might happen when broadcasting aliased arrays:

julia> A = rand(3,3);

julia> B = unsafe_wrap(Matrix{Float64}, pointer(A), size(A));
# A and B are aliased

julia> @allocated mycopy!(A, B) # triggers a defensive unaliascopy()
128

Since check_allocs looks for allocations that might happen in any execution given the input types, the check is behaving correctly here.

carstenbauer commented 8 months ago

Makes perfect sense, thanks. Although that means that all broadcasting expressions will show allocation errors which isn't great I guess. But fair enough for now.