I generated a 3240000×1460 SparseMatrixCSC{UInt8, Int64} with 518339 stored entries, hereafter called activitygrid. It holds a spatial 3D grid (dims: 300,300,36) every 30 seconds of a 12 hour period. It was very fast to generate and its size is 40 (using UInt8). The dense form would be sized 4730400000.
I then reshaped this sparse matrix to obtain a 4D grid of which I want to project maximum and sum across its various dimensions, which I will plot with Makie, which needs Float32 values:
sgrid4d = reshape(Float32.(activitygrid),(dims[1],dims[2],dims[3],size(activitygrid)[2]))
julia> typeof(sgrid4d)
Base.ReshapedArray{Float32, 4, SparseMatrixCSC{Float32, Int64}, Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}}
julia> sgrid4d
300×300×36×1460 reshape(::SparseMatrixCSC{Float32, Int64}, 300, 300, 36, 1460) with eltype Float32:
This is generated in a fraction of a second.
However, when I want to take the maximum or sum across dimensions, it takes very long to generate:
julia> @time xy_max = dropdims(maximum(sgrid4d,dims=(3,4)),dims=(3,4))
27.776353 seconds (715.90 k allocations: 47.358 MiB, 0.09% gc time, 1.53% compilation time)
300×300 Matrix{Float32}:
or, if instead I reshaped the matrix to use the time as the first dimension:
julia> @time xy_max = dropdims(maximum(sgrid4d,dims=(1,4)),dims=(1,4))
29.179732 seconds (23 allocations: 352.672 KiB)
300×300 Matrix{Float32}:
which improves allocations but not the speed. Is there a better way that improves performance without having to allocate many gigabytes? After all, it only needs to work on the nonzero values…
Is it possible to create a true 4D SparseMatricCSC instead of a ReshapedArray, and would it help the speed?