Mostly because it results in errors such as AssertionError: Can only unroll a loop over one of the function's arguments
or BoundsError: attempt to access 0-element Vector{Any} at index [1]
depending on how I try to break things up.
Here is a more complete example, where it seems to be not possible to trivialize the problem away that easily. Apart from the practical aspect in our code, I’m also interested in the conceptual answer to this question.
Here is the more complete example:
abstract type AbstractBaseType{T,N} end
mutable struct BaseStruct_1{T, N} <: AbstractBaseType{T,N}
some_parameter::T
end
mutable struct BaseStruct_2{T, N} <: AbstractBaseType{T,N}
some_parameter::T
end
Base.length(::Type{BaseStruct_1{T,N}}) where {T,N} = N + 1
Base.length(::Type{BaseStruct_2{T,N}}) where {T,N} = N^2
Base.eltype(::Type{<:AbstractBaseType{T,N}}) where {T,N} = T
struct Sinput{T,X,D}
input::X
someArray::Array{T,D}
buffer::Vector{T}
end
function Sinput(input::X) where {X}
D = length(input)
T = eltype(typeof(input[1]))
dims = Tuple([length(typeof(x)) for x in input])
someArray = rand(T, dims)
buffer = ones(T, D)
Sinput{T,X,D}(input, someArray, buffer)
end
function innercall(el::BaseStruct_1{T,N}, x::T) where {T,N}
x^2 + el.some_parameter - 3.23
el.some_parameter += 1.2
end
function innercall(el::BaseStruct_2{T,N}, x::T) where {T,N}
x - el.some_parameter^2
el.some_parameter += 1.2
end
function resetInternalParam(el::AbstractBaseType)
el.some_parameter = 0.
end
function (intP::Sinput{T,X,D})(x::T) where {T,X,D}
result = zero(T)
for ind in CartesianIndices(intP.someArray)
for i=1:D
if ind[i]==1
resetInternalParam(intP.input[i])
intP.buffer[i] = innercall(intP.input[i], x)
else
intP.buffer[i] = innercall(intP.input[i], x)
break
end
end
result += intP.someArray[ind] * prod(intP.buffer)
end
return result
end
base_1 = BaseStruct_1{Float64, 5}(1.);
base_2 = BaseStruct_2{Float64, 6}(1.);
s_input = Sinput((base_1, base_2));
s_input(1.2)
@code_warntype s_input(1.2)