-
-
Notifications
You must be signed in to change notification settings - Fork 113
Safely update retcodes to enums #274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## master #274 +/- ##
==========================================
+ Coverage 54.75% 55.35% +0.60%
==========================================
Files 41 42 +1
Lines 3008 3035 +27
==========================================
+ Hits 1647 1680 +33
+ Misses 1361 1355 -6
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
a1d11e5 to
117e1b4
Compare
117e1b4 to
d66db1f
Compare
src/retcodes.jl
Outdated
| Enumx.@enumx(ReturnCode,Default,Success,Terminated,MaxIters,DtLessThanMin,Unstable, | ||
| InitialFailure,ConvergenceFailure,Failure) | ||
|
|
||
| function Base.Symbol(retcode::ReturnCode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is already supported for enums, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is. This and the hacky convert are what I were playing around with for backwards compatibility since NonlinearSolve defined some of its own enums, but I don't think this is the right solution. Instead, expanding the meaning of success and telling people to use successful_retcode(sol.retcode) for things like Success or Terminated (which is, solve successfully reached steady state and terminated before final time point), EXACT_SOLUTION_LEFT (bisection grabbed the left), FLOATING_POINT_LIMIT (bisection successfully went to the floating point limit). Trying to slam everything to Success loses information, "is any form of success" seems like a better query for things like optimization loops.
However, I'll loop back to that after I figure out what's going on with downstream tests. DelayDiffEq.jl is being puzzling.
I think I found a way that is relatively safe. In all of our code throughout SciML, I noticed that the only thing that was truly done was `sol.retcode == :Success`, etc. in which case a relatively small amount of functions put over a retcode enum could be non-breaking to all functional uses of the previous retcode. If this is the case, we may finally have a good way to upgrade the one piece I find most hideous in the interface.
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
Co-authored-by: Fredrik Ekre <ekrefredrik@gmail.com>
This might be the last thing required to fully switch to enums, SciML/SciMLBase.jl#274
|
As expected, the See was a bigger lift than I thought it would be. Dear Jesus, this simple PR is done. julia> trees[end-1]
inserting convert(::Type{Symbol}, retcode::SciMLBase.ReturnCode.T) in SciMLBase at C:\Users\accou\.julia\dev\SciMLBase\src\retcodes.jl:4 invalidated:
mt_backedges: 1: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for Pair{Symbol, Any}(::Any, ::Any) (0 children)
2: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for REPL.LineEdit.PromptState(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any) (0 children)
3: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for REPL.LineEdit.MIState(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Any) (0 children)
4: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for push!(::Vector{Symbol}, ::Any) (0 children)
5: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for VSCodeServer.JuliaInterpreter.var"#FrameCode#1"(::Bool, ::Bool, ::Type{VSCodeServer.JuliaInterpreter.FrameCode}, ::Method, ::Core.CodeInfo) (0 children)
6: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for JuliaInterpreter.var"#FrameCode#1"(::Bool, ::Bool, ::Type{JuliaInterpreter.FrameCode}, ::Method, ::Core.CodeInfo) (0 children)
7: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for LoweredCodeUtils.set_to_running_name!(::Any, ::Dict{Symbol, Symbol}, ::JuliaInterpreter.Frame, ::Dict{Symbol, LoweredCodeUtils.MethodInfo}, ::LoweredCodeUtils.SelfCall, ::Dict{Symbol, Union{Nothing, Bool, Symbol}}, ::Symbol, ::Nothing) (0 children)
8: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for LoweredCodeUtils.signature(::Any, ::JuliaInterpreter.Frame, ::Any, ::Int64) (0 children)
9: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Artifacts.var"#load_overrides#1"(::Bool, ::typeof(Artifacts.load_overrides)) (0 children)
10: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Artifacts.var"#load_overrides#1"(::Bool, ::typeof(Artifacts.load_overrides)) (0 children)
11: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for LoopVectorization.add_anon_func!(::LoopVectorization.LoopSet, ::Symbol, ::Expr, ::Expr, ::Int64, ::Nothing, ::Int64) (0 children)
12: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Artifacts.var"#load_overrides#1"(::Bool, ::typeof(Artifacts.load_overrides)) (0 children)
13: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Artifacts.var"#load_overrides#1"(::Bool, ::typeof(Artifacts.load_overrides)) (0 children)
14: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Artifacts.var"#load_overrides#1"(::Bool, ::typeof(Artifacts.load_overrides)) (0 children)
15: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for LoopVectorization.Instruction(::Any, ::Any) (1 children)
16: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for setindex!(::Dict{Symbol, Function}, ::Any, ::Any) (2 children)
17: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for LoopVectorization.indices_loop!(::LoopVectorization.LoopSet, ::Expr, ::Symbol) (3 children)
18: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for LoopVectorization.Instruction(::Symbol, ::Any) (3 children)
19: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for setindex!(::IdDict{Module, Symbol}, ::Any, ::Any) (5 children)
20: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for REPL.REPLCompletions.FieldCompletion(::DataType, ::Any) (6 children)
21: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for SnoopCompile.var"#_flamegraph_frame#113"(::Bool, ::typeof(SnoopCompile._flamegraph_frame), ::IOBuffer, ::SnoopCompileCore.InferenceTimingNode, ::Float64, ::Bool, ::Set{Module}, ::Nothing) (6 children)
22: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setindex!(::Dict{Symbol, REPL.LineEdit.Prompt}, ::Any, ::Any) (7 children)
23: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for convert(::Type{Pair{Symbol, Any}}, ::Pair) (25 children)
24: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for LoopVectorization.dottosym(::Any) (28 children)
25: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setproperty!(::Base.RefValue{Symbol}, ::Symbol, ::Any) (97 children)
26: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Base.ImmutableDict{Symbol, Any}(::Base.ImmutableDict{Symbol, Any}, ::Any, ::Any) (132 children)
27: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered
MethodInstance for setindex!(::Dict{Symbol, Any}, ::Any, ::Any) (147 children)
3 mt_cache |
|
What's the plan to deprecate the conversion to julia> using SnoopCompileCore; invalidations = @snoopr(using Trixi); using SnoopCompile
julia> length(uinvalidated(invalidations))
3274
julia> trees = invalidation_trees(invalidations)
...
inserting convert(::Type{Symbol}, retcode::SciMLBase.ReturnCode.T) in SciMLBase at ~/.julia/packages/SciMLBase/cJ8FF/src/retcodes.jl:323 invalidated:
mt_backedges: 1: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for push!(::Vector{Symbol}, ::Any) (0 children)
2: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for SnoopCompileCore.__init__() (0 children)
3: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setindex!(::Dict{Symbol, Function}, ::Any, ::Any) (2 children)
4: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for REPL.REPLCompletions.FieldCompletion(::DataType, ::Any) (4 children)
5: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setproperty!(::Base.RefValue{Symbol}, ::Symbol, ::Any) (8 children)
6: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setindex!(::Dict{Symbol, REPL.LineEdit.Prompt}, ::Any, ::Any) (17 children)
7: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for convert(::Type{Pair{Symbol, Any}}, ::Pair) (25 children)
8: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setindex!(::IdDict{Module, Symbol}, ::Any, ::Any) (26 children)
9: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for setindex!(::Dict{Symbol, Any}, ::Any, ::Any) (176 children)
10: signature Tuple{typeof(convert), Type{Symbol}, Any} triggered MethodInstance for Base.ImmutableDict{Symbol, Any}(::Base.ImmutableDict{Symbol, Any}, ::Any, ::Any) (947 children) |
|
Yeah I knew this was going to be an issue. What I planned to do was first get this all pushed through, and now go add a depwarn now that it has stabilized, and then with v1.9 rip the bandaid off. There's a few codes that used |
|
Okay, sounds reasonable. Let me know when you need help with this (in some parts of the ecosystem). I will at least handle Trixi.jl etc. |
|
Everything should already be updated by now. But there may be a few places, we'll have to see when the depwarns start throwing. |
|
No hard feelings (in fact, I'm absurdly grateful for having access to all of these packages!), but this change unexpectedly broke my code (as an indirect user of this package via Even though a fix was easy after pinpointing the cause, I want to voice my opinion that major version bumps be considered as much as possible for changes that will break stuff for us downstream. In any case, I'm happy that the packages are constantly being improved—and thanks again for all the work! |
Where did the documentation show that? Anywhere that's shown I'll need to update. The documentation was always showing That said, it is hard to blame you though since we had a few libraries violate this ourselves in the tests. Since the symbols got ossified over 6 years, there were a few cases where people went "off script" and did a few things we did not expect, like defining their own return codes and modifying them into the solver, along with checking against |
https://diffeq.sciml.ai/stable/types/ode_types/#Solution-Type is still using the |
|
Thanks, updating the docs for that in #318 |
I think I found a way that is relatively safe. In all of our code throughout SciML, I noticed that the only thing that was truly done was
sol.retcode == :Success, etc. in which case a relatively small amount of functions put over a retcode enum could be non-breaking to all functional uses of the previous retcode. If this is the case, we may finally have a good way to upgrade the one piece I find most hideous in the interface.Fixes SciML/DifferentialEquations.jl#867