StackOverflowError

First time using JuMP. Below is my JuMP specific code. I am getting very vague error when I try to solve the model and so I am not sure how to follow up. I’m not even sure how specific I should get:

m = Model(solver=NLoptSolver(algorithm=:LD_MMA))
  JuMP.register(m, :f, 2, f, autodiff=true)
  @variable(m, lambda3)
  @variable(m, lambda4)
  setlowerbound(lambda3, -0.25)
  setlowerbound(lambda4, -0.25)
  @NLobjective(m, Min, f(lambda3, lambda4))
julia> solve(m)
ERROR: StackOverflowError:

note f is a user-defined function that is quite complicated, but I can certainly put it here if that is the next place to check.

Some suspicions i have:

f is a function defined within a function and references some variables that are in the scope of that function (its a closure, is that the correct term?). Could that be the issue? If so, how do I get around that?

f calls some other functions within it. Do they all have to be registered?

I might have narrowed it down to:

julia> f(ForwardDiff.Dual(1.2),ForwardDiff.Dual(3.4))
ERROR: StackOverflowError:

julia> f(1.2,3.4)
4.688062610165983

If you’re seeing the error just calling f with Dual arguments, then it’s not an issue with function registration in JuMP, so that simplifies the problem.

How much can you simplify f while still seeing the stack overflow? Can you post a minimal example? Stack overflow generally happens when you have infinite recursion, something like:

julia> f(x) = f(-x)
f (generic function with 1 method)

julia> f(1)
ERROR: StackOverflowError:
Stacktrace:
 [1] f(::Int64) at ./REPL[1]:1 (repeats 80000 times)

or something more complicated like:

f(x) = g(x)
g(x) = h(x)
h(x) = f(x)

Narrowed it down to the beta function.

beta(ForwardDiff.Dual(1.2), ForwardDiff.Dual(3.4))
ERROR: StackOverflowError:

So where does that leave me?

What version of ForwardDiff are you on? (Pkg.status()).

It works on 0.7.0

julia> beta(ForwardDiff.Dual(1.2), ForwardDiff.Dual(3.4))
Dual{Void}(0.20455811064350196)

JuMP pins it back to 0.5 or something =((((

 - ForwardDiff                   0.5.0

I will just use beta(x,y) =(gamma(x)*gamma(y))/ gamma(x+y) until JuMP updates to ForwardDiff 0.7

1 Like

You can commit some minor type piracy and do:

Beta.beta(x::ForwardDiff.Dual, y::ForwardDiff.Dual) = ...

so that you won’t interfere with usage of beta() on other types.

1 Like

The update to ForwardDiff 0.7 is incoming: https://github.com/JuliaLang/METADATA.jl/pull/12529