Skip to content

Commit 23c2bd7

Browse files
committed
DArray: Automatic partitioning, more constructors
Added AutoBlocks partitioner for automatic partitioning Added DArray/DVector/DMatrix constructor helpers Added methods for using AutoBlocks when partitioner is unspecified
1 parent 22e7422 commit 23c2bd7

File tree

8 files changed

+372
-181
lines changed

8 files changed

+372
-181
lines changed

src/array/alloc.jl

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,71 @@ function stage(ctx, a::AllocateArray)
3030
return DArray(a.eltype, a.domain, a.domainchunks, thunks, a.partitioning)
3131
end
3232

33-
function Base.rand(p::Blocks, eltype::Type, dims)
33+
const BlocksOrAuto = Union{Blocks{N} where N, AutoBlocks}
34+
35+
function Base.rand(p::Blocks, eltype::Type, dims::Dims)
3436
d = ArrayDomain(map(x->1:x, dims))
3537
a = AllocateArray(eltype, (_, x...) -> rand(x...), d, partition(p, d), p)
3638
return _to_darray(a)
3739
end
40+
Base.rand(p::BlocksOrAuto, T::Type, dims::Integer...) = rand(p, T, dims)
41+
Base.rand(p::BlocksOrAuto, T::Type, dims::Dims) = rand(p, T, dims)
42+
Base.rand(p::BlocksOrAuto, dims::Integer...) = rand(p, Float64, dims)
43+
Base.rand(p::BlocksOrAuto, dims::Dims) = rand(p, Float64, dims)
44+
Base.rand(::AutoBlocks, eltype::Type, dims::Dims) =
45+
rand(auto_blocks(dims), eltype, dims)
3846

39-
Base.rand(p::Blocks, t::Type, dims::Integer...) = rand(p, t, dims)
40-
Base.rand(p::Blocks, dims::Integer...) = rand(p, Float64, dims)
41-
Base.rand(p::Blocks, dims::Tuple) = rand(p, Float64, dims)
47+
function Base.randn(p::Blocks, eltype::Type, dims::Dims)
48+
d = ArrayDomain(map(x->1:x, dims))
49+
a = AllocateArray(eltype, (_, x...) -> randn(x...), d, partition(p, d), p)
50+
return _to_darray(a)
51+
end
52+
Base.randn(p::BlocksOrAuto, T::Type, dims::Integer...) = randn(p, T, dims)
53+
Base.randn(p::BlocksOrAuto, T::Type, dims::Dims) = randn(p, T, dims)
54+
Base.randn(p::BlocksOrAuto, dims::Integer...) = randn(p, Float64, dims)
55+
Base.randn(p::BlocksOrAuto, dims::Dims) = randn(p, Float64, dims)
56+
Base.randn(::AutoBlocks, eltype::Type, dims::Dims) =
57+
randn(auto_blocks(dims), eltype, dims)
4258

43-
function Base.randn(p::Blocks, eltype::Type, dims)
59+
function sprand(p::Blocks, eltype::Type, dims::Dims, sparsity::AbstractFloat)
4460
d = ArrayDomain(map(x->1:x, dims))
45-
a = AllocateArray(Float64, (_, x...) -> randn(x...), d, partition(p, d), p)
61+
a = AllocateArray(eltype, (_, T, _dims) -> sprand(T, _dims..., sparsity), d, partition(p, d), p)
4662
return _to_darray(a)
4763
end
48-
Base.randn(p::Blocks, t::Type, dims::Integer...) = randn(p, t, dims)
49-
Base.randn(p::Blocks, dims::Integer...) = randn(p, dims)
50-
Base.randn(p::Blocks, dims::Tuple) = randn(p, Float64, dims)
64+
sprand(p::BlocksOrAuto, T::Type, dims_and_sparsity::Real...) =
65+
sprand(p, T, dims_and_sparsity[1:end-1], dims_and_sparsity[end])
66+
sprand(p::BlocksOrAuto, T::Type, dims::Dims, sparsity::AbstractFloat) =
67+
sprand(p, T, dims, sparsity)
68+
sprand(p::BlocksOrAuto, dims_and_sparsity::Real...) =
69+
sprand(p, Float64, dims_and_sparsity[1:end-1], dims_and_sparsity[end])
70+
sprand(p::BlocksOrAuto, dims::Dims, sparsity::AbstractFloat) =
71+
sprand(p, Float64, dims, sparsity)
72+
sprand(::AutoBlocks, eltype::Type, dims::Dims, sparsity::AbstractFloat) =
73+
sprand(auto_blocks(dims), eltype, dims, sparsity)
5174

