ParallelUtilities.jl
ParallelUtilities.AbstractConstrainedProduct — TypeAbstractConstrainedProduct{T, N, Q}Supertype of ProductSplit and ProductSection.
ParallelUtilities.BroadcastFunction — TypeBroadcastFunction(f)Construct a binary function that evaluates f.(x, y) given the arguments x and y.
The function BroadcastFunction(f) is equivalent to Base.BroadcastFunction(f) on Julia versions 1.6 and above.
Examples
julia> ParallelUtilities.BroadcastFunction(+)(ones(3), ones(3))
3-element Vector{Float64}:
2.0
2.0
2.0ParallelUtilities.BroadcastStack — TypeBroadcastStack(f, dims)(x::AbstractArray, y::AbstractArray)Construct a binary function that stacks its arguments along dims, with overlapping indices I being replaced by f(x[I], y[I]). The arguments x and y must both be n-dimensional arrays that have identical axes along all dimensions aside from those specified by dims. The axes of the result along each dimensions d in dims would be union(axes(x, d), axes(y, d)). Along the other dimensions the result has the same axes as x and y.
If the resulting axes along the concatenated dimensions are not 1-based, one might require an offset array package such as OffsetArrays.jl.
Examples
julia> A = ones(2)*2
2-element Vector{Float64}:
2.0
2.0
julia> B = ones(3)*3
3-element Vector{Float64}:
3.0
3.0
3.0
julia> ParallelUtilities.BroadcastStack(min, 1)(A, B)
3-element Vector{Float64}:
2.0
2.0
3.0
julia> A = ones(2,2)*2
2×2 Matrix{Float64}:
2.0 2.0
2.0 2.0
julia> B = ones(2,3)*3
2×3 Matrix{Float64}:
3.0 3.0 3.0
3.0 3.0 3.0
julia> ParallelUtilities.BroadcastStack(+, 2)(A, B)
2×3 Matrix{Float64}:
5.0 5.0 3.0
5.0 5.0 3.0ParallelUtilities.Commutative — TypeCommutativeDeclare a reduction operator to be commutative in its arguments. No check is performed to ascertain if the operator is indeed commutative.
ParallelUtilities.Flip — TypeFlip(f)Flip the arguments of a binary function f, so that Flip(f)(x, y) == f(y,x).
Examples
julia> flip1 = ParallelUtilities.Flip(vcat);
julia> flip1(2, 3)
2-element Vector{Int64}:
3
2Two flips pop the original function back:
julia> flip2 = ParallelUtilities.Flip(flip1);
julia> flip2(2, 3)
2-element Vector{Int64}:
2
3ParallelUtilities.ProductSection — TypeProductSection{T, N, Q<:NTuple{N,AbstractRange}}Iterator that loops over a specified section of the outer product of ranges in. If the ranges are strictly increasing, the iteration will be in reverse - lexicographic order. Given N ranges, each element returned by the iterator will be a tuple of length N with one element from each range.
See also: ProductSplit
ParallelUtilities.ProductSection — MethodProductSection(iterators::Tuple{Vararg{AbstractRange}}, inds::AbstractUnitRange)Construct a ProductSection iterator that represents a 1D view of the outer product of the ranges provided in iterators, with the range of indices in the view being specified by inds.
Examples
julia> p = ParallelUtilities.ProductSection((1:3, 4:6), 5:8);
julia> collect(p)
4-element Vector{Tuple{Int64, Int64}}:
(2, 5)
(3, 5)
(1, 6)
(2, 6)
julia> collect(p) == collect(Iterators.product(1:3, 4:6))[5:8]
trueParallelUtilities.ProductSplit — TypeProductSplit{T, N, Q<:NTuple{N,AbstractRange}}Iterator that loops over a section of the outer product of ranges. If the ranges are strictly increasing, the iteration is in reverse - lexicographic order. Given N ranges, each element returned by the iterator will be a tuple of length N with one element from each range.
See also: ProductSection
ParallelUtilities.ProductSplit — MethodProductSplit(iterators::Tuple{Vararg{AbstractRange}}, np::Integer, p::Integer)Construct a ProductSplit iterator that represents the outer product of the iterators split over np workers, with this instance reprsenting the values on the p-th worker.
p here refers to the rank of the worker, and is unrelated to the worker ID obtained by executing myid() on that worker.
Examples
julia> ParallelUtilities.ProductSplit((1:2, 4:5), 2, 1) |> collect
2-element Vector{Tuple{Int64, Int64}}:
(1, 4)
(2, 4)
julia> ParallelUtilities.ProductSplit((1:2, 4:5), 2, 2) |> collect
2-element Vector{Tuple{Int64, Int64}}:
(1, 5)
(2, 5)ParallelUtilities.broadcastinplace — Methodbroadcastinplace(f, ::Val{N}) where {N}Construct a binary operator that evaluates f.(x, y) and overwrites the Nth argument with the result. For N == 1 this evaluates x .= f.(x, y), whereas for N == 2 this evaluates y .= f.(x, y).
Examples
julia> op = ParallelUtilities.broadcastinplace(+, Val(1));
julia> x = ones(3); y = ones(3);
julia> op(x, y)
3-element Vector{Float64}:
2.0
2.0
2.0
julia> x # overwritten
3-element Vector{Float64}:
2.0
2.0
2.0ParallelUtilities.childindex — Methodchildindex(ps::AbstractConstrainedProduct, ind)Return a tuple containing the indices of the individual AbstractRanges corresponding to the element that is present at index ind in the outer product of the ranges.
The index ind corresponds to the outer product of the ranges, and not to ps.
Examples
julia> iters = (1:5, 2:4, 1:3);
julia> ps = ParallelUtilities.ProductSplit(iters, 7, 1);
julia> ind = 6;
julia> cinds = ParallelUtilities.childindex(ps, ind)
(1, 2, 1)
julia> v = collect(Iterators.product(iters...));
julia> getindex.(iters, cinds) == v[ind]
trueSee also: childindexshifted
ParallelUtilities.childindexshifted — Methodchildindexshifted(ps::AbstractConstrainedProduct, ind)Return a tuple containing the indices in the individual iterators given an index of ps.
If the iterators (r1, r2, ...) are used to generate ps, then return (i1, i2, ...) such that ps[ind] == (r1[i1], r2[i2], ...).
Examples
julia> iters = (1:5, 2:4, 1:3);
julia> ps = ParallelUtilities.ProductSplit(iters, 7, 3);
julia> psind = 4;
julia> cinds = ParallelUtilities.childindexshifted(ps, psind)
(3, 1, 2)
julia> getindex.(iters, cinds) == ps[psind]
trueSee also: childindex
ParallelUtilities.dropleading — Methoddropleading(ps::AbstractConstrainedProduct{T, N, NTuple{N,AbstractUnitRange}}) where {T,N}Return a ProductSection leaving out the first iterator contained in ps. The range of values of the remaining iterators in the resulting ProductSection will be the same as in ps.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:5, 2:4, 1:3), 7, 3);
julia> collect(ps)
7-element Vector{Tuple{Int64, Int64, Int64}}:
(5, 4, 1)
(1, 2, 2)
(2, 2, 2)
(3, 2, 2)
(4, 2, 2)
(5, 2, 2)
(1, 3, 2)
julia> ParallelUtilities.dropleading(ps) |> collect
3-element Vector{Tuple{Int64, Int64}}:
(4, 1)
(2, 2)
(3, 2)ParallelUtilities.elementwisemax! — Functionelementwisemax!(x, y)Binary reduction operator that performs an elementwise max and stores the result inplace in x. The value of x is overwritten in the process.
Functionally elementwisemax!(x, y) is equivalent to x .= max.(x, y).
The operator is assumed to be commutative.
ParallelUtilities.elementwisemin! — Functionelementwisemin!(x, y)Binary reduction operator that performs an elementwise min and stores the result inplace in x. The value of x is overwritten in the process.
Functionally elementwisemin!(x, y) is equivalent to x .= min.(x, y).
The operator is assumed to be commutative.
ParallelUtilities.elementwiseproduct! — Functionelementwiseproduct!(x, y)Binary reduction operator that performs an elementwise product and stores the result inplace in x. The value of x is overwritten in the process.
Functionally elementwiseproduct!(x, y) is equivalent to x .= x .* y.
The operator is assumed to be commutative.
ParallelUtilities.elementwisesum! — Functionelementwisesum!(x, y)Binary reduction operator that performs an elementwise product and stores the result inplace in x. The value of x is overwritten in the process.
Functionally elementwisesum!(x, y) is equivalent to x .= x .+ y.
The operator is assumed to be commutative.
ParallelUtilities.extrema_commonlastdim — Methodextrema_commonlastdim(ps::AbstractConstrainedProduct{T, N, <:NTuple{N,AbstractUnitRange}}) where {T,N}Return the reverse - lexicographic extrema of values taken from ranges contained in ps, where the pairs of ranges are constructed by concatenating the ranges along each dimension with the last one.
For two ranges this simply returns ([first(ps)], [last(ps)]).
Examples
julia> ps = ParallelUtilities.ProductSplit((1:3, 4:7, 2:7), 10, 2);
julia> collect(ps)
8-element Vector{Tuple{Int64, Int64, Int64}}:
(3, 6, 2)
(1, 7, 2)
(2, 7, 2)
(3, 7, 2)
(1, 4, 3)
(2, 4, 3)
(3, 4, 3)
(1, 5, 3)
julia> ParallelUtilities.extrema_commonlastdim(ps)
([(1, 2), (6, 2)], [(3, 3), (5, 3)])ParallelUtilities.extremadims — Methodextremadims(ps::AbstractConstrainedProduct)Compute the extrema of the sections of all the ranges contained in ps. Functionally this is equivalent to
map(i -> extrema(ps, dims = i), 1:_niterators(ps))but it is implemented more efficiently.
Returns a Tuple containing the (min, max) pairs along each dimension, such that the i-th index of the result contains the extrema along the section of the i-th range contained locally.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:2, 4:5), 2, 1);
julia> collect(ps)
2-element Vector{Tuple{Int64, Int64}}:
(1, 4)
(2, 4)
julia> ParallelUtilities.extremadims(ps)
((1, 2), (4, 4))ParallelUtilities.extremaelement — Methodextremaelement(ps::AbstractConstrainedProduct; dims::Integer)Compute the extrema of the section of the range number dims contained in ps.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:2, 4:5), 2, 1);
julia> collect(ps)
2-element Vector{Tuple{Int64, Int64}}:
(1, 4)
(2, 4)
julia> ParallelUtilities.extremaelement(ps, dims = 1)
(1, 2)
julia> ParallelUtilities.extremaelement(ps, dims = 2)
(4, 4)ParallelUtilities.indexinproduct — Methodindexinproduct(iterators::NTuple{N, AbstractRange}, val::NTuple{N, Any}) where {N}Return the index of val in the outer product of iterators. Return nothing if val is not present.
Examples
julia> iterators = (1:4, 1:3, 3:5);
julia> val = (2, 2, 4);
julia> ind = ParallelUtilities.indexinproduct(iterators, val)
18
julia> collect(Iterators.product(iterators...))[ind] == val
trueParallelUtilities.localindex — Methodlocalindex(ps::AbstractConstrainedProduct{T}, val::T) where {T}Return the index of val in ps. Return nothing if the value is not found.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:3, 4:5:20), 3, 2);
julia> collect(ps)
4-element Vector{Tuple{Int64, Int64}}:
(2, 9)
(3, 9)
(1, 14)
(2, 14)
julia> ParallelUtilities.localindex(ps, (3, 9))
2ParallelUtilities.masternodeindex — Methodmasternodeindex(tree::SegmentedOrderedBinaryTree, p)Given the top worker p on one node, compute the serial order of the host that it corresponds to.
ParallelUtilities.maximumelement — Methodmaximumelement(ps::AbstractConstrainedProduct; dims::Integer)Compute the maximum value of the section of the range number dims contained in ps.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:2, 4:5), 2, 1);
julia> collect(ps)
2-element Vector{Tuple{Int64, Int64}}:
(1, 4)
(2, 4)
julia> ParallelUtilities.maximumelement(ps, dims = 1)
2
julia> ParallelUtilities.maximumelement(ps, dims = 2)
4ParallelUtilities.minimumelement — Methodminimumelement(ps::AbstractConstrainedProduct; dims::Integer)Compute the minimum value of the section of the range number dims contained in ps.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:2, 4:5), 2, 1);
julia> collect(ps)
2-element Vector{Tuple{Int64, Int64}}:
(1, 4)
(2, 4)
julia> ParallelUtilities.minimumelement(ps, dims = 1)
1
julia> ParallelUtilities.minimumelement(ps, dims = 2)
4ParallelUtilities.nelements — Methodnelements(ps::AbstractConstrainedProduct{T, N, <:NTuple{N,AbstractUnitRange}}; dims::Integer) where {T,N}Compute the number of unique values in the section of the dims-th range contained in ps.
The function is defined currently only for iterator products of AbstractUnitRanges.
Examples
julia> ps = ParallelUtilities.ProductSplit((1:5, 2:4, 1:3), 7, 3);
julia> collect(ps)
7-element Vector{Tuple{Int64, Int64, Int64}}:
(5, 4, 1)
(1, 2, 2)
(2, 2, 2)
(3, 2, 2)
(4, 2, 2)
(5, 2, 2)
(1, 3, 2)
julia> ParallelUtilities.nelements(ps, dims = 1)
5
julia> ParallelUtilities.nelements(ps, dims = 2)
3
julia> ParallelUtilities.nelements(ps, dims = 3)
2ParallelUtilities.pmapbatch — Methodpmapbatch(f, [pool::AbstractWorkerPool], iterators...)Carry out a pmap with the iterators divided evenly among the available workers.
See also: pmapreduce
ParallelUtilities.pmapbatch_productsplit — Methodpmapbatch_productsplit(f, [pool::AbstractWorkerPool], iterators...)Carry out a pmap with the outer product of iterators divided evenly among the available workers. The function f must accept a collection of Tuples.
See also: pmapbatch, pmapreduce_productsplit
ParallelUtilities.pmapreduce — Methodpmapreduce(f, op, [pool::AbstractWorkerPool], iterators...; reducekw...)Evaluate a parallel mapreduce over the elements from iterators. For multiple iterators, apply f elementwise.
The keyword arguments reducekw are passed on to the reduction.
See also: pmapreduce_productsplit
ParallelUtilities.pmapreduce_productsplit — Methodpmapreduce_productsplit(f, op, [pool::AbstractWorkerPool], iterators...; reducekw...)Evaluate a parallel mapreduce over the outer product of elements from iterators. The product of iterators is split over the workers available, and each worker is assigned a section of the product. The function f should accept a single argument that is a collection of Tuples.
The keyword arguments reducekw are passed on to the reduction.
See also: pmapreduce
ParallelUtilities.procrange_recast — Methodprocrange_recast(ps::AbstractConstrainedProduct, np_new::Integer)Return the range of processor ranks that would contain the values in ps if the iterators used to construct ps were split across np_new processes.
Examples
julia> iters = (1:10, 4:6, 1:4);
julia> ps = ParallelUtilities.ProductSplit(iters, 5, 2); # split across 5 processes initially
julia> ParallelUtilities.procrange_recast(ps, 10) # If `iters` were spread across 10 processes
3:4ParallelUtilities.procrange_recast — Methodprocrange_recast(iterators::Tuple{Vararg{AbstractRange}}, ps, np_new::Integer)Return the range of processor ranks that would contain the values in ps if the outer produce of the ranges in iterators is split across np_new workers.
The values contained in ps should be a subsection of the outer product of the ranges in iterators.
Examples
julia> iters = (1:10, 4:6, 1:4);
julia> ps = ParallelUtilities.ProductSplit(iters, 5, 2);
julia> ParallelUtilities.procrange_recast(iters, ps, 10)
3:4ParallelUtilities.whichproc — Methodwhichproc(iterators::Tuple{Vararg{AbstractRange}}, val::Tuple, np::Integer)Return the processor rank that will contain val if the outer product of the ranges contained in iterators is split evenly across np processors.
Examples
julia> iters = (1:4, 2:3);
julia> np = 2;
julia> ParallelUtilities.ProductSplit(iters, np, 2) |> collect
4-element Vector{Tuple{Int64, Int64}}:
(1, 3)
(2, 3)
(3, 3)
(4, 3)
julia> ParallelUtilities.whichproc(iters, (2, 3), np)
2ParallelUtilities.whichproc_localindex — Methodwhichproc_localindex(iterators::Tuple{Vararg{AbstractRange}}, val::Tuple, np::Integer)Return (rank, ind), where rank is the rank of the worker that val will reside on if the outer product of the ranges in iterators is spread over np workers, and ind is the index of val in the local section on that worker.
Examples
julia> iters = (1:4, 2:8);
julia> np = 10;
julia> ParallelUtilities.whichproc_localindex(iters, (2, 4), np)
(4, 1)
julia> ParallelUtilities.ProductSplit(iters, np, 4) |> collect
3-element Vector{Tuple{Int64, Int64}}:
(2, 4)
(3, 4)
(4, 4)