Skip to content

Commit bf1ce2f

Browse files
committed
add dot_product tests
1 parent c38dcd6 commit bf1ce2f

File tree

1 file changed

+78
-2
lines changed

1 file changed

+78
-2
lines changed

test/intrinsics/test_intrinsics.fypp

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ subroutine collect_suite(testsuite)
1818
type(unittest_type), allocatable, intent(out) :: testsuite(:)
1919

2020
testsuite = [ &
21-
new_unittest('sum', test_sum) &
22-
!new_unittest('dot_product', test_dot_product) &
21+
new_unittest('sum', test_sum), &
22+
new_unittest('dot_product', test_dot_product) &
2323
]
2424
end subroutine
2525

@@ -132,6 +132,82 @@ subroutine test_sum(error)
132132
#:endfor
133133

134134
end subroutine
135+
136+
subroutine test_dot_product(error)
137+
!> Error handling
138+
type(error_type), allocatable, intent(out) :: error
139+
140+
!> Internal parameters and variables
141+
integer, parameter :: n = 1e3, ncalc = 3, niter = 100
142+
real(sp) :: u
143+
integer :: iter, i, j
144+
!====================================================================================
145+
#:for k1, t1, s1 in R_KINDS_TYPES
146+
block
147+
${t1}$, allocatable :: x(:)
148+
${t1}$, parameter :: total_sum = 4*atan(1._${k1}$), tolerance = epsilon(1._${k1}$)*100
149+
${t1}$ :: xsum(ncalc), meanval(ncalc), err(ncalc)
150+
151+
allocate(x(n))
152+
do i = 1, n
153+
x(i) = sqrt( 8*atan(1._${k1}$)*(real(i,kind=${k1}$)-0.5_${k1}$)/real(n,kind=${k1}$)**2 )
154+
end do
155+
! scramble array
156+
do i = 1, n
157+
call random_number(u)
158+
j = 1 + floor(n*u)
159+
call swap( x(i), x(j) )
160+
end do
161+
162+
err(:) = 0._${k1}$
163+
do iter = 1, niter
164+
xsum(1) = dot_product(x,x) ! compiler intrinsic
165+
xsum(2) = fprod_kahan(x,x) ! chunked Kahan summation
166+
xsum(3) = fprod(x,x) ! chunked summation
167+
err(1:ncalc) = err(1:ncalc) + abs(1._${k1}$-xsum(1:ncalc)/total_sum)
168+
end do
169+
err(1:ncalc) = err(1:ncalc) / niter
170+
171+
call check(error, all(err(:)<tolerance) , "real dot_product is not accurate" )
172+
if (allocated(error)) return
173+
end block
174+
#:endfor
175+
176+
#:for k1, t1, s1 in C_KINDS_TYPES
177+
block
178+
${t1}$, allocatable :: x(:)
179+
real(${k1}$), parameter :: total_sum = 4*atan(1._${k1}$), tolerance = epsilon(1._${k1}$)*100
180+
real(${k1}$) :: err(ncalc)
181+
${t1}$ :: xsum(ncalc), meanval(ncalc)
182+
183+
allocate(x(n))
184+
do i = 1, n
185+
x(i) = complex(&
186+
sqrt(8*atan(1._${k1}$)*(real(i,kind=${k1}$)-0.5_${k1}$)/real(2*n,kind=${k1}$)**2),&
187+
sqrt(8*atan(1._${k1}$)*(real(i+n,kind=${k1}$)-0.5_${k1}$)/real(2*n,kind=${k1}$)**2))
188+
end do
189+
! scramble array
190+
do i = 1, n
191+
call random_number(u)
192+
j = 1 + floor(n*u)
193+
call swap( x(i), x(j) )
194+
end do
195+
196+
err(:) = 0._${k1}$
197+
do iter = 1, niter
198+
xsum(1) = dot_product(x,x) ! compiler intrinsic
199+
xsum(2) = fprod_kahan(x,x) ! chunked Kahan dot_product
200+
xsum(3) = fprod(x,x) ! chunked dot_product
201+
err(1:ncalc) = err(1:ncalc) + abs(1._${k1}$-(xsum(1:ncalc)%re+xsum(1:ncalc)%im)/total_sum)
202+
end do
203+
err(1:ncalc) = err(1:ncalc) / niter
204+
205+
call check(error, all(err(:)<tolerance) , "complex dot_product is not accurate" )
206+
if (allocated(error)) return
207+
end block
208+
#:endfor
209+
210+
end subroutine
135211

136212
end module test_intrinsics
137213

0 commit comments

Comments
 (0)