Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 1 addition & 133 deletions .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,6 @@ concurrency:
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}

jobs:
test-DI-Core:
name: ${{ matrix.version }} - DI Core (${{ matrix.group }})
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skipci') }}
timeout-minutes: 180
permissions:
# needed to allow julia-actions/cache to proactively delete old caches that it has created
actions: write
contents: read
strategy:
fail-fast: false # TODO: toggle
matrix:
version:
- '1.10'
- '1.11'
- '1.12'
group:
- Internals
- SimpleFiniteDiff
- ZeroBackends
skip_past:
- ${{ github.event.pull_request.draft }}
exclude:
- skip_past: true
version: '1.10'
- skip_past: true
version: '1.11'
env:
JULIA_DI_TEST_TYPE: 'Core'
JULIA_DI_TEST_GROUP: ${{ matrix.group }}
JULIA_DI_PR_DRAFT: ${{ github.event.pull_request.draft }}
steps:
- uses: actions/checkout@v6
- uses: julia-actions/setup-julia@v3
with:
version: ${{ matrix.version }}
arch: x64
- uses: julia-actions/cache@v3
- name: Install dependencies & run tests
run: julia --color=yes -e ' using Pkg;
Pkg.activate("./DifferentiationInterface/test"); if VERSION < v"1.11";
Pkg.rm("DifferentiationInterfaceTest"); Pkg.resolve(); else;
Pkg.develop(; path="./DifferentiationInterfaceTest"); end;
Pkg.activate("./DifferentiationInterface"); test_kwargs = (;
allow_reresolve=false, coverage=true); if ENV["JULIA_DI_PR_DRAFT"] ==
"true"; Pkg.test("DifferentiationInterface"; julia_args=["-O1"],
test_kwargs...); else; Pkg.test("DifferentiationInterface";
test_kwargs...); end;'
- uses: julia-actions/julia-processcoverage@v1
with:
directories: ./DifferentiationInterface/src,./DifferentiationInterface/ext,./DifferentiationInterface/test
- uses: codecov/codecov-action@v6
with:
files: lcov.info
flags: DI
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false

