1 /* 2 * Copyright (c) 2018, 2022, 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 * @modules jdk.incubator.vector 27 * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation $vectorteststype$ 28 */ 29 30 #warn This file is preprocessed before being compiled 31 32 import jdk.incubator.vector.VectorShape; 33 import jdk.incubator.vector.VectorSpecies; 34 import jdk.incubator.vector.VectorShuffle; 35 import jdk.incubator.vector.VectorMask; 36 import jdk.incubator.vector.VectorOperators; 37 import jdk.incubator.vector.Vector; 38 39 #if[Byte] 40 import jdk.incubator.vector.ByteVector; 41 #end[Byte] 42 #if[Float] 43 import jdk.incubator.vector.FloatVector; 44 #end[Float] 45 #if[Int] 46 import jdk.incubator.vector.IntVector; 47 #end[Int] 48 #if[Double] 49 import jdk.incubator.vector.DoubleVector; 50 #end[Double] 51 #if[Short] 52 import jdk.incubator.vector.ShortVector; 53 #end[Short] 54 #if[Long] 55 import jdk.incubator.vector.LongVector; 56 #end[Long] 57 58 import org.testng.Assert; 59 import org.testng.annotations.DataProvider; 60 import org.testng.annotations.Test; 61 62 import java.lang.Integer; 63 import java.util.List; 64 import java.util.Arrays; 65 import java.util.function.BiFunction; 66 import java.util.function.IntFunction; 67 import java.util.Objects; 68 import java.util.stream.Collectors; 69 import java.util.stream.Stream; 70 71 @Test 72 public class $vectorteststype$ extends AbstractVectorTest { 73 74 #if[MaxBit] 75 static final VectorSpecies<$Wideboxtype$> SPECIES = 76 $Type$Vector.SPECIES_MAX; 77 #else[MaxBit] 78 static final VectorSpecies<$Wideboxtype$> SPECIES = 79 $Type$Vector.SPECIES_$bits$; 80 #end[MaxBit] 81 82 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 83 84 #if[MaxBit] 85 static VectorShape getMaxBit() { 86 return VectorShape.S_Max_BIT; 87 } 88 89 private static final int Max = 256; // juts so we can do N/$bits$ 90 #end[MaxBit] 91 92 private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2; 93 94 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$); 95 96 interface FUnOp { 97 $type$ apply($type$ a); 98 } 99 100 static void assertArraysEquals($type$[] r, $type$[] a, FUnOp f) { 101 int i = 0; 102 try { 103 for (; i < a.length; i++) { 104 Assert.assertEquals(r[i], f.apply(a[i])); 105 } 106 } catch (AssertionError e) { 107 Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]); 108 } 109 } 110 111 interface FUnArrayOp { 112 $type$[] apply($type$ a); 113 } 114 115 static void assertArraysEquals($type$[] r, $type$[] a, FUnArrayOp f) { 116 int i = 0; 117 try { 118 for (; i < a.length; i += SPECIES.length()) { 119 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 120 f.apply(a[i])); 121 } 122 } catch (AssertionError e) { 123 $type$[] ref = f.apply(a[i]); 124 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 125 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 126 + ", res: " + Arrays.toString(res) 127 + "), at index #" + i); 128 } 129 } 130 131 static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask, FUnOp f) { 132 int i = 0; 133 try { 134 for (; i < a.length; i++) { 135 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]); 136 } 137 } catch (AssertionError e) { 138 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()]); 139 } 140 } 141 142 interface FReductionOp { 143 $type$ apply($type$[] a, int idx); 144 } 145 146 interface FReductionAllOp { 147 $type$ apply($type$[] a); 148 } 149 150 static void assertReductionArraysEquals($type$[] r, $type$ rc, $type$[] a, 151 FReductionOp f, FReductionAllOp fa) { 152 int i = 0; 153 try { 154 Assert.assertEquals(rc, fa.apply(a)); 155 for (; i < a.length; i += SPECIES.length()) { 156 Assert.assertEquals(r[i], f.apply(a, i)); 157 } 158 } catch (AssertionError e) { 159 Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!"); 160 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i); 161 } 162 } 163 164 interface FReductionMaskedOp { 165 $type$ apply($type$[] a, int idx, boolean[] mask); 166 } 167 168 interface FReductionAllMaskedOp { 169 $type$ apply($type$[] a, boolean[] mask); 170 } 171 172 static void assertReductionArraysEqualsMasked($type$[] r, $type$ rc, $type$[] a, boolean[] mask, 173 FReductionMaskedOp f, FReductionAllMaskedOp fa) { 174 int i = 0; 175 try { 176 Assert.assertEquals(rc, fa.apply(a, mask)); 177 for (; i < a.length; i += SPECIES.length()) { 178 Assert.assertEquals(r[i], f.apply(a, i, mask)); 179 } 180 } catch (AssertionError e) { 181 Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!"); 182 Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i); 183 } 184 } 185 186 #if[!Long] 187 interface FReductionOpLong { 188 long apply($type$[] a, int idx); 189 } 190 191 interface FReductionAllOpLong { 192 long apply($type$[] a); 193 } 194 195 static void assertReductionLongArraysEquals(long[] r, long rc, $type$[] a, 196 FReductionOpLong f, FReductionAllOpLong fa) { 197 int i = 0; 198 try { 199 Assert.assertEquals(rc, fa.apply(a)); 200 for (; i < a.length; i += SPECIES.length()) { 201 Assert.assertEquals(r[i], f.apply(a, i)); 202 } 203 } catch (AssertionError e) { 204 Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!"); 205 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i); 206 } 207 } 208 209 interface FReductionMaskedOpLong { 210 long apply($type$[] a, int idx, boolean[] mask); 211 } 212 213 interface FReductionAllMaskedOpLong { 214 long apply($type$[] a, boolean[] mask); 215 } 216 217 static void assertReductionLongArraysEqualsMasked(long[] r, long rc, $type$[] a, boolean[] mask, 218 FReductionMaskedOpLong f, FReductionAllMaskedOpLong fa) { 219 int i = 0; 220 try { 221 Assert.assertEquals(rc, fa.apply(a, mask)); 222 for (; i < a.length; i += SPECIES.length()) { 223 Assert.assertEquals(r[i], f.apply(a, i, mask)); 224 } 225 } catch (AssertionError e) { 226 Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!"); 227 Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i); 228 } 229 } 230 #end[!Long] 231 232 interface FBoolReductionOp { 233 boolean apply(boolean[] a, int idx); 234 } 235 236 static void assertReductionBoolArraysEquals(boolean[] r, boolean[] a, FBoolReductionOp f) { 237 int i = 0; 238 try { 239 for (; i < a.length; i += SPECIES.length()) { 240 Assert.assertEquals(r[i], f.apply(a, i)); 241 } 242 } catch (AssertionError e) { 243 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i); 244 } 245 } 246 247 interface FMaskReductionOp { 248 int apply(boolean[] a, int idx); 249 } 250 251 static void assertMaskReductionArraysEquals(int[] r, boolean[] a, FMaskReductionOp f) { 252 int i = 0; 253 try { 254 for (; i < a.length; i += SPECIES.length()) { 255 Assert.assertEquals(r[i], f.apply(a, i)); 256 } 257 } catch (AssertionError e) { 258 Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i); 259 } 260 } 261 262 static void assertInsertArraysEquals($type$[] r, $type$[] a, $type$ element, int index, int start, int end) { 263 int i = start; 264 try { 265 for (; i < end; i += 1) { 266 if(i%SPECIES.length() == index) { 267 Assert.assertEquals(r[i], element); 268 } else { 269 Assert.assertEquals(r[i], a[i]); 270 } 271 } 272 } catch (AssertionError e) { 273 if (i%SPECIES.length() == index) { 274 Assert.assertEquals(r[i], element, "at index #" + i); 275 } else { 276 Assert.assertEquals(r[i], a[i], "at index #" + i); 277 } 278 } 279 } 280 281 static void assertRearrangeArraysEquals($type$[] r, $type$[] a, int[] order, int vector_len) { 282 int i = 0, j = 0; 283 try { 284 for (; i < a.length; i += vector_len) { 285 for (j = 0; j < vector_len; j++) { 286 Assert.assertEquals(r[i+j], a[i+order[i+j]]); 287 } 288 } 289 } catch (AssertionError e) { 290 int idx = i + j; 291 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]); 292 } 293 } 294 295 static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, int vector_len) { 296 int i = 0, j = 0; 297 try { 298 for (; i < a.length; i += vector_len) { 299 for (j = 0; j < vector_len; j++) { 300 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]); 301 } 302 } 303 } catch (AssertionError e) { 304 int idx = i + j; 305 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]]); 306 } 307 } 308 309 static void assertRearrangeArraysEquals($type$[] r, $type$[] a, int[] order, boolean[] mask, int vector_len) { 310 int i = 0, j = 0; 311 try { 312 for (; i < a.length; i += vector_len) { 313 for (j = 0; j < vector_len; j++) { 314 if (mask[j % SPECIES.length()]) 315 Assert.assertEquals(r[i+j], a[i+order[i+j]]); 316 else 317 Assert.assertEquals(r[i+j], ($type$)0); 318 } 319 } 320 } catch (AssertionError e) { 321 int idx = i + j; 322 if (mask[j % SPECIES.length()]) 323 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]); 324 else 325 Assert.assertEquals(r[i+j], ($type$)0, "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]); 326 } 327 } 328 329 static void assertSelectFromArraysEquals($type$[] r, $type$[] a, $type$[] order, boolean[] mask, int vector_len) { 330 int i = 0, j = 0; 331 try { 332 for (; i < a.length; i += vector_len) { 333 for (j = 0; j < vector_len; j++) { 334 if (mask[j % SPECIES.length()]) 335 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]); 336 else 337 Assert.assertEquals(r[i+j], ($type$)0); 338 } 339 } 340 } catch (AssertionError e) { 341 int idx = i + j; 342 if (mask[j % SPECIES.length()]) 343 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()]); 344 else 345 Assert.assertEquals(r[i+j], ($type$)0, "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]); 346 } 347 } 348 349 static void assertBroadcastArraysEquals($type$[] r, $type$[] a) { 350 int i = 0; 351 for (; i < a.length; i += SPECIES.length()) { 352 int idx = i; 353 for (int j = idx; j < (idx + SPECIES.length()); j++) 354 a[j]=a[idx]; 355 } 356 357 try { 358 for (i = 0; i < a.length; i++) { 359 Assert.assertEquals(r[i], a[i]); 360 } 361 } catch (AssertionError e) { 362 Assert.assertEquals(r[i], a[i], "at index #" + i + ", input = " + a[i]); 363 } 364 } 365 366 interface FBinOp { 367 $type$ apply($type$ a, $type$ b); 368 } 369 370 interface FBinMaskOp { 371 $type$ apply($type$ a, $type$ b, boolean m); 372 373 static FBinMaskOp lift(FBinOp f) { 374 return (a, b, m) -> m ? f.apply(a, b) : a; 375 } 376 } 377 378 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) { 379 int i = 0; 380 try { 381 for (; i < a.length; i++) { 382 Assert.assertEquals(r[i], f.apply(a[i], b[i])); 383 } 384 } catch (AssertionError e) { 385 Assert.assertEquals(r[i], f.apply(a[i], b[i]), "(" + a[i] + ", " + b[i] + ") at index #" + i); 386 } 387 } 388 389 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) { 390 int i = 0; 391 try { 392 for (; i < a.length; i++) { 393 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])); 394 } 395 } catch (AssertionError e) { 396 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]), 397 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i); 398 } 399 } 400 401 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) { 402 int i = 0; 403 try { 404 for (; i < a.length; i++) { 405 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()]))); 406 } 407 } catch (AssertionError e) { 408 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()])), 409 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i); 410 } 411 } 412 413 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) { 414 assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f)); 415 } 416 417 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) { 418 int i = 0; 419 try { 420 for (; i < a.length; i++) { 421 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()])); 422 } 423 } catch (AssertionError err) { 424 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()]); 425 } 426 } 427 428 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) { 429 assertBroadcastArraysEquals(r, a, b, mask, FBinMaskOp.lift(f)); 430 } 431 432 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) { 433 int i = 0; 434 try { 435 for (; i < a.length; i++) { 436 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()])); 437 } 438 } catch (AssertionError err) { 439 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], 440 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + 441 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " + 442 mask[i % SPECIES.length()]); 443 } 444 } 445 446 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) { 447 assertBroadcastLongArraysEquals(r, a, b, mask, FBinMaskOp.lift(f)); 448 } 449 450 static void assertBroadcastLongArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) { 451 int i = 0; 452 try { 453 for (; i < a.length; i++) { 454 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()]), mask[i % SPECIES.length()])); 455 } 456 } catch (AssertionError err) { 457 Assert.assertEquals(r[i], f.apply(a[i], ($type$)((long)b[(i / SPECIES.length()) * SPECIES.length()]), 458 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + 459 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " + 460 mask[i % SPECIES.length()]); 461 } 462 } 463 464 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) { 465 int i = 0; 466 int j = 0; 467 try { 468 for (; j < a.length; j += SPECIES.length()) { 469 for (i = 0; i < SPECIES.length(); i++) { 470 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j])); 471 } 472 } 473 } catch (AssertionError e) { 474 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]), "at index #" + i + ", " + j); 475 } 476 } 477 478 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinOp f) { 479 assertShiftArraysEquals(r, a, b, mask, FBinMaskOp.lift(f)); 480 } 481 482 static void assertShiftArraysEquals($type$[] r, $type$[] a, $type$[] b, boolean[] mask, FBinMaskOp f) { 483 int i = 0; 484 int j = 0; 485 try { 486 for (; j < a.length; j += SPECIES.length()) { 487 for (i = 0; i < SPECIES.length(); i++) { 488 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i])); 489 } 490 } 491 } catch (AssertionError err) { 492 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]); 493 } 494 } 495 496 interface FBinConstOp { 497 $type$ apply($type$ a); 498 } 499 500 interface FBinConstMaskOp { 501 $type$ apply($type$ a, boolean m); 502 503 static FBinConstMaskOp lift(FBinConstOp f) { 504 return (a, m) -> m ? f.apply(a) : a; 505 } 506 } 507 508 static void assertShiftConstEquals($type$[] r, $type$[] a, FBinConstOp f) { 509 int i = 0; 510 int j = 0; 511 try { 512 for (; j < a.length; j += SPECIES.length()) { 513 for (i = 0; i < SPECIES.length(); i++) { 514 Assert.assertEquals(r[i+j], f.apply(a[i+j])); 515 } 516 } 517 } catch (AssertionError e) { 518 Assert.assertEquals(r[i+j], f.apply(a[i+j]), "at index #" + i + ", " + j); 519 } 520 } 521 522 static void assertShiftConstEquals($type$[] r, $type$[] a, boolean[] mask, FBinConstOp f) { 523 assertShiftConstEquals(r, a, mask, FBinConstMaskOp.lift(f)); 524 } 525 526 static void assertShiftConstEquals($type$[] r, $type$[] a, boolean[] mask, FBinConstMaskOp f) { 527 int i = 0; 528 int j = 0; 529 try { 530 for (; j < a.length; j += SPECIES.length()) { 531 for (i = 0; i < SPECIES.length(); i++) { 532 Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i])); 533 } 534 } 535 } catch (AssertionError err) { 536 Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", mask = " + mask[i]); 537 } 538 } 539 540 interface FTernOp { 541 $type$ apply($type$ a, $type$ b, $type$ c); 542 } 543 544 interface FTernMaskOp { 545 $type$ apply($type$ a, $type$ b, $type$ c, boolean m); 546 547 static FTernMaskOp lift(FTernOp f) { 548 return (a, b, c, m) -> m ? f.apply(a, b, c) : a; 549 } 550 } 551 552 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) { 553 int i = 0; 554 try { 555 for (; i < a.length; i++) { 556 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i])); 557 } 558 } catch (AssertionError e) { 559 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); 560 } 561 } 562 563 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FTernOp f) { 564 assertArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f)); 565 } 566 567 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FTernMaskOp f) { 568 int i = 0; 569 try { 570 for (; i < a.length; i++) { 571 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()])); 572 } 573 } catch (AssertionError err) { 574 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " 575 + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]); 576 } 577 } 578 579 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) { 580 int i = 0; 581 try { 582 for (; i < a.length; i++) { 583 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()])); 584 } 585 } catch (AssertionError e) { 586 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" + 587 i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + 588 c[(i / SPECIES.length()) * SPECIES.length()]); 589 } 590 } 591 592 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) { 593 int i = 0; 594 try { 595 for (; i < a.length; i++) { 596 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i])); 597 } 598 } catch (AssertionError e) { 599 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]), "at index #" + 600 i + ", input1 = " + a[i] + ", input2 = " + 601 b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " + c[i]); 602 } 603 } 604 605 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 606 FTernOp f) { 607 assertBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f)); 608 } 609 610 static void assertBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 611 FTernMaskOp f) { 612 int i = 0; 613 try { 614 for (; i < a.length; i++) { 615 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()], 616 mask[i % SPECIES.length()])); 617 } 618 } catch (AssertionError err) { 619 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()], 620 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + 621 b[i] + ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " + 622 mask[i % SPECIES.length()]); 623 } 624 } 625 626 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 627 FTernOp f) { 628 assertAltBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f)); 629 } 630 631 static void assertAltBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 632 FTernMaskOp f) { 633 int i = 0; 634 try { 635 for (; i < a.length; i++) { 636 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i], 637 mask[i % SPECIES.length()])); 638 } 639 } catch (AssertionError err) { 640 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i], 641 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + 642 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + 643 ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]); 644 } 645 } 646 647 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, FTernOp f) { 648 int i = 0; 649 try { 650 for (; i < a.length; i++) { 651 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], 652 c[(i / SPECIES.length()) * SPECIES.length()])); 653 } 654 } catch (AssertionError e) { 655 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], 656 c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] 657 + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " + 658 c[(i / SPECIES.length()) * SPECIES.length()]); 659 } 660 } 661 662 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 663 FTernOp f) { 664 assertDoubleBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f)); 665 } 666 667 static void assertDoubleBroadcastArraysEquals($type$[] r, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, 668 FTernMaskOp f) { 669 int i = 0; 670 try { 671 for (; i < a.length; i++) { 672 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], 673 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()])); 674 } 675 } catch (AssertionError err) { 676 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], 677 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]), "at index #" 678 + i + ", input1 = " + a[i] + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + 679 ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " + 680 mask[i % SPECIES.length()]); 681 } 682 } 683 684 685 #if[FP] 686 static boolean isWithin1Ulp($type$ actual, $type$ expected) { 687 if ($Type$.isNaN(expected) && !$Type$.isNaN(actual)) { 688 return false; 689 } else if (!$Type$.isNaN(expected) && $Type$.isNaN(actual)) { 690 return false; 691 } 692 693 $type$ low = Math.nextDown(expected); 694 $type$ high = Math.nextUp(expected); 695 696 if ($Type$.compare(low, expected) > 0) { 697 return false; 698 } 699 700 if ($Type$.compare(high, expected) < 0) { 701 return false; 702 } 703 704 return true; 705 } 706 707 static void assertArraysEqualsWithinOneUlp($type$[] r, $type$[] a, FUnOp mathf, FUnOp strictmathf) { 708 int i = 0; 709 try { 710 // Check that result is within 1 ulp of strict math or equivalent to math implementation. 711 for (; i < a.length; i++) { 712 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0 || 713 isWithin1Ulp(r[i], strictmathf.apply(a[i]))); 714 } 715 } catch (AssertionError e) { 716 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])); 717 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])); 718 } 719 } 720 721 static void assertArraysEqualsWithinOneUlp($type$[] r, $type$[] a, $type$[] b, FBinOp mathf, FBinOp strictmathf) { 722 int i = 0; 723 try { 724 // Check that result is within 1 ulp of strict math or equivalent to math implementation. 725 for (; i < a.length; i++) { 726 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0 || 727 isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i]))); 728 } 729 } catch (AssertionError e) { 730 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])); 731 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])); 732 } 733 } 734 735 static void assertBroadcastArraysEqualsWithinOneUlp($type$[] r, $type$[] a, $type$[] b, 736 FBinOp mathf, FBinOp strictmathf) { 737 int i = 0; 738 try { 739 // Check that result is within 1 ulp of strict math or equivalent to math implementation. 740 for (; i < a.length; i++) { 741 Assert.assertTrue($Type$.compare(r[i], 742 mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0 || 743 isWithin1Ulp(r[i], 744 strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]))); 745 } 746 } catch (AssertionError e) { 747 Assert.assertTrue($Type$.compare(r[i], 748 mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0, 749 "at index #" + i + ", input1 = " + a[i] + ", input2 = " + 750 b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] + 751 ", expected = " + mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])); 752 Assert.assertTrue(isWithin1Ulp(r[i], 753 strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])), 754 "at index #" + i + ", input1 = " + a[i] + ", input2 = " + 755 b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] + 756 ", expected (within 1 ulp) = " + strictmathf.apply(a[i], 757 b[(i / SPECIES.length()) * SPECIES.length()])); 758 } 759 } 760 #end[FP] 761 762 interface FBinArrayOp { 763 $type$ apply($type$[] a, int b); 764 } 765 766 static void assertArraysEquals($type$[] r, $type$[] a, FBinArrayOp f) { 767 int i = 0; 768 try { 769 for (; i < a.length; i++) { 770 Assert.assertEquals(r[i], f.apply(a, i)); 771 } 772 } catch (AssertionError e) { 773 Assert.assertEquals(r[i], f.apply(a,i), "at index #" + i); 774 } 775 } 776 777 interface FGatherScatterOp { 778 $type$[] apply($type$[] a, int ix, int[] b, int iy); 779 } 780 781 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, FGatherScatterOp f) { 782 int i = 0; 783 try { 784 for (; i < a.length; i += SPECIES.length()) { 785 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 786 f.apply(a, i, b, i)); 787 } 788 } catch (AssertionError e) { 789 $type$[] ref = f.apply(a, i, b, i); 790 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 791 Assert.assertEquals(res, ref, 792 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 793 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 794 + ", b: " 795 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 796 + " at index #" + i); 797 } 798 } 799 800 interface FGatherMaskedOp { 801 $type$[] apply($type$[] a, int ix, boolean[] mask, int[] b, int iy); 802 } 803 804 interface FScatterMaskedOp { 805 $type$[] apply($type$[] r, $type$[] a, int ix, boolean[] mask, int[] b, int iy); 806 } 807 808 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, boolean[] mask, FGatherMaskedOp f) { 809 int i = 0; 810 try { 811 for (; i < a.length; i += SPECIES.length()) { 812 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 813 f.apply(a, i, mask, b, i)); 814 } 815 } catch (AssertionError e) { 816 $type$[] ref = f.apply(a, i, mask, b, i); 817 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 818 Assert.assertEquals(res, ref, 819 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 820 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 821 + ", b: " 822 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 823 + ", mask: " 824 + Arrays.toString(mask) 825 + " at index #" + i); 826 } 827 } 828 829 static void assertArraysEquals($type$[] r, $type$[] a, int[] b, boolean[] mask, FScatterMaskedOp f) { 830 int i = 0; 831 try { 832 for (; i < a.length; i += SPECIES.length()) { 833 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 834 f.apply(r, a, i, mask, b, i)); 835 } 836 } catch (AssertionError e) { 837 $type$[] ref = f.apply(r, a, i, mask, b, i); 838 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 839 Assert.assertEquals(res, ref, 840 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 841 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 842 + ", b: " 843 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 844 + ", r: " 845 + Arrays.toString(Arrays.copyOfRange(r, i, i+SPECIES.length())) 846 + ", mask: " 847 + Arrays.toString(mask) 848 + " at index #" + i); 849 } 850 } 851 852 interface FLaneOp { 853 $type$[] apply($type$[] a, int origin, int idx); 854 } 855 856 static void assertArraysEquals($type$[] r, $type$[] a, int origin, FLaneOp f) { 857 int i = 0; 858 try { 859 for (; i < a.length; i += SPECIES.length()) { 860 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 861 f.apply(a, origin, i)); 862 } 863 } catch (AssertionError e) { 864 $type$[] ref = f.apply(a, origin, i); 865 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 866 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 867 + ", res: " + Arrays.toString(res) 868 + "), at index #" + i); 869 } 870 } 871 872 interface FLaneBop { 873 $type$[] apply($type$[] a, $type$[] b, int origin, int idx); 874 } 875 876 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, FLaneBop f) { 877 int i = 0; 878 try { 879 for (; i < a.length; i += SPECIES.length()) { 880 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 881 f.apply(a, b, origin, i)); 882 } 883 } catch (AssertionError e) { 884 $type$[] ref = f.apply(a, b, origin, i); 885 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 886 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 887 + ", res: " + Arrays.toString(res) 888 + "), at index #" + i 889 + ", at origin #" + origin); 890 } 891 } 892 893 interface FLaneMaskedBop { 894 $type$[] apply($type$[] a, $type$[] b, int origin, boolean[] mask, int idx); 895 } 896 897 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, boolean[] mask, FLaneMaskedBop f) { 898 int i = 0; 899 try { 900 for (; i < a.length; i += SPECIES.length()) { 901 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 902 f.apply(a, b, origin, mask, i)); 903 } 904 } catch (AssertionError e) { 905 $type$[] ref = f.apply(a, b, origin, mask, i); 906 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 907 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 908 + ", res: " + Arrays.toString(res) 909 + "), at index #" + i 910 + ", at origin #" + origin); 911 } 912 } 913 914 interface FLanePartBop { 915 $type$[] apply($type$[] a, $type$[] b, int origin, int part, int idx); 916 } 917 918 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, int part, FLanePartBop f) { 919 int i = 0; 920 try { 921 for (; i < a.length; i += SPECIES.length()) { 922 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 923 f.apply(a, b, origin, part, i)); 924 } 925 } catch (AssertionError e) { 926 $type$[] ref = f.apply(a, b, origin, part, i); 927 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 928 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 929 + ", res: " + Arrays.toString(res) 930 + "), at index #" + i 931 + ", at origin #" + origin 932 + ", with part #" + part); 933 } 934 } 935 936 interface FLanePartMaskedBop { 937 $type$[] apply($type$[] a, $type$[] b, int origin, int part, boolean[] mask, int idx); 938 } 939 940 static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, int origin, int part, boolean[] mask, FLanePartMaskedBop f) { 941 int i = 0; 942 try { 943 for (; i < a.length; i += SPECIES.length()) { 944 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 945 f.apply(a, b, origin, part, mask, i)); 946 } 947 } catch (AssertionError e) { 948 $type$[] ref = f.apply(a, b, origin, part, mask, i); 949 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 950 Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref) 951 + ", res: " + Arrays.toString(res) 952 + "), at index #" + i 953 + ", at origin #" + origin 954 + ", with part #" + part); 955 } 956 } 957 958 #if[!Int] 959 #if[!byteOrShort] 960 static int intCornerCaseValue(int i) { 961 switch(i % 5) { 962 case 0: 963 return Integer.MAX_VALUE; 964 case 1: 965 return Integer.MIN_VALUE; 966 case 2: 967 return Integer.MIN_VALUE; 968 case 3: 969 return Integer.MAX_VALUE; 970 default: 971 return (int)0; 972 } 973 } 974 975 static final List<IntFunction<$type$[]>> INT_$TYPE$_GENERATORS = List.of( 976 withToString("$type$[-i * 5]", (int s) -> { 977 return fill(s * BUFFER_REPS, 978 i -> ($type$)(-i * 5)); 979 }), 980 withToString("$type$[i * 5]", (int s) -> { 981 return fill(s * BUFFER_REPS, 982 i -> ($type$)(i * 5)); 983 }), 984 withToString("$type$[i + 1]", (int s) -> { 985 return fill(s * BUFFER_REPS, 986 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1))); 987 }), 988 withToString("$type$[intCornerCaseValue(i)]", (int s) -> { 989 return fill(s * BUFFER_REPS, 990 i -> ($type$)intCornerCaseValue(i)); 991 }) 992 ); 993 #end[!byteOrShort] 994 #end[!Int] 995 996 static void assertArraysEquals(int[] r, $type$[] a, int offs) { 997 int i = 0; 998 try { 999 for (; i < r.length; i++) { 1000 Assert.assertEquals(r[i], (int)(a[i+offs])); 1001 } 1002 } catch (AssertionError e) { 1003 Assert.assertEquals(r[i], (int)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]); 1004 } 1005 } 1006 1007 #if[!Long] 1008 #if[FP] 1009 static long longCornerCaseValue(int i) { 1010 switch(i % 5) { 1011 case 0: 1012 return Long.MAX_VALUE; 1013 case 1: 1014 return Long.MIN_VALUE; 1015 case 2: 1016 return Long.MIN_VALUE; 1017 case 3: 1018 return Long.MAX_VALUE; 1019 default: 1020 return (long)0; 1021 } 1022 } 1023 1024 static final List<IntFunction<$type$[]>> LONG_$TYPE$_GENERATORS = List.of( 1025 withToString("$type$[-i * 5]", (int s) -> { 1026 return fill(s * BUFFER_REPS, 1027 i -> ($type$)(-i * 5)); 1028 }), 1029 withToString("$type$[i * 5]", (int s) -> { 1030 return fill(s * BUFFER_REPS, 1031 i -> ($type$)(i * 5)); 1032 }), 1033 withToString("$type$[i + 1]", (int s) -> { 1034 return fill(s * BUFFER_REPS, 1035 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1))); 1036 }), 1037 withToString("$type$[cornerCaseValue(i)]", (int s) -> { 1038 return fill(s * BUFFER_REPS, 1039 i -> ($type$)longCornerCaseValue(i)); 1040 }) 1041 ); 1042 #end[FP] 1043 #end[!Long] 1044 1045 #if[byte] 1046 static void assertArraysEquals($type$[] r, $type$[] a, int offs) { 1047 int i = 0; 1048 try { 1049 for (; i < r.length; i++) { 1050 Assert.assertEquals(r[i], (long)(a[i+offs])); 1051 } 1052 } catch (AssertionError e) { 1053 Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]); 1054 } 1055 } 1056 #end[byte] 1057 1058 static void assertArraysEquals(long[] r, $type$[] a, int offs) { 1059 int i = 0; 1060 try { 1061 for (; i < r.length; i++) { 1062 Assert.assertEquals(r[i], (long)(a[i+offs])); 1063 } 1064 } catch (AssertionError e) { 1065 Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]); 1066 } 1067 } 1068 1069 #if[!Double] 1070 static void assertArraysEquals(double[] r, $type$[] a, int offs) { 1071 int i = 0; 1072 try { 1073 for (; i < r.length; i++) { 1074 Assert.assertEquals(r[i], (double)(a[i+offs])); 1075 } 1076 } catch (AssertionError e) { 1077 Assert.assertEquals(r[i], (double)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]); 1078 } 1079 } 1080 #end[!Double] 1081 1082 1083 static $bitstype$ bits($type$ e) { 1084 return {#if[FP]? $Type$.$type$To$Bitstype$Bits(e): e}; 1085 } 1086 1087 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of( 1088 withToString("$type$[-i * 5]", (int s) -> { 1089 return fill(s * BUFFER_REPS, 1090 i -> ($type$)(-i * 5)); 1091 }), 1092 withToString("$type$[i * 5]", (int s) -> { 1093 return fill(s * BUFFER_REPS, 1094 i -> ($type$)(i * 5)); 1095 }), 1096 withToString("$type$[i + 1]", (int s) -> { 1097 return fill(s * BUFFER_REPS, 1098 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1))); 1099 }), 1100 withToString("$type$[cornerCaseValue(i)]", (int s) -> { 1101 return fill(s * BUFFER_REPS, 1102 i -> cornerCaseValue(i)); 1103 }) 1104 ); 1105 1106 // Create combinations of pairs 1107 // @@@ Might be sensitive to order e.g. div by 0 1108 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_PAIRS = 1109 Stream.of($TYPE$_GENERATORS.get(0)). 1110 flatMap(fa -> $TYPE$_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). 1111 collect(Collectors.toList()); 1112 1113 @DataProvider 1114 public Object[][] boolUnaryOpProvider() { 1115 return BOOL_ARRAY_GENERATORS.stream(). 1116 map(f -> new Object[]{f}). 1117 toArray(Object[][]::new); 1118 } 1119 1120 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_TRIPLES = 1121 $TYPE$_GENERATOR_PAIRS.stream(). 1122 flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). 1123 collect(Collectors.toList()); 1124 1125 @DataProvider 1126 public Object[][] $type$BinaryOpProvider() { 1127 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray). 1128 toArray(Object[][]::new); 1129 } 1130 1131 @DataProvider 1132 public Object[][] $type$IndexedOpProvider() { 1133 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray). 1134 toArray(Object[][]::new); 1135 } 1136 1137 @DataProvider 1138 public Object[][] $type$BinaryOpMaskProvider() { 1139 return BOOLEAN_MASK_GENERATORS.stream(). 1140 flatMap(fm -> $TYPE$_GENERATOR_PAIRS.stream().map(lfa -> { 1141 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 1142 })). 1143 toArray(Object[][]::new); 1144 } 1145 1146 @DataProvider 1147 public Object[][] $type$TernaryOpProvider() { 1148 return $TYPE$_GENERATOR_TRIPLES.stream().map(List::toArray). 1149 toArray(Object[][]::new); 1150 } 1151 1152 @DataProvider 1153 public Object[][] $type$TernaryOpMaskProvider() { 1154 return BOOLEAN_MASK_GENERATORS.stream(). 1155 flatMap(fm -> $TYPE$_GENERATOR_TRIPLES.stream().map(lfa -> { 1156 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 1157 })). 1158 toArray(Object[][]::new); 1159 } 1160 1161 @DataProvider 1162 public Object[][] $type$UnaryOpProvider() { 1163 return $TYPE$_GENERATORS.stream(). 1164 map(f -> new Object[]{f}). 1165 toArray(Object[][]::new); 1166 } 1167 1168 @DataProvider 1169 public Object[][] $type$UnaryOpMaskProvider() { 1170 return BOOLEAN_MASK_GENERATORS.stream(). 1171 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> { 1172 return new Object[] {fa, fm}; 1173 })). 1174 toArray(Object[][]::new); 1175 } 1176 1177 #if[!Int] 1178 #if[!byteOrShort] 1179 @DataProvider 1180 public Object[][] $type$toIntUnaryOpProvider() { 1181 return INT_$TYPE$_GENERATORS.stream(). 1182 map(f -> new Object[]{f}). 1183 toArray(Object[][]::new); 1184 } 1185 #end[!byteOrShort] 1186 #end[!Int] 1187 1188 #if[FP] 1189 @DataProvider 1190 public Object[][] $type$toLongUnaryOpProvider() { 1191 return LONG_$TYPE$_GENERATORS.stream(). 1192 map(f -> new Object[]{f}). 1193 toArray(Object[][]::new); 1194 } 1195 #end[FP] 1196 1197 @DataProvider 1198 public Object[][] maskProvider() { 1199 return BOOLEAN_MASK_GENERATORS.stream(). 1200 map(f -> new Object[]{f}). 1201 toArray(Object[][]::new); 1202 } 1203 1204 @DataProvider 1205 public Object[][] maskCompareOpProvider() { 1206 return BOOLEAN_MASK_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray). 1207 toArray(Object[][]::new); 1208 } 1209 1210 @DataProvider 1211 public Object[][] shuffleProvider() { 1212 return INT_SHUFFLE_GENERATORS.stream(). 1213 map(f -> new Object[]{f}). 1214 toArray(Object[][]::new); 1215 } 1216 1217 @DataProvider 1218 public Object[][] shuffleCompareOpProvider() { 1219 return INT_SHUFFLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray). 1220 toArray(Object[][]::new); 1221 } 1222 1223 @DataProvider 1224 public Object[][] $type$UnaryOpShuffleProvider() { 1225 return INT_SHUFFLE_GENERATORS.stream(). 1226 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 1227 return new Object[] {fa, fs}; 1228 })). 1229 toArray(Object[][]::new); 1230 } 1231 1232 @DataProvider 1233 public Object[][] $type$UnaryOpShuffleMaskProvider() { 1234 return BOOLEAN_MASK_GENERATORS.stream(). 1235 flatMap(fm -> INT_SHUFFLE_GENERATORS.stream(). 1236 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 1237 return new Object[] {fa, fs, fm}; 1238 }))). 1239 toArray(Object[][]::new); 1240 } 1241 1242 #if[!Int] 1243 static final List<BiFunction<Integer,Integer,$type$[]>> $TYPE$_SHUFFLE_GENERATORS = List.of( 1244 withToStringBi("shuffle[random]", (Integer l, Integer m) -> { 1245 $type$[] a = new $type$[l]; 1246 #if[ByteMax] 1247 int upper = Math.min(Byte.MAX_VALUE + 1, m); 1248 #else[ByteMax] 1249 int upper = m; 1250 #end[ByteMax] 1251 for (int i = 0; i < 1; i++) { 1252 a[i] = ($type$)RAND.nextInt(upper); 1253 } 1254 return a; 1255 }) 1256 ); 1257 1258 @DataProvider 1259 public Object[][] $type$UnaryOpSelectFromProvider() { 1260 return $TYPE$_SHUFFLE_GENERATORS.stream(). 1261 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 1262 return new Object[] {fa, fs}; 1263 })). 1264 toArray(Object[][]::new); 1265 } 1266 1267 @DataProvider 1268 public Object[][] $type$UnaryOpSelectFromMaskProvider() { 1269 return BOOLEAN_MASK_GENERATORS.stream(). 1270 flatMap(fm -> $TYPE$_SHUFFLE_GENERATORS.stream(). 1271 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 1272 return new Object[] {fa, fs, fm}; 1273 }))). 1274 toArray(Object[][]::new); 1275 } 1276 1277 #end[!Int] 1278 1279 static final List<IntFunction<$type$[]>> $TYPE$_COMPARE_GENERATORS = List.of( 1280 withToString("$type$[i]", (int s) -> { 1281 return fill(s * BUFFER_REPS, 1282 i -> ($type$)i); 1283 }), 1284 withToString("$type$[i - length / 2]", (int s) -> { 1285 return fill(s * BUFFER_REPS, 1286 i -> ($type$)(i - (s * BUFFER_REPS / 2))); 1287 }), 1288 withToString("$type$[i + 1]", (int s) -> { 1289 return fill(s * BUFFER_REPS, 1290 i -> ($type$)(i + 1)); 1291 }), 1292 withToString("$type$[i - 2]", (int s) -> { 1293 return fill(s * BUFFER_REPS, 1294 i -> ($type$)(i - 2)); 1295 }), 1296 withToString("$type$[zigZag(i)]", (int s) -> { 1297 return fill(s * BUFFER_REPS, 1298 i -> i%3 == 0 ? ($type$)i : (i%3 == 1 ? ($type$)(i + 1) : ($type$)(i - 2))); 1299 }), 1300 withToString("$type$[cornerCaseValue(i)]", (int s) -> { 1301 return fill(s * BUFFER_REPS, 1302 i -> cornerCaseValue(i)); 1303 }) 1304 ); 1305 1306 static final List<List<IntFunction<$type$[]>>> $TYPE$_TEST_GENERATOR_ARGS = 1307 $TYPE$_COMPARE_GENERATORS.stream(). 1308 map(fa -> List.of(fa)). 1309 collect(Collectors.toList()); 1310 1311 @DataProvider 1312 public Object[][] $type$TestOpProvider() { 1313 return $TYPE$_TEST_GENERATOR_ARGS.stream().map(List::toArray). 1314 toArray(Object[][]::new); 1315 } 1316 1317 @DataProvider 1318 public Object[][] $type$TestOpMaskProvider() { 1319 return BOOLEAN_MASK_GENERATORS.stream(). 1320 flatMap(fm -> $TYPE$_TEST_GENERATOR_ARGS.stream().map(lfa -> { 1321 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 1322 })). 1323 toArray(Object[][]::new); 1324 } 1325 1326 static final List<List<IntFunction<$type$[]>>> $TYPE$_COMPARE_GENERATOR_PAIRS = 1327 $TYPE$_COMPARE_GENERATORS.stream(). 1328 flatMap(fa -> $TYPE$_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))). 1329 collect(Collectors.toList()); 1330 1331 @DataProvider 1332 public Object[][] $type$CompareOpProvider() { 1333 return $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray). 1334 toArray(Object[][]::new); 1335 } 1336 1337 @DataProvider 1338 public Object[][] $type$CompareOpMaskProvider() { 1339 return BOOLEAN_MASK_GENERATORS.stream(). 1340 flatMap(fm -> $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(lfa -> { 1341 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 1342 })). 1343 toArray(Object[][]::new); 1344 } 1345 1346 interface To$Type$F { 1347 $type$ apply(int i); 1348 } 1349 1350 static $type$[] fill(int s , To$Type$F f) { 1351 return fill(new $type$[s], f); 1352 } 1353 1354 static $type$[] fill($type$[] a, To$Type$F f) { 1355 for (int i = 0; i < a.length; i++) { 1356 a[i] = f.apply(i); 1357 } 1358 return a; 1359 } 1360 1361 static $type$ cornerCaseValue(int i) { 1362 #if[FP] 1363 switch(i % 7) { 1364 case 0: 1365 return $Wideboxtype$.MAX_VALUE; 1366 case 1: 1367 return $Wideboxtype$.MIN_VALUE; 1368 case 2: 1369 return $Wideboxtype$.NEGATIVE_INFINITY; 1370 case 3: 1371 return $Wideboxtype$.POSITIVE_INFINITY; 1372 case 4: 1373 return $Wideboxtype$.NaN; 1374 case 5: 1375 return ($type$)0.0; 1376 default: 1377 return ($type$)-0.0; 1378 } 1379 #else[FP] 1380 switch(i % 5) { 1381 case 0: 1382 return $Wideboxtype$.MAX_VALUE; 1383 case 1: 1384 return $Wideboxtype$.MIN_VALUE; 1385 case 2: 1386 return $Wideboxtype$.MIN_VALUE; 1387 case 3: 1388 return $Wideboxtype$.MAX_VALUE; 1389 default: 1390 return ($type$)0; 1391 } 1392 #end[FP] 1393 } 1394 1395 static $type$ get($type$[] a, int i) { 1396 return ($type$) a[i]; 1397 } 1398 1399 static final IntFunction<$type$[]> fr = (vl) -> { 1400 int length = BUFFER_REPS * vl; 1401 return new $type$[length]; 1402 }; 1403 1404 static final IntFunction<boolean[]> fmr = (vl) -> { 1405 int length = BUFFER_REPS * vl; 1406 return new boolean[length]; 1407 }; 1408 1409 #if[!Long] 1410 static final IntFunction<long[]> lfr = (vl) -> { 1411 int length = BUFFER_REPS * vl; 1412 return new long[length]; 1413 }; 1414 #end[!Long] 1415 1416 #if[BITWISE] 1417 static void replaceZero($type$[] a, $type$ v) { 1418 for (int i = 0; i < a.length; i++) { 1419 if (a[i] == 0) { 1420 a[i] = v; 1421 } 1422 } 1423 } 1424 1425 static void replaceZero($type$[] a, boolean[] mask, $type$ v) { 1426 for (int i = 0; i < a.length; i++) { 1427 if (mask[i % mask.length] && a[i] == 0) { 1428 a[i] = v; 1429 } 1430 } 1431 } 1432 1433 static $type$ ROL_scalar($type$ a, $type$ b) { 1434 #if[intOrLong] 1435 return $Wideboxtype$.rotateLeft(a, ((int)b)); 1436 #else[intOrLong] 1437 #if[short] 1438 return (short)(((((short)a) & 0xFFFF) << (b & 15)) | ((((short)a) & 0xFFFF) >>> (16 - (b & 15)))); 1439 #else[short] 1440 return (byte)(((((byte)a) & 0xFF) << (b & 7)) | ((((byte)a) & 0xFF) >>> (8 - (b & 7)))); 1441 #end[short] 1442 #end[intOrLong] 1443 } 1444 1445 static $type$ ROR_scalar($type$ a, $type$ b) { 1446 #if[intOrLong] 1447 return $Wideboxtype$.rotateRight(a, ((int)b)); 1448 #else[intOrLong] 1449 #if[short] 1450 return (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15)))); 1451 #else[short] 1452 return (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7)))); 1453 #end[short] 1454 #end[intOrLong] 1455 } 1456 #end[BITWISE] 1457 1458 static boolean eq($type$ a, $type$ b) { 1459 return a == b; 1460 } 1461 1462 static boolean neq($type$ a, $type$ b) { 1463 return a != b; 1464 } 1465 1466 static boolean lt($type$ a, $type$ b) { 1467 return a < b; 1468 } 1469 1470 static boolean le($type$ a, $type$ b) { 1471 return a <= b; 1472 } 1473 1474 static boolean gt($type$ a, $type$ b) { 1475 return a > b; 1476 } 1477 1478 static boolean ge($type$ a, $type$ b) { 1479 return a >= b; 1480 } 1481 1482 #if[!FP] 1483 static boolean ult($type$ a, $type$ b) { 1484 return $Boxtype$.compareUnsigned(a, b) < 0; 1485 } 1486 1487 static boolean ule($type$ a, $type$ b) { 1488 return $Boxtype$.compareUnsigned(a, b) <= 0; 1489 } 1490 1491 static boolean ugt($type$ a, $type$ b) { 1492 return $Boxtype$.compareUnsigned(a, b) > 0; 1493 } 1494 1495 static boolean uge($type$ a, $type$ b) { 1496 return $Boxtype$.compareUnsigned(a, b) >= 0; 1497 } 1498 #end[!FP] 1499 1500 static $type$ firstNonZero($type$ a, $type$ b) { 1501 return $Boxtype$.compare(a, ($type$) 0) != 0 ? a : b; 1502 } 1503 1504 @Test 1505 static void smokeTest1() { 1506 $abstractvectortype$ three = $abstractvectortype$.broadcast(SPECIES, (byte)-3); 1507 $abstractvectortype$ three2 = ($abstractvectortype$) SPECIES.broadcast(-3); 1508 assert(three.eq(three2).allTrue()); 1509 $abstractvectortype$ three3 = three2.broadcast(1).broadcast(-3); 1510 assert(three.eq(three3).allTrue()); 1511 int scale = 2; 1512 Class<?> ETYPE = $type$.class; 1513 if (ETYPE == double.class || ETYPE == long.class) 1514 scale = 1000000; 1515 else if (ETYPE == byte.class && SPECIES.length() >= 64) 1516 scale = 1; 1517 $abstractvectortype$ higher = three.addIndex(scale); 1518 VectorMask<$Boxtype$> m = three.compare(VectorOperators.LE, higher); 1519 assert(m.allTrue()); 1520 m = higher.min(($type$)-1).test(VectorOperators.IS_NEGATIVE); 1521 assert(m.allTrue()); 1522 #if[FP] 1523 m = higher.test(VectorOperators.IS_FINITE); 1524 assert(m.allTrue()); 1525 #end[FP] 1526 $type$ max = higher.reduceLanes(VectorOperators.MAX); 1527 assert(max == -3 + scale * (SPECIES.length()-1)); 1528 } 1529 1530 private static $type$[] 1531 bothToArray($abstractvectortype$ a, $abstractvectortype$ b) { 1532 $type$[] r = new $type$[a.length() + b.length()]; 1533 a.intoArray(r, 0); 1534 b.intoArray(r, a.length()); 1535 return r; 1536 } 1537 1538 @Test 1539 static void smokeTest2() { 1540 // Do some zipping and shuffling. 1541 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 1542 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES,0,1,false).toVector(); 1543 Assert.assertEquals(io, io2); 1544 $abstractvectortype$ a = io.add(($type$)1); //[1,2] 1545 $abstractvectortype$ b = a.neg(); //[-1,-2] 1546 $type$[] abValues = bothToArray(a,b); //[1,2,-1,-2] 1547 VectorShuffle<$Boxtype$> zip0 = VectorShuffle.makeZip(SPECIES, 0); 1548 VectorShuffle<$Boxtype$> zip1 = VectorShuffle.makeZip(SPECIES, 1); 1549 $abstractvectortype$ zab0 = a.rearrange(zip0,b); //[1,-1] 1550 $abstractvectortype$ zab1 = a.rearrange(zip1,b); //[2,-2] 1551 $type$[] zabValues = bothToArray(zab0, zab1); //[1,-1,2,-2] 1552 // manually zip 1553 $type$[] manual = new $type$[zabValues.length]; 1554 for (int i = 0; i < manual.length; i += 2) { 1555 manual[i+0] = abValues[i/2]; 1556 manual[i+1] = abValues[a.length() + i/2]; 1557 } 1558 Assert.assertEquals(Arrays.toString(zabValues), Arrays.toString(manual)); 1559 VectorShuffle<$Boxtype$> unz0 = VectorShuffle.makeUnzip(SPECIES, 0); 1560 VectorShuffle<$Boxtype$> unz1 = VectorShuffle.makeUnzip(SPECIES, 1); 1561 $abstractvectortype$ uab0 = zab0.rearrange(unz0,zab1); 1562 $abstractvectortype$ uab1 = zab0.rearrange(unz1,zab1); 1563 $type$[] abValues1 = bothToArray(uab0, uab1); 1564 Assert.assertEquals(Arrays.toString(abValues), Arrays.toString(abValues1)); 1565 } 1566 1567 static void iotaShuffle() { 1568 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 1569 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES, 0 , 1, false).toVector(); 1570 Assert.assertEquals(io, io2); 1571 } 1572 1573 @Test 1574 // Test all shuffle related operations. 1575 static void shuffleTest() { 1576 // To test backend instructions, make sure that C2 is used. 1577 for (int loop = 0; loop < INVOC_COUNT * INVOC_COUNT; loop++) { 1578 iotaShuffle(); 1579 } 1580 } 1581 1582 @Test 1583 void viewAsIntegeralLanesTest() { 1584 #if[FP] 1585 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes(); 1586 VectorSpecies<?> asIntegralSpecies = asIntegral.species(); 1587 Assert.assertNotEquals(asIntegralSpecies.elementType(), SPECIES.elementType()); 1588 Assert.assertEquals(asIntegralSpecies.vectorShape(), SPECIES.vectorShape()); 1589 Assert.assertEquals(asIntegralSpecies.length(), SPECIES.length()); 1590 Assert.assertEquals(asIntegral.viewAsFloatingLanes().species(), SPECIES); 1591 #else[FP] 1592 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes(); 1593 Assert.assertEquals(asIntegral.species(), SPECIES); 1594 #end[FP] 1595 } 1596 1597 #if[FP] 1598 @Test 1599 void viewAsFloatingLanesTest() { 1600 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes(); 1601 Assert.assertEquals(asFloating.species(), SPECIES); 1602 } 1603 #else[FP] 1604 #if[byteOrShort] 1605 @Test(expectedExceptions = UnsupportedOperationException.class) 1606 void viewAsFloatingLanesTest() { 1607 SPECIES.zero().viewAsFloatingLanes(); 1608 } 1609 #else[byteOrShort] 1610 @Test 1611 void viewAsFloatingLanesTest() { 1612 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes(); 1613 VectorSpecies<?> asFloatingSpecies = asFloating.species(); 1614 Assert.assertNotEquals(asFloatingSpecies.elementType(), SPECIES.elementType()); 1615 Assert.assertEquals(asFloatingSpecies.vectorShape(), SPECIES.vectorShape()); 1616 Assert.assertEquals(asFloatingSpecies.length(), SPECIES.length()); 1617 Assert.assertEquals(asFloating.viewAsIntegralLanes().species(), SPECIES); 1618 } 1619 #end[byteOrShort] 1620 #end[FP] 1621 1622 #if[BITWISE] 1623 @Test 1624 // Test div by 0. 1625 static void bitwiseDivByZeroSmokeTest() { 1626 try { 1627 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 1628 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0); 1629 a.div(b); 1630 Assert.fail(); 1631 } catch (ArithmeticException e) { 1632 } 1633 1634 try { 1635 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 1636 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0); 1637 VectorMask<$Boxtype$> m = a.lt(($type$) 1); 1638 a.div(b, m); 1639 Assert.fail(); 1640 } catch (ArithmeticException e) { 1641 } 1642 } 1643 #end[BITWISE]