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