Large matrix crashes StaticArrays

Hi,
I would like to instantiate a medium-size (1000,1000) matrix in a StaticArray field of MyStruct. But it crashes!
Can you tell me if I am doing something wrong?

a = SMatrix{1000,1000, Float64}(rand(1000,1000))


syntax: expression too large
Stacktrace:
 [1] top-level scope at /home/cocconat/Documents/Research/phd_project/simulations/tripod_network/weights/dataStructs.jl:96
 [2] _convert at /home/cocconat/.julia/packages/StaticArrays/LJQEe/src/convert.jl:35 [inlined]
 [3] convert at /home/cocconat/.julia/packages/StaticArrays/LJQEe/src/convert.jl:32 [inlined]
 [4] SArray{Tuple{1000,1000},Float64,2,L} where L(::Array{Float64,2}) at /home/cocconat/.julia/packages/StaticArrays/LJQEe/src/convert.jl:7
 [5] top-level scope at /home/cocconat/Documents/Research/phd_project/simulations/tripod_network/weights/dataStructs.jl:96

Thanks

1 Like

Static arrays are not meant for big matrices/vectors but only up to about 100 elements. I think this is essentially Julia’s parser giving up to parse an expression for a 1-million element tuple (which is the underlying storage for StaticArrays).

11 Likes

you are right, it is also written in the README

1 Like

Why does StaticArrays fail with large matrices? Does it allocate on the stack rather than the heap?

Should we be using Julia’s default arrays for large matrices, even when they won’t need to be resized and speed is important?

1 Like

Some of the StaticArrays do. The SArrays are immutable and are allocated on the stack.

There are also mutable but statically sized arrays, MArrays. There is also SizedArray which can be used to add size information to a normal Array.

SArray Demonstration

julia> using StaticArrays

julia> subtypes(StaticArray)
6-element Vector{Any}:
 FieldArray{N} where N<:Tuple
 MArray
 SArray
 SHermitianCompact
 SizedArray
 StaticArrays.SUnitRange



julia> sa = SArray{Tuple{2,2}}(ntuple(identity,4))
2×2 SMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
 1  3
 2  4

julia> typeof(sa.data)
NTuple{4, Int64}

julia> isimmutable(sa)
true

julia> isimmutable(sa.data)
true

julia> sa[1] = 2
ERROR: setindex!(::SMatrix{2, 2, Int64, 4}, value, ::Int) is not defined.
...

julia> pointer(sa)
ERROR: conversion to pointer not defined for SMatrix{2, 2, Int64, 4}

MArray demonstration

julia> ma = MArray{Tuple{2,2}}(1:4)
2×2 MMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
 1  3
 2  4

julia> isimmutable(ma)
false

julia> isimmutable(ma.data)
true

julia> ma[1] = 2
2

julia> ma
2×2 MMatrix{2, 2, Int64, 4} with indices SOneTo(2)×SOneTo(2):
 2  3
 2  4

julia> pma = pointer(ma)
Ptr{Int64} @0x00007f8ec8748a90

julia> unsafe_load(pma, 1)
2

julia> unsafe_load(pma, 2)
2

julia> unsafe_load(pma, 3)
3

julia> unsafe_load(pma, 4)
4


Yes. Or if they have special structure (symmetry, diagonal, etc), use some of the special wrappers in the LinearAlgebra stdlib.

1 Like