-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The limit of the number of generated functions? #59
Comments
It seems to be a Julia bug: JuliaLang/julia#35580 I'd suggest your slightly changing your implementation accordingly, or you can provide me an MME so that I can give your advice about how-to stuffs. |
Thanks for the pointer. I checked related issues a bit and believe the MWE from this issue is same as my setting. |
I'd suspect such an issue occurs due to overflows occurred in c part, because GG extensively uses of type level things and is likely to hit some boundaries. You might break your expressions into smaller parts and then runtime-generate them. |
I feel what you propose here can potentially alleviate the issue. using GeneralizedGenerated: mk_function
module GeneratedFunctions end
function rand_ex()
u = rand()
c = randn()
if u < 0.5
return :(m1 + m2 + r² + $c)
else
return :(m1 * m2 / r² * $c)
end
end
function gen_f_mkfunc(ex)
return mk_function(GeneratedFunctions, :((m1, m2, r²) -> $ex))
end
function main(N::Int)
for i in 1:N
m1, m2, r² = rand(3)
ex = rand_ex()
f_mkfunc = gen_f_mkfunc(ex)
f_mkfunc(m1, m2, r²)
end
end
main(500) # successful
main(5_000) # failed By in my case, it's bit hard for me to break my expression into smaller parts, |
Hi, I usually see people use runtime-generate functions only once, which looks quite abusing to me. |
The purpose of my generated function call is to evaluate how good the (random) function is, on some observed data. function main(N::Int)
m1, m2, r² = rand(3)
f = m1 * m2 / r²
for i in 1:N
ex = rand_ex()
f_mkfunc = gen_f_mkfunc(ex)
f_est = f_mkfunc(m1, m2, r²)
loss = sqrt((f - f_est)^2)
end
end |
This code runs and finishes instantly. Could you tell me if it is adequate? And if not, why? using GeneralizedGenerated: mk_function
function rand_f()
u = rand()
c = randn()
if u < 0.5
(m1, m2, r²) -> m1 + m2 + r² + c
else
(m1, m2, r²) -> m1 * m2 / r² * c
end
end
function main(N::Int)
for i in 1:N
m1, m2, r² = rand(3)
f_mkfunc = rand_f()
f_mkfunc(m1, m2, r²)
end
end
main(500) # successful
main(5_000) # |
You didn't use |
This is not really what I'm looking for. PS: This is replying to #59 (comment) |
For a more complete example function main(N::Int)
m1, m2, r² = rand(3)
f = m1 * m2 / r²
best_loss = Inf
best_func = nothing
for i in 1:N
ex = rand_ex()
f_mkfunc = gen_f_mkfunc(ex)
f_est = f_mkfunc(m1, m2, r²)
loss = sqrt((f - f_est)^2)
if loss < best_loss
best_loss = loss
best_func = f_mkfunc
end
end
# finding the best_func is my goal
end |
Hi, I guess this is adequate: function rand_f()
u = rand()
c = randn()
if u < 0.5
(m1, m2, r²) -> m1 + m2 + r² + c
else
(m1, m2, r²) -> m1 * m2 / r² * c
end
end
function main(N::Int)
m1, m2, r² = rand(3)
f = m1 * m2 / r²
best_loss = Inf
best_func = nothing
for i in 1:N
f_mkfunc = rand_f()
f_est = f_mkfunc(m1, m2, r²)
loss = sqrt((f - f_est)^2)
if loss < best_loss
best_loss = loss
best_func = f_mkfunc
end
end
best_func
end
f = main(4000) |
The issue for me is that I can't actually write down the using ExprOptimization
using ExprOptimization.ProbabilisticExprRules: RuleNode, mindepth_map, ProbabilisticGrammar
G = @grammar begin
Real = m1
Real = m2
Real = r²
Real = Real + Real
Real = Real - Real
Real = Real * Real
Real = Real / Real
end
PCFG = ProbabilisticGrammar(G)
function rand_f()
tree = rand(RuleNode, PCFG, :Real, mindepth_map(G), 5)
ex = get_executable(tree, G)
return mk_function(GeneratedFunctions, :((m1, m2, r²) -> $ex))
end Again, in practice my |
Hi @xukai92 , I hope you don't mind my jumping in on this... In my experience, most applications are a natural fit for either GG or https://github.com/SciML/RuntimeGeneratedFunctions.jl
I use both, choosing based on the kind of problem. Have you tried RGF for this case? |
function rand_f()
tree = rand(RuleNode, PCFG, :Real, mindepth_map(G), 5)
ex = get_executable(tree, G)
return @RuntimeGeneratedFunction :((m1, m2, r²) -> $ex)
end
julia> [rand_f()(1,2,3) for j in 1:2000][end-10:end]
11-element Vector{Real}:
1
1
1
-2.6666666666666665
4.0
3
3
0.5
2.0
1
2 I prefer GG when you're writing a few functions that will be evaluated many times. But for a very large number of functions, RGF can handle simpler cases without needing to build as many types. |
Thanks a lot @cscherrer for pointing RuntimeGeneratedFunctions.jl, which I didn't know before!
Thanks for also making this comment here. Thanks again! |
Thanks a lot @cscherrer ! RGF is absolutely a right way here. Besides, you @xukai92 do not need to generate functions so many times. You only need to generate one function: function rand_ex()
tree = rand(RuleNode, PCFG, :Real, mindepth_map(G), 5)
ex = get_executable(tree, G)
return ex
end
for j = 1:2000
f_mkfunc_ex = rand_ex()
f_est = eval(:(
let (m1, m2, r²) = $(((m1, m2, r²))
$f_mkfunc_ex
end))
loss = sqrt((f - f_est)^2)
if loss < best_loss
best_loss = loss
best_ex = f_mkfunc_ex
end
end
best_func = @RuntimeGeneratedFunction :((m1, m2, r²) -> $best_ex) |
This is now directly supported by GG v0.3 |
I meet a weird situation:
My code with GG.jl works fine as long as I only generated around
< 400
functions usingmk_functions
.When the number of total functions generated reaches a fewer than 400, I see this error:
(Just copying-pasting a few lines in the head of the error message; the complete version is a bit long.)
Is this a known issue of GG.jl or Julia?
The text was updated successfully, but these errors were encountered: