@@ -47,15 +47,18 @@ contains
47
47
subroutine ${name}$(error)
48
48
type(error_type), allocatable, intent(out) :: error
49
49
50
- ${inttype}$, parameter :: N = 10, Nreps = 2, Nm = 8
51
- ${inttype}$, parameter :: Nr = min(HUGE(N)/2_int64, 25_int64) ! < HUGE(N)
50
+ integer, parameter :: ip = ${intkind}$
51
+ ${inttype}$, parameter :: N = 10, Nm = 8
52
+ ${inttype}$, parameter :: near_huge = HUGE(N) - 1_ip ! Segfaults without the -1_ip
53
+ ${inttype}$, parameter :: Nreps = 2 ! Number of repetitions of random sampling
54
+ ${inttype}$, parameter :: Nr = 25_ip ! Size of random array, must be < HUGE(N)
52
55
53
56
${arraytype}$ :: x(N), x_copy(N), mat(Nm), mat_copy(Nm), len1(1), len2(2), &
54
57
kth_smallest, random_vals(Nr), one = 1
55
58
${inttype}$ :: i, p, up_rank, down_rank, mid_rank
56
59
real(dp) :: random_doubles(Nr) ! Deliberately double precision for all cases
57
60
logical :: test1, test2, test3
58
- integer, parameter :: ip = ${intkind}$
61
+ ${arraytype}$, allocatable :: long_array(:)
59
62
60
63
! x contains the numbers 1**2, 2**2, .... 10**2, with mixed-up order
61
64
x = (/( i**2, i=1, size(x, kind=ip) )/)
@@ -88,6 +91,19 @@ contains
88
91
if(allocated(error)) return
89
92
end do
90
93
94
+ ! The test below can catch overflow in naive calculation of the middle index, like discussed here:
95
+ ! https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html
96
+ ! But don't do it if near_huge is large, to avoid allocating a big array and slowing the tests
97
+ if(near_huge < 200) then
98
+ allocate(long_array(near_huge))
99
+ long_array = 0 * one
100
+ long_array(1:3) = one
101
+ call select(long_array, near_huge - 2_ip, kth_smallest)
102
+ call check( error, (kth_smallest == one), " ${name}$: designed to catch overflow in middle index")
103
+ if(allocated(error)) return
104
+ deallocate(long_array)
105
+ end if
106
+
91
107
! Simple tests
92
108
mat = one * [3, 2, 7, 4, 5, 1, 4, -1]
93
109
mat_copy = mat
@@ -213,9 +229,11 @@ contains
213
229
subroutine ${name}$(error)
214
230
type(error_type), allocatable, intent(out) :: error
215
231
216
- ${inttype}$, parameter :: N = 10, Nreps = 2, Nm = 8
217
- ${inttype}$, parameter :: Nr = min(HUGE(N)/2_int64, 25_int64) ! < HUGE(N)
218
232
integer, parameter :: ip = ${intkind}$
233
+ ${inttype}$, parameter :: N = 10, Nm = 8
234
+ ${inttype}$, parameter :: near_huge = HUGE(N) - 1_ip ! Segfaults without the -1_ip
235
+ ${inttype}$, parameter :: Nreps = 2 ! Number of repetitions of random sampling
236
+ ${inttype}$, parameter :: Nr = 25_ip ! Size of random array, must be < HUGE(N)
219
237
220
238
${arraytype}$ :: x(N), mat(Nm), len1(1), len2(2), random_vals(Nr), one=1
221
239
@@ -224,6 +242,8 @@ contains
224
242
real(dp) :: random_doubles(Nr) ! Deliberately double precision for all cases
225
243
integer(ip) :: i, j, p, up_rank, down_rank, mid_rank, kth_smallest
226
244
logical :: test1, test2, test3
245
+ ${arraytype}$, allocatable :: long_array(:)
246
+ ${inttype}$, allocatable :: long_array_index(:)
227
247
228
248
! Make x contain 1**2, 2**2, .... 10**2, but mix up the order
229
249
x = (/( i**2, i=1, size(x, kind=ip) )/)
@@ -258,6 +278,21 @@ contains
258
278
if(allocated(error)) return
259
279
end do
260
280
281
+ ! The test below would catch overflow in naive calculation of the middle index, like discussed here:
282
+ ! https://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html
283
+ ! But don't do it if near_huge is large, to avoid allocating a big array and slowing the tests
284
+ if(near_huge < 200) then
285
+ allocate(long_array(near_huge))
286
+ allocate(long_array_index(near_huge))
287
+ long_array = 0 * one
288
+ long_array(1:3) = one
289
+ long_array_index = (/( i, i = 1_ip, size(long_array, kind=ip) )/)
290
+ call arg_select(long_array, long_array_index, near_huge - 2_ip, kth_smallest)
291
+ call check( error, (kth_smallest < 4), " ${name}$: designed to catch overflow in middle index")
292
+ if(allocated(error)) return
293
+ deallocate(long_array, long_array_index)
294
+ end if
295
+
261
296
! Simple tests
262
297
mat = one * [3, 2, 7, 4, 5, 1, 4, -1]
263
298
indx_mat = (/( i, i = 1, size(mat, kind=ip) )/)
0 commit comments