From b7d1de7c56e547a5c96f005ffdd29aabbff448d7 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Mon, 13 Dec 2021 10:06:34 +0100 Subject: [PATCH 1/3] Revert "explicitly SIMD muladd with duals (#562)" This reverts commit ab0e239452cfa059e3c0d7467d6bb489e57ea1ab. --- src/ForwardDiff.jl | 7 ------- src/dual.jl | 20 -------------------- src/partials.jl | 7 +++++++ 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/ForwardDiff.jl b/src/ForwardDiff.jl index 5174e324..35ee6a8a 100644 --- a/src/ForwardDiff.jl +++ b/src/ForwardDiff.jl @@ -16,13 +16,6 @@ import SpecialFunctions import LogExpFunctions import CommonSubexpressions -const SIMDFloat = Union{Float64, Float32} -const SIMDInt = Union{ - Int128, Int64, Int32, Int16, Int8, - UInt128, UInt64, UInt32, UInt16, UInt8, - } -const SIMDType = Union{SIMDFloat, SIMDInt} - include("prelude.jl") include("partials.jl") include("dual.jl") diff --git a/src/dual.jl b/src/dual.jl index 75d46378..03330c00 100644 --- a/src/dual.jl +++ b/src/dual.jl @@ -541,16 +541,6 @@ end # fma # #-----# -@inline function calc_fma_xyz(x::Dual{T,V,N}, - y::Dual{T,V,N}, - z::Dual{T,V,N}) where {T, V<:SIMDFloat,N} - xv, yv, zv = value(x), value(y), value(z) - rv = fma(xv, yv, zv) - N == 0 && return Dual{T}(rv) - xp, yp, zp = Vec(partials(x).values), Vec(partials(y).values), Vec(partials(z).values) - parts = Tuple(fma(xv, yp, fma(yv, xp, zp))) - Dual{T}(rv, parts) -end @generated function calc_fma_xyz(x::Dual{T,<:Any,N}, y::Dual{T,<:Any,N}, z::Dual{T,<:Any,N}) where {T,N} @@ -593,16 +583,6 @@ end # muladd # #--------# -@inline function calc_muladd_xyz(x::Dual{T,V,N}, - y::Dual{T,V,N}, - z::Dual{T,V,N}) where {T, V<:SIMDType,N} - xv, yv, zv = value(x), value(y), value(z) - rv = muladd(xv, yv, zv) - N == 0 && return Dual{T}(rv) - xp, yp, zp = Vec(partials(x).values), Vec(partials(y).values), Vec(partials(z).values) - parts = Tuple(muladd(xv, yp, muladd(yv, xp, zp))) - Dual{T}(rv, parts) -end @generated function calc_muladd_xyz(x::Dual{T,<:Any,N}, y::Dual{T,<:Any,N}, z::Dual{T,<:Any,N}) where {T,N} diff --git a/src/partials.jl b/src/partials.jl index 7a94884e..eca0a76c 100644 --- a/src/partials.jl +++ b/src/partials.jl @@ -205,6 +205,13 @@ end return tupexpr(i -> :(rand(V)), N) end + +const SIMDFloat = Union{Float64, Float32} +const SIMDInt = Union{ + Int128, Int64, Int32, Int16, Int8, + UInt128, UInt64, UInt32, UInt16, UInt8, + } +const SIMDType = Union{SIMDFloat, SIMDInt} const NT{N,T} = NTuple{N,T} # SIMD implementation From 237a5713938bfec6933056d19b745b94848265f7 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Mon, 13 Dec 2021 10:06:39 +0100 Subject: [PATCH 2/3] Revert "use explicit simd for iszero check on partials (#559)" This reverts commit 5bb4546843d7f9bbe1b696f0172abf5a23131dc5. --- src/ForwardDiff.jl | 1 - src/partials.jl | 23 ++++++++--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ForwardDiff.jl b/src/ForwardDiff.jl index 35ee6a8a..93d3b246 100644 --- a/src/ForwardDiff.jl +++ b/src/ForwardDiff.jl @@ -8,7 +8,6 @@ if VERSION >= v"1.6" end using Random using LinearAlgebra -import SIMD: Vec import Printf import NaNMath diff --git a/src/partials.jl b/src/partials.jl index eca0a76c..26c26c01 100644 --- a/src/partials.jl +++ b/src/partials.jl @@ -141,13 +141,6 @@ end @inline _mul_partials(a::Partials{0,A}, b::Partials{N,B}, afactor, bfactor) where {N,A,B} = bfactor * b @inline _mul_partials(a::Partials{N,A}, b::Partials{0,B}, afactor, bfactor) where {N,A,B} = afactor * a -const SIMDFloat = Union{Float64, Float32} -const SIMDInt = Union{ - Int128, Int64, Int32, Int16, Int8, - UInt128, UInt64, UInt32, UInt16, UInt8, - } -const SIMDType = Union{SIMDFloat, SIMDInt} - ################################## # Generated Functions on NTuples # ################################## @@ -171,7 +164,6 @@ end @inline rand_tuple(::AbstractRNG, ::Type{Tuple{}}) = tuple() @inline rand_tuple(::Type{Tuple{}}) = tuple() -iszero_tuple(tup::NTuple{N,V}) where {N, V<:SIMDType} = sum(Vec(tup) != zero(V)) == 0 @generated function iszero_tuple(tup::NTuple{N,V}) where {N,V} ex = Expr(:&&, [:(z == tup[$i]) for i=1:N]...) return quote @@ -213,14 +205,15 @@ const SIMDInt = Union{ } const SIMDType = Union{SIMDFloat, SIMDInt} const NT{N,T} = NTuple{N,T} +using SIMD # SIMD implementation -@inline add_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) + Vec(b)) -@inline sub_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) - Vec(b)) -@inline scale_tuple(tup::NT{N,T}, x::T) where {N, T<:SIMDType} = Tuple(Vec(tup) * x) -@inline div_tuple_by_scalar(tup::NT{N,T}, x::T) where {N, T<:SIMDFloat} = Tuple(Vec(tup) / x) -@inline minus_tuple(tup::NT{N,T}) where {N, T<:SIMDType} = Tuple(-Vec(tup)) -@inline mul_tuples(a::NT{N,T}, b::NT{N,T}, af::T, bf::T) where {N, T<:SIMDType} = Tuple(muladd(af, Vec(a), bf * Vec(b))) +add_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) + Vec(b)) +sub_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) - Vec(b)) +scale_tuple(tup::NT{N,T}, x::T) where {N, T<:SIMDType} = Tuple(Vec(tup) * x) +div_tuple_by_scalar(tup::NT{N,T}, x::T) where {N, T<:SIMDFloat} = Tuple(Vec(tup) / x) +minus_tuple(tup::NT{N,T}) where {N, T<:SIMDType} = Tuple(-Vec(tup)) +mul_tuples(a::NT{N,T}, b::NT{N,T}, af::T, bf::T) where {N, T<:SIMDType} = Tuple(muladd(Vec{N,T}(af), Vec(a), Vec{N,T}(bf) * Vec(b))) # Fallback implementations @@ -229,7 +222,7 @@ const NT{N,T} = NTuple{N,T} @generated scale_tuple(tup::NT{N}, x) where N = tupexpr(i -> :(tup[$i] * x), N) @generated div_tuple_by_scalar(tup::NT{N}, x) where N = tupexpr(i -> :(tup[$i] / x), N) @generated minus_tuple(tup::NT{N}) where N = tupexpr(i -> :(-tup[$i]), N) -@generated mul_tuples(a::NT{N}, b::NT{N}, af, bf) where N = tupexpr(i -> :(muladd(af, a[$i], bf * b[$i])), N) +@generated mul_tuples(a::NT{N}, b::NT{N}, af, bf) where N = tupexpr(i -> :((af * a[$i]) + (bf * b[$i])), N) ################### # Pretty Printing # From 7dbd072351e44cbecd0917124b233530324b24fc Mon Sep 17 00:00:00 2001 From: KristofferC Date: Mon, 13 Dec 2021 10:06:44 +0100 Subject: [PATCH 3/3] Revert "use SIMD.jl for explicit vectorization of partial operations (#557)" This reverts commit d033d2ae827ed3534d5d7ece66fad064636f6880. --- .github/workflows/ci.yml | 1 + Project.toml | 4 +--- src/partials.jl | 47 +++++++++++++++++++--------------------- test/PartialsTest.jl | 2 +- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 23735ec5..f83be7ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ jobs: fail-fast: false matrix: version: + - '1.0' - '1' - 'nightly' os: diff --git a/Project.toml b/Project.toml index 5c5fd7fc..3318b46d 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,6 @@ NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" Preferences = "21216c6a-2e73-6563-6e65-726566657250" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -SIMD = "fdea26ae-647d-5447-a871-4b548cad5224" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" @@ -25,10 +24,9 @@ DiffTests = "0.0.1, 0.1" LogExpFunctions = "0.3" NaNMath = "0.2.2, 0.3" Preferences = "1" -SIMD = "3" SpecialFunctions = "0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 1.0" StaticArrays = "0.8.3, 0.9, 0.10, 0.11, 0.12, 1.0" -julia = "1.6" +julia = "1" [extras] Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" diff --git a/src/partials.jl b/src/partials.jl index 26c26c01..fce67b0a 100644 --- a/src/partials.jl +++ b/src/partials.jl @@ -197,32 +197,29 @@ end return tupexpr(i -> :(rand(V)), N) end +@generated function scale_tuple(tup::NTuple{N}, x) where N + return tupexpr(i -> :(tup[$i] * x), N) +end + +@generated function div_tuple_by_scalar(tup::NTuple{N}, x) where N + return tupexpr(i -> :(tup[$i] / x), N) +end + +@generated function add_tuples(a::NTuple{N}, b::NTuple{N}) where N + return tupexpr(i -> :(a[$i] + b[$i]), N) +end -const SIMDFloat = Union{Float64, Float32} -const SIMDInt = Union{ - Int128, Int64, Int32, Int16, Int8, - UInt128, UInt64, UInt32, UInt16, UInt8, - } -const SIMDType = Union{SIMDFloat, SIMDInt} -const NT{N,T} = NTuple{N,T} -using SIMD - -# SIMD implementation -add_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) + Vec(b)) -sub_tuples(a::NT{N,T}, b::NT{N,T}) where {N, T<:SIMDType} = Tuple(Vec(a) - Vec(b)) -scale_tuple(tup::NT{N,T}, x::T) where {N, T<:SIMDType} = Tuple(Vec(tup) * x) -div_tuple_by_scalar(tup::NT{N,T}, x::T) where {N, T<:SIMDFloat} = Tuple(Vec(tup) / x) -minus_tuple(tup::NT{N,T}) where {N, T<:SIMDType} = Tuple(-Vec(tup)) -mul_tuples(a::NT{N,T}, b::NT{N,T}, af::T, bf::T) where {N, T<:SIMDType} = Tuple(muladd(Vec{N,T}(af), Vec(a), Vec{N,T}(bf) * Vec(b))) - - -# Fallback implementations -@generated add_tuples(a::NT{N}, b::NT{N}) where N = tupexpr(i -> :(a[$i] + b[$i]), N) -@generated sub_tuples(a::NT{N}, b::NT{N}) where N = tupexpr(i -> :(a[$i] - b[$i]), N) -@generated scale_tuple(tup::NT{N}, x) where N = tupexpr(i -> :(tup[$i] * x), N) -@generated div_tuple_by_scalar(tup::NT{N}, x) where N = tupexpr(i -> :(tup[$i] / x), N) -@generated minus_tuple(tup::NT{N}) where N = tupexpr(i -> :(-tup[$i]), N) -@generated mul_tuples(a::NT{N}, b::NT{N}, af, bf) where N = tupexpr(i -> :((af * a[$i]) + (bf * b[$i])), N) +@generated function sub_tuples(a::NTuple{N}, b::NTuple{N}) where N + return tupexpr(i -> :(a[$i] - b[$i]), N) +end + +@generated function minus_tuple(tup::NTuple{N}) where N + return tupexpr(i -> :(-tup[$i]), N) +end + +@generated function mul_tuples(a::NTuple{N}, b::NTuple{N}, afactor, bfactor) where N + return tupexpr(i -> :((afactor * a[$i]) + (bfactor * b[$i])), N) +end ################### # Pretty Printing # diff --git a/test/PartialsTest.jl b/test/PartialsTest.jl index 08e76bda..39fb05d7 100644 --- a/test/PartialsTest.jl +++ b/test/PartialsTest.jl @@ -114,7 +114,7 @@ for N in (0, 3), T in (Int, Float32, Float64) if N > 0 @test ForwardDiff._div_partials(PARTIALS, PARTIALS2, X, Y) == ForwardDiff._mul_partials(PARTIALS, PARTIALS2, inv(Y), -X/(Y^2)) - @test all(isapprox.(ForwardDiff._mul_partials(PARTIALS, PARTIALS2, X, Y).values, map((a, b) -> (X * a) + (Y * b), VALUES, VALUES2))) + @test ForwardDiff._mul_partials(PARTIALS, PARTIALS2, X, Y).values == map((a, b) -> (X * a) + (Y * b), VALUES, VALUES2) @test ForwardDiff._mul_partials(ZERO_PARTIALS, PARTIALS, X, Y) == Y * PARTIALS @test ForwardDiff._mul_partials(PARTIALS, ZERO_PARTIALS, X, Y) == X * PARTIALS