Skip to content
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

feat: indexing rework with new SymbolicIndexingInterface #532

Merged
merged 1 commit into from
Dec 12, 2023

Conversation

AayushSabharwal
Copy link
Member

No description provided.

return [xi[s] for xi in x]
end

Base.@propagate_inbounds function Base.getindex(x::AbstractEnsembleSolution,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am very happy you were able to get rid of this.

Comment on lines 428 to 432
function SymbolicIndexingInterface.is_variable(A::DEIntegrator, sym)
is_variable(A.f, sym)
end

function SymbolicIndexingInterface.variable_index(A::DEIntegrator, sym)
variable_index(A.f, sym)
end

function SymbolicIndexingInterface.variable_symbols(A::DEIntegrator)
variable_symbols(A.f)
end

function SymbolicIndexingInterface.is_parameter(A::DEIntegrator, sym)
is_parameter(A.f, sym)
end

function SymbolicIndexingInterface.parameter_index(A::DEIntegrator, sym)
parameter_index(A.f, sym)
end

function SymbolicIndexingInterface.is_independent_variable(A::DEIntegrator, sym)
is_independent_variable(A.f, sym)
end

function SymbolicIndexingInterface.is_observed(A::DEIntegrator, sym)
return !is_variable(A, sym) && !is_parameter(A, sym) && !is_independent_variable(A, sym) && symbolic_type(sym) == ScalarSymbolic()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem ideal. It seems like there should possibly be an easier way to define all of these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off the top of my head, I guess SII could have a function symbolic_indexing_fallback(sys) which specifies what to fallback the methods to. All the other methods then have a default implementation along the lines of is_variable(symbolic_indexing_fallback(sys), sym)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds great!


function SymbolicIndexingInterface.is_variable(fn::AbstractSciMLFunction, sym)
has_sys(fn) && return is_variable(fn.sys, sym)
has_syms(fn) && return Symbol(sym) in fn.syms
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we can get rid of this part? i.e. in the SciMLFunction constructor we could turn syms/paramsyms into a sys with the appropriate behavior.

Comment on lines -97 to +169
if has_sys(sol.prob.f)
DiffEqArray{typeof(A).parameters[1:4]..., typeof(sol.prob.f.sys), typeof(observed),
typeof(p)}(A.u,
A.t,
sol.prob.f.sys,
observed,
p)
else
syms = hasproperty(sol.prob.f, :syms) && sol.prob.f.syms !== nothing ?
[sol.prob.f.syms[idxs]] : nothing
DiffEqArray(A.u, A.t, syms, getindepsym(sol), observed, p)
end
return DiffEqArray(A.u, A.t, p, sol)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is happy-making :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My favourite part of this PR was removing all the getindex methods for AbstractTimeseriesSolution.

@oscardssmith
Copy link
Contributor

Overall, this looks great! I think there might be a little more cleanup possible by getting rid of syms/paramsyms and always using sys, but this already is a substantial clean up.

@AayushSabharwal
Copy link
Member Author

Did not mean to start a new review, I'm not sure how that happened

@ChrisRackauckas
Copy link
Member

Needs a rebase?

- Implement SII for solutions, problems, SciMLFunctions, integrators
- Solution indexing falls back to AbstractVectorOfArray indexing
- remove issymbollike
- remove has_static_variable
- add new parameter indexing
- fix adjoint definitions
- Remove syms, paramsyms, indepsym from SciMLFunctions, use SymbolCache in place of
  f.sys instead
@AayushSabharwal
Copy link
Member Author

Yep, almost done

@AayushSabharwal
Copy link
Member Author

Rebased

@AayushSabharwal
Copy link
Member Author

Should SciMLBase also export getp and setp?

Copy link

codecov bot commented Dec 12, 2023

Codecov Report

Attention: 258 lines in your changes are missing coverage. Please review.

Comparison is base (9fdb9c8) 25.91% compared to head (bbba9c6) 0.00%.

Files Patch % Lines
src/integrator_interface.jl 0.00% 67 Missing ⚠️
src/solutions/solution_interface.jl 0.00% 67 Missing ⚠️
src/scimlfunctions.jl 0.00% 42 Missing ⚠️
src/problems/problem_interface.jl 0.00% 34 Missing ⚠️
src/symbolic_utils.jl 0.00% 24 Missing ⚠️
src/solutions/ode_solutions.jl 0.00% 8 Missing ⚠️
src/solutions/optimization_solutions.jl 0.00% 6 Missing ⚠️
ext/SciMLBaseZygoteExt.jl 0.00% 3 Missing ⚠️
src/ensemble/ensemble_solutions.jl 0.00% 3 Missing ⚠️
ext/SciMLBaseChainRulesCoreExt.jl 0.00% 2 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #532       +/-   ##
==========================================
- Coverage   25.91%   0.00%   -25.92%     
==========================================
  Files          53      53               
  Lines        4140    4034      -106     
==========================================
- Hits         1073       0     -1073     
- Misses       3067    4034      +967     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ChrisRackauckas ChrisRackauckas merged commit dc1c83d into SciML:master Dec 12, 2023
34 of 80 checks passed
@hexaeder
Copy link

In my code I make heavy use of odefunction.syms to get the symbols for plotting purposes, find the right indices in the u vector, and so on. Is there a recommended way to get the symbols now?
I found odefunction.sys.variables but this again uses some internals that might change in the future...

@AayushSabharwal
Copy link
Member Author

The recommended way is to import SymbolicIndexingInterface and use variable_symbols(odefunction)

@ChrisRackauckas
Copy link
Member

Indeed. The main purpose of this transition is to establish a well-defined interface that this is all based off of, rather than having to know internals voodoo for what's setup related to symbolic indexing. This is https://github.com/SciML/SymbolicIndexingInterface.jl, with our downstream packages implemented the documented interface https://docs.sciml.ai/SymbolicIndexingInterface/stable/api/ (and tutorials coming soon). If you stick to the documented interface and version control with respect to that, you will get guarantees of correctness in the setup which relying on internals could never give you. Hopefully this makes everything easier to maintain in the future, not just for us but for anyone like you who downstream is trying to use/extend the symbolic indexing in any way.

@hexaeder
Copy link

Thanks a lot for the details, I'll look into that package! Pleas don't get me wrong, I did not mean to complain about the "breakage" at all -- that's what you get for using internals. I really like the transition to more and more tested and guaranteed interfaces. Luckily we have funding for a major rewrite next your so we can base our package on modern SciML standards removing many of those 3 year old hacks...

@ChrisRackauckas
Copy link
Member

Yes no worries. Interfaces are great, but you definitely have to rip off a few bandaids to put one in place where there wasn't one before. I mean, .syms served us well from 2016-2022, so it did its job 😅. I couldn't have predicted we needed an interface back when it was put in. But now we are in a different place and really formalizing what's going on is the only way for people to make use of all of its functionality correctly and in a way that allows maximum performance.

@Datseris
Copy link
Contributor

Indeed. The main purpose of this transition is to establish a well-defined interface that this is all based off of, rather than having to know internals voodoo for what's setup related to symbolic indexing. This is https://github.com/SciML/SymbolicIndexingInterface.jl, with our downstream packages implemented the documented interface https://docs.sciml.ai/SymbolicIndexingInterface/stable/api/ (and tutorials coming soon). If you stick to the documented interface and version control with respect to that, you will get guarantees of correctness in the setup which relying on internals could never give you. Hopefully this makes everything easier to maintain in the future, not just for us but for anyone like you who downstream is trying to use/extend the symbolic indexing in any way.

Great, thanks for the work @AayushSabharwal and @ChrisRackauckas and everyone else working on this. I was just about to interface ODESystem in DynamicalSystems.jl and allow using symbols for e.g., set_parameter or continuation. Now I'll start learning and doing it the proper way!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants