Skip to content

Commit a233591

Browse files
authored
Merge pull request #120 from JuliaParallel/anj/bc
Define general broadcasting of DArrays
2 parents 012a912 + 5a44418 commit a233591

File tree

6 files changed

+78
-50
lines changed

6 files changed

+78
-50
lines changed

.travis.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ os:
33
- linux
44
- osx
55
julia:
6-
- 0.5
76
- nightly
87
matrix:
9-
allow_failures:
10-
- julia: nightly
8+
# allow_failures:
9+
# - julia: nightly
1110
notifications:
1211
email: false
1312
before_install:

REQUIRE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
julia 0.5-
1+
julia 0.6-
22
Primes

src/darray.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ empty_localpart(T,N,A) = convert(A, Array(T, ntuple(zero, N)))
6161
typealias SubDArray{T,N,D<:DArray} SubArray{T,N,D}
6262
typealias SubOrDArray{T,N} Union{DArray{T,N}, SubDArray{T,N}}
6363

64-
localtype{T,N,S}(A::DArray{T,N,S}) = S
64+
localtype{T,N,S}(::Type{DArray{T,N,S}}) = S
65+
localtype{T,N,D}(::Type{SubDArray{T,N,D}}) = localtype(D)
66+
localtype(A::SubOrDArray) = localtype(typeof(A))
6567
localtype(A::AbstractArray) = typeof(A)
6668

6769
## core constructors ##
@@ -272,7 +274,7 @@ end
272274
# get array of start indexes for dividing sz into nc chunks
273275
function defaultdist(sz::Int, nc::Int)
274276
if sz >= nc
275-
return round(Int, linspace(1, sz+1, nc+1))
277+
return round.(Int, linspace(1, sz+1, nc+1))
276278
else
277279
return [[1:(sz+1);], zeros(Int, nc-sz);]
278280
end

src/mapreduce.jl

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,38 @@
22

33
Base.map(f, d::DArray) = DArray(I->map(f, localpart(d)), d)
44

5-
Base.map!{F}(f::F, d::DArray) = begin
6-
@sync for p in procs(d)
7-
@async remotecall_fetch((f,d)->(map!(f, localpart(d)); nothing), p, f, d)
5+
Base.map!{F}(f::F, dest::DArray, src::DArray) = begin
6+
@sync for p in procs(dest)
7+
@async remotecall_fetch(() -> (map!(f, localpart(dest), src[localindexes(dest)...]); nothing), p)
88
end
9-
return d
9+
return dest
1010
end
1111

12-
# FixMe! We'll have to handle the general n args case but it seems tricky
13-
Base.broadcast(f, d::DArray) = DArray(I -> broadcast(f, localpart(d)), d)
12+
Base.Broadcast.containertype{D<:DArray}(::Type{D}) = DArray
13+
14+
Base.Broadcast.promote_containertype(::Type{DArray}, ::Type{DArray}) = DArray
15+
Base.Broadcast.promote_containertype(::Type{DArray}, ::Type{Array}) = DArray
16+
Base.Broadcast.promote_containertype(::Type{DArray}, ct) = DArray
17+
Base.Broadcast.promote_containertype(::Type{Array}, ::Type{DArray}) = DArray
18+
Base.Broadcast.promote_containertype(ct, ::Type{DArray}) = DArray
19+
20+
Base.Broadcast.broadcast_indices(::Type{DArray}, A) = indices(A)
21+
Base.Broadcast.broadcast_indices(::Type{DArray}, A::Ref) = ()
22+
23+
# FixMe!
24+
## 1. Support for arbitrary indices including OneTo
25+
## 2. This is as type unstable as it can be. Overhead might not matter too much for DArrays though.
26+
function Base.Broadcast.broadcast_c(f, ::Type{DArray}, As...)
27+
T = Base.Broadcast._broadcast_eltype(f, As...)
28+
shape = Base.Broadcast.broadcast_indices(As...)
29+
iter = Base.CartesianRange(shape)
30+
D = DArray(map(length, shape)) do I
31+
Base.Broadcast.broadcast_c(f, Array,
32+
map(a -> isa(a, Union{Number,Ref}) ? a :
33+
localtype(a)(a[ntuple(i -> i > ndims(a) ? 1 : (size(a, i) == 1 ? (1:1) : I[i]), length(shape))...]), As)...)
34+
end
35+
return D
36+
end
1437

