SciML / OrdinaryDiffEq.jl

High performance ordinary differential equation (ODE) and differential-algebraic equation (DAE) solvers, including neural ordinary differential equations (neural ODEs) and scientific machine learning (SciML)
https://diffeq.sciml.ai/latest/
Other
523 stars 199 forks source link

`@cache` macro generates code with OrdinaryDiffEq namespace #2158

Closed evetion closed 3 weeks ago

evetion commented 4 months ago

Describe the bug 🐞

@cache macro generates code with OrdinaryDiffEq namespace.

Expected behavior

No error on using @cache on our own structs.

Minimal Reproducible Example πŸ‘‡ Following the documentation on adding algorithms, we run:

using OrdinaryDiffEq
import OrdinaryDiffEq: 
      OrdinaryDiffEqAlgorithm, OrdinaryDiffEqMutableCache, OrdinaryDiffEqConstantCache,
      alg_order, alg_cache, initialize!, perform_step!, trivial_limiter!, constvalue,
      @muladd, @unpack, @cache, @..

struct RK_ALG{StageLimiter,StepLimiter} <: OrdinaryDiffEq.OrdinaryDiffEqAlgorithm 
  stage_limiter!::StageLimiter
  step_limiter!::StepLimiter
end
RK_ALG(stage_limiter! = trivial_limiter!) = RK_ALG(stage_limiter!, trivial_limiter!)
export RK_ALG
alg_order(alg::RK_ALG) = 3

@cache struct RK_ALGCache{uType,rateType,StageLimiter,StepLimiter,TabType} <: OrdinaryDiffEqMutableCache
  u::uType
  uprev::uType
  k::rateType
  tmp::uType
  uβ‚‚::uType
  fsalfirst::rateType
  stage_limiter!::StageLimiter
  step_limiter!::StepLimiter
  tab::TabType
end

Error & Stacktrace ⚠️

Which produces the following error:

ERROR: UndefVarError: `RK_ALGCache` not defined

Additional context

Macroexpand to the rescue:

julia> @macroexpand @cache struct RK_ALGCache{uType,rateType,StageLimiter,StepLimiter,TabType} <: OrdinaryDiffEqMutableCache
         u::uType
         uprev::uType
         k::rateType
         tmp::uType
         uβ‚‚::uType
         fsalfirst::rateType
         stage_limiter!::StageLimiter
         step_limiter!::StepLimiter
         tab::TabType
       end
quote
    #= /Users/evetion/.julia/packages/OrdinaryDiffEq/DmspS/src/misc_utils.jl:37 =#
    struct RK_ALGCache{var"#324#uType", var"#325#rateType", var"#326#StageLimiter", var"#327#StepLimiter", var"#328#TabType"} <: OrdinaryDiffEq.OrdinaryDiffEqMutableCache
        #= REPL[40]:2 =#
        u::var"#324#uType"
        #= REPL[40]:3 =#
        uprev::var"#324#uType"
        #= REPL[40]:4 =#
        k::var"#325#rateType"
        #= REPL[40]:5 =#
        tmp::var"#324#uType"
        #= REPL[40]:6 =#
        uβ‚‚::var"#324#uType"
        #= REPL[40]:7 =#
        fsalfirst::var"#325#rateType"
        #= REPL[40]:8 =#
        stage_limiter!::var"#326#StageLimiter"
        #= REPL[40]:9 =#
        step_limiter!::var"#327#StepLimiter"
        #= REPL[40]:10 =#
        tab::var"#328#TabType"
    end
    #= /Users/evetion/.julia/packages/OrdinaryDiffEq/DmspS/src/misc_utils.jl:38 =#
    full_cache(var"#329#c"::OrdinaryDiffEq.RK_ALGCache) = begin
            #= /Users/evetion/.julia/packages/OrdinaryDiffEq/DmspS/src/misc_utils.jl:38 =#
            OrdinaryDiffEq.tuple((var"#329#c").u, (var"#329#c").uprev, (var"#329#c").k, (var"#329#c").tmp, (var"#329#c").uβ‚‚, (var"#329#c").fsalfirst)
        end
end

Which shows that the macro generates full_cache(var"#329#c"::OrdinaryDiffEq.RK_ALGCache), with RK_ALGCache defined in the OrdinaryDiffEq namespace, and not in Main (where the example is run), leading to the UndefVarError.

ChrisRackauckas commented 4 weeks ago

Yeah this came up in the refactor PRs. I'm not entirely sure what's causing this behavior but after the refactor I plan to figure out what's going on here.