52-
function Base.ones(p::Blocks, eltype::Type, dims)
75+
function Base.ones(p::Blocks, eltype::Type, dims::Dims)
5376
d = ArrayDomain(map(x->1:x, dims))
5477
a = AllocateArray(eltype, (_, x...) -> ones(x...), d, partition(p, d), p)
5578
return _to_darray(a)
5679
end
57-
Base.ones(p::Blocks, t::Type, dims::Integer...) = ones(p, t, dims)
58-
Base.ones(p::Blocks, dims::Integer...) = ones(p, Float64, dims)
59-
Base.ones(p::Blocks, dims::Tuple) = ones(p, Float64, dims)
80+
Base.ones(p::BlocksOrAuto, T::Type, dims::Integer...) = ones(p, T, dims)
81+
Base.ones(p::BlocksOrAuto, T::Type, dims::Dims) = ones(p, T, dims)
82+
Base.ones(p::BlocksOrAuto, dims::Integer...) = ones(p, Float64, dims)
83+
Base.ones(p::BlocksOrAuto, dims::Dims) = ones(p, Float64, dims)
84+
Base.ones(::AutoBlocks, eltype::Type, dims::Dims) =
85+
ones(auto_blocks(dims), eltype, dims)
6086

61-
function Base.zeros(p::Blocks, eltype::Type, dims)
87+
function Base.zeros(p::Blocks, eltype::Type, dims::Dims)
6288
d = ArrayDomain(map(x->1:x, dims))
6389
a = AllocateArray(eltype, (_, x...) -> zeros(x...), d, partition(p, d), p)
6490
return _to_darray(a)
6591
end
66-
Base.zeros(p::Blocks, t::Type, dims::Integer...) = zeros(p, t, dims)
67-
Base.zeros(p::Blocks, dims::Integer...) = zeros(p, Float64, dims)
68-
Base.zeros(p::Blocks, dims::Tuple) = zeros(p, Float64, dims)
92+
Base.zeros(p::BlocksOrAuto, T::Type, dims::Integer...) = zeros(p, T, dims)
93+
Base.zeros(p::BlocksOrAuto, T::Type, dims::Dims) = zeros(p, T, dims)
94+
Base.zeros(p::BlocksOrAuto, dims::Integer...) = zeros(p, Float64, dims)
95+
Base.zeros(p::BlocksOrAuto, dims::Dims) = zeros(p, Float64, dims)
96+
Base.zeros(::AutoBlocks, eltype::Type, dims::Dims) =
97+
zeros(auto_blocks(dims), eltype, dims)
6998

7099
function Base.zero(x::DArray{T,N}) where {T,N}
71100
dims = ntuple(i->x.domain.indexes[i].stop, N)
@@ -83,22 +112,3 @@ function Base.view(A::AbstractArray{T,N}, p::Blocks{N}) where {T,N}
83112
chunks = [tochunk(view(A, x.indexes...)) for x in dc]
84113
return DArray(T, d, dc, chunks, p)
85114
end
86-
87-
function sprand(p::Blocks, m::Integer, n::Integer, sparsity::Real)
88-
s = rand(UInt)
89-
f = function (idx, t,sz)
90-
sprand(MersenneTwister(s+idx), sz...,sparsity)
91-
end
92-
d = ArrayDomain((1:m, 1:n))
93-
a = AllocateArray(Float64, f, d, partition(p, d), p)
94-
return _to_darray(a)
95-
end
96-
97-
function sprand(p::Blocks, n::Integer, sparsity::Real)
98-
s = rand(UInt)
99-
f = function (idx,t,sz)
100-
sprand(MersenneTwister(s+idx), sz...,sparsity)
101-
end
102-
a = AllocateArray(Float64, f, d, partition(p, ArrayDomain((1:n,))), p)
103-
return _to_darray(a)
104-
end

src/array/darray.jl

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import Base: ==, fetch
22
using Serialization
33
import Serialization: serialize, deserialize
44

5+
export DArray, DVector, DMatrix, Blocks, AutoBlocks
6+
export distribute
7+
8+
59
###### Array Domains ######
610

