@@ -37,16 +37,21 @@ subroutine test_sum(error)
37
37
${t1}$, allocatable :: x(:)
38
38
${t1}$, parameter :: total_sum = 4*atan(1._${k1}$), tolerance = epsilon(1._${k1}$)*100
39
39
${t1}$ :: xsum(ncalc), meanval(ncalc), err(ncalc)
40
+ logical, allocatable :: mask(:), nmask(:)
40
41
41
42
allocate(x(n))
42
43
do i = 1, n
43
44
x(i) = 8*atan(1._${k1}$)*(real(i,kind=${k1}$)-0.5_${k1}$)/real(n,kind=${k1}$)**2
44
45
end do
46
+ allocate(mask(n),source=.false.); mask(1:n:2) = .true.
47
+ allocate(nmask(n)); nmask = .not.mask
45
48
! scramble array
46
49
do i = 1, n
47
50
call random_number(u)
48
51
j = 1 + floor(n*u)
49
52
call swap( x(i), x(j) )
53
+ call swap( mask(i), mask(j) )
54
+ call swap( nmask(i), nmask(j) )
50
55
end do
51
56
52
57
err(:) = 0._${k1}$
@@ -60,6 +65,18 @@ subroutine test_sum(error)
60
65
61
66
call check(error, all(err(:)<tolerance) , "real sum is not accurate" )
62
67
if (allocated(error)) return
68
+
69
+ err(:) = 0._${k1}$
70
+ do iter = 1, niter
71
+ xsum(1) = sum(x,mask)+sum(x,nmask) ! compiler intrinsic
72
+ xsum(2) = fsum_kahan(x,mask)+fsum_kahan(x,nmask) ! chunked Kahan summation
73
+ xsum(3) = fsum(x,mask)+fsum(x,nmask) ! chunked summation
74
+ err(1:ncalc) = err(1:ncalc) + abs(1._${k1}$-xsum(1:ncalc)/total_sum)
75
+ end do
76
+ err(1:ncalc) = err(1:ncalc) / niter
77
+
78
+ call check(error, all(err(:)<tolerance) , "masked real sum is not accurate" )
79
+ if (allocated(error)) return
63
80
end block
64
81
#:endfor
65
82
@@ -69,18 +86,23 @@ subroutine test_sum(error)
69
86
real(${k1}$), parameter :: total_sum = 4*atan(1._${k1}$), tolerance = epsilon(1._${k1}$)*100
70
87
real(${k1}$) :: err(ncalc)
71
88
${t1}$ :: xsum(ncalc), meanval(ncalc)
89
+ logical, allocatable :: mask(:), nmask(:)
72
90
73
91
allocate(x(n))
74
92
do i = 1, n
75
93
x(i) = complex(&
76
94
8*atan(1._${k1}$)*(real(i,kind=${k1}$)-0.5_${k1}$)/real(2*n,kind=${k1}$)**2,&
77
95
8*atan(1._${k1}$)*(real(i+n,kind=${k1}$)-0.5_${k1}$)/real(2*n,kind=${k1}$)**2)
78
96
end do
97
+ allocate(mask(n),source=.false.); mask(1:n:2) = .true.
98
+ allocate(nmask(n)); nmask = .not.mask
79
99
! scramble array
80
100
do i = 1, n
81
101
call random_number(u)
82
102
j = 1 + floor(n*u)
83
103
call swap( x(i), x(j) )
104
+ call swap( mask(i), mask(j) )
105
+ call swap( nmask(i), nmask(j) )
84
106
end do
85
107
86
108
err(:) = 0._${k1}$
@@ -94,6 +116,18 @@ subroutine test_sum(error)
94
116
95
117
call check(error, all(err(:)<tolerance) , "complex sum is not accurate" )
96
118
if (allocated(error)) return
119
+
120
+ err(:) = 0._${k1}$
121
+ do iter = 1, niter
122
+ xsum(1) = sum(x,mask)+sum(x,nmask) ! compiler intrinsic
123
+ xsum(2) = fsum_kahan(x,mask)+fsum_kahan(x,nmask) ! chunked Kahan summation
124
+ xsum(3) = fsum(x,mask)+fsum(x,nmask) ! chunked summation
125
+ err(1:ncalc) = err(1:ncalc) + abs(1._${k1}$-(xsum(1:ncalc)%re+xsum(1:ncalc)%im)/total_sum)
126
+ end do
127
+ err(1:ncalc) = err(1:ncalc) / niter
128
+
129
+ call check(error, all(err(:)<tolerance) , "complex masked sum is not accurate" )
130
+ if (allocated(error)) return
97
131
end block
98
132
#:endfor
99
133
0 commit comments