test-DI-Backend:
name: ${{ matrix.version }} - DI Back (${{ matrix.group }})
runs-on: ubuntu-latest
Expand All @@ -91,24 +33,7 @@ jobs:
- '1.11'
- '1.12'
group:
- ChainRules
- DifferentiateWith
# - Diffractor
- Enzyme
- FastDifferentiation
- FiniteDiff
- FiniteDifferences
- ForwardDiff
- GTPSA
- HyperHessians
- Mooncake
- Mooncake-old
- PolyesterForwardDiff
- ReverseDiff
- SparsityDetector
- Symbolics
- Tracker
- Zygote
skip_past:
- ${{ github.event.pull_request.draft }}
exclude:
Expand Down Expand Up @@ -139,7 +64,7 @@ jobs:
include("./DifferentiationInterface/test/Back/run_backend.jl");'
- name: Install dependencies & run tests (not draft)
if: ${{ !github.event.pull_request.draft }}
run: julia -O1 --code-coverage=user --color=yes -e ' using Pkg; group =
run: julia --code-coverage=user --color=yes -e ' using Pkg; group =
ENV["JULIA_DI_TEST_GROUP"];
Pkg.activate("./DifferentiationInterface/test/Back/$group");
Pkg.develop([PackageSpec(path="./DifferentiationInterface"),
Expand All @@ -154,60 +79,3 @@ jobs:
flags: DI
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false

test-DIT:
name: ${{ matrix.version }} - DIT (${{ matrix.group }})
runs-on: ubuntu-latest
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skipci') }}
timeout-minutes: 60
permissions:
# needed to allow julia-actions/cache to proactively delete old caches that it has created
actions: write
contents: read
strategy:
fail-fast: false # TODO: toggle
matrix:
version:
- '1.10'
- '1.11'
- '1.12'
group:
- Formalities
- Zero
- Standard
- Weird
skip_past:
- ${{ github.event.pull_request.draft }}
exclude:
- skip_past: true
version: '1.10'
- skip_past: true
version: '1.11'
env:
JULIA_DIT_TEST_GROUP: ${{ matrix.group }}
JULIA_DI_PR_DRAFT: ${{ github.event.pull_request.draft }}
steps:
- uses: actions/checkout@v6
- uses: julia-actions/setup-julia@v3
with:
version: ${{ matrix.version }}
arch: x64
- uses: julia-actions/cache@v3
- name: Install dependencies & run tests
run:
julia --project=./DifferentiationInterfaceTest --color=yes -e ' using Pkg;
Pkg.Registry.update(); Pkg.develop(path="./DifferentiationInterface");
if ENV["JULIA_DI_PR_DRAFT"] == "true";
Pkg.test("DifferentiationInterfaceTest"; allow_reresolve=false,
coverage=true, julia_args=["-O1"]); else;
Pkg.test("DifferentiationInterfaceTest"; allow_reresolve=false,
coverage=true); end;'
- uses: julia-actions/julia-processcoverage@v1
with:
directories: ./DifferentiationInterfaceTest/src,./DifferentiationInterfaceTest/ext,./DifferentiationInterfaceTest/test
- uses: codecov/codecov-action@v6
with:
files: lcov.info
flags: DIT
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
207 changes: 16 additions & 191 deletions DifferentiationInterface/test/Back/Enzyme/test.jl
Original file line number Diff line number Diff line change
@@ -1,199 +1,24 @@
include("../../testutils.jl")

using ADTypes: ADTypes
using DifferentiationInterface, DifferentiationInterfaceTest
import DifferentiationInterfaceTest as DIT
using Enzyme: Enzyme
using LinearAlgebra
using StaticArrays
using DifferentiationInterface
import Enzyme
using Test

using ExplicitImports
check_no_implicit_imports(DifferentiationInterface)

backends = [
AutoEnzyme(; mode = nothing),
AutoEnzyme(; mode = Enzyme.Forward),
AutoEnzyme(; mode = Enzyme.Reverse),
AutoEnzyme(; mode = nothing, function_annotation = Enzyme.Const),
]

duplicated_backends = [
AutoEnzyme(; mode = Enzyme.Forward, function_annotation = Enzyme.Duplicated),
AutoEnzyme(; mode = Enzyme.Reverse, function_annotation = Enzyme.Duplicated),
]

@testset "Checks" begin
@testset "Check $(typeof(backend))" for backend in backends
@test check_available(backend)
@test check_inplace(backend)
end
end;

@testset "First order" begin
test_differentiation(
backends, default_scenarios(); excluded = SECOND_ORDER, logging = LOGGING
)

test_differentiation(
backends[1:3],
default_scenarios(; include_normal = false, include_constantified = true);
excluded = SECOND_ORDER,
logging = LOGGING,
)

test_differentiation(
backends[2:3],
default_scenarios(;
include_normal = false,
include_cachified = true,
include_constantorcachified = true,
use_tuples = true,
);
excluded = SECOND_ORDER,
logging = LOGGING,
)

test_differentiation(
duplicated_backends,
default_scenarios(; include_normal = false, include_closurified = true);
excluded = SECOND_ORDER,
logging = LOGGING,
)
end

@testset "Second order" begin
test_differentiation(
AutoEnzyme(),
default_scenarios(; include_constantified = true, include_cachified = true);
excluded = vcat(FIRST_ORDER, :hvp, :hessian),
logging = LOGGING,
)

test_differentiation(
AutoEnzyme(),
default_scenarios(; include_constantified = true);
excluded = vcat(FIRST_ORDER, :second_derivative),
logging = LOGGING,
)
backend = SecondOrder(
AutoEnzyme(; mode = Enzyme.set_runtime_activity(Enzyme.Forward)),
AutoEnzyme(; mode = Enzyme.set_runtime_activity(Enzyme.Reverse))
)

test_differentiation(
# TODO: simplify when https://github.com/EnzymeAD/Enzyme.jl/issues/2854 and https://github.com/EnzymeAD/Enzyme.jl/issues/2925 are fixed
if VERSION >= v"1.11"
SecondOrder(
AutoEnzyme(; mode = Enzyme.set_runtime_activity(Enzyme.Forward)),
AutoEnzyme(; mode = Enzyme.set_runtime_activity(Enzyme.Reverse))
)
else
AutoEnzyme()
end,
default_scenarios(; include_normal = false, include_constantified = false, include_cachified = true);
excluded = vcat(FIRST_ORDER, :second_derivative),
logging = LOGGING,
)

test_differentiation(
[
SecondOrder(
AutoEnzyme(; mode = Enzyme.Reverse), AutoEnzyme(; mode = Enzyme.Forward)
),
],
default_scenarios(; include_constantified = true, include_cachified = true);
excluded = FIRST_ORDER,
logging = LOGGING,
)
end

@testset "Sparse" begin
test_differentiation(
MyAutoSparse.(AutoEnzyme(; function_annotation = Enzyme.Const)),
if VERSION < v"1.11"
sparse_scenarios()
else
filter(s -> s.x isa AbstractVector, sparse_scenarios())
end;
sparsity = true,
logging = LOGGING,
)
end

@testset "Static" begin
filtered_static_scenarios = filter(static_scenarios()) do s
DIT.operator_place(s) == :out && DIT.function_place(s) == :out
end

test_differentiation(
[AutoEnzyme(; mode = Enzyme.Forward), AutoEnzyme(; mode = Enzyme.Reverse)],
filtered_static_scenarios;
excluded = SECOND_ORDER,
logging = LOGGING,
)
struct StoreInCache{F}
f::F
end

@testset "Coverage" begin
# ConstantOrCache without cache
f_nocontext(x, p) = x
@test I == DifferentiationInterface.jacobian(
f_nocontext, AutoEnzyme(; mode = Enzyme.Forward), rand(10), ConstantOrCache(nothing)
)
@test I == DifferentiationInterface.jacobian(
f_nocontext, AutoEnzyme(; mode = Enzyme.Reverse), rand(10), ConstantOrCache(nothing)
)
function (sc::StoreInCache)(x, y_cache)
y_cache[1] = sc.f(x)
return y_cache[1]
end

@testset "Hints" begin
@testset "MutabilityError" begin
f = let
cache = [0.0]
x -> sum(copyto!(cache, x))
end

e = nothing
try
gradient(f, AutoEnzyme(), [1.0])
catch e
end
msg = sprint(showerror, e)
@test occursin("AutoEnzyme", msg)
@test occursin("function_annotation", msg)
@test occursin("ADTypes", msg)
end

@testset "RuntimeActivityError" begin
function g(active_var, constant_var, cond)
if cond
return active_var
else
return constant_var
end
end

function h(active_var, constant_var, cond)
return [g(active_var, constant_var, cond), g(active_var, constant_var, cond)]
end

e = nothing
try
pushforward(
h,
AutoEnzyme(; mode = Enzyme.Forward),
[1.0],
([1.0],),
Constant([1.0]),
Constant(true),
)
catch e
end
msg = sprint(showerror, e)
@test_broken occursin("AutoEnzyme", msg)
@test_broken occursin("ADTypes", msg)
end
end
f(x::AbstractArray) = sum(vec(x .^ 4) .* transpose(vec(x .^ 6)))

@testset "Empty arrays" begin
test_differentiation(
[AutoEnzyme(; mode = Enzyme.Forward), AutoEnzyme(; mode = Enzyme.Reverse)],
empty_scenarios();
excluded = [:jacobian],
)
end;
x = [1.0;;]
dx = [3.0;;]
c = similar(x)
@test_nowarn gradient_and_hvp(StoreInCache(f), backend, x, (dx,), Cache(x))
Loading