Skip to content

Commit ca7d681

Browse files
2 parents b514238 + e85ebd3 commit ca7d681

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4622
-474
lines changed

.github/workflows/Tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ jobs:
3737
- "LinearSolvePardiso"
3838
- "NoPre"
3939
- "LinearSolveAutotune"
40+
- "Preferences"
4041
os:
4142
- ubuntu-latest
4243
- macos-latest

Project.toml

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "LinearSolve"
22
uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae"
33
authors = ["SciML"]
4-
version = "3.28.0"
4+
version = "3.40.2"
55

66
[deps]
77
ArrayInterface = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
@@ -17,6 +17,7 @@ Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
1717
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1818
MKL_jll = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
1919
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
20+
OpenBLAS_jll = "4536629a-c528-5b80-bd46-f80d51c5b363"
2021
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
2122
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
2223
RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
@@ -34,6 +35,7 @@ BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0"
3435
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
3536
CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e"
3637
CUSOLVERRF = "a8cc9031-bad2-4722-94f5-40deabb4245c"
38+
CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8"
3739
EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869"
3840
FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e"
3941
FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641"
@@ -59,6 +61,7 @@ LinearSolveBlockDiagonalsExt = "BlockDiagonals"
5961
LinearSolveCUDAExt = "CUDA"
6062
LinearSolveCUDSSExt = "CUDSS"
6163
LinearSolveCUSOLVERRFExt = ["CUSOLVERRF", "SparseArrays"]
64+
LinearSolveCliqueTreesExt = ["CliqueTrees", "SparseArrays"]
6265
LinearSolveEnzymeExt = "EnzymeCore"
6366
LinearSolveFastAlmostBandedMatricesExt = "FastAlmostBandedMatrices"
6467
LinearSolveFastLapackInterfaceExt = "FastLapackInterface"
@@ -75,60 +78,63 @@ LinearSolveSparseArraysExt = "SparseArrays"
7578
LinearSolveSparspakExt = ["SparseArrays", "Sparspak"]
7679

