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 ByteMaxVectorLoadStoreTests 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.ByteVector; 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 ByteMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest { 53 static final VectorSpecies<Byte> SPECIES = 54 ByteVector.SPECIES_MAX; 55 56 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 57 58 static final ValueLayout.OfByte ELEMENT_LAYOUT = ValueLayout.JAVA_BYTE.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(byte[] r, byte[] 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] : (byte) 0); 73 } 74 } catch (AssertionError e) { 75 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i); 76 } 77 } 78 79 static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of( 80 withToString("byte[i * 5]", (int s) -> { 81 return fill(s * BUFFER_REPS, 82 i -> (byte)(i * 5)); 83 }), 84 withToString("byte[i + 1]", (int s) -> { 85 return fill(s * BUFFER_REPS, 86 i -> (((byte)(i + 1) == 0) ? 1 : (byte)(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[][] byteProvider() { 148 return BYTE_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[][] byteProviderForIOOBE() { 162 var f = BYTE_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[][] byteMaskProvider() { 171 return BOOLEAN_MASK_GENERATORS.stream(). 172 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> { 173 return new Object[] {fa, fm}; 174 })). 175 toArray(Object[][]::new); 176 } 177 178 @DataProvider 179 public Object[][] byteMaskProviderForIOOBE() { 180 var f = BYTE_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[][] byteMemorySegmentProvider() { 190 return BYTE_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[][] byteMemorySegmentMaskProvider() { 200 return BOOLEAN_MASK_GENERATORS.stream(). 201 flatMap(fm -> BYTE_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[][] byteByteProviderForIOOBE() { 211 var f = BYTE_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[][] byteByteMaskProviderForIOOBE() { 220 var f = BYTE_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(byte[] 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 byte[] segmentToArray(MemorySegment ms) { 237 return ms.toArray(ELEMENT_LAYOUT); 238 } 239 240 241 interface ToByteF { 242 byte apply(int i); 243 } 244 245 static byte[] fill(int s , ToByteF f) { 246 return fill(new byte[s], f); 247 } 248 249 static byte[] fill(byte[] a, ToByteF 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 ByteVector fromArray(byte[] a, int i) { 258 return ByteVector.fromArray(SPECIES, a, i); 259 } 260 261 @DontInline 262 static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) { 263 return ByteVector.fromArray(SPECIES, a, i, m); 264 } 265 266 @DontInline 267 static void intoArray(ByteVector v, byte[] a, int i) { 268 v.intoArray(a, i); 269 } 270 271 @DontInline 272 static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) { 273 v.intoArray(a, i, m); 274 } 275 276 @DontInline 277 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 278 return ByteVector.fromMemorySegment(SPECIES, a, i, bo); 279 } 280 281 @DontInline 282 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) { 283 return ByteVector.fromMemorySegment(SPECIES, a, i, bo, m); 284 } 285 286 @DontInline 287 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo) { 288 v.intoMemorySegment(a, i, bo); 289 } 290 291 @DontInline 292 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) { 293 v.intoMemorySegment(a, i, bo, m); 294 } 295 296 @Test(dataProvider = "byteProvider") 297 static void loadStoreArray(IntFunction<byte[]> fa) { 298 byte[] a = fa.apply(SPECIES.length()); 299 byte[] r = new byte[a.length]; 300 301 for (int ic = 0; ic < INVOC_COUNT; ic++) { 302 for (int i = 0; i < a.length; i += SPECIES.length()) { 303 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 304 av.intoArray(r, i); 305 } 306 } 307 Assert.assertEquals(r, a); 308 } 309 310 @Test(dataProvider = "byteProviderForIOOBE") 311 static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 312 byte[] a = fa.apply(SPECIES.length()); 313 byte[] r = new byte[a.length]; 314 315 for (int ic = 0; ic < INVOC_COUNT; ic++) { 316 for (int i = 0; i < a.length; i += SPECIES.length()) { 317 ByteVector 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 = "byteProviderForIOOBE") 337 static void storeArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 338 byte[] a = fa.apply(SPECIES.length()); 339 byte[] r = new byte[a.length]; 340 341 for (int ic = 0; ic < INVOC_COUNT; ic++) { 342 for (int i = 0; i < a.length; i += SPECIES.length()) { 343 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMaskProvider") 365 static void loadStoreMaskArray(IntFunction<byte[]> fa, 366 IntFunction<boolean[]> fm) { 367 byte[] a = fa.apply(SPECIES.length()); 368 byte[] r = new byte[a.length]; 369 boolean[] mask = fm.apply(SPECIES.length()); 370 VectorMask<Byte> 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 ByteVector av = ByteVector.fromArray(SPECIES, a, i, vmask); 375 av.intoArray(r, i); 376 } 377 } 378 assertArraysEquals(r, a, mask); 379 380 381 r = new byte[a.length]; 382 383 for (int ic = 0; ic < INVOC_COUNT; ic++) { 384 for (int i = 0; i < a.length; i += SPECIES.length()) { 385 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 386 av.intoArray(r, i, vmask); 387 } 388 } 389 assertArraysEquals(r, a, mask); 390 } 391 392 @Test(dataProvider = "byteMaskProviderForIOOBE") 393 static void loadArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 394 byte[] a = fa.apply(SPECIES.length()); 395 byte[] r = new byte[a.length]; 396 boolean[] mask = fm.apply(SPECIES.length()); 397 VectorMask<Byte> 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 ByteVector 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 = "byteMaskProviderForIOOBE") 421 static void storeArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 422 byte[] a = fa.apply(SPECIES.length()); 423 byte[] r = new byte[a.length]; 424 boolean[] mask = fm.apply(SPECIES.length()); 425 VectorMask<Byte> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMaskProvider") 451 static void loadStoreMask(IntFunction<byte[]> 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<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i); 459 vmask.intoArray(r, i); 460 } 461 } 462 Assert.assertEquals(r, mask); 463 } 464 465 466 @Test(dataProvider = "byteMemorySegmentProvider") 467 static void loadStoreMemorySegment(IntFunction<byte[]> 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 ByteVector av = ByteVector.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 = "byteByteProviderForIOOBE") 487 static void loadMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 488 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE)); 489 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.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 ByteVector 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 = "byteByteProviderForIOOBE") 516 static void storeMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 517 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE)); 518 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMemorySegmentMaskProvider") 546 static void loadStoreMemorySegmentMask(IntFunction<byte[]> fa, 547 IntFunction<MemorySegment> fb, 548 IntFunction<boolean[]> fm, 549 ByteOrder bo) { 550 byte[] _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<Byte> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteByteMaskProviderForIOOBE") 580 static void loadMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 581 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE)); 582 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE); 583 boolean[] mask = fm.apply(SPECIES.length()); 584 VectorMask<Byte> 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 ByteVector 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 = "byteByteMaskProviderForIOOBE") 611 static void storeMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 612 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, Byte.SIZE)); 613 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), Byte.SIZE); 614 boolean[] mask = fm.apply(SPECIES.length()); 615 VectorMask<Byte> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMemorySegmentProvider") 643 static void loadStoreReadonlyMemorySegment(IntFunction<byte[]> 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<Byte> 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<Byte> 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 static void assertArraysEquals(boolean[] r, byte[] a) { 702 int i = 0; 703 try { 704 for (; i < a.length; i++) { 705 Assert.assertEquals(r[i], (a[i] & 1) == 1); 706 } 707 } catch (AssertionError e) { 708 Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); 709 } 710 } 711 712 static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { 713 int i = 0; 714 try { 715 for (; i < a.length; i++) { 716 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); 717 } 718 } catch (AssertionError e) { 719 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); 720 } 721 } 722 723 static boolean[] convertToBooleanArray(byte[] a) { 724 boolean[] r = new boolean[a.length]; 725 726 for (int i = 0; i < a.length; i++) { 727 r[i] = (a[i] & 1) == 1; 728 } 729 730 return r; 731 } 732 733 @Test(dataProvider = "byteProvider") 734 static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) { 735 byte[] a = fa.apply(SPECIES.length()); 736 boolean[] r = new boolean[a.length]; 737 738 for (int ic = 0; ic < INVOC_COUNT; ic++) { 739 for (int i = 0; i < a.length; i += SPECIES.length()) { 740 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 741 av.intoBooleanArray(r, i); 742 } 743 } 744 assertArraysEquals(r, a); 745 } 746 747 @Test(dataProvider = "byteProvider") 748 static void loadStoreBooleanArray(IntFunction<byte[]> fa) { 749 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 750 boolean[] r = new boolean[a.length]; 751 752 for (int ic = 0; ic < INVOC_COUNT; ic++) { 753 for (int i = 0; i < a.length; i += SPECIES.length()) { 754 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 755 av.intoBooleanArray(r, i); 756 } 757 } 758 Assert.assertEquals(r, a); 759 } 760 761 @Test(dataProvider = "byteMaskProvider") 762 static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa, 763 IntFunction<boolean[]> fm) { 764 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 765 boolean[] r = new boolean[a.length]; 766 boolean[] mask = fm.apply(SPECIES.length()); 767 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 768 769 for (int ic = 0; ic < INVOC_COUNT; ic++) { 770 for (int i = 0; i < a.length; i += SPECIES.length()) { 771 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); 772 av.intoBooleanArray(r, i); 773 } 774 } 775 assertArraysEquals(r, a, mask); 776 777 778 r = new boolean[a.length]; 779 780 for (int ic = 0; ic < INVOC_COUNT; ic++) { 781 for (int i = 0; i < a.length; i += SPECIES.length()) { 782 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 783 av.intoBooleanArray(r, i, vmask); 784 } 785 } 786 assertArraysEquals(r, a, mask); 787 } 788 789 790 // Gather/Scatter load/store tests 791 792 static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap) { 793 int i = 0; 794 int j = 0; 795 try { 796 for (; i < a.length; i += SPECIES.length()) { 797 j = i; 798 for (; j < i + SPECIES.length(); j++) { 799 Assert.assertEquals(r[j], a[i + indexMap[j]]); 800 } 801 } 802 } catch (AssertionError e) { 803 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 804 } 805 } 806 807 static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) { 808 int i = 0; 809 int j = 0; 810 try { 811 for (; i < a.length; i += SPECIES.length()) { 812 j = i; 813 for (; j < i + SPECIES.length(); j++) { 814 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0); 815 } 816 } 817 } catch (AssertionError e) { 818 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0, "at index #" + j); 819 } 820 } 821 822 static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) { 823 byte[] expected = new byte[r.length]; 824 825 // Store before checking, since the same location may be stored to more than once 826 for (int i = 0; i < a.length; i += SPECIES.length()) { 827 for (int j = i; j < i + SPECIES.length(); j++) { 828 if (mask[j % SPECIES.length()]) { 829 expected[i + indexMap[j]] = a[j]; 830 } 831 } 832 } 833 834 Assert.assertEquals(r, expected); 835 } 836 837 static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap) { 838 byte[] expected = new byte[r.length]; 839 840 // Store before checking, since the same location may be stored to more than once 841 for (int i = 0; i < a.length; i += SPECIES.length()) { 842 for (int j = i; j < i + SPECIES.length(); j++) { 843 expected[i + indexMap[j]] = a[j]; 844 } 845 } 846 847 Assert.assertEquals(r, expected); 848 } 849 850 @DataProvider 851 public Object[][] gatherScatterProvider() { 852 return INT_INDEX_GENERATORS.stream(). 853 flatMap(fs -> BYTE_GENERATORS.stream().map(fa -> { 854 return new Object[] {fa, fs}; 855 })). 856 toArray(Object[][]::new); 857 } 858 859 @DataProvider 860 public Object[][] gatherScatterMaskProvider() { 861 return BOOLEAN_MASK_GENERATORS.stream(). 862 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 863 BYTE_GENERATORS.stream().map(fa -> { 864 return new Object[] {fa, fm, fs}; 865 }))). 866 toArray(Object[][]::new); 867 } 868 869 870 @Test(dataProvider = "gatherScatterProvider") 871 static void gather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 872 byte[] a = fa.apply(SPECIES.length()); 873 int[] b = fs.apply(a.length, SPECIES.length()); 874 byte[] r = new byte[a.length]; 875 876 for (int ic = 0; ic < INVOC_COUNT; ic++) { 877 for (int i = 0; i < a.length; i += SPECIES.length()) { 878 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i); 879 av.intoArray(r, i); 880 } 881 } 882 883 assertGatherArraysEquals(r, a, b); 884 } 885 886 @Test(dataProvider = "gatherScatterMaskProvider") 887 static void gatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 888 byte[] a = fa.apply(SPECIES.length()); 889 int[] b = fs.apply(a.length, SPECIES.length()); 890 byte[] r = new byte[a.length]; 891 boolean[] mask = fm.apply(SPECIES.length()); 892 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 893 894 for (int ic = 0; ic < INVOC_COUNT; ic++) { 895 for (int i = 0; i < a.length; i += SPECIES.length()) { 896 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i, vmask); 897 av.intoArray(r, i); 898 } 899 } 900 901 assertGatherArraysEquals(r, a, b, mask); 902 } 903 904 @Test(dataProvider = "gatherScatterProvider") 905 static void scatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 906 byte[] a = fa.apply(SPECIES.length()); 907 int[] b = fs.apply(a.length, SPECIES.length()); 908 byte[] r = new byte[a.length]; 909 910 for (int ic = 0; ic < INVOC_COUNT; ic++) { 911 for (int i = 0; i < a.length; i += SPECIES.length()) { 912 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 913 av.intoArray(r, i, b, i); 914 } 915 } 916 917 assertScatterArraysEquals(r, a, b); 918 } 919 920 @Test(dataProvider = "gatherScatterMaskProvider") 921 static void scatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 922 byte[] a = fa.apply(SPECIES.length()); 923 int[] b = fs.apply(a.length, SPECIES.length()); 924 byte[] r = new byte[a.length]; 925 boolean[] mask = fm.apply(SPECIES.length()); 926 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 927 928 for (int ic = 0; ic < INVOC_COUNT; ic++) { 929 for (int i = 0; i < a.length; i += SPECIES.length()) { 930 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 931 av.intoArray(r, i, b, i, vmask); 932 } 933 } 934 935 assertScatterArraysEquals(r, a, b, mask); 936 } 937 938 939 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 940 int i = 0; 941 int j = 0; 942 try { 943 for (; i < a.length; i += SPECIES.length()) { 944 j = i; 945 for (; j < i + SPECIES.length(); j++) { 946 Assert.assertEquals(r[j], a[i + indexMap[j]]); 947 } 948 } 949 } catch (AssertionError e) { 950 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 951 } 952 } 953 954 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 955 int i = 0; 956 int j = 0; 957 try { 958 for (; i < a.length; i += SPECIES.length()) { 959 j = i; 960 for (; j < i + SPECIES.length(); j++) { 961 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false); 962 } 963 } 964 } catch (AssertionError e) { 965 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j); 966 } 967 } 968 969 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 970 boolean[] expected = new boolean[r.length]; 971 972 // Store before checking, since the same location may be stored to more than once 973 for (int i = 0; i < a.length; i += SPECIES.length()) { 974 for (int j = i; j < i + SPECIES.length(); j++) { 975 if (mask[j % SPECIES.length()]) { 976 expected[i + indexMap[j]] = a[j]; 977 } 978 } 979 } 980 981 Assert.assertEquals(r, expected); 982 } 983 984 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 985 boolean[] expected = new boolean[r.length]; 986 987 // Store before checking, since the same location may be stored to more than once 988 for (int i = 0; i < a.length; i += SPECIES.length()) { 989 for (int j = i; j < i + SPECIES.length(); j++) { 990 expected[i + indexMap[j]] = a[j]; 991 } 992 } 993 994 Assert.assertEquals(r, expected); 995 } 996 997 @Test(dataProvider = "gatherScatterProvider") 998 static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 999 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1000 int[] b = fs.apply(a.length, SPECIES.length()); 1001 boolean[] r = new boolean[a.length]; 1002 1003 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1004 for (int i = 0; i < a.length; i += SPECIES.length()) { 1005 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i); 1006 av.intoBooleanArray(r, i); 1007 } 1008 } 1009 1010 assertGatherArraysEquals(r, a, b); 1011 } 1012 1013 @Test(dataProvider = "gatherScatterMaskProvider") 1014 static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1015 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1016 int[] b = fs.apply(a.length, SPECIES.length()); 1017 boolean[] r = new boolean[a.length]; 1018 boolean[] mask = fm.apply(SPECIES.length()); 1019 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1020 1021 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1022 for (int i = 0; i < a.length; i += SPECIES.length()) { 1023 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i, vmask); 1024 av.intoBooleanArray(r, i); 1025 } 1026 } 1027 1028 assertGatherArraysEquals(r, a, b, mask); 1029 } 1030 1031 @Test(dataProvider = "gatherScatterProvider") 1032 static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1033 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1034 int[] b = fs.apply(a.length, SPECIES.length()); 1035 boolean[] r = new boolean[a.length]; 1036 1037 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1038 for (int i = 0; i < a.length; i += SPECIES.length()) { 1039 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1040 av.intoBooleanArray(r, i, b, i); 1041 } 1042 } 1043 1044 assertScatterArraysEquals(r, a, b); 1045 } 1046 1047 @Test(dataProvider = "gatherScatterMaskProvider") 1048 static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1049 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1050 int[] b = fs.apply(a.length, SPECIES.length()); 1051 boolean[] r = new boolean[a.length]; 1052 boolean[] mask = fm.apply(SPECIES.length()); 1053 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1054 1055 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1056 for (int i = 0; i < a.length; i += SPECIES.length()) { 1057 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1058 av.intoBooleanArray(r, i, b, i, vmask); 1059 } 1060 } 1061 1062 assertScatterArraysEquals(r, a, b, mask); 1063 } 1064 1065 }