Создание и компиляция функций (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): делит выходную функцию на подфункции, содержащие не болееcutoffколичества выходныхrhss. Эти подфункции вызываются функцией верхнего уровня, которую возвращает функцияbuild. Это помогает сократить время компиляции генерируемой функции. -
MultithreadedForm(): многопоточное выполнение со статическим разделением, равномерно распределяющим количество выражений на поток.
-
-
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 mostcutoffnumber 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. Работает только в выражениях и массивах выражений.