1 /*
2 * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @key randomness
27 *
28 * @library /test/lib
29 * @modules jdk.incubator.vector
30 * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation $vectorteststype$
31 */
32
33 #warn This file is preprocessed before being compiled
34
35 import jdk.incubator.vector.VectorShape;
36 import jdk.incubator.vector.VectorSpecies;
37 import jdk.incubator.vector.VectorShuffle;
38 import jdk.incubator.vector.VectorMask;
39 import jdk.incubator.vector.VectorOperators;
40 import jdk.incubator.vector.Vector;
41 #if[!FP]
42 import jdk.incubator.vector.VectorMath;
43 #end[!FP]
44
45 #if[Byte]
46 import jdk.incubator.vector.ByteVector;
47 #end[Byte]
48 #if[Float]
49 import jdk.incubator.vector.FloatVector;
50 #end[Float]
51 #if[Int]
52 import jdk.incubator.vector.IntVector;
53 #end[Int]
54 #if[Double]
55 import jdk.incubator.vector.DoubleVector;
56 #end[Double]
57 #if[Short]
58 import jdk.incubator.vector.ShortVector;
59 #end[Short]
60 #if[Long]
61 import jdk.incubator.vector.LongVector;
62 #end[Long]
63
64 import org.testng.Assert;
65 import org.testng.annotations.DataProvider;
66 import org.testng.annotations.Test;
67
68 import java.lang.Integer;
69 import java.util.List;
70 import java.util.Arrays;
71 import java.util.function.BiFunction;
72 import java.util.function.IntFunction;
73 import java.util.Objects;
74 import java.util.stream.Collectors;
75 import java.util.stream.Stream;
76
77 @Test
78 public class $vectorteststype$ extends AbstractVectorTest {
79
80 #if[MaxBit]
81 static final VectorSpecies<$Wideboxtype$> SPECIES =
82 $Type$Vector.SPECIES_MAX;
83 #else[MaxBit]
84 static final VectorSpecies<$Wideboxtype$> SPECIES =
85 $Type$Vector.SPECIES_$bits$;
86 #end[MaxBit]
87
88 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
89
90 static $abstractvectortype$ bcast_vec = $abstractvectortype$.broadcast(SPECIES, ($type$)10);
91
92 #if[MaxBit]
93 static VectorShape getMaxBit() {
94 return VectorShape.S_Max_BIT;
95 }
96
97 private static final int Max = 256; // juts so we can do N/$bits$
98 #end[MaxBit]
99
100 #if[BITWISE]
101 private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2;
102 #end[BITWISE]
103 #if[FP]
104 // for floating point addition reduction ops that may introduce rounding errors
105 private static final $type$ RELATIVE_ROUNDING_ERROR_FACTOR_ADD = ($type$)10.0;
106
107 // for floating point multiplication reduction ops that may introduce rounding errors
108 private static final $type$ RELATIVE_ROUNDING_ERROR_FACTOR_MUL = ($type$)50.0;
109 #end[FP]
110
111 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$);
112
113 static void assertArraysStrictlyEquals($type$[] r, $type$[] a) {
114 for (int i = 0; i < a.length; i++) {
115 #if[FP]
116 $bitstype$ ir = $Wideboxtype$.$type$ToRaw$Bitstype$Bits(r[i]);
117 $bitstype$ ia = $Wideboxtype$.$type$ToRaw$Bitstype$Bits(a[i]);
118 if (ir != ia) {
119 #if[Float]
120 Assert.fail(String.format("at index #%d, expected = %08X, actual = %08X", i, ia, ir));
121 #else[Float]
122 Assert.fail(String.format("at index #%d, expected = %016X, actual = %016X", i, ia, ir));
123 #end[Float]
124 }
125 #else[FP]
126 if (r[i] != a[i]) {
127 Assert.fail("at index #" + i + ", expected = " + a[i] + ", actual = " + r[i]);
128 }
129 #end[FP]
130 }
131 }
132
133 interface FUnOp {
134 $type$ apply($type$ a);
135 }
136
137 static void assertArraysEquals($type$[] r, $type$[] a, FUnOp f) {
138 int i = 0;
139 try {
140 for (; i < a.length; i++) {
141 Assert.assertEquals(r[i], f.apply(a[i]));
142 }
143 } catch (AssertionError e) {
144 Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]);
145 }
146 }
147
148 interface FUnArrayOp {
149 $type$[] apply($type$ a);
150 }
151
152 static void assertArraysEquals($type$[] r, $type$[] a, FUnArrayOp f) {
153 int i = 0;
154 try {
155 for (; i < a.length; i += SPECIES.length()) {
156 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
157 f.apply(a[i]));
158 }
159 } catch (AssertionError e) {
160 $type$[] ref = f.apply(a[i]);
161 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
162 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
163 + ", res: " + Arrays.toString(res)
164 + "), at index #" + i);
165 }
166 }
167
168 static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask, FUnOp f) {
169 int i = 0;
170 try {
171 for (; i < a.length; i++) {
172 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]);
173 }
174 } catch (AssertionError e) {
175 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i], "at index #" + i + ", input = " + a[i] + ", mask = " + mask[i % SPECIES.length()]);
176 }
177 }
178
179 interface FReductionOp {
180 $type$ apply($type$[] a, int idx);
181 }
182
183 interface FReductionAllOp {
184 $type$ apply($type$[] a);
185 }
186
187 static void assertReductionArraysEquals($type$[] r, $type$ rc, $type$[] a,
188 FReductionOp f, FReductionAllOp fa) {
189 #if[FP]
190 assertReductionArraysEquals(r, rc, a, f, fa, ($type$)0.0);
191 #else[FP]
192 int i = 0;
193 try {
194 Assert.assertEquals(rc, fa.apply(a));
195 for (; i < a.length; i += SPECIES.length()) {
196 Assert.assertEquals(r[i], f.apply(a, i));
197 }
198 } catch (AssertionError e) {
199 Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
200 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
201 }
202 #end[FP]
203 }
204 #if[FP]
205
206 static void assertReductionArraysEquals($type$[] r, $type$ rc, $type$[] a,
207 FReductionOp f, FReductionAllOp fa,
208 $type$ relativeErrorFactor) {
209 int i = 0;
210 try {
211 Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor);
212 for (; i < a.length; i += SPECIES.length()) {
213 Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor);
214 }
215 } catch (AssertionError e) {
216 Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor, "Final result is incorrect!");
217 Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor, "at index #" + i);
218 }
219 }
220 #end[FP]
221
222 interface FReductionMaskedOp {
223 $type$ apply($type$[] a, int idx, boolean[] mask);
224 }
225
226 interface FReductionAllMaskedOp {
227 $type$ apply($type$[] a, boolean[] mask);
228 }
229
230 static void assertReductionArraysEqualsMasked($type$[] r, $type$ rc, $type$[] a, boolean[] mask,
231 FReductionMaskedOp f, FReductionAllMaskedOp fa) {
232 #if[FP]
233 assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, ($type$)0.0);
234 #else[FP]
235 int i = 0;
236 try {
237 Assert.assertEquals(rc, fa.apply(a, mask));
238 for (; i < a.length; i += SPECIES.length()) {
239 Assert.assertEquals(r[i], f.apply(a, i, mask));
240 }
241 } catch (AssertionError e) {
242 Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
243 Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
244 }
245 #end[FP]
246 }
247 #if[FP]
248
249 static void assertReductionArraysEqualsMasked($type$[] r, $type$ rc, $type$[] a, boolean[] mask,
250 FReductionMaskedOp f, FReductionAllMaskedOp fa,
251 $type$ relativeError) {
252 int i = 0;
253 try {
254 Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
255 for (; i < a.length; i += SPECIES.length()) {
256 Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
257 relativeError));
258 }
259 } catch (AssertionError e) {
260 Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
261 Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
262 }
263 }
264 #end[FP]
265
266 #if[!Long]
267 interface FReductionOpLong {
268 long apply($type$[] a, int idx);
269 }
270
271 interface FReductionAllOpLong {
272 long apply($type$[] a);
273 }
274
275 static void assertReductionLongArraysEquals(long[] r, long rc, $type$[] a,
276 FReductionOpLong f, FReductionAllOpLong fa) {
277 int i = 0;
278 try {
279 Assert.assertEquals(rc, fa.apply(a));
280 for (; i < a.length; i += SPECIES.length()) {
281 Assert.assertEquals(r[i], f.apply(a, i));
282 }
283 } catch (AssertionError e) {
284 Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
285 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
286 }
287 }
288
289 interface FReductionMaskedOpLong {
290 long apply($type$[] a, int idx, boolean[] mask);
291 }
292
293 interface FReductionAllMaskedOpLong {
294 long apply($type$[] a, boolean[] mask);
295 }
296
297 static void assertReductionLongArraysEqualsMasked(long[] r, long rc, $type$[] a, boolean[] mask,
298 FReductionMaskedOpLong f, FReductionAllMaskedOpLong fa) {
299 int i = 0;
300 try {
301 Assert.assertEquals(rc, fa.apply(a, mask));
302 for (; i < a.length; i += SPECIES.length()) {
303 Assert.assertEquals(r[i], f.apply(a, i, mask));
304 }
305 } catch (AssertionError e) {
306 Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
307 Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
308 }
309 }
310 #end[!Long]
311
312 interface FBoolReductionOp {
313 boolean apply(boolean[] a, int idx);
314 }
315
316 static void assertReductionBoolArraysEquals(boolean[] r, boolean[] a, FBoolReductionOp f) {
317 int i = 0;
318 try {
319 for (; i < a.length; i += SPECIES.length()) {
320 Assert.assertEquals(r[i], f.apply(a, i));
321 }
322 } catch (AssertionError e) {
323 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
324 }
325 }
326
327 interface FMaskReductionOp {
328 int apply(boolean[] a, int idx);
329 }
330
331 static void assertMaskReductionArraysEquals(int[] r, boolean[] a, FMaskReductionOp f) {
332 int i = 0;
333 try {
334 for (; i < a.length; i += SPECIES.length()) {
335 Assert.assertEquals(r[i], f.apply(a, i));
336 }
337 } catch (AssertionError e) {
338 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
339 }
340 }
341
342 static void assertRearrangeArraysEquals($type$[] r, $type$[] a, int[] order, int vector_len) {
343 int i = 0, j = 0;
344 try {
345 for (; i < a.length; i += vector_len) {
346 for (j = 0; j < vector_len; j++) {
347 Assert.assertEquals(r[i+j], a[i+order[i+j]]);
348 }
349 }
350 } catch (AssertionError e) {
351 int idx = i + j;
352 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]);
353 }
354 }
355
356 static void assertcompressArraysEquals($type$[] r, $type$[] a, boolean[] m, int vector_len) {
357 int i = 0, j = 0, k = 0;
358 try {
359 for (; i < a.length; i += vector_len) {
360 k = 0;
361 for (j = 0; j < vector_len; j++) {
362 if (m[(i + j) % SPECIES.length()]) {
363 Assert.assertEquals(r[i + k], a[i + j]);
364 k++;
365 }
366 }
367 for (; k < vector_len; k++) {
368 Assert.assertEquals(r[i + k], ($type$)0);
369 }
370 }
371 } catch (AssertionError e) {
372 int idx = i + k;
373 if (m[(i + j) % SPECIES.length()]) {
374 Assert.assertEquals(r[idx], a[i + j], "at index #" + idx);
375 } else {
376 Assert.assertEquals(r[idx], ($type$)0, "at index #" + idx);
377 }
378 }
379 }
380
381 static void assertexpandArraysEquals($type$[] r, $type$[] a, boolean[] m, int vector_len) {
382 int i = 0, j = 0, k = 0;
383 try {
384 for (; i < a.length; i += vector_len) {
385 k = 0;
386 for (j = 0; j < vector_len; j++) {
387 if (m[(i + j) % SPECIES.length()]) {
388 Assert.assertEquals(r[i + j], a[i + k]);
389 k++;
390 } else {
391 Assert.assertEquals(r[i + j], ($type$)0);
392 }
393 }
394 }
395 } catch (AssertionError e) {
396 int idx = i + j;
397 if (m[idx % SPECIES.length()]) {
398 Assert.assertEquals(r[idx], a[i + k], "at index #" + idx);
399 } else {
400 Assert.assertEquals(r[idx], ($type$)0, "at index #" + idx);
401 }
402 }
403 }
404
405 static void assertSelectFromTwoVectorEquals($type$[] r, $type$[] order, $type$[] a, $type$[] b, int vector_len) {
406 int i = 0, j = 0;
407 boolean is_exceptional_idx = false;
408 int idx = 0, wrapped_index = 0, oidx = 0;
409 try {
410 for (; i < a.length; i += vector_len) {
411 for (j = 0; j < vector_len; j++) {
412 idx = i + j;
413 wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
414 is_exceptional_idx = wrapped_index >= vector_len;
415 oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
416 Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
417 }
418 }
419 } catch (AssertionError e) {
420 Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
421 }
422 }
423
424 static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, int vector_len) {
425 int i = 0, j = 0;
426 try {
427 for (; i < a.length; i += vector_len) {
428 for (j = 0; j < vector_len; j++) {
429 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
430 }
431 }
432 } catch (AssertionError e) {
433 int idx = i + j;
434 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]]);
435 }
436 }
437
438 static void assertRearrangeArraysEquals($type$[] r, $type$[] a, int[] order, boolean[] mask, int vector_len) {
439 int i = 0, j = 0;
440 try {
441 for (; i < a.length; i += vector_len) {
442 for (j = 0; j < vector_len; j++) {
443 if (mask[j % SPECIES.length()])
444 Assert.assertEquals(r[i+j], a[i+order[i+j]]);
445 else
446 Assert.assertEquals(r[i+j], ($type$)0);
447 }
448 }
449 } catch (AssertionError e) {
450 int idx = i + j;
451 if (mask[j % SPECIES.length()])
452 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
453 else
454 Assert.assertEquals(r[i+j], ($type$)0, "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
455 }
456 }
457
458 static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, boolean[] mask, int vector_len) {
459 int i = 0, j = 0;
460 try {
461 for (; i < a.length; i += vector_len) {
462 for (j = 0; j < vector_len; j++) {
463 if (mask[j % SPECIES.length()])
464 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
465 else
466 Assert.assertEquals(r[i+j], ($type$)0);
467 }
468 }
469 } catch (AssertionError e) {
470 int idx = i + j;
471 if (mask[j % SPECIES.length()])
472 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
473 else
474 Assert.assertEquals(r[i+j], ($type$)0, "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
475 }
476 }
477
478 static void assertBroadcastArraysEquals($type$[] r, $type$[] a) {
479 int i = 0;
480 for (; i < a.length; i += SPECIES.length()) {
481 int idx = i;
482 for (int j = idx; j < (idx + SPECIES.length()); j++)
483 a[j]=a[idx];
484 }
485
486 try {
487 for (i = 0; i < a.length; i++) {
488 Assert.assertEquals(r[i], a[i]);
489 }
490 } catch (AssertionError e) {
491 Assert.assertEquals(r[i], a[i], "at index #" + i + ", input = " + a[i]);
492 }
493 }
494
495 interface FBinOp {
496 $type$ apply($type$ a, $type$ b);
497 }
498
499 interface FBinMaskOp {
500 $type$ apply($type$ a, $type$ b, boolean m);
501
502 static FBinMaskOp lift(FBinOp f) {
503 return (a, b, m) -> m ? f.apply(a, b) : a;
504 }
505 }
506
507 static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, FBinOp f) {
508 int i = 0;
509 try {
510 for (; i < a.length; i++) {
511 //Left associative
512 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]));
513
514 //Right associative
515 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])));
516
517 //Results equal sanity check
518 Assert.assertEquals(rl[i], rr[i]);
519 }
520 } catch (AssertionError e) {
521 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
522 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
523 Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
524 }
525 }
526
527 static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FBinOp f) {
528 assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f));
529 }
530
531 static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FBinMaskOp f) {
532 int i = 0;
533 boolean mask_bit = false;
534 try {
535 for (; i < a.length; i++) {
536 mask_bit = mask[i % SPECIES.length()];
537 //Left associative
538 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit));
539
540 //Right associative
541 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit));
542
543 //Results equal sanity check
544 Assert.assertEquals(rl[i], rr[i]);
545 }
546 } catch (AssertionError e) {
547 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
548 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
549 Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
550 }
551 }
552
553 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) {
554 int i = 0;
555 try {
556 for (; i < a.length; i++) {
557 Assert.assertEquals(r[i], f.apply(a[i], b[i]));
558 }
559 } catch (AssertionError e) {
560 Assert.assertEquals(r[i], f.apply(a[i], b[i]), "(" + a[i] + ", " + b[i] + ") at index #" + i);
561 }
562 }
563
564 static void assertArraysEquals($type$[] r, $type$[] a, $type$ b, FBinOp f) {
565 int i = 0;
566 try {
567 for (; i < a.length; i++) {
568 Assert.assertEquals(r[i], f.apply(a[i], b));
569 }
570 } catch (AssertionError e) {
571 Assert.assertEquals(r[i], f.apply(a[i], b), "(" + a[i] + ", " + b + ") at index #" + i);
572 }
573 }
574
575 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) {
576 int i = 0;
577 try {
578 for (; i < a.length; i++) {
579 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
580 }
581 } catch (AssertionError e) {
582 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]),
583 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
584 }
585 }
586
587 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) {
588 int i = 0;
589 try {
590 for (; i < a.length; i++) {
591 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()])));
592 }
593 } catch (AssertionError e) {
594 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()])),
595 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
596 }
597 }
598
599 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) {
600 assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
601 }
602
603 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) {
604 int i = 0;
605 try {
606 for (; i < a.length; i++) {
607 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]));
608 }
609 } catch (AssertionError err) {
610 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", mask = " + mask[i % SPECIES.length()]);
611 }
612 }
613
614 static void assertArraysEquals($type$[] r, $type$[] a, $type$ b, boolean[] mask, FBinOp f) {
615 assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
616 }
617
618 static void assertArraysEquals($type$[] r, $type$[] a, $type$ b, boolean[] mask, FBinMaskOp f) {
619 int i = 0;
620 try {
621 for (; i < a.length; i++) {
622 Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]));
623 }
624 } catch (AssertionError err) {
625 Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b + ", mask = " + mask[i % SPECIES.length()]);
626 }
627 }
628
629 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) {
630 assertBroadcastArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
631 }
632
633 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) {
634 int i = 0;
635 try {
636 for (; i < a.length; i++) {
637 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
638 }
639 } catch (AssertionError err) {
640 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
641 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
642 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
643 mask[i % SPECIES.length()]);
644 }
645 }
646
647 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) {
648 assertBroadcastLongArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
649 }
650
651 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) {
652 int i = 0;
653 try {
654 for (; i < a.length; i++) {
655 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()]), mask[i % SPECIES.length()]));
656 }
657 } catch (AssertionError err) {
658 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()]),
659 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
660 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
661 mask[i % SPECIES.length()]);
662 }
663 }
664
665 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) {
666 int i = 0;
667 int j = 0;
668 try {
669 for (; j < a.length; j += SPECIES.length()) {
670 for (i = 0; i < SPECIES.length(); i++) {
671 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]));
672 }
673 }
674 } catch (AssertionError e) {
675 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]), "at index #" + i + ", " + j);
676 }
677 }
678
679 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) {
680 assertShiftArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
681 }
682
683 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) {
684 int i = 0;
685 int j = 0;
686 try {
687 for (; j < a.length; j += SPECIES.length()) {
688 for (i = 0; i < SPECIES.length(); i++) {
689 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]));
690 }
691 }
692 } catch (AssertionError err) {
693 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", input2 = " + b[j] + ", mask = " + mask[i]);
694 }
695 }
696
697 interface FBinConstOp {
698 $type$ apply($type$ a);
699 }
700
701 interface FBinConstMaskOp {
702 $type$ apply($type$ a, boolean m);
703
704 static FBinConstMaskOp lift(FBinConstOp f) {
705 return (a, m) -> m ? f.apply(a) : a;
706 }
707 }
708
709 static void assertShiftConstEquals($type$[] r, $type$[] a, FBinConstOp f) {
710 int i = 0;
711 int j = 0;
712 try {
713 for (; j < a.length; j += SPECIES.length()) {
714 for (i = 0; i < SPECIES.length(); i++) {
715 Assert.assertEquals(r[i+j], f.apply(a[i+j]));
716 }
717 }
718 } catch (AssertionError e) {
719 Assert.assertEquals(r[i+j], f.apply(a[i+j]), "at index #" + i + ", " + j);
720 }
721 }
722
723 static void assertShiftConstEquals($type$[] r, $type$[] a, boolean[] mask, FBinConstOp f) {
724 assertShiftConstEquals(r, a, mask, FBinConstMaskOp.lift(f));
725 }
726
727 static void assertShiftConstEquals($type$[] r, $type$[] a, boolean[] mask, FBinConstMaskOp f) {
728 int i = 0;
729 int j = 0;
730 try {
731 for (; j < a.length; j += SPECIES.length()) {
732 for (i = 0; i < SPECIES.length(); i++) {
733 Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]));
734 }
735 }
736 } catch (AssertionError err) {
737 Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", mask = " + mask[i]);
738 }
739 }
740
741 interface FTernOp {
742 $type$ apply($type$ a, $type$ b, $type$ c);
743 }
744
745 interface FTernMaskOp {
746 $type$ apply($type$ a, $type$ b, $type$ c, boolean m);
747
748 static FTernMaskOp lift(FTernOp f) {
749 return (a, b, c, m) -> m ? f.apply(a, b, c) : a;
750 }
751 }
752
753 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) {
754 int i = 0;
755 try {
756 for (; i < a.length; i++) {
757 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]));
758 }
759 } catch (AssertionError e) {
760 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
761 }
762 }
763
764 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FTernOp f) {
765 assertArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
766 }
767
768 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FTernMaskOp f) {
769 int i = 0;
770 try {
771 for (; i < a.length; i++) {
772 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]));
773 }
774 } catch (AssertionError err) {
775 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = "
776 + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
777 }
778 }
779
780 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) {
781 int i = 0;
782 try {
783 for (; i < a.length; i++) {
784 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]));
785 }
786 } catch (AssertionError e) {
787 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" +
788 i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " +
789 c[(i / SPECIES.length()) * SPECIES.length()]);
790 }
791 }
792
793 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) {
794 int i = 0;
795 try {
796 for (; i < a.length; i++) {
797 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]));
798 }
799 } catch (AssertionError e) {
800 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]), "at index #" +
801 i + ", input1 = " + a[i] + ", input2 = " +
802 b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " + c[i]);
803 }
804 }
805
806 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
807 FTernOp f) {
808 assertBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
809 }
810
811 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
812 FTernMaskOp f) {
813 int i = 0;
814 try {
815 for (; i < a.length; i++) {
816 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
817 mask[i % SPECIES.length()]));
818 }
819 } catch (AssertionError err) {
820 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
821 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
822 b[i] + ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
823 mask[i % SPECIES.length()]);
824 }
825 }
826
827 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
828 FTernOp f) {
829 assertAltBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
830 }
831
832 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
833 FTernMaskOp f) {
834 int i = 0;
835 try {
836 for (; i < a.length; i++) {
837 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
838 mask[i % SPECIES.length()]));
839 }
840 } catch (AssertionError err) {
841 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
842 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
843 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
844 ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
845 }
846 }
847
848 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) {
849 int i = 0;
850 try {
851 for (; i < a.length; i++) {
852 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
853 c[(i / SPECIES.length()) * SPECIES.length()]));
854 }
855 } catch (AssertionError e) {
856 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
857 c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" + i + ", input1 = " + a[i]
858 + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " +
859 c[(i / SPECIES.length()) * SPECIES.length()]);
860 }
861 }
862
863 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
864 FTernOp f) {
865 assertDoubleBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
866 }
867
868 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask,
869 FTernMaskOp f) {
870 int i = 0;
871 try {
872 for (; i < a.length; i++) {
873 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
874 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
875 }
876 } catch (AssertionError err) {
877 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
878 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]), "at index #"
879 + i + ", input1 = " + a[i] + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
880 ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
881 mask[i % SPECIES.length()]);
882 }
883 }
884
885
886 #if[FP]
887 static boolean isWithin1Ulp($type$ actual, $type$ expected) {
888 if ($Type$.isNaN(expected) && !$Type$.isNaN(actual)) {
889 return false;
890 } else if (!$Type$.isNaN(expected) && $Type$.isNaN(actual)) {
891 return false;
892 }
893
894 $type$ low = Math.nextDown(expected);
895 $type$ high = Math.nextUp(expected);
896
897 if ($Type$.compare(low, expected) > 0) {
898 return false;
899 }
900
901 if ($Type$.compare(high, expected) < 0) {
902 return false;
903 }
904
905 return true;
906 }
907
908 static void assertArraysEqualsWithinOneUlp($type$[] r, $type$[] a, FUnOp mathf, FUnOp strictmathf) {
909 int i = 0;
910 try {
911 // Check that result is within 1 ulp of strict math or equivalent to math implementation.
912 for (; i < a.length; i++) {
913 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0 ||
914 isWithin1Ulp(r[i], strictmathf.apply(a[i])));
915 }
916 } catch (AssertionError e) {
917 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0, "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i]));
918 Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i])), "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i]));
919 }
920 }
921
922 static void assertArraysEqualsWithinOneUlp($type$[] r, $type$[] a, $type$[] b, FBinOp mathf, FBinOp strictmathf) {
923 int i = 0;
924 try {
925 // Check that result is within 1 ulp of strict math or equivalent to math implementation.
926 for (; i < a.length; i++) {
927 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0 ||
928 isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])));
929 }
930 } catch (AssertionError e) {
931 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0, "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i], b[i]));
932 Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i], b[i]));
933 }
934 }
935
936 static void assertBroadcastArraysEqualsWithinOneUlp($type$[] r, $type$[] a, $type$[] b,
937 FBinOp mathf, FBinOp strictmathf) {
938 int i = 0;
939 try {
940 // Check that result is within 1 ulp of strict math or equivalent to math implementation.
941 for (; i < a.length; i++) {
942 Assert.assertTrue($Type$.compare(r[i],
943 mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0 ||
944 isWithin1Ulp(r[i],
945 strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])));
946 }
947 } catch (AssertionError e) {
948 Assert.assertTrue($Type$.compare(r[i],
949 mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0,
950 "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
951 b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
952 ", expected = " + mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
953 Assert.assertTrue(isWithin1Ulp(r[i],
954 strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])),
955 "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
956 b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
957 ", expected (within 1 ulp) = " + strictmathf.apply(a[i],
958 b[(i / SPECIES.length()) * SPECIES.length()]));
959 }
960 }
961 #end[FP]
962
963 interface FGatherScatterOp {
964 $type$[] apply($type$[] a, int ix, int[] b, int iy);
965 }
966
967 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, FGatherScatterOp f) {
968 int i = 0;
969 try {
970 for (; i < a.length; i += SPECIES.length()) {
971 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
972 f.apply(a, i, b, i));
973 }
974 } catch (AssertionError e) {
975 $type$[] ref = f.apply(a, i, b, i);
976 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
977 Assert.assertEquals(res, ref,
978 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
979 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
980 + ", b: "
981 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
982 + " at index #" + i);
983 }
984 }
985
986 interface FGatherMaskedOp {
987 $type$[] apply($type$[] a, int ix, boolean[] mask, int[] b, int iy);
988 }
989
990 interface FScatterMaskedOp {
991 $type$[] apply($type$[] r, $type$[] a, int ix, boolean[] mask, int[] b, int iy);
992 }
993
994 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, boolean[] mask, FGatherMaskedOp f) {
995 int i = 0;
996 try {
997 for (; i < a.length; i += SPECIES.length()) {
998 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
999 f.apply(a, i, mask, b, i));
1000 }
1001 } catch (AssertionError e) {
1002 $type$[] ref = f.apply(a, i, mask, b, i);
1003 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1004 Assert.assertEquals(res, ref,
1005 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
1006 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
1007 + ", b: "
1008 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
1009 + ", mask: "
1010 + Arrays.toString(mask)
1011 + " at index #" + i);
1012 }
1013 }
1014
1015 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, boolean[] mask, FScatterMaskedOp f) {
1016 int i = 0;
1017 try {
1018 for (; i < a.length; i += SPECIES.length()) {
1019 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1020 f.apply(r, a, i, mask, b, i));
1021 }
1022 } catch (AssertionError e) {
1023 $type$[] ref = f.apply(r, a, i, mask, b, i);
1024 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1025 Assert.assertEquals(res, ref,
1026 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
1027 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
1028 + ", b: "
1029 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
1030 + ", r: "
1031 + Arrays.toString(Arrays.copyOfRange(r, i, i+SPECIES.length()))
1032 + ", mask: "
1033 + Arrays.toString(mask)
1034 + " at index #" + i);
1035 }
1036 }
1037
1038 interface FLaneOp {
1039 $type$[] apply($type$[] a, int origin, int idx);
1040 }
1041
1042 static void assertArraysEquals($type$[] r, $type$[] a, int origin, FLaneOp f) {
1043 int i = 0;
1044 try {
1045 for (; i < a.length; i += SPECIES.length()) {
1046 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1047 f.apply(a, origin, i));
1048 }
1049 } catch (AssertionError e) {
1050 $type$[] ref = f.apply(a, origin, i);
1051 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1052 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1053 + ", res: " + Arrays.toString(res)
1054 + "), at index #" + i);
1055 }
1056 }
1057
1058 interface FLaneBop {
1059 $type$[] apply($type$[] a, $type$[] b, int origin, int idx);
1060 }
1061
1062 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, FLaneBop f) {
1063 int i = 0;
1064 try {
1065 for (; i < a.length; i += SPECIES.length()) {
1066 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1067 f.apply(a, b, origin, i));
1068 }
1069 } catch (AssertionError e) {
1070 $type$[] ref = f.apply(a, b, origin, i);
1071 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1072 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1073 + ", res: " + Arrays.toString(res)
1074 + "), at index #" + i
1075 + ", at origin #" + origin);
1076 }
1077 }
1078
1079 interface FLaneMaskedBop {
1080 $type$[] apply($type$[] a, $type$[] b, int origin, boolean[] mask, int idx);
1081 }
1082
1083 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, boolean[] mask, FLaneMaskedBop f) {
1084 int i = 0;
1085 try {
1086 for (; i < a.length; i += SPECIES.length()) {
1087 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1088 f.apply(a, b, origin, mask, i));
1089 }
1090 } catch (AssertionError e) {
1091 $type$[] ref = f.apply(a, b, origin, mask, i);
1092 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1093 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1094 + ", res: " + Arrays.toString(res)
1095 + "), at index #" + i
1096 + ", at origin #" + origin);
1097 }
1098 }
1099
1100 interface FLanePartBop {
1101 $type$[] apply($type$[] a, $type$[] b, int origin, int part, int idx);
1102 }
1103
1104 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, int part, FLanePartBop f) {
1105 int i = 0;
1106 try {
1107 for (; i < a.length; i += SPECIES.length()) {
1108 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1109 f.apply(a, b, origin, part, i));
1110 }
1111 } catch (AssertionError e) {
1112 $type$[] ref = f.apply(a, b, origin, part, i);
1113 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1114 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1115 + ", res: " + Arrays.toString(res)
1116 + "), at index #" + i
1117 + ", at origin #" + origin
1118 + ", with part #" + part);
1119 }
1120 }
1121
1122 interface FLanePartMaskedBop {
1123 $type$[] apply($type$[] a, $type$[] b, int origin, int part, boolean[] mask, int idx);
1124 }
1125
1126 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, int part, boolean[] mask, FLanePartMaskedBop f) {
1127 int i = 0;
1128 try {
1129 for (; i < a.length; i += SPECIES.length()) {
1130 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1131 f.apply(a, b, origin, part, mask, i));
1132 }
1133 } catch (AssertionError e) {
1134 $type$[] ref = f.apply(a, b, origin, part, mask, i);
1135 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1136 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1137 + ", res: " + Arrays.toString(res)
1138 + "), at index #" + i
1139 + ", at origin #" + origin
1140 + ", with part #" + part);
1141 }
1142 }
1143
1144 #if[!Int]
1145 #if[!byteOrShort]
1146 static int intCornerCaseValue(int i) {
1147 switch(i % 5) {
1148 case 0:
1149 return Integer.MAX_VALUE;
1150 case 1:
1151 return Integer.MIN_VALUE;
1152 case 2:
1153 return Integer.MIN_VALUE;
1154 case 3:
1155 return Integer.MAX_VALUE;
1156 default:
1157 return (int)0;
1158 }
1159 }
1160
1161 static final List<IntFunction<$type$[]>> INT_$TYPE$_GENERATORS = List.of(
1162 withToString("$type$[-i * 5]", (int s) -> {
1163 return fill(s * BUFFER_REPS,
1164 i -> ($type$)(-i * 5));
1165 }),
1166 withToString("$type$[i * 5]", (int s) -> {
1167 return fill(s * BUFFER_REPS,
1168 i -> ($type$)(i * 5));
1169 }),
1170 withToString("$type$[i + 1]", (int s) -> {
1171 return fill(s * BUFFER_REPS,
1172 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
1173 }),
1174 withToString("$type$[intCornerCaseValue(i)]", (int s) -> {
1175 return fill(s * BUFFER_REPS,
1176 i -> ($type$)intCornerCaseValue(i));
1177 })
1178 );
1179 #end[!byteOrShort]
1180 #end[!Int]
1181
1182 static void assertArraysEquals(int[] r, $type$[] a, int offs) {
1183 int i = 0;
1184 try {
1185 for (; i < r.length; i++) {
1186 Assert.assertEquals(r[i], (int)(a[i+offs]));
1187 }
1188 } catch (AssertionError e) {
1189 Assert.assertEquals(r[i], (int)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1190 }
1191 }
1192
1193 #if[!Long]
1194 #if[FP]
1195 static long longCornerCaseValue(int i) {
1196 switch(i % 5) {
1197 case 0:
1198 return Long.MAX_VALUE;
1199 case 1:
1200 return Long.MIN_VALUE;
1201 case 2:
1202 return Long.MIN_VALUE;
1203 case 3:
1204 return Long.MAX_VALUE;
1205 default:
1206 return (long)0;
1207 }
1208 }
1209
1210 static final List<IntFunction<$type$[]>> LONG_$TYPE$_GENERATORS = List.of(
1211 withToString("$type$[-i * 5]", (int s) -> {
1212 return fill(s * BUFFER_REPS,
1213 i -> ($type$)(-i * 5));
1214 }),
1215 withToString("$type$[i * 5]", (int s) -> {
1216 return fill(s * BUFFER_REPS,
1217 i -> ($type$)(i * 5));
1218 }),
1219 withToString("$type$[i + 1]", (int s) -> {
1220 return fill(s * BUFFER_REPS,
1221 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
1222 }),
1223 withToString("$type$[cornerCaseValue(i)]", (int s) -> {
1224 return fill(s * BUFFER_REPS,
1225 i -> ($type$)longCornerCaseValue(i));
1226 })
1227 );
1228 #end[FP]
1229 #end[!Long]
1230
1231 #if[byte]
1232 static void assertArraysEquals($type$[] r, $type$[] a, int offs) {
1233 int i = 0;
1234 try {
1235 for (; i < r.length; i++) {
1236 Assert.assertEquals(r[i], (long)(a[i+offs]));
1237 }
1238 } catch (AssertionError e) {
1239 Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1240 }
1241 }
1242 #end[byte]
1243
1244 static void assertArraysEquals(long[] r, $type$[] a, int offs) {
1245 int i = 0;
1246 try {
1247 for (; i < r.length; i++) {
1248 Assert.assertEquals(r[i], (long)(a[i+offs]));
1249 }
1250 } catch (AssertionError e) {
1251 Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1252 }
1253 }
1254 #if[!Double]
1255
1256 static void assertArraysEquals(double[] r, $type$[] a, int offs) {
1257 int i = 0;
1258 try {
1259 for (; i < r.length; i++) {
1260 Assert.assertEquals(r[i], (double)(a[i+offs]));
1261 }
1262 } catch (AssertionError e) {
1263 Assert.assertEquals(r[i], (double)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1264 }
1265 }
1266 #end[!Double]
1267
1268 static $bitstype$ bits($type$ e) {
1269 return {#if[FP]? $Type$.$type$To$Bitstype$Bits(e): e};
1270 }
1271
1272 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
1273 withToString("$type$[-i * 5]", (int s) -> {
1274 return fill(s * BUFFER_REPS,
1275 i -> ($type$)(-i * 5));
1276 }),
1277 withToString("$type$[i * 5]", (int s) -> {
1278 return fill(s * BUFFER_REPS,
1279 i -> ($type$)(i * 5));
1280 }),
1281 withToString("$type$[i + 1]", (int s) -> {
1282 return fill(s * BUFFER_REPS,
1283 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
1284 }),
1285 #if[FP]
1286 withToString("$type$[0.01 + (i / (i + 1))]", (int s) -> {
1287 return fill(s * BUFFER_REPS,
1288 i -> ($type$)0.01 + (($type$)i / (i + 1)));
1289 }),
1290 withToString("$type$[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
1291 return fill(s * BUFFER_REPS,
1292 i -> i % 17 == 0 ? cornerCaseValue(i) : ($type$)0.01 + (($type$)i / (i + 1)));
1293 }),
1294 #end[FP]
1295 withToString("$type$[cornerCaseValue(i)]", (int s) -> {
1296 return fill(s * BUFFER_REPS,
1297 i -> cornerCaseValue(i));
1298 })
1299 );
1300
1301 #if[!FP]
1302 static final List<IntFunction<$type$[]>> $TYPE$_SATURATING_GENERATORS = List.of(
1303 withToString("$type$[$Boxtype$.MIN_VALUE]", (int s) -> {
1304 return fill(s * BUFFER_REPS,
1305 i -> ($type$)($Boxtype$.MIN_VALUE));
1306 }),
1307 withToString("$type$[$Boxtype$.MAX_VALUE]", (int s) -> {
1308 return fill(s * BUFFER_REPS,
1309 i -> ($type$)($Boxtype$.MAX_VALUE));
1310 }),
1311 withToString("$type$[$Boxtype$.MAX_VALUE - 100]", (int s) -> {
1312 return fill(s * BUFFER_REPS,
1313 i -> ($type$)($Boxtype$.MAX_VALUE - 100));
1314 }),
1315 withToString("$type$[$Boxtype$.MIN_VALUE + 100]", (int s) -> {
1316 return fill(s * BUFFER_REPS,
1317 i -> ($type$)($Boxtype$.MIN_VALUE + 100));
1318 }),
1319 withToString("$type$[-i * 5]", (int s) -> {
1320 return fill(s * BUFFER_REPS,
1321 i -> ($type$)(-i * 5));
1322 }),
1323 withToString("$type$[i * 5]", (int s) -> {
1324 return fill(s * BUFFER_REPS,
1325 i -> ($type$)(i * 5));
1326 })
1327 );
1328
1329 static final List<IntFunction<$type$[]>> $TYPE$_SATURATING_GENERATORS_ASSOC = List.of(
1330 withToString("$type$[$Boxtype$.MAX_VALUE]", (int s) -> {
1331 return fill(s * BUFFER_REPS,
1332 i -> ($type$)($Boxtype$.MAX_VALUE));
1333 }),
1334 withToString("$type$[$Boxtype$.MAX_VALUE - 100]", (int s) -> {
1335 return fill(s * BUFFER_REPS,
1336 i -> ($type$)($Boxtype$.MAX_VALUE - 100));
1337 }),
1338 withToString("$type$[-1]", (int s) -> {
1339 return fill(s * BUFFER_REPS,
1340 i -> ($type$)(-1));
1341 })
1342 );
1343
1344 #end[!FP]
1345 // Create combinations of pairs
1346 // @@@ Might be sensitive to order e.g. div by 0
1347 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_PAIRS =
1348 Stream.of($TYPE$_GENERATORS.get(0)).
1349 flatMap(fa -> $TYPE$_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
1350 collect(Collectors.toList());
1351
1352 #if[!FP]
1353 static final List<List<IntFunction<$type$[]>>> $TYPE$_SATURATING_GENERATOR_PAIRS =
1354 Stream.of($TYPE$_GENERATORS.get(0)).
1355 flatMap(fa -> $TYPE$_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
1356 collect(Collectors.toList());
1357
1358 static final List<List<IntFunction<$type$[]>>> $TYPE$_SATURATING_GENERATOR_TRIPLETS =
1359 Stream.of($TYPE$_GENERATORS.get(1))
1360 .flatMap(fa -> $TYPE$_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb)))
1361 .flatMap(pair -> $TYPE$_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f)))
1362 .collect(Collectors.toList());
1363
1364 #end[!FP]
1365 @DataProvider
1366 public Object[][] boolUnaryOpProvider() {
1367 return BOOL_ARRAY_GENERATORS.stream().
1368 map(f -> new Object[]{f}).
1369 toArray(Object[][]::new);
1370 }
1371
1372 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_TRIPLES =
1373 $TYPE$_GENERATOR_PAIRS.stream().
1374 flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1375 collect(Collectors.toList());
1376
1377 static final List<IntFunction<$type$[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
1378 withToString("$type$[0..VECLEN*2)", (int s) -> {
1379 return fill(s * BUFFER_REPS,
1380 i -> ($type$)(RAND.nextInt()));
1381 })
1382 );
1383
1384 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_SELECT_FROM_TRIPLES =
1385 $TYPE$_GENERATOR_PAIRS.stream().
1386 flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1387 collect(Collectors.toList());
1388
1389 @DataProvider
1390 public Object[][] $type$BinaryOpProvider() {
1391 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
1392 toArray(Object[][]::new);
1393 }
1394
1395 #if[!FP]
1396 @DataProvider
1397 public Object[][] $type$SaturatingBinaryOpProvider() {
1398 return $TYPE$_SATURATING_GENERATOR_PAIRS.stream().map(List::toArray).
1399 toArray(Object[][]::new);
1400 }
1401
1402 @DataProvider
1403 public Object[][] $type$SaturatingBinaryOpAssocProvider() {
1404 return $TYPE$_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray).
1405 toArray(Object[][]::new);
1406 }
1407
1408 @DataProvider
1409 public Object[][] $type$SaturatingBinaryOpAssocMaskProvider() {
1410 return BOOLEAN_MASK_GENERATORS.stream().
1411 flatMap(fm -> $TYPE$_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> {
1412 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1413 })).
1414 toArray(Object[][]::new);
1415 }
1416
1417
1418 #end[!FP]
1419 @DataProvider
1420 public Object[][] $type$IndexedOpProvider() {
1421 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray).
1422 toArray(Object[][]::new);
1423 }
1424
1425 #if[!FP]
1426 @DataProvider
1427 public Object[][] $type$SaturatingBinaryOpMaskProvider() {
1428 return BOOLEAN_MASK_GENERATORS.stream().
1429 flatMap(fm -> $TYPE$_SATURATING_GENERATOR_PAIRS.stream().map(lfa -> {
1430 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1431 })).
1432 toArray(Object[][]::new);
1433 }
1434
1435 @DataProvider
1436 public Object[][] $type$SaturatingUnaryOpProvider() {
1437 return $TYPE$_SATURATING_GENERATORS.stream().
1438 map(f -> new Object[]{f}).
1439 toArray(Object[][]::new);
1440 }
1441
1442 @DataProvider
1443 public Object[][] $type$SaturatingUnaryOpMaskProvider() {
1444 return BOOLEAN_MASK_GENERATORS.stream().
1445 flatMap(fm -> $TYPE$_SATURATING_GENERATORS.stream().map(fa -> {
1446 return new Object[] {fa, fm};
1447 })).
1448 toArray(Object[][]::new);
1449 }
1450
1451 #end[!FP]
1452 @DataProvider
1453 public Object[][] $type$BinaryOpMaskProvider() {
1454 return BOOLEAN_MASK_GENERATORS.stream().
1455 flatMap(fm -> $TYPE$_GENERATOR_PAIRS.stream().map(lfa -> {
1456 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1457 })).
1458 toArray(Object[][]::new);
1459 }
1460
1461 @DataProvider
1462 public Object[][] $type$TernaryOpProvider() {
1463 return $TYPE$_GENERATOR_TRIPLES.stream().map(List::toArray).
1464 toArray(Object[][]::new);
1465 }
1466
1467 @DataProvider
1468 public Object[][] $type$SelectFromTwoVectorOpProvider() {
1469 return $TYPE$_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
1470 toArray(Object[][]::new);
1471 }
1472
1473 @DataProvider
1474 public Object[][] $type$TernaryOpMaskProvider() {
1475 return BOOLEAN_MASK_GENERATORS.stream().
1476 flatMap(fm -> $TYPE$_GENERATOR_TRIPLES.stream().map(lfa -> {
1477 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1478 })).
1479 toArray(Object[][]::new);
1480 }
1481
1482 @DataProvider
1483 public Object[][] $type$UnaryOpProvider() {
1484 return $TYPE$_GENERATORS.stream().
1485 map(f -> new Object[]{f}).
1486 toArray(Object[][]::new);
1487 }
1488
1489 @DataProvider
1490 public Object[][] $type$UnaryOpMaskProvider() {
1491 return BOOLEAN_MASK_GENERATORS.stream().
1492 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
1493 return new Object[] {fa, fm};
1494 })).
1495 toArray(Object[][]::new);
1496 }
1497 #if[!Int]
1498 #if[!byteOrShort]
1499
1500 @DataProvider
1501 public Object[][] $type$toIntUnaryOpProvider() {
1502 return INT_$TYPE$_GENERATORS.stream().
1503 map(f -> new Object[]{f}).
1504 toArray(Object[][]::new);
1505 }
1506 #end[!byteOrShort]
1507 #end[!Int]
1508 #if[FP]
1509
1510 @DataProvider
1511 public Object[][] $type$toLongUnaryOpProvider() {
1512 return LONG_$TYPE$_GENERATORS.stream().
1513 map(f -> new Object[]{f}).
1514 toArray(Object[][]::new);
1515 }
1516 #end[FP]
1517
1518 @DataProvider
1519 public Object[][] maskProvider() {
1520 return BOOLEAN_MASK_GENERATORS.stream().
1521 map(f -> new Object[]{f}).
1522 toArray(Object[][]::new);
1523 }
1524
1525 @DataProvider
1526 public Object[][] maskCompareOpProvider() {
1527 return BOOLEAN_MASK_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1528 toArray(Object[][]::new);
1529 }
1530
1531 @DataProvider
1532 public Object[][] shuffleProvider() {
1533 return INT_SHUFFLE_GENERATORS.stream().
1534 map(f -> new Object[]{f}).
1535 toArray(Object[][]::new);
1536 }
1537
1538 @DataProvider
1539 public Object[][] shuffleCompareOpProvider() {
1540 return INT_SHUFFLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1541 toArray(Object[][]::new);
1542 }
1543
1544 @DataProvider
1545 public Object[][] $type$UnaryOpShuffleProvider() {
1546 return INT_SHUFFLE_GENERATORS.stream().
1547 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1548 return new Object[] {fa, fs};
1549 })).
1550 toArray(Object[][]::new);
1551 }
1552
1553 @DataProvider
1554 public Object[][] $type$UnaryOpShuffleMaskProvider() {
1555 return BOOLEAN_MASK_GENERATORS.stream().
1556 flatMap(fm -> INT_SHUFFLE_GENERATORS.stream().
1557 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1558 return new Object[] {fa, fs, fm};
1559 }))).
1560 toArray(Object[][]::new);
1561 }
1562 #if[!Int]
1563
1564 static final List<BiFunction<Integer,Integer,$type$[]>> $TYPE$_SHUFFLE_GENERATORS = List.of(
1565 withToStringBi("shuffle[random]", (Integer l, Integer m) -> {
1566 $type$[] a = new $type$[l];
1567 #if[ByteMax]
1568 int upper = Math.min(Byte.MAX_VALUE + 1, m);
1569 #else[ByteMax]
1570 int upper = m;
1571 #end[ByteMax]
1572 for (int i = 0; i < 1; i++) {
1573 a[i] = ($type$)RAND.nextInt(upper);
1574 }
1575 return a;
1576 })
1577 );
1578
1579 @DataProvider
1580 public Object[][] $type$UnaryOpSelectFromProvider() {
1581 return $TYPE$_SHUFFLE_GENERATORS.stream().
1582 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1583 return new Object[] {fa, fs};
1584 })).
1585 toArray(Object[][]::new);
1586 }
1587
1588 @DataProvider
1589 public Object[][] $type$UnaryOpSelectFromMaskProvider() {
1590 return BOOLEAN_MASK_GENERATORS.stream().
1591 flatMap(fm -> $TYPE$_SHUFFLE_GENERATORS.stream().
1592 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1593 return new Object[] {fa, fs, fm};
1594 }))).
1595 toArray(Object[][]::new);
1596 }
1597 #end[!Int]
1598
1599 static final List<IntFunction<$type$[]>> $TYPE$_COMPARE_GENERATORS = List.of(
1600 withToString("$type$[i]", (int s) -> {
1601 return fill(s * BUFFER_REPS,
1602 i -> ($type$)i);
1603 }),
1604 withToString("$type$[i - length / 2]", (int s) -> {
1605 return fill(s * BUFFER_REPS,
1606 i -> ($type$)(i - (s * BUFFER_REPS / 2)));
1607 }),
1608 withToString("$type$[i + 1]", (int s) -> {
1609 return fill(s * BUFFER_REPS,
1610 i -> ($type$)(i + 1));
1611 }),
1612 withToString("$type$[i - 2]", (int s) -> {
1613 return fill(s * BUFFER_REPS,
1614 i -> ($type$)(i - 2));
1615 }),
1616 withToString("$type$[zigZag(i)]", (int s) -> {
1617 return fill(s * BUFFER_REPS,
1618 i -> i%3 == 0 ? ($type$)i : (i%3 == 1 ? ($type$)(i + 1) : ($type$)(i - 2)));
1619 }),
1620 withToString("$type$[cornerCaseValue(i)]", (int s) -> {
1621 return fill(s * BUFFER_REPS,
1622 i -> cornerCaseValue(i));
1623 })
1624 );
1625
1626 static final List<List<IntFunction<$type$[]>>> $TYPE$_TEST_GENERATOR_ARGS =
1627 $TYPE$_COMPARE_GENERATORS.stream().
1628 map(fa -> List.of(fa)).
1629 collect(Collectors.toList());
1630
1631 @DataProvider
1632 public Object[][] $type$TestOpProvider() {
1633 return $TYPE$_TEST_GENERATOR_ARGS.stream().map(List::toArray).
1634 toArray(Object[][]::new);
1635 }
1636
1637 @DataProvider
1638 public Object[][] $type$TestOpMaskProvider() {
1639 return BOOLEAN_MASK_GENERATORS.stream().
1640 flatMap(fm -> $TYPE$_TEST_GENERATOR_ARGS.stream().map(lfa -> {
1641 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1642 })).
1643 toArray(Object[][]::new);
1644 }
1645
1646 static final List<List<IntFunction<$type$[]>>> $TYPE$_COMPARE_GENERATOR_PAIRS =
1647 $TYPE$_COMPARE_GENERATORS.stream().
1648 flatMap(fa -> $TYPE$_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))).
1649 collect(Collectors.toList());
1650
1651 @DataProvider
1652 public Object[][] $type$CompareOpProvider() {
1653 return $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1654 toArray(Object[][]::new);
1655 }
1656
1657 @DataProvider
1658 public Object[][] $type$CompareOpMaskProvider() {
1659 return BOOLEAN_MASK_GENERATORS.stream().
1660 flatMap(fm -> $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(lfa -> {
1661 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1662 })).
1663 toArray(Object[][]::new);
1664 }
1665
1666 interface To$Type$F {
1667 $type$ apply(int i);
1668 }
1669
1670 static $type$[] fill(int s , To$Type$F f) {
1671 return fill(new $type$[s], f);
1672 }
1673
1674 static $type$[] fill($type$[] a, To$Type$F f) {
1675 for (int i = 0; i < a.length; i++) {
1676 a[i] = f.apply(i);
1677 }
1678 return a;
1679 }
1680
1681 static $type$ cornerCaseValue(int i) {
1682 #if[FP]
1683 return switch(i % 8) {
1684 case 0 -> $Wideboxtype$.MAX_VALUE;
1685 case 1 -> $Wideboxtype$.MIN_VALUE;
1686 case 2 -> $Wideboxtype$.NEGATIVE_INFINITY;
1687 case 3 -> $Wideboxtype$.POSITIVE_INFINITY;
1688 case 4 -> $Wideboxtype$.NaN;
1689 #if[Float]
1690 case 5 -> Float.intBitsToFloat(0x7F812345);
1691 #else[Float]
1692 case 5 -> Double.longBitsToDouble(0x7FF123456789ABCDL);
1693 #end[Float]
1694 case 6 -> ($type$)0.0;
1695 default -> ($type$)-0.0;
1696 };
1697 #else[FP]
1698 switch(i % 5) {
1699 case 0:
1700 return $Wideboxtype$.MAX_VALUE;
1701 case 1:
1702 return $Wideboxtype$.MIN_VALUE;
1703 case 2:
1704 return $Wideboxtype$.MIN_VALUE;
1705 case 3:
1706 return $Wideboxtype$.MAX_VALUE;
1707 default:
1708 return ($type$)0;
1709 }
1710 #end[FP]
1711 }
1712
1713 static final IntFunction<$type$[]> fr = (vl) -> {
1714 int length = BUFFER_REPS * vl;
1715 return new $type$[length];
1716 };
1717
1718 static final IntFunction<boolean[]> fmr = (vl) -> {
1719 int length = BUFFER_REPS * vl;
1720 return new boolean[length];
1721 };
1722 #if[!Long]
1723
1724 static final IntFunction<long[]> lfr = (vl) -> {
1725 int length = BUFFER_REPS * vl;
1726 return new long[length];
1727 };
1728 #end[!Long]
1729 #if[BITWISE]
1730
1731 static void replaceZero($type$[] a, $type$ v) {
1732 for (int i = 0; i < a.length; i++) {
1733 if (a[i] == 0) {
1734 a[i] = v;
1735 }
1736 }
1737 }
1738
1739 static void replaceZero($type$[] a, boolean[] mask, $type$ v) {
1740 for (int i = 0; i < a.length; i++) {
1741 if (mask[i % mask.length] && a[i] == 0) {
1742 a[i] = v;
1743 }
1744 }
1745 }
1746
1747 static $type$ ROL_scalar($type$ a, $type$ b) {
1748 #if[intOrLong]
1749 return $Wideboxtype$.rotateLeft(a, ((int)b));
1750 #else[intOrLong]
1751 #if[short]
1752 return (short)(((((short)a) & 0xFFFF) << (b & 15)) | ((((short)a) & 0xFFFF) >>> (16 - (b & 15))));
1753 #else[short]
1754 return (byte)(((((byte)a) & 0xFF) << (b & 7)) | ((((byte)a) & 0xFF) >>> (8 - (b & 7))));
1755 #end[short]
1756 #end[intOrLong]
1757 }
1758
1759 static $type$ ROR_scalar($type$ a, $type$ b) {
1760 #if[intOrLong]
1761 return $Wideboxtype$.rotateRight(a, ((int)b));
1762 #else[intOrLong]
1763 #if[short]
1764 return (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15))));
1765 #else[short]
1766 return (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7))));
1767 #end[short]
1768 #end[intOrLong]
1769 }
1770
1771 static $type$ TRAILING_ZEROS_COUNT_scalar($type$ a) {
1772 #if[intOrLong]
1773 return $Wideboxtype$.numberOfTrailingZeros(a);
1774 #else[intOrLong]
1775 #if[short]
1776 return (short) (a != 0 ? Integer.numberOfTrailingZeros(a) : 16);
1777 #else[short]
1778 return (byte) (a != 0 ? Integer.numberOfTrailingZeros(a) : 8);
1779 #end[short]
1780 #end[intOrLong]
1781 }
1782
1783 static $type$ LEADING_ZEROS_COUNT_scalar($type$ a) {
1784 #if[intOrLong]
1785 return $Wideboxtype$.numberOfLeadingZeros(a);
1786 #else[intOrLong]
1787 #if[short]
1788 return (short) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 16 : 0);
1789 #else[short]
1790 return (byte) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 24 : 0);
1791 #end[short]
1792 #end[intOrLong]
1793 }
1794
1795 static $type$ REVERSE_scalar($type$ a) {
1796 #if[intOrLong]
1797 return $Wideboxtype$.reverse(a);
1798 #else[intOrLong]
1799 #if[short]
1800 $type$ b = ROL_scalar(a, ($type$) 8);
1801 b = (short) (((b & 0x5555) << 1) | ((b & 0xAAAA) >>> 1));
1802 b = (short) (((b & 0x3333) << 2) | ((b & 0xCCCC) >>> 2));
1803 b = (short) (((b & 0x0F0F) << 4) | ((b & 0xF0F0) >>> 4));
1804 return b;
1805 #else[short]
1806 $type$ b = ($type$) ROL_scalar(a, ($type$) 4);
1807 b = (byte) (((b & 0x55) << 1) | ((b & 0xAA) >>> 1));
1808 b = (byte) (((b & 0x33) << 2) | ((b & 0xCC) >>> 2));
1809 return b;
1810 #end[short]
1811 #end[intOrLong]
1812 }
1813 #end[BITWISE]
1814
1815 static boolean eq($type$ a, $type$ b) {
1816 return a == b;
1817 }
1818
1819 static boolean neq($type$ a, $type$ b) {
1820 return a != b;
1821 }
1822
1823 static boolean lt($type$ a, $type$ b) {
1824 return a < b;
1825 }
1826
1827 static boolean le($type$ a, $type$ b) {
1828 return a <= b;
1829 }
1830
1831 static boolean gt($type$ a, $type$ b) {
1832 return a > b;
1833 }
1834
1835 static boolean ge($type$ a, $type$ b) {
1836 return a >= b;
1837 }
1838 #if[!FP]
1839
1840 static boolean ult($type$ a, $type$ b) {
1841 return $Boxtype$.compareUnsigned(a, b) < 0;
1842 }
1843
1844 static boolean ule($type$ a, $type$ b) {
1845 return $Boxtype$.compareUnsigned(a, b) <= 0;
1846 }
1847
1848 static boolean ugt($type$ a, $type$ b) {
1849 return $Boxtype$.compareUnsigned(a, b) > 0;
1850 }
1851
1852 static boolean uge($type$ a, $type$ b) {
1853 return $Boxtype$.compareUnsigned(a, b) >= 0;
1854 }
1855 #end[!FP]
1856
1857 static $type$ firstNonZero($type$ a, $type$ b) {
1858 return $Boxtype$.compare(a, ($type$) 0) != 0 ? a : b;
1859 }
1860
1861 @Test
1862 static void smokeTest1() {
1863 $abstractvectortype$ three = $abstractvectortype$.broadcast(SPECIES, (byte)-3);
1864 $abstractvectortype$ three2 = ($abstractvectortype$) SPECIES.broadcast(-3);
1865 assert(three.eq(three2).allTrue());
1866 $abstractvectortype$ three3 = three2.broadcast(1).broadcast(-3);
1867 assert(three.eq(three3).allTrue());
1868 int scale = 2;
1869 Class<?> ETYPE = $type$.class;
1870 if (ETYPE == double.class || ETYPE == long.class)
1871 scale = 1000000;
1872 else if (ETYPE == byte.class && SPECIES.length() >= 64)
1873 scale = 1;
1874 $abstractvectortype$ higher = three.addIndex(scale);
1875 VectorMask<$Boxtype$> m = three.compare(VectorOperators.LE, higher);
1876 assert(m.allTrue());
1877 m = higher.min(($type$)-1).test(VectorOperators.IS_NEGATIVE);
1878 assert(m.allTrue());
1879 #if[FP]
1880 m = higher.test(VectorOperators.IS_FINITE);
1881 assert(m.allTrue());
1882 #end[FP]
1883 $type$ max = higher.reduceLanes(VectorOperators.MAX);
1884 assert(max == -3 + scale * (SPECIES.length()-1));
1885 }
1886
1887 private static $type$[]
1888 bothToArray($abstractvectortype$ a, $abstractvectortype$ b) {
1889 $type$[] r = new $type$[a.length() + b.length()];
1890 a.intoArray(r, 0);
1891 b.intoArray(r, a.length());
1892 return r;
1893 }
1894
1895 @Test
1896 static void smokeTest2() {
1897 // Do some zipping and shuffling.
1898 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1);
1899 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES,0,1,false).toVector();
1900 Assert.assertEquals(io, io2);
1901 $abstractvectortype$ a = io.add(($type$)1); //[1,2]
1902 $abstractvectortype$ b = a.neg(); //[-1,-2]
1903 $type$[] abValues = bothToArray(a,b); //[1,2,-1,-2]
1904 VectorShuffle<$Boxtype$> zip0 = VectorShuffle.makeZip(SPECIES, 0);
1905 VectorShuffle<$Boxtype$> zip1 = VectorShuffle.makeZip(SPECIES, 1);
1906 $abstractvectortype$ zab0 = a.rearrange(zip0,b); //[1,-1]
1907 $abstractvectortype$ zab1 = a.rearrange(zip1,b); //[2,-2]
1908 $type$[] zabValues = bothToArray(zab0, zab1); //[1,-1,2,-2]
1909 // manually zip
1910 $type$[] manual = new $type$[zabValues.length];
1911 for (int i = 0; i < manual.length; i += 2) {
1912 manual[i+0] = abValues[i/2];
1913 manual[i+1] = abValues[a.length() + i/2];
1914 }
1915 Assert.assertEquals(Arrays.toString(zabValues), Arrays.toString(manual));
1916 VectorShuffle<$Boxtype$> unz0 = VectorShuffle.makeUnzip(SPECIES, 0);
1917 VectorShuffle<$Boxtype$> unz1 = VectorShuffle.makeUnzip(SPECIES, 1);
1918 $abstractvectortype$ uab0 = zab0.rearrange(unz0,zab1);
1919 $abstractvectortype$ uab1 = zab0.rearrange(unz1,zab1);
1920 $type$[] abValues1 = bothToArray(uab0, uab1);
1921 Assert.assertEquals(Arrays.toString(abValues), Arrays.toString(abValues1));
1922 }
1923
1924 static void iotaShuffle() {
1925 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1);
1926 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES, 0 , 1, false).toVector();
1927 Assert.assertEquals(io, io2);
1928 }
1929
1930 @Test
1931 // Test all shuffle related operations.
1932 static void shuffleTest() {
1933 // To test backend instructions, make sure that C2 is used.
1934 for (int loop = 0; loop < INVOC_COUNT * INVOC_COUNT; loop++) {
1935 iotaShuffle();
1936 }
1937 }
1938
1939 @Test
1940 void viewAsIntegeralLanesTest() {
1941 #if[FP]
1942 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes();
1943 VectorSpecies<?> asIntegralSpecies = asIntegral.species();
1944 Assert.assertNotEquals(asIntegralSpecies.elementType(), SPECIES.elementType());
1945 Assert.assertEquals(asIntegralSpecies.vectorShape(), SPECIES.vectorShape());
1946 Assert.assertEquals(asIntegralSpecies.length(), SPECIES.length());
1947 Assert.assertEquals(asIntegral.viewAsFloatingLanes().species(), SPECIES);
1948 #else[FP]
1949 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes();
1950 Assert.assertEquals(asIntegral.species(), SPECIES);
1951 #end[FP]
1952 }
1953 #if[FP]
1954
1955 @Test
1956 void viewAsFloatingLanesTest() {
1957 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes();
1958 Assert.assertEquals(asFloating.species(), SPECIES);
1959 }
1960 #else[FP]
1961 #if[byteOrShort]
1962
1963 @Test(expectedExceptions = UnsupportedOperationException.class)
1964 void viewAsFloatingLanesTest() {
1965 SPECIES.zero().viewAsFloatingLanes();
1966 }
1967 #else[byteOrShort]
1968
1969 @Test
1970 void viewAsFloatingLanesTest() {
1971 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes();
1972 VectorSpecies<?> asFloatingSpecies = asFloating.species();
1973 Assert.assertNotEquals(asFloatingSpecies.elementType(), SPECIES.elementType());
1974 Assert.assertEquals(asFloatingSpecies.vectorShape(), SPECIES.vectorShape());
1975 Assert.assertEquals(asFloatingSpecies.length(), SPECIES.length());
1976 Assert.assertEquals(asFloating.viewAsIntegralLanes().species(), SPECIES);
1977 }
1978 #end[byteOrShort]
1979 #end[FP]
1980 #if[BITWISE]
1981
1982 @Test
1983 // Test div by 0.
1984 static void bitwiseDivByZeroSmokeTest() {
1985 try {
1986 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1);
1987 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0);
1988 a.div(b);
1989 Assert.fail();
1990 } catch (ArithmeticException e) {
1991 }
1992
1993 try {
1994 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1);
1995 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0);
1996 VectorMask<$Boxtype$> m = a.lt(($type$) 1);
1997 a.div(b, m);
1998 Assert.fail();
1999 } catch (ArithmeticException e) {
2000 }
2001 }
2002 #end[BITWISE]