Symbolics build_function and usage


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:

@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?

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.

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

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

It does type inference like any other function in Julia.

1 Like