1538
function Base.reduce(f, d::DArray)
1639
results=[]
@@ -148,15 +171,17 @@ end
148171
# Unary vector functions
149172
(-)(D::DArray) = map(-, D)
150173

151-
# scalar ops
152-
(+)(A::DArray{Bool}, x::Bool) = A .+ x
153-
(+)(x::Bool, A::DArray{Bool}) = x .+ A
154-
(-)(A::DArray{Bool}, x::Bool) = A .- x
155-
(-)(x::Bool, A::DArray{Bool}) = x .- A
156-
(+)(A::DArray, x::Number) = A .+ x
157-
(+)(x::Number, A::DArray) = x .+ A
158-
(-)(A::DArray, x::Number) = A .- x
159-
(-)(x::Number, A::DArray) = x .- A
174+
@static if VERSION < v"0.6.0-dev.1731"
175+
# scalar ops
176+
(+)(A::DArray{Bool}, x::Bool) = A .+ x
177+
(+)(x::Bool, A::DArray{Bool}) = x .+ A
178+
(-)(A::DArray{Bool}, x::Bool) = A .- x
179+
(-)(x::Bool, A::DArray{Bool}) = x .- A
180+
(+)(A::DArray, x::Number) = A .+ x
181+
(+)(x::Number, A::DArray) = x .+ A
182+
(-)(A::DArray, x::Number) = A .- x
183+
(-)(x::Number, A::DArray) = x .- A
184+
end
160185

161186
map_localparts(f::Callable, d::DArray) = DArray(i->f(localpart(d)), d)
162187
map_localparts(f::Callable, d1::DArray, d2::DArray) = DArray(d1) do I
@@ -192,10 +217,12 @@ end
192217
# the same size and distribution
193218
map_localparts(f::Callable, As::DArray...) = DArray(I->f(map(localpart, As)...), As[1])
194219

