diff --git a/src/run/fractal_flame.jl b/src/run/fractal_flame.jl index 00797bf..7dc374a 100644 --- a/src/run/fractal_flame.jl +++ b/src/run/fractal_flame.jl @@ -19,14 +19,14 @@ #------------------------------------------------------------------------------# export run! -@generated function call_pt_fx(fxs, pt, frame, kwargs, idx) +@generated function call_pt_fx(fxs, pt, frame, kwargs, idx, fidx) exs = Expr[] push!(exs, :(@inline)) push!(exs, Expr(:inbounds, true)) for i = 1:length(fxs.parameters) ex = quote - if idx == $i - pt = fxs[$i](pt.y, pt.x, frame; kwargs[$i]...) + if fidx == $i + pt = fxs[$i](pt.y, pt.x, frame; kwargs[idx]...) end end push!(exs, ex) @@ -39,16 +39,17 @@ end # These functions essentially unroll the loops in the kernel because of a # known julia bug preventing us from using for i = 1:10... -@inline @generated function pt_loop(fxs, fid, pt, frame, fnums, kwargs; - bit_offset = UInt(0), fx_offset = 0) +@inline @generated function pt_loop(fxs, fid, pt, frame, fnums, + call_set, kwargs; + bit_offset = UInt(0), fx_offset = 0) exs = Expr[] push!(exs, :(@inline)) push!(exs, :(bit_offset = bit_offset)) push!(exs, :(fx_offset = fx_offset)) for i = 1:length(fnums.parameters) ex = quote - idx = decode_fid(fid, bit_offset, fnums[$i]) + fx_offset - pt = call_pt_fx(fxs, pt, frame, kwargs, idx) + idx = decode_fid(fid, bit_offset, fnums[$i])+fx_offset + pt = call_pt_fx(fxs, pt, frame, kwargs, idx, call_set[idx]) bit_offset += ceil(UInt,log2(fnums[$i])) fx_offset += fnums[$i] end @@ -63,13 +64,13 @@ end return Expr(:block, exs...) end -@inline @generated function call_clr_fx(fxs, pt, clr, frame, kwargs, idx) +@inline @generated function call_clr_fx(fxs, pt, clr, frame, kwargs, idx, fidx) exs = Expr[] push!(exs, :(@inline)) for i = 1:length(fxs.parameters) ex = quote - if idx == $i - clr = call_clr_fx(fxs[$i], pt, clr, frame, kwargs[$i]) + if fidx == $i + clr = call_clr_fx(fxs[$i], pt, clr, frame, kwargs[idx]) end end push!(exs, ex) @@ -84,7 +85,7 @@ end end @inline @generated function call_clr_fx(fx::Tuple, pt::Point2D, clr, - frame, kwargs::Tuple) + frame, kwargs::Tuple) exs = Expr[] push!(exs, :(@inline)) for i = 1:length(fx.parameters) @@ -97,8 +98,9 @@ end return Expr(:block, exs...) end -@inline @generated function clr_loop(fxs, fid, pt, clr, frame, fnums, kwargs; - bit_offset = UInt(0), fx_offset = 0) +@inline @generated function clr_loop(fxs, fid, pt, clr, frame, fnums, + clr_call_set, kwargs; + bit_offset = UInt(0), fx_offset = 0) exs = Expr[] push!(exs, :(@inline)) push!(exs, :(bit_offset = bit_offset)) @@ -106,7 +108,8 @@ end for i = 1:length(fnums.parameters) ex = quote idx = decode_fid(fid, bit_offset, fnums[$i]) + fx_offset - clr = call_clr_fx(fxs, pt, clr, frame, kwargs, idx) + clr = call_clr_fx(fxs, pt, clr, frame, kwargs, idx, + clr_call_set[idx]) bit_offset += ceil(UInt,log2(fnums[$i])) fx_offset += fnums[$i] end @@ -122,24 +125,27 @@ end end @inline @generated function semi_random_loop!(layer_values, layer_reds, layer_greens, - layer_blues, layer_alphas, priorities, - fid, fxs, clr_fxs, pt, clr, - frame, fnums, kwargs, clr_kwargs, - probs, bounds, dims, bin_widths, - iteration, num_ignore, overlay; - fx_offset = 0) + layer_blues, layer_alphas, + priorities, fid, fxs, call_set, + clr_fxs, clr_call_set, pt, clr, + frame, fnums, kwargs, clr_kwargs, + probs, bounds, dims, bin_widths, + iteration, num_ignore, overlay; + fx_offset = 0) exs = Expr[] push!(exs, :(@inline)) push!(exs, :(temp_prob = 0.0)) push!(exs, :(fx_max_range = fx_offset + sum(fnums))) push!(exs, :(curr_pt = pt)) push!(exs, :(curr_clr = clr)) - for i = 1:length(fxs.parameters) + for i = 1:length(call_set.parameters) ex = quote if fx_offset + 1 <= $i <= fx_max_range - curr_pt = fxs[$i](curr_pt.y, curr_pt.x, frame; kwargs[$i]...) - curr_clr = clr_fxs[$i](curr_pt.y, curr_pt.x, curr_clr, frame; - clr_kwargs[$i]...) + idx = call_set[$i] + curr_pt = fxs[idx](curr_pt.y, curr_pt.x, frame; kwargs[$i]...) + idx = clr_call_set[$i] + curr_clr = clr_fxs[idx](curr_pt.y, curr_pt.x, curr_clr, frame; + clr_kwargs[$i]...) temp_prob += probs[$i] if isapprox(temp_prob, 1.0) || temp_prob >= 1.0 output!(layer_values, layer_reds, layer_greens, @@ -226,7 +232,6 @@ end end end - # couldn't figure out how to get an n-dim version working for GPU @inline function on_image(p_y, p_x, bounds, dims) flag = true @@ -262,20 +267,21 @@ function iterate!(layer::FractalLayer, H::Hutchinson, n, kernel! = fx(backend, layer.params.numthreads) if isnothing(H_post) - kernel!(layer.particles, n, H.fxs, combine(H.kwargs, H.fis), - H.color_fxs, combine(H.color_kwargs, H.color_fis), + kernel!(layer.particles, n, H.fxs, H.call_set, combine(H.kwargs, H.fis), + H.color_fxs, H.color_call_set, + combine(H.color_kwargs, H.color_fis), H.prob_set, H.fnums, layer.values, layer.reds, layer.greens, layer.blues, layer.alphas, layer.priorities, frame, bounds, Tuple(bin_widths), layer.params.num_ignore, max_range, layer.params.overlay, ndrange=size(layer.particles)[1]) else - kernel!(layer.particles, n, H.fxs, combine(H.kwargs, H.fis), - H.color_fxs, combine(H.color_kwargs, H.color_fis), - H.prob_set, H.fnums, - H_post.fxs, combine(H_post.kwargs, H_post.fis), - H_post.color_fxs, combine(H_post.color_kwargs, - H_post.color_fis), + kernel!(layer.particles, n, H.fxs, H.call_set, combine(H.kwargs, H.fis), + H.color_fxs, H.color_call_set, + combine(H.color_kwargs, H.color_fis), H.prob_set, H.fnums, + H_post.fxs, H_post.call_set, combine(H_post.kwargs, H_post.fis), + H_post.color_fxs, H_post.color_call_set, + combine(H_post.color_kwargs, H_post.color_fis), H_post.prob_set, H_post.fnums, layer.values, layer.reds, layer.greens, layer.blues, layer.alphas, layer.priorities, @@ -285,8 +291,8 @@ function iterate!(layer::FractalLayer, H::Hutchinson, n, end end -@kernel function naive_chaos_kernel!(points, n, H_fxs, H_kwargs, - H_clrs, H_clr_kwargs, +@kernel function naive_chaos_kernel!(points, n, H_fxs, H_call_set, H_kwargs, + H_clrs, H_clr_call_set, H_clr_kwargs, H_probs, H_fnums, layer_values, layer_reds, layer_greens, layer_blues, layer_alphas, priorities, @@ -317,10 +323,11 @@ end fid = UInt(1) end - pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], + pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], H_call_set, H_kwargs; fx_offset) clr = clr_loop(H_clrs, fid, recenter(pt, bounds, bin_widths), - clr, frame, H_fnums[j], H_clr_kwargs; fx_offset) + clr, frame, H_fnums[j], H_clr_call_set, + H_clr_kwargs; fx_offset) fid = (fid+1) << bit_offset+1 @@ -338,11 +345,13 @@ end end -@kernel function semi_random_chaos_kernel!(points, n, H_fxs, H_kwargs, - H_clrs, H_clr_kwargs, - H_probs, H_fnums, - H_post_fxs, H_post_kwargs, - H_post_clrs, H_post_clr_kwargs, +@kernel function semi_random_chaos_kernel!(points, n, H_fxs, H_call_set, + H_kwargs, H_clrs, H_clr_call_set, + H_clr_kwargs, H_probs, H_fnums, + H_post_fxs, H_post_call_set, + H_post_kwargs, H_post_clrs, + H_post_clr_call_set, + H_post_clr_kwargs, H_post_probs, H_post_fnums, layer_values, layer_reds, layer_greens, layer_blues, @@ -374,16 +383,18 @@ end fid = UInt(1) end - pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], H_kwargs; - fx_offset) + pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], H_call_set, + H_kwargs; fx_offset) clr = clr_loop(H_clrs, fid, recenter(pt, bounds, bin_widths), - clr, frame, H_fnums[j], H_clr_kwargs; fx_offset) + clr, frame, H_fnums[j], H_clr_call_set, + H_clr_kwargs; fx_offset) fid = (fid+1) << bit_offset semi_random_loop!(layer_values, layer_reds, layer_greens, layer_blues, layer_alphas, priorities, fid, - H_post_fxs, H_post_clrs, + H_post_fxs, H_post_call_set, + H_post_clrs, H_post_clr_call_set, pt, clr, frame, H_post_fnums[j], H_post_kwargs, H_post_clr_kwargs, H_post_probs, bounds, dims, bin_widths, @@ -402,11 +413,12 @@ end end -@kernel function naive_chaos_kernel!(points, n, H_fxs, H_kwargs, - H_clrs, H_clr_kwargs, +@kernel function naive_chaos_kernel!(points, n, H_fxs, H_call_set, H_kwargs, + H_clrs, H_clr_call_set, H_clr_kwargs, H_probs, H_fnums, - H_post_fxs, H_post_kwargs, - H_post_clrs, H_post_clr_kwargs, + H_post_fxs, H_post_call_set, H_post_kwargs, + H_post_clrs, H_post_clr_call_set, + H_post_clr_kwargs, H_post_probs, H_post_fnums, layer_values, layer_reds, layer_greens, layer_blues, layer_alphas, priorities, @@ -449,17 +461,20 @@ end fid_2 = UInt(1) end - pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], H_kwargs; - fx_offset) + pt = pt_loop(H_fxs, fid, pt, frame, H_fnums[j], H_call_set, + H_kwargs; fx_offset) clr = clr_loop(H_clrs, fid, recenter(pt, bounds, bin_widths), - clr, frame, H_fnums[j], H_clr_kwargs; fx_offset) + clr, frame, H_fnums[j], H_clr_call_set, + H_clr_kwargs; fx_offset) - output_pt = pt_loop(H_post_fxs, fid, pt, frame, - H_post_fnums[j], H_post_kwargs; + output_pt = pt_loop(H_post_fxs, fid_2, pt, frame, + H_post_fnums[j], H_post_call_set, + H_post_kwargs; fx_offset = post_fx_offset) output_clr = clr_loop(H_post_clrs, fid_2, recenter(pt, bounds, bin_widths), clr, frame, H_post_fnums[j], + H_post_clr_call_set, H_post_clr_kwargs; fx_offset = post_fx_offset) diff --git a/src/structs/fractal_executable/hutchinson.jl b/src/structs/fractal_executable/hutchinson.jl index 0e90398..1943cee 100644 --- a/src/structs/fractal_executable/hutchinson.jl +++ b/src/structs/fractal_executable/hutchinson.jl @@ -2,31 +2,39 @@ export Hutchinson mutable struct Hutchinson <: FractalExecutable fxs::Tuple + call_set::Tuple kwargs::Tuple fis::Tuple color_fxs::Tuple + color_call_set::Tuple color_kwargs::Tuple color_fis::Tuple prob_set::Tuple fnums::Tuple end -Hutchinson() = Hutchinson((),(),(),(),(),(),(),()) +Hutchinson() = Hutchinson((),(),(),(),(),(),(),(),(),()) Base.length(H::Hutchinson) = length(H.fnums) function Hutchinson(fo::FractalOperator) - kwargs, fis, fxs, color_kwargs, color_fis, color_fxs, + kwargs, fis, fxs, color_kwargs, + color_fis, color_fxs, prob_set, fnums = extract_info(fo) - return Hutchinson(fxs, kwargs, fis, - color_fxs, color_kwargs, color_fis, + fxs, call_set = make_unique(fxs) + color_fxs, color_call_set = make_unique(color_fxs) + return Hutchinson(fxs, call_set, kwargs, fis, + color_fxs, color_call_set, color_kwargs, color_fis, prob_set, (fnums,)) end function Hutchinson(fos::T) where T <: Union{Tuple, Vector{FractalOperator}} - kwargs, fis, fxs, color_kwargs, color_fis, color_fxs, + kwargs, fis, fxs, + color_kwargs, color_fis, color_fxs, prob_set, fnums = extract_info(fos) - return Hutchinson(fxs, kwargs, fis, - color_fxs, color_kwargs, color_fis, + fxs, call_set = make_unique(fxs) + color_fxs, color_call_set = make_unique(color_fxs) + return Hutchinson(fxs, call_set, kwargs, fis, + color_fxs, color_call_set, color_kwargs, color_fis, prob_set, fnums) end diff --git a/src/structs/fractal_operators.jl b/src/structs/fractal_operators.jl index 20f82b2..79c5226 100644 --- a/src/structs/fractal_operators.jl +++ b/src/structs/fractal_operators.jl @@ -178,6 +178,8 @@ function flatten(kwargs::Tuple, fis::Tuple, fxs::Tuple, new_probs = (new_probs..., temp_probs...) new_fnums = (new_fnums..., temp_fnums...) end + #new_fxs, new_call_set = make_unique(new_fxs) + #new_color_fxs, new_color_call_set = make_unique(new_color_fxs) return (new_kwargs, new_fis, new_fxs, new_color_kwargs, new_color_fis, new_color_fxs, new_probs, fnums) @@ -208,3 +210,27 @@ end function extract_ops_info(op::FractalUserMethod) return (op.kwargs, op.fis, op.fx) end + +function make_unique(t::Tuple) + new_t, call_set = make_unique(t[1]) + count = length(new_t) + for i = 2:length(t) + temp_t, temp_set = make_unique(t[i]) + for j = 1:length(temp_t) + if in(temp_t[j], new_t) + idx = findfirst(isequal(temp_t[j]),new_t) + call_set = (call_set..., idx) + else + count += 1 + new_t = (new_t...,temp_t[j]) + call_set = (call_set..., count) + end + end + end + + return new_t, call_set +end + +function make_unique(a) + return (a,), (1,) +end