|
| 1 | + |
| 2 | +@time @testset "ForwardDiff.jl" begin |
| 3 | + m = 5 |
| 4 | + n = 6 |
| 5 | + k = 7 |
| 6 | + |
| 7 | + A1 = rand(Float64, m, k) |
| 8 | + B1 = rand(Float64, k, n) |
| 9 | + C1 = rand(Float64, m, n) |
| 10 | + |
| 11 | + A2 = deepcopy(A1) |
| 12 | + B2 = deepcopy(B1) |
| 13 | + C2 = deepcopy(C1) |
| 14 | + |
| 15 | + α = Float64(2.0) |
| 16 | + β = Float64(2.0) |
| 17 | + |
| 18 | + Octavian.matmul!(C1, A1, B1, α, β) |
| 19 | + LinearAlgebra.mul!(C2, A2, B2, α, β) |
| 20 | + @test C1 ≈ C2 |
| 21 | + |
| 22 | + @testset "real array from the left" begin |
| 23 | + config = ForwardDiff.JacobianConfig(nothing, C1, B1) |
| 24 | + I = LinearAlgebra.I(size(B1, 2)) |
| 25 | + |
| 26 | + J1 = ForwardDiff.jacobian((C, B) -> Octavian.matmul!(C, A1, B), C1, B1, config) |
| 27 | + @test J1 ≈ kron(I, A1) |
| 28 | + |
| 29 | + J2 = ForwardDiff.jacobian((C, B) -> LinearAlgebra.mul!(C, A2, B), C2, B2, config) |
| 30 | + @test J1 ≈ kron(I, A2) |
| 31 | + @test J1 ≈ J2 |
| 32 | + end |
| 33 | + |
| 34 | + @testset "real array from the right" begin |
| 35 | + # dense and column-major arrays |
| 36 | + config = ForwardDiff.JacobianConfig(nothing, C1, A1) |
| 37 | + |
| 38 | + J1 = ForwardDiff.jacobian((C, A) -> Octavian.matmul!(C, A, B1), C1, A1, config) |
| 39 | + J2 = ForwardDiff.jacobian((C, A) -> LinearAlgebra.mul!(C, A, B2), C2, A2, config) |
| 40 | + @test J1 ≈ J2 |
| 41 | + |
| 42 | + # transposed arrays |
| 43 | + A1new = Matrix(A1')' |
| 44 | + A2new = Matrix(A2')' |
| 45 | + config = ForwardDiff.JacobianConfig(nothing, C1, A1new) |
| 46 | + |
| 47 | + J1 = ForwardDiff.jacobian((C, A) -> Octavian.matmul!(C, A, B1), C1, A1new, config) |
| 48 | + J2 = ForwardDiff.jacobian((C, A) -> LinearAlgebra.mul!(C, A, B2), C2, A2new, config) |
| 49 | + @test J1 ≈ J2 |
| 50 | + |
| 51 | + # direct version using dual numbers |
| 52 | + A1dual = zeros(eltype(config), reverse(size(A1))...) |
| 53 | + A1dual .= A1' |
| 54 | + C1dual = zeros(eltype(config), size(C1)...) |
| 55 | + |
| 56 | + A2dual = deepcopy(A1dual) |
| 57 | + C2dual = deepcopy(C1dual) |
| 58 | + |
| 59 | + Octavian.matmul!(C1dual, A1dual', B1) |
| 60 | + Octavian.matmul!(C2dual, A2dual', B2) |
| 61 | + @test C1dual ≈ C2dual |
| 62 | + end |
| 63 | +end |
0 commit comments