Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 70 additions & 55 deletions src/run/fractal_flame.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -97,16 +98,18 @@ 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))
push!(exs, :(fx_offset = fx_offset))
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
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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

Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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)

Expand Down
22 changes: 15 additions & 7 deletions src/structs/fractal_executable/hutchinson.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
26 changes: 26 additions & 0 deletions src/structs/fractal_operators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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