Skip to content

Conversation

@loiseaujc
Copy link
Contributor

@loiseaujc loiseaujc commented Oct 20, 2025

Following #930, this PR extends the qr interface to enable the computation of the QR factorization with column pivoting. It is based on the xGEQP3 driver from lapack.

Proposed interfaces

  • call qr(a, q, r, pivots [, overwrite_a, storage, err])

where a is the matrix to be factorized, q the orthonormal basis for colspan(a), r the upper triangular matrix and pivots an integer array with indices of the pivoted columns.

Progress

  • Interface
  • Base implementation
  • Tests
  • In-code documentation
  • Specifications
  • Example

Ping: @perazz, @jvdp1, @jalvesz

@loiseaujc
Copy link
Contributor Author

I think this PR is almost ready to be reviewed. I have the specs left to write but this should pretty quick as it mainly is a small modification of the qr specs. I'll try to do that by the end of the week. It seems like there is a small issue with the unbuntu-22.04/cmake/inter-classic 2021.10 setup though. Not sure what it is and I don't have the intel compilers on my laptop so I can't really dig into it at the moment.

@loiseaujc loiseaujc linked an issue Oct 22, 2025 that may be closed by this pull request
@jalvesz jalvesz requested a review from Copilot November 1, 2025 19:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for QR factorization with column pivoting to the linear algebra library. The implementation leverages the LAPACK geqp3 routine and extends the existing qr interface to support pivot tracking.

  • Adds pivoting QR factorization via geqp3 LAPACK routine
  • Extends qr() and qr_space() interfaces to support column pivoting with pivot output
  • Includes comprehensive test coverage for tall, wide, and rank-deficient matrices

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/linalg/test_linalg_pivoting_qr.fypp Comprehensive test suite for pivoting QR factorization across different matrix types and configurations
test/linalg/CMakeLists.txt Adds pivoting QR test to build system
src/stdlib_linalg_qr.fypp Implements pivoting QR factorization routines and workspace calculation
src/stdlib_linalg_lapack.fypp Adds LAPACK geqp3 interface for QR with column pivoting
src/stdlib_linalg.fypp Extends public interface with pivoting QR subroutines
src/lapack/stdlib_linalg_lapack_aux.fypp Adds error handler for geqp3 LAPACK routine
example/linalg/example_pivoting_qr_space.f90 Example demonstrating pivoting QR with pre-allocated storage
example/linalg/example_pivoting_qr.f90 Basic example demonstrating pivoting QR factorization
example/linalg/CMakeLists.txt Adds pivoting QR examples to build system

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov
Copy link

codecov bot commented Nov 4, 2025

Codecov Report

❌ Patch coverage is 0% with 16 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (master@9e4c230). Learn more about missing BASE report.

Files with missing lines Patch % Lines
example/linalg/example_pivoting_qr_space.f90 0.00% 10 Missing ⚠️
example/linalg/example_pivoting_qr.f90 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             master    #1045   +/-   ##
=========================================
  Coverage          ?   68.55%           
=========================================
  Files             ?      396           
  Lines             ?    12746           
  Branches          ?     1376           
=========================================
  Hits              ?     8738           
  Misses            ?     4008           
  Partials          ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@loiseaujc loiseaujc marked this pull request as ready for review November 5, 2025 09:00
@loiseaujc
Copy link
Contributor Author

Modulo the issue with the unbuntu-22.04/cmake/intel-classic 2021.10 setup which I haven't been able to investigate yet, this PR is ready for review.

Copy link
Member

@jvdp1 jvdp1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @loiseaujc . Overall LGTM. I just have some minor suggestions.

Copy link
Member

@perazz perazz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this implementation @loiseaujc, great work.
I stand by @jvdp1's comments, and I added a few edits/typos.

Overall, looks good to me with the above.

@loiseaujc
Copy link
Contributor Author

Everything seems to be working as expected now. The issue with one of the workspace query. Not exactly sure though what the exact problem was since, before I fixed it, the allocated workspace was larger than needed (if my understanding is correct). In any case, it works.

@jalvesz
Copy link
Contributor

jalvesz commented Jan 9, 2026

LGTM @loiseaujc, just: is there a reason for keeping forall? This is a deprecated feature of the language, we should avoid introducing it within new code.

@perazz
Copy link
Member

perazz commented Jan 12, 2026

Everything seems to be working as expected now

