-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
@register_symbolic
takes "very long" to compile as the number of arguments increases
#2251
Comments
@register_symbolic
takes "very long" to compile as the number of arguments increase@register_symbolic
takes "very long" to compile as the number of arguments increases
There is an exponential growth in the number of functions being registered by doing so. I'm not sure that is very easy without the user restricting dispatches. |
I don't fully understand what is happening under the hood, but is there a specific reason it has been configured like this? If being able to specify the type of each argument is the fix for this issue, then it is worthwhile in my opinion. |
You can already specify the type of each argument, which is why I suggested that. It has to be like that otherwise the general form has dispatch ambiguities. |
Oh I didn't realize that was possible. Would the code look something like this example?
|
You have to just not tag what would be symbolic: @register_symbolic test_func(a, b::Float64, c::Float64, d::Float64, e::Float64) allows a symbolic |
So my goal is for all the arguments to be symbolic, actually. So 5 symbolic arguments for this example. Once I surpass 5 args in my src code, the compile time skyrockets. So now I am wondering if your suggestion is applicable for bypassing this issue. |
The problem is that it has to do all combinations: @register_symbolic test_func(a::Num, b::Float64, c::Float64, d::Float64, e::Float64)
@register_symbolic test_func(a::Float64, b::Num, c::Float64, d::Float64, e::Float64)
... If you know you'll only ever do all of them symbolic, and not mixing in floating point numbers, that could possibly work. |
Ok I see the pattern. Yes my goal is for all the function arguments to be symbolic such that it can be used in an MTK equation. Thanks, I will try this and report back! Perhaps there is a way to make this generic such that functions of larger argument quantities can be registered, assuming all symbolic args? I would say this is the reason I made this issue. |
@shashi what do you think about a macro that only registers the all symbolic version? |
Why not just define the method instead? |
I don't think we want people touching internals and building |
It's like quoting in Julia. It should be more encouraged. It's not great that we have a state of affairs where this becomes "touching the internals". I think the weird bit is that there are 2 kinds of Symbolic types: For this case, I would want to add this: julia> using Symbolics: has_symwrapper, wrapper_type, Symbolic, wrap, unwrap
julia> symbolic_t(T) = has_symwrapper(T) ? Union{wrapper_type(T), Symbolic{<:T}} : Symbolic{<:T}
symbolic_t (generic function with 1 method)
julia> R=symbolic_t(Real)
Union{Num, Symbolic{<:Real}}
Or just take the last line if you're not going to write this as a macro, Then you can define: julia> f(w::R,x::R,y::R,z::R) = wrap(term(f, unwrap.((w, x, y, z))...)) |
Add docs on it? |
Sorry for the delay. I am not versed in all the nuances here so I am trying my best to understand; I'm not sure the process is clear to me yet. This is what I am interpreting 1.You are suggesting to define the type Really, what I am interested in is this: I want to be able to register a function with any number of arguments that returns a scalar value or vector of values. This currently works for a function with all scalar argument types up to a limit of <= 5 args without considerable compile time. How do we enable this? Taking it one step further: I think we should even be able to register any function that might have a variety of argument types as long as the function returns a scalar value or vector of values. For example, one of the inputs is a string that is used in an if-else statement internal to the function. Another example, we register a function with methods that are dispatched based on subtype; each method returns a value but the operation is different based on the passed in type. Another case, one of the inputs is a vector of values. I assume the all-symbolic-inputs-case might be the most common case and is less to bite off, but I have come across the more complicated case already. Curious to hear your thoughts. Thanks, Chris |
The right hand side of that function will make a term that is a scalar use
to make it a scalar.
You don't need this. |
Hello,
I have noticed a limitation of the
@register_symbolic
is that the compile time, when you try to register a function with typically >= 5 arguments, is "very long". It seems to increase exponentially with more arguments which can equate to 100s to 1000s of seconds of wait time when compiling.It would be awesome if this could be improved. I have found the register capability to be extremely useful/powerful for integrating external functions that are difficult to write symbolically or cannot be written symbolically; however, I have registered functions that simply cannot be written with less arguments and the compile time is long enough that it difficult to work with.
Thanks, Chris
The text was updated successfully, but these errors were encountered: