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