Skip to content

Commit

Permalink
Defined apply on Map
Browse files Browse the repository at this point in the history
  • Loading branch information
fverdugo committed Jun 7, 2019
1 parent 81ce386 commit b5707b9
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 14 deletions.
32 changes: 19 additions & 13 deletions src/ArrayOperations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,31 +33,37 @@ end

function CellArrayFromKernel(k::ArrayKernel,v::Vararg{<:CellValue})
_checks(v)
T = _compute_type(k,v)
N = _compute_N(v)
T = _compute_T(k,v)
N = _compute_N(k,v)
K = typeof(k)
V = typeof(v)
CellArrayFromKernel{T,N,K,V}(k,v)
end

function _compute_type(k,v)
function _compute_T(k,v)
t = tuple([ _eltype(vi) for vi in v ]...)
T = compute_type(k,t...)
@assert T <: NumberLike
T
end

function _compute_N(v)
n = 0
for vi in v
n = max(n,_ndims(vi))
end
n
function _compute_N(k,v)
d = _compute_ndims(v...)
compute_ndim(k,d...)
end

_ndims(v::CellNumber) = 0
_nd(v::CellNumber) = 0

_ndims(v::CellArray{T,N}) where {T,N} = N
_nd(v::CellArray{T,N}) where {T,N} = N

# TODO use a generated function here
_compute_ndims(v...) = @notimplemented
_compute_ndims(v1) = (_nd(v1),)
_compute_ndims(v1,v2) = (_nd(v1),_nd(v2))
_compute_ndims(v1,v2,v3) = (_nd(v1),_nd(v2),_nd(v3))
_compute_ndims(v1,v2,v3,v4) = (_nd(v1),_nd(v2),_nd(v3),_nd(v4))
_compute_ndims(v1,v2,v3,v4,v5) = (_nd(v1),_nd(v2),_nd(v3),_nd(v4),_nd(v5))
_compute_ndims(v1,v2,v3,v4,v5,v6) = (_nd(v1),_nd(v2),_nd(v3),_nd(v4),_nd(v5),_nd(v6))

_eltype(v::CellNumber{T}) where T = T

Expand Down Expand Up @@ -111,8 +117,8 @@ end

function IndexCellArrayFromKernel(k::ArrayKernel,v::Vararg{<:CellValue})
_checks(v)
T = _compute_type(k,v)
N = _compute_N(v)
T = _compute_T(k,v)
N = _compute_N(k,v)
K = typeof(k)
V = typeof(v)
cache = CachedArray(T,N)
Expand Down
3 changes: 3 additions & 0 deletions src/CellwiseValues.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,7 @@ include("CachedArrays.jl")
include("ArrayOperations.jl")
@reexport using CellwiseValues.ArrayOperations

include("MapOperations.jl")
@reexport using CellwiseValues.MapOperations

end # module
16 changes: 16 additions & 0 deletions src/Kernels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export compute_type
export compute_value
export compute_value!
export compute_size
export compute_ndim
export test_number_kernel
export test_array_kernel

Expand All @@ -32,6 +33,10 @@ function compute_type(::ArrayKernel,::Vararg{<:Type})::Type{<:NumberLike}
@abstractmethod
end

function compute_ndim(::ArrayKernel,::Vararg{Int})::Int
@abstractmethod
end

function compute_size(::ArrayKernel,::Vararg{<:NTuple})::NTuple
@abstractmethod
end
Expand All @@ -58,6 +63,9 @@ function test_array_kernel(
s = [ _size_for_broadcast(ii) for ii in i ]
si = compute_size(k,s...)
@test size(o) == si
d = [length(si) for si in s]
n = compute_ndim(k,d...)
@test n == length(si)
r = Array{T,N}(undef,si)
compute_value!(r,k,i...)
@test r == o
Expand Down Expand Up @@ -102,4 +110,12 @@ function compute_value!(
broadcast!(k.fun,v,a...)
end

function compute_ndim(::ArrayKernelFromBroadcastedFunction,d::Vararg{Int})
n = 0
for di in d
n = max(n,di)
end
n
end

end # module Kernels
161 changes: 161 additions & 0 deletions src/MapOperations.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
module MapOperations

using CellwiseValues
using CellwiseValues.ArrayOperations: _compute_N, _compute_T

import CellwiseValues.ArrayOperations: _nd, _eltype
import CellwiseValues: apply
import CellwiseValues: evaluate!
import CellwiseValues: return_size

function apply(k::ArrayKernel,m::Map,v::Vararg)
MapFromKernel(k,m,v...)
end

struct MapFromKernel{S,M,T,N,K,V,C} <: Map{S,M,T,N}
kernel::K
inputs::V
caches::C
end

function MapFromKernel(k::ArrayKernel,v::Vararg)
S = _compute_S(v)
M = _compute_M(v)
T = _compute_T(k,v)
N = _compute_N(k,v)
K = typeof(k)
V = typeof(v)
c = _create_caches(v)
C = typeof(c)
MapFromKernel{S,M,T,N,K,V,C}(k,v,c)
end

function evaluate!(
m::MapFromKernel{S,M,T,N},
points::AbstractArray{S,M},
v::AbstractArray{T,N}) where {S,M,T,N}
_evaluate_inputs!(points,m.caches...,m.inputs...)
compute_value!(v,m.kernel,m.caches...)
end

function return_size(m::MapFromKernel{S,M},s::NTuple{M,Int}) where {S,M}
z = _return_sizes(s,m.inputs...)
compute_size(m.kernel,z...)
end

function _create_caches(v)
tuple([_cache(vi) for vi in v]...)
end

_cache(v::Map{S,M,T,N}) where {S,M,T,N} = CachedArray(T,N)

_cache(v::AbstractArray{T,N}) where {T,N} = CachedArray(T,N)

function _compute_S(v)
@assert length(v) > 0
v1, = v
S = _stype(v1)
@assert S != nothing
@assert all([ (_stype(vi)==S || _stype(vi)==nothing ) for vi in v ])
S
end

function _compute_M(v)
@assert length(v) > 0
v1, = v
M = _m(v1)
@assert M != nothing
@assert all([ (_m(vi)==M || _m(vi)==nothing ) for vi in v ])
M
end

_stype(v::Map{S}) where S = S

_stype(v::AbstractArray) = nothing

_m(v::Map{S,M}) where {S,M} = M

_m(v::AbstractArray) = nothing

_eltype(v::Map{S,M,T}) where {S,M,T} = T

_eltype(v::AbstractArray{T}) where T = T

_nd(v::Map{S,M,T,N}) where {S,M,T,N} = N

_nd(v::AbstractArray{T,N}) where {T,N} = N

_rz(s,i) = @unreachable

_rz(s,i::Map) = return_size(i,s)

_rz(s,i::AbstractArray) = size(i)

# TODO also with a generated function
_return_sizes(s,i...) = @notimplemented
_return_sizes(s,i1) = (_rz(s,i1),)
_return_sizes(s,i1,i2) = (_rz(s,i1),_rz(s,i2))
_return_sizes(s,i1,i2,i3) = (_rz(s,i1),_rz(s,i2),_rz(s,i3))
_return_sizes(s,i1,i2,i3,i4) = (_rz(s,i1),_rz(s,i2),_rz(s,i3),_rz(s,i4))
_return_sizes(s,i1,i2,i3,i4,i5) = (_rz(s,i1),_rz(s,i2),_rz(s,i3),_rz(s,i4),_rz(s,i5))
_return_sizes(s,i1,i2,i3,i4,i5,i6) = (_rz(s,i1),_rz(s,i2),_rz(s,i3),_rz(s,i4),_rz(s,i5),_rz(s,i6))

_ev!(p,c,i) = @unreachable

function _ev!(p,c,i::Map)
s = return_size(i,size(p))
setsize!(c,s)
evaluate!(i,p,c)
end

function _ev!(p,c,i::AbstractArray)
s = size(i)
setsize!(c,s)
for k in eachindex(i)
@inbounds c[k] = i[k]
end
end

# TODO also with a generated function
_evaluate_inputs!(p,ci...) = @notimplemented

function _evaluate_inputs!(p,c1,i1)
_ev!(p,c1,i1)
end

function _evaluate_inputs!(p,c1,c2,i1,i2)
_ev!(p,c1,i1)
_ev!(p,c2,i2)
end

function _evaluate_inputs!(p,c1,c2,c3,i1,i2,i3)
_ev!(p,c1,i1)
_ev!(p,c2,i2)
_ev!(p,c3,i3)
end

function _evaluate_inputs!(p,c1,c2,c3,c4,i1,i2,i3,i4)
_ev!(p,c1,i1)
_ev!(p,c2,i2)
_ev!(p,c3,i3)
_ev!(p,c4,i4)
end

function _evaluate_inputs!(p,c1,c2,c3,c4,c5,i1,i2,i3,i4,i5)
_ev!(p,c1,i1)
_ev!(p,c2,i2)
_ev!(p,c3,i3)
_ev!(p,c4,i4)
_ev!(p,c5,i5)
end

function _evaluate_inputs!(p,c1,c2,c3,c4,c5,c6,i1,i2,i3,i4,i5,i6)
_ev!(p,c1,i1)
_ev!(p,c2,i2)
_ev!(p,c3,i3)
_ev!(p,c4,i4)
_ev!(p,c5,i5)
_ev!(p,c6,i6)
end

end # module MapOperations
2 changes: 1 addition & 1 deletion src/NumberOperations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function apply(k::NumberKernel,v::Vararg{<:IndexCellValue})
IndexCellNumberFromKernel(k,v...)
end

function apply(f::Function,v::Vararg{<:CellValue};broadcast=false)
function apply(f::Function,v::Vararg;broadcast=false)
_apply(f,v,Val(broadcast))
end

Expand Down
31 changes: 31 additions & 0 deletions test/MapOperationsTests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module MapOperationsTests

using Test
using CellwiseValues
using TensorValues

using ..MapsMocks

a = VectorValue(10,10)
b = VectorValue(15,20)
p1 = VectorValue(1,1)
p2 = VectorValue(2,2)
p3 = VectorValue(3,3)
p = [p1,p2,p3]
m = MockMap(a)

m2 = apply(-,m,broadcast=true)

r = evaluate(m,p)
r2 = -r
test_map(m2,p,r2)

m3 = apply(-,m,m2,broadcast=true)
r3 = r .- r2
test_map(m3,p,r3)

m3 = apply(-,m,p,broadcast=true)
r3 = r .- p
test_map(m3,p,r3)

end # module MapOperationsTests
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ include("MapsMocks.jl")

@time @testset "ArrayOperations" begin include("ArrayOperationsTests.jl") end

@time @testset "MapOperations" begin include("MapOperationsTests.jl") end

end # module CellwiseValuesTests

0 comments on commit b5707b9

Please sign in to comment.