@@ -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 ]
2424end subroutine
2525
@@ -132,6 +132,82 @@ subroutine test_sum(error)
132132 #:endfor
133133
134134end 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
136212end module test_intrinsics
137213
0 commit comments