Skip to content

Commit 3fcd796

Browse files
committed
p.o.c using Vecs for dual part
1 parent ee40717 commit 3fcd796

File tree

4 files changed

+23
-88
lines changed

4 files changed

+23
-88
lines changed

REQUIRE

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
julia 0.4
1+
julia 0.5
22
Calculus
33
NaNMath
4+
SIMD

src/ForwardDiff.jl

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ isdefined(Base, :__precompile__) && __precompile__()
22

33
module ForwardDiff
44

5+
using SIMD
6+
57
if VERSION < v"0.4-"
68
warn("ForwardDiff.jl is only officially compatible with Julia v0.4-. You're currently running Julia $VERSION.")
79
end

src/GradientNumber.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
################
22
# Constructors #
33
################
4-
GradientNumber{N,T}(value::T, grad::NTuple{N,T}) = GradientNumber{N,T,NTuple{N,T}}(value, Partials(grad))
4+
GradientNumber{N,T}(value::T, grad::Vec{N,T}) = GradientNumber{N,T,Vec{N,T}}(value, Partials(grad))
55
GradientNumber{T}(value::T, grad::T...) = GradientNumber(value, grad)
66

77
##############################

src/Partials.jl

+18-86
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
immutable Partials{T,C}
22
data::C
3-
Partials{N}(data::NTuple{N,T}) = new(data)
4-
Partials(data::Vector{T}) = new(data)
3+
Partials{N}(data::Vec{N,T}) = new(data)
54
end
65

7-
typealias PartialsTup{N,T} Partials{T,NTuple{N,T}}
8-
typealias PartialsVec{T} Partials{T,Vector{T}}
6+
typealias PartialsTup{N,T} Partials{T,Vec{N,T}}
97

108
Partials(data) = Partials{eltype(data),typeof(data)}(data)
119

@@ -31,12 +29,9 @@ done(partials, i) = done(data(partials), i)
3129
################
3230
# Constructors #
3331
################
34-
@inline zero_partials{C<:Tuple}(::Type{C}, n::Int) = Partials(zero_tuple(C))
32+
@inline zero_partials{C<:Vec}(::Type{C}, n::Int) = Partials(zero_tuple(C))
3533
zero_partials{T}(::Type{Vector{T}}, n) = Partials(zeros(T, n))
3634

37-
@inline rand_partials{C<:Tuple}(::Type{C}, n::Int) = Partials(rand_tuple(C))
38-
rand_partials{T}(::Type{Vector{T}}, n::Int) = Partials(rand(T, n))
39-
4035
#####################
4136
# Generic Functions #
4237
#####################
@@ -53,39 +48,6 @@ hash(partials::Partials, hsh::UInt64) = hash(hash(partials), hsh)
5348

5449
@inline copy(partials::Partials) = partials
5550

56-
function read{N,T}(io::IO, ::Type{PartialsTup{N,T}}, n::Int)
57-
return Partials(ntuple(i->read(io, T), Val{N}))
58-
end
59-
60-
function read{T}(io::IO, ::Type{PartialsVec{T}}, n::Int)
61-
return Partials([read(io, T) for i in 1:n])
62-
end
63-
64-
function write(io::IO, partials::Partials)
65-
for partial in data(partials)
66-
write(io, partial)
67-
end
68-
end
69-
70-
########################
71-
# Conversion/Promotion #
72-
########################
73-
convert{N,A,B}(::Type{PartialsTup{N,A}}, data::NTuple{N,B}) = PartialsTup{N,A}(NTuple{N,A}(data))
74-
convert{N,A,B}(::Type{PartialsTup{N,A}}, data::Vector{B}) = PartialsTup{N,A}(NTuple{N,A}(data...))
75-
convert{N,A,B}(::Type{PartialsVec{A}}, data::NTuple{N,B}) = PartialsVec{A}(Vector{A}(collect(data)))
76-
convert{A,B}(::Type{PartialsVec{A}}, data::Vector{B}) = PartialsVec{A}(Vector{A}(data))
77-
convert{T}(::Type{PartialsVec{T}}, data::Vector{T}) = PartialsVec{T}(data)
78-
convert{N,T}(::Type{PartialsTup{N,T}}, data::NTuple{N,T}) = PartialsTup{N,T}(data)
79-
80-
convert{T,C}(::Type{Partials{T,C}}, partials::Partials) = Partials{T,C}(data(partials))
81-
convert{T,C}(::Type{Partials{T,C}}, partials::Partials{T,C}) = partials
82-
convert(::Type{Partials}, partials::Partials) = partials
83-
84-
promote_rule{A,B}(::Type{PartialsVec{A}}, ::Type{PartialsVec{B}}) = PartialsVec{promote_type(A, B)}
85-
promote_rule{N,A,B}(::Type{PartialsTup{N,A}}, ::Type{PartialsVec{B}}) = PartialsVec{promote_type(A, B)}
86-
promote_rule{N,A,B}(::Type{PartialsVec{A}}, ::Type{PartialsTup{N,B}}) = PartialsVec{promote_type(A, B)}
87-
promote_rule{N,A,B}(::Type{PartialsTup{N,A}}, ::Type{PartialsTup{N,B}}) = PartialsTup{N,promote_type(A, B)}
88-
8951
##################
9052
# Math Functions #
9153
##################
@@ -96,31 +58,19 @@ promote_rule{N,A,B}(::Type{PartialsTup{N,A}}, ::Type{PartialsTup{N,B}}) = Partia
9658
return Partials(add_tuples(data(a), data(b)))
9759
end
9860

99-
function +{A,B}(a::PartialsVec{A}, b::PartialsVec{B})
100-
return Partials(data(a) + data(b))
101-
end
102-
10361
@inline function -{N,A,B}(a::PartialsTup{N,A}, b::PartialsTup{N,B})
10462
return Partials(subtract_tuples(data(a), data(b)))
10563
end
10664

107-
function -{A,B}(a::PartialsVec{A}, b::PartialsVec{B})
108-
return Partials(data(a) - data(b))
109-
end
11065

11166
@inline -{N,T}(partials::PartialsTup{N,T}) = Partials(minus_tuple(data(partials)))
112-
-{T}(partials::PartialsVec{T}) = Partials(-data(partials))
11367

11468
# Multiplication #
11569
#----------------#
11670
@inline function *{N,T}(partials::PartialsTup{N,T}, x::Number)
11771
return Partials(scale_tuple(data(partials), x))
11872
end
11973

120-
function *{T}(partials::PartialsVec{T}, x::Number)
121-
return Partials(data(partials)*x)
122-
end
123-
12474
@inline *(x::Number, partials::Partials) = partials*x
12575

12676
function _load_mul_partials!(result::Vector, a, b, afactor, bfactor)
@@ -130,11 +80,6 @@ function _load_mul_partials!(result::Vector, a, b, afactor, bfactor)
13080
return result
13181
end
13282

133-
function _mul_partials{A,B,C,D}(a::PartialsVec{A}, b::PartialsVec{B}, afactor::C, bfactor::D)
134-
T = promote_type(A, B, C, D)
135-
return Partials(_load_mul_partials!(Vector{T}(length(a)), a, b, afactor, bfactor))
136-
end
137-
13883
@inline function _mul_partials{N,A,B}(a::PartialsTup{N,A}, b::PartialsTup{N,B}, afactor, bfactor)
13984
return Partials(mul_tuples(data(a), data(b), afactor, bfactor))
14085
end
@@ -145,9 +90,6 @@ end
14590
return Partials(div_tuple_by_scalar(data(partials), x))
14691
end
14792

148-
function /{T}(partials::PartialsVec{T}, x::Number)
149-
return Partials(data(partials) / x)
150-
end
15193

15294
@inline function _div_partials(a::Partials, b::Partials, aval, bval)
15395
afactor = inv(bval)
@@ -156,7 +98,7 @@ end
15698
end
15799

158100
##################################
159-
# Generated Functions on NTuples #
101+
# Generated Functions on Vecs #
160102
##################################
161103
# The below functions are generally
162104
# equivalent to directly mapping over
@@ -171,42 +113,32 @@ function tupexpr(f,N)
171113
end
172114
end
173115

174-
@inline zero_tuple(::Type{Tuple{}}) = tuple()
175-
176-
@generated function zero_tuple{N,T}(::Type{NTuple{N,T}})
177-
result = tupexpr(i -> :z, N)
178-
return quote
179-
z = zero($T)
180-
return $result
181-
end
116+
function zero_tuple{N,T}(tup::Type{Vec{N,T}})
117+
return SIMD.create(tup, zero(T))
182118
end
183119

184120
@inline rand_tuple(::Type{Tuple{}}) = tuple()
185121

186-
@generated function rand_tuple{N,T}(::Type{NTuple{N,T}})
187-
return tupexpr(i -> :(rand($T)), N)
188-
end
189-
190-
@generated function scale_tuple{N}(tup::NTuple{N}, x)
191-
return tupexpr(i -> :(tup[$i] * x), N)
122+
function scale_tuple{N, T}(tup::Vec{N, T}, x)
123+
return SIMD.create(Vec{N, T}, T(x)) * tup
192124
end
193125

194-
@generated function div_tuple_by_scalar{N}(tup::NTuple{N}, x)
195-
return tupexpr(i -> :(tup[$i]/x), N)
126+
function div_tuple_by_scalar{N, T}(tup::Vec{N, T}, x)
127+
return tup / SIMD.create(Vec{N, T}, T(x))
196128
end
197129

198-
@generated function minus_tuple{N}(tup::NTuple{N})
199-
return tupexpr(i -> :(-tup[$i]), N)
130+
function minus_tuple{N}(tup::Vec{N})
131+
return -tup
200132
end
201133

202-
@generated function subtract_tuples{N}(a::NTuple{N}, b::NTuple{N})
203-
return tupexpr(i -> :(a[$i]-b[$i]), N)
134+
function subtract_tuples{N}(a::Vec{N}, b::Vec{N})
135+
return b - a
204136
end
205137

206-
@generated function add_tuples{N}(a::NTuple{N}, b::NTuple{N})
207-
return tupexpr(i -> :(a[$i]+b[$i]), N)
138+
function add_tuples{N}(a::Vec{N}, b::Vec{N})
139+
return a + b
208140
end
209141

210-
@generated function mul_tuples{N}(a::NTuple{N}, b::NTuple{N}, afactor, bfactor)
211-
return tupexpr(i -> :((afactor * a[$i]) + (bfactor * b[$i])), N)
142+
function mul_tuples{N, T}(a::Vec{N, T}, b::Vec{N, T}, afactor, bfactor)
143+
return SIMD.create(Vec{N, T}, T(afactor)) * a + SIMD.create(Vec{N, T}, T(bfactor)) * b
212144
end

0 commit comments

Comments
 (0)