Skip to content
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

resize! of HybridArray #64

Open
judober opened this issue May 1, 2023 · 6 comments
Open

resize! of HybridArray #64

judober opened this issue May 1, 2023 · 6 comments

Comments

@judober
Copy link

judober commented May 1, 2023

I use HybridArrays as a replacement for a Vector of SMatrices. Now I found the need to resize! the Vector.
This works for Vector of SMatrices but not a HybridArray:

V = [SA[1 2; 3 4], SA[5 6; 7 8]]; 
resize!(V, 3) # adds one entry

H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2));
resize!(H, 3) # errors

Is there a way to achieve this with a HybridArray?

@mateuszbaran
Copy link
Collaborator

Currently there is no such functionality but I can add it for https://github.com/JuliaArrays/ElasticArrays.jl wrapped in HybridArrays. Would that work for you?

@judober
Copy link
Author

judober commented May 1, 2023

I didn't know ElasticArrays but it sounds interesting!

However, I understand my problem better now and solved it differently.

My first attempt to increase the Array was generate a new one and copy the data resulting in bad performance (example with short arrays):

H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
@btime H2[:,:,1:2] .= H #30.800 μs (333 allocations: 21.00 KiB)

But when I insted loop over the third dimension, I get good performance:

@btime for i = 1:2; H2[:,:,i] = H[:,:,i]; end #66.667 ns (2 allocations: 96 bytes)

I guess .= is not implemented efficiently as it depends on which dimensions are Dynamic.

So from my side this issue can actually be closed.

@mateuszbaran
Copy link
Collaborator

Hm, that broadcast shouldn't be so slow but I'm not sure what causes that issue. I'll have to investigate.

@judober
Copy link
Author

judober commented May 6, 2023

I improved the benchmark a little with:

H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
@btime $H2[:,:,1:2] .= $H #196.189 ns (16 allocations: 512 bytes)
@btime for i = 1:2; $H2[:,:,i] = $H[:,:,i]; end #3.000 ns (0 allocations: 0 bytes)

The difference is smaller but still signifficant.

f() = begin H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
       H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
       H2[:,:,1:2] .= H
       end
@profview for i = 1:10_000_000 f() end

tells me that most time is spend in _setindex!_scalar, not sure if this helps.

@mateuszbaran
Copy link
Collaborator

I've spent some time investigating but I got stuck: https://discourse.julialang.org/t/tracking-the-cause-of-allocation-in-the-presence-of-a-generated-function/98215 . I have no idea why Julia failed to optimize that call and the tools I know don't help 😕 . I think it would be easier to implement resize! for hybrid elastic arrays.

@judober
Copy link
Author

judober commented May 7, 2023

Ok, thanks for looking into this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants