From ddb0440966625b0f3494de0f910706c96bd4375f Mon Sep 17 00:00:00 2001 From: Andinus Date: Thu, 4 Nov 2021 15:46:20 +0530 Subject: Process iterations in parallel --- lib/Fornax/CLI.rakumod | 114 +++++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/lib/Fornax/CLI.rakumod b/lib/Fornax/CLI.rakumod index 1cf518d..43a5fe3 100644 --- a/lib/Fornax/CLI.rakumod +++ b/lib/Fornax/CLI.rakumod @@ -16,6 +16,7 @@ proto MAIN(|) is export { unless so @*ARGS { put $*USAGE; exit }; {*} } multi sub MAIN( File $input, #= fornax format file (solved) IO() :$out = '/tmp', #= output directory (default: /tmp) + Int() :$batch = 4, #= batch size (generate frames in parallel) Rat() :$frame-rate = 1, #= frame rate (default: 1) Bool :$skip-video, #= skip video solution Bool :$verbose = True, #= verbosity @@ -75,64 +76,73 @@ multi sub MAIN( enum IterStatus ; + my Promise @p; for @lines.skip.kv -> $idx, $iter is rw { - my IterStatus $status; - given $iter.substr(0, 1) { - when '|' { $status = Completed } - when '!' { $status = Blocked } - default { $status = Walking } - }; - - # Remove marker. - $iter .= substr(1) if $status == Completed|Blocked; - - put "[fornax] $idx $iter $status" if $verbose; - - my @grid = $iter.comb.rotor: %meta; - warn "Invalid grid: $idx $iter $status" unless @grid.elems == %meta; - - given Cairo::Image.create( - Cairo::FORMAT_ARGB32, %CANVAS, %CANVAS - ) { - given Cairo::Context.new($_) { - # Paint the entire canvas white. - .rgb: |%C; - .rectangle(0, 0, %CANVAS, %CANVAS); - .fill; - .stroke; - - for ^%meta -> $r { - for ^%meta -> $c { - my Int @target = %excess div 2 + $c * $side, - %excess div 2 + $r * $side, - $side, $side; - - .rectangle: |@target; - given @grid[$r][$c] -> $cell { - when $cell eq $CUR { - .rgba: |%C, 0.56; - .rgba: |%C, 0.72 if $status == Completed; - .rgba: |%C, 0.72 if $status == Blocked; - } - when $cell eq $VIS { - .rgba: |%C, 0.64; - .rgba: |%C, 0.96 if $status == Completed; - .rgba: |%C, 0.96 if $status == Blocked; + # Wait until all scheduled jobs are finished, then empty the + # array and continue. + if @p.elems == $batch { + while @p.grep(*.status).elems !== $batch {}; + @p = []; + } + + push @p, start { + my IterStatus $status; + given $iter.substr(0, 1) { + when '|' { $status = Completed } + when '!' { $status = Blocked } + default { $status = Walking } + }; + + # Remove marker. + $iter .= substr(1) if $status == Completed|Blocked; + + put "[fornax] $idx $iter $status" if $verbose; + + my @grid = $iter.comb.rotor: %meta; + warn "Invalid grid: $idx $iter $status" unless @grid.elems == %meta; + + given Cairo::Image.create( + Cairo::FORMAT_ARGB32, %CANVAS, %CANVAS + ) { + given Cairo::Context.new($_) { + # Paint the entire canvas white. + .rgb: |%C; + .rectangle(0, 0, %CANVAS, %CANVAS); + .fill; + + for ^%meta -> $r { + for ^%meta -> $c { + my Int @target = %excess div 2 + $c * $side, + %excess div 2 + $r * $side, + $side, $side; + + .rectangle: |@target; + + given @grid[$r][$c] -> $cell { + when $cell eq $CUR { + .rgba: |%C, 0.56; + .rgba: |%C, 0.72 if $status == Completed; + .rgba: |%C, 0.72 if $status == Blocked; + } + when $cell eq $VIS { + .rgba: |%C, 0.72; + .rgba: |%C, 0.96 if $status == Completed; + .rgba: |%C, 0.96 if $status == Blocked; + } + when $cell eq $BLOK { .rgba: |%C, 0.56 } + when $cell eq $DEST { .rgb: |%C } + default { .rgba: |%C, 0.08 } } - when $cell eq $BLOK { .rgba: |%C, 0.48 } - when $cell eq $DEST { .rgb: |%C } - default { .rgba: |%C, 0.08 } - } - .fill :preserve; + .fill :preserve; - .rgb: |%C; - .rectangle: |@target; - .stroke; + .rgb: |%C; + .stroke; + } } } + .write_png("%s/%08d.png".sprintf: $output, $idx); + .finish; } - .write_png("%s/%08d.png".sprintf: $output, $idx); - .finish; } } -- cgit 1.4.1-2-gfad0