Skip to content

Provide BLAS, LAPACK backends and interfaces #772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f3ac970
Upload BLAS/LAPACK, create preprocessor directives
perazz Mar 11, 2024
5882ad6
enable fpm deployment
perazz Mar 11, 2024
ac65112
update `fpm` version in CI
perazz Mar 11, 2024
c25e3ff
add tests
perazz Mar 11, 2024
ce52faf
typo: `getri`
perazz Mar 11, 2024
3e8c5b6
safeguards for qp procedure templates
perazz Mar 11, 2024
29eeec2
public qp interfaces
perazz Mar 11, 2024
8be6484
more `WITH_QP` guards
perazz Mar 11, 2024
a937382
skip unsupported `xdp` precision
perazz Mar 11, 2024
a356f14
Delete .test_trapz.fypp.swp
perazz Mar 11, 2024
2ae057f
unify pre-processing of blas/lapack sources
perazz Mar 12, 2024
edfeb59
OpenMP: replace `cpp` macros with `!$` conditional compilation
perazz Mar 14, 2024
da5d90c
force `example.dat` back into repo
perazz Mar 14, 2024
d379e9c
free-form `!$omp` continuation style
perazz Mar 14, 2024
2be3340
indent OpenMP sentinels
perazz Mar 23, 2024
592e085
remove `FPM_DEPLOYMENT`
perazz Mar 24, 2024
5785f6c
Update src/stdlib_linalg_constants.fypp
perazz Mar 24, 2024
fa3f147
Merge branch 'blas_lapack_backend' of github.com:perazz/stdlib into b…
perazz Mar 24, 2024
281b068
Document BLAS/LAPACK backends
perazz Mar 26, 2024
4586f32
typo
perazz Mar 26, 2024
3c2349f
Update doc/specs/stdlib_linalg.md
perazz Mar 26, 2024
464aba4
Update doc/specs/stdlib_linalg.md
perazz Mar 26, 2024
a56d685
Update doc/specs/stdlib_linalg.md
perazz Mar 26, 2024
819f2b2
add Licensing information
perazz Mar 26, 2024
a46b86f
add `Syntax` section
perazz Mar 26, 2024
ae6c009
clarify fpm macros
perazz Mar 26, 2024
545b4c3
link to the conversion script
perazz Mar 26, 2024
e30b2ec
dnrm2/snrm2: fix missing interface type
perazz Mar 27, 2024
745bcf8
shorten doc comment
perazz Mar 27, 2024
c12b3c3
lapack interface: import procedure interfaces
perazz Mar 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add tests
  • Loading branch information
perazz committed Mar 11, 2024
commit c25e3ff248526edffb632e0d4f317da8e13ed3d4
2 changes: 2 additions & 0 deletions test/linalg/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
set(
fppFiles
"test_linalg.fypp"
"test_blas_lapack.fypp"
"test_linalg_matrix_property_checks.fypp"
)
fypp_f90("${fyppFlags}" "${fppFiles}" outFiles)

ADDTEST(linalg)
ADDTEST(linalg_matrix_property_checks)
ADDTEST(blas_lapack)
140 changes: 140 additions & 0 deletions test/linalg/test_blas_lapack.fypp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#:include "common.fypp"
#:set RC_KINDS_TYPES = REAL_KINDS_TYPES + CMPLX_KINDS_TYPES

module test_blas_lapack
use testdrive, only : new_unittest, unittest_type, error_type, check, skip_test
use stdlib_kinds, only: sp, dp, xdp, qp, int8, int16, int32, int64
use stdlib_linalg, only: eye
use stdlib_linalg_blas
use stdlib_linalg_lapack

implicit none

real(sp), parameter :: sptol = 1000 * epsilon(1._sp)
real(dp), parameter :: dptol = 1000 * epsilon(1._dp)
#:if WITH_QP
real(qp), parameter :: qptol = 1000 * epsilon(1._qp)
#:endif



