@@ -18,8 +18,8 @@ subroutine collect_suite(testsuite)
18
18
type(unittest_type), allocatable, intent(out) :: testsuite(:)
19
19
20
20
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) &
23
23
]
24
24
end subroutine
25
25
@@ -132,6 +132,82 @@ subroutine test_sum(error)
132
132
#:endfor
133
133
134
134
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
135
211
136
212
end module test_intrinsics
137
213
0 commit comments