Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 875d94d

Browse files
zozihaperazzjvdp1
authoredMay 9, 2025··
Add findBLAS support to CMakeLists.txt (#844)
* Add findBLAS support to CMakeLists.txt * find BLAS, LAPACK * add tests * Link to OpenBLAS for MINGW64 of MSYS2 * add FIND_BLAS option * Tests with OpenBLAS on MINGW64 and MKL on Ubuntu * Parallel CI construction to reduce CI time * Source MKL PATH * Add support mkl * test * fix test svd (related to signs of singular values) * Update .github/workflows/CI.yml * Fix typos * CI: split and optimize the BLAS CI process * fix(CMakeLists.txt): Correct cppFiles * feat(CMake): Enhance BLAS/LAPACK detection with ILP64 support --------- Co-authored-by: Federico Perini <[email protected]> Co-authored-by: Jeremie Vandenplas <[email protected]>
1 parent c14d599 commit 875d94d

File tree

13 files changed

+305
-37
lines changed

13 files changed

+305
-37
lines changed
 

‎.github/workflows/CI.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,24 @@ jobs:
6161
compiler: ${{ matrix.toolchain.compiler }}
6262
version: ${{ matrix.toolchain.version }}
6363

64+
# Build and test with built-in BLAS and LAPACK
6465
- name: Configure with CMake
6566
if: ${{ contains(matrix.build, 'cmake') }}
6667
run: >-
6768
cmake -Wdev -G Ninja
6869
-DCMAKE_BUILD_TYPE=Release
6970
-DCMAKE_MAXIMUM_RANK:String=4
7071
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
72+
-DFIND_BLAS:STRING=FALSE
7173
-S . -B ${{ env.BUILD_DIR }}
7274
7375
- name: Build and compile
7476
if: ${{ contains(matrix.build, 'cmake') }}
7577
run: cmake --build ${{ env.BUILD_DIR }} --parallel
7678

7779
- name: catch build fail
78-
run: cmake --build ${{ env.BUILD_DIR }} --verbose --parallel 1
7980
if: ${{ failure() && contains(matrix.build, 'cmake') }}
81+
run: cmake --build ${{ env.BUILD_DIR }} --verbose --parallel 1
8082

8183
- name: test
8284
if: ${{ contains(matrix.build, 'cmake') }}

‎.github/workflows/ci_BLAS.yml

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: CI_BLAS
2+
3+
on: [push, pull_request]
4+
5+
env:
6+
CTEST_TIME_TIMEOUT: "5" # some failures hang forever
7+
CMAKE_GENERATOR: Ninja
8+
9+
jobs:
10+
msys2-build:
11+
runs-on: windows-latest
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
include: [{ msystem: UCRT64, arch: x86_64 }]
16+
defaults:
17+
run:
18+
shell: msys2 {0}
19+
steps:
20+
- uses: actions/checkout@v2
21+
22+
- name: Setup MinGW native environment
23+
uses: msys2/setup-msys2@v2
24+
with:
25+
msystem: ${{ matrix.msystem }}
26+
update: false
27+
install: >-
28+
git
29+
mingw-w64-ucrt-${{ matrix.arch }}-gcc
30+
mingw-w64-ucrt-${{ matrix.arch }}-gcc-fortran
31+
mingw-w64-ucrt-${{ matrix.arch }}-python
32+
mingw-w64-ucrt-${{ matrix.arch }}-python-fypp
33+
mingw-w64-ucrt-${{ matrix.arch }}-cmake
34+
mingw-w64-ucrt-${{ matrix.arch }}-ninja
35+
mingw-w64-ucrt-${{ matrix.arch }}-openblas
36+
37+
# Build and test with external BLAS and LAPACK (OpenBLAS on UCRT64)
38+
- name: Configure with CMake and OpenBLAS
39+
run: >-
40+
PATH=$PATH:/ucrt64/bin/ cmake
41+
-Wdev
42+
-B build
43+
-DCMAKE_BUILD_TYPE=Debug
44+
-DCMAKE_Fortran_FLAGS_DEBUG="-Wall -Wextra -Wimplicit-interface -fPIC -g -fcheck=all -fbacktrace"
45+
-DCMAKE_MAXIMUM_RANK:String=4
46+
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
47+
-DFIND_BLAS:STRING=TRUE
48+
env:
49+
FC: gfortran
50+
CC: gcc
51+
CXX: g++
52+
53+
- name: CMake build with OpenBLAS
54+
run: PATH=$PATH:/ucrt64/bin/ cmake --build build --parallel
55+
56+
- name: catch build fail
57+
if: failure()
58+
run: PATH=$PATH:/ucrt64/bin/ cmake --build build --verbose --parallel 1
59+
60+
- name: CTest with OpenBLAS
61+
run: PATH=$PATH:/ucrt64/bin/ ctest --test-dir build --output-on-failure --parallel -V -LE quadruple_precision
62+
63+
- uses: actions/upload-artifact@v4
64+
if: failure()
65+
with:
66+
name: WindowsCMakeTestlog_openblas
67+
path: build/Testing/Temporary/LastTest.log
68+
69+
- name: Install project with OpenBLAS
70+
run: PATH=$PATH:/ucrt64/bin/ cmake --install build
71+
72+
Build:
73+
runs-on: ubuntu-latest
74+
strategy:
75+
fail-fast: false
76+
matrix:
77+
toolchain:
78+
- { compiler: intel, version: "2024.1" }
79+
build: [cmake]
80+
env:
81+
BUILD_DIR: ${{ matrix.build == 'cmake' && 'build' || '.' }}
82+
APT_PACKAGES: >-
83+
intel-oneapi-mkl
84+
intel-oneapi-mkl-devel
85+
steps:
86+
- name: Checkout code
87+
uses: actions/checkout@v4
88+
89+
- name: Set up Python 3.x
90+
uses: actions/setup-python@v5 # Use pip to install latest CMake, & FORD/Jin2For, etc.
91+
with:
92+
python-version: 3.x
93+
94+
- name: Install fypp
95+
run: pip install --upgrade fypp ninja
96+
97+
- name: Setup Fortran compiler
98+
uses: fortran-lang/setup-fortran@v1.6.1
99+
id: setup-fortran
100+
with:
101+
compiler: ${{ matrix.toolchain.compiler }}
102+
version: ${{ matrix.toolchain.version }}
103+
104+
- name: Install Intel oneAPI MKL
105+
run: |
106+
sudo apt-get install ${APT_PACKAGES}
107+
source /opt/intel/oneapi/mkl/latest/env/vars.sh
108+
printenv >> $GITHUB_ENV
109+
110+
# Build and test with external BLAS and LAPACK (MKL on Ubuntu with Intel compilers)
111+
- name: Configure with CMake and MKL
112+
run: >-
113+
cmake -Wdev -G Ninja
114+
-DCMAKE_BUILD_TYPE=Release
115+
-DCMAKE_MAXIMUM_RANK:String=4
116+
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
117+
-DFIND_BLAS:STRING=TRUE
118+
-S . -B ${{ env.BUILD_DIR }}
119+
120+
- name: Build and compile with MKL
121+
run: cmake --build ${{ env.BUILD_DIR }} --parallel
122+
123+
- name: catch build fail with MKL
124+
if: failure()
125+
run: cmake --build ${{ env.BUILD_DIR }} --verbose --parallel 1
126+
127+
- name: test with MKL
128+
run: >-
129+
ctest
130+
--test-dir ${{ env.BUILD_DIR }}
131+
--parallel
132+
--output-on-failure
133+
--no-tests=error
134+
135+
- name: Install project with MKL
136+
run: cmake --install ${{ env.BUILD_DIR }}

‎.github/workflows/ci_windows.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ jobs:
4343
-DCMAKE_Fortran_FLAGS_DEBUG="-Wall -Wextra -Wimplicit-interface -fPIC -g -fcheck=all -fbacktrace"
4444
-DCMAKE_MAXIMUM_RANK:String=4
4545
-DCMAKE_INSTALL_PREFIX=$PWD/_dist
46+
-DFIND_BLAS:STRING=FALSE
4647
env:
4748
FC: gfortran
4849
CC: gcc

‎CMakeLists.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,58 @@ if(NOT DEFINED CMAKE_MAXIMUM_RANK)
4242
set(CMAKE_MAXIMUM_RANK 4 CACHE STRING "Maximum array rank for generated procedures")
4343
endif()
4444

45+
option(FIND_BLAS "Find external BLAS and LAPACK" ON)
46+
47+
# --- find external BLAS and LAPACK
48+
if(FIND_BLAS)
49+
50+
message(STATUS "Searching for external BLAS/LAPACK")
51+
52+
# Common MKL setup
53+
if(DEFINED ENV{MKLROOT} OR "${BLA_VENDOR}" MATCHES "^(Intel|Intel10_64)")
54+
enable_language("C")
55+
message(STATUS "Detected Intel MKL environment")
56+
endif()
57+
58+
find_package(BLAS)
59+
find_package(LAPACK)
60+
61+
if(BLAS_FOUND AND LAPACK_FOUND)
62+
message(STATUS "Found external BLAS: ${BLAS_LIBRARIES}")
63+
message(STATUS "Found external LAPACK: ${LAPACK_LIBRARIES}")
64+
65+
# Detect ILP64 (common function)
66+
function(detect_ilp64 lib_name)
67+
set(${lib_name}_ILP64 False PARENT_SCOPE)
68+
# Prefer checking BLA_SIZEOF_INTEGER (available in CMake >= 3.22)
69+
if(DEFINED BLA_SIZEOF_INTEGER AND BLA_SIZEOF_INTEGER EQUAL 8)
70+
set(${lib_name}_ILP64 True PARENT_SCOPE)
71+
# Fallback: Check BLA_VENDOR manually for signs of ILP64
72+
elseif("${BLA_VENDOR}" MATCHES ".*(_ilp|ILP64).*")
73+
set(${lib_name}_ILP64 True PARENT_SCOPE)
74+
endif()
75+
endfunction()
76+
77+
detect_ilp64(BLAS)
78+
detect_ilp64(LAPACK)
79+
80+
# Set compile definitions
81+
if(BLAS_ILP64 OR LAPACK_ILP64)
82+
message(STATUS "Enabling 64-bit integer support (ILP64)")
83+
add_compile_definitions(STDLIB_EXTERNAL_BLAS_I64 STDLIB_EXTERNAL_LAPACK_I64)
84+
set(WITH_ILP64 True CACHE BOOL "Use 64-bit integer BLAS/LAPACK" FORCE)
85+
else()
86+
message(STATUS "Using standard 32-bit integer interface")
87+
add_compile_definitions(STDLIB_EXTERNAL_BLAS STDLIB_EXTERNAL_LAPACK)
88+
endif()
89+
90+
else()
91+
message(WARNING "External BLAS/LAPACK not found - "
92+
"Using built-in reference BLAS")
93+
endif()
94+
95+
endif()
96+
4597
# --- find preprocessor
4698
find_program(FYPP fypp)
4799
if(NOT FYPP)

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ Important options are
135135
- `-DBUILD_TESTING` set to `off` in case you want to disable the stdlib tests (default: `on`).
136136
- `-DCMAKE_VERBOSE_MAKEFILE` is by default set to `Off`, but if set to `On` will show commands used to compile the code.
137137
- `-DCMAKE_BUILD_TYPE` is by default set to `RelWithDebInfo`, which uses compiler flags suitable for code development (but with only `-O2` optimization). Beware the compiler flags set this way will override any compiler flags specified via `FFLAGS`. To prevent this, use `-DCMAKE_BUILD_TYPE=NoConfig` in conjunction with `FFLAGS`.
138+
- `-DFIND_BLAS` set to `off` in case you want to disable finding the external BLAS/LAPACK dependency (default: `on`).
138139

139140
For example, to configure a build using the Ninja backend while specifying compiler optimization via `FFLAGS`, generating procedures up to rank 7, installing to your home directory, using the `NoConfig` compiler flags, and printing the compiler commands, use
140141

‎config/fypp_deployment.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,8 @@
66
C_PREPROCESSED = (
77
"stdlib_linalg_constants" ,
88
"stdlib_linalg_blas" ,
9-
"stdlib_linalg_blas_aux",
10-
"stdlib_linalg_blas_s",
11-
"stdlib_linalg_blas_d",
12-
"stdlib_linalg_blas_q",
13-
"stdlib_linalg_blas_c",
14-
"stdlib_linalg_blas_z",
15-
"stdlib_linalg_blas_w",
169
"stdlib_linalg_lapack",
17-
"stdlib_linalg_lapack_aux",
18-
"stdlib_linalg_lapack_s",
19-
"stdlib_linalg_lapack_d",
20-
"stdlib_linalg_lapack_q",
21-
"stdlib_linalg_lapack_c",
22-
"stdlib_linalg_lapack_z",
23-
"stdlib_linalg_lapack_w"
10+
"test_blas_lapack"
2411
)
2512

2613
def pre_process_fypp(args):
@@ -105,7 +92,7 @@ def recursive_copy(folder):
10592
for root, _, files in os.walk(folder):
10693
for file in files:
10794
if file not in prune:
108-
if file.endswith((".f90", ".F90", ".dat", ".npy", ".c")):
95+
if file.endswith((".f90", ".F90", ".dat", ".npy", ".c", ".h")):
10996
shutil.copy2(os.path.join(root, file), base_folder+os.sep+folder+os.sep+file)
11097
recursive_copy('src')
11198
recursive_copy('test')

‎src/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ set(SRC
126126

127127
add_library(${PROJECT_NAME} ${SRC})
128128

129+
# Link to BLAS and LAPACK
130+
if(BLAS_FOUND AND LAPACK_FOUND)
131+
target_link_libraries(${PROJECT_NAME} "BLAS::BLAS")
132+
target_link_libraries(${PROJECT_NAME} "LAPACK::LAPACK")
133+
endif()
134+
129135
set_target_properties(
130136
${PROJECT_NAME}
131137
PROPERTIES

‎src/blas/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ set(dir "${CMAKE_CURRENT_SOURCE_DIR}")
44

55
list(APPEND fppFiles
66
blas/stdlib_blas_constants.fypp
7-
)
8-
9-
list(APPEND cppFiles
107
blas/stdlib_blas.fypp
118
blas/stdlib_blas_level1.fypp
129
blas/stdlib_blas_level2_ban.fypp
@@ -21,4 +18,3 @@ list(APPEND cppFiles
2118
)
2219

2320
set(fppFiles "${fppFiles}" PARENT_SCOPE)
24-
set(cppFiles "${cppFiles}" PARENT_SCOPE)

‎src/lapack/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
list(APPEND cppFiles
1+
list(APPEND fppFiles
22
lapack/stdlib_lapack_base.fypp
33
lapack/stdlib_lapack_solve.fypp
44
lapack/stdlib_lapack_others.fypp
@@ -55,4 +55,4 @@ list(APPEND cppFiles
5555
lapack/stdlib_lapack_svd_comp2.fypp
5656
)
5757

58-
set(cppFiles "${cppFiles}" PARENT_SCOPE)
58+
set(fppFiles "${fppFiles}" PARENT_SCOPE)

‎test/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ macro(ADDTEST name)
1010
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
1111
endmacro(ADDTEST)
1212

13+
macro(ADDTESTPP name)
14+
add_executable(test_${name} test_${name}.F90)
15+
target_link_libraries(test_${name} "${PROJECT_NAME}" "test-drive::test-drive")
16+
add_test(NAME ${name}
17+
COMMAND $<TARGET_FILE:test_${name}> ${CMAKE_CURRENT_BINARY_DIR}
18+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
19+
endmacro(ADDTESTPP)
20+
21+
1322
add_subdirectory(array)
1423
add_subdirectory(ascii)
1524
add_subdirectory(bitsets)
@@ -31,4 +40,4 @@ add_subdirectory(system)
3140
add_subdirectory(quadrature)
3241
add_subdirectory(math)
3342
add_subdirectory(stringlist)
34-
add_subdirectory(terminal)
43+
add_subdirectory(terminal)

‎test/linalg/CMakeLists.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
set(
22
fppFiles
33
"test_linalg.fypp"
4-
"test_blas_lapack.fypp"
5-
"test_linalg_cholesky.fypp"
64
"test_linalg_eigenvalues.fypp"
75
"test_linalg_solve.fypp"
86
"test_linalg_inverse.fypp"
@@ -16,8 +14,17 @@ set(
1614
"test_linalg_svd.fypp"
1715
"test_linalg_matrix_property_checks.fypp"
1816
"test_linalg_sparse.fypp"
17+
"test_linalg_cholesky.fypp"
18+
)
19+
20+
# Preprocessed files to contain preprocessor directives -> .F90
21+
set(
22+
cppFiles
23+
"test_blas_lapack.fypp"
1924
)
25+
2026
fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)
27+
fypp_f90pp("${fyppFlags}" "${cppFiles}" outPreprocFiles)
2128

2229
ADDTEST(linalg)
2330
ADDTEST(linalg_cholesky)
@@ -33,5 +40,5 @@ ADDTEST(linalg_lstsq)
3340
ADDTEST(linalg_qr)
3441
ADDTEST(linalg_schur)
3542
ADDTEST(linalg_svd)
36-
ADDTEST(blas_lapack)
3743
ADDTEST(linalg_sparse)
44+
ADDTESTPP(blas_lapack)

‎test/linalg/test_blas_lapack.fypp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ contains
2323
new_unittest("test_gemv${t1[0]}$${k1}$", test_gemv${t1[0]}$${k1}$), &
2424
new_unittest("test_getri${t1[0]}$${k1}$", test_getri${t1[0]}$${k1}$), &
2525
#:endfor
26-
new_unittest("test_idamax", test_idamax) &
26+
new_unittest("test_idamax", test_idamax), &
27+
new_unittest("test_external_blas",external_blas_test), &
28+
new_unittest("test_external_lapack",external_lapack_test) &
2729
]
2830

2931
end subroutine collect_blas_lapack
@@ -104,6 +106,75 @@ contains
104106

105107
end subroutine test_idamax
106108

109+
!> Test availability of the external BLAS interface
110+
subroutine external_blas_test(error)
111+
!> Error handling
112+
type(error_type), allocatable, intent(out) :: error
113+
114+
#ifdef STDLIB_EXTERNAL_BLAS
115+
interface
116+
subroutine saxpy(n,sa,sx,incx,sy,incy)
117+
import sp,ilp
118+
implicit none(type,external)
119+
real(sp), intent(in) :: sa,sx(*)
120+
integer(ilp), intent(in) :: incx,incy,n
121+
real(sp), intent(inout) :: sy(*)
122+
end subroutine saxpy
123+
end interface
124+
125+
integer(ilp), parameter :: n = 5, inc=1
126+
real(sp) :: a,x(n),y(n)
127+
128+
x = 1.0_sp
129+
y = 2.0_sp
130+
a = 3.0_sp
131+
132+
call saxpy(n,a,x,inc,y,inc)
133+
call check(error, all(abs(y-5.0_sp)<sqrt(epsilon(0.0_sp))), "saxpy: check result")
134+
if (allocated(error)) return
135+
136+
#else
137+
call skip_test(error, "Not using an external BLAS")
138+
#endif
139+
140+
end subroutine external_blas_test
141+
142+
!> Test availability of the external BLAS interface
143+
subroutine external_lapack_test(error)
144+
!> Error handling
145+
type(error_type), allocatable, intent(out) :: error
146+
147+
#ifdef STDLIB_EXTERNAL_LAPACK
148+
interface
149+
subroutine dgetrf( m, n, a, lda, ipiv, info )
150+
import dp,ilp
151+
implicit none(type,external)
152+
integer(ilp), intent(out) :: info,ipiv(*)
153+
integer(ilp), intent(in) :: lda,m,n
154+
real(dp), intent(inout) :: a(lda,*)
155+
end subroutine dgetrf
156+
end interface
157+
158+
integer(ilp), parameter :: n = 3
159+
real(dp) :: A(n,n)
160+
integer(ilp) :: ipiv(n),info
161+
162+
163+
A = eye(n)
164+
info = 123
165+
166+
! Factorize matrix
167+
call dgetrf(n,n,A,n,ipiv,info)
168+
169+
call check(error, info==0, "dgetrf: check result")
170+
if (allocated(error)) return
171+
172+
#else
173+
call skip_test(error, "Not using an external LAPACK")
174+
#endif
175+
176+
end subroutine external_lapack_test
177+
107178
end module test_blas_lapack
108179

109180

‎test/linalg/test_linalg_svd.fypp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ module test_linalg_svd
8686
if (allocated(error)) return
8787
call check(error, all(abs(s-s_sol)<=tol), test//': S')
8888
if (allocated(error)) return
89-
call check(error, all(abs(u-u_sol)<=tol) .or. all(abs(u+u_sol)<=tol), test//': U')
89+
call check(error, all(abs(abs(u)-abs(u_sol))<=tol), test//': U')
9090
if (allocated(error)) return
9191

9292
!> [S, U]. Overwrite A matrix
@@ -97,7 +97,7 @@ module test_linalg_svd
9797
if (allocated(error)) return
9898
call check(error, all(abs(s-s_sol)<=tol), test//': S')
9999
if (allocated(error)) return
100-
call check(error, all(abs(u-u_sol)<=tol) .or. all(abs(u+u_sol)<=tol), test//': U')
100+
call check(error, all(abs(abs(u)-abs(u_sol))<=tol), test//': U')
101101
if (allocated(error)) return
102102

103103
!> [S, U, V^T]
@@ -109,9 +109,9 @@ module test_linalg_svd
109109
if (allocated(error)) return
110110
call check(error, all(abs(s-s_sol)<=tol), test//': S')
111111
if (allocated(error)) return
112-
call check(error, all(abs(u-u_sol)<=tol) .or. all(abs(u+u_sol)<=tol), test//': U')
112+
call check(error, all(abs(abs(u)-abs(u_sol))<=tol), test//': U')
113113
if (allocated(error)) return
114-
call check(error, all(abs(vt-vt_sol)<=tol) .or. all(abs(vt+vt_sol)<=tol), test//': V^T')
114+
call check(error, all(abs(abs(vt)-abs(vt_sol))<=tol), test//': V^T')
115115
if (allocated(error)) return
116116

117117
!> [S, V^T]. Do not overwrite A matrix
@@ -123,7 +123,7 @@ module test_linalg_svd
123123
if (allocated(error)) return
124124
call check(error, all(abs(s-s_sol)<=tol), test//': S')
125125
if (allocated(error)) return
126-
call check(error, all(abs(vt-vt_sol)<=tol) .or. all(abs(vt+vt_sol)<=tol), test//': V^T')
126+
call check(error, all(abs(abs(vt)-abs(vt_sol))<=tol), test//': V^T')
127127
if (allocated(error)) return
128128

129129
!> [S, V^T]. Overwrite A matrix
@@ -134,7 +134,7 @@ module test_linalg_svd
134134
if (allocated(error)) return
135135
call check(error, all(abs(s-s_sol)<=tol), test//': S')
136136
if (allocated(error)) return
137-
call check(error, all(abs(vt-vt_sol)<=tol) .or. all(abs(vt+vt_sol)<=tol), test//': V^T')
137+
call check(error, all(abs(abs(vt)-abs(vt_sol))<=tol), test//': V^T')
138138
if (allocated(error)) return
139139

140140
!> [U, S, V^T].
@@ -144,11 +144,11 @@ module test_linalg_svd
144144
test = '[U, S, V^T]'
145145
call check(error,state%ok(),test//': '//state%print())
146146
if (allocated(error)) return
147-
call check(error, all(abs(u-u_sol)<=tol) .or. all(abs(u+u_sol)<=tol), test//': U')
147+
call check(error, all(abs(abs(u)-abs(u_sol))<=tol), test//': U')
148148
if (allocated(error)) return
149149
call check(error, all(abs(s-s_sol)<=tol), test//': S')
150150
if (allocated(error)) return
151-
call check(error, all(abs(vt-vt_sol)<=tol) .or. all(abs(vt+vt_sol)<=tol), test//': V^T')
151+
call check(error, all(abs(abs(vt)-abs(vt_sol))<=tol), test//': V^T')
152152
if (allocated(error)) return
153153

154154
!> [U, S, V^T]. Partial storage -> compare until k=2 columns of U rows of V^T
@@ -160,11 +160,11 @@ module test_linalg_svd
160160
test = '[U, S, V^T], partial storage'
161161
call check(error,state%ok(),test//': '//state%print())
162162
if (allocated(error)) return
163-
call check(error, all(abs(u(:,:2)-u_sol(:,:2))<=tol) .or. all(abs(u(:,:2)+u_sol(:,:2))<=tol), test//': U(:,:2)')
163+
call check(error, all(abs(abs(u(:,:2))-abs(u_sol(:,:2)))<=tol), test//': U(:,:2)')
164164
if (allocated(error)) return
165165
call check(error, all(abs(s-s_sol)<=tol), test//': S')
166166
if (allocated(error)) return
167-
call check(error, all(abs(vt(:2,:)-vt_sol(:2,:))<=tol) .or. all(abs(vt(:2,:)+vt_sol(:2,:))<=tol), test//': V^T(:2,:)')
167+
call check(error, all(abs(abs(vt(:2,:))-abs(vt_sol(:2,:)))<=tol), test//': V^T(:2,:)')
168168
if (allocated(error)) return
169169

170170
end subroutine test_svd_${ri}$

0 commit comments

Comments
 (0)
Please sign in to comment.