Hello,
I use big structs in my code with lots of different vectors of integers and floats like so:
mutable struct Bodies
a:: Vector{StaticArrays.SVector{3,Float64}}
b:: Int
c:: Vector{StaticArrays.SVector{3,Int}}
d:: Int
e:: Vector{StaticArrays.SVector{4,Int}}
f:: Int
g:: Int
h:: Vector{Int}
i:: Vector{Union{ StaticArrays.SVector{3,Int},StaticArrays.SVector{4,Int} }}
j:: Vector{Vector{Int}}
...
Right now this code is running on the CPU. An older version without structs ran on the GPU and now I want to port this one to be CPU/GPU runnable.
How would you guys recommend I do that? Do I need to have 2 structs definitions, one using CuArrays and one with Vectors or is there a more elegant way to do this?
Thanks a lot!
Yep, that doesn’t work. The error such a definition throws (I use Dict instead of StaticArray to not need using a package):
julia> struct A{V}
a::V{Dict{Int,Int}}
end
ERROR: TypeError: in Type{...} expression, expected UnionAll, got a value of type TypeVar
Stacktrace:
[1] top-level scope
@ REPL[1]:1
is a bit cryptic. But it boils down to that types need to be fully defined within the type-def (i.e. a UnionAll and not a TypeVar). This means that you cannot do “type calculations” within the type-def. For instance this is not possible either:
julia> struct B{N}
a::Array{Int, N+1}
end
ERROR: MethodError: no method matching +(::TypeVar, ::Int64)
...
What you can do is:
julia> struct D{V<:U where U<:AbstractVector{D} where D<:Dict{Int,Int}}
a::V
b::V
end
julia> D([Dict(1=>1)], [Dict(2=>2)])
D{Vector{Dict{Int64, Int64}}}([Dict(1 => 1)], [Dict(2 => 2)])
However, for your case this approach may not be that useful as the types of your fields all seem a bit different. So, probably you just give each a type parameter (without any fancy & verbose constraints) and be done with it.
Yes, that is probably best, as too many type parameters are bad (e.g. really annoying in error messages). You can use something like this to avoid repetition:
julia> for (n,V) in zip([:CPUstuct, :GPUstruct], [:Vector, :CuVector])
eval(quote
struct $n
a::$V{StaticArrays.SVector{3,Float64}}
c::$V{StaticArrays.SVector{20,Float64}}
end
end
)
end