7780
[compat]
78-
AMDGPU = "1"
81+
AMDGPU = "1.2, 2"
7982
AllocCheck = "0.2"
8083
Aqua = "0.8"
81-
ArrayInterface = "7.7"
82-
BandedMatrices = "1.5"
84+
ArrayInterface = "7.17"
85+
BandedMatrices = "1.8"
8386
BlockDiagonals = "0.2"
84-
CUDA = "5"
87+
CUDA = "5.5"
8588
CUDSS = "0.4"
8689
CUSOLVERRF = "0.2.6"
87-
ChainRulesCore = "1.22"
90+
ChainRulesCore = "1.25"
91+
CliqueTrees = "1.11.0"
8892
ConcreteStructs = "0.2.3"
8993
DocStringExtensions = "0.9.3"
9094
EnumX = "1.0.4"
91-
EnzymeCore = "0.8.1"
92-
ExplicitImports = "1"
93-
FastAlmostBandedMatrices = "0.1"
94-
FastLapackInterface = "2"
95-
FiniteDiff = "2.22"
96-
ForwardDiff = "0.10.36, 1"
95+
EnzymeCore = "0.8.5"
96+
ExplicitImports = "1.10"
97+
FastAlmostBandedMatrices = "0.1.4"
98+
FastLapackInterface = "2.0.4"
99+
FiniteDiff = "2.26"
100+
ForwardDiff = "0.10.38, 1"
97101
GPUArraysCore = "0.2"
98-
HYPRE = "1.4.0"
102+
HYPRE = "1.7"
99103
InteractiveUtils = "1.10"
100-
IterativeSolvers = "0.9.3"
101-
KernelAbstractions = "0.9.27"
104+
IterativeSolvers = "0.9.4"
105+
KernelAbstractions = "0.9.30"
102106
Krylov = "0.10"
103107
KrylovKit = "0.10"
104108
KrylovPreconditioners = "0.3"
105109
LAPACK_jll = "3"
106-
LazyArrays = "1.8, 2"
110+
LazyArrays = "2.3"
107111
Libdl = "1.10"
108112
LinearAlgebra = "1.10"
113+
MKL_jll = "2019, 2020, 2021, 2022, 2023, 2024, 2025"
109114
MPI = "0.20"
110115
Markdown = "1.10"
111-
Metal = "1"
112-
MultiFloats = "1"
113-
Pardiso = "0.5.7, 1"
114-
Pkg = "1"
116+
Metal = "1.4"
117+
MultiFloats = "2.3"
118+
OpenBLAS_jll = "0.3"
119+
Pardiso = "1"
120+
Pkg = "1.10"
115121
PrecompileTools = "1.2"
116122
Preferences = "1.4"
117-
Random = "1"
118-
RecursiveArrayTools = "3.27.2"
119-
RecursiveFactorization = "0.2.14"
120-
Reexport = "1"
123+
Random = "1.10"
124+
RecursiveArrayTools = "3.37"
125+
RecursiveFactorization = "0.2.23"
126+
Reexport = "1.2.2"
121127
SafeTestsets = "0.1"
122128
SciMLBase = "2.70"
123-
SciMLOperators = "1"
124-
Setfield = "1"
129+
SciMLOperators = "1.7.1"
130+
Setfield = "1.1.1"
125131
SparseArrays = "1.10"
126-
Sparspak = "0.3.6"
127-
StableRNGs = "1"
128-
StaticArrays = "1.5"
129-
StaticArraysCore = "1.4.2"
130-
Test = "1"
131-
UnPack = "1"
132+
Sparspak = "0.3.9"
133+
StableRNGs = "1.0"
134+
StaticArrays = "1.9"
135+
StaticArraysCore = "1.4.3"
136+
Test = "1.10"
137+
UnPack = "1.0.2"
132138
Zygote = "0.7"
133139
blis_jll = "0.9.0"
134140
julia = "1.10"
@@ -138,6 +144,7 @@ AllocCheck = "9b6a8646-10ed-4001-bbdc-1d2f46dfbb1a"
138144
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
139145
BandedMatrices = "aae01518-5342-5314-be14-df237901396f"
140146
BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0"
147+
CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8"
141148
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
142149
FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e"
143150
FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641"
@@ -166,4 +173,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
166173
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
167174

168175
[targets]
169-
test = ["Aqua", "Test", "IterativeSolvers", "InteractiveUtils", "KrylovKit", "KrylovPreconditioners", "Pkg", "Random", "SafeTestsets", "MultiFloats", "ForwardDiff","Mooncake", "HYPRE", "MPI", "BlockDiagonals", "FiniteDiff", "BandedMatrices", "FastAlmostBandedMatrices", "StaticArrays", "AllocCheck", "StableRNGs", "Zygote", "RecursiveFactorization", "Sparspak", "FastLapackInterface", "SparseArrays", "ExplicitImports"]
176+
test = ["Aqua", "Test", "IterativeSolvers", "InteractiveUtils", "KrylovKit", "KrylovPreconditioners", "Pkg", "Random", "SafeTestsets", "MultiFloats", "ForwardDiff", "HYPRE", "MPI", "BlockDiagonals", "FiniteDiff", "BandedMatrices", "FastAlmostBandedMatrices", "StaticArrays", "AllocCheck", "StableRNGs", "Zygote", "RecursiveFactorization", "Sparspak", "CliqueTrees", "FastLapackInterface", "SparseArrays", "ExplicitImports"]

