Создание и компиляция функций (build_function)
В любой момент вызываемые функции могут быть сгенерированы из IR Symbolics с помощью Symbolics.toexpr
. При этом выполняется определенная очистка для возвращения выражения без лишних частей, что обычно соответствует выражениям, которые можно написать в функциях, например для решателей дифференциальных уравнений или библиотек оптимизации. Эти функции можно автоматически распараллелить. Они также могут специализировать такие типы Julia, как статические массивы и разреженные матрицы.
Основным процессом компиляции IR Symbolics является build_function
. build_function
принимает операцию или AbstractArray
операций и генерирует компилируемую версию модели для численных решателей. Форма этого вывода зависит от target
. По умолчанию целевой объект выводит код Julia, но доступны и другие форматы, такие как C, Stan и MATLAB. Они могут быть сгенерированы как выражения, которые затем могут быть вычислены в вызываемую функцию, либо могут быть вызваны компиляторы для соответствующих целевых объектов для непосредственного возвращения дескриптора функции.
build_function
#
Symbolics.build_function
— Function
build_function
Генерирует пригодную для численного использования функцию из Symbolics Num
.
build_function(ex, args...;
expression = Val{true},
target = JuliaTarget(),
parallel=nothing,
kwargs...)
Аргументы
-
ex
: компилируемоеNum
-
args
: аргументы функции -
expression
: следует ли генерировать код или генерировать скомпилированную форму. По умолчаниюexpression = Val{true}
, что означает, что возвращается код функции. ЕслиVal{false}
, возвращаемое значение компилируется.
Именованные аргументы
-
target
: выходной объект процесса компиляции. Возможные значения:-
JuliaTarget
: генерирует функцию Julia -
CTarget
: генерирует функцию C -
StanTarget
: генерирует функцию для компиляции с использованием языка вероятностного программирования Stan -
MATLABTarget
: генерирует анонимную функция для использования в средах MATLAB и Octave
-
-
parallel
: тип параллелизма, который следует использовать в генерируемой функции. Значение по умолчанию —SerialForm()
, т. е. параллелизм отсутствует, еслиex
— это единственное выражение или массив, содержащий не более 1500 ненулевых выражений. Еслиex
является массивом, содержащим более 1500 ненулевых выражений, используетсяShardedForm(80, 4)
. Дополнительные сведения оShardedForm
см. ниже. Обратите внимание, что параллельные формы не экспортируются и поэтому должны быть выбраны какSymbolics.SerialForm()
. Вот возможные варианты.-
SerialForm()
: последовательное выполнение. -
ShardedForm(cutoff, ncalls)
: делит выходную функцию на подфункции. which contain at mostcutoff
number of outputrhss
. These sub-functions are called by the top-level function that buildfunction returns. This helps in reducing the compile time of the generated function. -
MultithreadedForm()
: многопоточное выполнение со статическим разделением, равномерно распределяющим количество выражений на поток. splitting the number of expressions per thread.
-
-
fname
: используется некоторыми целевыми объектами для имени функции в целевом пространстве.
Обратите внимание, что не все целевые объекты построения поддерживают полный интерфейс компиляции. Более подробные сведения см. в документации по конкретному целевому объекту.
Определения, относящиеся к конкретным целевым объектам
#
Symbolics._build_function
— _Method
_build_function(target::JuliaTarget, rhss::AbstractArray, args...;
conv=toexpr,
expression = Val{true},
expression_module = @__MODULE__(),
checkbounds = false,
postprocess_fbody=ex -> ex,
linenumbers = false,
outputidxs=nothing,
skipzeros = false,
force_SA = false,
wrap_code = (nothing, nothing),
fillzeros = skipzeros && !(rhss isa SparseMatrixCSC),
states = LazyState(),
iip_config = (true, true),
parallel=nothing, cse = false, kwargs...)
Целевой объект функции построения: 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...)
Генерирует функцию Julia, которая может быть использована для дальнейших вычислений. Если expression=Val{false}, возвращается функция Julia, которая использует RuntimeGeneratedFunctions.jl, чтобы исключить проблемы с «возрастом мира».
Если rhss
является скаляром, генерируемая функция — это функция со скалярным выводом. В противном случае, если это AbstractArray
, выводом являются две функции, одна из которых предназначена для вывода AbstractArray не на месте, а вторая является изменяемой. Выводимые функции соответствуют заданному порядку аргументов, т. е. f(u,p,args…) для функций не на месте и скалярных функций и f!(du,u,p,args..)
для версии на месте.
Специальные именованные аргументы
-
parallel
: тип параллелизма, который следует использовать в генерируемой функции. Значение по умолчанию —SerialForm()
, т. е. параллелизм отсутствует. Обратите внимание, что параллельные формы не экспортируются и поэтому должны быть выбраны какSymbolics.SerialForm()
. Вот возможные варианты.-
SerialForm()
: последовательное выполнение. -
ShardedForm(cutoff, ncalls)
: делит выходную функцию на подфункции. which contain at mostcutoff
number of outputrhss
. These sub-functions are called by the top-level function that buildfunction returns. -
MultithreadedForm()
: многопоточное выполнение со статическим разделением, равномерно распределяющим количество выражений на поток. splitting the number of expressions per thread.
-
-
conv
: функция преобразования символьных типов в выражения. По умолчанию используется функцияtoexpr
. -
checkbounds
: включать ли проверку границ внутри сгенерированной функции. Значение по умолчанию — false, означающее, что применяется@inbounds
. -
linenumbers
: определяет, сохранять ли в сгенерированном выражении функции номера строк. Значение по умолчанию — true. -
convert_oop
: определяет, должна ли версия OOP пытаться преобразовать выходные данные в соответствии с типом первых входных данных. Полезно для таких случаев, как использование массивов LabelledArray или других типов массивов, которые несут дополнительную информацию. Значение по умолчанию — true. -
force_SA
: возвращает выходные данные версию OOP в виде StaticArray. По умолчанию имеет значениеfalse
и выводит статический массив, если первый аргумент является статическим массивом. -
skipzeros
: нужно ли пропускать заполнение нулей в версии на месте, если функция заполнения равна 0. -
fillzeros
: нужно ли выполнятьfill(out,0)
перед вычислениями, чтобы обеспечить безопасность при работе сskipzeros
.
#
Symbolics._build_function
— _Method
Целевой объект функции построения: 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)
Создает функцию C на месте. Работает только в массивах уравнений. Если expression == Val{false}
, то создается функция на C, затем она компилируется и возвращается лямбда этой скомпилированной функции. Компиляцией управляют следующие специальные именованные аргументы.
-
libpath: путь для хранения двоичного файла. По умолчанию используется временный путь.
-
compiler: какой компилятор C следует использовать. По умолчанию используется :gcc, который на данный момент является единственным доступным вариантом.
#
Symbolics._build_function
— _Method
Целевой объект функции построения: 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])
Создает функцию Stan на месте, совместимую с решателями дифференциальных уравнений Stan. В отличие от других целевых объектов построения, этот требует (vs, ps, iv) в качестве аргументов функции. Работает только в массивах уравнений.
#
Symbolics._build_function
— _Method
Целевой объект функции построения: 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])
Создает анонимную функцию @(t,rhsnames[1]) не на месте, которая будет использоваться в MATLAB. Она совместима с решателями дифференциальных уравнений MATLAB. Работает только в выражениях и массивах выражений.