How does RuntimeGeneratedFunction ensure that the correct dependency libraries are available?
This example compiles an expression which includes the constant twoπ
which is defined in IrrationalConstants.jl and used in DiffRules.jl. DiffRules is a direct dependency of my project, FastDifferentiation.jl, but IrrationalConstants is not.
My code does not import or export twoπ
. It is not defined in the REPL environment:
julia> twoπ
ERROR: UndefVarError: `twoπ` not defined
nor is it defined in FastDifferentiation:
julia> FastDifferentiation.twoπ
ERROR: UndefVarError: `twoπ` not defined
But somehow RuntimeGeneratedFunctions figures out that twoπ in the quoted expression is the value defined in IrrationalConstants instead of throwing a not defined exception:
julia> using FastDifferentiation
julia> @variables x
julia> f = mod2pi(x)
mod2pi(x)
julia> derivative([f],x)
1-element Vector{FastDifferentiation.Node}:
(if_else isinteger((x / twoπ)) NaN 1) #here twoπ is an element of the FastDifferentiation expression tree
julia> g = ans
1-element Vector{FastDifferentiation.Node}:
(if_else isinteger((x / twoπ)) NaN 1)
julia> h = make_function(g,[x,y])
RuntimeGeneratedFunction(#=in FastDifferentiation=#, #=using FastDifferentiation=#, :((input_variables,)->begin
#= c:\Users\seatt\source\FastDifferentiation.jl\src\CodeGeneration.jl:229 =#
#= c:\Users\seatt\source\FastDifferentiation.jl\src\CodeGeneration.jl:229 =# @inbounds begin
#= c:\Users\seatt\source\FastDifferentiation.jl\src\CodeGeneration.jl:230 =#
begin
result_element_type = promote_type(Float64, eltype(input_variables))
result = Array{result_element_type}(undef, (1,))
var"##227" = input_variables[1] / twoπ #here twoπ is in the quoted expression that I generate. But it is not prefixed with DiffRules or IrrationalConstants
var"##226" = isinteger(var"##227")
var"##225" = if var"##226"
#= c:\Users\seatt\source\FastDifferentiation.jl\src\CodeGeneration.jl:58 =#
begin
var"##s#228" = NaN
end
else
#= c:\Users\seatt\source\FastDifferentiation.jl\src\CodeGeneration.jl:60 =#
begin
var"##s#229" = 1
end
end
result[1] = var"##225"
return result
end
end
end))
julia> h([2*π])
1-element Vector{Float64}:
NaN
I want to ensure that when users call make_function it returns a function that will compile correctly regardless of what packages the user has loaded into their environment. It seems RuntimeGeneratedFunction is doing the right thing with twoπ
but I don’t understand how.