Skip to content

Commit d29dacf

Browse files
authored
Merge branch 'master' into feature/furlongs_test
2 parents 41999eb + a7991dd commit d29dacf

22 files changed

+677
-323
lines changed

.github/workflows/ci.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: CI
22

33
on:
44
pull_request:
5-
branches:
6-
- master
75
push:
86
branches:
97
- master
@@ -17,7 +15,7 @@ permissions:
1715

1816
jobs:
1917
test:
20-
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
18+
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - NaN-safe mode ${{ matrix.nansafe && 'enabled' || 'disabled' }} - ${{ github.event_name }}
2119
runs-on: ${{ matrix.os }}
2220
strategy:
2321
fail-fast: false
@@ -26,14 +24,26 @@ jobs:
2624
- 'min'
2725
- 'lts'
2826
- '1'
27+
- 'pre'
2928
os:
3029
- ubuntu-latest
30+
- windows-latest
31+
- macOS-latest
32+
nansafe:
33+
- true
34+
- false
3135
steps:
32-
- uses: actions/checkout@v4
36+
- uses: actions/checkout@v5
3337
- uses: julia-actions/setup-julia@v2
3438
with:
3539
version: ${{ matrix.version }}
3640
- uses: julia-actions/cache@v2
41+
- name: Set NaN-safe mode preference
42+
run: |
43+
open(joinpath(pwd(), "Project.toml"), "a") do io
44+
println(io, "\n[preferences.ForwardDiff]\nnansafe_mode = ${{ matrix.nansafe }}\n")
45+
end
46+
shell: julia --color=yes {0}
3747
- uses: julia-actions/julia-buildpkg@v1
3848
- uses: julia-actions/julia-runtest@v1
3949
- uses: julia-actions/julia-processcoverage@v1
@@ -46,7 +56,7 @@ jobs:
4656
name: Documentation
4757
runs-on: ubuntu-latest
4858
steps:
49-
- uses: actions/checkout@v4
59+
- uses: actions/checkout@v5
5060
- uses: julia-actions/setup-julia@v2
5161
with:
5262
version: '1'

Project.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ForwardDiff"
22
uuid = "f6369f11-7733-5829-9624-2563aa707210"
3-
version = "1.0.1"
3+
version = "1.3.0"
44

55
[deps]
66
CommonSubexpressions = "bbf7d656-a473-5ed7-a52c-81e309532950"
@@ -13,7 +13,6 @@ Preferences = "21216c6a-2e73-6563-6e65-726566657250"
1313
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
1414
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1515
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
16-
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1716

1817
[weakdeps]
1918
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
@@ -28,21 +27,23 @@ DiffResults = "1.1"
2827
DiffRules = "1.4"
2928
DiffTests = "0.1"
3029
IrrationalConstants = "0.1, 0.2"
30+
JET = "0.9, 0.10"
3131
LogExpFunctions = "0.3"
3232
NaNMath = "1"
3333
Preferences = "1"
3434
SpecialFunctions = "1, 2"
3535
StaticArrays = "1.5"
36-
julia = "1.6"
36+
julia = "1.10"
3737

3838
[extras]
3939
Calculus = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
4040
DiffTests = "de460e47-3fe3-5279-bb4a-814414816d5d"
4141
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
4242
IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6"
43+
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
4344
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
4445
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
4546
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4647