195-
for f in (:.+, :.-, :.*, :./, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
196-
@eval begin
197-
($f){T}(A::DArray{T}, B::Number) = map_localparts(r->($f)(r, B), A)
198-
($f){T}(A::Number, B::DArray{T}) = map_localparts(r->($f)(A, r), B)
220+
@static if VERSION < v"0.6.0-dev.1632"
221+
for f in (:.+, :.-, :.*, :./, :.%, :.<<, :.>>, :div, :mod, :rem, :&, :|, :$)
222+
@eval begin
223+
($f){T}(A::DArray{T}, B::Number) = map_localparts(r->($f)(r, B), A)
224+
($f){T}(A::Number, B::DArray{T}) = map_localparts(r->($f)(A, r), B)
225+
end
199226
end
200227
end
201228

@@ -217,13 +244,15 @@ for f in (:+, :-, :div, :mod, :rem, :&, :|, :$)
217244
($f){T}(A::Array{T}, B::DArray{T}) = map_localparts($f, A, B)
218245
end
219246
end
220-
for f in (:.+, :.-, :.*, :./, :.%, :.<<, :.>>)
221-
@eval begin
222-
function ($f){T}(A::DArray{T}, B::DArray{T})
223-
map_localparts($f, A, B)
247+
@static if VERSION < v"0.6.0-dev.1632"
248+
for f in (:.+, :.-, :.*, :./, :.%, :.<<, :.>>)
249+
@eval begin
250+
function ($f){T}(A::DArray{T}, B::DArray{T})
251+
map_localparts($f, A, B)
252+
end
253+
($f){T}(A::DArray{T}, B::Array{T}) = map_localparts($f, A, B)
254+
($f){T}(A::Array{T}, B::DArray{T}) = map_localparts($f, A, B)
224255
end
225-
($f){T}(A::DArray{T}, B::Array{T}) = map_localparts($f, A, B)
226-
($f){T}(A::Array{T}, B::DArray{T}) = map_localparts($f, A, B)
227256
end
228257
end
229258

test/darray.jl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ t=@testset "test DArray reduce" begin
171171
end
172172

173173
@testset "test map! / reduce" begin
174-
map!(x->1, D)
174+
map!(x->1, D, D)
175175
@test reduce(+, D) == 100
176176
end
177177
close(D)
@@ -343,16 +343,16 @@ end
343343
check_leaks(t)
344344

345345
t=@testset "test max / min / sum" begin
346-
a = map(x->Int(round(rand() * 100)) - 50, Array(Int, 100,1000))
346+
a = map(x -> Int(round(rand() * 100)) - 50, Array(Int, 100,1000))
347347
d = distribute(a)
348348

349-
@test sum(d) == sum(a)
350-
@test maximum(d) == maximum(a)
351-
@test minimum(d) == minimum(a)
352-
@test maxabs(d) == maxabs(a)
353-
@test minabs(d) == minabs(a)
354-
@test sumabs(d) == sumabs(a)
355-
@test sumabs2(d) == sumabs2(a)
349+
@test sum(d) == sum(a)
350+
@test maximum(d) == maximum(a)
351+
@test minimum(d) == minimum(a)
352+
@test maximum(abs, d) == maximum(abs, a)
353+
@test minimum(abs, d) == minimum(abs, a)
354+
@test sum(abs, d) == sum(abs, a)
355+
@test sum(abs2, d) == sum(abs2, a)
356356
close(d)
357357
end
358358

@@ -720,22 +720,22 @@ t=@testset "test scalar ops" begin
720720
c = drand(20,20)
721721
d = convert(Array, c)
722722

723-
@testset "$f" for f in (+, -, .+, .-, .*, ./, .%, div, mod)
723+
@testset "$f" for f in (:+, :-, :.+, :.-, :.*, :./, :.%)
724724
x = rand()
725-
@test f(a, x) == f(b, x)
726-
@test f(x, a) == f(x, b)
727-
@test f(a, c) == f(b, d)
725+
@test @eval ($f)($a, $x) == ($f)($b, $x)
726+
@test @eval ($f)($x, $a) == ($f)($x, $b)
727+
@test @eval ($f)($a, $c) == ($f)($b, $d)
728728
end
729729

730730
close(a)
731731
close(c)
732732

733733
a = dones(Int, 20, 20)
734734
b = convert(Array, a)
735-
@testset "$f" for f in (.<<, .>>)
736-
@test f(a, 2) == f(b, 2)
737-
@test f(2, a) == f(2, b)
738-
@test f(a, a) == f(b, b)
735+
@testset "$f" for f in (:.<<, :.>>)
736+
@test @eval ($f)($a, 2) == ($f)($b, 2)
737+
@test @eval ($f)(2, $a) == ($f)(2, $b)
738+
@test @eval ($f)($a, $a) == ($f)($b, $b)
739739
end
740740

741741
@testset "$f" for f in (rem,)

test/runtests.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ const OTHERIDS = filter(id-> id != MYID, procs())[rand(1:(nprocs()-1))]
2020

2121
# On 0.6, @testset does not display the test description automatically anymore.
2222
function print_test_desc(t, n=0)
23-
VERSION < v"0.6-" && return
24-
2523
println(repeat(" ", n), "Passed : ", t.description)
2624
for t2 in t.results
2725
if isa(t2, Base.Test.DefaultTestSet)

0 commit comments

Comments
 (0)