From b0662ebed801f14a8bad652cff224760d80ab9c6 Mon Sep 17 00:00:00 2001 From: Evgeny Tankhilevich Date: Wed, 28 Aug 2019 11:15:46 +0100 Subject: [PATCH] #362: More tests and documentation; simplify the dims --- src/mapreduce.jl | 13 ++++++++++--- test/base.jl | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/mapreduce.jl b/src/mapreduce.jl index 2d2d2e18..c03f4832 100644 --- a/src/mapreduce.jl +++ b/src/mapreduce.jl @@ -97,11 +97,11 @@ function Base._mapreducedim!(f, op, R::CuArray{T}, A::CuArray{T}) where {T} end import Base.minimum, Base.maximum, Base.reduce -_initarray(x::CuArray{T}, ::Colon, init) where {T} = fill!(similar(x, T, Base.reduced_indices(x, 1:ndims(x))), init) -_initarray(x::CuArray{T}, dims, init) where {T} = fill!(similar(x, T, Base.reduced_indices(x, dims)), init) +_reduced_dims(x::CuArray, ::Colon) = Tuple(ones(Int, ndims(x))) +_reduced_dims(x::CuArray, dims) = Base.reduced_indices(x, dims) -reduce(op, x::CuArray; dims=:, init) where {T} = _reduce(op, x, init, dims) +_initarray(x::CuArray{T}, dims, init) where {T} = fill!(similar(x, T, _reduced_dims(x, dims)), init) function _reduce(op, x::CuArray, init, ::Colon) mx = _initarray(x, :, init) @@ -114,5 +114,12 @@ function _reduce(op, x::CuArray, init, dims) Base._mapreducedim!(identity, op, mx, x) end +""" + reduce(op, x::CuArray; dims=:, init) + +The initial value `init` is mandatory for `reduce` on `CuArray`'s. It must be a neutral element for `op`. +""" +reduce(op, x::CuArray; dims=:, init) = _reduce(op, x, init, dims) + minimum(x::CuArray{T}; dims=:) where {T} = _reduce(min, x, typemax(T), dims) maximum(x::CuArray{T}; dims=:) where {T} = _reduce(max, x, typemin(T), dims) diff --git a/test/base.jl b/test/base.jl index fcbd05b8..9a4115f3 100644 --- a/test/base.jl +++ b/test/base.jl @@ -143,16 +143,25 @@ end @test testf(x -> minimum(x), rand(2, 3)) @test testf(x -> minimum(x, dims=2), rand(2, 3)) - @test testf(x -> minimum(x, dims=(2,3)), rand(2, 3, 4)) + @test testf(x -> minimum(x, dims=(2, 3)), rand(2, 3, 4)) @test testf(x -> maximum(x), rand(2, 3)) @test testf(x -> maximum(x, dims=2), rand(2, 3)) - @test testf(x -> maximum(x, dims=(2,3)), rand(2, 3, 4)) + @test testf(x -> maximum(x, dims=(2, 3)), rand(2, 3, 4)) - myreducer(x1, x2) = x1+x2 # bypass optimisations for sum() - @test testf(x -> reduce(myreducer, x, dims=(2,3), init=0.0), rand(2, 3, 4)) + myreducer(x1, x2) = x1 + x2 # bypass optimisations for sum() + @test testf(x -> reduce(myreducer, x, dims=(2, 3), init=0.0), rand(2, 3, 4)) @test testf(x -> reduce(myreducer, x, init=0.0), rand(2, 3)) @test testf(x -> reduce(myreducer, x, dims=2, init=42.0), rand(2, 3)) + + ex = ErrorException("Please supply a neutral element for &. E.g: mapreduce(f, &, A; init = 1)") + @test_throws ex mapreduce(t -> t > 0.5, &, cu(rand(2, 3))) + @test testf(x -> mapreduce(t -> t > 0.5, &, x, init=true), rand(2, 3)) + + ex = UndefKeywordError(:init) + cub = map(t -> t > 0.5, cu(rand(2, 3))) + @test_throws ex reduce(|, cub) + @test testf(x -> reduce(|, x, init=false), map(t -> t > 0.5, cu(rand(2, 3)))) end @testset "0D" begin