-
-
Notifications
You must be signed in to change notification settings - Fork 308
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
data_limits dispatch for Mesh to omit slow iteration over buffer #2874
Conversation
… then the for loop never stops? sus
some errors in tests: running 59: space 2D autolimits
space 2D autolimits: Error During Test at /home/runner/work/Makie.jl/Makie.jl/ReferenceTests/src/database.jl:45
Test threw exception
Expression: save_result(joinpath(RECORDING_DIR[], "space 2D autolimits"), result)
MethodError: Cannot `convert` an object of type Tuple{Float32, Float32} to an object of type Float32
Closest candidates are:
convert(::Type{T}, ::Base.TwicePrecision) where T<:Number at twiceprecision.jl:273
convert(::Type{T}, ::AbstractChar) where T<:Number at char.jl:185
convert(::Type{T}, ::CartesianIndex{1}) where T<:Number at multidimensional.jl:130
...
Stacktrace:
[1] (::GeometryBasics.var"#23#34"{Float32, Tuple{Float32, Float32}})(i::Int64)
@ GeometryBasics ~/.julia/packages/GeometryBasics/kt2Em/src/fixed_arrays.jl:45
[2] ntuple
@ ./ntuple.jl:50 [inlined]
[3] Vec{3, Float32}(x::Tuple{Float32, Float32})
@ GeometryBasics ~/.julia/packages/GeometryBasics/kt2Em/src/fixed_arrays.jl:45
[4] convert
@ ~/.julia/packages/StaticArrays/4uslg/src/convert.jl:176 [inlined]
[5] HyperRectangle{3, Float32}(origin::StaticArraysCore.SizedVector{2, Float32, Vector{Float32}}, widths::StaticArraysCore.SizedVector{2, Float32, Vector{Float32}})
@ GeometryBasics ~/.julia/packages/GeometryBasics/kt2Em/src/primitives/rectangles.jl:10
[6] data_limits(plot::MakieCore.Mesh{Tuple{GeometryBasics.Mesh{2, Float32, TriangleP{2, Float32, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}}, FaceView{TriangleP{2, Float32, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}}, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}, NamedTuple{(:position, :uv, :normals), Tuple{Vector{Point{2, Float32}}, Vector{Vec{2, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}})
@ Makie ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:215
[7] (::Makie.var"#775#777"{Makie.var"#exclude#1397"{Int64}, Base.RefValue{HyperRectangle{3, Float32}}})(plot::MakieCore.Mesh{Tuple{GeometryBasics.Mesh{2, Float32, TriangleP{2, Float32, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}}, FaceView{TriangleP{2, Float32, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}}, PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{2, Float32, Point{2, Float32}, (:uv, :normals), Tuple{Vec{2, Float32}, Vec{3, Float32}}}, NamedTuple{(:position, :uv, :normals), Tuple{Vector{Point{2, Float32}}, Vector{Vec{2, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}})
@ Makie ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:198
[8] foreach(f::Makie.var"#775#777"{Makie.var"#exclude#1397"{Int64}, Base.RefValue{HyperRectangle{3, Float32}}}, itr::Vector{AbstractPlot})
@ Base ./abstractarray.jl:2774
[9] foreach_plot
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:109 [inlined]
[10] foreach_plot
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:103 [inlined]
[11] data_limits
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:196 [inlined]
[12] getlimits(la::Axis, dim::Int64)
@ Makie ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:881
[13] autolimits(ax::Axis, dim::Int64)
@ Makie ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:951
[14] xautolimits
@ ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:982 [inlined]
[15] reset_limits!(ax::Axis; xauto::Bool, yauto::Bool, zauto::Bool)
@ Makie ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:582
[16] reset_limits!
@ ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:[569](https://github.com/MakieOrg/Makie.jl/actions/runs/4752774705/jobs/8443537615?pr=2874#step:6:570) [inlined]
[17] update_state_before_display!(ax::Axis)
@ Makie ~/work/Makie.jl/Makie.jl/src/makielayout/blocks/axis.jl:1376
[18] update_state_before_display!(f::Figure)
@ Makie ~/work/Makie.jl/Makie.jl/src/figureplotting.jl:178 updating multiple meshes: Error During Test at /home/runner/work/Makie.jl/Makie.jl/ReferenceTests/src/database.jl:32
Got exception outside of a @test
type Array has no field position
Stacktrace:
[1] getproperty(x::Vector{GeometryBasics.Mesh{3, Float32, TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, FaceView{TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NamedTuple{(:position, :normals), Tuple{Vector{Point{3, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}, f::Symbol)
@ Base ./Base.jl:38
[2] data_limits(plot::MakieCore.Mesh{Tuple{Vector{GeometryBasics.Mesh{3, Float32, TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, FaceView{TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NamedTuple{(:position, :normals), Tuple{Vector{Point{3, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}}})
@ Makie ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:213
[3] (::Makie.var"#775#777"{Makie.var"#774#776", Base.RefValue{HyperRectangle{3, Float32}}})(plot::MakieCore.Mesh{Tuple{Vector{GeometryBasics.Mesh{3, Float32, TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, FaceView{TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NamedTuple{(:position, :normals), Tuple{Vector{Point{3, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}}})
@ Makie ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:198
[4] foreach(f::Makie.var"#775#777"{Makie.var"#774#776", Base.RefValue{HyperRectangle{3, Float32}}}, itr::Vector{AbstractPlot})
@ Base ./abstractarray.jl:2774
[5] foreach_plot
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:109 [inlined]
[6] foreach_plot
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:103 [inlined]
[7] data_limits
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:196 [inlined]
[8] data_limits
@ ~/work/Makie.jl/Makie.jl/src/layouting/data_limits.jl:195 [inlined]
[9] is2d
@ ~/work/Makie.jl/Makie.jl/src/scenes.jl:590 [inlined]
[10] plot(P::Type{MakieCore.Mesh}, args::Vector{GeometryBasics.Mesh{3, Float32, TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, FaceView{TriangleP{3, Float32, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}}, PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NgonFace{3, OffsetInteger{-1, UInt32}}, StructArrays.StructVector{PointMeta{3, Float32, Point{3, Float32}, (:normals,), Tuple{Vec{3, Float32}}}, NamedTuple{(:position, :normals), Tuple{Vector{Point{3, Float32}}, Vector{Vec{3, Float32}}}}, Int64}, Vector{NgonFace{3, OffsetInteger{-1, UInt32}}}}}}; axis::NamedTuple{(), Tuple{}}, figure::NamedTuple{(), Tuple{}}, kw_attributes::Base.Pairs{Symbol, Vector{RGB{Float32}}, Tuple{Symbol}, NamedTuple{(:color,), Tuple{Vector{RGB{Float32}}}}})
@ Makie ~/work/Makie.jl/Makie.jl/src/figureplotting.jl:49
[11] #mesh#39
@ ~/work/Makie.jl/Makie.jl/MakieCore/src/recipes.jl:34 [inlined] |
Remaining CI fails seem unrelated, locally all tests pass for me |
The test case that fails has |
Should I restrict to |
Sounds reasonable to me |
I still think we should just fix the iteration performance in Buffer, instead of special casing in Makie. |
would it be possible to dispatch |
After peeking into this further, I do not think it is an iteration over the buffer. function f(buf::T) where T
sum = zero(eltype(T))
for val ∈ buf
sum += val^2
end
return sum
end;
buf = GLMakie.Buffer(ones(100));
@btime f($buf); # 92.409 ns (0 allocations: 0 bytes) I think most of the allocations come from Makie.jl/src/layouting/data_limits.jl Line 59 in 84a1cdf
Benchmark: brain = load(assetpath("brain.stl"))
brain_1 = GeometryBasics.Mesh(metafree(coordinates(brain)), faces(brain))
@btime mesh(
$brain_1
) # 9.735 ms (36781 allocations: 2.28 MiB)
@btime decompose(Point, $brain_1) # 3.120 ns (0 allocations: 0 bytes)
brain_2 = GeometryBasics.Mesh(Buffer(metafree(coordinates(brain))), Buffer(faces(brain)))
@btime mesh(
$brain_2
) # 10.634 ms (36789 allocations: 6.30 MiB)
@btime decompose(Point, $brain_2) # 131.912 μs (2 allocations: 1.34 MiB) | is called 3 times => 4.02MB |
I guess with iterator Simon means the |
Because it would be very nice to squeeze out every bit of possible performance for this. At least I'd appreciate it very much :D |
Is this actually still needed after the data_limit changes I introduced? |
Which changes exactly? Just that I know what version to try |
Does #3076 solve your issue? |
I'm closing this for now, since we need a better undestanding of what this is supposed to solve! |
Description
Fixes #2864
This PR changes the performance of the following:
to
by usingextrema
indata_limits
instead of computing thebbox
by iterating overmesh.position
which is still expensive. I'm not sure tho whatextrema
uses under the hood the avoid the performance issues. I looked up the source code atbut I don't understand anything that's going on there :DI included a function
bbox_mesh
that iterates over the coordinates and checks the bbox manually. There is some weird issue that if I move the function's body insidedata_limits
the for loop never stops. Not sure what's going on thereThe PR is also beneficial for
GeometryBasics.Mesh
es withoutShaderAbstractions.Buffer
. From this:to
Type of change
Delete options that do not apply:
Checklist