Use dependabot and drop support for Julia < 1.10 - #292
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #292 +/- ##
==========================================
- Coverage 86.07% 85.53% -0.54%
==========================================
Files 18 19 +1
Lines 1967 1964 -3
==========================================
- Hits 1693 1680 -13
- Misses 274 284 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The downgrade test resolved FunctionWrappers 1.0.0 and errored in every
testset that exercises a `CompiledTape` (ChainRulesTests, GradientTests,
JacobianTests, HessianTests):
LoadError: Module IR does not contain specified entry function
Stacktrace:
[1] assume @ FunctionWrappers/src/FunctionWrappers.jl:11 [inlined]
...
[5] forward_pass!(compiled_tape::ReverseDiff.CompiledTape{...})
@ ReverseDiff src/api/tape.jl:124
FunctionWrappers <= 1.1.1 defines `assume` with the pre-Julia-1.6 form of
`Base.llvmcall` in which the second element of the tuple is the function
body. Since v"1.6.0-DEV.663" Julia interprets that element as the name of
the entry function in the supplied module IR, so the call fails at run
time. FunctionWrappers 1.1.2 is the first release that branches on
`VERSION` and emits a named `@fw_assume` definition.
ReverseDiff therefore never worked with FunctionWrappers < 1.1.2 on any
Julia version we still support, so the lower bound was simply wrong.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`JacobianConfig` builds its tracked output buffer with
`similar(output, TrackedReal{D,D,Nothing})` and then fills it
element-wise in `track!`. `TrackedReal` is never `isbitstype`: it is a
`mutable struct`, and it holds the `InstructionTape`. `MArray` only
supports `setindex!` for isbits eltypes, since it fakes element
assignment with `unsafe_store!` into its single `NTuple` field.
StaticArrays only returns a `SizedArray` from `similar` for non-isbits
eltypes from 1.6.4 on; 1.6.3 and earlier return an `MArray` whose
`setindex!` errors with
setindex!() with non-isbitstype eltype is not supported by
StaticArrays. Consider using SizedArray.
So `hessian!(::DiffResult, f, ::MVector)` and the corresponding
`jacobian!` path need StaticArrays >= 1.6.4. Without the bound the
Downgrade job would resolve a version that cannot run them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`Statistics` was a hard dependency for exactly one method, `mean(::TrackedArray)`, and its two instruction hooks. Nothing is lost by making it weak. `ReverseDiff` does not export or re-export `mean`, so reaching the method at all requires the name, and every route to it already loads `Statistics`: `using Statistics`, a qualified `Statistics.mean`, or a package such as StatsBase that re-exports it and depends on it. The extension therefore loads exactly when the method can be called. In return `ReverseDiff` stops loading `Statistics` for everyone, which also stops it triggering `StaticArraysStatisticsExt` downstream, since `StaticArrays` is a hard dependency and takes `Statistics` as a weakdep. The tests assert the extension is absent before `using Statistics` and present after. Without them a broken extension would go unnoticed: `TrackedArray <: AbstractArray`, so the generic `mean` falls through to the tracked `sum`, records a different instruction and still returns the right value and gradient. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`julia-downgrade-compat` merges the main and test projects and promotes
weakdeps to dependencies:
Info: Promoting Statistics from weakdep to dependency in merged project
so `Statistics` loads with `ReverseDiff` there and `StatisticsExt` is
always present. The job sets `DOWNGRADE_TEST` for the test step and the
assertion is skipped when it is set. The check that the extension does
load after `using Statistics` still runs everywhere.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drops support for Julia < 1.10 and replaces CompatHelper with dependabot.
.github/dependabot.ymlgains thejuliaecosystem, with all Julia package updates grouped into one daily PR. The CompatHelper workflow is removed.Downgradeworkflow runs the test suite against the declared lower bounds.[extras]/[targets]totest/Project.toml, with[workspace] projects = ["test", "docs"]in the root.julia = "1.10", and the CI matrix testsmin-patchinstead ofmin.Base.div(::TrackedReal, ::TrackedReal, ::RoundingMode)is now defined unconditionally, andSPARSE_CAT_AMBIGUITYdrops itsVERSION >= v"1.10"half.The lower compat bounds are raised to versions that work. One of them is required, not bookkeeping:
StaticArrays = "1.6.4".JacobianConfigbuilds its tracked output buffer withsimilar(output, TrackedReal{D,D,Nothing})and fills it element-wise intrack!.TrackedRealis neverisbitstype: it is amutable struct, and it holds theInstructionTape.MArrayfakes element assignment withunsafe_store!into its singleNTuplefield, so it only supportssetindex!for isbits eltypes. StaticArrays returns aSizedArrayfromsimilarfor non-isbits eltypes from 1.6.4 on; 1.6.3 and earlier return anMArray, whosesetindex!errors withPinning both versions confirms it: 1.6.3 reproduces the error, 1.6.4 returns a
SizedArray. Sohessian!(::DiffResult, f, ::MVector)and the correspondingjacobian!path require 1.6.4. Without the bound theDowngradejob resolves a StaticArrays that cannot run them. #295 fails on the same code path, on Julia 1.0, where the resolver picks StaticArrays 1.3.6.Statisticsbecomes a package extensionStatisticswas a hard dependency for exactly one method,mean(::TrackedArray), and its two instruction hooks. Those move toext/StatisticsExt.jl.Nothing is lost by making it weak. ReverseDiff does not export or re-export
mean, so reaching the method requires the name, and every route to it already loadsStatistics:using Statistics, a qualifiedStatistics.mean, or a package such as StatsBase that re-exports it and depends on it. The extension loads exactly when the method can be called.In return ReverseDiff stops loading
Statisticsfor everyone, which also stops it triggeringStaticArraysStatisticsExtdownstream, since StaticArrays is a hard dependency that takesStatisticsas a weakdep. Measured with@time_imports, that is ~1.2 ms plus ~1.3 ms against a ~1740 msusing ReverseDiff— small, so the argument is the accurate dependency declaration rather than the load time.The tests assert the extension is absent before
using Statisticsand present after. Without that, a broken extension would go unnoticed:TrackedArray <: AbstractArray, so the genericmeanfalls through to the trackedsumand still returns the right value and gradient while recording a different instruction. This is not hypothetical — it happened during development against a stale manifest.🤖 Generated with Claude Code