@floop begin s₁ = initialization of s₁ s₂ # pre-initialized variable ... for x in xs, ... ... end end
@floop begin ... end expects a (possibly empty) series of assignments or variable declaration (as in
s₂ above) followed by a
When there is no induction variables,
begin ... end can be omitted:
@floop for x in xs, ... ... end
@reduce for parallel execution:
@floop for x in xs, ... ... @reduce ... end
@floop can also take an
executor argument (which should be an instance of executor such as
DistributedEx) or a
nothing (indicating an appropriate parallel executor):
@floop executor for x in xs, ... ... @reduce ... end
See the module docstring of
FLoops for examples.
@reduce() do (acc₁ [= init₁]; x₁), ..., (accₙ [= initₙ]; xₙ) ... end @reduce(acc₁ ⊗₁= x₁, ..., accₙ ⊗ₙ= xₙ) @reduce(acc₁ .⊗₁= x₁, ..., accₙ .⊗ₙ= xₙ) @reduce(acc₁ = ⊗₁(init₁, x₁), ..., accₙ = ⊗ₙ(initₙ, xₙ)) @reduce(acc₁ .= (⊗₁).(init₁, x₁), ..., accₙ = (⊗ₙ).(initₙ, xₙ))
Declare how accumulators are updated in the sequential basecase and how the resulting accumulators from two basecases are combined.
xᵢ must be symbols except for
xᵢ of the last three forms in which an expression can be used at
In the first form,
function ((acc₁, acc₂, ..., accₙ), (x₁, x₂, ..., xₙ)) ... # body of the `do` block return (acc₁, acc₂, ..., accₙ) end
should be an associative function.
In the last three forms, every binary operation
⊗ᵢ should be an associative function.
initᵢ is specified, the tuple
(init₁, init₂, ..., initₙ) should be the identify of the related associative function.
accᵢ = initᵢ is evaluated for each basecase (each
Task) in the beginning.
Consider a loop with the following form
@floop for ... # code computing (x₁, x₂, ..., xₙ) @reduce() do (acc₁ = init₁; x₁), ..., (accₙ = initₙ; xₙ) # code updating (acc₁, acc₂, ..., accₙ) using (x₁, x₂, ..., xₙ) end end
This is converted to
acc₁ = init₁ ... accₙ = initₙ for ... # code computing (x₁, x₂, ..., xₙ) # code updating (acc₁, acc₂, ..., accₙ) using (x₁, x₂, ..., xₙ) end
(acc₁, acc₂, ..., accₙ) of each basecase. The accumulators
accᵢ of two basecases are combined using "code updating
(acc₁, acc₂, ..., accₙ) using
(x₁, x₂, ..., xₙ)" where
(x₁, x₂, ..., xₙ) are replaced with
(acc₁, acc₂, ..., accₙ) of the next basecase. Note that "code computing
(x₁, x₂, ..., xₙ)" is not used for combining the basecases.
@reduce() do (vmax=-Inf; v), (imax=0; i) if isless(vmax, v) vmax = v imax = i end end @reduce(s += y, p *= y) @reduce(xs = append!!(EmptyVector(), x), ys = append!!(EmptyVector(), y))
@init begin pv₁ = init₁ ... pvₙ = initₙ end
Initialize private variables
pvᵢ with initializer expression
initᵢ for each task. This can be used for mutating objects in a data race-free manner.
An executor controls how a given
@floop is executed. FLoops.jl re-exports
DistributedEx executors from Transducers.jl.
@flooptutorials on executors
- Executor section in Transducers.jl's glossary.
- How is a parallel
@floopexecuted? What is the scheduling strategy?
Set assistant mode; i.e., what to do when FLoops.jl finds a problematic usage pattern.
:ignore: do nothing
:warn: print warning once
:warn_always: print warning always
:error: throw an error
FLoops.assistant(false) is equivalent to
FLoops.assistant(true) is equivalent to