Route the LAPACKE_malloc / LAPACKE_free defaults through function
pointers so the LAPACKE test suite can inject allocation failures at
run time, mirroring LAPACKE_set_nancheck. Compile-time macro overrides
are unaffected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SUFFIX is now a required argument and an optional SYMBOL_ALLOWLIST
restricts the renaming to the listed symbols (needed by the upcoming
LAPACKE test suite). All 3523 generated _64 sources stay byte-identical.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Shares error_percent with the Markdown report, including the 0.01%
floor for nonzero counts; the error columns are rebalanced by one
character so (100.00%) still fits under the rule.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A nonzero error count whose percentage would display as 0.00% is
shown as 0.01% instead, so it cannot read as a zero error rate.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
testing_results.txt and the JUnit XML are kept for 14 days even when
the tests fail; the step summary links to the artifact.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Summary tables first, then one entry per failing output file with
its notable lines collapsed; sized in UTF-8 bytes to stay under
GitHub's 1 MiB step-summary limit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1+INT((N-1)*u) with u in (0,1) can never reach N, so the IU=N branch
of the RANGE='V' bound in xDRVST has been unreachable since the code
was written. xLARND excludes 0 and 1, so 1+INT(N*u) covers [1,N].
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
INT was applied to the (0,1) deviate instead of the scaled value, so
IL and IU were always 1 and the RANGE='I'/'V' paths never tested more
than a single eigenvector. Matches the form already used in xDRVBD,
xDRVSG and the other xDRVST variants.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xSTEIN reorthogonalizes only eigenvectors whose eigenvalues lie within
1e-3*|T|; pairs just past that cutoff are orthogonal only to
O(ulp*|T|/gap), so test 21 of xCHKST legitimately reaches about
1000*H(n-1)/n =~ 500 at n=3. Seen in-suite: 53.7 (csep/cse2, n=5,
type 21); handcrafted worst cases reach 170.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6dc1a78ea normalized DFLAG 0/1 to -1 for every regular result,
contradicting the documented compact DPARAM forms and failing the
xblat1 ROTMG tests at points 1-2. The ELSE IF guard alone is enough
to fix the #244 clobber, so keep the normalization inside the loops.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SINGVQX is only filled to KQ, so SINGVQX(K) read uninitialized memory
whenever DGEDMD's rank K exceeded DGEDMDQ's KQ -- harmless in the
default API by luck, an abort in the _64 build. cchkdmd/zchkdmd
already use KQ.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Collapses a library's two API sections into one table when they report
the same errors. Compared per output file, so a missing file or two
different failures with equal totals keep the sections split.
Add the CBLAS suite as its own library, alongside LAPACK and BLAS:
- A test case per precision and BLAS level. The CBLAS inputs carry no
output file name, so the same input serves both APIs and the harness
redirects the output for every level, unlike the BLAS Level 2 and 3
drivers.
- --cblas-dir, defaulting to CBLAS/testing, which is the correct
relative path from both a CMake build root and the source tree. A
missing directory is skipped silently, since CBLAS is off by
default.
- The verdict and count patterns accept the COLUMN-MAJOR and ROW-MAJOR
tags the CBLAS drivers add, which the BLAS drivers do not emit.
The parser itself is shared with BLAS: both suites report their counts
in the same form, so only the layout tags and the test tables differ.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Like their BLAS counterparts, the Level 1 testers print only a PASS line
or a bare FAIL per subprogram, with no counts and no footer. Report:
CBLAS_SDOT COMPUTATIONAL TESTS: 16 RUN, 0 FAILED
One test is one element comparison in STEST or ITEST1; CTEST delegates
to STEST and is not counted separately. The counters travel in a new
/CNTBLA/ block and the subprogram name reaches the main program from
HEADER through /NAMBLA/, matching the BLAS Level 1 drivers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The C error-exit checkers report only a pass/fail verdict per routine.
Report the counts too, matching the Fortran drivers:
cblas_sgemv ERROR-EXIT TESTS: 13 RUN, 0 FAILED
One test is one chkxer() call. A test fails either because the routine
never reached xerbla, which chkxer already detects through cblas_lerr,
or because c_xerbla.c was reached with the wrong routine name, which
clears cblas_ok without chkxer noticing. The extended API build hits
exactly that second case, reporting cblas_sgemv_64 against an expected
cblas_sgemv, so a new cblas_xbad flag carries it across and the counts
agree with the verdict.
The Windows path that skips the xerbla tests returns before printing a
verdict and so prints no counts either.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Report how many tests each routine ran and how many failed, in the same
shape as the BLAS drivers, tagged with the data layout so the two passes
stay distinguishable:
cblas_sgemv COLUMN-MAJOR COMPUTATIONAL TESTS: 3456 RUN, 0 FAILED
cblas_sgemv ROW-MAJOR COMPUTATIONAL TESTS: 3456 RUN, 0 FAILED
As in the BLAS drivers, NTESTS and NFAILS sit beside the existing
ERRMAX, are incremented where ERRMAX accumulates, and are reported at
the common exit so every verdict path carries them. The paths that set
FATAL bump them too, so an aborting routine cannot report zero failures.
Existing output lines are unchanged.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c_sblat2.f, c_dblat2.f and all four Level 3 drivers dispatch on IORDER
and report the column-major and row-major passes with distinct wording.
c_cblat2.f and c_zblat2.f never got that dispatch, so they print two
textually identical lines per routine:
cblas_cgemv PASSED THE COMPUTATIONAL TESTS ( 3460 CALLS)
cblas_cgemv PASSED THE COMPUTATIONAL TESTS ( 3460 CALLS)
There is no way to tell which layout a verdict belongs to, or to notice
that one of the two is missing. Add the dispatch, reusing the wording
and the 10000..10003 labels the other drivers already use. Those labels
also name the layout banner in the main program, which is fine: FORMAT
labels are local to a program unit.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The BLAS tests run under both build systems but nothing reported on
them: the script knew only the LAPACK drivers and scanned only the
LAPACK testing directory.
Add the BLAS suite as its own library:
- A test case per precision and BLAS level, with the Level 1 drivers
marked as reading no input, and the Level 2 and 3 drivers marked as
opening their own output file.
- parse_blas, which takes run and failure counts from the driver's
report lines. Computational failures are numerical errors and
error-exit failures are other errors.
- --blas-dir, defaulting to BLAS/TESTING. That relative path is
correct from a CMake build root and from the source tree alike, so
no existing invocation needs changing. A missing directory is
skipped silently, since builds against an optimized BLAS have none.
- --run support, which needs the input-less Level 1 drivers handled
and the output redirection suppressed for Level 2 and 3. A _64 run
of Level 2 or 3 requires the generated _64 input; without it the
driver would write over the default-API output, so it is skipped
with a message instead.
The drivers exit 0 even when they abandon a run, and print END OF TESTS
even when routines failed, so breakage is read from the text: an
abandoned or misconfigured run, and a Level 2 or 3 file that never
reached its footer, each count as one other error. Detail lines behind
an already counted verdict are shown but not counted, which otherwise
inflates a failing file several fold.
Output from a build whose drivers do not report counts is still
summarized, by counting one test per verdict. That is coarse, but never
silently zero.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The script is built around a single testing directory and a single set
of test families. Adding another test suite means teaching it that a
test case belongs to a library, that each library has its own directory,
and that each gets its own section of the summary table.
Introduce that structure without changing what is analyzed:
- TestCase gains a library field, defaulting to LAPACK.
- The testing directories are held in a per-library mapping, which
read_output_file, run_test_case and the unrecognized-output scan now
resolve through instead of assuming one directory.
- find_unrecognized_outputs takes that mapping and matches each
directory against only the cases of the library that owns it, so
--fail-on-unrecognized stays accurate once more directories exist.
- discover_suffixes takes the cases and directory of one library, so
the extended API is detected per library rather than globally.
- The summary loop iterates over (library, API) sections, and
section_title names both.
- -t gains a lapack value selecting all LAPACK families, so the
previous default remains expressible once other libraries are added.
The only visible change is that section headings now read
"LAPACK: Default API" rather than "Default API". Analyzed output is
otherwise byte for byte identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Level 1 tests are registered with neither -DINPUT nor -DOUTPUT, so
xblat1s writes to stdout and the harness lets it go to the ctest log
only. No .out file is produced, and the four Level 1 results per
precision cannot be summarized after the fact.
Pass -DOUTPUT for the no-input branch, giving {s,d,c,z}blat1.out in the
testing binary directory. These are the names BLAS/TESTING/Makefile's
run target already produces, so both build systems now yield the same
set of files.
The Level 2 and 3 branch deliberately keeps no -DOUTPUT: those drivers
OPEN their own summary file on unit 6, and redirecting stdout onto the
same path would put two writers on one file.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Level 1 testers print "----- PASS -----" or a bare FAIL per
subprogram, with no counts and no footer at all, so a summary tool can
only say which subprograms failed, not how much was checked. Report the
same line the Level 2 and 3 drivers now do:
SDOT COMPUTATIONAL TESTS: 16 RUN, 0 FAILED
One test is one element comparison in STEST, TESTDSDOT or ITEST1. CTEST
converts complex pairs and delegates to STEST, so it is not counted
separately.
The counters live in a new /CNTBLA/ block rather than in /COMBLA/,
because ?B1NRM2 takes N and INCX as arguments and could not declare
/COMBLA/ without a name collision. The subprogram name reaches the main
program from HEADER through /NAMBLA/, mirroring /SRNAMC/ in the Level 2
and 3 drivers.
?B1NRM2 failures never cleared PASS, so a case could print NRM2 failure
lines and "----- PASS -----" together. They are counted as failures,
which makes them visible for the first time.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
?CHKE reports only a pass/fail verdict per routine, with no indication
of how many error exits it checked. Report those counts too, in the same
shape as the computational ones:
SGEMV ERROR-EXIT TESTS: 6 RUN, 0 FAILED
One test is one CHKXER call. CHKXER is called between 96 and 229 times
per driver, so threading counters through its argument list is not an
option; they travel in a new /XERCNT/ block instead, following the
/INFOC/ and /SRNAMC/ pattern these files already use.
A test fails in two distinct ways. Either the routine never called
XERBLA, which CHKXER already detects through LERR; or XERBLA was called
with the wrong INFO or the wrong routine name, which clears OK inside
XERBLA without CHKXER ever noticing. The second case is not theoretical:
it is what the extended API drivers hit, where the BLAS reports SRNAME
as CGEMV_ against an expected CGEMV. NXBAD carries that across so the
counts agree with the verdict instead of reporting zero failures beside
a FAILED line.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Level 2 and 3 testers report a per-routine verdict and a cumulative
count of BLAS calls, but never how many tests they ran or how many of
them failed. The call count is also absent from the hard-failure path,
so it shrinks exactly when something goes wrong, and nothing downstream
can tell a clean run from a broken one without reading the prose.
Each ?CHKn already computes a test ratio per accuracy check and compares
the worst of them against the threshold; it just discards the rest. Keep
NTESTS and NFAILS alongside the existing ERRMAX, incremented at the one
point where ERRMAX accumulates, and report them at the common exit so
the line appears on the PASSED, the COMPLETED/SUSPECT and the
FAILED ON CALL NUMBER paths alike:
SGEMV COMPUTATIONAL TESTS: 3456 RUN, 0 FAILED
A corrupted argument or a spurious error exit is not a threshold
failure, so those paths bump the counters where they set FATAL.
Otherwise a routine could abort and still report zero failures.
Every existing output line is unchanged; the report line is additive.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Describes the style the xerbla sources are written in: three-space
indent, Allman braces, 80 columns, and the return type on its own line
for definitions. Every option clang-format knows about is listed, with
the ones inherited from the LLVM base style commented out, so that the
uncommented lines are exactly what this style changes.
The file applies to all of CBLAS, but the older sources here do not
follow it, so format only the lines you touch, e.g. with
git clang-format.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Switch cblas_xerbla(), F77_xerbla_base() and the test harness over to
cblas_xerbla_internal.h. Two diagnostic bugs go away with the duplicated
code:
- the row-major remap keyed off strstr(rout, "gemm"), which also
matches gemmtr and so wrongly swapped its arguments 4 and 5;
- the six-character name buffer truncated cblas_sgemmtr and
cblas_sskewsyr2k in the library, while the harness used an
eleven-character buffer and did not, so the two disagreed about the
same routine.
The Fortran entry points now take FCHAR and read the argument number
through F77_INT consistently, honour the hidden string length instead of
assuming six characters, and carry doxygen comments.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
cblas_xerbla_internal.h collects the routine-name construction and the
row-major INFO remapping that the library and the test harness each
open-code today, so the two copies can no longer drift apart.
Relative to those copies the helper also trims the blank padding Fortran
supplies, drops the _64 suffix that BUILD_INDEX64_EXT_API rewrites into
the XERBLA name literals, matches operation names exactly rather than by
substring, and derives its buffer size from a named maximum so that long
names are clamped instead of silently truncated.
It has no user yet; the xerbla sources are switched over next.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
c_xerbla.c needs the Fortran integer and character types to declare
F77_xerbla(), but the testing sources deliberately do not include
cblas_f77.h: that header maps every F77_* name to the real BLAS symbol
while cblas_test.h maps them to the Fortran test wrappers, and 141 of
those names collide.
Copy the two fallbacks into cblas_test.h instead, alongside the
BLAS_FORTRAN_STRLEN_END and FORTRAN_STRLEN definitions it already
duplicates for the same reason.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replace the repeated
void
#ifdef HAS_ATTRIBUTE_WEAK_SUPPORT
__attribute__((weak))
#endif
preamble on the cblas_xerbla(), cblas_xerbla_64() and F77_xerbla_base()
declarations with a single CBLAS_WEAK_SYMBOL macro.
Define it in cblas.h ahead of the cblas_64.h include: cblas_64.h declares
cblas_xerbla_64() with the macro, and its own include of cblas.h is a
no-op while cblas.h is still inside its own include guard.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The row-major branches of cherk/zherk and cher2k/zher2k mapped the
invalid CblasTrans to 'N', and those of csyrk/zsyrk and csyr2k/zsyr2k
mapped the invalid CblasConjTrans to 'N', silently computing a
different operation instead of rejecting the argument. The
column-major branches forward these values to the Fortran routine,
which reports them as an illegal second argument (parameter 3 of the
CBLAS call). Drop the bogus mappings so the invalid values reach the
row-major branches' existing error exits, which also report
parameter 3.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The error-exit testers only exercised the option arguments (Side,
Uplo, Trans, Diag) with CblasColMajor, so the diagnostics in the
row-major branches of the level-3 routines were never tested. Mirror
every column-major option-argument test under CblasRowMajor, add the
missing row-major N/K dimension tests for the syrk/herk/syr2k/her2k/
skewsyr2k families, turn the duplicated column-major blocks in the
spr/hpr sections into the intended row-major tests, and make the
mislabelled gemmtr ldb "row major" tests actually use CblasRowMajor.
The new tests expose wrong INFO values in the row-major branches of
cgemm (TransB) and the syrk/syr2k/herk/skewsyr2k families (Uplo), and
silently accepted invalid Trans values in the row-major branches of
the complex herk/her2k/syrk/syr2k routines; these are fixed in the
following commits.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The relative-error denominator used MAX(A(I,J), AIN(I,J)) without
taking absolute values. For entries where both matrices are negative,
the subsequent clamp replaced the denominator with SFMIN, and the
difference divided by SFMIN overflowed to Infinity in single precision
(sbal.in example 11). The complex checkers already use CABS1 here.
sbal now reports the same finite largest error (0.100E+01, example 5)
as the other three precisions.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The row-major branch transposed the full m-by-n matrix through
temporaries and copied the never-written complementary region of the
destination temporary back over B, corrupting the triangle uplo requires
to be preserved and reading uninitialized memory. Call the Fortran kernel
directly with uplo swapped (U<->L) and m/n swapped, exactly as the
correct column-major path does. Applies identically to s/d/c/z.
The eigenvalue divide-and-conquer helper routines DLAED2/SLAED2 and
DLAED8/SLAED8 used a deflation tolerance of 8*EPS, while the SVD
routines DLASD2/SLASD2 and DLASD7/SLASD7 now use 64*EPS (since
PR #1286). The downstream eigenvector computation in DLAED3 divides
by eigenvalue differences (DLAMBDA(I) - DLABMDA(J)), causing the same
catastrophic cancellation when close eigenvalues escape deflation with
the tighter tolerance.
Raise all four routines to 64*EPS (EIGHT*EIGHT*EPS), matching the SVD
path, so close eigenvalues are deflated and the eigenvector computation
remains stable.
Follow-up for #255
Clarify that the workspace query returns a valid LWORK (>= 1) even
when MIN(M,N) = 0. The code already handles this correctly; this
is purely a documentation update.
Correct the decomposition formula from U**T*D*U to U*D*U**T
in the doc header and comments for dsytrf.f and ssytrf.f.
The complex variants (csytrf, zsytrf) already used the correct form.
Closes#977
Replace the Fortran intrinsic HUGE with SLAMCH('O')/DLAMCH('O')
for consistency with the rest of LAPACK. HUGENUM is changed from
a compile-time PARAMETER to a runtime assignment since LAMCH is a
function call.
Closes#608
The left-solving non-transposed path in DTRSM/S/CTRSM/ZTRSM has an
optimization that skips the division B(K,J)/A(K,K) when B(K,J) is
exactly zero. When A(K,K) is also zero (singular matrix), this
leaves B(K,J)=0 instead of computing 0/0=NaN, producing inconsistent
results across different calling variants of the same triangular
solve.
Closes#636
The LQ test drivers (dchklq, schklq, cchklq, zchklq) called DGELS/SGELS
which re-factorizes AF internally using GEQRF when M>=N. This corrupted
the LQ factorization expected by subsequent LQT02/LQT03 calls on later
K iterations, causing test(1) and test(2) failures.
Fix by re-copying A to AF and re-factorizing with GELQF after the GELS
call, restoring the LQ factorization for the remaining tests.
Closes#973
The *evr and *stevr routines now call CSTEMR/DSTEMR/SSTEMR with the
user-specified RANGE argument on IEEE-754 compliant machines, instead of
only using the fast path when the full spectrum is requested
(ALLEIG or IL=1, IU=N). Partial eigenvalue ranges with eigenvectors
now also benefit from the faster algorithm.
Fix a bug where WANTZ=.FALSE. with a partial range on IEEE machines
would incorrectly set M=N and skip the DSTEBZ fallback, because INFO
remained 0 from initialization when SSTERF was skipped (it can only
compute all eigenvalues). The IF(INFO.EQ.0) success check is now
moved inside each computational branch so it only triggers when
SSTERF or CSTEMR was actually called and succeeded.
Closes#1277
The ZGGEV/DGGEV/SGGEV/CGGEV test drivers compared eigenvalues
from full (both L/R eigenvectors) and partial (eigenvalues only)
computations using exact Fortran .NE. This is fragile because the
QZ algorithm applies orthogonal transformations to a different
scope of columns depending on the JOB parameter ('S' vs 'E'),
causing 1-ULP differences in eigenvalues on some architectures.
Replace the binary ULPINV sentinel with a relative tolerance
comparison: RESULT(5/6/7) now reports the maximum relative
difference across ALPHA/ALPHAI/BETA, which is compared against
the regular THRESH threshold. Fixes the spurious failure on
Intel Xeon E5-2698 v4 and other platforms.
Closes#744
Offset computations like j*lda overflow 32-bit lapack_int once
n = lda >= 46341, e.g. LAPACKE_dpotrf crashes in its NaN check before
the factorization runs. Cast to size_t (or int64_t for the tz offsets)
the same way ge/gb/tp/tf already do.
The Golub-Reinsch-SVD-style iteration in xBBCSD used an absolute
convergence threshold THRESH ~ 90*EPS to decide when off-diagonal
bulges are negligible and can be skipped. For rows where the
diagonal entries are small (tiny singular values in the ratio),
this absolute threshold is too large relative to the diagonal,
causing the algorithm to stop chasing bulges prematurely and
producing inaccurate singular vectors (||X21 - U2 D2 V^*|| up to
50*EPS ||X21||).
Fix: change all bulge-convergence checks (RESTART flags in the
inner loop, initial bulge-chase decisions, and the IMAX-1 cleanup)
from absolute to relative by scaling THRESH by the adjacent diagonal
entries:
RESTART11 = |B11E|^2+|BULGE|^2 <= (THRESH * MAX(|B11D(I-1)|,|B11D(I)|,UNFL))^2
This mirrors DBDSQR's relative convergence check |E| <= TOL*|D|.
Applied to all 4 bidiagonal blocks (B11/B21/B12/B22) at all 3
check-points in the iteration.
Fixes#965
The workspace query formula LWKOPT = NW*NB + TSIZE used TSIZE = LDT*NBMAX
= 65*64 = 4160, a hardcoded constant. The blocked algorithm only stores
one T matrix block at a time (reused across loop iterations), so the
per-iteration workspace is LDT*NB, not LDT*NBMAX. For tiny M,N,K where
a single block suffices (NB >= N or NB >= K), LWKOPT was always >= 4160
regardless of problem size.
Fix: change LWKOPT = NW*NB + TSIZE -> LWKOPT = NW*NB + LDT*NB.
The NB adjustment formula when LWORK is limited must consistently use
the per-iteration T storage instead of TSIZE:
NB = (LWORK - TSIZE) / LDWORK -> NB = LWORK / (LDWORK + LDT)
Applied to all 16 routines (s,d,c,z x {orm,unm}{qr,rq,lq,ql}).
Closes#546
When P=0 and M=Q (U2 is M-by-M, X21 is M-by-M and orthogonal),
or P=M and M=Q (U1 is M-by-M, X11 is M-by-M and orthogonal),
or Q=0, the minimal dimension R = MIN(P, M-P, Q, M-Q) is zero,
so C and S are empty. In these degenerate cases the preceding
code entered the R == P or R == M-P branch and called the
bidiagonalization subroutines (SORBDB2/SORBDB3) which then
accessed elements X21(I,I+1) or X11(I,I+1) out of bounds in
the second DO loop (I = P+1, Q or I = M-P+1, Q).
Fix: handle R = 0 directly in the four driver routines before
the case-dependent bidiagonalization path. The three trivial
CSD cases are:
Q = 0: set U1 = I, U2 = I, return.
P = 0, M = Q: copy X21 to U2, set V1T = I, return.
P = M, M = Q: copy X11 to U1, set V1T = I, return.
All other R=0 configurations are non-standard and still fall
through to the existing path (which may fail).
Fixes#549
In the general case (xnorm > eps*|alpha|, beta >= 0), the
Householder reflector formula computes
ALPHA = -XNORM^2 / (alpha + beta)
which can be subnormal even when beta itself is safely above
SMLNUM. When this subnormal ALPHA was used in the subsequent
CALL SSCAL( N-1, ONE / ALPHA, X, INCX )
the reciprocal overflowed (e.g. ALPHA = 2^-137 → ONE/ALPHA = 2^137
which exceeds SP max ~3.4e38).
Fix: guard the SSCAL with ABS(ALPHA) < SMLNUM. When ALPHA is very
small, scale X by ONE/SMLNUM then by SMLNUM/ALPHA — both safe
since ONE/SMLNUM = BIGNUM is below the overflow threshold and
SMLNUM/ALPHA ≤ MAX_EXPONENT.
The complex variants (clarfgp/zlarfgp) are already safe because
they compute 1/ALPHA via CLADIV/ZLADIV, which internally handles
overflow/underflow without intermediate overflow.
Fixes#938
The workspace NB queries in all four ?gelsy variants used
?GERQF and ?UNMRQ, but the routines actually called at runtime
are ?TZRZF and ?UNMRZ (real) / ?UNMRZ (complex).
While ?GERQF and ?TZRZF are related (both produce an RQ-like
factorization), their block sizes may differ in ILAENV's tuned
values. If the user relied on LWKOPT from the query to allocate
exactly the right workspace, the actual ?TZRZF/?UNMRZ calls could
underflow or overflow the work array.
Fix the ILAENV calls to match the routines actually invoked:
?GERQF -> ?TZRZF
?UNMRQ -> ?UNMRZ
Closes#676
When the computed random value rounds to exactly 1.0 (once every
~2^24 single-precision calls), both SLARAN and SLARUV reject it and
recompute — but they advanced the seed differently:
SLARAN: ISEED(1:4) = IT1..IT4 (correct — carry forward the
multiplier-transformed state)
SLARUV: I1 = I1 + 2 (wrong — ad-hoc skip in seed
space)
SLARUV's +2 produces a different subsequent random sequence than
SLARAN would for the same initial seed. Fix by using the same
seed advancement in both: set I1..I4 = IT1..IT4, matching SLARAN.
Applies to DLARUV as well.
Closes#1108
The row-major path hardcoded `lda_t = MAX(1,k)`, which is only correct
when SIDE='L' (A is K-by-N). When SIDE='R', A is M-by-K and the
transposition dimensions, allocation, and leading-dimension checks were
all wrong.
- Introduce nrowsA/ncolsA/nrowsV determined by SIDE (following the
same pattern as the LAPACKE_?tpmqrt_work fix in PR #540).
- lda_t now uses nrowsA instead of always k.
- lda check compares against ncolsA instead of always m.
- A transpose uses (nrowsA, ncolsA) instead of (k, m).
- LDV check depends on STOREV: ldv >= nrowsV for STOREV='C',
ldv >= k for STOREV='R'.
- V transpose uses nrowsV rows instead of ldv.
Closes#734
Fix DBDSDC/SBDSDC returning non-orthogonal U/V for bidiagonal matrices
with many nearly-equal singular values (e.g., all singular values ≈ 1).
The divide-and-conquer bidiagonal SVD has two code paths:
- Full vector path (DLASD2/SLASD2): deflation tolerance = 8 * EPS
- Compact path (DLASD7/SLASD7): deflation tolerance = 64 * EPS
With the weaker tolerance (8*EPS), singular values differing by only
~10*EPS (e.g., ~2e-15 for double precision) escape deflation. The
subsequent Z computation in DLASD3 then suffers catastrophic
cancellation from denominators (σ_i - σ_j) that are tiny, polluting the
singular vectors and causing loss of orthogonality.
Raise DLASD2 and SLASD2 to 64*EPS, matching DLASD7 and SLASD7, so more
close singular values are deflated and the singular-vector computation
remains stable.
Closes#255
Problem: When NCVT = NRU = NCC = 0 (no singular vectors requested),
BDSQR calls the dqds algorithm. If dqds failed with INFO = 1 or 3,
the routine returned immediately with that error, even though the
standard QR algorithm could still compute the singular values. Only
INFO = 2 triggered the fallback.
Change `IF( INFO .NE. 2 ) RETURN` to `IF( INFO .EQ. 0 ) RETURN`
after the dqds call, so the standard QR fallback runs on any
dqds failure (INFO=1,2,3) and not only INFO=2.
Closes#242
Per LAPACK docs, in [cz]tgexc, ilst is [in,out]. The LAPACKE C
interface was passing both ifst and ilst by value as input-only
scalars, so callers could never observe the updated ilst value.
Change both ifst and ilst to lapack_int* pointers in the complex
tgexc variants to match the real-precision stgexc/dtgexc interface
and the underlying Fortran semantics.
Fixes#771
When ?HSEQR encounters non-finite input, it can return a negative
INFO. The undo-scaling block at label 50 then computes N-INFO (which
exceeds N) and indexes WR( INFO+1 ) (out of bounds), causing memory
corruption through ?LASCL.
Add INFO.GE.0 to the outer IF( SCALEA ) guard so the undo-scaling
block is skipped entirely when INFO is negative. The inner
IF( INFO.GT.0 ) guard only covered the second pair of ?LASCL calls.
Fixes#1128
When DFLAG=0 and both DD1 and DD2 need rescaling, the first
scaling loop transitions DFLAG from 0 to -1 and correctly
scales DH11 and DH12. But the second scaling loop then hits
the ELSE branch (matching DFLAG=-1) which unconditionally
resets DH21=-1 and DH12=1, overwriting the scaled DH12.
Change ELSE to ELSE IF (DFLAG.EQ.ONE) so the implied-element
initialization (DH21=-1, DH12=1) only fires when DFLAG=1,
not when DFLAG=-1 (where all elements are already explicit).
Fixes#244
Two comments in the DGEHRD/DHSEQR test incorrectly say "Compute
Schur form":
- The DGEHRD call reduces to upper Hessenberg form, not Schur.
- The DHSEQR call computes eigenvalues and the Schur form, so
use a more descriptive label.
Fixes#587
When JOBU='N' or JOBVT='N', the U and VT matrices are not referenced,
so the leading dimension checks should be skipped. Previously the
code rejected ldvt=0 (and ldu=0) even when those matrices were not
used, causing a spurious INFO=12 error on row-major calls with
JOBVT='N' (or INFO=10 for JOBU='N').
Fixes#1090
The actual SLAQZ0 call uses 'S' when ILV is true and 'E' otherwise,
but the query gated that choice on ILVL, undersizing LWORK for
JOBVL='N', JOBVR='V'. Mirror DGGEV3: gate SLAQZ0 and SGGHD3 on ILV,
SORGQR on ILVL.
DLASWLQ tested NB.LT.0 instead of NB.LE.0, accepting NB=0 silently and
falling into the divide-by-(NB-M) path on line 255 (KK = MOD((N-M),(NB-M)))
when M=0. The single/complex/double-complex siblings all use NB.LE.0.
The argument-validation block at the top of ?LAQZ0 sets INFO=-i and
correctly calls XERBLA(name, -INFO), but the second validation block
(LWORK .LT. LWORKREQ) calls XERBLA(name, INFO) with the negative
value. XERBLA prints its argument verbatim, so this would emit
"parameter number -18 had an illegal value" instead of "18".
Affects S/D/C/Z LAQZ0; ?LAQZ2 and the rest of LAPACK already use
the correct -INFO form.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
INFO=-N value reported to XERBLA on a too-small workspace
(or LRWORK) does not match the actual signature position of the
argument being tested.
Sites:
- ?ORBDB4 / ?UNBDB4: LWORK test reported -14 (WORK), should be -15.
- ?GGSVD3: LWORK.LT.1 test reported -24 (the INFO arg in S/D;
IWORK in C/Z), should be -22 (LWORK).
- ?ORCSD / ?UNCSD: LWORK test reported -22 (LDU2), should be -28
(LWORK). Z/C also report LRWORK as -24 (LDV1T), should be -30.
- C/ZLAQZ0: LWORK test reported -19 (RWORK), should be -18.
(S/DLAQZ0 use ALPHAR+ALPHAI instead of ALPHA, so LWORK is at
position 19 there and -19 is already correct.)
- C/ZLAQZ2: LWORK test reported -26 (RWORK), should be -25.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SGGES body calls XERBLA at line 423 but the EXTERNAL block omits it;
DGGES correctly lists XERBLA. Add it.
ZRSCL's Doxygen header advertised the routine as ZDRSCL (which is a
different routine that ZRSCL calls internally). Fix the brief, the
download links, and the filename references so the generated docs
correspond to ZRSCL.
- dlaqp2.f:171: replace stale DLARF with DLARF1F
(body calls DLARF1F; slaqp2 already declares SLARF1F).
- zhetrf_aa.f:166: drop stale ZGEMV
(body calls only ZGEMM; chetrf_aa correctly omits CGEMV).
- zlahef_aa.f:173: drop stale ZGEMM
(body calls only ZGEMV; clahef_aa correctly omits CGEMM).
- slaqr2.f:314: replace stale SLARF1L with SLARF1F
(body calls SLARF1F).
- sgelqt.f:147: drop stale SGEQRT2 and SGEQRT3
(body calls only SGELQT3 and SLARFB).
In the LSVEC && RSVEC branch of SGEJSV, the IF arm fills the strict
upper triangle of U with U(p,q) = -SIGN(TEMP1, U(q,p)) while the
ELSE arm zeros it via SLASET('U', ...). Both arms then call SGESVJ
on U with JOBA='L', which tells SGESVJ that U is lower triangular
and the strict upper is zero. After the IF arm that is not true:
SGESVJ silently drops the upper-triangular data the IF arm just
deposited, biasing the SVD result. JOBA='G' (general) is correct
for both arms; DGEJSV already uses 'G' at the matching call site.
In the RSVEC && !LSVEC && !ALMORT branch of DGEJSV, the inner DGESVJ
call passes WORK(N+1) as the workspace base (offset by N) but the
full LWORK as the workspace size. DGESVJ may then write up to N
entries past the end of WORK(LWORK). The float sibling SGEJSV
correctly passes LWORK-N at the same call site.
Bug: In ?ROT call LDX11 is passed as the leading dimension of X21.
Fix: use LDX21 as the INCY argument, matching how X21 is addressed
everywhere else in the same loop body.
The extended complex NRM2 tests can compare an expected +Inf norm with
a computed +Inf norm. The relative-error path then evaluates Inf - Inf,
producing NaN and reporting a spurious failure.
Treat exactly equal results as zero test ratio before computing the
relative difference. This matches the existing SNRM2 and DNRM2 test
logic.
Fixes#1047.
Also included sgecxx.f in to
SRC/CMakeLists.txt
SRC/Makefile
and modified SRC/lapack_64.h to reflect the addition
SRC/sgecxx.f
modified: SRC/CMakeLists.txt
modified: SRC/Makefile
modified: SRC/lapack_64.h
new file: SRC/sgecxx.f
since min( M, N) = 0 implies min( MSUB, NSUB) = 0,
changed
From:
IF( MIN( MINMN, MIN( MSUB, NSUB )).EQ.0 ) THEN
K = 0
MAXC2NRMK = ZERO
RELMAXC2NRMK = ZERO
FNRMK = ZERO
RETURN
END IF
To:
IF( MIN( MSUB, NSUB ).EQ.0 ) THEN
K = 0
MAXC2NRMK = ZERO
RELMAXC2NRMK = ZERO
FNRMK = ZERO
RETURN
END IF
modified: SRC/dgecxx.f
after NSEL columns and NFREE columns factorization:
from update style K = NSEL, and K = NSEL + KFREE
to increment style K = K + NSEL, K = K + KFEE
modified: SRC/dgecxx.f
In case, when we return the matrrix X as well, we use the copy
of the origonal matrix A that is stored in X. So that we do not need
to save the matrix A into the array C, and do not need to select the
columns of A in the array C in place. Instead, we just copy the selected
columns of the matrix A into the matrix C.
modified: SRC/dgecxx.f
1) added 'On exit' parameter descriptions to DESEL_ROWS and SEL_DESEL_COLS, since they are modified on output.
2) For row deselection, changed:
IPIV( I ) = IPIV( MSUB )
IPIV( MSUB ) = I
ITEMP = DESEL_ROWS( I )
DESEL_ROWS( I ) = DESEL_ROWS( MSUB )
DESEL_ROWS( MSUB ) = ITEMP into:
into
IPIV( I ) = IPIV( MSUB )
IPIV( MSUB ) = I
DESEL_ROWS( MSUB ) = DESEL_ROWS( I )
DESEL_ROWS( I ) = -1
2) cleaned up comments in the code dgecxx.f
modified: SRC/dgecxx.f
Quick rfturn if possible for
a) M = 0 or N = 0. There is no matrix A(1:M,1:N).
b) MSUB = 0 or NSUB = 0. There is no matrix A_sub(1:MSUB,1:NSUB).
modified: SRC/dgecxx.f
(1) removed redundant '--config ${{env.BUILD_TYPE}}' from 'cmake --build build -config ${{env.BUILD_TYPE}}' for a sigle configuration generator Ninja.
(2) wrote comments before each 'cmake --build build' about '--config ${{env.BUILD_TYPE}}' redundancy.
(3) in test-install-cblas-lapacke-without-fortran-compiler job, addded 'env' field 'BUILD_TYPE: Release' to make it consistent with other jobs in the script.
Rewrite the complex sine computation in CLARTG and ZLARTG to avoid forming a large intermediate value before the final multiplication by the conjugate of g.
The existing scaling keeps f2*h2 in a safe range, so this is not an overflow or underflow fix for f2*h2 itself. However, expressions such as
conjg(g) * ( f / sqrt(f2*h2) )
can still form a large intermediate value in the division before it is multiplied by conjg(g). Use the mathematically equivalent form
( f / sqrt(f2) ) * ( conjg(g) / sqrt(h2) )
so that the factors stay closer to unit scale. Apply the same rewrite to the scaled branch using fs and gs.
Replace direct NORM character comparisons for the one-norm option with LSAME in the condition estimation routines. This keeps the '1' checks consistent with the existing LSAME handling for the equivalent 'O' option.
Replace direct UPLO character comparisons in the LATSP and LATSY test helpers with LSAME. This keeps option handling consistent with the LAPACK convention for case-insensitive checks.
Replace direct UPLO character comparisons in the LALSD routines with LSAME. This keeps option handling consistent with the surrounding LAPACK convention for case-insensitive checks.
Replace direct case-sensitive TRANS character comparisons in the GTTRS routines with LSAME. This keeps option handling consistent with the surrounding LAPACK convention for case-insensitive checks.
Replace direct case-sensitive UPLO character comparisons in CPTTRS and ZPTTRS with LSAME. This matches the surrounding LAPACK convention for case-insensitive option checks.
Replace hard-coded floating-point constants with named constants in selected TESTING/EIG error-exit tests. This keeps the test setup code consistent with surrounding LAPACK test style.
Replace REALONE/REALZERO and complex ZERO/ONE with
type-specific named constants in the CSD test routines:
ZERO/ONE for real scalars, and CZERO/CONE for complex values.
Update {C,Z}LASET, {C,Z}GEMM, and {C,Z}HERK call sites to use
the matching constant type, and replace literal imaginary zeros
in CMPLX/DCMPLX calls with the named real ZERO constant.
No functional change intended.
Replace hard-coded floating-point constants with existing named
constants in the drvrf3 and drvrfp test drivers. This keeps the test
initialization code consistent with surrounding LAPACK test style.
TESTING/csd.in declares that the number of values of M, P, and Q
is 10, but each of the three data lines actually contains 11
entries.
Update the count to 11 so the header matches the test input data.
This is a test-data consistency fix only.
Replace hard-coded 1./1.D0 literals with the named constant ONE
in several TESTING/EIG error-exit test routines.
Add missing ONE parameter declarations where needed so the test
setup code follows the surrounding named-constant style.
The DMD test drivers use the testing ILAENV from TESTING/EIG, where
ISPEC=9 returns IPARMS(9). The drivers never initialized that entry,
so the xGESDD/xBDSDC divide-and-conquer cutoff SMLSIZ came from
undefined state.
This undefined test state can lead to invalid xLASD0 calls and a large
number of false failures. In this patch we initialize XLAENV(9,25) in
the s/c/d/z DMD test drivers so the tests start from a defined ILAENV
configuration.
Replace the literal 1.0 / 1.0D0 in the computation of
MU = SQRT(ONE - NU**2) so the BBCSD routines consistently use
the named parameter constants already defined in each source.
Also reorder the parameter declarations to match the PARAMETER list
and remove trailing blank lines at end of file.
No functional change intended.
CUNMLQ's documentation says LWORK must be:
If SIDE = 'L', LWORK >= max(1,N);
if SIDE = 'R', LWORK >= max(1,M).
In the current implementation, however, when K=0 a workspace query
will return LWORK=1 in WORK(1). This means a subsequent call to CUNMLQ
with a workspace of that size will fail with INFO = -12.
The other ???MLQ routines return consistent values of LWORK when K=0
(that is, equal to or greater than NW) so this patch makes CUNMLQ's
behaviour match theirs.
The local ABS1 statement function in CLARGV and ZLARGV does not compute
the usual complex ABS1/CABS1 quantity. It returns
max(abs(real(z)), abs(aimag(z)))
and is used only as a scaling helper in the same algorithmic path as
CLARTG/ZLARTG.
Rename the helper to CABSMAX so that the name matches its actual
behavior and does not suggest CABS1 semantics.
No numerical behavior is changed.
Several LAPACK, BLAS, and CBLAS source files defined a local statement
function named ABS1 for the complex 1-norm approximation:
ABS1( X ) = ABS( REAL( X ) ) + ABS( AIMAG( X ) )
ABS1( X ) = ABS( DBLE( X ) ) + ABS( DIMAG( X ) )
The majority of the codebase already uses CABS1 for this identical
purpose. This commit renames ABS1 to CABS1 in all remaining files
(definition line, declaration line, and all call sites within the
same file) to make the naming consistent across the repository.
A small number of fixed-form lines required continuation-line splits
to stay within the 72-column limit after the rename.
No numerical change. Statement functions are file-local in Fortran,
so there is no ABI or interface impact.
This is a preparatory cleanup before inlining these statement
functions (see issue #1200).
Replace external function references to SCABS1 and DCABS1 with a local
statement function CABS1 in CAXPY and ZAXPY respectively, eliminating
the dependency on those auxiliary routines.
Turn on test options that were left disabled in several TESTING input files.
Set "Put T to test the driver routines" to T in cgg.in, dgg.in, sgg.in,
and zgg.in so the generalized nonsymmetric eigenvalue driver tests are run.
Also set "Put T to test the error exits" to T in cbb.in, dbb.in, sbb.in,
and zbb.in to restore the corresponding error-exit checks.
Turn on test options that were left disabled in several TESTING input files.
Set "Put T to test the driver routines" to T in cgg.in, dgg.in, sgg.in,
and zgg.in so the generalized nonsymmetric eigenvalue driver tests are run.
Also set "Put T to test the error exits" to T in cbb.in, dbb.in, sbb.in,
and zbb.in to restore the corresponding error-exit checks.
In cdrvsg2stg.f, ddrvsg2stg.f, sdrvsg2stg.f, and zdrvsg2stg.f, the
three RANGE='A'/'V'/'I' calls to CHPGVX, DSPGVX, SSPGVX, and ZHPGVX
were passing INFO as the output error argument instead of IINFO.
The error-check block immediately following each call tests IINFO.NE.0,
but IINFO was never updated by the routine, so errors were silently
ignored. Additionally, the block sets INFO = ABS(IINFO), which would
overwrite the value ZHPGVX/xSPGVX had written into INFO with the
stale value of IINFO.
All other driver calls in these files (ZHEGV, ZHEGVD, ZHEGVX, ZHPGV,
ZHPGVD, ZHBGV, ZHBGVD, ZHBGVX and their s/d/c equivalents) correctly
use IINFO. This commit brings the xSPGVX/xHPGVX calls into line with
the established pattern.
Affected routines (3 call sites each):
CHPGVX in cdrvsg2stg.f
DSPGVX in ddrvsg2stg.f
SSPGVX in sdrvsg2stg.f
ZHPGVX in zdrvsg2stg.f
Remove the erroneous "LDSWORK = 2" assignment inside the LQUERY branch
of STRSYL3, DTRSYL3, CTRSYL3, and ZTRSYL3. The assignment overwrites
the caller's input argument, which is declared as intent(in) in the
documentation. The assignment was unnecessary because SWORK(1,1) and
SWORK(2,1) access column 1 only, making the leading dimension
irrelevant for these stores (offset = (i-1) + (j-1)*LDSWORK, j=1).
In ddrvst.f, ddrvst2stg.f, and dlatm4.f, DBLE() was applied to
DOUBLE PRECISION array elements assigned to DOUBLE PRECISION
variables ― a no-op conversion. Similarly, in sdrvst.f,
sdrvst2stg.f, and slatm4.f, REAL() was applied to REAL array
elements assigned to REAL variables.
Remove these 168 redundant calls. Integer-to-real conversions
(e.g., DBLE(N), DBLE(KLEN-1), REAL(MAX(1,N))) are retained as
they are semantically necessary.
In 26 driver routines across all four precisions (S, D, C, Z),
xSTEBZ was called writing directly to INFO, which was then
silently overwritten by xSTEIN. Two bugs are fixed:
1. xSTEBZ errors were not propagated to the caller at all.
2. When xSTEBZ returned INFO > 0, eigenvectors were computed
with an incomplete or empty eigenvalue set (INFO=2,3,4) or
with reduced accuracy (INFO=1), producing silently wrong
results.
Fix: route xSTEBZ return value through IINFO. For INFO != 1,
skip xSTEIN entirely via GO TO. For INFO == 1 (bisection
convergence warning), xSTEIN is still called since M eigenvalues
are available; the warning is preserved in INFO.
The xSTEBZ error is encoded as INFO = N + IINFO to distinguish
it from xSTEIN failures (1..N), matching the convention already
used for xPBSTF errors in the xBGVX routines. For the four
xBGVX routines, which already use INFO = N+i for xPBSTF, the
xSTEBZ error is encoded as INFO = 2*N + IINFO.
Update INFO documentation in all 26 files accordingly.
Also add IINFO to the INTEGER declaration in dstevx.f and
sstevx.f where it was missing.
Files modified (26):
SRC/chbevx.f, SRC/chbevx_2stage.f, SRC/chbgvx.f,
SRC/cheevx.f, SRC/cheevx_2stage.f, SRC/chpevx.f,
SRC/dsbevx.f, SRC/dsbevx_2stage.f, SRC/dsbgvx.f,
SRC/dspevx.f, SRC/dstevx.f, SRC/dsyevx.f, SRC/dsyevx_2stage.f,
SRC/ssbevx.f, SRC/ssbevx_2stage.f, SRC/ssbgvx.f,
SRC/sspevx.f, SRC/sstevx.f, SRC/ssyevx.f, SRC/ssyevx_2stage.f,
SRC/zhbevx.f, SRC/zhbevx_2stage.f, SRC/zhbgvx.f,
SRC/zheevx.f, SRC/zheevx_2stage.f, SRC/zhpevx.f
Fix workspace size handling in {s,d,c,z}{sy,sp,he,hp}gvd:
1. Workspace readback: remove redundant REAL()/DBLE() casts on INTEGER
and same-type operands in the post-CHEEVD/ZHEEVD/etc. MAX expressions.
The old pattern INT(MAX(REAL(int_var), REAL(fp_var))) needlessly
round-tripped integers through floating-point; for IWORK (already
INTEGER) the conversion was entirely spurious and risks precision
loss when 5*N+3 exceeds the 23-bit (single) or 52-bit (double)
significand.
2. WORK(1) writes: use SROUNDUP_LWORK/DROUNDUP_LWORK in dspgvd, dsygvd,
zhegvd, zhpgvd where the optimal workspace size was previously stored
via bare assignment (WORK(1) = LOPT), losing the ceiling guarantee
that ROUNDUP_LWORK provides.
3. RWORK(1) writes: replace REAL(LROPT) with SROUNDUP_LWORK (chegvd,
chpgvd) or DROUNDUP_LWORK (zhegvd, zhpgvd). The zhegvd/zhpgvd case
was a latent bug: RWORK is DOUBLE PRECISION but REAL() truncated to
single precision before storing.
4. Add DROUNDUP_LWORK declarations (type + EXTERNAL) to the four
double-precision / complex-16 routines that lacked them. Remove
now-unused REAL/DBLE from INTRINSIC lists where applicable.
The INTEGER declaration line added by PR #1202 exceeds column 72,
causing 'MINMNFACT' to extend into the sequence number field
(columns 73-80). In fixed-form Fortran, compilers silently truncate
at column 72, so 'MINMNFACT' is parsed as 'MINMNF', leaving the
actual variable undeclared.
Move KBOUND, MINMNFACT to the continuation line to keep all code
within columns 1-72.
In all four variants (SLAQP2RK, DLAQP2RK, CLAQP2RK, ZLAQP2RK),
KMAX was declared as [in] in the documentation but was overwritten
internally via:
KMAX = MIN( KMAX, MINMNFACT )
This is a bug in the reference LAPACK implementation: the Fortran
calling convention silently tolerates this when the caller passes
a temporary expression, but the intent annotation is violated and
C/C++ translations fail to compile (cannot bind rvalue to non-const
reference).
Introduce local variable KBOUND to hold the clamped value:
KBOUND = MIN( KMAX, MINMNFACT )
and replace all subsequent uses of KMAX in the executable section
(loop bound and final assignment K = KBOUND) with KBOUND.
KMAX itself is no longer modified.
The four TESTING/LIN routines currently document ISEED as an
INTEGER array of dimension (4), but their dummy argument
declarations use ISEED(*).
All four routines pass ISEED to CLARND or ZLARND, whose interfaces
require ISEED(4) and document that the fourth element must be odd.
Replace the assumed-size declaration with an explicit size of 4 in
both the commented argument declarations and the actual dummy
argument declarations, so that the source matches the documented
contract and the callee interfaces.
No functional change is intended.
The default seed generates a matrix for N=6, JTYPE=21 that causes
DGGES to fail (INFO=9) when compiled without FMA instructions.
Use a custom seed that avoids this specific ill-conditioned case
while maintaining full test coverage.
Implement the support for the `_Fcomplex` and `_Dcomplex` types used
by MSVC in place of the standard C99 complex types. This is necessary
to make LAPACK build out of the box with MSVC, since it does not
implement the default C99 types.
See: https://learn.microsoft.com/en-us/cpp/c-runtime-library/complex-math-support
I went for the simplest implementation possible, limiting the changes
to swapping the default types used when MSVC is used as the compiler,
also when `lapack_config.h` is not used. I haven't added
a `LAPACK_COMPLEX_*` ifdef for it, but I can do that if you prefer.
Signed-off-by: Michał Górny <mgorny@quansight.com>
Add substitutions to `lapack.pc.in`, in order to ensure that
the generated `lapack64.pc` file correctly references the index64
library and BLAS dependency. It seems that other pkg-config templates
have been updated as part of #462 but this one was omitted.
As a result, finding a lapack64 via pkg-config gave non-index64
libraries.
Signed-off-by: Michał Górny <mgorny@gentoo.org>
The modulefile la_xisnan.F90 depends on the modulefile
la_constants.f90 but this dependency is not expressed in the CMake
rules. In some parallel builds we have observed failures where
compilation of objects that depend on la_constants.mod starts before
compilation of la_constants.f90 has finished.
This patch modifies CMakeLists.txt to ensure that la_constants.mod is
built before any other object or modulefile that depends on it.
Bug reported by @neil-lindquist. Thanks Neil!
On line 93 of both lapacke_cunmlq_work.c and lapacke_zunmlq_work.c, m is passed
to LAPACKE_zge_trans as the 2nd dimension. However, the 2nd dimension should be
r to handle side right correctly. All the other versions of {or,un}m{qr,lq} seem
to be correct.
Also line 52 of lapacke_cunmlq.c and lapacke_zunmlq.c have the same issue: m is
used for the column dimension instead of r. (Those files also do not currently
compute r). The real valued cases have the correct behavior.
- make the SRNAME in XERBLA more robust against strings passed from C (e.g. OpenBLAS)
- adjust the maximum length of a function name from 6 to 7 characters
- add a missing parameter in the error output for z/cgemmtr.
For the extended API subroutine names are extended with _64 (e.g.
CGEGS becomes CGEGS_64). Extra space is needed so that the extension
does not violate Fortran line length conventions.
CMake only sets install names on darwin to `@rpath/<name>` (which is
desired otherwise rpaths don't work at all) when CMP0042 is ON. That's
the default when CMake 3.0 or higher is required. And lapack requires it
already for years: as of v3.9.1
(8f004b353a).
So, delete the old workarounds that effectively set CMP0042 to ON.
Further, delete the following three options that are redefinitions of
builtin with values that are builtin defaults:
- `CMAKE_MACOSX_RPATH`
- `CMAKE_SKIP_BUILD_RPATH`
- `CMAKE_BUILD_WITH_INSTALL_RPATH`
Lastly, lapack automatically sets `CMAKE_INSTALL_RPATH_USE_LINK_PATH` to
`ON` whenever installing to a non-system dir. The assumption is that
whenever you install something to a non-system dir, you need rpaths to
locate dependencies. But this is just an assumption which may or may
not hold. The downside of it is that the option can be annoying when
lapack is used as a sub-project as it affects a global CMake variable
(for example OpenBLAS uses lapack as a sub-project). Instead, let users
or packagers provide this on the command line if they really need it --
remove it from lapack as it's as helpful as it is harmful.
The `CMAKE_INSTALL_LIBDIR` was used here from the command line, probably
accidentally. It is a variable provided by the core CMake module
GNUInstallDirs and shouldn't be overridden. The variable, that makes
sense in this context is the `CMAKE_INSTALL_PREFIX` variable, which is
intended to be set by the user.
It names a subdirectory added to the install location of all LAPACK
binaries. It is empty by default.
This allows a consumer, to install the Reference LAPACK binaries into a
subdirectory of, e.g., `/usr/local/lib` without inadvertantly changing
the install location of the CMake package scripts, which remain
unchanged in `/usr/local/lib/cmake`.
This can be necessary to avoid conflicts with other BLAS/LAPACK
distributions. Previously, this would require the consumer to override
`CMAKE_INSTALL_LIBDIR` directly. This shouldn't be done, though, because
the variable is provided by the core CMake module GNUInstallDirs and is
used in many places. Thus, changing it can have unforeseen consequences.
Here, overriding it also changed the install locations of the CMake
package scripts and PKGConfig files, which prevents them from being
discovered by default by their respective tools.
Fix the following warning by GCC 12.2.0:
Warning: Use of the NUMERIC_STORAGE_SIZE named constant from intrinsic
module ISO_FORTRAN_ENV at (1) is incompatible with option
-fdefault-integer-8
Re-scale the input vector even if `X` is negligibly small in norm if the
imaginary part of `ALPHA` is nonzero. For otherwise `XNORM` will not be
computed with a small _relative_ error.
fixes#980
SRC/zgedmd.f90:213: warning: reached end of comment while inside a \verbatim block; check for missing \endverbatim tag!
SRC/zgedmdq.f90:710: warning: unexpected command endverbatim
SRC/cgedmdq.f90:548: warning: argument 'lzwork' from the argument list of cgedmdq has multiple @param documentation sections
SRC/zgedmdq.f90:546: warning: argument 'lzwork' from the argument list of zgedmdq has multiple @param documentation sections
When both BUILD_HTML_DOCUMENTATION and BUILD_MAN_DOCUMENTATION are ON,
DOXYGEN_GENERATE_HTML was set to YES (and some other HTML-only variables
were set) whenever Doxyfile.man was generated, and therefore `make man`
would also populate DOCS/explore-html, but with less detail due to the
other differences between Doxyfile.man and Doxyfile.html.
This removes another difference with DOCS/Doxyfile.
From the CMake 3.9.6 documentation (earliest version describing
doxygen_add_docs, I've updated cmake_minimum_required to match):
"So that relative input paths work as expected, by default the working
directory of the Doxygen command will be the current source directory
(i.e. CMAKE_CURRENT_SOURCE_DIR)."
Likewise for the output directory:
"Set to CMAKE_CURRENT_BINARY_DIR by this module. Note that if the
project provides its own value for this and it is a relative path, it
will be converted to an absolute path relative to the current binary
directory. This is necessary because doxygen will normally be run from
a directory within the source tree so that relative source paths work as
expected."
The goal is to minimize the output of `doxygen -x DOCS/Doxyfile` so that
it contains only the settings specified in CMakeLists.txt. In all
cases, the changed values are intended to match what CMake is generating
when using -DBUILD_HTML_DOCUMENTATION=ON, and ideally the changes should
have no effect.
Comments for ABBREVIATE_BRIEF and EXAMPLE_PATTERNS describe the default
behavior when they are blank, but our blank values show up in the output
of `doxygen -x DOCS/Doxyfile` indicating that blank is not the default
value. Setting values to match the current default behavior should have
no effect, unless Doxygen changes in the future. On the other hand,
MATHJAX_RELPATH has changed and will change again in newer Doxygen
versions.
CMake automatically inserts its own set of EXCLUDE_PATTERNS that
contains none of the patterns previously listed here. Neither the
previous values nor the CMake-generated ones should have any effect due
to our choice of INPUT and FILE_PATTERNS.
MATHJAX_RELPATH, LATEX_CMD_NAME, RTF_HYPERLINKS, and MAN_LINKS all
require some other option (USE_MATHJAX, GENERATE_LATEX, GENERATE_RTF,
and GENERATE_MAN, respectively) to be set to YES to take effect, and all
are set to NO, so these changes should have no effect. Note that the
CMake-generated Doxyfile.man sets MAN_LINKS=YES in addition to
GENERATE_MAN=YES.
Since this is a regression after upgrading from v3.11.0 to v3.12.0, we can
narrow down the range of the bug into the newly added SB1NRM2 subroutine.
According to the buildlog and the documentation in the code, the VALUES(9),
calculated as SXVALS(XX,2) should be infty. But the current code is returning
a zero (or randomly) initialized variable YY, which does not make sense.
In fact, if you go back to the reference implementation, namely the
supplementary material of this paper
https://dl.acm.org/doi/abs/10.1145/3061665
You can find a similar implementation of the SXVALS function in the
`la_xxvals.F90` file. This patch corrests the test following the reference
code.
Consolidated the initialization of the RESULT array and the reporting of
test outcomes for the xCHKQP3RK tests. The initialization of the RESULT array to
zeros is now occurring immediately before the tests, ensuring a clean
slate without scattering across different test phases. Reporting
functionality has been centralized at the end of the 5 tests,
eliminating redundant blocks and improving maintainability.
printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY"
fi
fi
- name:Install
# Since we use a single configuration generator, Ninja, there is no need to provide
# the '--config ${{env.BUILD_TYPE}}' option for the build step in the 'cmake --build' command.
printf '\nThe raw output of every test run (`testing_results.txt`) and a JUnit XML report are in the [test-results artifact](%s).\n' "$ARTIFACT_URL" >> "$GITHUB_STEP_SUMMARY"
* --Reference BLAS isa software package provided by Univ. of Tennessee, --
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.