contains

!> Collect all exported unit tests
subroutine collect_blas_lapack(testsuite)
!> Collection of tests
type(unittest_type), allocatable, intent(out) :: testsuite(:)

testsuite = [ &
#:for k1, t1 in REAL_KINDS_TYPES
new_unittest("test_gemv${t1[0]}$${k1}$", test_gemv${t1[0]}$${k1}$), &
new_unittest("test_getri${t1[0]}$${k1}$", test_gemv${t1[0]}$${k1}$), &
#:endfor
new_unittest("test_idamax", test_idamax) &
]

end subroutine collect_blas_lapack


#:for k1, t1 in REAL_KINDS_TYPES
subroutine test_gemv${t1[0]}$${k1}$(error)
!> Error handling
type(error_type), allocatable, intent(out) :: error

${t1}$ :: A(3,3),x(3),y(3),ylap(3),yintr(3),alpha,beta
call random_number(alpha)
call random_number(beta)
call random_number(A)
call random_number(x)
call random_number(y)
ylap = y
call gemv('No transpose',size(A,1),size(A,2),alpha,A,size(A,1),x,1,beta,ylap,1)
yintr = alpha*matmul(A,x)+beta*y

call check(error, sum(abs(ylap - yintr)) < sptol, &
"blas vs. intrinsics axpy: sum() < sptol failed")
if (allocated(error)) return

end subroutine test_gemv${t1[0]}$${k1}$

! Find matrix inverse from LU decomposition
subroutine test_getri${t1[0]}$${k1}$(error)
!> Error handling
type(error_type), allocatable, intent(out) :: error

integer(ilp), parameter :: n = 3
${t1}$ :: A(n,n)
${t1}$,allocatable :: work(:)
integer(ilp) :: ipiv(n),info,lwork,nb


A = eye(n)

! Factorize matrix (overwrite result)
call getrf(size(A,1),size(A,2),A,size(A,1),ipiv,info)
call check(error, info==0, "lapack getrf returned info/=0")
if (allocated(error)) return

! Get optimal worksize (returned in work(1)) (apply 2% safety parameter)
nb = stdlib_ilaenv(1,'${t1[0]}$getri',' ',n,-1,-1,-1)
lwork = nint(1.02*n*nb,kind=ilp)
allocate (work(lwork))

! Invert matrix
call getri(n,a,n,ipiv,work,lwork,info)

call check(error, info==0, "lapack getri returned info/=0")
if (allocated(error)) return

call check(error, sum(abs(A - eye(3))) < sptol, &
"lapack eye inversion: tolerance check failed")
if (allocated(error)) return

end subroutine test_getri${t1[0]}$${k1}$
#:endfor

! Return
subroutine test_idamax(error)
!> Error handling
type(error_type), allocatable, intent(out) :: error

integer(ilp), parameter :: n = 5
integer(ilp) :: imax
real(dp) :: x(n)

x = [1,2,3,4,5]

imax = stdlib_idamax(n,x,1)

call check(error, imax==5, "blas idamax returned wrong location")

end subroutine test_idamax

end module test_blas_lapack


program tester
use, intrinsic :: iso_fortran_env, only : error_unit
use testdrive, only : run_testsuite, new_testsuite, testsuite_type
use test_blas_lapack, only : collect_blas_lapack
implicit none
integer :: stat, is
type(testsuite_type), allocatable :: testsuites(:)
character(len=*), parameter :: fmt = '("#", *(1x, a))'

stat = 0
testsuites = [ &
new_testsuite("blas_lapack", collect_blas_lapack) &
]

do is = 1, size(testsuites)
write(error_unit, fmt) "Testing:", testsuites(is)%name
call run_testsuite(testsuites(is)%collect, error_unit, stat)
end do

if (stat > 0) then
write(error_unit, '(i0, 1x, a)') stat, "test(s) failed!"
error stop
end if
end program