@@ -346,3 +346,101 @@ function init_cacheval(alg::GenericFactorization{<:RFWrapper},
346
346
abstol, reltol, verbose)
347
347
ArrayInterfaceCore. lu_instance (convert (AbstractMatrix, A))
348
348
end
349
+
350
+ # # FastLAPACKFactorizations
351
+
352
+ struct WorkspaceAndFactors{W, F}
353
+ workspace:: W
354
+ factors:: F
355
+ end
356
+
357
+ # There's no options like pivot here.
358
+ # But I'm not sure it makes sense as a GenericFactorization
359
+ # since it just uses `LAPACK.getrf!`.
360
+ struct FastLUFactorization <: AbstractFactorization end
361
+
362
+ function init_cacheval (:: FastLUFactorization , A, b, u, Pl, Pr,
363
+ maxiters, abstol, reltol, verbose)
364
+ ws = LUWs (A)
365
+ return WorkspaceAndFactors (ws, LinearAlgebra. LU (LAPACK. getrf! (ws, A)... ))
366
+ end
367
+
368
+ function SciMLBase. solve (cache:: LinearCache , alg:: FastLUFactorization )
369
+ A = cache. A
370
+ A = convert (AbstractMatrix, A)
371
+ ws_and_fact = cache. cacheval
372
+ if cache. isfresh
373
+ # we will fail here if A is a different *size* than in a previous version of the same cache.
374
+ # it may instead be desirable to resize the workspace.
375
+ @set! ws_and_fact. factors = LinearAlgebra. LU (LAPACK. getrf! (ws_and_fact. workspace,
376
+ A)... )
377
+ cache = set_cacheval (cache, ws_and_fact)
378
+ end
379
+ y = ldiv! (cache. u, cache. cacheval. factors, cache. b)
380
+ SciMLBase. build_linear_solution (alg, y, nothing , cache)
381
+ end
382
+
383
+ struct FastQRFactorization{P} <: AbstractFactorization
384
+ pivot:: P
385
+ blocksize:: Int
386
+ end
387
+
388
+ function FastQRFactorization ()
389
+ pivot = @static if VERSION < v " 1.7beta"
390
+ Val (false )
391
+ else
392
+ NoPivot ()
393
+ end
394
+ FastQRFactorization (pivot, 36 ) # is 36 or 16 better here? LinearAlgebra and FastLapackInterface use 36,
395
+ # but QRFactorization uses 16.
396
+ end
397
+
398
+ @static if VERSION < v " 1.7beta"
399
+ function init_cacheval (alg:: FastQRFactorization{Val{false}} , A, b, u, Pl, Pr,
400
+ maxiters, abstol, reltol, verbose)
401
+ ws = QRWYWs (A; blocksize = alg. blocksize)
402
+ return WorkspaceAndFactors (ws, LinearAlgebra. QRCompactWY (LAPACK. geqrt! (ws, A)... ))
403
+ end
404
+
405
+ function init_cacheval (:: FastQRFactorization{Val{true}} , A, b, u, Pl, Pr,
406
+ maxiters, abstol, reltol, verbose)
407
+ ws = QRpWs (A)
408
+ return WorkspaceAndFactors (ws, LinearAlgebra. QRPivoted (LAPACK. geqp3! (ws, A)... ))
409
+ end
410
+ else
411
+ function init_cacheval (alg:: FastQRFactorization{NoPivot} , A, b, u, Pl, Pr,
412
+ maxiters, abstol, reltol, verbose)
413
+ ws = QRWYWs (A; blocksize = alg. blocksize)
414
+ return WorkspaceAndFactors (ws, LinearAlgebra. QRCompactWY (LAPACK. geqrt! (ws, A)... ))
415
+ end
416
+ function init_cacheval (:: FastQRFactorization{ColumnNorm} , A, b, u, Pl, Pr,
417
+ maxiters, abstol, reltol, verbose)
418
+ ws = QRpWs (A)
419
+ return WorkspaceAndFactors (ws, LinearAlgebra. QRPivoted (LAPACK. geqp3! (ws, A)... ))
420
+ end
421
+ end
422
+
423
+ function SciMLBase. solve (cache:: LinearCache , alg:: FastQRFactorization{P} ) where {P}
424
+ A = cache. A
425
+ A = convert (AbstractMatrix, A)
426
+ ws_and_fact = cache. cacheval
427
+ if cache. isfresh
428
+ # we will fail here if A is a different *size* than in a previous version of the same cache.
429
+ # it may instead be desirable to resize the workspace.
430
+ nopivot = @static if VERSION < v " 1.7beta"
431
+ Val{false }
432
+ else
433
+ NoPivot
434
+ end
435
+ if P === nopivot
436
+ @set! ws_and_fact. factors = LinearAlgebra. QRCompactWY (LAPACK. geqrt! (ws_and_fact. workspace,
437
+ A)... )
438
+ else
439
+ @set! ws_and_fact. factors = LinearAlgebra. QRPivoted (LAPACK. geqp3! (ws_and_fact. workspace,
440
+ A)... )
441
+ end
442
+ cache = set_cacheval (cache, ws_and_fact)
443
+ end
444
+ y = ldiv! (cache. u, cache. cacheval. factors, cache. b)
445
+ SciMLBase. build_linear_solution (alg, y, nothing , cache)
446
+ end
0 commit comments