-
-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathalloc.jl
103 lines (90 loc) · 3.51 KB
/
alloc.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import Base: cat
import Random: MersenneTwister
export partition
mutable struct AllocateArray{T,N} <: ArrayOp{T,N}
eltype::Type{T}
f::Function
domain::ArrayDomain{N}
domainchunks
partitioning::AbstractBlocks
end
size(a::AllocateArray) = size(a.domain)
function _cumlength(len, step)
nice_pieces = div(len, step)
extra = rem(len, step)
ps = [step for i=1:nice_pieces]
cumsum(extra > 0 ? vcat(ps, extra) : ps)
end
function partition(p::AbstractBlocks, dom::ArrayDomain)
DomainBlocks(map(first, indexes(dom)),
map(_cumlength, map(length, indexes(dom)), p.blocksize))
end
function stage(ctx, a::AllocateArray)
alloc(idx, sz) = a.f(idx, a.eltype, sz)
thunks = [Dagger.@spawn alloc(i, size(x)) for (i, x) in enumerate(a.domainchunks)]
return DArray(a.eltype, a.domain, a.domainchunks, thunks, a.partitioning)
end
function Base.rand(p::Blocks, eltype::Type, dims)
d = ArrayDomain(map(x->1:x, dims))
a = AllocateArray(eltype, (_, x...) -> rand(x...), d, partition(p, d), p)
return _to_darray(a)
end
Base.rand(p::Blocks, t::Type, dims::Integer...) = rand(p, t, dims)
Base.rand(p::Blocks, dims::Integer...) = rand(p, Float64, dims)
Base.rand(p::Blocks, dims::Tuple) = rand(p, Float64, dims)
function Base.randn(p::Blocks, eltype::Type, dims)
d = ArrayDomain(map(x->1:x, dims))
a = AllocateArray(Float64, (_, x...) -> randn(x...), d, partition(p, d), p)
return _to_darray(a)
end
Base.randn(p::Blocks, t::Type, dims::Integer...) = randn(p, t, dims)
Base.randn(p::Blocks, dims::Integer...) = randn(p, dims)
Base.randn(p::Blocks, dims::Tuple) = randn(p, Float64, dims)
function Base.ones(p::Blocks, eltype::Type, dims)
d = ArrayDomain(map(x->1:x, dims))
a = AllocateArray(eltype, (_, x...) -> ones(x...), d, partition(p, d), p)
return _to_darray(a)
end
Base.ones(p::Blocks, t::Type, dims::Integer...) = ones(p, t, dims)
Base.ones(p::Blocks, dims::Integer...) = ones(p, Float64, dims)
Base.ones(p::Blocks, dims::Tuple) = ones(p, Float64, dims)
function Base.zeros(p::Blocks, eltype::Type, dims)
d = ArrayDomain(map(x->1:x, dims))
a = AllocateArray(eltype, (_, x...) -> zeros(x...), d, partition(p, d), p)
return _to_darray(a)
end
Base.zeros(p::Blocks, t::Type, dims::Integer...) = zeros(p, t, dims)
Base.zeros(p::Blocks, dims::Integer...) = zeros(p, Float64, dims)
Base.zeros(p::Blocks, dims::Tuple) = zeros(p, Float64, dims)
function Base.zero(x::DArray{T,N}) where {T,N}
dims = ntuple(i->x.domain.indexes[i].stop, N)
sd = first(x.subdomains)
part_size = ntuple(i->sd.indexes[i].stop, N)
a = zeros(Blocks(part_size...), T, dims)
return _to_darray(a)
end
function Base.view(A::AbstractArray{T,N}, p::Blocks{N}) where {T,N}
d = ArrayDomain(Base.index_shape(A))
dc = partition(p, d)
# N.B. We use `tochunk` because we only want to take the view locally, and
# taking views should be very fast
chunks = [tochunk(view(A, x.indexes...)) for x in dc]
return DArray(T, d, dc, chunks, p)
end
function sprand(p::Blocks, m::Integer, n::Integer, sparsity::Real)
s = rand(UInt)
f = function (idx, t,sz)
sprand(MersenneTwister(s+idx), sz...,sparsity)
end
d = ArrayDomain((1:m, 1:n))
a = AllocateArray(Float64, f, d, partition(p, d), p)
return _to_darray(a)
end
function sprand(p::Blocks, n::Integer, sparsity::Real)
s = rand(UInt)
f = function (idx,t,sz)
sprand(MersenneTwister(s+idx), sz...,sparsity)
end
a = AllocateArray(Float64, f, d, partition(p, ArrayDomain((1:n,))), p)
return _to_darray(a)
end