Skip to content

Commit 164f9e8

Browse files
authored
Try to improve type stability with Householder (#184)
* rework algorithms for type stability * more or less give up and just force things to be type stable * fix algos maybe * avoid generated function * no longer test deprecated algorithms * export Householder * handle empty tuples * handle all tuples? * one more try * revert to generated functions * add comment
1 parent bb27392 commit 164f9e8

13 files changed

Lines changed: 95 additions & 68 deletions

File tree

ext/MatrixAlgebraKitGenericLinearAlgebraExt.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ end
5858

5959
function MatrixAlgebraKit.householder_qr!(
6060
driver::MatrixAlgebraKit.GLA, A::AbstractMatrix, Q::AbstractMatrix, R::AbstractMatrix;
61-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
61+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
6262
)
63-
blocksize == 1 ||
63+
blocksize <= 1 ||
6464
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
6565
pivoted &&
6666
throw(ArgumentError(lazy"$driver does not provide a pivoted QR decomposition"))
@@ -102,9 +102,9 @@ end
102102

103103
function MatrixAlgebraKit.householder_qr_null!(
104104
driver::MatrixAlgebraKit.GLA, A::AbstractMatrix, N::AbstractMatrix;
105-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
105+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
106106
)
107-
blocksize == 1 ||
107+
blocksize <= 1 ||
108108
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
109109
pivoted &&
110110
throw(ArgumentError(lazy"$driver does not provide a pivoted QR decomposition"))

src/MatrixAlgebraKit.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export left_polar!, right_polar!
3131
export left_orth, right_orth, left_null, right_null
3232
export left_orth!, right_orth!, left_null!, right_null!
3333

34-
export Native_HouseholderQR, Native_HouseholderLQ
34+
export Householder, Native_HouseholderQR, Native_HouseholderLQ
3535
export LAPACK_HouseholderQR, LAPACK_HouseholderLQ, LAPACK_Simple, LAPACK_Expert,
3636
LAPACK_QRIteration, LAPACK_Bisection, LAPACK_MultipleRelativelyRobustRepresentations,
3737
LAPACK_DivideAndConquer, LAPACK_Jacobi

src/algorithms.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,20 @@ See also [`@algdef`](@ref).
1919
"""
2020
struct Algorithm{name, K} <: AbstractAlgorithm
2121
kwargs::K
22+
23+
# Ensure keywords are always in canonical order
24+
function Algorithm{Name}(kwargs::NamedTuple) where {Name}
25+
kwargs_sorted = _canonicalize_namedtuple(kwargs)
26+
return new{Name, typeof(kwargs_sorted)}(kwargs_sorted)
27+
end
2228
end
29+
Algorithm{Name}(; kwargs...) where {Name} = Algorithm{Name}(NamedTuple(kwargs))
30+
31+
# Utility function to canonicalize keys
32+
# TODO: generated function can likely be dropped once Julia 1.10 support is dropped
33+
@generated _canonicalize_namedtuple(nt::NamedTuple{N}) where {N} =
34+
:(NamedTuple{$(Tuple(sort(collect(N))))}(nt))
35+
2336
name(alg::Algorithm) = name(typeof(alg))
2437
name(::Type{<:Algorithm{N}}) where {N} = N
2538

@@ -88,7 +101,9 @@ Finally, the same behavior is obtained when the keyword arguments are
88101
passed as the third positional argument in the form of a `NamedTuple`.
89102
""" select_algorithm
90103

91-
@inline function select_algorithm(f::F, A, alg::Alg = nothing; kwargs...) where {F, Alg}
104+
# WARNING: In order to keep everything type stable, this function is marked as foldable.
105+
# This mostly means that the `default_algorithm` implementation must be foldable as well
106+
Base.@assume_effects :foldable function select_algorithm(f::F, A, alg::Alg = nothing; kwargs...) where {F, Alg}
92107
if isnothing(alg)
93108
return default_algorithm(f, A; kwargs...)
94109
elseif alg isa Symbol
@@ -117,8 +132,10 @@ In general, this is called by [`select_algorithm`](@ref) if no algorithm is spec
117132
explicitly.
118133
New types should prefer to register their default algorithms in the type domain.
119134
""" default_algorithm
120-
default_algorithm(f::F, A; kwargs...) where {F} = default_algorithm(f, typeof(A); kwargs...)
121-
default_algorithm(f::F, A, B; kwargs...) where {F} = default_algorithm(f, typeof(A), typeof(B); kwargs...)
135+
@inline default_algorithm(f::F, A; kwargs...) where {F} =
136+
default_algorithm(f, typeof(A); kwargs...)
137+
@inline default_algorithm(f::F, A, B; kwargs...) where {F} =
138+
default_algorithm(f, typeof(A), typeof(B); kwargs...)
122139
# avoid infinite recursion:
123140
function default_algorithm(f::F, ::Type{T}; kwargs...) where {F, T}
124141
throw(MethodError(default_algorithm, (f, T)))
@@ -299,11 +316,6 @@ macro algdef(name)
299316
return esc(
300317
quote
301318
const $name{K} = Algorithm{$(QuoteNode(name)), K}
302-
function $name(; kwargs...)
303-
# TODO: is this necessary/useful?
304-
kw = NamedTuple(kwargs) # normalize type
305-
return $name{typeof(kw)}(kw)
306-
end
307319
function Base.show(io::IO, alg::$name)
308320
return ($_show_alg)(io, alg)
309321
end

src/implementations/lq.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@ householder_lq!(driver::Union{CUSOLVER, ROCSOLVER, GLA}, A, L, Q; kwargs...) =
120120
lq_via_qr!(A, L, Q, Householder(; driver, kwargs...))
121121
function householder_lq!(
122122
driver::LAPACK, A::AbstractMatrix, L::AbstractMatrix, Q::AbstractMatrix;
123-
positive = true, pivoted = false,
124-
blocksize = ((pivoted || A === Q) ? 1 : YALAPACK.default_qr_blocksize(A))
123+
positive = true, pivoted = false, blocksize::Int = 0
125124
)
125+
blocksize = blocksize > 0 ? blocksize : ((pivoted || A === Q) ? 1 : YALAPACK.default_qr_blocksize(A))
126+
126127
# error messages for disallowing driver - setting combinations
127128
pivoted && (blocksize > 1) &&
128129
throw(ArgumentError(lazy"$driver does not provide a blocked pivoted LQ decomposition"))
@@ -176,10 +177,10 @@ function householder_lq!(
176177
end
177178
function householder_lq!(
178179
driver::Native, A::AbstractMatrix, L::AbstractMatrix, Q::AbstractMatrix;
179-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
180+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
180181
)
181182
# error messages for disallowing driver - setting combinations
182-
blocksize == 1 ||
183+
blocksize <= 1 ||
183184
throw(ArgumentError(lazy"$driver does not provide a blocked LQ decomposition"))
184185
pivoted &&
185186
throw(ArgumentError(lazy"$driver does not provide a pivoted LQ decomposition"))
@@ -225,8 +226,10 @@ householder_lq_null!(driver::Union{CUSOLVER, ROCSOLVER, GLA}, A, Nᴴ; kwargs...
225226
lq_null_via_qr!(A, Nᴴ, Householder(; driver, kwargs...))
226227
function householder_lq_null!(
227228
driver::LAPACK, A::AbstractMatrix, Nᴴ::AbstractMatrix;
228-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = pivoted ? 1 : YALAPACK.default_qr_blocksize(A)
229+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
229230
)
231+
blocksize = blocksize > 0 ? blocksize : (pivoted ? 1 : YALAPACK.default_qr_blocksize(A))
232+
230233
# error messages for disallowing driver - setting combinations
231234
pivoted && (blocksize > 1) &&
232235
throw(ArgumentError(lazy"$driver does not provide a blocked pivoted LQ decomposition"))
@@ -248,10 +251,10 @@ function householder_lq_null!(
248251
end
249252
function householder_lq_null!(
250253
driver::Native, A::AbstractMatrix, Nᴴ::AbstractMatrix;
251-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
254+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
252255
)
253256
# error messages for disallowing driver - setting combinations
254-
blocksize == 1 ||
257+
blocksize <= 1 ||
255258
throw(ArgumentError(lazy"$driver does not provide a blocked LQ decomposition"))
256259
pivoted &&
257260
throw(ArgumentError(lazy"$driver does not provide a pivoted LQ decomposition"))

src/implementations/qr.jl

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,10 @@ householder_qr!(::DefaultDriver, A, Q, R; kwargs...) =
121121
function householder_qr!(
122122
driver::Union{LAPACK, CUSOLVER, ROCSOLVER}, A::AbstractMatrix, Q::AbstractMatrix, R::AbstractMatrix;
123123
positive::Bool = true, pivoted::Bool = false,
124-
blocksize::Int = ((driver !== LAPACK() || pivoted || A === Q) ? 1 : YALAPACK.default_qr_blocksize(A))
124+
blocksize::Int = 0
125125
)
126+
blocksize = blocksize > 0 ? blocksize : ((driver !== LAPACK() || pivoted || A === Q) ? 1 : YALAPACK.default_qr_blocksize(A))
127+
126128
# error messages for disallowing driver - setting combinations
127129
(blocksize == 1 || driver === LAPACK()) ||
128130
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
@@ -202,10 +204,10 @@ function householder_qr!(
202204
end
203205
function householder_qr!(
204206
driver::Native, A::AbstractMatrix, Q::AbstractMatrix, R::AbstractMatrix;
205-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
207+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
206208
)
207209
# error messages for disallowing driver - setting combinations
208-
blocksize == 1 ||
210+
blocksize <= 1 ||
209211
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
210212
pivoted &&
211213
throw(ArgumentError(lazy"$driver does not provide a pivoted QR decomposition"))
@@ -249,9 +251,9 @@ householder_qr_null!(::DefaultDriver, A, N; kwargs...) =
249251
householder_qr_null!(default_householder_driver(A), A, N; kwargs...)
250252
function householder_qr_null!(
251253
driver::Union{LAPACK, CUSOLVER, ROCSOLVER}, A::AbstractMatrix, N::AbstractMatrix;
252-
positive::Bool = true, pivoted::Bool = false,
253-
blocksize::Int = ((driver !== LAPACK() || pivoted) ? 1 : YALAPACK.default_qr_blocksize(A))
254+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
254255
)
256+
blocksize = blocksize > 0 ? blocksize : ((driver !== LAPACK() || pivoted) ? 1 : YALAPACK.default_qr_blocksize(A))
255257
# error messages for disallowing driver - setting combinations
256258
(blocksize == 1 || driver === LAPACK()) ||
257259
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
@@ -277,10 +279,10 @@ function householder_qr_null!(
277279
end
278280
function householder_qr_null!(
279281
driver::Native, A::AbstractMatrix, N::AbstractMatrix;
280-
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 1
282+
positive::Bool = true, pivoted::Bool = false, blocksize::Int = 0
281283
)
282284
# error messages for disallowing driver - setting combinations
283-
blocksize == 1 ||
285+
blocksize <= 1 ||
284286
throw(ArgumentError(lazy"$driver does not provide a blocked QR decomposition"))
285287
pivoted &&
286288
throw(ArgumentError(lazy"$driver does not provide a pivoted QR decomposition"))

src/interface/decompositions.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,17 @@ The optional `driver` symbol can be used to choose between different implementat
7474
7575
- `positive::Bool = true` : Fix the gauge of the resulting factors by making the diagonal elements of `L` or `R` non-negative.
7676
- `pivoted::Bool = false` : Use column- or row-pivoting for low-rank input matrices.
77-
- `blocksize::Int` : Use a blocked version of the algorithm if `blocksize > 1`.
77+
- `blocksize::Int` : Use a blocked version of the algorithm if `blocksize > 1`. Use the default if `blocksize ≤ 0`.
7878
7979
Depending on the driver, various other keywords may be (un)available to customize the implementation.
8080
"""
8181
@algdef Householder
82+
function Householder(;
83+
blocksize::Int = 0, driver::Driver = DefaultDriver(),
84+
pivoted::Bool = false, positive::Bool = true
85+
)
86+
return Householder((; blocksize, driver, pivoted, positive))
87+
end
8288

8389
default_householder_driver(A) = default_householder_driver(typeof(A))
8490
default_householder_driver(::Type) = Native()

src/interface/lq.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ See also [`qr_full(!)`](@ref lq_full) and [`qr_compact(!)`](@ref lq_compact).
7171
default_lq_algorithm(A; kwargs...) = default_lq_algorithm(typeof(A); kwargs...)
7272

7373
default_lq_algorithm(T::Type; kwargs...) = throw(MethodError(default_lq_algorithm, (T,)))
74-
default_lq_algorithm(::Type{T}; driver = default_householder_driver(T), kwargs...) where {T <: AbstractMatrix} =
75-
Householder(; driver, kwargs...)
74+
default_lq_algorithm(::Type{T}; kwargs...) where {T <: AbstractMatrix} =
75+
Householder(; kwargs...)
7676
default_lq_algorithm(::Type{T}; kwargs...) where {T <: Diagonal} =
7777
DiagonalAlgorithm(; kwargs...)
7878
default_lq_algorithm(::Type{<:Base.ReshapedArray{T, N, A}}) where {T, N, A} =

src/interface/orthnull.jl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -334,79 +334,79 @@ See also [`left_null(!)`](@ref left_null), [`left_orth(!)`](@ref left_orth) and
334334
@inline select_algorithm(::typeof(right_null!), A, alg::Symbol; kwargs...) =
335335
select_algorithm(right_null!, A, Val(alg); kwargs...)
336336

337-
function select_algorithm(::typeof(left_orth!), A, ::Val{:qr}; trunc = nothing, kwargs...)
337+
@inline function select_algorithm(::typeof(left_orth!), A, ::Val{:qr}; trunc = nothing, kwargs...)
338338
isnothing(trunc) ||
339339
throw(ArgumentError("QR-based `left_orth` is incompatible with specifying `trunc`"))
340340
alg′ = select_algorithm(qr_compact!, A; kwargs...)
341341
return LeftOrthViaQR(alg′)
342342
end
343-
function select_algorithm(::typeof(left_orth!), A, ::Val{:polar}; trunc = nothing, kwargs...)
343+
@inline function select_algorithm(::typeof(left_orth!), A, ::Val{:polar}; trunc = nothing, kwargs...)
344344
isnothing(trunc) ||
345345
throw(ArgumentError("Polar-based `left_orth` is incompatible with specifying `trunc`"))
346346
alg′ = select_algorithm(left_polar!, A; kwargs...)
347347
return LeftOrthViaPolar(alg′)
348348
end
349-
function select_algorithm(::typeof(left_orth!), A, ::Val{:svd}; trunc = nothing, kwargs...)
349+
@inline function select_algorithm(::typeof(left_orth!), A, ::Val{:svd}; trunc = nothing, kwargs...)
350350
alg′ = isnothing(trunc) ? select_algorithm(svd_compact!, A; kwargs...) :
351351
select_algorithm(svd_trunc!, A; trunc, kwargs...)
352352
return LeftOrthViaSVD(alg′)
353353
end
354354

355-
function select_algorithm(::typeof(right_orth!), A, ::Val{:lq}; trunc = nothing, kwargs...)
355+
@inline function select_algorithm(::typeof(right_orth!), A, ::Val{:lq}; trunc = nothing, kwargs...)
356356
isnothing(trunc) ||
357357
throw(ArgumentError("LQ-based `right_orth` is incompatible with specifying `trunc`"))
358358
alg = select_algorithm(lq_compact!, A; kwargs...)
359359
return RightOrthViaLQ(alg)
360360
end
361-
function select_algorithm(::typeof(right_orth!), A, ::Val{:polar}; trunc = nothing, kwargs...)
361+
@inline function select_algorithm(::typeof(right_orth!), A, ::Val{:polar}; trunc = nothing, kwargs...)
362362
isnothing(trunc) ||
363363
throw(ArgumentError("Polar-based `right_orth` is incompatible with specifying `trunc`"))
364364
alg = select_algorithm(right_polar!, A; kwargs...)
365365
return RightOrthViaPolar(alg)
366366
end
367-
function select_algorithm(::typeof(right_orth!), A, ::Val{:svd}; trunc = nothing, kwargs...)
367+
@inline function select_algorithm(::typeof(right_orth!), A, ::Val{:svd}; trunc = nothing, kwargs...)
368368
alg′ = isnothing(trunc) ? select_algorithm(svd_compact!, A; kwargs...) :
369369
select_algorithm(svd_trunc!, A; trunc, kwargs...)
370370
return RightOrthViaSVD(alg′)
371371
end
372372

373-
function select_algorithm(::typeof(left_null!), A, ::Val{:qr}; trunc = nothing, kwargs...)
373+
@inline function select_algorithm(::typeof(left_null!), A, ::Val{:qr}; trunc = nothing, kwargs...)
374374
isnothing(trunc) ||
375375
throw(ArgumentError("QR-based `left_null` is incompatible with specifying `trunc`"))
376376
alg = select_algorithm(qr_null!, A; kwargs...)
377377
return LeftNullViaQR(alg)
378378
end
379-
function select_algorithm(::typeof(left_null!), A, ::Val{:svd}; trunc = nothing, kwargs...)
379+
@inline function select_algorithm(::typeof(left_null!), A, ::Val{:svd}; trunc = nothing, kwargs...)
380380
alg_svd = select_algorithm(svd_full!, A, get(kwargs, :svd, nothing))
381381
alg = TruncatedAlgorithm(alg_svd, select_null_truncation(trunc))
382382
return LeftNullViaSVD(alg)
383383
end
384384

385-
function select_algorithm(::typeof(right_null!), A, ::Val{:lq}; trunc = nothing, kwargs...)
385+
@inline function select_algorithm(::typeof(right_null!), A, ::Val{:lq}; trunc = nothing, kwargs...)
386386
isnothing(trunc) ||
387387
throw(ArgumentError("LQ-based `right_null` is incompatible with specifying `trunc`"))
388388
alg = select_algorithm(lq_null!, A; kwargs...)
389389
return RightNullViaLQ(alg)
390390
end
391-
function select_algorithm(::typeof(right_null!), A, ::Val{:svd}; trunc = nothing, kwargs...)
391+
@inline function select_algorithm(::typeof(right_null!), A, ::Val{:svd}; trunc = nothing, kwargs...)
392392
alg_svd = select_algorithm(svd_full!, A; kwargs...)
393393
alg = TruncatedAlgorithm(alg_svd, select_null_truncation(trunc))
394394
return RightNullViaSVD(alg)
395395
end
396396

397-
default_algorithm(::typeof(left_orth!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
397+
@inline default_algorithm(::typeof(left_orth!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
398398
isnothing(trunc) ? select_algorithm(left_orth!, A, Val(:qr); kwargs...) :
399399
select_algorithm(left_orth!, A, Val(:svd); trunc, kwargs...)
400400

401-
default_algorithm(::typeof(right_orth!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
401+
@inline default_algorithm(::typeof(right_orth!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
402402
isnothing(trunc) ? select_algorithm(right_orth!, A, Val(:lq); kwargs...) :
403403
select_algorithm(right_orth!, A, Val(:svd); trunc, kwargs...)
404404

405-
default_algorithm(::typeof(left_null!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
405+
@inline default_algorithm(::typeof(left_null!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
406406
isnothing(trunc) ? select_algorithm(left_null!, A, Val(:qr); kwargs...) :
407407
select_algorithm(left_null!, A, Val(:svd); trunc, kwargs...)
408408

409-
default_algorithm(::typeof(right_null!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
409+
@inline default_algorithm(::typeof(right_null!), ::Type{A}; trunc = nothing, kwargs...) where {A} =
410410
isnothing(trunc) ? select_algorithm(right_null!, A, Val(:lq); kwargs...) :
411411
select_algorithm(right_null!, A, Val(:svd); trunc, kwargs...)
412412

src/interface/qr.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ See also [`lq_full(!)`](@ref lq_full) and [`lq_compact(!)`](@ref lq_compact).
7171
default_qr_algorithm(A; kwargs...) = default_qr_algorithm(typeof(A); kwargs...)
7272

7373
default_qr_algorithm(T::Type; kwargs...) = throw(MethodError(default_qr_algorithm, (T,)))
74-
default_qr_algorithm(::Type{T}; driver = default_householder_driver(T), kwargs...) where {T <: AbstractMatrix} =
75-
Householder(; driver, kwargs...)
74+
default_qr_algorithm(::Type{T}; kwargs...) where {T <: AbstractMatrix} =
75+
Householder(; kwargs...)
7676
default_qr_algorithm(::Type{T}; kwargs...) where {T <: Diagonal} =
7777
DiagonalAlgorithm(; kwargs...)
7878
default_qr_algorithm(::Type{<:Base.ReshapedArray{T, N, A}}) where {T, N, A} =

test/algorithms.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ using MatrixAlgebraKit
22
using Test
33
using TestExtras
44
using MatrixAlgebraKit: LAPACK_SVDAlgorithm, PolarViaSVD, TruncatedAlgorithm,
5-
default_algorithm, select_algorithm, Householder, LAPACK
5+
default_algorithm, select_algorithm, Householder, DefaultDriver
66

77
@testset "default_algorithm" begin
88
A = randn(3, 3)
@@ -17,21 +17,21 @@ using MatrixAlgebraKit: LAPACK_SVDAlgorithm, PolarViaSVD, TruncatedAlgorithm,
1717
LAPACK_MultipleRelativelyRobustRepresentations()
1818
end
1919
for f in (lq_full!, lq_full, lq_compact!, lq_compact, lq_null!, lq_null)
20-
@test @constinferred(default_algorithm(f, A)) == Householder(; driver = LAPACK())
20+
@test @constinferred(default_algorithm(f, A)) == Householder()
2121
end
2222
for f in (left_polar!, left_polar, right_polar!, right_polar)
2323
@test @constinferred(default_algorithm(f, A)) ==
2424
PolarViaSVD(LAPACK_DivideAndConquer())
2525
end
2626
for f in (qr_full!, qr_full, qr_compact!, qr_compact, qr_null!, qr_null)
27-
@test @constinferred(default_algorithm(f, A)) == Householder(; driver = LAPACK())
27+
@test @constinferred(default_algorithm(f, A)) == Householder()
2828
end
2929
for f in (schur_full!, schur_full, schur_vals!, schur_vals)
3030
@test @constinferred(default_algorithm(f, A)) === LAPACK_Expert()
3131
end
3232

3333
@test @constinferred(default_algorithm(qr_compact!, A; blocksize = 2)) ==
34-
Householder(; driver = LAPACK(), blocksize = 2)
34+
Householder(; blocksize = 2)
3535
end
3636

3737
@testset "select_algorithm" begin

0 commit comments

Comments
 (0)