Skip to content

Commit ff439bd

Browse files
committed
Fix method ambiguity
1 parent ffbfa85 commit ff439bd

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

src/algorithms.jl

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,23 +220,37 @@ Driver to select GenericSchur.jl as the implementation strategy.
220220
struct GS <: Driver end
221221

222222
# In order to avoid amibiguities, this method is implemented in a tiered way
223-
# default_driver(alg, A) -> default_driver(typeof(alg), typeof(A))
224-
# default_driver(Talg, TA) -> default_driver(TA)
223+
# default_driver(alg, A) -> default_driver(typeof(alg), typeof(A))
224+
# default_driver(Talg, A) -> default_driver(Talg, typeof(A))
225+
# default_driver(Talg, TA) -> default_driver(Talg, _unwrapped_array_type(TA)) | default_driver(TA)
226+
# default_driver(TA) -> driver
225227
# This is to try and minimize ambiguity while allowing overloading at multiple levels
226228
@inline default_driver(alg::AbstractAlgorithm, A) = default_driver(typeof(alg), A isa Type ? A : typeof(A))
227229
@inline default_driver(::Type{Alg}, A) where {Alg <: AbstractAlgorithm} = default_driver(Alg, typeof(A))
228-
@inline default_driver(::Type{Alg}, ::Type{TA}) where {Alg <: AbstractAlgorithm, TA} = default_driver(TA)
230+
231+
# Generic 2-arg fallback: if `TA` is a supported wrapper type, recurse on the
232+
# unwrapped storage type (so algorithm-specialized methods on the parent array
233+
# type still apply). Otherwise drop the algorithm and fall through to the
234+
# array-only dispatch.
235+
@inline function default_driver(::Type{Alg}, ::Type{TA}) where {Alg <: AbstractAlgorithm, TA <: AbstractArray}
236+
UA = _unwrapped_array_type(TA)
237+
return UA === TA ? default_driver(TA) : default_driver(Alg, UA)
238+
end
229239

230240
# defaults
231241
default_driver(::Type{TA}) where {TA <: AbstractArray} = Native() # default fallback
232242
default_driver(::Type{TA}) where {TA <: YALAPACK.MaybeBlasVecOrMat} = LAPACK()
233243

234-
# wrapper types
235-
@inline default_driver(::Type{Alg}, ::Type{<:SubArray{T, N, A}}) where {Alg <: AbstractAlgorithm, T, N, A} = default_driver(Alg, A)
236-
@inline default_driver(::Type{Alg}, ::Type{<:Base.ReshapedArray{T, N, A}}) where {Alg <: AbstractAlgorithm, T, N, A} = default_driver(Alg, A)
244+
# wrapper types (1-arg form, reached via the generic 2-arg fallback)
237245
@inline default_driver(::Type{<:SubArray{T, N, A}}) where {T, N, A} = default_driver(A)
238246
@inline default_driver(::Type{<:Base.ReshapedArray{T, N, A}}) where {T, N, A} = default_driver(A)
239247

248+
# Internal helper: strip supported wrapper types to the underlying storage
249+
# array type. Add a new method here when introducing additional wrappers.
250+
@inline _unwrapped_array_type(::Type{TA}) where {TA <: AbstractArray} = TA
251+
@inline _unwrapped_array_type(::Type{<:SubArray{T, N, A}}) where {T, N, A} = _unwrapped_array_type(A)
252+
@inline _unwrapped_array_type(::Type{<:Base.ReshapedArray{T, N, A}}) where {T, N, A} = _unwrapped_array_type(A)
253+
240254
# Truncation strategy
241255
# -------------------
242256
"""

0 commit comments

Comments
 (0)