Julia provides @spawn
as a basic building block for parallelism and FLoops.jl provides generic parallel for
loop syntax. However, they are often too "low-level" as an API for building parallel programs. To make writing parallel programs simpler, Folds.jl and ThreadsX.jl provide basic "high-level" algorithms similar to Julia's Base
library as described below. High-level APIs can be used for expressing what you want to compute which aids not only understandability and maintainability of the program but also the efficiency of the program because the library implementers can use adequate strategy for how to compute the result.
If you are familiar with the functions listed in Folds.jl and ThreadsX.jl, no further explanations are required for start using them. However, since not all Base
functions are parallelizable, it may be hard to remember which functions are supported by these libraries. This how-to guide tries to provide a simple "guide map" for navigating the functions provided by Folds.jl and ThreadsX.jl, as summarized in the following picture:
TODO: cumprod!(ys)
-> cumprod!(ys, xs)
The above picture is only very superficially accurate and you may need to "unlearn" it to use these libraries in full extent. However, it is a good approximation for start using
map
-family)Given an array xs
with elements ...
Function | Returns |
---|---|
map(f, xs) | |
map!(f, ys, xs) | ditto, but stores the result in ys |
foreach(f, xs) | runs in parallel for side-effect |
TODO: explanations, examples, ...
reduce
-family)Function | Returns |
---|---|
reduce(⊗, xs) | |
sum(xs) | |
prod(xs) | |
all(xs) | |
any(xs) | |
count(xs) | |
maximum(xs) | |
minimum(xs) | |
extrema(xs) | (minimum(xs), maximum(xs)) |
issorted(xs) |
mapreduce
-family)Function | Returns |
---|---|
mapreduce(f, ⊗, xs) | |
sum(f, xs) | |
prod(f, xs) | |
all(f, xs) | |
any(f, xs) | |
count(f, xs) | |
maximum(f, xs) | |
minimum(f, xs) | |
extrema(f, xs) | (minimum(xs), maximum(xs)) |
issorted(xs; by = f) |
Function | Returns |
---|---|
findmax(f, xs) | (x, index) s.t. xs[index] == x == maximum(f, xs) |
findmin(f, xs) | (x, index) s.t. xs[index] == x == minimum(f, xs) |
argmax(f, xs) | x s.t. f(x) == maximum(f, xs) |
argmin(f, xs) | x s.t. f(x) == minimum(f, xs) |
findall(f, xs) | indices such that f(xs[i]) holds iff i in indices |
findfirst(f, xs) | first i s.t. f(xs[i]) holds; nothing if not found |
findlast(f, xs) | last i s.t. f(xs[i]) holds; nothing if not found |
accumulate
-family)Function | Returns |
---|---|
accumulate(⊗, xs) | |
accumulate!(⊗, ys, xs) | ditto, but stores the result in ys |
scan!(⊗, xs) | ditto, but stores the result in xs |
cumsum(xs) | |
cumsum!(ys, xs) | ditto, but stores the result in ys |
cumprod(xs) | |
cumprod!(ys, xs) | ditto, but stores the result in ys |
collect
-family)In above sections, we pretended that xs
is an array. However, there various collection of items in Julia. We can turn sufficiently well-behaving such collections into an array in parallel using Folds.collect
. It is also possible to collect only unique elements using Folds.unique
. The output data structure does not have to be an array. We can use Folds.set
to create a set of elements. If there is no need to preserve the ordering of the input, it is more efficient than Folds.unique
. Given a collection of Pair
s, we can use Folds.dict
to create a dictionary.
Function | Returns |
---|---|
collect(xs) | collect elements of xs into an array |
unique(xs) | collect unique elements of xs into an array, preserving the order |
set(xs) | collect elements of xs into a set |
dict(xs) | collect elements of xs into a dictionary |
xs = (f(y) for x in collection if p(x) for y in g(x))
# ---- ------- -------------
# mapping filtering flattening
See also: A quick introduction to data parallelism in Julia
ThreadsX.jl provides a similar interface like Folds.jl but it is specific to multi-core -based parallelism. Furthermore, it provides algorithms such as sort!
that cannot be easily expressed as a simple invocation of reduce
.
Folds.jl focuses on algorithms expressible in terms of a generalized reduce
.