Hello. I am using julia 1.7.1
.
I am facing trouble trying to understand an unexpected memory allocation in the below simplified and self-contained program:
struct VerticalLine{I}
i_min::I
i_max::I
j::I
end
struct ParallelVerticalLines{I}
i::I
j::I
height::I
width::I
end
function put_pixel!(image::AbstractMatrix, i, j, color)
image[i, j] = color
return nothing
end
function draw!(f::Function, image::AbstractMatrix, shape::VerticalLine, color)
i_min = shape.i_min
i_max = shape.i_max
j = shape.j
for i in i_min:i_max
f(image, i, j, color)
end
return nothing
end
function draw!(f::Function, image::AbstractMatrix, shape::ParallelVerticalLines, color)
i_min = shape.i
i_max = shape.i + shape.height - one(shape.height)
# i_max = shape.i
j_min = shape.j
j_max = shape.j + shape.width - one(shape.width)
# j_max = shape.j
shape1 = VerticalLine(i_min, i_max, j_min)
draw!(f, image, shape1, color)
shape2 = VerticalLine(i_min, i_max, j_max)
draw!(f, image, shape2, color)
return nothing
end
const shape = ParallelVerticalLines(1, 1, 3, 3)
const image1 = zeros(UInt32, 32, 32)
const color1 = 0x00ffffff
draw!(put_pixel!, image1, shape, color1)
println(@allocated draw!(put_pixel!, image1, shape, color1))
const image2 = falses(32, 32)
const color2 = true
draw!(put_pixel!, image2, shape, color2)
println(@allocated draw!(put_pixel!, image2, shape, color2))
Here are my observations that are puzzling to me:
- The
draw!
function allocates memory in theUInt32
case but not in theBool
case. - When I comment out
i_max = shape.i + shape.height - one(shape.height)
andj_max = shape.j + shape.width - one(shape.width)
, and replace them withi_max = shape.i
andj_max = shape.j
respectively, the memory allocation vanishes. - When I comment out
shape2 = VerticalLine(i_min, i_max, j_max)
anddraw!(f, image, shape2, color)
, the memory allocation again vanishes. -
@code_warntype draw!(put_pixel!, image1, VerticalLine(1, 3, 1), color1)
and@code_warntype draw!(put_pixel!, image2, VerticalLine(1, 3, 1), color2)
have aUnion
type inferred for an automatically named local variable. I don’t understand what this local variable is and why it is not inferred correctly.
@code_warntype draw!(put_pixel!, image1, shape, color1)
and @code_warntype draw!(put_pixel!, image2, shape, color2)
shows that all types seem to be inferred. I don’t see any obvious type instability that might be causing the above issues.
It would be great if someone could help me explain the reasons behind my observations. Thanks!
Here is the output of versioninfo()
, if needed:
julia> versioninfo()
Julia Version 1.7.1
Commit ac5cc99908 (2021-12-22 19:35 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-12.0.1 (ORCJIT, skylake)