1 /* 2 * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules jdk.incubator.vector java.base/jdk.internal.vm.annotation 27 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED 28 * -XX:-TieredCompilation IntMaxVectorLoadStoreTests 29 * 30 */ 31 32 // -- This file was mechanically generated: Do not edit! -- // 33 34 import java.lang.foreign.MemorySegment; 35 import java.lang.foreign.Arena; 36 import java.lang.foreign.ValueLayout; 37 import jdk.incubator.vector.IntVector; 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 IntMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest { 53 static final VectorSpecies<Integer> SPECIES = 54 IntVector.SPECIES_MAX; 55 56 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 57 58 static final ValueLayout.OfInt ELEMENT_LAYOUT = ValueLayout.JAVA_INT.withByteAlignment(1); 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(int[] r, int[] 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] : (int) 0); 73 } 74 } catch (AssertionError e) { 75 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (int) 0, "at index #" + i); 76 } 77 } 78 79 static final List<IntFunction<int[]>> INT_GENERATORS = List.of( 80 withToString("int[i * 5]", (int s) -> { 81 return fill(s * BUFFER_REPS, 82 i -> (int)(i * 5)); 83 }), 84 withToString("int[i + 1]", (int s) -> { 85 return fill(s * BUFFER_REPS, 86 i -> (((int)(i + 1) == 0) ? 1 : (int)(i + 1))); 87 }) 88 ); 89 90 // Relative to array.length 91 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 92 withToString("-1", (int l) -> { 93 return -1; 94 }), 95 withToString("l", (int l) -> { 96 return l; 97 }), 98 withToString("l - 1", (int l) -> { 99 return l - 1; 100 }), 101 withToString("l + 1", (int l) -> { 102 return l + 1; 103 }), 104 withToString("l - speciesl + 1", (int l) -> { 105 return l - SPECIES.length() + 1; 106 }), 107 withToString("l + speciesl - 1", (int l) -> { 108 return l + SPECIES.length() - 1; 109 }), 110 withToString("l + speciesl", (int l) -> { 111 return l + SPECIES.length(); 112 }), 113 withToString("l + speciesl + 1", (int l) -> { 114 return l + SPECIES.length() + 1; 115 }) 116 ); 117 118 // Relative to byte[] array.length or MemorySegment.byteSize() 119 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 120 withToString("-1", (int l) -> { 121 return -1; 122 }), 123 withToString("l", (int l) -> { 124 return l; 125 }), 126 withToString("l - 1", (int l) -> { 127 return l - 1; 128 }), 129 withToString("l + 1", (int l) -> { 130 return l + 1; 131 }), 132 withToString("l - speciesl*ebsize + 1", (int l) -> { 133 return l - SPECIES.vectorByteSize() + 1; 134 }), 135 withToString("l + speciesl*ebsize - 1", (int l) -> { 136 return l + SPECIES.vectorByteSize() - 1; 137 }), 138 withToString("l + speciesl*ebsize", (int l) -> { 139 return l + SPECIES.vectorByteSize(); 140 }), 141 withToString("l + speciesl*ebsize + 1", (int l) -> { 142 return l + SPECIES.vectorByteSize() + 1; 143 }) 144 ); 145 146 @DataProvider 147 public Object[][] intProvider() { 148 return INT_GENERATORS.stream(). 149 map(f -> new Object[]{f}). 150 toArray(Object[][]::new); 151 } 152 153 @DataProvider 154 public Object[][] maskProvider() { 155 return BOOLEAN_MASK_GENERATORS.stream(). 156 map(f -> new Object[]{f}). 157 toArray(Object[][]::new); 158 } 159 160 @DataProvider 161 public Object[][] intProviderForIOOBE() { 162 var f = INT_GENERATORS.get(0); 163 return INDEX_GENERATORS.stream().map(fi -> { 164 return new Object[] {f, fi}; 165 }). 166 toArray(Object[][]::new); 167 } 168 169 @DataProvider 170 public Object[][] intMaskProvider() { 171 return BOOLEAN_MASK_GENERATORS.stream(). 172 flatMap(fm -> INT_GENERATORS.stream().map(fa -> { 173 return new Object[] {fa, fm}; 174 })). 175 toArray(Object[][]::new); 176 } 177 178 @DataProvider 179 public Object[][] intMaskProviderForIOOBE() { 180 var f = INT_GENERATORS.get(0); 181 return BOOLEAN_MASK_GENERATORS.stream(). 182 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 183 return new Object[] {f, fi, fm}; 184 })). 185 toArray(Object[][]::new); 186 } 187 188 @DataProvider 189 public Object[][] intMemorySegmentProvider() { 190 return INT_GENERATORS.stream(). 191 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 192 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 193 return new Object[]{fa, fb, bo}; 194 }))). 195 toArray(Object[][]::new); 196 } 197 198 @DataProvider 199 public Object[][] intMemorySegmentMaskProvider() { 200 return BOOLEAN_MASK_GENERATORS.stream(). 201 flatMap(fm -> INT_GENERATORS.stream(). 202 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 203 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 204 return new Object[]{fa, fb, fm, bo}; 205 })))). 206 toArray(Object[][]::new); 207 } 208 209 @DataProvider 210 public Object[][] intByteProviderForIOOBE() { 211 var f = INT_GENERATORS.get(0); 212 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 213 return new Object[] {f, fi}; 214 }). 215 toArray(Object[][]::new); 216 } 217 218 @DataProvider 219 public Object[][] intByteMaskProviderForIOOBE() { 220 var f = INT_GENERATORS.get(0); 221 return BOOLEAN_MASK_GENERATORS.stream(). 222 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 223 return new Object[] {f, fi, fm}; 224 })). 225 toArray(Object[][]::new); 226 } 227 228 static MemorySegment toSegment(int[] a, IntFunction<MemorySegment> fb) { 229 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8); 230 for (int i = 0; i < a.length; i++) { 231 ms.set(ELEMENT_LAYOUT, i * SPECIES.elementSize() / 8 , a[i]); 232 } 233 return ms; 234 } 235 236 static int[] segmentToArray(MemorySegment ms) { 237 return ms.toArray(ELEMENT_LAYOUT); 238 } 239 240 241 interface ToIntF { 242 int apply(int i); 243 } 244 245 static int[] fill(int s , ToIntF f) { 246 return fill(new int[s], f); 247 } 248 249 static int[] fill(int[] a, ToIntF f) { 250 for (int i = 0; i < a.length; i++) { 251 a[i] = f.apply(i); 252 } 253 return a; 254 } 255 256 @DontInline 257 static IntVector fromArray(int[] a, int i) { 258 return IntVector.fromArray(SPECIES, a, i); 259 } 260 261 @DontInline 262 static IntVector fromArray(int[] a, int i, VectorMask<Integer> m) { 263 return IntVector.fromArray(SPECIES, a, i, m); 264 } 265 266 @DontInline 267 static void intoArray(IntVector v, int[] a, int i) { 268 v.intoArray(a, i); 269 } 270 271 @DontInline 272 static void intoArray(IntVector v, int[] a, int i, VectorMask<Integer> m) { 273 v.intoArray(a, i, m); 274 } 275 276 @DontInline 277 static IntVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 278 return IntVector.fromMemorySegment(SPECIES, a, i, bo); 279 } 280 281 @DontInline 282 static IntVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Integer> m) { 283 return IntVector.fromMemorySegment(SPECIES, a, i, bo, m); 284 } 285 286 @DontInline 287 static void intoMemorySegment(IntVector v, MemorySegment a, int i, ByteOrder bo) { 288 v.intoMemorySegment(a, i, bo); 289 } 290 291 @DontInline 292 static void intoMemorySegment(IntVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Integer> m) { 293 v.intoMemorySegment(a, i, bo, m); 294 } 295 296 @Test(dataProvider = "intProvider") 297 static void loadStoreArray(IntFunction<int[]> fa) { 298 int[] a = fa.apply(SPECIES.length()); 299 int[] r = new int[a.length]; 300 301 for (int ic = 0; ic < INVOC_COUNT; ic++) { 302 for (int i = 0; i < a.length; i += SPECIES.length()) { 303 IntVector av = IntVector.fromArray(SPECIES, a, i); 304 av.intoArray(r, i); 305 } 306 } 307 Assert.assertEquals(r, a); 308 } 309 310 @Test(dataProvider = "intProviderForIOOBE") 311 static void loadArrayIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi) { 312 int[] a = fa.apply(SPECIES.length()); 313 int[] r = new int[a.length]; 314 315 for (int ic = 0; ic < INVOC_COUNT; ic++) { 316 for (int i = 0; i < a.length; i += SPECIES.length()) { 317 IntVector av = fromArray(a, i); 318 av.intoArray(r, i); 319 } 320 } 321 322 int index = fi.apply(a.length); 323 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 324 try { 325 fromArray(a, index); 326 if (shouldFail) { 327 Assert.fail("Failed to throw IndexOutOfBoundsException"); 328 } 329 } catch (IndexOutOfBoundsException e) { 330 if (!shouldFail) { 331 Assert.fail("Unexpected IndexOutOfBoundsException"); 332 } 333 } 334 } 335 336 @Test(dataProvider = "intProviderForIOOBE") 337 static void storeArrayIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi) { 338 int[] a = fa.apply(SPECIES.length()); 339 int[] r = new int[a.length]; 340 341 for (int ic = 0; ic < INVOC_COUNT; ic++) { 342 for (int i = 0; i < a.length; i += SPECIES.length()) { 343 IntVector av = IntVector.fromArray(SPECIES, a, i); 344 intoArray(av, r, i); 345 } 346 } 347 348 int index = fi.apply(a.length); 349 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 350 try { 351 IntVector av = IntVector.fromArray(SPECIES, a, 0); 352 intoArray(av, r, index); 353 if (shouldFail) { 354 Assert.fail("Failed to throw IndexOutOfBoundsException"); 355 } 356 } catch (IndexOutOfBoundsException e) { 357 if (!shouldFail) { 358 Assert.fail("Unexpected IndexOutOfBoundsException"); 359 } 360 } 361 } 362 363 364 @Test(dataProvider = "intMaskProvider") 365 static void loadStoreMaskArray(IntFunction<int[]> fa, 366 IntFunction<boolean[]> fm) { 367 int[] a = fa.apply(SPECIES.length()); 368 int[] r = new int[a.length]; 369 boolean[] mask = fm.apply(SPECIES.length()); 370 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 371 372 for (int ic = 0; ic < INVOC_COUNT; ic++) { 373 for (int i = 0; i < a.length; i += SPECIES.length()) { 374 IntVector av = IntVector.fromArray(SPECIES, a, i, vmask); 375 av.intoArray(r, i); 376 } 377 } 378 assertArraysEquals(r, a, mask); 379 380 381 r = new int[a.length]; 382 383 for (int ic = 0; ic < INVOC_COUNT; ic++) { 384 for (int i = 0; i < a.length; i += SPECIES.length()) { 385 IntVector av = IntVector.fromArray(SPECIES, a, i); 386 av.intoArray(r, i, vmask); 387 } 388 } 389 assertArraysEquals(r, a, mask); 390 } 391 392 @Test(dataProvider = "intMaskProviderForIOOBE") 393 static void loadArrayMaskIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 394 int[] a = fa.apply(SPECIES.length()); 395 int[] r = new int[a.length]; 396 boolean[] mask = fm.apply(SPECIES.length()); 397 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 398 399 for (int ic = 0; ic < INVOC_COUNT; ic++) { 400 for (int i = 0; i < a.length; i += SPECIES.length()) { 401 IntVector av = fromArray(a, i, vmask); 402 av.intoArray(r, i); 403 } 404 } 405 406 int index = fi.apply(a.length); 407 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 408 try { 409 fromArray(a, index, vmask); 410 if (shouldFail) { 411 Assert.fail("Failed to throw IndexOutOfBoundsException"); 412 } 413 } catch (IndexOutOfBoundsException e) { 414 if (!shouldFail) { 415 Assert.fail("Unexpected IndexOutOfBoundsException"); 416 } 417 } 418 } 419 420 @Test(dataProvider = "intMaskProviderForIOOBE") 421 static void storeArrayMaskIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 422 int[] a = fa.apply(SPECIES.length()); 423 int[] r = new int[a.length]; 424 boolean[] mask = fm.apply(SPECIES.length()); 425 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 426 427 for (int ic = 0; ic < INVOC_COUNT; ic++) { 428 for (int i = 0; i < a.length; i += SPECIES.length()) { 429 IntVector av = IntVector.fromArray(SPECIES, a, i); 430 intoArray(av, r, i, vmask); 431 } 432 } 433 434 int index = fi.apply(a.length); 435 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 436 try { 437 IntVector av = IntVector.fromArray(SPECIES, a, 0); 438 intoArray(av, a, index, vmask); 439 if (shouldFail) { 440 Assert.fail("Failed to throw IndexOutOfBoundsException"); 441 } 442 } catch (IndexOutOfBoundsException e) { 443 if (!shouldFail) { 444 Assert.fail("Unexpected IndexOutOfBoundsException"); 445 } 446 } 447 } 448 449 450 @Test(dataProvider = "intMaskProvider") 451 static void loadStoreMask(IntFunction<int[]> fa, 452 IntFunction<boolean[]> fm) { 453 boolean[] mask = fm.apply(SPECIES.length()); 454 boolean[] r = new boolean[mask.length]; 455 456 for (int ic = 0; ic < INVOC_COUNT; ic++) { 457 for (int i = 0; i < mask.length; i += SPECIES.length()) { 458 VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, i); 459 vmask.intoArray(r, i); 460 } 461 } 462 Assert.assertEquals(r, mask); 463 } 464 465 466 @Test(dataProvider = "intMemorySegmentProvider") 467 static void loadStoreMemorySegment(IntFunction<int[]> fa, 468 IntFunction<MemorySegment> fb, 469 ByteOrder bo) { 470 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb); 471 MemorySegment r = fb.apply((int) a.byteSize()); 472 473 int l = (int) a.byteSize(); 474 int s = SPECIES.vectorByteSize(); 475 476 for (int ic = 0; ic < INVOC_COUNT; ic++) { 477 for (int i = 0; i < l; i += s) { 478 IntVector av = IntVector.fromMemorySegment(SPECIES, a, i, bo); 479 av.intoMemorySegment(r, i, bo); 480 } 481 } 482 long m = r.mismatch(a); 483 Assert.assertEquals(m, -1, "Segments not equal"); 484 } 485 486 @Test(dataProvider = "intByteProviderForIOOBE") 487 static void loadMemorySegmentIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi) { 488 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Integer.SIZE)); 489 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Integer.SIZE); 490 491 int l = (int) a.byteSize(); 492 int s = SPECIES.vectorByteSize(); 493 494 for (int ic = 0; ic < INVOC_COUNT; ic++) { 495 for (int i = 0; i < l; i += s) { 496 IntVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder()); 497 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 498 } 499 } 500 501 int index = fi.apply((int) a.byteSize()); 502 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 503 try { 504 fromMemorySegment(a, index, ByteOrder.nativeOrder()); 505 if (shouldFail) { 506 Assert.fail("Failed to throw IndexOutOfBoundsException"); 507 } 508 } catch (IndexOutOfBoundsException e) { 509 if (!shouldFail) { 510 Assert.fail("Unexpected IndexOutOfBoundsException"); 511 } 512 } 513 } 514 515 @Test(dataProvider = "intByteProviderForIOOBE") 516 static void storeMemorySegmentIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi) { 517 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Integer.SIZE)); 518 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Integer.SIZE); 519 520 int l = (int) a.byteSize(); 521 int s = SPECIES.vectorByteSize(); 522 523 for (int ic = 0; ic < INVOC_COUNT; ic++) { 524 for (int i = 0; i < l; i += s) { 525 IntVector av = IntVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 526 intoMemorySegment(av, r, i, ByteOrder.nativeOrder()); 527 } 528 } 529 530 int index = fi.apply((int) a.byteSize()); 531 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 532 try { 533 IntVector av = IntVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 534 intoMemorySegment(av, r, index, ByteOrder.nativeOrder()); 535 if (shouldFail) { 536 Assert.fail("Failed to throw IndexOutOfBoundsException"); 537 } 538 } catch (IndexOutOfBoundsException e) { 539 if (!shouldFail) { 540 Assert.fail("Unexpected IndexOutOfBoundsException"); 541 } 542 } 543 } 544 545 @Test(dataProvider = "intMemorySegmentMaskProvider") 546 static void loadStoreMemorySegmentMask(IntFunction<int[]> fa, 547 IntFunction<MemorySegment> fb, 548 IntFunction<boolean[]> fm, 549 ByteOrder bo) { 550 int[] _a = fa.apply(SPECIES.length()); 551 MemorySegment a = toSegment(_a, fb); 552 MemorySegment r = fb.apply((int) a.byteSize()); 553 boolean[] mask = fm.apply(SPECIES.length()); 554 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 555 556 int l = (int) a.byteSize(); 557 int s = SPECIES.vectorByteSize(); 558 559 for (int ic = 0; ic < INVOC_COUNT; ic++) { 560 for (int i = 0; i < l; i += s) { 561 IntVector av = IntVector.fromMemorySegment(SPECIES, a, i, bo, vmask); 562 av.intoMemorySegment(r, i, bo); 563 } 564 } 565 assertArraysEquals(segmentToArray(r), _a, mask); 566 567 568 r = fb.apply((int) a.byteSize()); 569 570 for (int ic = 0; ic < INVOC_COUNT; ic++) { 571 for (int i = 0; i < l; i += s) { 572 IntVector av = IntVector.fromMemorySegment(SPECIES, a, i, bo); 573 av.intoMemorySegment(r, i, bo, vmask); 574 } 575 } 576 assertArraysEquals(segmentToArray(r), _a, mask); 577 } 578 579 @Test(dataProvider = "intByteMaskProviderForIOOBE") 580 static void loadMemorySegmentMaskIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 581 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Integer.SIZE)); 582 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Integer.SIZE); 583 boolean[] mask = fm.apply(SPECIES.length()); 584 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 585 586 int l = (int) a.byteSize(); 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 IntVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask); 592 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 593 } 594 } 595 596 int index = fi.apply((int) a.byteSize()); 597 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 598 try { 599 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask); 600 if (shouldFail) { 601 Assert.fail("Failed to throw IndexOutOfBoundsException"); 602 } 603 } catch (IndexOutOfBoundsException e) { 604 if (!shouldFail) { 605 Assert.fail("Unexpected IndexOutOfBoundsException"); 606 } 607 } 608 } 609 610 @Test(dataProvider = "intByteMaskProviderForIOOBE") 611 static void storeMemorySegmentMaskIOOBE(IntFunction<int[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 612 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Integer.SIZE)); 613 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Integer.SIZE); 614 boolean[] mask = fm.apply(SPECIES.length()); 615 VectorMask<Integer> vmask = VectorMask.fromValues(SPECIES, mask); 616 617 int l = (int) a.byteSize(); 618 int s = SPECIES.vectorByteSize(); 619 620 for (int ic = 0; ic < INVOC_COUNT; ic++) { 621 for (int i = 0; i < l; i += s) { 622 IntVector av = IntVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 623 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask); 624 } 625 } 626 627 int index = fi.apply((int) a.byteSize()); 628 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 629 try { 630 IntVector av = IntVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 631 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask); 632 if (shouldFail) { 633 Assert.fail("Failed to throw IndexOutOfBoundsException"); 634 } 635 } catch (IndexOutOfBoundsException e) { 636 if (!shouldFail) { 637 Assert.fail("Unexpected IndexOutOfBoundsException"); 638 } 639 } 640 } 641 642 @Test(dataProvider = "intMemorySegmentProvider") 643 static void loadStoreReadonlyMemorySegment(IntFunction<int[]> fa, 644 IntFunction<MemorySegment> fb, 645 ByteOrder bo) { 646 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly(); 647 648 Assert.assertThrows( 649 UnsupportedOperationException.class, 650 () -> SPECIES.zero().intoMemorySegment(a, 0, bo) 651 ); 652 653 Assert.assertThrows( 654 UnsupportedOperationException.class, 655 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true)) 656 ); 657 658 Assert.assertThrows( 659 UnsupportedOperationException.class, 660 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false)) 661 ); 662 663 VectorMask<Integer> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 664 .laneIsValid(); 665 Assert.assertThrows( 666 UnsupportedOperationException.class, 667 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m) 668 ); 669 } 670 671 672 @Test(dataProvider = "maskProvider") 673 static void loadStoreMask(IntFunction<boolean[]> fm) { 674 boolean[] a = fm.apply(SPECIES.length()); 675 boolean[] r = new boolean[a.length]; 676 677 for (int ic = 0; ic < INVOC_COUNT; ic++) { 678 for (int i = 0; i < a.length; i += SPECIES.length()) { 679 VectorMask<Integer> vmask = SPECIES.loadMask(a, i); 680 vmask.intoArray(r, i); 681 } 682 } 683 Assert.assertEquals(r, a); 684 } 685 686 687 @Test 688 static void loadStoreShuffle() { 689 IntUnaryOperator fn = a -> a + 5; 690 for (int ic = 0; ic < INVOC_COUNT; ic++) { 691 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 692 int [] r = shuffle.toArray(); 693 694 int [] a = expectedShuffle(SPECIES.length(), fn); 695 Assert.assertEquals(r, a); 696 } 697 } 698 699 700 701 702 703 // Gather/Scatter load/store tests 704 705 static void assertGatherArraysEquals(int[] r, int[] a, int[] indexMap) { 706 int i = 0; 707 int j = 0; 708 try { 709 for (; i < a.length; i += SPECIES.length()) { 710 j = i; 711 for (; j < i + SPECIES.length(); j++) { 712 Assert.assertEquals(r[j], a[i + indexMap[j]]); 713 } 714 } 715 } catch (AssertionError e) { 716 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 717 } 718 } 719 720 static void assertGatherArraysEquals(int[] r, int[] a, int[] indexMap, boolean[] mask) { 721 int i = 0; 722 int j = 0; 723 try { 724 for (; i < a.length; i += SPECIES.length()) { 725 j = i; 726 for (; j < i + SPECIES.length(); j++) { 727 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (int) 0); 728 } 729 } 730 } catch (AssertionError e) { 731 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (int) 0, "at index #" + j); 732 } 733 } 734 735 static void assertScatterArraysEquals(int[] r, int[] a, int[] indexMap, boolean[] mask) { 736 int[] expected = new int[r.length]; 737 738 // Store before checking, since the same location may be stored to more than once 739 for (int i = 0; i < a.length; i += SPECIES.length()) { 740 for (int j = i; j < i + SPECIES.length(); j++) { 741 if (mask[j % SPECIES.length()]) { 742 expected[i + indexMap[j]] = a[j]; 743 } 744 } 745 } 746 747 Assert.assertEquals(r, expected); 748 } 749 750 static void assertScatterArraysEquals(int[] r, int[] a, int[] indexMap) { 751 int[] expected = new int[r.length]; 752 753 // Store before checking, since the same location may be stored to more than once 754 for (int i = 0; i < a.length; i += SPECIES.length()) { 755 for (int j = i; j < i + SPECIES.length(); j++) { 756 expected[i + indexMap[j]] = a[j]; 757 } 758 } 759 760 Assert.assertEquals(r, expected); 761 } 762 763 @DataProvider 764 public Object[][] gatherScatterProvider() { 765 return INT_INDEX_GENERATORS.stream(). 766 flatMap(fs -> INT_GENERATORS.stream().map(fa -> { 767 return new Object[] {fa, fs}; 768 })). 769 toArray(Object[][]::new); 770 } 771 772 @DataProvider 773 public Object[][] gatherScatterMaskProvider() { 774 return BOOLEAN_MASK_GENERATORS.stream(). 775 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 776 INT_GENERATORS.stream().map(fa -> { 777 return new Object[] {fa, fm, fs}; 778 }))). 779 toArray(Object[][]::new); 780 } 781 782 783 @Test(dataProvider = "gatherScatterProvider") 784 static void gather(IntFunction<int[]> fa, BiFunction<Integer,Integer,int[]> fs) { 785 int[] a = fa.apply(SPECIES.length()); 786 int[] b = fs.apply(a.length, SPECIES.length()); 787 int[] r = new int[a.length]; 788 789 for (int ic = 0; ic < INVOC_COUNT; ic++) { 790 for (int i = 0; i < a.length; i += SPECIES.length()) { 791 IntVector av = IntVector.fromArray(SPECIES, a, i, b, i); 792 av.intoArray(r, i); 793 } 794 } 795 796 assertGatherArraysEquals(r, a, b); 797 } 798 799 @Test(dataProvider = "gatherScatterMaskProvider") 800 static void gatherMask(IntFunction<int[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 801 int[] a = fa.apply(SPECIES.length()); 802 int[] b = fs.apply(a.length, SPECIES.length()); 803 int[] r = new int[a.length]; 804 boolean[] mask = fm.apply(SPECIES.length()); 805 VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0); 806 807 for (int ic = 0; ic < INVOC_COUNT; ic++) { 808 for (int i = 0; i < a.length; i += SPECIES.length()) { 809 IntVector av = IntVector.fromArray(SPECIES, a, i, b, i, vmask); 810 av.intoArray(r, i); 811 } 812 } 813 814 assertGatherArraysEquals(r, a, b, mask); 815 } 816 817 @Test(dataProvider = "gatherScatterProvider") 818 static void scatter(IntFunction<int[]> fa, BiFunction<Integer,Integer,int[]> fs) { 819 int[] a = fa.apply(SPECIES.length()); 820 int[] b = fs.apply(a.length, SPECIES.length()); 821 int[] r = new int[a.length]; 822 823 for (int ic = 0; ic < INVOC_COUNT; ic++) { 824 for (int i = 0; i < a.length; i += SPECIES.length()) { 825 IntVector av = IntVector.fromArray(SPECIES, a, i); 826 av.intoArray(r, i, b, i); 827 } 828 } 829 830 assertScatterArraysEquals(r, a, b); 831 } 832 833 @Test(dataProvider = "gatherScatterMaskProvider") 834 static void scatterMask(IntFunction<int[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 835 int[] a = fa.apply(SPECIES.length()); 836 int[] b = fs.apply(a.length, SPECIES.length()); 837 int[] r = new int[a.length]; 838 boolean[] mask = fm.apply(SPECIES.length()); 839 VectorMask<Integer> vmask = VectorMask.fromArray(SPECIES, mask, 0); 840 841 for (int ic = 0; ic < INVOC_COUNT; ic++) { 842 for (int i = 0; i < a.length; i += SPECIES.length()) { 843 IntVector av = IntVector.fromArray(SPECIES, a, i); 844 av.intoArray(r, i, b, i, vmask); 845 } 846 } 847 848 assertScatterArraysEquals(r, a, b, mask); 849 } 850 851 852 853 }