4748
[targets]
48-
test = ["Calculus", "DiffTests", "IrrationalConstants", "SparseArrays", "StaticArrays", "Test", "InteractiveUtils"]
49+
test = ["Calculus", "DiffTests", "IrrationalConstants", "JET", "SparseArrays", "StaticArrays", "Test", "InteractiveUtils"]

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
[![CI](https://github.com/JuliaDiff/ForwardDiff.jl/workflows/CI/badge.svg)](https://github.com/JuliaDiff/ForwardDiff.jl/actions/workflows/ci.yml)
2-
[![Coverage Status](https://coveralls.io/repos/JuliaDiff/ForwardDiff.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/JuliaDiff/ForwardDiff.jl?branch=master)
1+
[![CI](https://github.com/JuliaDiff/ForwardDiff.jl/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/JuliaDiff/ForwardDiff.jl/actions/workflows/ci.yml?query=branch%3Amaster)
2+
[![codecov](https://codecov.io/gh/JuliaDiff/ForwardDiff.jl/graph/badge.svg?token=SzHfhyoxUa)](https://codecov.io/gh/JuliaDiff/ForwardDiff.jl)
33

44
[![](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliadiff.org/ForwardDiff.jl/stable)
55
[![](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliadiff.org/ForwardDiff.jl/dev)

docs/src/user/advanced.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ julia> @time ForwardDiff.gradient!(out, rosenbrock, x, cfg);
8585
```
8686

8787
The underlying heuristic will compute a suitable chunk size smaller or equal
88-
to the `ForwardDiff.DEFAULT_CHUNK_THRESHOLD` constant. As of ForwardDiff
89-
v0.10.32 and Julia 1.6, this constant can be configured at load time via
88+
to the `ForwardDiff.DEFAULT_CHUNK_THRESHOLD` constant.
89+
This constant can be configured at load time via
9090
[Preferences.jl](https://github.com/JuliaPackaging/Preferences.jl) by setting the
9191
`default_chunk_threshold` value.
9292

ext/ForwardDiffStaticArraysExt.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module ForwardDiffStaticArraysExt
33
using ForwardDiff, StaticArrays
44
using ForwardDiff.LinearAlgebra
55
using ForwardDiff.DiffResults
6-
using ForwardDiff: Dual, partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk,
6+
using ForwardDiff: Dual, partials, npartials, Partials, GradientConfig, JacobianConfig, HessianConfig, Tag, Chunk,
77
gradient, hessian, jacobian, gradient!, hessian!, jacobian!,
88
extract_gradient!, extract_jacobian!, extract_value!,
99
vector_mode_gradient, vector_mode_gradient!,
@@ -47,7 +47,7 @@ ForwardDiff._lyap_div!!(A::StaticArrays.MMatrix, λ::AbstractVector) = ForwardDi
4747
result = Expr(:tuple, [:(partials(T, y, $i)) for i in 1:length(x)]...)
4848
return quote
4949
$(Expr(:meta, :inline))
50-
V = StaticArrays.similar_type(S, valtype($y))
50+
V = StaticArrays.similar_type(S, valtype(T, $y))
5151
return V($result)
5252
end
5353
end
@@ -71,12 +71,13 @@ end
7171
@inline ForwardDiff.jacobian!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::JacobianConfig) where {F} = jacobian!(result, f, x)
7272
@inline ForwardDiff.jacobian!(result::Union{AbstractArray,DiffResult}, f::F, x::StaticArray, cfg::JacobianConfig, ::Val) where {F} = jacobian!(result, f, x)
7373

74-
@generated function extract_jacobian(::Type{T}, ydual::StaticArray, x::S) where {T,S<:StaticArray}
75-
M, N = length(ydual), length(x)
74+
@generated function extract_jacobian(::Type{T}, ydual::Union{StaticArray,Partials}, x::S) where {T,S<:StaticArray}
75+
M = ydual <: Partials ? npartials(ydual) : length(ydual)
76+
N = length(x)
7677
result = Expr(:tuple, [:(partials(T, ydual[$i], $j)) for i in 1:M, j in 1:N]...)
7778
return quote
7879
$(Expr(:meta, :inline))
79-
V = StaticArrays.similar_type(S, valtype(eltype($ydual)), Size($M, $N))
80+
V = StaticArrays.similar_type(S, valtype(T, eltype($ydual)), Size($M, $N))
8081
return V($result)
8182
end
8283
end
@@ -87,7 +88,7 @@ end
8788
end
8889

8990
function extract_jacobian(::Type{T}, ydual::AbstractArray, x::StaticArray) where T
90-
result = similar(ydual, valtype(eltype(ydual)), length(ydual), length(x))
91+
result = similar(ydual, valtype(T, eltype(ydual)), length(ydual), length(x))
9192
return extract_jacobian!(T, result, ydual, length(x))
9293
end
9394

src/ForwardDiff.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ include("gradient.jl")
2222
include("jacobian.jl")
2323
include("hessian.jl")
2424

25-
if !isdefined(Base, :get_extension)
26-
include("../ext/ForwardDiffStaticArraysExt.jl")
27-
end
28-
2925
export DiffResults
3026

3127
end # module

src/apiutils.jl

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,36 @@ end
7272

7373
function seed!(duals::AbstractArray{Dual{T,V,N}}, x,
7474
seed::Partials{N,V} = zero(Partials{N,V})) where {T,V,N}
75-
for idx in structural_eachindex(duals, x)
76-
duals[idx] = Dual{T,V,N}(x[idx], seed)
75+
if isbitstype(V)
76+
for idx in structural_eachindex(duals, x)
77+
duals[idx] = Dual{T,V,N}(x[idx], seed)
78+
end
79+
else
80+
for idx in structural_eachindex(duals, x)
81+
if isassigned(x, idx)
82+
duals[idx] = Dual{T,V,N}(x[idx], seed)
83+
else
84+
Base._unsetindex!(duals, idx)
85+
end
86+
end
7787
end
7888
return duals
7989
end
8090

8191
function seed!(duals::AbstractArray{Dual{T,V,N}}, x,
8292
seeds::NTuple{N,Partials{N,V}}) where {T,V,N}
83-
for (i, idx) in zip(1:N, structural_eachindex(duals, x))
84-
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
93+
if isbitstype(V)
94+
for (i, idx) in zip(1:N, structural_eachindex(duals, x))
95+
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
96+
end
97+
else
98+
for (i, idx) in zip(1:N, structural_eachindex(duals, x))
99+
if isassigned(x, idx)
100+
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
101+
else
102+
Base._unsetindex!(duals, idx)
103+
end
104+
end
85105
end
86106
return duals
87107
end
@@ -90,8 +110,18 @@ function seed!(duals::AbstractArray{Dual{T,V,N}}, x, index,
90110
seed::Partials{N,V} = zero(Partials{N,V})) where {T,V,N}
91111
offset = index - 1
92112
idxs = Iterators.drop(structural_eachindex(duals, x), offset)
93-
for idx in idxs
94-
duals[idx] = Dual{T,V,N}(x[idx], seed)
113+
if isbitstype(V)
114+
for idx in idxs
115+
duals[idx] = Dual{T,V,N}(x[idx], seed)
116+
end
117+
else
118+
for idx in idxs
119+
if isassigned(x, idx)
120+
duals[idx] = Dual{T,V,N}(x[idx], seed)
121+
else
122+
Base._unsetindex!(duals, idx)
123+
end
124+
end
95125
end
96126
return duals
97127
end
@@ -100,8 +130,18 @@ function seed!(duals::AbstractArray{Dual{T,V,N}}, x, index,
100130
seeds::NTuple{N,Partials{N,V}}, chunksize = N) where {T,V,N}
101131
offset = index - 1
102132
idxs = Iterators.drop(structural_eachindex(duals, x), offset)
103-
for (i, idx) in zip(1:chunksize, idxs)
104-
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
133+
if isbitstype(V)
134+
for (i, idx) in zip(1:chunksize, idxs)
135+
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
136+
end
137+
else
138+
for (i, idx) in zip(1:chunksize, idxs)
139+
if isassigned(x, idx)
140+
duals[idx] = Dual{T,V,N}(x[idx], seeds[i])
141+
else
142+
Base._unsetindex!(duals, idx)
143+
end
144+
end
105145
end
106146
return duals
107147
end

src/config.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct InvalidTagException{E,O} <: Exception
2929
end
3030

3131
Base.showerror(io::IO, e::InvalidTagException{E,O}) where {E,O} =
32-
print(io, "Invalid Tag object:\n Expected $E,\n Observed $O.")
32+
print(io, "Invalid Tag object:\n Expected ", E, ",\n Observed ", O, ".")
3333

3434
checktag(::Type{Tag{FT,VT}}, f::F, x::AbstractArray{V}) where {FT,VT,F,V} =
3535
throw(InvalidTagException{Tag{F,V},Tag{FT,VT}}())

0 commit comments

Comments
 (0)