This is great @loiseaujc - would you mind to squash all commits between 0cfaf2f and aa294c6? So we can see what the global changes are. LGTM otherwise

@loiseaujc
Copy link
Contributor Author

Sure, I'll wrap and tidy everything up tomorrow.

@loiseaujc
Copy link
Contributor Author

Alright guys, I can't quite get what is happening with intel. If I replace

forall(i=1:min(r1,m),j=2:n) r(i,j) = merge(amat(i,j),zero,i<=j)

with

do concurrent(i=1:min(r1, m), j=2:n)
    r(i, j) = merge(amat(i, j), zero, i <= j)
enddo

the test fails. Yet, in both cases, the R matrix is identical. For some reasons, the do concurrent leads to a change in tau(1) which leads to the Q matrix being wrong. Note that if I replace the do concurrent with

do j = 2, n
    do i = 1, min(r1, m)
        if (i <= j) then
            r(i, j) = amat(i, j)
        else
            r(i, j) = zero
        endif
    enddo
enddo

the whole thing works again as expected. My understanding is that all of these three loops should be essentially compiled to the exact same set of instructions. Have you ever seen that? Could that be some kind of compiler bug (although really hard to track) or related to a possible memory leak somewhere?

In any case, how should we proceed? Do we keep the forall even though it may be deprecated or return to plain old nested do loops?

@jalvesz
Copy link
Contributor

jalvesz commented Jan 16, 2026

I do have had bad surprises with ifort 19.1 and do concurrent. I would suggest to go for the plain do loops but keep the merge.

do j = 2, n
    do i = 1, min(r1, m)
        r(i, j) = merge(amat(i, j), zero, i <= j)
    enddo
enddo

Looking at it... I do wonder even if it can seem too basic ... could the issue be in the evaluation of min within the do concurrent construct ? would it change anything if the result of min(r1, m) is put in an integer temp variable before executing the loop ?

@loiseaujc
Copy link
Contributor Author

Nice idea but didn't help. We'll stick with the nested loops then.
@perazz : I ain't sure how to squash commits properly. Tried something but it didn't quite work. Any good reference there?

@perazz
Copy link
Member

perazz commented Jan 17, 2026

Any good reference there?

I just use GitHub Desktop - you select the range of commits you want to squash -> right click -> squash, it will do the job. For a command-line version, asking an AI would probably be best

I don't have intel-classic 2021.10 on my computer. Debugging via Github
Actions calls (hopefully)

Debugging intel classic

Debug intel classic

Debugging intel

Debug intel-classic. Change error metric.

Revert "Further simplification of the interface fyyp-template."

This reverts commit b7a4475.

Revert "Debug ubuntu-22.04/cmake/intel-classic"

This reverts commit c2fbf36.

Trying to pinpoint which test fails with intel.

Pinpoint which exact check is failing.

Pinpoint which check is failing.

Fix typo

Force Q and R to zero instead of ieee_value.

Print maximum reconstruction error.

Debug prints.

Debug prints

Debug prints

Additional debug prints

Deterministic matrix to verify output.

Check tau vector.

Deterministic vandermonde matrix.

Force pivot to zero.

Print pivots

Fix query workspace ?

Fix workspace query ?

Restoring checks.

Restoring checks.

Restoring tests.

Clean-up tests.

Reactivating tests.

Cleaned-up code.

Replaced forall with original do concurrent.

Restore random matrix for the pivoting qr tests.

Revert "Replaced forall with original do concurrent."

This reverts commit 9c8473c.

Replaced forall with do concurrent.

Pinpointing which test fails.

Fix typo in print

Debug prints

Deterministic matrix to have reproducible error.

Debug prints.

Debug print

Trying different loop structure

Fixing issue with do concurrent and intel.

Try José idea to fix intel do concurrent.

Revert "Try José idea to fix intel do concurrent."

This reverts commit 55a4b3e.

Turn on back the other tests.
@loiseaujc
Copy link
Contributor Author

Alright, I've squashed everything (using Git Kraken). Not entirely sure what the resulting git tree is supposed to look like (first time I used this).

Copy link
Member

@perazz perazz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks a lot for the edits @loiseaujc

@perazz perazz merged commit 9a52f83 into fortran-lang:master Jan 20, 2026
27 checks passed
@loiseaujc loiseaujc deleted the rank_revealing_qr branch January 20, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rank-revealing QR decomposition

4 participants