Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
perazz committed Mar 11, 2024
1 parent ac65112 commit c25e3ff
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
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

0 comments on commit c25e3ff

Please sign in to comment.