docs/pages.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ pages = ["index.md",
88
"tutorials/gpu.md",
99
"tutorials/autotune.md"],
1010
"Basics" => Any["basics/LinearProblem.md",
11+
"basics/algorithm_selection.md",
1112
"basics/common_solver_opts.md",
1213
"basics/OperatorAssumptions.md",
1314
"basics/Preconditioners.md",
1415
"basics/FAQ.md"],
1516
"Solvers" => Any["solvers/solvers.md"],
16-
"Advanced" => Any["advanced/developing.md"
17-
"advanced/custom.md"],
17+
"Advanced" => Any["advanced/developing.md",
18+
"advanced/custom.md",
19+
"advanced/internal_api.md"],
1820
"Release Notes" => "release_notes.md"
1921
]

docs/src/advanced/internal_api.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# Internal API Documentation
2+
3+
This page documents LinearSolve.jl's internal API, which is useful for developers who want to understand the package's architecture, contribute to the codebase, or develop custom linear solver algorithms.
4+
5+
## Abstract Type Hierarchy
6+
7+
LinearSolve.jl uses a well-structured type hierarchy to organize different classes of linear solver algorithms:
8+
9+
```@docs
10+
LinearSolve.SciMLLinearSolveAlgorithm
11+
LinearSolve.AbstractFactorization
12+
LinearSolve.AbstractDenseFactorization
13+
LinearSolve.AbstractSparseFactorization
14+
LinearSolve.AbstractKrylovSubspaceMethod
15+
LinearSolve.AbstractSolveFunction
16+
```
17+
18+
## Core Cache System
19+
20+
The caching system is central to LinearSolve.jl's performance and functionality:
21+
22+
```@docs
23+
LinearSolve.LinearCache
24+
LinearSolve.init_cacheval
25+
```
26+
27+
## Algorithm Selection
28+
29+
The automatic algorithm selection is one of LinearSolve.jl's key features:
30+
31+
```@docs
32+
LinearSolve.defaultalg
33+
LinearSolve.get_tuned_algorithm
34+
LinearSolve.is_algorithm_available
35+
LinearSolve.show_algorithm_choices
36+
LinearSolve.make_preferences_dynamic!
37+
```
38+
39+
### Preference System Architecture
40+
41+
The dual preference system provides intelligent algorithm selection with comprehensive fallbacks:
42+
43+
#### **Core Functions**
44+
- **`get_tuned_algorithm`**: Retrieves tuned algorithm preferences based on matrix size and element type
45+
- **`is_algorithm_available`**: Checks if a specific algorithm is currently available (extensions loaded)
46+
- **`show_algorithm_choices`**: Analysis function displaying algorithm choices for all element types
47+
- **`make_preferences_dynamic!`**: Testing function that enables runtime preference checking
48+
49+
#### **Size Categorization**
50+
The system categorizes matrix sizes to match LinearSolveAutotune benchmarking:
51+
- **tiny**: ≤20 elements (matrices ≤10 always override to GenericLU)
52+
- **small**: 21-100 elements
53+
- **medium**: 101-300 elements
54+
- **large**: 301-1000 elements
55+
- **big**: >1000 elements
56+
57+
#### **Dual Preference Structure**
58+
For each category and element type (Float32, Float64, ComplexF32, ComplexF64):
59+
- `best_algorithm_{type}_{size}`: Overall fastest algorithm from autotune
60+
- `best_always_loaded_{type}_{size}`: Fastest always-available algorithm (fallback)
61+
62+
#### **Preference File Organization**
63+
All preference-related functionality is consolidated in `src/preferences.jl`:
64+
65+
**Compile-Time Constants**:
66+
- `AUTOTUNE_PREFS`: Preference structure loaded at package import
67+
- `AUTOTUNE_PREFS_SET`: Fast path check for whether any preferences are set
68+
- `_string_to_algorithm_choice`: Mapping from preference strings to algorithm enums
69+
70+
**Runtime Functions**:
71+
- `_get_tuned_algorithm_runtime`: Dynamic preference checking for testing
72+
- `_choose_available_algorithm`: Algorithm availability and fallback logic
73+
- `show_algorithm_choices`: Comprehensive analysis and display function
74+
75+
**Testing Infrastructure**:
76+
- `make_preferences_dynamic!`: Eval-based function redefinition for testing
77+
- Enables runtime preference verification without affecting production performance
78+
79+
#### **Testing Mode Operation**
80+
The testing system uses an elegant eval-based approach:
81+
```julia
82+
# Production: Uses compile-time constants (maximum performance)
83+
get_tuned_algorithm(Float64, Float64, 200) # → Uses AUTOTUNE_PREFS constants
84+
85+
# Testing: Redefines function to use runtime checking
86+
make_preferences_dynamic!()
87+
get_tuned_algorithm(Float64, Float64, 200) # → Uses runtime preference loading
88+
```
89+
90+
This approach maintains type stability and inference while enabling comprehensive testing.
91+
92+
#### **Algorithm Support Scope**
93+
The preference system focuses exclusively on LU algorithms for dense matrices:
94+
95+
**Supported LU Algorithms**:
96+
- `LUFactorization`, `GenericLUFactorization`, `RFLUFactorization`
97+
- `MKLLUFactorization`, `AppleAccelerateLUFactorization`
98+
- `SimpleLUFactorization`, `FastLUFactorization` (both map to LU)
99+
- GPU LU variants (CUDA, Metal, AMDGPU - all map to LU)
100+
101+
**Non-LU algorithms** (QR, Cholesky, SVD, etc.) are not included in the preference system
102+
as they serve different use cases and are not typically the focus of dense matrix autotune optimization.
103+
104+
## Trait Functions
105+
106+
These trait functions help determine algorithm capabilities and requirements:
107+
108+
```@docs
109+
LinearSolve.needs_concrete_A
110+
```
111+
112+
## Utility Functions
113+
114+
Various utility functions support the core functionality:
115+
116+
```@docs
117+
LinearSolve.default_tol
118+
LinearSolve.default_alias_A
119+
LinearSolve.default_alias_b
120+
LinearSolve.__init_u0_from_Ab
121+
```
122+
123+
## Solve Functions
124+
125+
For custom solving strategies:
126+
127+
```@docs
128+
LinearSolve.LinearSolveFunction
129+
LinearSolve.DirectLdiv!
130+
```
131+
132+
## Preconditioner Infrastructure
133+
134+
The preconditioner system allows for flexible preconditioning strategies:
135+
136+
```@docs
137+
LinearSolve.ComposePreconditioner
138+
LinearSolve.InvPreconditioner
139+
```
140+
141+
## Internal Algorithm Types
142+
143+
These are internal algorithm implementations:
144+
145+
```@docs
146+
LinearSolve.SimpleLUFactorization
147+
LinearSolve.LUSolver
148+
```
149+
150+
## Developer Notes
151+
152+
### Adding New Algorithms
153+
154+
When adding a new linear solver algorithm to LinearSolve.jl:
155+
156+
1. **Choose the appropriate abstract type**: Inherit from the most specific abstract type that fits your algorithm
157+
2. **Implement required methods**: At minimum, implement `solve!` and possibly `init_cacheval`
158+
3. **Consider trait functions**: Override trait functions like `needs_concrete_A` if needed
159+
4. **Document thoroughly**: Add comprehensive docstrings following the patterns shown here
160+
161+
### Performance Considerations
162+
163+
- The `LinearCache` system is designed for efficient repeated solves
164+
- Use `cache.isfresh` to avoid redundant computations when the matrix hasn't changed
165+
- Consider implementing specialized `init_cacheval` for algorithms that need setup
166+
- Leverage trait functions to optimize dispatch and memory usage
167+
168+
### Testing Guidelines
169+
170+
When adding new functionality:
171+
172+
- Test with various matrix types (dense, sparse, GPU arrays)
173+
- Verify caching behavior works correctly
174+
- Ensure trait functions return appropriate values
175+
- Test integration with the automatic algorithm selection system

0 commit comments

Comments
 (0)