1 /* 2 * Copyright (c) 2018, 2021, 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.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation 27 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED 28 * -XX:-TieredCompilation ShortMaxVectorLoadStoreTests 29 * 30 */ 31 32 // -- This file was mechanically generated: Do not edit! -- // 33 34 import jdk.incubator.vector.ShortVector; 35 import jdk.incubator.vector.VectorMask; 36 import jdk.incubator.vector.VectorShape; 37 import jdk.incubator.vector.VectorSpecies; 38 import jdk.incubator.vector.VectorShuffle; 39 import jdk.internal.vm.annotation.DontInline; 40 import org.testng.Assert; 41 import org.testng.annotations.DataProvider; 42 import org.testng.annotations.Test; 43 44 import java.lang.invoke.MethodHandles; 45 import java.lang.invoke.VarHandle; 46 import java.nio.ByteBuffer; 47 import java.nio.ShortBuffer; 48 import java.nio.ByteOrder; 49 import java.nio.ReadOnlyBufferException; 50 import java.util.List; 51 import java.util.function.*; 52 53 @Test 54 public class ShortMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest { 55 static final VectorSpecies<Short> SPECIES = 56 ShortVector.SPECIES_MAX; 57 58 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 59 60 static VectorShape getMaxBit() { 61 return VectorShape.S_Max_BIT; 62 } 63 64 private static final int Max = 256; // juts so we can do N/Max 65 66 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max); 67 68 static void assertArraysEquals(short[] r, short[] a, boolean[] mask) { 69 int i = 0; 70 try { 71 for (; i < a.length; i++) { 72 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0); 73 } 74 } catch (AssertionError e) { 75 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0, "at index #" + i); 76 } 77 } 78 79 static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) { 80 int i = 0; 81 try { 82 for (; i < a.length; i++) { 83 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0); 84 } 85 } catch (AssertionError e) { 86 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i); 87 } 88 } 89 90 static final List<IntFunction<short[]>> SHORT_GENERATORS = List.of( 91 withToString("short[i * 5]", (int s) -> { 92 return fill(s * BUFFER_REPS, 93 i -> (short)(i * 5)); 94 }), 95 withToString("short[i + 1]", (int s) -> { 96 return fill(s * BUFFER_REPS, 97 i -> (((short)(i + 1) == 0) ? 1 : (short)(i + 1))); 98 }) 99 ); 100 101 // Relative to array.length 102 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 103 withToString("-1", (int l) -> { 104 return -1; 105 }), 106 withToString("l", (int l) -> { 107 return l; 108 }), 109 withToString("l - 1", (int l) -> { 110 return l - 1; 111 }), 112 withToString("l + 1", (int l) -> { 113 return l + 1; 114 }), 115 withToString("l - speciesl + 1", (int l) -> { 116 return l - SPECIES.length() + 1; 117 }), 118 withToString("l + speciesl - 1", (int l) -> { 119 return l + SPECIES.length() - 1; 120 }), 121 withToString("l + speciesl", (int l) -> { 122 return l + SPECIES.length(); 123 }), 124 withToString("l + speciesl + 1", (int l) -> { 125 return l + SPECIES.length() + 1; 126 }) 127 ); 128 129 // Relative to byte[] array.length or ByteBuffer.limit() 130 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 131 withToString("-1", (int l) -> { 132 return -1; 133 }), 134 withToString("l", (int l) -> { 135 return l; 136 }), 137 withToString("l - 1", (int l) -> { 138 return l - 1; 139 }), 140 withToString("l + 1", (int l) -> { 141 return l + 1; 142 }), 143 withToString("l - speciesl*ebsize + 1", (int l) -> { 144 return l - SPECIES.vectorByteSize() + 1; 145 }), 146 withToString("l + speciesl*ebsize - 1", (int l) -> { 147 return l + SPECIES.vectorByteSize() - 1; 148 }), 149 withToString("l + speciesl*ebsize", (int l) -> { 150 return l + SPECIES.vectorByteSize(); 151 }), 152 withToString("l + speciesl*ebsize + 1", (int l) -> { 153 return l + SPECIES.vectorByteSize() + 1; 154 }) 155 ); 156 157 @DataProvider 158 public Object[][] shortProvider() { 159 return SHORT_GENERATORS.stream(). 160 map(f -> new Object[]{f}). 161 toArray(Object[][]::new); 162 } 163 164 @DataProvider 165 public Object[][] maskProvider() { 166 return BOOLEAN_MASK_GENERATORS.stream(). 167 map(f -> new Object[]{f}). 168 toArray(Object[][]::new); 169 } 170 171 @DataProvider 172 public Object[][] shortProviderForIOOBE() { 173 var f = SHORT_GENERATORS.get(0); 174 return INDEX_GENERATORS.stream().map(fi -> { 175 return new Object[] {f, fi}; 176 }). 177 toArray(Object[][]::new); 178 } 179 180 @DataProvider 181 public Object[][] shortMaskProvider() { 182 return BOOLEAN_MASK_GENERATORS.stream(). 183 flatMap(fm -> SHORT_GENERATORS.stream().map(fa -> { 184 return new Object[] {fa, fm}; 185 })). 186 toArray(Object[][]::new); 187 } 188 189 @DataProvider 190 public Object[][] shortMaskProviderForIOOBE() { 191 var f = SHORT_GENERATORS.get(0); 192 return BOOLEAN_MASK_GENERATORS.stream(). 193 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 194 return new Object[] {f, fi, fm}; 195 })). 196 toArray(Object[][]::new); 197 } 198 199 @DataProvider 200 public Object[][] shortByteBufferProvider() { 201 return SHORT_GENERATORS.stream(). 202 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream(). 203 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 204 return new Object[]{fa, fb, bo}; 205 }))). 206 toArray(Object[][]::new); 207 } 208 209 @DataProvider 210 public Object[][] shortByteBufferMaskProvider() { 211 return BOOLEAN_MASK_GENERATORS.stream(). 212 flatMap(fm -> SHORT_GENERATORS.stream(). 213 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream(). 214 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 215 return new Object[]{fa, fb, fm, bo}; 216 })))). 217 toArray(Object[][]::new); 218 } 219 220 @DataProvider 221 public Object[][] shortByteArrayProvider() { 222 return SHORT_GENERATORS.stream(). 223 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> { 224 return new Object[]{fa, bo}; 225 })). 226 toArray(Object[][]::new); 227 } 228 229 @DataProvider 230 public Object[][] shortByteArrayMaskProvider() { 231 return BOOLEAN_MASK_GENERATORS.stream(). 232 flatMap(fm -> SHORT_GENERATORS.stream(). 233 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> { 234 return new Object[]{fa, fm, bo}; 235 }))). 236 toArray(Object[][]::new); 237 } 238 239 @DataProvider 240 public Object[][] shortByteProviderForIOOBE() { 241 var f = SHORT_GENERATORS.get(0); 242 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 243 return new Object[] {f, fi}; 244 }). 245 toArray(Object[][]::new); 246 } 247 248 @DataProvider 249 public Object[][] shortByteMaskProviderForIOOBE() { 250 var f = SHORT_GENERATORS.get(0); 251 return BOOLEAN_MASK_GENERATORS.stream(). 252 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 253 return new Object[] {f, fi, fm}; 254 })). 255 toArray(Object[][]::new); 256 } 257 258 static ByteBuffer toBuffer(short[] a, IntFunction<ByteBuffer> fb) { 259 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 260 for (short v : a) { 261 bb.putShort(v); 262 } 263 return bb.clear(); 264 } 265 266 static short[] bufferToArray(ByteBuffer bb) { 267 ShortBuffer db = bb.asShortBuffer(); 268 short[] d = new short[db.capacity()]; 269 db.get(0, d); 270 return d; 271 } 272 273 static byte[] toByteArray(short[] a, IntFunction<byte[]> fb, ByteOrder bo) { 274 byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8); 275 ShortBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).asShortBuffer(); 276 for (short v : a) { 277 bb.put(v); 278 } 279 return b; 280 } 281 282 283 interface ToShortF { 284 short apply(int i); 285 } 286 287 static short[] fill(int s , ToShortF f) { 288 return fill(new short[s], f); 289 } 290 291 static short[] fill(short[] a, ToShortF f) { 292 for (int i = 0; i < a.length; i++) { 293 a[i] = f.apply(i); 294 } 295 return a; 296 } 297 298 @DontInline 299 static ShortVector fromArray(short[] a, int i) { 300 return ShortVector.fromArray(SPECIES, a, i); 301 } 302 303 @DontInline 304 static ShortVector fromArray(short[] a, int i, VectorMask<Short> m) { 305 return ShortVector.fromArray(SPECIES, a, i, m); 306 } 307 308 @DontInline 309 static void intoArray(ShortVector v, short[] a, int i) { 310 v.intoArray(a, i); 311 } 312 313 @DontInline 314 static void intoArray(ShortVector v, short[] a, int i, VectorMask<Short> m) { 315 v.intoArray(a, i, m); 316 } 317 318 @DontInline 319 static ShortVector fromByteArray(byte[] a, int i, ByteOrder bo) { 320 return ShortVector.fromByteArray(SPECIES, a, i, bo); 321 } 322 323 @DontInline 324 static ShortVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Short> m) { 325 return ShortVector.fromByteArray(SPECIES, a, i, bo, m); 326 } 327 328 @DontInline 329 static void intoByteArray(ShortVector v, byte[] a, int i, ByteOrder bo) { 330 v.intoByteArray(a, i, bo); 331 } 332 333 @DontInline 334 static void intoByteArray(ShortVector v, byte[] a, int i, ByteOrder bo, VectorMask<Short> m) { 335 v.intoByteArray(a, i, bo, m); 336 } 337 338 @DontInline 339 static ShortVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) { 340 return ShortVector.fromByteBuffer(SPECIES, a, i, bo); 341 } 342 343 @DontInline 344 static ShortVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Short> m) { 345 return ShortVector.fromByteBuffer(SPECIES, a, i, bo, m); 346 } 347 348 @DontInline 349 static void intoByteBuffer(ShortVector v, ByteBuffer a, int i, ByteOrder bo) { 350 v.intoByteBuffer(a, i, bo); 351 } 352 353 @DontInline 354 static void intoByteBuffer(ShortVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Short> m) { 355 v.intoByteBuffer(a, i, bo, m); 356 } 357 358 359 @Test(dataProvider = "shortProvider") 360 static void loadStoreArray(IntFunction<short[]> fa) { 361 short[] a = fa.apply(SPECIES.length()); 362 short[] r = new short[a.length]; 363 364 for (int ic = 0; ic < INVOC_COUNT; ic++) { 365 for (int i = 0; i < a.length; i += SPECIES.length()) { 366 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 367 av.intoArray(r, i); 368 } 369 } 370 Assert.assertEquals(r, a); 371 } 372 373 @Test(dataProvider = "shortProviderForIOOBE") 374 static void loadArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 375 short[] a = fa.apply(SPECIES.length()); 376 short[] r = new short[a.length]; 377 378 for (int ic = 0; ic < INVOC_COUNT; ic++) { 379 for (int i = 0; i < a.length; i += SPECIES.length()) { 380 ShortVector av = fromArray(a, i); 381 av.intoArray(r, i); 382 } 383 } 384 385 int index = fi.apply(a.length); 386 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 387 try { 388 fromArray(a, index); 389 if (shouldFail) { 390 Assert.fail("Failed to throw IndexOutOfBoundsException"); 391 } 392 } catch (IndexOutOfBoundsException e) { 393 if (!shouldFail) { 394 Assert.fail("Unexpected IndexOutOfBoundsException"); 395 } 396 } 397 } 398 399 @Test(dataProvider = "shortProviderForIOOBE") 400 static void storeArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 401 short[] a = fa.apply(SPECIES.length()); 402 short[] r = new short[a.length]; 403 404 for (int ic = 0; ic < INVOC_COUNT; ic++) { 405 for (int i = 0; i < a.length; i += SPECIES.length()) { 406 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 407 intoArray(av, r, i); 408 } 409 } 410 411 int index = fi.apply(a.length); 412 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 413 try { 414 ShortVector av = ShortVector.fromArray(SPECIES, a, 0); 415 intoArray(av, r, index); 416 if (shouldFail) { 417 Assert.fail("Failed to throw IndexOutOfBoundsException"); 418 } 419 } catch (IndexOutOfBoundsException e) { 420 if (!shouldFail) { 421 Assert.fail("Unexpected IndexOutOfBoundsException"); 422 } 423 } 424 } 425 426 427 @Test(dataProvider = "shortMaskProvider") 428 static void loadStoreMaskArray(IntFunction<short[]> fa, 429 IntFunction<boolean[]> fm) { 430 short[] a = fa.apply(SPECIES.length()); 431 short[] r = new short[a.length]; 432 boolean[] mask = fm.apply(SPECIES.length()); 433 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 434 435 for (int ic = 0; ic < INVOC_COUNT; ic++) { 436 for (int i = 0; i < a.length; i += SPECIES.length()) { 437 ShortVector av = ShortVector.fromArray(SPECIES, a, i, vmask); 438 av.intoArray(r, i); 439 } 440 } 441 assertArraysEquals(r, a, mask); 442 443 444 r = new short[a.length]; 445 446 for (int ic = 0; ic < INVOC_COUNT; ic++) { 447 for (int i = 0; i < a.length; i += SPECIES.length()) { 448 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 449 av.intoArray(r, i, vmask); 450 } 451 } 452 assertArraysEquals(r, a, mask); 453 } 454 455 @Test(dataProvider = "shortMaskProviderForIOOBE") 456 static void loadArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 457 short[] a = fa.apply(SPECIES.length()); 458 short[] r = new short[a.length]; 459 boolean[] mask = fm.apply(SPECIES.length()); 460 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 461 462 for (int ic = 0; ic < INVOC_COUNT; ic++) { 463 for (int i = 0; i < a.length; i += SPECIES.length()) { 464 ShortVector av = fromArray(a, i, vmask); 465 av.intoArray(r, i); 466 } 467 } 468 469 int index = fi.apply(a.length); 470 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 471 try { 472 fromArray(a, index, vmask); 473 if (shouldFail) { 474 Assert.fail("Failed to throw IndexOutOfBoundsException"); 475 } 476 } catch (IndexOutOfBoundsException e) { 477 if (!shouldFail) { 478 Assert.fail("Unexpected IndexOutOfBoundsException"); 479 } 480 } 481 } 482 483 @Test(dataProvider = "shortMaskProviderForIOOBE") 484 static void storeArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 485 short[] a = fa.apply(SPECIES.length()); 486 short[] r = new short[a.length]; 487 boolean[] mask = fm.apply(SPECIES.length()); 488 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 489 490 for (int ic = 0; ic < INVOC_COUNT; ic++) { 491 for (int i = 0; i < a.length; i += SPECIES.length()) { 492 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 493 intoArray(av, r, i, vmask); 494 } 495 } 496 497 int index = fi.apply(a.length); 498 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 499 try { 500 ShortVector av = ShortVector.fromArray(SPECIES, a, 0); 501 intoArray(av, a, index, vmask); 502 if (shouldFail) { 503 Assert.fail("Failed to throw IndexOutOfBoundsException"); 504 } 505 } catch (IndexOutOfBoundsException e) { 506 if (!shouldFail) { 507 Assert.fail("Unexpected IndexOutOfBoundsException"); 508 } 509 } 510 } 511 512 513 @Test(dataProvider = "shortMaskProvider") 514 static void loadStoreMask(IntFunction<short[]> fa, 515 IntFunction<boolean[]> fm) { 516 boolean[] mask = fm.apply(SPECIES.length()); 517 boolean[] r = new boolean[mask.length]; 518 519 for (int ic = 0; ic < INVOC_COUNT; ic++) { 520 for (int i = 0; i < mask.length; i += SPECIES.length()) { 521 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, i); 522 vmask.intoArray(r, i); 523 } 524 } 525 Assert.assertEquals(r, mask); 526 } 527 528 529 @Test(dataProvider = "shortByteBufferProvider") 530 static void loadStoreByteBuffer(IntFunction<short[]> fa, 531 IntFunction<ByteBuffer> fb, 532 ByteOrder bo) { 533 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 534 ByteBuffer r = fb.apply(a.limit()); 535 536 int l = a.limit(); 537 int s = SPECIES.vectorByteSize(); 538 539 for (int ic = 0; ic < INVOC_COUNT; ic++) { 540 for (int i = 0; i < l; i += s) { 541 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, bo); 542 av.intoByteBuffer(r, i, bo); 543 } 544 } 545 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 546 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 547 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 548 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 549 Assert.assertEquals(r, a, "Buffers not equal"); 550 } 551 552 @Test(dataProvider = "shortByteProviderForIOOBE") 553 static void loadByteBufferIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 554 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 555 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 556 557 int l = a.limit(); 558 int s = SPECIES.vectorByteSize(); 559 560 for (int ic = 0; ic < INVOC_COUNT; ic++) { 561 for (int i = 0; i < l; i += s) { 562 ShortVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder()); 563 av.intoByteBuffer(r, i, ByteOrder.nativeOrder()); 564 } 565 } 566 567 int index = fi.apply(a.limit()); 568 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit()); 569 try { 570 fromByteBuffer(a, index, ByteOrder.nativeOrder()); 571 if (shouldFail) { 572 Assert.fail("Failed to throw IndexOutOfBoundsException"); 573 } 574 } catch (IndexOutOfBoundsException e) { 575 if (!shouldFail) { 576 Assert.fail("Unexpected IndexOutOfBoundsException"); 577 } 578 } 579 } 580 581 @Test(dataProvider = "shortByteProviderForIOOBE") 582 static void storeByteBufferIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 583 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 584 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 585 586 int l = a.limit(); 587 int s = SPECIES.vectorByteSize(); 588 589 for (int ic = 0; ic < INVOC_COUNT; ic++) { 590 for (int i = 0; i < l; i += s) { 591 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder()); 592 intoByteBuffer(av, r, i, ByteOrder.nativeOrder()); 593 } 594 } 595 596 int index = fi.apply(a.limit()); 597 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit()); 598 try { 599 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder()); 600 intoByteBuffer(av, r, index, ByteOrder.nativeOrder()); 601 if (shouldFail) { 602 Assert.fail("Failed to throw IndexOutOfBoundsException"); 603 } 604 } catch (IndexOutOfBoundsException e) { 605 if (!shouldFail) { 606 Assert.fail("Unexpected IndexOutOfBoundsException"); 607 } 608 } 609 } 610 611 612 @Test(dataProvider = "shortByteBufferMaskProvider") 613 static void loadStoreByteBufferMask(IntFunction<short[]> fa, 614 IntFunction<ByteBuffer> fb, 615 IntFunction<boolean[]> fm, 616 ByteOrder bo) { 617 short[] _a = fa.apply(SPECIES.length()); 618 ByteBuffer a = toBuffer(_a, fb); 619 ByteBuffer r = fb.apply(a.limit()); 620 boolean[] mask = fm.apply(SPECIES.length()); 621 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 622 623 int l = a.limit(); 624 int s = SPECIES.vectorByteSize(); 625 626 for (int ic = 0; ic < INVOC_COUNT; ic++) { 627 for (int i = 0; i < l; i += s) { 628 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, bo, vmask); 629 av.intoByteBuffer(r, i, bo); 630 } 631 } 632 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 633 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 634 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 635 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 636 assertArraysEquals(bufferToArray(r), _a, mask); 637 638 639 r = fb.apply(a.limit()); 640 641 for (int ic = 0; ic < INVOC_COUNT; ic++) { 642 for (int i = 0; i < l; i += s) { 643 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, bo); 644 av.intoByteBuffer(r, i, bo, vmask); 645 } 646 } 647 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 648 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 649 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 650 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 651 assertArraysEquals(bufferToArray(r), _a, mask); 652 } 653 654 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 655 static void loadByteBufferMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 656 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 657 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 658 boolean[] mask = fm.apply(SPECIES.length()); 659 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 660 661 int l = a.limit(); 662 int s = SPECIES.vectorByteSize(); 663 664 for (int ic = 0; ic < INVOC_COUNT; ic++) { 665 for (int i = 0; i < l; i += s) { 666 ShortVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask); 667 av.intoByteBuffer(r, i, ByteOrder.nativeOrder()); 668 } 669 } 670 671 int index = fi.apply(a.limit()); 672 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8); 673 try { 674 fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask); 675 if (shouldFail) { 676 Assert.fail("Failed to throw IndexOutOfBoundsException"); 677 } 678 } catch (IndexOutOfBoundsException e) { 679 if (!shouldFail) { 680 Assert.fail("Unexpected IndexOutOfBoundsException"); 681 } 682 } 683 } 684 685 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 686 static void storeByteBufferMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 687 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 688 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 689 boolean[] mask = fm.apply(SPECIES.length()); 690 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 691 692 int l = a.limit(); 693 int s = SPECIES.vectorByteSize(); 694 695 for (int ic = 0; ic < INVOC_COUNT; ic++) { 696 for (int i = 0; i < l; i += s) { 697 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder()); 698 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask); 699 } 700 } 701 702 int index = fi.apply(a.limit()); 703 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8); 704 try { 705 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder()); 706 intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask); 707 if (shouldFail) { 708 Assert.fail("Failed to throw IndexOutOfBoundsException"); 709 } 710 } catch (IndexOutOfBoundsException e) { 711 if (!shouldFail) { 712 Assert.fail("Unexpected IndexOutOfBoundsException"); 713 } 714 } 715 } 716 717 718 @Test(dataProvider = "shortByteBufferProvider") 719 static void loadStoreReadonlyByteBuffer(IntFunction<short[]> fa, 720 IntFunction<ByteBuffer> fb, 721 ByteOrder bo) { 722 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer(); 723 724 try { 725 SPECIES.zero().intoByteBuffer(a, 0, bo); 726 Assert.fail("ReadOnlyBufferException expected"); 727 } catch (ReadOnlyBufferException e) { 728 } 729 730 try { 731 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true)); 732 Assert.fail("ReadOnlyBufferException expected"); 733 } catch (ReadOnlyBufferException e) { 734 } 735 736 try { 737 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false)); 738 Assert.fail("ReadOnlyBufferException expected"); 739 } catch (ReadOnlyBufferException e) { 740 } 741 742 try { 743 VectorMask<Short> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 744 .laneIsValid(); 745 SPECIES.zero().intoByteBuffer(a, 0, bo, m); 746 Assert.fail("ReadOnlyBufferException expected"); 747 } catch (ReadOnlyBufferException e) { 748 } 749 } 750 751 752 @Test(dataProvider = "shortByteArrayProvider") 753 static void loadStoreByteArray(IntFunction<short[]> fa, 754 ByteOrder bo) { 755 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo); 756 byte[] r = new byte[a.length]; 757 758 int s = SPECIES.vectorByteSize(); 759 int l = a.length; 760 761 for (int ic = 0; ic < INVOC_COUNT; ic++) { 762 for (int i = 0; i < l; i += s) { 763 ShortVector av = ShortVector.fromByteArray(SPECIES, a, i, bo); 764 av.intoByteArray(r, i, bo); 765 } 766 } 767 Assert.assertEquals(r, a, "Byte arrays not equal"); 768 } 769 770 @Test(dataProvider = "shortByteProviderForIOOBE") 771 static void loadByteArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 772 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 773 byte[] r = new byte[a.length]; 774 775 int s = SPECIES.vectorByteSize(); 776 int l = a.length; 777 778 for (int ic = 0; ic < INVOC_COUNT; ic++) { 779 for (int i = 0; i < l; i += s) { 780 ShortVector av = fromByteArray(a, i, ByteOrder.nativeOrder()); 781 av.intoByteArray(r, i, ByteOrder.nativeOrder()); 782 } 783 } 784 785 int index = fi.apply(a.length); 786 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length); 787 try { 788 fromByteArray(a, index, ByteOrder.nativeOrder()); 789 if (shouldFail) { 790 Assert.fail("Failed to throw IndexOutOfBoundsException"); 791 } 792 } catch (IndexOutOfBoundsException e) { 793 if (!shouldFail) { 794 Assert.fail("Unexpected IndexOutOfBoundsException"); 795 } 796 } 797 } 798 799 @Test(dataProvider = "shortByteProviderForIOOBE") 800 static void storeByteArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 801 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 802 byte[] r = new byte[a.length]; 803 804 int s = SPECIES.vectorByteSize(); 805 int l = a.length; 806 807 for (int ic = 0; ic < INVOC_COUNT; ic++) { 808 for (int i = 0; i < l; i += s) { 809 ShortVector av = ShortVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder()); 810 intoByteArray(av, r, i, ByteOrder.nativeOrder()); 811 } 812 } 813 814 int index = fi.apply(a.length); 815 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length); 816 try { 817 ShortVector av = ShortVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder()); 818 intoByteArray(av, r, index, ByteOrder.nativeOrder()); 819 if (shouldFail) { 820 Assert.fail("Failed to throw IndexOutOfBoundsException"); 821 } 822 } catch (IndexOutOfBoundsException e) { 823 if (!shouldFail) { 824 Assert.fail("Unexpected IndexOutOfBoundsException"); 825 } 826 } 827 } 828 829 830 @Test(dataProvider = "shortByteArrayMaskProvider") 831 static void loadStoreByteArrayMask(IntFunction<short[]> fa, 832 IntFunction<boolean[]> fm, 833 ByteOrder bo) { 834 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo); 835 byte[] r = new byte[a.length]; 836 boolean[] mask = fm.apply(SPECIES.length()); 837 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 838 839 int s = SPECIES.vectorByteSize(); 840 int l = a.length; 841 842 for (int ic = 0; ic < INVOC_COUNT; ic++) { 843 for (int i = 0; i < l; i += s) { 844 ShortVector av = ShortVector.fromByteArray(SPECIES, a, i, bo, vmask); 845 av.intoByteArray(r, i, bo); 846 } 847 } 848 assertArraysEquals(r, a, mask); 849 850 851 r = new byte[a.length]; 852 853 for (int ic = 0; ic < INVOC_COUNT; ic++) { 854 for (int i = 0; i < l; i += s) { 855 ShortVector av = ShortVector.fromByteArray(SPECIES, a, i, bo); 856 av.intoByteArray(r, i, bo, vmask); 857 } 858 } 859 assertArraysEquals(r, a, mask); 860 } 861 862 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 863 static void loadByteArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 864 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 865 byte[] r = new byte[a.length]; 866 boolean[] mask = fm.apply(SPECIES.length()); 867 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 868 869 int s = SPECIES.vectorByteSize(); 870 int l = a.length; 871 872 for (int ic = 0; ic < INVOC_COUNT; ic++) { 873 for (int i = 0; i < l; i += s) { 874 ShortVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask); 875 av.intoByteArray(r, i, ByteOrder.nativeOrder()); 876 } 877 } 878 879 int index = fi.apply(a.length); 880 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8); 881 try { 882 fromByteArray(a, index, ByteOrder.nativeOrder(), vmask); 883 if (shouldFail) { 884 Assert.fail("Failed to throw IndexOutOfBoundsException"); 885 } 886 } catch (IndexOutOfBoundsException e) { 887 if (!shouldFail) { 888 Assert.fail("Unexpected IndexOutOfBoundsException"); 889 } 890 } 891 } 892 893 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 894 static void storeByteArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 895 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 896 byte[] r = new byte[a.length]; 897 boolean[] mask = fm.apply(SPECIES.length()); 898 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 899 900 int s = SPECIES.vectorByteSize(); 901 int l = a.length; 902 903 for (int ic = 0; ic < INVOC_COUNT; ic++) { 904 for (int i = 0; i < l; i += s) { 905 ShortVector av = ShortVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder()); 906 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask); 907 } 908 } 909 910 int index = fi.apply(a.length); 911 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8); 912 try { 913 ShortVector av = ShortVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder()); 914 intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask); 915 if (shouldFail) { 916 Assert.fail("Failed to throw IndexOutOfBoundsException"); 917 } 918 } catch (IndexOutOfBoundsException e) { 919 if (!shouldFail) { 920 Assert.fail("Unexpected IndexOutOfBoundsException"); 921 } 922 } 923 } 924 925 @Test(dataProvider = "maskProvider") 926 static void loadStoreMask(IntFunction<boolean[]> fm) { 927 boolean[] a = fm.apply(SPECIES.length()); 928 boolean[] r = new boolean[a.length]; 929 930 for (int ic = 0; ic < INVOC_COUNT; ic++) { 931 for (int i = 0; i < a.length; i += SPECIES.length()) { 932 VectorMask<Short> vmask = SPECIES.loadMask(a, i); 933 vmask.intoArray(r, i); 934 } 935 } 936 Assert.assertEquals(r, a); 937 } 938 939 @Test 940 static void loadStoreShuffle() { 941 IntUnaryOperator fn = a -> a + 5; 942 for (int ic = 0; ic < INVOC_COUNT; ic++) { 943 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 944 int [] r = shuffle.toArray(); 945 946 int [] a = expectedShuffle(SPECIES.length(), fn); 947 Assert.assertEquals(r, a); 948 } 949 } 950 951 952 static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { 953 int i = 0; 954 try { 955 for (; i < a.length; i++) { 956 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); 957 } 958 } catch (AssertionError e) { 959 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); 960 } 961 } 962 963 static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of( 964 withToString("char[i * 5]", (int s) -> { 965 return fillChar(s * BUFFER_REPS, 966 i -> (char)(i * 5)); 967 }), 968 withToString("char[i + 1]", (int s) -> { 969 return fillChar(s * BUFFER_REPS, 970 i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); 971 }) 972 ); 973 974 @DataProvider 975 public Object[][] charProvider() { 976 return CHAR_GENERATORS.stream(). 977 map(f -> new Object[]{f}). 978 toArray(Object[][]::new); 979 } 980 981 @DataProvider 982 public Object[][] charProviderForIOOBE() { 983 var f = CHAR_GENERATORS.get(0); 984 return INDEX_GENERATORS.stream().map(fi -> { 985 return new Object[] {f, fi}; 986 }). 987 toArray(Object[][]::new); 988 } 989 990 @DataProvider 991 public Object[][] charMaskProvider() { 992 return BOOLEAN_MASK_GENERATORS.stream(). 993 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { 994 return new Object[] {fa, fm}; 995 })). 996 toArray(Object[][]::new); 997 } 998 999 @DataProvider 1000 public Object[][] charMaskProviderForIOOBE() { 1001 var f = CHAR_GENERATORS.get(0); 1002 return BOOLEAN_MASK_GENERATORS.stream(). 1003 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 1004 return new Object[] {f, fi, fm}; 1005 })). 1006 toArray(Object[][]::new); 1007 } 1008 1009 interface ToCharF { 1010 char apply(int i); 1011 } 1012 1013 static char[] fillChar(int s , ToCharF f) { 1014 return fillChar(new char[s], f); 1015 } 1016 1017 static char[] fillChar(char[] a, ToCharF f) { 1018 for (int i = 0; i < a.length; i++) { 1019 a[i] = f.apply(i); 1020 } 1021 return a; 1022 } 1023 1024 @DontInline 1025 static ShortVector fromCharArray(char[] a, int i) { 1026 return ShortVector.fromCharArray(SPECIES, a, i); 1027 } 1028 1029 @DontInline 1030 static ShortVector fromCharArray(char[] a, int i, VectorMask<Short> m) { 1031 return ShortVector.fromCharArray(SPECIES, a, i, m); 1032 } 1033 1034 @DontInline 1035 static void intoCharArray(ShortVector v, char[] a, int i) { 1036 v.intoCharArray(a, i); 1037 } 1038 1039 @DontInline 1040 static void intoCharArray(ShortVector v, char[] a, int i, VectorMask<Short> m) { 1041 v.intoCharArray(a, i, m); 1042 } 1043 1044 @Test(dataProvider = "charProvider") 1045 static void loadStoreCharArray(IntFunction<char[]> fa) { 1046 char[] a = fa.apply(SPECIES.length()); 1047 char[] r = new char[a.length]; 1048 1049 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1050 for (int i = 0; i < a.length; i += SPECIES.length()) { 1051 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1052 av.intoCharArray(r, i); 1053 } 1054 } 1055 Assert.assertEquals(a, r); 1056 } 1057 1058 @Test(dataProvider = "charProviderForIOOBE") 1059 static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 1060 char[] a = fa.apply(SPECIES.length()); 1061 char[] r = new char[a.length]; 1062 1063 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1064 for (int i = 0; i < a.length; i += SPECIES.length()) { 1065 ShortVector av = fromCharArray(a, i); 1066 av.intoCharArray(r, i); 1067 } 1068 } 1069 1070 int index = fi.apply(a.length); 1071 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 1072 try { 1073 fromCharArray(a, index); 1074 if (shouldFail) { 1075 Assert.fail("Failed to throw IndexOutOfBoundsException"); 1076 } 1077 } catch (IndexOutOfBoundsException e) { 1078 if (!shouldFail) { 1079 Assert.fail("Unexpected IndexOutOfBoundsException"); 1080 } 1081 } 1082 } 1083 1084 @Test(dataProvider = "charProviderForIOOBE") 1085 static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 1086 char[] a = fa.apply(SPECIES.length()); 1087 char[] r = new char[a.length]; 1088 1089 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1090 for (int i = 0; i < a.length; i += SPECIES.length()) { 1091 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1092 intoCharArray(av, r, i); 1093 } 1094 } 1095 1096 int index = fi.apply(a.length); 1097 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 1098 try { 1099 ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); 1100 intoCharArray(av, r, index); 1101 if (shouldFail) { 1102 Assert.fail("Failed to throw IndexOutOfBoundsException"); 1103 } 1104 } catch (IndexOutOfBoundsException e) { 1105 if (!shouldFail) { 1106 Assert.fail("Unexpected IndexOutOfBoundsException"); 1107 } 1108 } 1109 } 1110 1111 @Test(dataProvider = "charMaskProvider") 1112 static void loadStoreMaskCharArray(IntFunction<char[]> fa, 1113 IntFunction<boolean[]> fm) { 1114 char[] a = fa.apply(SPECIES.length()); 1115 char[] r = new char[a.length]; 1116 boolean[] mask = fm.apply(SPECIES.length()); 1117 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 1118 1119 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1120 for (int i = 0; i < a.length; i += SPECIES.length()) { 1121 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); 1122 av.intoCharArray(r, i); 1123 } 1124 } 1125 assertArraysEquals(a, r, mask); 1126 1127 1128 r = new char[a.length]; 1129 1130 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1131 for (int i = 0; i < a.length; i += SPECIES.length()) { 1132 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1133 av.intoCharArray(r, i, vmask); 1134 } 1135 } 1136 assertArraysEquals(a, r, mask); 1137 } 1138 1139 @Test(dataProvider = "charMaskProviderForIOOBE") 1140 static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 1141 char[] a = fa.apply(SPECIES.length()); 1142 char[] r = new char[a.length]; 1143 boolean[] mask = fm.apply(SPECIES.length()); 1144 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 1145 1146 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1147 for (int i = 0; i < a.length; i += SPECIES.length()) { 1148 ShortVector av = fromCharArray(a, i, vmask); 1149 av.intoCharArray(r, i); 1150 } 1151 } 1152 1153 int index = fi.apply(a.length); 1154 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 1155 try { 1156 fromCharArray(a, index, vmask); 1157 if (shouldFail) { 1158 Assert.fail("Failed to throw IndexOutOfBoundsException"); 1159 } 1160 } catch (IndexOutOfBoundsException e) { 1161 if (!shouldFail) { 1162 Assert.fail("Unexpected IndexOutOfBoundsException"); 1163 } 1164 } 1165 } 1166 1167 @Test(dataProvider = "charMaskProviderForIOOBE") 1168 static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 1169 char[] a = fa.apply(SPECIES.length()); 1170 char[] r = new char[a.length]; 1171 boolean[] mask = fm.apply(SPECIES.length()); 1172 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 1173 1174 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1175 for (int i = 0; i < a.length; i += SPECIES.length()) { 1176 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1177 intoCharArray(av, r, i, vmask); 1178 } 1179 } 1180 1181 int index = fi.apply(a.length); 1182 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 1183 try { 1184 ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); 1185 intoCharArray(av, a, index, vmask); 1186 if (shouldFail) { 1187 Assert.fail("Failed to throw IndexOutOfBoundsException"); 1188 } 1189 } catch (IndexOutOfBoundsException e) { 1190 if (!shouldFail) { 1191 Assert.fail("Unexpected IndexOutOfBoundsException"); 1192 } 1193 } 1194 } 1195 1196 1197 1198 1199 // Gather/Scatter load/store tests 1200 1201 static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap) { 1202 int i = 0; 1203 int j = 0; 1204 try { 1205 for (; i < a.length; i += SPECIES.length()) { 1206 j = i; 1207 for (; j < i + SPECIES.length(); j++) { 1208 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1209 } 1210 } 1211 } catch (AssertionError e) { 1212 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1213 } 1214 } 1215 1216 static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) { 1217 int i = 0; 1218 int j = 0; 1219 try { 1220 for (; i < a.length; i += SPECIES.length()) { 1221 j = i; 1222 for (; j < i + SPECIES.length(); j++) { 1223 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0); 1224 } 1225 } 1226 } catch (AssertionError e) { 1227 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0, "at index #" + j); 1228 } 1229 } 1230 1231 static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) { 1232 short[] expected = new short[r.length]; 1233 1234 // Store before checking, since the same location may be stored to more than once 1235 for (int i = 0; i < a.length; i += SPECIES.length()) { 1236 for (int j = i; j < i + SPECIES.length(); j++) { 1237 if (mask[j % SPECIES.length()]) { 1238 expected[i + indexMap[j]] = a[j]; 1239 } 1240 } 1241 } 1242 1243 Assert.assertEquals(r, expected); 1244 } 1245 1246 static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap) { 1247 short[] expected = new short[r.length]; 1248 1249 // Store before checking, since the same location may be stored to more than once 1250 for (int i = 0; i < a.length; i += SPECIES.length()) { 1251 for (int j = i; j < i + SPECIES.length(); j++) { 1252 expected[i + indexMap[j]] = a[j]; 1253 } 1254 } 1255 1256 Assert.assertEquals(r, expected); 1257 } 1258 1259 @DataProvider 1260 public Object[][] gatherScatterProvider() { 1261 return INT_INDEX_GENERATORS.stream(). 1262 flatMap(fs -> SHORT_GENERATORS.stream().map(fa -> { 1263 return new Object[] {fa, fs}; 1264 })). 1265 toArray(Object[][]::new); 1266 } 1267 1268 @DataProvider 1269 public Object[][] gatherScatterMaskProvider() { 1270 return BOOLEAN_MASK_GENERATORS.stream(). 1271 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1272 SHORT_GENERATORS.stream().map(fa -> { 1273 return new Object[] {fa, fm, fs}; 1274 }))). 1275 toArray(Object[][]::new); 1276 } 1277 1278 1279 @Test(dataProvider = "gatherScatterProvider") 1280 static void gather(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1281 short[] a = fa.apply(SPECIES.length()); 1282 int[] b = fs.apply(a.length, SPECIES.length()); 1283 short[] r = new short[a.length]; 1284 1285 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1286 for (int i = 0; i < a.length; i += SPECIES.length()) { 1287 ShortVector av = ShortVector.fromArray(SPECIES, a, i, b, i); 1288 av.intoArray(r, i); 1289 } 1290 } 1291 1292 assertGatherArraysEquals(r, a, b); 1293 } 1294 1295 @Test(dataProvider = "gatherScatterMaskProvider") 1296 static void gatherMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1297 short[] a = fa.apply(SPECIES.length()); 1298 int[] b = fs.apply(a.length, SPECIES.length()); 1299 short[] r = new short[a.length]; 1300 boolean[] mask = fm.apply(SPECIES.length()); 1301 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1302 1303 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1304 for (int i = 0; i < a.length; i += SPECIES.length()) { 1305 ShortVector av = ShortVector.fromArray(SPECIES, a, i, b, i, vmask); 1306 av.intoArray(r, i); 1307 } 1308 } 1309 1310 assertGatherArraysEquals(r, a, b, mask); 1311 } 1312 1313 @Test(dataProvider = "gatherScatterProvider") 1314 static void scatter(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1315 short[] a = fa.apply(SPECIES.length()); 1316 int[] b = fs.apply(a.length, SPECIES.length()); 1317 short[] r = new short[a.length]; 1318 1319 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1320 for (int i = 0; i < a.length; i += SPECIES.length()) { 1321 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 1322 av.intoArray(r, i, b, i); 1323 } 1324 } 1325 1326 assertScatterArraysEquals(r, a, b); 1327 } 1328 1329 @Test(dataProvider = "gatherScatterMaskProvider") 1330 static void scatterMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1331 short[] a = fa.apply(SPECIES.length()); 1332 int[] b = fs.apply(a.length, SPECIES.length()); 1333 short[] r = new short[a.length]; 1334 boolean[] mask = fm.apply(SPECIES.length()); 1335 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1336 1337 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1338 for (int i = 0; i < a.length; i += SPECIES.length()) { 1339 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 1340 av.intoArray(r, i, b, i, vmask); 1341 } 1342 } 1343 1344 assertScatterArraysEquals(r, a, b, mask); 1345 } 1346 1347 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) { 1348 int i = 0; 1349 int j = 0; 1350 try { 1351 for (; i < a.length; i += SPECIES.length()) { 1352 j = i; 1353 for (; j < i + SPECIES.length(); j++) { 1354 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1355 } 1356 } 1357 } catch (AssertionError e) { 1358 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1359 } 1360 } 1361 1362 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1363 int i = 0; 1364 int j = 0; 1365 try { 1366 for (; i < a.length; i += SPECIES.length()) { 1367 j = i; 1368 for (; j < i + SPECIES.length(); j++) { 1369 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0); 1370 } 1371 } 1372 } catch (AssertionError e) { 1373 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j); 1374 } 1375 } 1376 1377 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1378 char[] expected = new char[r.length]; 1379 1380 // Store before checking, since the same location may be stored to more than once 1381 for (int i = 0; i < a.length; i += SPECIES.length()) { 1382 for (int j = i; j < i + SPECIES.length(); j++) { 1383 if (mask[j % SPECIES.length()]) { 1384 expected[i + indexMap[j]] = a[j]; 1385 } 1386 } 1387 } 1388 1389 Assert.assertEquals(r, expected); 1390 } 1391 1392 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) { 1393 char[] expected = new char[r.length]; 1394 1395 // Store before checking, since the same location may be stored to more than once 1396 for (int i = 0; i < a.length; i += SPECIES.length()) { 1397 for (int j = i; j < i + SPECIES.length(); j++) { 1398 expected[i + indexMap[j]] = a[j]; 1399 } 1400 } 1401 1402 Assert.assertEquals(r, expected); 1403 } 1404 1405 @DataProvider 1406 public Object[][] charGatherScatterProvider() { 1407 return INT_INDEX_GENERATORS.stream(). 1408 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> { 1409 return new Object[] {fa, fs}; 1410 })). 1411 toArray(Object[][]::new); 1412 } 1413 1414 @DataProvider 1415 public Object[][] charGatherScatterMaskProvider() { 1416 return BOOLEAN_MASK_GENERATORS.stream(). 1417 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1418 CHAR_GENERATORS.stream().map(fa -> { 1419 return new Object[] {fa, fm, fs}; 1420 }))). 1421 toArray(Object[][]::new); 1422 } 1423 1424 1425 @Test(dataProvider = "charGatherScatterProvider") 1426 static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1427 char[] a = fa.apply(SPECIES.length()); 1428 int[] b = fs.apply(a.length, SPECIES.length()); 1429 char[] r = new char[a.length]; 1430 1431 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1432 for (int i = 0; i < a.length; i += SPECIES.length()) { 1433 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i); 1434 av.intoCharArray(r, i); 1435 } 1436 } 1437 1438 assertGatherArraysEquals(r, a, b); 1439 } 1440 1441 @Test(dataProvider = "charGatherScatterMaskProvider") 1442 static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1443 char[] a = fa.apply(SPECIES.length()); 1444 int[] b = fs.apply(a.length, SPECIES.length()); 1445 char[] r = new char[a.length]; 1446 boolean[] mask = fm.apply(SPECIES.length()); 1447 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1448 1449 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1450 for (int i = 0; i < a.length; i += SPECIES.length()) { 1451 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i, vmask); 1452 av.intoCharArray(r, i); 1453 } 1454 } 1455 1456 assertGatherArraysEquals(r, a, b, mask); 1457 } 1458 1459 @Test(dataProvider = "charGatherScatterProvider") 1460 static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1461 char[] a = fa.apply(SPECIES.length()); 1462 int[] b = fs.apply(a.length, SPECIES.length()); 1463 char[] r = new char[a.length]; 1464 1465 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1466 for (int i = 0; i < a.length; i += SPECIES.length()) { 1467 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1468 av.intoCharArray(r, i, b, i); 1469 } 1470 } 1471 1472 assertScatterArraysEquals(r, a, b); 1473 } 1474 1475 @Test(dataProvider = "charGatherScatterMaskProvider") 1476 static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1477 char[] a = fa.apply(SPECIES.length()); 1478 int[] b = fs.apply(a.length, SPECIES.length()); 1479 char[] r = new char[a.length]; 1480 boolean[] mask = fm.apply(SPECIES.length()); 1481 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1482 1483 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1484 for (int i = 0; i < a.length; i += SPECIES.length()) { 1485 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1486 av.intoCharArray(r, i, b, i, vmask); 1487 } 1488 } 1489 1490 assertScatterArraysEquals(r, a, b, mask); 1491 } 1492 1493 1494 }