# Symbolics build\_function and usage

**URL:** <https://discourse.julialang.org/t/symbolics-build-function-and-usage/101005>\
**Category:** Performance\
**Tags:** symbolics, runtimegeneratedfunc\
**Created:** [June 30, 2023, 2:42am UTC](https://discourse.julialang.org/t/symbolics-build-function-and-usage/101005 "2023-06-30T02:42:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Whyborn](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/whyborn/32/34755_2.png) [@Whyborn](https://discourse.julialang.org/u/Whyborn)\
**Post date:** [June 30, 2023, 2:42am UTC](https://discourse.julialang.org/t/symbolics-build-function-and-usage/101005/1 "2023-06-30T02:42:26Z")

</div>

Hi,

I’m having some trouble using the build\_function tool within the `Symbolics` package, and a question about how build\_function works.

The issue I am having is that executing the function generated by build\_function consumes so much RAM that the process is either killed, or it simply crashes my machine (relatively recent machine with 16GB of RAM). The `Num` I am generating a function for is a sparse matrix of order ~1000x1000 with ~0.1% density, fairly similar to the sparse jacobian in the Automated Sparse Parallelism example in the documentation. The input arguments are a set of Arrays with 2 constants. In abbreviated form:

```julia
@variables u_m[1:5, 1:20, 1:20] v_m[1:5, 1:20, 1:20] w_m[1:5, 1:20, 1:20] b c
A # 2280x2280 SparseMatrixCSC{Num, Int64} which contains only the previously defined variables and number literals

# This seems to work without issue
Afunc = eval(build_function(A, u_m, v_m, w_m, b, c, parallel = Symbolics.MultithreadedForm())[2])

# Generate some dummy data
AMat = similar(A, Float64)
u = rand(Float64, 5, 20, 20); v = rand(Float64, 5, 20, 20); w = rand(Float64, 5, 20, 20)
bval = 100; cval = 10

# This eventually kills the process/crashes the machine
Afunc(AMat, u, v, w, bval, cval)

```

Is the compilation process expected to be that expensive? Or am I misusing the function in some way? Would using `parallel = Symbolics.SerialForm()` be likely to help reduce the cost?

My question is then regarding the use of the `expression` keyword in `build_function`. With the default `Val{true}`, it returns the generated code which we then `eval()`. But with `Val{false}`, the return value is “compiled”- what does that actually mean in this context? How does it make any of the type inferences required to compile a fast function?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 5, 2023, 10:59pm UTC](https://discourse.julialang.org/t/symbolics-build-function-and-usage/101005/2 "2023-08-05T22:59:29Z")

</div>

> [@Whyborn](#):
>
> Is the compilation process expected to be that expensive?

For a big function, yes. It scalarizes the function. For a better scaling you may need to use some other form of compilation like the JuliaSimCompiler.

> **[Home · JuliaSimCompiler.jl](https://help.juliahub.com/juliasimcompiler/dev/)**
>
> Documentation for JuliaSimCompiler.jl.

> [@Whyborn](#):
>
> Would using `parallel = Symbolics.SerialForm()` be likely to help reduce the cost?

No, Symbolics scalarizes. You’d need to use the alternative compiler stuff in order to avoid that.

> [@Whyborn](#):
>
> My question is then regarding the use of the `expression` keyword in `build_function`. With the default `Val{true}`, it returns the generated code which we then `eval()`. But with `Val{false}`, the return value is “compiled”- what does that actually mean in this context?

It returns a RuntimeGeneratedFunction, similar to the `eval`’d form but without potential world age issues.

> [@Whyborn](#):
>
> How does it make any of the type inferences required to compile a fast function?

It does type inference like any other function in Julia.
