1 /* 2 * Copyright (c) 2018, 2020, 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 $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.stream.Collectors; 68 import java.util.stream.Stream; 69 70 @Test 71 public class $vectorteststype$ extends AbstractVectorTest { 72 73 #if[MaxBit] 74 static final VectorSpecies<$Wideboxtype$> SPECIES = 75 $Type$Vector.SPECIES_MAX; 76 #else[MaxBit] 77 static final VectorSpecies<$Wideboxtype$> SPECIES = 78 $Type$Vector.SPECIES_$bits$; 79 #end[MaxBit] 80 81 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 82 83 #if[MaxBit] 84 static VectorShape getMaxBit() { 85 return VectorShape.S_Max_BIT; 86 } 87 88 private static final int Max = 256; // juts so we can do N/$bits$ 89 #end[MaxBit] 90 91 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$); 92 93 static final int BUFFER_SIZE = Integer.getInteger("jdk.incubator.vector.test.buffer-size", BUFFER_REPS * ($bits$ / 8)); 94 95 interface FUnOp { 96 $type$ apply($type$ a); 97 } 98 99 static void assertArraysEquals($type$[] a, $type$[] r, FUnOp f) { 100 int i = 0; 101 try { 102 for (; i < a.length; i++) { 103 Assert.assertEquals(r[i], f.apply(a[i])); 104 } 105 } catch (AssertionError e) { 106 Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]); 107 } 108 } 109 110 interface FUnArrayOp { 111 $type$[] apply($type$ a); 112 } 113 114 static void assertArraysEquals($type$[] a, $type$[] r, FUnArrayOp f) { 115 int i = 0; 116 try { 117 for (; i < a.length; i += SPECIES.length()) { 118 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 119 f.apply(a[i])); 120 } 121 } catch (AssertionError e) { 122 $type$[] ref = f.apply(a[i]); 123 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 124 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 125 + ", res: " + Arrays.toString(res) 126 + "), at index #" + i); 127 } 128 } 129 130 static void assertArraysEquals($type$[] a, $type$[] r, boolean[] mask, FUnOp f) { 131 int i = 0; 132 try { 133 for (; i < a.length; i++) { 134 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]); 135 } 136 } catch (AssertionError e) { 137 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()]); 138 } 139 } 140 141 interface FReductionOp { 142 $type$ apply($type$[] a, int idx); 143 } 144 145 interface FReductionAllOp { 146 $type$ apply($type$[] a); 147 } 148 149 static void assertReductionArraysEquals($type$[] a, $type$[] b, $type$ c, 150 FReductionOp f, FReductionAllOp fa) { 151 int i = 0; 152 try { 153 Assert.assertEquals(c, fa.apply(a)); 154 for (; i < a.length; i += SPECIES.length()) { 155 Assert.assertEquals(b[i], f.apply(a, i)); 156 } 157 } catch (AssertionError e) { 158 Assert.assertEquals(c, fa.apply(a), "Final result is incorrect!"); 159 Assert.assertEquals(b[i], f.apply(a, i), "at index #" + i); 160 } 161 } 162 163 interface FReductionMaskedOp { 164 $type$ apply($type$[] a, int idx, boolean[] mask); 165 } 166 167 interface FReductionAllMaskedOp { 168 $type$ apply($type$[] a, boolean[] mask); 169 } 170 171 static void assertReductionArraysEqualsMasked($type$[] a, $type$[] b, $type$ c, boolean[] mask, 172 FReductionMaskedOp f, FReductionAllMaskedOp fa) { 173 int i = 0; 174 try { 175 Assert.assertEquals(c, fa.apply(a, mask)); 176 for (; i < a.length; i += SPECIES.length()) { 177 Assert.assertEquals(b[i], f.apply(a, i, mask)); 178 } 179 } catch (AssertionError e) { 180 Assert.assertEquals(c, fa.apply(a, mask), "Final result is incorrect!"); 181 Assert.assertEquals(b[i], f.apply(a, i, mask), "at index #" + i); 182 } 183 } 184 185 interface FBoolReductionOp { 186 boolean apply(boolean[] a, int idx); 187 } 188 189 static void assertReductionBoolArraysEquals(boolean[] a, boolean[] b, FBoolReductionOp f) { 190 int i = 0; 191 try { 192 for (; i < a.length; i += SPECIES.length()) { 193 Assert.assertEquals(b[i], f.apply(a, i)); 194 } 195 } catch (AssertionError e) { 196 Assert.assertEquals(b[i], f.apply(a, i), "at index #" + i); 197 } 198 } 199 200 static void assertInsertArraysEquals($type$[] a, $type$[] b, $type$ element, int index) { 201 int i = 0; 202 try { 203 for (; i < a.length; i += 1) { 204 if(i%SPECIES.length() == index) { 205 Assert.assertEquals(b[i], element); 206 } else { 207 Assert.assertEquals(b[i], a[i]); 208 } 209 } 210 } catch (AssertionError e) { 211 if (i%SPECIES.length() == index) { 212 Assert.assertEquals(b[i], element, "at index #" + i); 213 } else { 214 Assert.assertEquals(b[i], a[i], "at index #" + i); 215 } 216 } 217 } 218 219 static void assertRearrangeArraysEquals($type$[] a, $type$[] r, int[] order, int vector_len) { 220 int i = 0, j = 0; 221 try { 222 for (; i < a.length; i += vector_len) { 223 for (j = 0; j < vector_len; j++) { 224 Assert.assertEquals(r[i+j], a[i+order[i+j]]); 225 } 226 } 227 } catch (AssertionError e) { 228 int idx = i + j; 229 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]); 230 } 231 } 232 233 static void assertBroadcastArraysEquals($type$[]a, $type$[]r) { 234 int i = 0; 235 for (; i < a.length; i += SPECIES.length()) { 236 int idx = i; 237 for (int j = idx; j < (idx + SPECIES.length()); j++) 238 a[j]=a[idx]; 239 } 240 241 try { 242 for (i = 0; i < a.length; i++) { 243 Assert.assertEquals(r[i], a[i]); 244 } 245 } catch (AssertionError e) { 246 Assert.assertEquals(r[i], a[i], "at index #" + i + ", input = " + a[i]); 247 } 248 } 249 250 interface FBinOp { 251 $type$ apply($type$ a, $type$ b); 252 } 253 254 interface FBinMaskOp { 255 $type$ apply($type$ a, $type$ b, boolean m); 256 257 static FBinMaskOp lift(FBinOp f) { 258 return (a, b, m) -> m ? f.apply(a, b) : a; 259 } 260 } 261 262 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, FBinOp f) { 263 int i = 0; 264 try { 265 for (; i < a.length; i++) { 266 Assert.assertEquals(r[i], f.apply(a[i], b[i])); 267 } 268 } catch (AssertionError e) { 269 Assert.assertEquals(r[i], f.apply(a[i], b[i]), "(" + a[i] + ", " + b[i] + ") at index #" + i); 270 } 271 } 272 273 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinOp f) { 274 assertArraysEquals(a, b, r, mask, FBinMaskOp.lift(f)); 275 } 276 277 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinMaskOp f) { 278 int i = 0; 279 try { 280 for (; i < a.length; i++) { 281 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()])); 282 } 283 } catch (AssertionError err) { 284 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()]); 285 } 286 } 287 288 static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, FBinOp f) { 289 int i = 0; 290 int j = 0; 291 try { 292 for (; j < a.length; j += SPECIES.length()) { 293 for (i = 0; i < SPECIES.length(); i++) { 294 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j])); 295 } 296 } 297 } catch (AssertionError e) { 298 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]), "at index #" + i + ", " + j); 299 } 300 } 301 302 static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinOp f) { 303 assertShiftArraysEquals(a, b, r, mask, FBinMaskOp.lift(f)); 304 } 305 306 static void assertShiftArraysEquals($type$[] a, $type$[] b, $type$[] r, boolean[] mask, FBinMaskOp f) { 307 int i = 0; 308 int j = 0; 309 try { 310 for (; j < a.length; j += SPECIES.length()) { 311 for (i = 0; i < SPECIES.length(); i++) { 312 Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i])); 313 } 314 } 315 } catch (AssertionError err) { 316 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]); 317 } 318 } 319 320 interface FTernOp { 321 $type$ apply($type$ a, $type$ b, $type$ c); 322 } 323 324 interface FTernMaskOp { 325 $type$ apply($type$ a, $type$ b, $type$ c, boolean m); 326 327 static FTernMaskOp lift(FTernOp f) { 328 return (a, b, c, m) -> m ? f.apply(a, b, c) : a; 329 } 330 } 331 332 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, FTernOp f) { 333 int i = 0; 334 try { 335 for (; i < a.length; i++) { 336 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i])); 337 } 338 } catch (AssertionError e) { 339 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); 340 } 341 } 342 343 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, boolean[] mask, FTernOp f) { 344 assertArraysEquals(a, b, c, r, mask, FTernMaskOp.lift(f)); 345 } 346 347 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] c, $type$[] r, boolean[] mask, FTernMaskOp f) { 348 int i = 0; 349 try { 350 for (; i < a.length; i++) { 351 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()])); 352 } 353 } catch (AssertionError err) { 354 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " 355 + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]); 356 } 357 } 358 359 #if[FP] 360 static boolean isWithin1Ulp($type$ actual, $type$ expected) { 361 if ($Type$.isNaN(expected) && !$Type$.isNaN(actual)) { 362 return false; 363 } else if (!$Type$.isNaN(expected) && $Type$.isNaN(actual)) { 364 return false; 365 } 366 367 $type$ low = Math.nextDown(expected); 368 $type$ high = Math.nextUp(expected); 369 370 if ($Type$.compare(low, expected) > 0) { 371 return false; 372 } 373 374 if ($Type$.compare(high, expected) < 0) { 375 return false; 376 } 377 378 return true; 379 } 380 381 static void assertArraysEqualsWithinOneUlp($type$[] a, $type$[] r, FUnOp mathf, FUnOp strictmathf) { 382 int i = 0; 383 try { 384 // Check that result is within 1 ulp of strict math or equivalent to math implementation. 385 for (; i < a.length; i++) { 386 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i])) == 0 || 387 isWithin1Ulp(r[i], strictmathf.apply(a[i]))); 388 } 389 } catch (AssertionError e) { 390 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])); 391 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])); 392 } 393 } 394 395 static void assertArraysEqualsWithinOneUlp($type$[] a, $type$[] b, $type$[] r, FBinOp mathf, FBinOp strictmathf) { 396 int i = 0; 397 try { 398 // Check that result is within 1 ulp of strict math or equivalent to math implementation. 399 for (; i < a.length; i++) { 400 Assert.assertTrue($Type$.compare(r[i], mathf.apply(a[i], b[i])) == 0 || 401 isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i]))); 402 } 403 } catch (AssertionError e) { 404 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])); 405 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])); 406 } 407 } 408 #end[FP] 409 410 interface FBinArrayOp { 411 $type$ apply($type$[] a, int b); 412 } 413 414 static void assertArraysEquals($type$[] a, $type$[] r, FBinArrayOp f) { 415 int i = 0; 416 try { 417 for (; i < a.length; i++) { 418 Assert.assertEquals(r[i], f.apply(a, i)); 419 } 420 } catch (AssertionError e) { 421 Assert.assertEquals(r[i], f.apply(a,i), "at index #" + i); 422 } 423 } 424 425 interface FGatherScatterOp { 426 $type$[] apply($type$[] a, int ix, int[] b, int iy); 427 } 428 429 static void assertArraysEquals($type$[] a, int[] b, $type$[] r, FGatherScatterOp f) { 430 int i = 0; 431 try { 432 for (; i < a.length; i += SPECIES.length()) { 433 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 434 f.apply(a, i, b, i)); 435 } 436 } catch (AssertionError e) { 437 $type$[] ref = f.apply(a, i, b, i); 438 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 439 Assert.assertEquals(res, ref, 440 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 441 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 442 + ", b: " 443 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 444 + " at index #" + i); 445 } 446 } 447 448 interface FGatherMaskedOp { 449 $type$[] apply($type$[] a, int ix, boolean[] mask, int[] b, int iy); 450 } 451 452 interface FScatterMaskedOp { 453 $type$[] apply($type$[] r, $type$[] a, int ix, boolean[] mask, int[] b, int iy); 454 } 455 456 static void assertArraysEquals($type$[] a, int[] b, $type$[] r, boolean[] mask, FGatherMaskedOp f) { 457 int i = 0; 458 try { 459 for (; i < a.length; i += SPECIES.length()) { 460 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 461 f.apply(a, i, mask, b, i)); 462 } 463 } catch (AssertionError e) { 464 $type$[] ref = f.apply(a, i, mask, b, i); 465 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 466 Assert.assertEquals(ref, res, 467 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 468 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 469 + ", b: " 470 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 471 + ", mask: " 472 + Arrays.toString(mask) 473 + " at index #" + i); 474 } 475 } 476 477 static void assertArraysEquals($type$[] a, int[] b, $type$[] r, boolean[] mask, FScatterMaskedOp f) { 478 int i = 0; 479 try { 480 for (; i < a.length; i += SPECIES.length()) { 481 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 482 f.apply(r, a, i, mask, b, i)); 483 } 484 } catch (AssertionError e) { 485 $type$[] ref = f.apply(r, a, i, mask, b, i); 486 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 487 Assert.assertEquals(ref, res, 488 "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: " 489 + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length())) 490 + ", b: " 491 + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length())) 492 + ", r: " 493 + Arrays.toString(Arrays.copyOfRange(r, i, i+SPECIES.length())) 494 + ", mask: " 495 + Arrays.toString(mask) 496 + " at index #" + i); 497 } 498 } 499 500 interface FLaneOp { 501 $type$[] apply($type$[] a, int origin, int idx); 502 } 503 504 static void assertArraysEquals($type$[] a, $type$[] r, int origin, FLaneOp f) { 505 int i = 0; 506 try { 507 for (; i < a.length; i += SPECIES.length()) { 508 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 509 f.apply(a, origin, i)); 510 } 511 } catch (AssertionError e) { 512 $type$[] ref = f.apply(a, origin, i); 513 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 514 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 515 + ", res: " + Arrays.toString(res) 516 + "), at index #" + i); 517 } 518 } 519 520 interface FLaneBop { 521 $type$[] apply($type$[] a, $type$[] b, int origin, int idx); 522 } 523 524 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, int origin, FLaneBop f) { 525 int i = 0; 526 try { 527 for (; i < a.length; i += SPECIES.length()) { 528 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 529 f.apply(a, b, origin, i)); 530 } 531 } catch (AssertionError e) { 532 $type$[] ref = f.apply(a, b, origin, i); 533 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 534 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 535 + ", res: " + Arrays.toString(res) 536 + "), at index #" + i 537 + ", at origin #" + origin); 538 } 539 } 540 541 interface FLaneMaskedBop { 542 $type$[] apply($type$[] a, $type$[] b, int origin, boolean[] mask, int idx); 543 } 544 545 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, int origin, boolean[] mask, FLaneMaskedBop f) { 546 int i = 0; 547 try { 548 for (; i < a.length; i += SPECIES.length()) { 549 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 550 f.apply(a, b, origin, mask, i)); 551 } 552 } catch (AssertionError e) { 553 $type$[] ref = f.apply(a, b, origin, mask, i); 554 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 555 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 556 + ", res: " + Arrays.toString(res) 557 + "), at index #" + i 558 + ", at origin #" + origin); 559 } 560 } 561 562 interface FLanePartBop { 563 $type$[] apply($type$[] a, $type$[] b, int origin, int part, int idx); 564 } 565 566 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, int origin, int part, FLanePartBop f) { 567 int i = 0; 568 try { 569 for (; i < a.length; i += SPECIES.length()) { 570 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 571 f.apply(a, b, origin, part, i)); 572 } 573 } catch (AssertionError e) { 574 $type$[] ref = f.apply(a, b, origin, part, i); 575 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 576 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 577 + ", res: " + Arrays.toString(res) 578 + "), at index #" + i 579 + ", at origin #" + origin 580 + ", with part #" + part); 581 } 582 } 583 584 interface FLanePartMaskedBop { 585 $type$[] apply($type$[] a, $type$[] b, int origin, int part, boolean[] mask, int idx); 586 } 587 588 static void assertArraysEquals($type$[] a, $type$[] b, $type$[] r, int origin, int part, boolean[] mask, FLanePartMaskedBop f) { 589 int i = 0; 590 try { 591 for (; i < a.length; i += SPECIES.length()) { 592 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()), 593 f.apply(a, b, origin, part, mask, i)); 594 } 595 } catch (AssertionError e) { 596 $type$[] ref = f.apply(a, b, origin, part, mask, i); 597 $type$[] res = Arrays.copyOfRange(r, i, i+SPECIES.length()); 598 Assert.assertEquals(ref, res, "(ref: " + Arrays.toString(ref) 599 + ", res: " + Arrays.toString(res) 600 + "), at index #" + i 601 + ", at origin #" + origin 602 + ", with part #" + part); 603 } 604 } 605 606 static $bitstype$ bits($type$ e) { 607 return {#if[FP]? $Type$.$type$To$Bitstype$Bits(e): e}; 608 } 609 610 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of( 611 withToString("$type$[-i * 5]", (int s) -> { 612 return fill(s * BUFFER_REPS, 613 i -> ($type$)(-i * 5)); 614 }), 615 withToString("$type$[i * 5]", (int s) -> { 616 return fill(s * BUFFER_REPS, 617 i -> ($type$)(i * 5)); 618 }), 619 withToString("$type$[i + 1]", (int s) -> { 620 return fill(s * BUFFER_REPS, 621 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1))); 622 }), 623 withToString("$type$[cornerCaseValue(i)]", (int s) -> { 624 return fill(s * BUFFER_REPS, 625 i -> cornerCaseValue(i)); 626 }) 627 ); 628 629 // Create combinations of pairs 630 // @@@ Might be sensitive to order e.g. div by 0 631 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_PAIRS = 632 Stream.of($TYPE$_GENERATORS.get(0)). 633 flatMap(fa -> $TYPE$_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). 634 collect(Collectors.toList()); 635 636 @DataProvider 637 public Object[][] boolUnaryOpProvider() { 638 return BOOL_ARRAY_GENERATORS.stream(). 639 map(f -> new Object[]{f}). 640 toArray(Object[][]::new); 641 } 642 643 static final List<List<IntFunction<$type$[]>>> $TYPE$_GENERATOR_TRIPLES = 644 $TYPE$_GENERATOR_PAIRS.stream(). 645 flatMap(pair -> $TYPE$_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))). 646 collect(Collectors.toList()); 647 648 @DataProvider 649 public Object[][] $type$BinaryOpProvider() { 650 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray). 651 toArray(Object[][]::new); 652 } 653 654 @DataProvider 655 public Object[][] $type$IndexedOpProvider() { 656 return $TYPE$_GENERATOR_PAIRS.stream().map(List::toArray). 657 toArray(Object[][]::new); 658 } 659 660 @DataProvider 661 public Object[][] $type$BinaryOpMaskProvider() { 662 return BOOLEAN_MASK_GENERATORS.stream(). 663 flatMap(fm -> $TYPE$_GENERATOR_PAIRS.stream().map(lfa -> { 664 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 665 })). 666 toArray(Object[][]::new); 667 } 668 669 @DataProvider 670 public Object[][] $type$TernaryOpProvider() { 671 return $TYPE$_GENERATOR_TRIPLES.stream().map(List::toArray). 672 toArray(Object[][]::new); 673 } 674 675 @DataProvider 676 public Object[][] $type$TernaryOpMaskProvider() { 677 return BOOLEAN_MASK_GENERATORS.stream(). 678 flatMap(fm -> $TYPE$_GENERATOR_TRIPLES.stream().map(lfa -> { 679 return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); 680 })). 681 toArray(Object[][]::new); 682 } 683 684 @DataProvider 685 public Object[][] $type$UnaryOpProvider() { 686 return $TYPE$_GENERATORS.stream(). 687 map(f -> new Object[]{f}). 688 toArray(Object[][]::new); 689 } 690 691 @DataProvider 692 public Object[][] $type$UnaryOpMaskProvider() { 693 return BOOLEAN_MASK_GENERATORS.stream(). 694 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> { 695 return new Object[] {fa, fm}; 696 })). 697 toArray(Object[][]::new); 698 } 699 700 @DataProvider 701 public Object[][] $type$UnaryOpShuffleProvider() { 702 return INT_SHUFFLE_GENERATORS.stream(). 703 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 704 return new Object[] {fa, fs}; 705 })). 706 toArray(Object[][]::new); 707 } 708 709 @DataProvider 710 public Object[][] $type$UnaryOpIndexProvider() { 711 return INT_INDEX_GENERATORS.stream(). 712 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 713 return new Object[] {fa, fs}; 714 })). 715 toArray(Object[][]::new); 716 } 717 718 @DataProvider 719 public Object[][] $type$UnaryMaskedOpIndexProvider() { 720 return BOOLEAN_MASK_GENERATORS.stream(). 721 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 722 $TYPE$_GENERATORS.stream().map(fa -> { 723 return new Object[] {fa, fm, fs}; 724 }))). 725 toArray(Object[][]::new); 726 } 727 728 @DataProvider 729 public Object[][] scatterMaskedOpIndexProvider() { 730 return BOOLEAN_MASK_GENERATORS.stream(). 731 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 732 $TYPE$_GENERATORS.stream().flatMap(fn -> 733 $TYPE$_GENERATORS.stream().map(fa -> { 734 return new Object[] {fa, fn, fm, fs}; 735 })))). 736 toArray(Object[][]::new); 737 } 738 739 static final List<IntFunction<$type$[]>> $TYPE$_COMPARE_GENERATORS = List.of( 740 withToString("$type$[i]", (int s) -> { 741 return fill(s * BUFFER_REPS, 742 i -> ($type$)i); 743 }), 744 withToString("$type$[i + 1]", (int s) -> { 745 return fill(s * BUFFER_REPS, 746 i -> ($type$)(i + 1)); 747 }), 748 withToString("$type$[i - 2]", (int s) -> { 749 return fill(s * BUFFER_REPS, 750 i -> ($type$)(i - 2)); 751 }), 752 withToString("$type$[zigZag(i)]", (int s) -> { 753 return fill(s * BUFFER_REPS, 754 i -> i%3 == 0 ? ($type$)i : (i%3 == 1 ? ($type$)(i + 1) : ($type$)(i - 2))); 755 }), 756 withToString("$type$[cornerCaseValue(i)]", (int s) -> { 757 return fill(s * BUFFER_REPS, 758 i -> cornerCaseValue(i)); 759 }) 760 ); 761 762 static final List<List<IntFunction<$type$[]>>> $TYPE$_TEST_GENERATOR_ARGS = 763 $TYPE$_COMPARE_GENERATORS.stream(). 764 map(fa -> List.of(fa)). 765 collect(Collectors.toList()); 766 767 @DataProvider 768 public Object[][] $type$TestOpProvider() { 769 return $TYPE$_TEST_GENERATOR_ARGS.stream().map(List::toArray). 770 toArray(Object[][]::new); 771 } 772 773 static final List<List<IntFunction<$type$[]>>> $TYPE$_COMPARE_GENERATOR_PAIRS = 774 $TYPE$_COMPARE_GENERATORS.stream(). 775 flatMap(fa -> $TYPE$_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))). 776 collect(Collectors.toList()); 777 778 @DataProvider 779 public Object[][] $type$CompareOpProvider() { 780 return $TYPE$_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray). 781 toArray(Object[][]::new); 782 } 783 784 interface To$Type$F { 785 $type$ apply(int i); 786 } 787 788 static $type$[] fill(int s , To$Type$F f) { 789 return fill(new $type$[s], f); 790 } 791 792 static $type$[] fill($type$[] a, To$Type$F f) { 793 for (int i = 0; i < a.length; i++) { 794 a[i] = f.apply(i); 795 } 796 return a; 797 } 798 799 static $type$ cornerCaseValue(int i) { 800 #if[FP] 801 switch(i % 7) { 802 case 0: 803 return $Wideboxtype$.MAX_VALUE; 804 case 1: 805 return $Wideboxtype$.MIN_VALUE; 806 case 2: 807 return $Wideboxtype$.NEGATIVE_INFINITY; 808 case 3: 809 return $Wideboxtype$.POSITIVE_INFINITY; 810 case 4: 811 return $Wideboxtype$.NaN; 812 case 5: 813 return ($type$)0.0; 814 default: 815 return ($type$)-0.0; 816 } 817 #else[FP] 818 switch(i % 5) { 819 case 0: 820 return $Wideboxtype$.MAX_VALUE; 821 case 1: 822 return $Wideboxtype$.MIN_VALUE; 823 case 2: 824 return $Wideboxtype$.MIN_VALUE; 825 case 3: 826 return $Wideboxtype$.MAX_VALUE; 827 default: 828 return ($type$)0; 829 } 830 #end[FP] 831 } 832 static $type$ get($type$[] a, int i) { 833 return ($type$) a[i]; 834 } 835 836 static final IntFunction<$type$[]> fr = (vl) -> { 837 int length = BUFFER_REPS * vl; 838 return new $type$[length]; 839 }; 840 841 static final IntFunction<boolean[]> fmr = (vl) -> { 842 int length = BUFFER_REPS * vl; 843 return new boolean[length]; 844 }; 845 846 #if[BITWISE] 847 static void replaceZero($type$[] a, $type$ v) { 848 for (int i = 0; i < a.length; i++) { 849 if (a[i] == 0) { 850 a[i] = v; 851 } 852 } 853 } 854 855 static void replaceZero($type$[] a, boolean[] mask, $type$ v) { 856 for (int i = 0; i < a.length; i++) { 857 if (mask[i % mask.length] && a[i] == 0) { 858 a[i] = v; 859 } 860 } 861 } 862 #end[BITWISE] 863 864 @Test 865 static void smokeTest1() { 866 $abstractvectortype$ three = $abstractvectortype$.broadcast(SPECIES, (byte)-3); 867 $abstractvectortype$ three2 = ($abstractvectortype$) SPECIES.broadcast(-3); 868 assert(three.eq(three2).allTrue()); 869 $abstractvectortype$ three3 = three2.broadcast(1).broadcast(-3); 870 assert(three.eq(three3).allTrue()); 871 int scale = 2; 872 Class<?> ETYPE = $type$.class; 873 if (ETYPE == double.class || ETYPE == long.class) 874 scale = 1000000; 875 else if (ETYPE == byte.class && SPECIES.length() >= 64) 876 scale = 1; 877 $abstractvectortype$ higher = three.addIndex(scale); 878 VectorMask<$Boxtype$> m = three.compare(VectorOperators.LE, higher); 879 assert(m.allTrue()); 880 m = higher.min(($type$)-1).test(VectorOperators.IS_NEGATIVE); 881 assert(m.allTrue()); 882 #if[FP] 883 m = higher.test(VectorOperators.IS_FINITE); 884 assert(m.allTrue()); 885 #end[FP] 886 $type$ max = higher.reduceLanes(VectorOperators.MAX); 887 assert(max == -3 + scale * (SPECIES.length()-1)); 888 } 889 890 private static $type$[] 891 bothToArray($abstractvectortype$ a, $abstractvectortype$ b) { 892 $type$[] r = new $type$[a.length() + b.length()]; 893 a.intoArray(r, 0); 894 b.intoArray(r, a.length()); 895 return r; 896 } 897 898 @Test 899 static void smokeTest2() { 900 // Do some zipping and shuffling. 901 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 902 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES,0,1,false).toVector(); 903 Assert.assertEquals(io, io2); 904 $abstractvectortype$ a = io.add(($type$)1); //[1,2] 905 $abstractvectortype$ b = a.neg(); //[-1,-2] 906 $type$[] abValues = bothToArray(a,b); //[1,2,-1,-2] 907 VectorShuffle<$Boxtype$> zip0 = VectorShuffle.makeZip(SPECIES, 0); 908 VectorShuffle<$Boxtype$> zip1 = VectorShuffle.makeZip(SPECIES, 1); 909 $abstractvectortype$ zab0 = a.rearrange(zip0,b); //[1,-1] 910 $abstractvectortype$ zab1 = a.rearrange(zip1,b); //[2,-2] 911 $type$[] zabValues = bothToArray(zab0, zab1); //[1,-1,2,-2] 912 // manually zip 913 $type$[] manual = new $type$[zabValues.length]; 914 for (int i = 0; i < manual.length; i += 2) { 915 manual[i+0] = abValues[i/2]; 916 manual[i+1] = abValues[a.length() + i/2]; 917 } 918 Assert.assertEquals(Arrays.toString(zabValues), Arrays.toString(manual)); 919 VectorShuffle<$Boxtype$> unz0 = VectorShuffle.makeUnzip(SPECIES, 0); 920 VectorShuffle<$Boxtype$> unz1 = VectorShuffle.makeUnzip(SPECIES, 1); 921 $abstractvectortype$ uab0 = zab0.rearrange(unz0,zab1); 922 $abstractvectortype$ uab1 = zab0.rearrange(unz1,zab1); 923 $type$[] abValues1 = bothToArray(uab0, uab1); 924 Assert.assertEquals(Arrays.toString(abValues), Arrays.toString(abValues1)); 925 } 926 927 static void iotaShuffle() { 928 $abstractvectortype$ io = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 929 $abstractvectortype$ io2 = ($abstractvectortype$) VectorShuffle.iota(SPECIES, 0 , 1, false).toVector(); 930 Assert.assertEquals(io, io2); 931 } 932 933 @Test 934 // Test all shuffle related operations. 935 static void shuffleTest() { 936 // To test backend instructions, make sure that C2 is used. 937 for (int loop = 0; loop < INVOC_COUNT * INVOC_COUNT; loop++) { 938 iotaShuffle(); 939 } 940 } 941 942 @Test 943 void viewAsIntegeralLanesTest() { 944 #if[FP] 945 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes(); 946 VectorSpecies<?> asIntegralSpecies = asIntegral.species(); 947 Assert.assertNotEquals(asIntegralSpecies.elementType(), SPECIES.elementType()); 948 Assert.assertEquals(asIntegralSpecies.vectorShape(), SPECIES.vectorShape()); 949 Assert.assertEquals(asIntegralSpecies.length(), SPECIES.length()); 950 Assert.assertEquals(asIntegral.viewAsFloatingLanes().species(), SPECIES); 951 #else[FP] 952 Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes(); 953 Assert.assertEquals(asIntegral.species(), SPECIES); 954 #end[FP] 955 } 956 957 #if[FP] 958 @Test 959 void viewAsFloatingLanesTest() { 960 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes(); 961 Assert.assertEquals(asFloating.species(), SPECIES); 962 } 963 #else[FP] 964 #if[byteOrShort] 965 @Test(expectedExceptions = UnsupportedOperationException.class) 966 void viewAsFloatingLanesTest() { 967 SPECIES.zero().viewAsFloatingLanes(); 968 } 969 #else[byteOrShort] 970 @Test 971 void viewAsFloatingLanesTest() { 972 Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes(); 973 VectorSpecies<?> asFloatingSpecies = asFloating.species(); 974 Assert.assertNotEquals(asFloatingSpecies.elementType(), SPECIES.elementType()); 975 Assert.assertEquals(asFloatingSpecies.vectorShape(), SPECIES.vectorShape()); 976 Assert.assertEquals(asFloatingSpecies.length(), SPECIES.length()); 977 Assert.assertEquals(asFloating.viewAsIntegralLanes().species(), SPECIES); 978 } 979 #end[byteOrShort] 980 #end[FP] 981 982 #if[BITWISE] 983 @Test 984 // Test div by 0. 985 static void bitwiseDivByZeroSmokeTest() { 986 try { 987 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 988 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0); 989 a.div(b); 990 Assert.fail(); 991 } catch (ArithmeticException e) { 992 } 993 994 try { 995 $abstractvectortype$ a = ($abstractvectortype$) SPECIES.broadcast(0).addIndex(1); 996 $abstractvectortype$ b = ($abstractvectortype$) SPECIES.broadcast(0); 997 VectorMask<$Boxtype$> m = a.lt(($type$) 1); 998 a.div(b, m); 999 Assert.fail(); 1000 } catch (ArithmeticException e) { 1001 } 1002 } 1003 #end[BITWISE]