Function Building and Compilation (build_function)
At any time, callable functions can be generated from Symbolics IR by using Symbolics.toexpr
. This performs some cleaning to return an expression without extraneous pieces that commonly matches expressions one would write in functions like those for differential equation solvers and optimization libraries. These functions can be automatically parallelize and specialize on Julia types like static arrays and sparse matrices.
The core compilation process of Symbolics IR is build_function
. build_function
takes an operation or an AbstractArray
of operations and generates a compilable version of the model for numerical solvers. The form of this output is dependent on the target
. By default, the target outputs Julia code, but other formats, such as C, Stan, and MATLAB are available. These can be generated as expressions which can then be evaluated into a callable function, or the compilers for the respective targets can be invoked to directly give back the function handle.
build_function
Symbolics.build_function
— Functionbuild_function
Generates a numerically-usable function from a Symbolics Num
.
build_function(ex, args...;
expression = Val{true},
target = JuliaTarget(),
kwargs...)
Arguments:
ex
: TheNum
to compileargs
: The arguments of the functionexpression
: Whether to generate code or whether to generate the compiled form. By default,expression = Val{true}
, which means that the code for the function is returned. IfVal{false}
, then the returned value is compiled.
Keyword Arguments:
target
: The output target of the compilation process. Possible options are:JuliaTarget
: Generates a Julia functionCTarget
: Generates a C functionStanTarget
: Generates a function for compiling with the Stan probabilistic programming languageMATLABTarget
: Generates an anonymous function for use in MATLAB and Octave environments
fname
: Used by some targets for the name of the function in the target space.
Note that not all build targets support the full compilation interface. Check the individual target documentation for details.
Target-Specific Definitions
Symbolics._build_function
— MethodBuild function target: JuliaTarget
function _build_function(target::JuliaTarget, rhss, args...;
conv = toexpr, expression = Val{true},
checkbounds = false,
linenumbers = false,
headerfun = addheader, outputidxs=nothing,
convert_oop = true, force_SA = false,
skipzeros = outputidxs===nothing,
fillzeros = skipzeros && !(typeof(rhss)<:SparseMatrixCSC),
parallel=SerialForm(), kwargs...)
Generates a Julia function which can then be utilized for further evaluations. If expression=Val{false}, the return is a Julia function which utilizes RuntimeGeneratedFunctions.jl in order to be free of world-age issues.
If the rhss
is a scalar, the generated function is a function with a scalar output, otherwise if it's an AbstractArray
, the output is two functions, one for out-of-place AbstractArray output and a second which is a mutating function. The outputted functions match the given argument order, i.e., f(u,p,args...) for the out-of-place and scalar functions and f!(du,u,p,args..)
for the in-place version.
Special Keyword Argumnets:
parallel
: The kind of parallelism to use in the generated function. Defaults toSerialForm()
, i.e. no parallelism. Note that the parallel forms are not exported and thus need to be chosen likeSymbolics.SerialForm()
. The choices are:SerialForm()
: Serial execution.MultithreadedForm()
: Multithreaded execution with a static split, evenly splitting the number of expressions per thread.
conv
: The conversion function of symbolic types to Expr. By default this uses thetoexpr
function.checkbounds
: For whether to enable bounds checking inside of the generated function. Defaults to false, meaning that@inbounds
is applied.linenumbers
: Determines whether the generated function expression retains the line numbers. Defaults to true.convert_oop
: Determines whether the OOP version should try to convert the output to match the type of the first input. This is useful for cases like LabelledArrays or other array types that carry extra information. Defaults to true.force_SA
: Forces the output of the OOP version to be a StaticArray. Defaults tofalse
, and outputs a static array when the first argument is a static array.skipzeros
: Whether to skip filling zeros in the in-place version if the filling function is 0.fillzeros
: Whether to performfill(out,0)
before the calculations to ensure safety withskipzeros
.
Symbolics._build_function
— MethodBuild function target: CTarget
function _build_function(target::CTarget, eqs::Array{<:Equation}, args...;
conv = toexpr, expression = Val{true},
fname = :diffeqf,
lhsname=:du,rhsnames=[Symbol("RHS$i") for i in 1:length(args)],
libpath=tempname(),compiler=:gcc)
This builds an in-place C function. Only works on arrays of equations. If expression == Val{false}
, then this builds a function in C, compiles it, and returns a lambda to that compiled function. These special keyword arguments control the compilation:
- libpath: the path to store the binary. Defaults to a temporary path.
- compiler: which C compiler to use. Defaults to :gcc, which is currently the only available option.
Symbolics._build_function
— MethodBuild function target: StanTarget
function _build_function(target::StanTarget, eqs::Array{<:Equation}, vs, ps, iv;
conv = toexpr, expression = Val{true},
fname = :diffeqf, lhsname=:internal_var___du,
rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])
This builds an in-place Stan function compatible with the Stan differential equation solvers. Unlike other build targets, this one requestions (vs, ps, iv) as the function arguments. Only allowed on arrays of equations.
Symbolics._build_function
— MethodBuild function target: MATLABTarget
function _build_function(target::MATLABTarget, eqs::Array{<:Equation}, args...;
conv = toexpr, expression = Val{true},
lhsname=:internal_var___du,
rhsnames=[:internal_var___u,:internal_var___p,:internal_var___t])
This builds an out of place anonymous function @(t,rhsnames[1]) to be used in MATLAB. Compatible with the MATLAB differential equation solvers. Only allowed on expressions, and arrays of expressions.