711
"""
@@ -149,11 +153,11 @@ mutable struct DArray{T,N,B<:AbstractBlocks{N},F} <: ArrayOp{T, N}
149153
end
150154
end
151155

152-
WrappedDArray{T,N} = Union{<:DArray{T,N}, Transpose{<:DArray{T,N}}, Adjoint{<:DArray{T,N}}}
153-
WrappedDMatrix{T} = WrappedDArray{T,2}
154-
WrappedDVector{T} = WrappedDArray{T,1}
155-
DMatrix{T} = DArray{T,2}
156-
DVector{T} = DArray{T,1}
156+
const WrappedDArray{T,N} = Union{<:DArray{T,N}, Transpose{<:DArray{T,N}}, Adjoint{<:DArray{T,N}}}
157+
const WrappedDMatrix{T} = WrappedDArray{T,2}
158+
const WrappedDVector{T} = WrappedDArray{T,1}
159+
const DMatrix{T} = DArray{T,2}
160+
const DVector{T} = DArray{T,1}
157161

158162

159163
# mainly for backwards-compatibility
@@ -319,8 +323,6 @@ end
319323
Base.@deprecate_binding Cat DArray
320324
Base.@deprecate_binding ComputedArray DArray
321325

322-
export Distribute, distribute
323-
324326
struct Distribute{T,N,B<:AbstractBlocks} <: ArrayOp{T, N}
325327
domainchunks
326328
partitioning::B
@@ -385,22 +387,44 @@ function stage(ctx::Context, d::Distribute)
385387
d.partitioning)
386388
end
387389

388-
function distribute(x::AbstractArray, dist::Blocks)
389-
_to_darray(Distribute(dist, x))
390-
end
390+
"""
391+
AutoBlocks
391392
393+
Automatically determines the size and number of blocks for a distributed array.
394+
This may construct any kind of `Dagger.AbstractBlocks` partitioning.
395+
"""
396+
struct AutoBlocks end
397+
function auto_blocks(dims::Dims{N}) where N
398+
# TODO: Allow other partitioning schemes
399+
np = num_processors()
400+
p = cld(dims[end], np)
401+
return Blocks(ntuple(i->i == N ? p : dims[i], N))
402+
end
403+
auto_blocks(A::AbstractArray{T,N}) where {T,N} = auto_blocks(size(A))
404+
405+
distribute(A::AbstractArray) = distribute(A, AutoBlocks())
406+
distribute(A::AbstractArray{T,N}, dist::Blocks{N}) where {T,N} =
407+
_to_darray(Distribute(dist, A))
408+
distribute(A::AbstractArray, ::AutoBlocks) = distribute(A, auto_blocks(A))
392409
function distribute(x::AbstractArray{T,N}, n::NTuple{N}) where {T,N}
393410
p = map((d, dn)->ceil(Int, d / dn), size(x), n)
394411
distribute(x, Blocks(p))
395412
end
413+
distribute(x::AbstractVector, n::Int) = distribute(x, (n,))
414+
distribute(x::AbstractVector, n::Vector{<:Integer}) =
415+
distribute(x, DomainBlocks((1,), (cumsum(n),)))
396416

397-
function distribute(x::AbstractVector, n::Int)
398-
distribute(x, (n,))
399-
end
417+
DVector(A::AbstractVector{T}, part::Blocks{1}) where T = distribute(A, part)
418+
DMatrix(A::AbstractMatrix{T}, part::Blocks{2}) where T = distribute(A, part)
419+
DArray(A::AbstractArray{T,N}, part::Blocks{N}) where {T,N} = distribute(A, part)
400420

401-
function distribute(x::AbstractVector, n::Vector{<:Integer})
402-
distribute(x, DomainBlocks((1,), (cumsum(n),)))
403-
end
421+
DVector(A::AbstractVector{T}) where T = DVector(A, AutoBlocks())
422+
DMatrix(A::AbstractMatrix{T}) where T = DMatrix(A, AutoBlocks())
423+
DArray(A::AbstractArray) = DArray(A, AutoBlocks())
424+
425+
DVector(A::AbstractVector{T}, ::AutoBlocks) where T = DVector(A, auto_blocks(A))
426+
DMatrix(A::AbstractMatrix{T}, ::AutoBlocks) where T = DMatrix(A, auto_blocks(A))
427+
DArray(A::AbstractArray, ::AutoBlocks) = DArray(A, auto_blocks(A))
404428

405429
function Base.:(==)(x::ArrayOp{T,N}, y::AbstractArray{S,N}) where {T,S,N}
406430
collect(x) == y

src/array/indexing.jl

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ Base.getindex(A::DArray, idx::Integer) =
9595
getindex(A, Base._ind2sub(A, idx))
9696
Base.getindex(A::DArray, idx::CartesianIndex) =
9797
getindex(A, Tuple(idx))
98+
function Base.getindex(A::DArray{T,N}, idxs::Dims{S}) where {T,N,S}
99+
if S > N
100+
if all(idxs[(N+1):end] .== 1)
101+
return getindex(A, idxs[1:N])
102+
else
103+
throw(BoundsError(A, idxs))
104+
end
105+
elseif S < N
106+
throw(BoundsError(A, idxs))
107+
end
108+
error()
109+
end
98110

99111
### setindex!
100112

@@ -126,6 +138,18 @@ Base.setindex!(A::DArray, value, idx::Integer) =
126138
setindex!(A, value, Base._ind2sub(A, idx))
127139
Base.setindex!(A::DArray, value, idx::CartesianIndex) =
128140
setindex!(A, value, Tuple(idx))
141+
function Base.setindex!(A::DArray{T,N}, value, idxs::Dims{S}) where {T,N,S}
142+
if S > N
143+
if all(idxs[(N+1):end] .== 1)
144+
return setindex!(A, value, idxs[1:N])
145+
else
146+
throw(BoundsError(A, idxs))
147+
end
148+
elseif S < N
149+
throw(BoundsError(A, idxs))
150+
end
151+
error()
152+
end
129153

130154
### Allow/disallow scalar indexing
131155

0 commit comments

Comments
 (0)