1 /* 2 * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules jdk.incubator.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.foreign.MemorySegment; 35 import jdk.incubator.foreign.ResourceScope; 36 import jdk.incubator.foreign.ValueLayout; 37 import jdk.incubator.vector.ShortVector; 38 import jdk.incubator.vector.VectorMask; 39 import jdk.incubator.vector.VectorShape; 40 import jdk.incubator.vector.VectorSpecies; 41 import jdk.incubator.vector.VectorShuffle; 42 import jdk.internal.vm.annotation.DontInline; 43 import org.testng.Assert; 44 import org.testng.annotations.DataProvider; 45 import org.testng.annotations.Test; 46 47 import java.nio.ByteOrder; 48 import java.util.List; 49 import java.util.function.*; 50 51 @Test 52 public class ShortMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest { 53 static final VectorSpecies<Short> SPECIES = 54 ShortVector.SPECIES_MAX; 55 56 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 57 58 static VectorShape getMaxBit() { 59 return VectorShape.S_Max_BIT; 60 } 61 62 private static final int Max = 256; // juts so we can do N/Max 63 64 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max); 65 66 static void assertArraysEquals(short[] r, short[] a, boolean[] mask) { 67 int i = 0; 68 try { 69 for (; i < a.length; i++) { 70 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0); 71 } 72 } catch (AssertionError e) { 73 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (short) 0, "at index #" + i); 74 } 75 } 76 77 static final List<IntFunction<short[]>> SHORT_GENERATORS = List.of( 78 withToString("short[i * 5]", (int s) -> { 79 return fill(s * BUFFER_REPS, 80 i -> (short)(i * 5)); 81 }), 82 withToString("short[i + 1]", (int s) -> { 83 return fill(s * BUFFER_REPS, 84 i -> (((short)(i + 1) == 0) ? 1 : (short)(i + 1))); 85 }) 86 ); 87 88 // Relative to array.length 89 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 90 withToString("-1", (int l) -> { 91 return -1; 92 }), 93 withToString("l", (int l) -> { 94 return l; 95 }), 96 withToString("l - 1", (int l) -> { 97 return l - 1; 98 }), 99 withToString("l + 1", (int l) -> { 100 return l + 1; 101 }), 102 withToString("l - speciesl + 1", (int l) -> { 103 return l - SPECIES.length() + 1; 104 }), 105 withToString("l + speciesl - 1", (int l) -> { 106 return l + SPECIES.length() - 1; 107 }), 108 withToString("l + speciesl", (int l) -> { 109 return l + SPECIES.length(); 110 }), 111 withToString("l + speciesl + 1", (int l) -> { 112 return l + SPECIES.length() + 1; 113 }) 114 ); 115 116 // Relative to byte[] array.length or MemorySegment.byteSize() 117 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 118 withToString("-1", (int l) -> { 119 return -1; 120 }), 121 withToString("l", (int l) -> { 122 return l; 123 }), 124 withToString("l - 1", (int l) -> { 125 return l - 1; 126 }), 127 withToString("l + 1", (int l) -> { 128 return l + 1; 129 }), 130 withToString("l - speciesl*ebsize + 1", (int l) -> { 131 return l - SPECIES.vectorByteSize() + 1; 132 }), 133 withToString("l + speciesl*ebsize - 1", (int l) -> { 134 return l + SPECIES.vectorByteSize() - 1; 135 }), 136 withToString("l + speciesl*ebsize", (int l) -> { 137 return l + SPECIES.vectorByteSize(); 138 }), 139 withToString("l + speciesl*ebsize + 1", (int l) -> { 140 return l + SPECIES.vectorByteSize() + 1; 141 }) 142 ); 143 144 @DataProvider 145 public Object[][] shortProvider() { 146 return SHORT_GENERATORS.stream(). 147 map(f -> new Object[]{f}). 148 toArray(Object[][]::new); 149 } 150 151 @DataProvider 152 public Object[][] maskProvider() { 153 return BOOLEAN_MASK_GENERATORS.stream(). 154 map(f -> new Object[]{f}). 155 toArray(Object[][]::new); 156 } 157 158 @DataProvider 159 public Object[][] shortProviderForIOOBE() { 160 var f = SHORT_GENERATORS.get(0); 161 return INDEX_GENERATORS.stream().map(fi -> { 162 return new Object[] {f, fi}; 163 }). 164 toArray(Object[][]::new); 165 } 166 167 @DataProvider 168 public Object[][] shortMaskProvider() { 169 return BOOLEAN_MASK_GENERATORS.stream(). 170 flatMap(fm -> SHORT_GENERATORS.stream().map(fa -> { 171 return new Object[] {fa, fm}; 172 })). 173 toArray(Object[][]::new); 174 } 175 176 @DataProvider 177 public Object[][] shortMaskProviderForIOOBE() { 178 var f = SHORT_GENERATORS.get(0); 179 return BOOLEAN_MASK_GENERATORS.stream(). 180 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 181 return new Object[] {f, fi, fm}; 182 })). 183 toArray(Object[][]::new); 184 } 185 186 @DataProvider 187 public Object[][] shortMemorySegmentProvider() { 188 return SHORT_GENERATORS.stream(). 189 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 190 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 191 return new Object[]{fa, fb, bo}; 192 }))). 193 toArray(Object[][]::new); 194 } 195 196 @DataProvider 197 public Object[][] shortMemorySegmentMaskProvider() { 198 return BOOLEAN_MASK_GENERATORS.stream(). 199 flatMap(fm -> SHORT_GENERATORS.stream(). 200 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 201 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 202 return new Object[]{fa, fb, fm, bo}; 203 })))). 204 toArray(Object[][]::new); 205 } 206 207 @DataProvider 208 public Object[][] shortByteProviderForIOOBE() { 209 var f = SHORT_GENERATORS.get(0); 210 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 211 return new Object[] {f, fi}; 212 }). 213 toArray(Object[][]::new); 214 } 215 216 @DataProvider 217 public Object[][] shortByteMaskProviderForIOOBE() { 218 var f = SHORT_GENERATORS.get(0); 219 return BOOLEAN_MASK_GENERATORS.stream(). 220 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 221 return new Object[] {f, fi, fm}; 222 })). 223 toArray(Object[][]::new); 224 } 225 226 static MemorySegment toSegment(short[] a, IntFunction<MemorySegment> fb) { 227 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8); 228 for (int i = 0; i < a.length; i++) { 229 ms.set(ValueLayout.JAVA_SHORT, i * SPECIES.elementSize() / 8 , a[i]); 230 } 231 return ms; 232 } 233 234 static short[] segmentToArray(MemorySegment ms) { 235 return ms.toArray(ValueLayout.JAVA_SHORT); 236 } 237 238 239 interface ToShortF { 240 short apply(int i); 241 } 242 243 static short[] fill(int s , ToShortF f) { 244 return fill(new short[s], f); 245 } 246 247 static short[] fill(short[] a, ToShortF f) { 248 for (int i = 0; i < a.length; i++) { 249 a[i] = f.apply(i); 250 } 251 return a; 252 } 253 254 @DontInline 255 static ShortVector fromArray(short[] a, int i) { 256 return ShortVector.fromArray(SPECIES, a, i); 257 } 258 259 @DontInline 260 static ShortVector fromArray(short[] a, int i, VectorMask<Short> m) { 261 return ShortVector.fromArray(SPECIES, a, i, m); 262 } 263 264 @DontInline 265 static void intoArray(ShortVector v, short[] a, int i) { 266 v.intoArray(a, i); 267 } 268 269 @DontInline 270 static void intoArray(ShortVector v, short[] a, int i, VectorMask<Short> m) { 271 v.intoArray(a, i, m); 272 } 273 274 @DontInline 275 static ShortVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 276 return ShortVector.fromMemorySegment(SPECIES, a, i, bo); 277 } 278 279 @DontInline 280 static ShortVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Short> m) { 281 return ShortVector.fromMemorySegment(SPECIES, a, i, bo, m); 282 } 283 284 @DontInline 285 static void intoMemorySegment(ShortVector v, MemorySegment a, int i, ByteOrder bo) { 286 v.intoMemorySegment(a, i, bo); 287 } 288 289 @DontInline 290 static void intoMemorySegment(ShortVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Short> m) { 291 v.intoMemorySegment(a, i, bo, m); 292 } 293 294 @Test(dataProvider = "shortProvider") 295 static void loadStoreArray(IntFunction<short[]> fa) { 296 short[] a = fa.apply(SPECIES.length()); 297 short[] r = new short[a.length]; 298 299 for (int ic = 0; ic < INVOC_COUNT; ic++) { 300 for (int i = 0; i < a.length; i += SPECIES.length()) { 301 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 302 av.intoArray(r, i); 303 } 304 } 305 Assert.assertEquals(r, a); 306 } 307 308 @Test(dataProvider = "shortProviderForIOOBE") 309 static void loadArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 310 short[] a = fa.apply(SPECIES.length()); 311 short[] r = new short[a.length]; 312 313 for (int ic = 0; ic < INVOC_COUNT; ic++) { 314 for (int i = 0; i < a.length; i += SPECIES.length()) { 315 ShortVector av = fromArray(a, i); 316 av.intoArray(r, i); 317 } 318 } 319 320 int index = fi.apply(a.length); 321 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 322 try { 323 fromArray(a, index); 324 if (shouldFail) { 325 Assert.fail("Failed to throw IndexOutOfBoundsException"); 326 } 327 } catch (IndexOutOfBoundsException e) { 328 if (!shouldFail) { 329 Assert.fail("Unexpected IndexOutOfBoundsException"); 330 } 331 } 332 } 333 334 @Test(dataProvider = "shortProviderForIOOBE") 335 static void storeArrayIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 336 short[] a = fa.apply(SPECIES.length()); 337 short[] r = new short[a.length]; 338 339 for (int ic = 0; ic < INVOC_COUNT; ic++) { 340 for (int i = 0; i < a.length; i += SPECIES.length()) { 341 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 342 intoArray(av, r, i); 343 } 344 } 345 346 int index = fi.apply(a.length); 347 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 348 try { 349 ShortVector av = ShortVector.fromArray(SPECIES, a, 0); 350 intoArray(av, r, index); 351 if (shouldFail) { 352 Assert.fail("Failed to throw IndexOutOfBoundsException"); 353 } 354 } catch (IndexOutOfBoundsException e) { 355 if (!shouldFail) { 356 Assert.fail("Unexpected IndexOutOfBoundsException"); 357 } 358 } 359 } 360 361 362 @Test(dataProvider = "shortMaskProvider") 363 static void loadStoreMaskArray(IntFunction<short[]> fa, 364 IntFunction<boolean[]> fm) { 365 short[] a = fa.apply(SPECIES.length()); 366 short[] r = new short[a.length]; 367 boolean[] mask = fm.apply(SPECIES.length()); 368 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 369 370 for (int ic = 0; ic < INVOC_COUNT; ic++) { 371 for (int i = 0; i < a.length; i += SPECIES.length()) { 372 ShortVector av = ShortVector.fromArray(SPECIES, a, i, vmask); 373 av.intoArray(r, i); 374 } 375 } 376 assertArraysEquals(r, a, mask); 377 378 379 r = new short[a.length]; 380 381 for (int ic = 0; ic < INVOC_COUNT; ic++) { 382 for (int i = 0; i < a.length; i += SPECIES.length()) { 383 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 384 av.intoArray(r, i, vmask); 385 } 386 } 387 assertArraysEquals(r, a, mask); 388 } 389 390 @Test(dataProvider = "shortMaskProviderForIOOBE") 391 static void loadArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 392 short[] a = fa.apply(SPECIES.length()); 393 short[] r = new short[a.length]; 394 boolean[] mask = fm.apply(SPECIES.length()); 395 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 396 397 for (int ic = 0; ic < INVOC_COUNT; ic++) { 398 for (int i = 0; i < a.length; i += SPECIES.length()) { 399 ShortVector av = fromArray(a, i, vmask); 400 av.intoArray(r, i); 401 } 402 } 403 404 int index = fi.apply(a.length); 405 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 406 try { 407 fromArray(a, index, vmask); 408 if (shouldFail) { 409 Assert.fail("Failed to throw IndexOutOfBoundsException"); 410 } 411 } catch (IndexOutOfBoundsException e) { 412 if (!shouldFail) { 413 Assert.fail("Unexpected IndexOutOfBoundsException"); 414 } 415 } 416 } 417 418 @Test(dataProvider = "shortMaskProviderForIOOBE") 419 static void storeArrayMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 420 short[] a = fa.apply(SPECIES.length()); 421 short[] r = new short[a.length]; 422 boolean[] mask = fm.apply(SPECIES.length()); 423 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 424 425 for (int ic = 0; ic < INVOC_COUNT; ic++) { 426 for (int i = 0; i < a.length; i += SPECIES.length()) { 427 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 428 intoArray(av, r, i, vmask); 429 } 430 } 431 432 int index = fi.apply(a.length); 433 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 434 try { 435 ShortVector av = ShortVector.fromArray(SPECIES, a, 0); 436 intoArray(av, a, index, vmask); 437 if (shouldFail) { 438 Assert.fail("Failed to throw IndexOutOfBoundsException"); 439 } 440 } catch (IndexOutOfBoundsException e) { 441 if (!shouldFail) { 442 Assert.fail("Unexpected IndexOutOfBoundsException"); 443 } 444 } 445 } 446 447 448 @Test(dataProvider = "shortMaskProvider") 449 static void loadStoreMask(IntFunction<short[]> fa, 450 IntFunction<boolean[]> fm) { 451 boolean[] mask = fm.apply(SPECIES.length()); 452 boolean[] r = new boolean[mask.length]; 453 454 for (int ic = 0; ic < INVOC_COUNT; ic++) { 455 for (int i = 0; i < mask.length; i += SPECIES.length()) { 456 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, i); 457 vmask.intoArray(r, i); 458 } 459 } 460 Assert.assertEquals(r, mask); 461 } 462 463 464 @Test(dataProvider = "shortMemorySegmentProvider") 465 static void loadStoreMemorySegment(IntFunction<short[]> fa, 466 IntFunction<MemorySegment> fb, 467 ByteOrder bo) { 468 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb); 469 MemorySegment r = fb.apply((int) a.byteSize()); 470 471 int l = (int) a.byteSize(); 472 int s = SPECIES.vectorByteSize(); 473 474 for (int ic = 0; ic < INVOC_COUNT; ic++) { 475 for (int i = 0; i < l; i += s) { 476 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo); 477 av.intoMemorySegment(r, i, bo); 478 } 479 } 480 long m = r.mismatch(a); 481 Assert.assertEquals(m, -1, "Segments not equal"); 482 } 483 484 @Test(dataProvider = "shortByteProviderForIOOBE") 485 static void loadMemorySegmentIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 486 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 487 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 488 489 int l = (int) a.byteSize(); 490 int s = SPECIES.vectorByteSize(); 491 492 for (int ic = 0; ic < INVOC_COUNT; ic++) { 493 for (int i = 0; i < l; i += s) { 494 ShortVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder()); 495 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 496 } 497 } 498 499 int index = fi.apply((int) a.byteSize()); 500 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 501 try { 502 fromMemorySegment(a, index, ByteOrder.nativeOrder()); 503 if (shouldFail) { 504 Assert.fail("Failed to throw IndexOutOfBoundsException"); 505 } 506 } catch (IndexOutOfBoundsException e) { 507 if (!shouldFail) { 508 Assert.fail("Unexpected IndexOutOfBoundsException"); 509 } 510 } 511 } 512 513 @Test(dataProvider = "shortByteProviderForIOOBE") 514 static void storeMemorySegmentIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi) { 515 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 516 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 517 518 int l = (int) a.byteSize(); 519 int s = SPECIES.vectorByteSize(); 520 521 for (int ic = 0; ic < INVOC_COUNT; ic++) { 522 for (int i = 0; i < l; i += s) { 523 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 524 intoMemorySegment(av, r, i, ByteOrder.nativeOrder()); 525 } 526 } 527 528 int index = fi.apply((int) a.byteSize()); 529 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 530 try { 531 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 532 intoMemorySegment(av, r, index, ByteOrder.nativeOrder()); 533 if (shouldFail) { 534 Assert.fail("Failed to throw IndexOutOfBoundsException"); 535 } 536 } catch (IndexOutOfBoundsException e) { 537 if (!shouldFail) { 538 Assert.fail("Unexpected IndexOutOfBoundsException"); 539 } 540 } 541 } 542 543 @Test(dataProvider = "shortMemorySegmentMaskProvider") 544 static void loadStoreMemorySegmentMask(IntFunction<short[]> fa, 545 IntFunction<MemorySegment> fb, 546 IntFunction<boolean[]> fm, 547 ByteOrder bo) { 548 short[] _a = fa.apply(SPECIES.length()); 549 MemorySegment a = toSegment(_a, fb); 550 MemorySegment r = fb.apply((int) a.byteSize()); 551 boolean[] mask = fm.apply(SPECIES.length()); 552 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 553 554 int l = (int) a.byteSize(); 555 int s = SPECIES.vectorByteSize(); 556 557 for (int ic = 0; ic < INVOC_COUNT; ic++) { 558 for (int i = 0; i < l; i += s) { 559 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo, vmask); 560 av.intoMemorySegment(r, i, bo); 561 } 562 } 563 assertArraysEquals(segmentToArray(r), _a, mask); 564 565 566 r = fb.apply((int) a.byteSize()); 567 568 for (int ic = 0; ic < INVOC_COUNT; ic++) { 569 for (int i = 0; i < l; i += s) { 570 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, bo); 571 av.intoMemorySegment(r, i, bo, vmask); 572 } 573 } 574 assertArraysEquals(segmentToArray(r), _a, mask); 575 } 576 577 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 578 static void loadMemorySegmentMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 579 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 580 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 581 boolean[] mask = fm.apply(SPECIES.length()); 582 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 583 584 int l = (int) a.byteSize(); 585 int s = SPECIES.vectorByteSize(); 586 587 for (int ic = 0; ic < INVOC_COUNT; ic++) { 588 for (int i = 0; i < l; i += s) { 589 ShortVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask); 590 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 591 } 592 } 593 594 int index = fi.apply((int) a.byteSize()); 595 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 596 try { 597 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask); 598 if (shouldFail) { 599 Assert.fail("Failed to throw IndexOutOfBoundsException"); 600 } 601 } catch (IndexOutOfBoundsException e) { 602 if (!shouldFail) { 603 Assert.fail("Unexpected IndexOutOfBoundsException"); 604 } 605 } 606 } 607 608 @Test(dataProvider = "shortByteMaskProviderForIOOBE") 609 static void storeMemorySegmentMaskIOOBE(IntFunction<short[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 610 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 611 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 612 boolean[] mask = fm.apply(SPECIES.length()); 613 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 614 615 int l = (int) a.byteSize(); 616 int s = SPECIES.vectorByteSize(); 617 618 for (int ic = 0; ic < INVOC_COUNT; ic++) { 619 for (int i = 0; i < l; i += s) { 620 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 621 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask); 622 } 623 } 624 625 int index = fi.apply((int) a.byteSize()); 626 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 627 try { 628 ShortVector av = ShortVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 629 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask); 630 if (shouldFail) { 631 Assert.fail("Failed to throw IndexOutOfBoundsException"); 632 } 633 } catch (IndexOutOfBoundsException e) { 634 if (!shouldFail) { 635 Assert.fail("Unexpected IndexOutOfBoundsException"); 636 } 637 } 638 } 639 640 @Test(dataProvider = "shortMemorySegmentProvider") 641 static void loadStoreReadonlyMemorySegment(IntFunction<short[]> fa, 642 IntFunction<MemorySegment> fb, 643 ByteOrder bo) { 644 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly(); 645 646 Assert.assertThrows( 647 UnsupportedOperationException.class, 648 () -> SPECIES.zero().intoMemorySegment(a, 0, bo) 649 ); 650 651 Assert.assertThrows( 652 UnsupportedOperationException.class, 653 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true)) 654 ); 655 656 Assert.assertThrows( 657 UnsupportedOperationException.class, 658 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false)) 659 ); 660 661 VectorMask<Short> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 662 .laneIsValid(); 663 Assert.assertThrows( 664 UnsupportedOperationException.class, 665 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m) 666 ); 667 } 668 669 670 @Test(dataProvider = "maskProvider") 671 static void loadStoreMask(IntFunction<boolean[]> fm) { 672 boolean[] a = fm.apply(SPECIES.length()); 673 boolean[] r = new boolean[a.length]; 674 675 for (int ic = 0; ic < INVOC_COUNT; ic++) { 676 for (int i = 0; i < a.length; i += SPECIES.length()) { 677 VectorMask<Short> vmask = SPECIES.loadMask(a, i); 678 vmask.intoArray(r, i); 679 } 680 } 681 Assert.assertEquals(r, a); 682 } 683 684 685 @Test 686 static void loadStoreShuffle() { 687 IntUnaryOperator fn = a -> a + 5; 688 for (int ic = 0; ic < INVOC_COUNT; ic++) { 689 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 690 int [] r = shuffle.toArray(); 691 692 int [] a = expectedShuffle(SPECIES.length(), fn); 693 Assert.assertEquals(r, a); 694 } 695 } 696 697 698 static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { 699 int i = 0; 700 try { 701 for (; i < a.length; i++) { 702 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); 703 } 704 } catch (AssertionError e) { 705 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); 706 } 707 } 708 709 static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of( 710 withToString("char[i * 5]", (int s) -> { 711 return fillChar(s * BUFFER_REPS, 712 i -> (char)(i * 5)); 713 }), 714 withToString("char[i + 1]", (int s) -> { 715 return fillChar(s * BUFFER_REPS, 716 i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); 717 }) 718 ); 719 720 @DataProvider 721 public Object[][] charProvider() { 722 return CHAR_GENERATORS.stream(). 723 map(f -> new Object[]{f}). 724 toArray(Object[][]::new); 725 } 726 727 @DataProvider 728 public Object[][] charProviderForIOOBE() { 729 var f = CHAR_GENERATORS.get(0); 730 return INDEX_GENERATORS.stream().map(fi -> { 731 return new Object[] {f, fi}; 732 }). 733 toArray(Object[][]::new); 734 } 735 736 @DataProvider 737 public Object[][] charMaskProvider() { 738 return BOOLEAN_MASK_GENERATORS.stream(). 739 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { 740 return new Object[] {fa, fm}; 741 })). 742 toArray(Object[][]::new); 743 } 744 745 @DataProvider 746 public Object[][] charMaskProviderForIOOBE() { 747 var f = CHAR_GENERATORS.get(0); 748 return BOOLEAN_MASK_GENERATORS.stream(). 749 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 750 return new Object[] {f, fi, fm}; 751 })). 752 toArray(Object[][]::new); 753 } 754 755 interface ToCharF { 756 char apply(int i); 757 } 758 759 static char[] fillChar(int s , ToCharF f) { 760 return fillChar(new char[s], f); 761 } 762 763 static char[] fillChar(char[] a, ToCharF f) { 764 for (int i = 0; i < a.length; i++) { 765 a[i] = f.apply(i); 766 } 767 return a; 768 } 769 770 @DontInline 771 static ShortVector fromCharArray(char[] a, int i) { 772 return ShortVector.fromCharArray(SPECIES, a, i); 773 } 774 775 @DontInline 776 static ShortVector fromCharArray(char[] a, int i, VectorMask<Short> m) { 777 return ShortVector.fromCharArray(SPECIES, a, i, m); 778 } 779 780 @DontInline 781 static void intoCharArray(ShortVector v, char[] a, int i) { 782 v.intoCharArray(a, i); 783 } 784 785 @DontInline 786 static void intoCharArray(ShortVector v, char[] a, int i, VectorMask<Short> m) { 787 v.intoCharArray(a, i, m); 788 } 789 790 @Test(dataProvider = "charProvider") 791 static void loadStoreCharArray(IntFunction<char[]> fa) { 792 char[] a = fa.apply(SPECIES.length()); 793 char[] r = new char[a.length]; 794 795 for (int ic = 0; ic < INVOC_COUNT; ic++) { 796 for (int i = 0; i < a.length; i += SPECIES.length()) { 797 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 798 av.intoCharArray(r, i); 799 } 800 } 801 Assert.assertEquals(a, r); 802 } 803 804 @Test(dataProvider = "charProviderForIOOBE") 805 static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 806 char[] a = fa.apply(SPECIES.length()); 807 char[] r = new char[a.length]; 808 809 for (int ic = 0; ic < INVOC_COUNT; ic++) { 810 for (int i = 0; i < a.length; i += SPECIES.length()) { 811 ShortVector av = fromCharArray(a, i); 812 av.intoCharArray(r, i); 813 } 814 } 815 816 int index = fi.apply(a.length); 817 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 818 try { 819 fromCharArray(a, index); 820 if (shouldFail) { 821 Assert.fail("Failed to throw IndexOutOfBoundsException"); 822 } 823 } catch (IndexOutOfBoundsException e) { 824 if (!shouldFail) { 825 Assert.fail("Unexpected IndexOutOfBoundsException"); 826 } 827 } 828 } 829 830 @Test(dataProvider = "charProviderForIOOBE") 831 static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 832 char[] a = fa.apply(SPECIES.length()); 833 char[] r = new char[a.length]; 834 835 for (int ic = 0; ic < INVOC_COUNT; ic++) { 836 for (int i = 0; i < a.length; i += SPECIES.length()) { 837 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 838 intoCharArray(av, r, i); 839 } 840 } 841 842 int index = fi.apply(a.length); 843 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 844 try { 845 ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); 846 intoCharArray(av, r, index); 847 if (shouldFail) { 848 Assert.fail("Failed to throw IndexOutOfBoundsException"); 849 } 850 } catch (IndexOutOfBoundsException e) { 851 if (!shouldFail) { 852 Assert.fail("Unexpected IndexOutOfBoundsException"); 853 } 854 } 855 } 856 857 @Test(dataProvider = "charMaskProvider") 858 static void loadStoreMaskCharArray(IntFunction<char[]> fa, 859 IntFunction<boolean[]> fm) { 860 char[] a = fa.apply(SPECIES.length()); 861 char[] r = new char[a.length]; 862 boolean[] mask = fm.apply(SPECIES.length()); 863 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 864 865 for (int ic = 0; ic < INVOC_COUNT; ic++) { 866 for (int i = 0; i < a.length; i += SPECIES.length()) { 867 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, vmask); 868 av.intoCharArray(r, i); 869 } 870 } 871 assertArraysEquals(a, r, mask); 872 873 874 r = new char[a.length]; 875 876 for (int ic = 0; ic < INVOC_COUNT; ic++) { 877 for (int i = 0; i < a.length; i += SPECIES.length()) { 878 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 879 av.intoCharArray(r, i, vmask); 880 } 881 } 882 assertArraysEquals(a, r, mask); 883 } 884 885 @Test(dataProvider = "charMaskProviderForIOOBE") 886 static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 887 char[] a = fa.apply(SPECIES.length()); 888 char[] r = new char[a.length]; 889 boolean[] mask = fm.apply(SPECIES.length()); 890 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 891 892 for (int ic = 0; ic < INVOC_COUNT; ic++) { 893 for (int i = 0; i < a.length; i += SPECIES.length()) { 894 ShortVector av = fromCharArray(a, i, vmask); 895 av.intoCharArray(r, i); 896 } 897 } 898 899 int index = fi.apply(a.length); 900 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 901 try { 902 fromCharArray(a, index, vmask); 903 if (shouldFail) { 904 Assert.fail("Failed to throw IndexOutOfBoundsException"); 905 } 906 } catch (IndexOutOfBoundsException e) { 907 if (!shouldFail) { 908 Assert.fail("Unexpected IndexOutOfBoundsException"); 909 } 910 } 911 } 912 913 @Test(dataProvider = "charMaskProviderForIOOBE") 914 static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 915 char[] a = fa.apply(SPECIES.length()); 916 char[] r = new char[a.length]; 917 boolean[] mask = fm.apply(SPECIES.length()); 918 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 919 920 for (int ic = 0; ic < INVOC_COUNT; ic++) { 921 for (int i = 0; i < a.length; i += SPECIES.length()) { 922 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 923 intoCharArray(av, r, i, vmask); 924 } 925 } 926 927 int index = fi.apply(a.length); 928 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 929 try { 930 ShortVector av = ShortVector.fromCharArray(SPECIES, a, 0); 931 intoCharArray(av, a, index, vmask); 932 if (shouldFail) { 933 Assert.fail("Failed to throw IndexOutOfBoundsException"); 934 } 935 } catch (IndexOutOfBoundsException e) { 936 if (!shouldFail) { 937 Assert.fail("Unexpected IndexOutOfBoundsException"); 938 } 939 } 940 } 941 942 943 944 945 // Gather/Scatter load/store tests 946 947 static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap) { 948 int i = 0; 949 int j = 0; 950 try { 951 for (; i < a.length; i += SPECIES.length()) { 952 j = i; 953 for (; j < i + SPECIES.length(); j++) { 954 Assert.assertEquals(r[j], a[i + indexMap[j]]); 955 } 956 } 957 } catch (AssertionError e) { 958 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 959 } 960 } 961 962 static void assertGatherArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) { 963 int i = 0; 964 int j = 0; 965 try { 966 for (; i < a.length; i += SPECIES.length()) { 967 j = i; 968 for (; j < i + SPECIES.length(); j++) { 969 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0); 970 } 971 } 972 } catch (AssertionError e) { 973 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (short) 0, "at index #" + j); 974 } 975 } 976 977 static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap, boolean[] mask) { 978 short[] expected = new short[r.length]; 979 980 // Store before checking, since the same location may be stored to more than once 981 for (int i = 0; i < a.length; i += SPECIES.length()) { 982 for (int j = i; j < i + SPECIES.length(); j++) { 983 if (mask[j % SPECIES.length()]) { 984 expected[i + indexMap[j]] = a[j]; 985 } 986 } 987 } 988 989 Assert.assertEquals(r, expected); 990 } 991 992 static void assertScatterArraysEquals(short[] r, short[] a, int[] indexMap) { 993 short[] expected = new short[r.length]; 994 995 // Store before checking, since the same location may be stored to more than once 996 for (int i = 0; i < a.length; i += SPECIES.length()) { 997 for (int j = i; j < i + SPECIES.length(); j++) { 998 expected[i + indexMap[j]] = a[j]; 999 } 1000 } 1001 1002 Assert.assertEquals(r, expected); 1003 } 1004 1005 @DataProvider 1006 public Object[][] gatherScatterProvider() { 1007 return INT_INDEX_GENERATORS.stream(). 1008 flatMap(fs -> SHORT_GENERATORS.stream().map(fa -> { 1009 return new Object[] {fa, fs}; 1010 })). 1011 toArray(Object[][]::new); 1012 } 1013 1014 @DataProvider 1015 public Object[][] gatherScatterMaskProvider() { 1016 return BOOLEAN_MASK_GENERATORS.stream(). 1017 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1018 SHORT_GENERATORS.stream().map(fa -> { 1019 return new Object[] {fa, fm, fs}; 1020 }))). 1021 toArray(Object[][]::new); 1022 } 1023 1024 1025 @Test(dataProvider = "gatherScatterProvider") 1026 static void gather(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1027 short[] a = fa.apply(SPECIES.length()); 1028 int[] b = fs.apply(a.length, SPECIES.length()); 1029 short[] r = new short[a.length]; 1030 1031 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1032 for (int i = 0; i < a.length; i += SPECIES.length()) { 1033 ShortVector av = ShortVector.fromArray(SPECIES, a, i, b, i); 1034 av.intoArray(r, i); 1035 } 1036 } 1037 1038 assertGatherArraysEquals(r, a, b); 1039 } 1040 1041 @Test(dataProvider = "gatherScatterMaskProvider") 1042 static void gatherMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1043 short[] a = fa.apply(SPECIES.length()); 1044 int[] b = fs.apply(a.length, SPECIES.length()); 1045 short[] r = new short[a.length]; 1046 boolean[] mask = fm.apply(SPECIES.length()); 1047 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 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.fromArray(SPECIES, a, i, b, i, vmask); 1052 av.intoArray(r, i); 1053 } 1054 } 1055 1056 assertGatherArraysEquals(r, a, b, mask); 1057 } 1058 1059 @Test(dataProvider = "gatherScatterProvider") 1060 static void scatter(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1061 short[] a = fa.apply(SPECIES.length()); 1062 int[] b = fs.apply(a.length, SPECIES.length()); 1063 short[] r = new short[a.length]; 1064 1065 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1066 for (int i = 0; i < a.length; i += SPECIES.length()) { 1067 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 1068 av.intoArray(r, i, b, i); 1069 } 1070 } 1071 1072 assertScatterArraysEquals(r, a, b); 1073 } 1074 1075 @Test(dataProvider = "gatherScatterMaskProvider") 1076 static void scatterMask(IntFunction<short[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1077 short[] a = fa.apply(SPECIES.length()); 1078 int[] b = fs.apply(a.length, SPECIES.length()); 1079 short[] r = new short[a.length]; 1080 boolean[] mask = fm.apply(SPECIES.length()); 1081 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1082 1083 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1084 for (int i = 0; i < a.length; i += SPECIES.length()) { 1085 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 1086 av.intoArray(r, i, b, i, vmask); 1087 } 1088 } 1089 1090 assertScatterArraysEquals(r, a, b, mask); 1091 } 1092 1093 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) { 1094 int i = 0; 1095 int j = 0; 1096 try { 1097 for (; i < a.length; i += SPECIES.length()) { 1098 j = i; 1099 for (; j < i + SPECIES.length(); j++) { 1100 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1101 } 1102 } 1103 } catch (AssertionError e) { 1104 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1105 } 1106 } 1107 1108 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1109 int i = 0; 1110 int j = 0; 1111 try { 1112 for (; i < a.length; i += SPECIES.length()) { 1113 j = i; 1114 for (; j < i + SPECIES.length(); j++) { 1115 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0); 1116 } 1117 } 1118 } catch (AssertionError e) { 1119 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j); 1120 } 1121 } 1122 1123 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1124 char[] expected = new char[r.length]; 1125 1126 // Store before checking, since the same location may be stored to more than once 1127 for (int i = 0; i < a.length; i += SPECIES.length()) { 1128 for (int j = i; j < i + SPECIES.length(); j++) { 1129 if (mask[j % SPECIES.length()]) { 1130 expected[i + indexMap[j]] = a[j]; 1131 } 1132 } 1133 } 1134 1135 Assert.assertEquals(r, expected); 1136 } 1137 1138 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) { 1139 char[] expected = new char[r.length]; 1140 1141 // Store before checking, since the same location may be stored to more than once 1142 for (int i = 0; i < a.length; i += SPECIES.length()) { 1143 for (int j = i; j < i + SPECIES.length(); j++) { 1144 expected[i + indexMap[j]] = a[j]; 1145 } 1146 } 1147 1148 Assert.assertEquals(r, expected); 1149 } 1150 1151 @DataProvider 1152 public Object[][] charGatherScatterProvider() { 1153 return INT_INDEX_GENERATORS.stream(). 1154 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> { 1155 return new Object[] {fa, fs}; 1156 })). 1157 toArray(Object[][]::new); 1158 } 1159 1160 @DataProvider 1161 public Object[][] charGatherScatterMaskProvider() { 1162 return BOOLEAN_MASK_GENERATORS.stream(). 1163 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1164 CHAR_GENERATORS.stream().map(fa -> { 1165 return new Object[] {fa, fm, fs}; 1166 }))). 1167 toArray(Object[][]::new); 1168 } 1169 1170 1171 @Test(dataProvider = "charGatherScatterProvider") 1172 static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1173 char[] a = fa.apply(SPECIES.length()); 1174 int[] b = fs.apply(a.length, SPECIES.length()); 1175 char[] r = new char[a.length]; 1176 1177 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1178 for (int i = 0; i < a.length; i += SPECIES.length()) { 1179 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i); 1180 av.intoCharArray(r, i); 1181 } 1182 } 1183 1184 assertGatherArraysEquals(r, a, b); 1185 } 1186 1187 @Test(dataProvider = "charGatherScatterMaskProvider") 1188 static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1189 char[] a = fa.apply(SPECIES.length()); 1190 int[] b = fs.apply(a.length, SPECIES.length()); 1191 char[] r = new char[a.length]; 1192 boolean[] mask = fm.apply(SPECIES.length()); 1193 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1194 1195 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1196 for (int i = 0; i < a.length; i += SPECIES.length()) { 1197 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i, b, i, vmask); 1198 av.intoCharArray(r, i); 1199 } 1200 } 1201 1202 assertGatherArraysEquals(r, a, b, mask); 1203 } 1204 1205 @Test(dataProvider = "charGatherScatterProvider") 1206 static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1207 char[] a = fa.apply(SPECIES.length()); 1208 int[] b = fs.apply(a.length, SPECIES.length()); 1209 char[] r = new char[a.length]; 1210 1211 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1212 for (int i = 0; i < a.length; i += SPECIES.length()) { 1213 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1214 av.intoCharArray(r, i, b, i); 1215 } 1216 } 1217 1218 assertScatterArraysEquals(r, a, b); 1219 } 1220 1221 @Test(dataProvider = "charGatherScatterMaskProvider") 1222 static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1223 char[] a = fa.apply(SPECIES.length()); 1224 int[] b = fs.apply(a.length, SPECIES.length()); 1225 char[] r = new char[a.length]; 1226 boolean[] mask = fm.apply(SPECIES.length()); 1227 VectorMask<Short> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1228 1229 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1230 for (int i = 0; i < a.length; i += SPECIES.length()) { 1231 ShortVector av = ShortVector.fromCharArray(SPECIES, a, i); 1232 av.intoCharArray(r, i, b, i, vmask); 1233 } 1234 } 1235 1236 assertScatterArraysEquals(r, a, b, mask); 1237 } 1238 1239 1240 }