Skip to content

Commit 849fa21

Browse files
Fix TypeError for nonsquare linear systems with QR factorization
Fixes #674 The issue occurred when solving nonsquare linear systems (A*u = b where A is m×n with m≠n). On some platforms, Julia's qr function with ColumnNorm pivot returns QRPivoted with Vector{Int32} for pivot indices, while LinearSolve's DefaultLinearSolverInit struct expects Vector{Int64}. This fix adds a helper function _ensure_int64_pivot that converts QRPivoted pivot vectors from Int32 to Int64 when necessary, ensuring compatibility across all platforms. Changes: - Added _ensure_int64_pivot helper function to convert pivot indices to Int64 - Applied conversion in do_factorization for QRFactorization - Applied conversion in all init_cacheval functions that return QRPivoted - Ensured PREALLOCATED_QR_ColumnNorm uses Int64 pivot indices 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent f468950 commit 849fa21

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

src/factorization.jl

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,18 @@ function QRFactorization(pivot::LinearAlgebra.PivotingStrategy, inplace::Bool =
281281
QRFactorization(pivot, 16, inplace)
282282
end
283283

284+
# Helper function to ensure QRPivoted has Int64 pivot indices
285+
function _ensure_int64_pivot(fact::LinearAlgebra.QRPivoted)
286+
if eltype(fact.p) !== Int64
287+
# Convert to Int64 if needed
288+
return LinearAlgebra.QRPivoted(fact.factors, fact.τ, convert(Vector{Int64}, fact.p))
289+
end
290+
return fact
291+
end
292+
293+
# For non-pivoted QR, just return as-is
294+
_ensure_int64_pivot(fact) = fact
295+
284296
function do_factorization(alg::QRFactorization, A, b, u)
285297
A = convert(AbstractMatrix, A)
286298
if ArrayInterface.can_setindex(typeof(A))
@@ -296,22 +308,26 @@ function do_factorization(alg::QRFactorization, A, b, u)
296308
else
297309
fact = qr(A, alg.pivot)
298310
end
299-
return fact
311+
# Ensure Int64 pivot indices for QRPivoted
312+
return _ensure_int64_pivot(fact)
300313
end
301314

302315
function init_cacheval(alg::QRFactorization, A, b, u, Pl, Pr,
303316
maxiters::Int, abstol, reltol, verbose::Bool,
304317
assumptions::OperatorAssumptions)
305-
ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot)
318+
fact = ArrayInterface.qr_instance(convert(AbstractMatrix, A), alg.pivot)
319+
return _ensure_int64_pivot(fact)
306320
end
307321

308322
function init_cacheval(alg::QRFactorization, A::Symmetric{<:Number, <:Array}, b, u, Pl, Pr,
309323
maxiters::Int, abstol, reltol, verbose::Bool,
310324
assumptions::OperatorAssumptions)
311-
return qr(convert(AbstractMatrix, A), alg.pivot)
325+
fact = qr(convert(AbstractMatrix, A), alg.pivot)
326+
return _ensure_int64_pivot(fact)
312327
end
313328

314-
const PREALLOCATED_QR_ColumnNorm = ArrayInterface.qr_instance(rand(1, 1), ColumnNorm())
329+
# Create with Int64 pivot indices from the start
330+
const PREALLOCATED_QR_ColumnNorm = _ensure_int64_pivot(ArrayInterface.qr_instance(rand(1, 1), ColumnNorm()))
315331

316332
function init_cacheval(alg::QRFactorization{ColumnNorm}, A::Matrix{Float64}, b, u, Pl, Pr,
317333
maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
@@ -322,7 +338,8 @@ function init_cacheval(
322338
alg::QRFactorization, A::Union{<:Adjoint, <:Transpose}, b, u, Pl, Pr,
323339
maxiters::Int, abstol, reltol, verbose::Bool, assumptions::OperatorAssumptions)
324340
A isa GPUArraysCore.AnyGPUArray && return qr(A)
325-
return qr(A, alg.pivot)
341+
fact = qr(A, alg.pivot)
342+
return _ensure_int64_pivot(fact)
326343
end
327344

328345
const PREALLOCATED_QR_NoPivot = ArrayInterface.qr_instance(rand(1, 1))

0 commit comments

Comments
 (0)