# Inference in nested quadgk

**URL:** <https://discourse.julialang.org/t/inference-in-nested-quadgk/99937>\
**Category:** Performance\
**Tags:** inference\
**Created:** [June 6, 2023, 1:11pm UTC](https://discourse.julialang.org/t/inference-in-nested-quadgk/99937 "2023-06-06T13:11:48Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![lxvm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lxvm/32/50010_2.png) [@lxvm](https://discourse.julialang.org/u/lxvm)\
**Post date:** [June 6, 2023, 1:11pm UTC](https://discourse.julialang.org/t/inference-in-nested-quadgk/99937/1 "2023-06-06T13:11:48Z")

</div>

There have been a handful of threads on this forum regarding long compilation times for nested quadgk calls (e.g. [here](https://discourse.julialang.org/t/performance-with-nested-quadgk-integrals/19889)) and I was wondering what are some of the possible reasons that type inference may be failing in this case. As an example

```julia
julia> using QuadGK

julia> mysin(x) = quadgk(cos, 0, x, atol=1e-8)[1]
mysin (generic function with 1 method)

julia> mycos(x) = quadgk(mysin, 0, 1, atol=1e-7)[1] 
mycos (generic function with 1 method)

julia> @code_warntype mycos(1.0) # returns Any

julia> @code_warntype mysin(1.0) # returns Float64

julia> @code_warntype mycos(1.0) # returns Float64

```

With tests like these we can only see the inference of `mycos` fail if `mysin` hasn’t been inferred before.

Since `mysin` is inferrable, but `mycos` is not (at least until `mysin` is inferred), does the success/failure of inference suggest that the code of `quadgk` too large/expensive to infer when doubly nested? Are closures (such as [this](https://github.com/JuliaMath/QuadGK.jl/blob/b14ea2ffb02abff6ddf9570c44a623daad360c26/src/adapt.jl#L10)) possibly responsible and in general are there any tips on writing code that is easier to infer when multiply nested?

I will add that we can make inference succeed by calling `Base.promote_op` on the inner integral, for example (in a fresh session):

```julia
julia> using QuadGK

julia> mysin(x) = quadgk(cos, 0, x, atol=1e-8)[1]
mysin (generic function with 1 method)

julia> function mycos2(x)
           F = float(typeof(x))
           O = Base.promote_op(mysin, F)
           return quadgk(mysin, 0, x, atol=1e-7)[1]
       end 
mycos2 (generic function with 1 method)

julia> @code_warntype mycos2(1.0) # returns Float64

```

Getting inference to work this way, or with [FunctionWrappers](https://github.com/yuyichao/FunctionWrappers.jl), seems artificial, but it works.
