Build_function: stack overflow in type inference

I am trying to use Symbolics.build_function to generate JuMP.AffExpr expressions from symbolic expressions.

I see an error message

Internal error: stack overflow in type inference of (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :ˍ₋arg3, :λ_slope, :λ_sector, :P, :ζ²), Symbolics.var"#_RGF_ModTag", Symbolics.var"#_RGF_ModTag", (0xc10ed7fe, 0x47ee3867, 0xeabcab9f, 0x039a29c4, 0x30209ded), Expr})(Array{JuMP.GenericAffExpr{Float64, JuMP.GenericVariableRef{Float64}}, 2}, Array{JuMP.GenericAffExpr{Float64, JuMP.GenericVariableRef{Float64}}, 2}, Array{JuMP.GenericAffExpr{Float64, JuMP.GenericVariableRef{Float64}}, 2}, JuMP.GenericVariableRef{Float64}, JuMP.GenericVariableRef{Float64}, Array{JuMP.GenericVariableRef{Float64}, 2}, Float64).
This might be caused by recursion over very long tuples or argument lists.

I would like to understand what measure of complicatedness is problematic for build_function and how well I should expect it to scale. (There was a thread [1] earlier with a comment that mentioned “tens of thousands of variables” as a notion of a large function, and I have much fewer than that.)

As can be seen in the error message, the function has only 7 arguments and those are mostly matrices of JuMP expressions. The matrices used as arguments are not very large (diagonal matrices of size around 30x30 or dense of size 4x4). Symbolics.substitute replaces the variables in around 4 seconds, and I was hoping for build_function to offer a faster alternative as I want to perform the same optimization many times while varying parameter values and on new JuMP models.

(I suspect the right solution to my problem may involve reusing JuMP models instead, and replacing parameters in those, but this questions is one step along the way of testing different options, and I have not yet looked for information on reusing JuMP models.)

[1] Compiling large Symbolics.jl expressions using build_function - #3 by ChrisRackauckas

Make a post with your real question. You should be able to do this all in JuMP. You wont need to use symbolics.

Are you using symbolic array expressions? You should make sure that your function isn’t scalarizing. Share some code.

I have tried using symbolic arrays and symbolic array expressions, but I had problems [1] where substitute and build_function both failed to replace all occurences of the variables, and I therefore started to scalarize my expressions to obtain correct results.

I now sometimes define symbolic arrays, but I always scalarize them before using them in mathematical operations.

By the way, I never spent enough time debugging my issues with symbolic arrays, but I think some may have been related to getindex expressions like (broadcast(-, K))[1, 2] perhaps being considered non-composite expressions, due to [2].

[1] Symbolics build_function issues on complicated expressions

[2] In Symbolics.jl, in the file utils.jl, getindex operations are all treated the same, regardless of the complexity of the argument to getindex, in the following function.

function is_singleton(e)
    if istree(e)
        op = operation(e)
        op === getindex && return true
        istree(op) && return is_singleton(op) # recurse to reach getindex for array element variables
        return issym(op)
    else
        return issym(e)
    end
end

Can you provide a reproducible example? Its much easier to offer specific advice than general.