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 -XX:-TieredCompilation Byte256VectorLoadStoreTests 28 * 29 */ 30 31 // -- This file was mechanically generated: Do not edit! -- // 32 33 import jdk.incubator.foreign.MemorySegment; 34 import jdk.incubator.foreign.ResourceScope; 35 import jdk.incubator.foreign.ValueLayout; 36 import jdk.incubator.vector.ByteVector; 37 import jdk.incubator.vector.VectorMask; 38 import jdk.incubator.vector.VectorSpecies; 39 import jdk.incubator.vector.VectorShuffle; 40 import jdk.internal.vm.annotation.DontInline; 41 import org.testng.Assert; 42 import org.testng.annotations.DataProvider; 43 import org.testng.annotations.Test; 44 45 import java.nio.ByteOrder; 46 import java.util.List; 47 import java.util.function.*; 48 49 @Test 50 public class Byte256VectorLoadStoreTests extends AbstractVectorLoadStoreTest { 51 static final VectorSpecies<Byte> SPECIES = 52 ByteVector.SPECIES_256; 53 54 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 55 56 57 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 256); 58 59 static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) { 60 int i = 0; 61 try { 62 for (; i < a.length; i++) { 63 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0); 64 } 65 } catch (AssertionError e) { 66 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i); 67 } 68 } 69 70 static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of( 71 withToString("byte[i * 5]", (int s) -> { 72 return fill(s * BUFFER_REPS, 73 i -> (byte)(i * 5)); 74 }), 75 withToString("byte[i + 1]", (int s) -> { 76 return fill(s * BUFFER_REPS, 77 i -> (((byte)(i + 1) == 0) ? 1 : (byte)(i + 1))); 78 }) 79 ); 80 81 // Relative to array.length 82 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 83 withToString("-1", (int l) -> { 84 return -1; 85 }), 86 withToString("l", (int l) -> { 87 return l; 88 }), 89 withToString("l - 1", (int l) -> { 90 return l - 1; 91 }), 92 withToString("l + 1", (int l) -> { 93 return l + 1; 94 }), 95 withToString("l - speciesl + 1", (int l) -> { 96 return l - SPECIES.length() + 1; 97 }), 98 withToString("l + speciesl - 1", (int l) -> { 99 return l + SPECIES.length() - 1; 100 }), 101 withToString("l + speciesl", (int l) -> { 102 return l + SPECIES.length(); 103 }), 104 withToString("l + speciesl + 1", (int l) -> { 105 return l + SPECIES.length() + 1; 106 }) 107 ); 108 109 // Relative to byte[] array.length or MemorySegment.byteSize() 110 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 111 withToString("-1", (int l) -> { 112 return -1; 113 }), 114 withToString("l", (int l) -> { 115 return l; 116 }), 117 withToString("l - 1", (int l) -> { 118 return l - 1; 119 }), 120 withToString("l + 1", (int l) -> { 121 return l + 1; 122 }), 123 withToString("l - speciesl*ebsize + 1", (int l) -> { 124 return l - SPECIES.vectorByteSize() + 1; 125 }), 126 withToString("l + speciesl*ebsize - 1", (int l) -> { 127 return l + SPECIES.vectorByteSize() - 1; 128 }), 129 withToString("l + speciesl*ebsize", (int l) -> { 130 return l + SPECIES.vectorByteSize(); 131 }), 132 withToString("l + speciesl*ebsize + 1", (int l) -> { 133 return l + SPECIES.vectorByteSize() + 1; 134 }) 135 ); 136 137 @DataProvider 138 public Object[][] byteProvider() { 139 return BYTE_GENERATORS.stream(). 140 map(f -> new Object[]{f}). 141 toArray(Object[][]::new); 142 } 143 144 @DataProvider 145 public Object[][] maskProvider() { 146 return BOOLEAN_MASK_GENERATORS.stream(). 147 map(f -> new Object[]{f}). 148 toArray(Object[][]::new); 149 } 150 151 @DataProvider 152 public Object[][] byteProviderForIOOBE() { 153 var f = BYTE_GENERATORS.get(0); 154 return INDEX_GENERATORS.stream().map(fi -> { 155 return new Object[] {f, fi}; 156 }). 157 toArray(Object[][]::new); 158 } 159 160 @DataProvider 161 public Object[][] byteMaskProvider() { 162 return BOOLEAN_MASK_GENERATORS.stream(). 163 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> { 164 return new Object[] {fa, fm}; 165 })). 166 toArray(Object[][]::new); 167 } 168 169 @DataProvider 170 public Object[][] byteMaskProviderForIOOBE() { 171 var f = BYTE_GENERATORS.get(0); 172 return BOOLEAN_MASK_GENERATORS.stream(). 173 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 174 return new Object[] {f, fi, fm}; 175 })). 176 toArray(Object[][]::new); 177 } 178 179 @DataProvider 180 public Object[][] byteMemorySegmentProvider() { 181 return BYTE_GENERATORS.stream(). 182 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 183 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 184 return new Object[]{fa, fb, bo}; 185 }))). 186 toArray(Object[][]::new); 187 } 188 189 @DataProvider 190 public Object[][] byteMemorySegmentMaskProvider() { 191 return BOOLEAN_MASK_GENERATORS.stream(). 192 flatMap(fm -> BYTE_GENERATORS.stream(). 193 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 194 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 195 return new Object[]{fa, fb, fm, bo}; 196 })))). 197 toArray(Object[][]::new); 198 } 199 200 @DataProvider 201 public Object[][] byteByteProviderForIOOBE() { 202 var f = BYTE_GENERATORS.get(0); 203 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 204 return new Object[] {f, fi}; 205 }). 206 toArray(Object[][]::new); 207 } 208 209 @DataProvider 210 public Object[][] byteByteMaskProviderForIOOBE() { 211 var f = BYTE_GENERATORS.get(0); 212 return BOOLEAN_MASK_GENERATORS.stream(). 213 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 214 return new Object[] {f, fi, fm}; 215 })). 216 toArray(Object[][]::new); 217 } 218 219 static MemorySegment toSegment(byte[] a, IntFunction<MemorySegment> fb) { 220 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8); 221 for (int i = 0; i < a.length; i++) { 222 ms.set(ValueLayout.JAVA_BYTE, i * SPECIES.elementSize() / 8 , a[i]); 223 } 224 return ms; 225 } 226 227 static byte[] segmentToArray(MemorySegment ms) { 228 return ms.toArray(ValueLayout.JAVA_BYTE); 229 } 230 231 232 interface ToByteF { 233 byte apply(int i); 234 } 235 236 static byte[] fill(int s , ToByteF f) { 237 return fill(new byte[s], f); 238 } 239 240 static byte[] fill(byte[] a, ToByteF f) { 241 for (int i = 0; i < a.length; i++) { 242 a[i] = f.apply(i); 243 } 244 return a; 245 } 246 247 @DontInline 248 static ByteVector fromArray(byte[] a, int i) { 249 return ByteVector.fromArray(SPECIES, a, i); 250 } 251 252 @DontInline 253 static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) { 254 return ByteVector.fromArray(SPECIES, a, i, m); 255 } 256 257 @DontInline 258 static void intoArray(ByteVector v, byte[] a, int i) { 259 v.intoArray(a, i); 260 } 261 262 @DontInline 263 static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) { 264 v.intoArray(a, i, m); 265 } 266 267 @DontInline 268 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 269 return ByteVector.fromMemorySegment(SPECIES, a, i, bo); 270 } 271 272 @DontInline 273 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) { 274 return ByteVector.fromMemorySegment(SPECIES, a, i, bo, m); 275 } 276 277 @DontInline 278 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo) { 279 v.intoMemorySegment(a, i, bo); 280 } 281 282 @DontInline 283 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) { 284 v.intoMemorySegment(a, i, bo, m); 285 } 286 287 @Test(dataProvider = "byteProvider") 288 static void loadStoreArray(IntFunction<byte[]> fa) { 289 byte[] a = fa.apply(SPECIES.length()); 290 byte[] r = new byte[a.length]; 291 292 for (int ic = 0; ic < INVOC_COUNT; ic++) { 293 for (int i = 0; i < a.length; i += SPECIES.length()) { 294 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 295 av.intoArray(r, i); 296 } 297 } 298 Assert.assertEquals(r, a); 299 } 300 301 @Test(dataProvider = "byteProviderForIOOBE") 302 static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 303 byte[] a = fa.apply(SPECIES.length()); 304 byte[] r = new byte[a.length]; 305 306 for (int ic = 0; ic < INVOC_COUNT; ic++) { 307 for (int i = 0; i < a.length; i += SPECIES.length()) { 308 ByteVector av = fromArray(a, i); 309 av.intoArray(r, i); 310 } 311 } 312 313 int index = fi.apply(a.length); 314 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 315 try { 316 fromArray(a, index); 317 if (shouldFail) { 318 Assert.fail("Failed to throw IndexOutOfBoundsException"); 319 } 320 } catch (IndexOutOfBoundsException e) { 321 if (!shouldFail) { 322 Assert.fail("Unexpected IndexOutOfBoundsException"); 323 } 324 } 325 } 326 327 @Test(dataProvider = "byteProviderForIOOBE") 328 static void storeArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 329 byte[] a = fa.apply(SPECIES.length()); 330 byte[] r = new byte[a.length]; 331 332 for (int ic = 0; ic < INVOC_COUNT; ic++) { 333 for (int i = 0; i < a.length; i += SPECIES.length()) { 334 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 335 intoArray(av, r, i); 336 } 337 } 338 339 int index = fi.apply(a.length); 340 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 341 try { 342 ByteVector av = ByteVector.fromArray(SPECIES, a, 0); 343 intoArray(av, r, index); 344 if (shouldFail) { 345 Assert.fail("Failed to throw IndexOutOfBoundsException"); 346 } 347 } catch (IndexOutOfBoundsException e) { 348 if (!shouldFail) { 349 Assert.fail("Unexpected IndexOutOfBoundsException"); 350 } 351 } 352 } 353 354 355 @Test(dataProvider = "byteMaskProvider") 356 static void loadStoreMaskArray(IntFunction<byte[]> fa, 357 IntFunction<boolean[]> fm) { 358 byte[] a = fa.apply(SPECIES.length()); 359 byte[] r = new byte[a.length]; 360 boolean[] mask = fm.apply(SPECIES.length()); 361 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 362 363 for (int ic = 0; ic < INVOC_COUNT; ic++) { 364 for (int i = 0; i < a.length; i += SPECIES.length()) { 365 ByteVector av = ByteVector.fromArray(SPECIES, a, i, vmask); 366 av.intoArray(r, i); 367 } 368 } 369 assertArraysEquals(r, a, mask); 370 371 372 r = new byte[a.length]; 373 374 for (int ic = 0; ic < INVOC_COUNT; ic++) { 375 for (int i = 0; i < a.length; i += SPECIES.length()) { 376 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 377 av.intoArray(r, i, vmask); 378 } 379 } 380 assertArraysEquals(r, a, mask); 381 } 382 383 @Test(dataProvider = "byteMaskProviderForIOOBE") 384 static void loadArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 385 byte[] a = fa.apply(SPECIES.length()); 386 byte[] r = new byte[a.length]; 387 boolean[] mask = fm.apply(SPECIES.length()); 388 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 389 390 for (int ic = 0; ic < INVOC_COUNT; ic++) { 391 for (int i = 0; i < a.length; i += SPECIES.length()) { 392 ByteVector av = fromArray(a, i, vmask); 393 av.intoArray(r, i); 394 } 395 } 396 397 int index = fi.apply(a.length); 398 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 399 try { 400 fromArray(a, index, vmask); 401 if (shouldFail) { 402 Assert.fail("Failed to throw IndexOutOfBoundsException"); 403 } 404 } catch (IndexOutOfBoundsException e) { 405 if (!shouldFail) { 406 Assert.fail("Unexpected IndexOutOfBoundsException"); 407 } 408 } 409 } 410 411 @Test(dataProvider = "byteMaskProviderForIOOBE") 412 static void storeArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 413 byte[] a = fa.apply(SPECIES.length()); 414 byte[] r = new byte[a.length]; 415 boolean[] mask = fm.apply(SPECIES.length()); 416 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 417 418 for (int ic = 0; ic < INVOC_COUNT; ic++) { 419 for (int i = 0; i < a.length; i += SPECIES.length()) { 420 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 421 intoArray(av, r, i, vmask); 422 } 423 } 424 425 int index = fi.apply(a.length); 426 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 427 try { 428 ByteVector av = ByteVector.fromArray(SPECIES, a, 0); 429 intoArray(av, a, index, vmask); 430 if (shouldFail) { 431 Assert.fail("Failed to throw IndexOutOfBoundsException"); 432 } 433 } catch (IndexOutOfBoundsException e) { 434 if (!shouldFail) { 435 Assert.fail("Unexpected IndexOutOfBoundsException"); 436 } 437 } 438 } 439 440 441 @Test(dataProvider = "byteMaskProvider") 442 static void loadStoreMask(IntFunction<byte[]> fa, 443 IntFunction<boolean[]> fm) { 444 boolean[] mask = fm.apply(SPECIES.length()); 445 boolean[] r = new boolean[mask.length]; 446 447 for (int ic = 0; ic < INVOC_COUNT; ic++) { 448 for (int i = 0; i < mask.length; i += SPECIES.length()) { 449 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i); 450 vmask.intoArray(r, i); 451 } 452 } 453 Assert.assertEquals(r, mask); 454 } 455 456 457 @Test(dataProvider = "byteMemorySegmentProvider") 458 static void loadStoreMemorySegment(IntFunction<byte[]> fa, 459 IntFunction<MemorySegment> fb, 460 ByteOrder bo) { 461 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb); 462 MemorySegment r = fb.apply((int) a.byteSize()); 463 464 int l = (int) a.byteSize(); 465 int s = SPECIES.vectorByteSize(); 466 467 for (int ic = 0; ic < INVOC_COUNT; ic++) { 468 for (int i = 0; i < l; i += s) { 469 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo); 470 av.intoMemorySegment(r, i, bo); 471 } 472 } 473 long m = r.mismatch(a); 474 Assert.assertEquals(m, -1, "Segments not equal"); 475 } 476 477 @Test(dataProvider = "byteByteProviderForIOOBE") 478 static void loadMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 479 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 480 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 481 482 int l = (int) a.byteSize(); 483 int s = SPECIES.vectorByteSize(); 484 485 for (int ic = 0; ic < INVOC_COUNT; ic++) { 486 for (int i = 0; i < l; i += s) { 487 ByteVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder()); 488 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 489 } 490 } 491 492 int index = fi.apply((int) a.byteSize()); 493 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 494 try { 495 fromMemorySegment(a, index, ByteOrder.nativeOrder()); 496 if (shouldFail) { 497 Assert.fail("Failed to throw IndexOutOfBoundsException"); 498 } 499 } catch (IndexOutOfBoundsException e) { 500 if (!shouldFail) { 501 Assert.fail("Unexpected IndexOutOfBoundsException"); 502 } 503 } 504 } 505 506 @Test(dataProvider = "byteByteProviderForIOOBE") 507 static void storeMemorySegmentIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) { 508 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 509 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 510 511 int l = (int) a.byteSize(); 512 int s = SPECIES.vectorByteSize(); 513 514 for (int ic = 0; ic < INVOC_COUNT; ic++) { 515 for (int i = 0; i < l; i += s) { 516 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 517 intoMemorySegment(av, r, i, ByteOrder.nativeOrder()); 518 } 519 } 520 521 int index = fi.apply((int) a.byteSize()); 522 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 523 try { 524 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 525 intoMemorySegment(av, r, index, ByteOrder.nativeOrder()); 526 if (shouldFail) { 527 Assert.fail("Failed to throw IndexOutOfBoundsException"); 528 } 529 } catch (IndexOutOfBoundsException e) { 530 if (!shouldFail) { 531 Assert.fail("Unexpected IndexOutOfBoundsException"); 532 } 533 } 534 } 535 536 @Test(dataProvider = "byteMemorySegmentMaskProvider") 537 static void loadStoreMemorySegmentMask(IntFunction<byte[]> fa, 538 IntFunction<MemorySegment> fb, 539 IntFunction<boolean[]> fm, 540 ByteOrder bo) { 541 byte[] _a = fa.apply(SPECIES.length()); 542 MemorySegment a = toSegment(_a, fb); 543 MemorySegment r = fb.apply((int) a.byteSize()); 544 boolean[] mask = fm.apply(SPECIES.length()); 545 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 546 547 int l = (int) a.byteSize(); 548 int s = SPECIES.vectorByteSize(); 549 550 for (int ic = 0; ic < INVOC_COUNT; ic++) { 551 for (int i = 0; i < l; i += s) { 552 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo, vmask); 553 av.intoMemorySegment(r, i, bo); 554 } 555 } 556 assertArraysEquals(segmentToArray(r), _a, mask); 557 558 559 r = fb.apply((int) a.byteSize()); 560 561 for (int ic = 0; ic < INVOC_COUNT; ic++) { 562 for (int i = 0; i < l; i += s) { 563 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, bo); 564 av.intoMemorySegment(r, i, bo, vmask); 565 } 566 } 567 assertArraysEquals(segmentToArray(r), _a, mask); 568 } 569 570 @Test(dataProvider = "byteByteMaskProviderForIOOBE") 571 static void loadMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 572 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 573 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 574 boolean[] mask = fm.apply(SPECIES.length()); 575 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 576 577 int l = (int) a.byteSize(); 578 int s = SPECIES.vectorByteSize(); 579 580 for (int ic = 0; ic < INVOC_COUNT; ic++) { 581 for (int i = 0; i < l; i += s) { 582 ByteVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask); 583 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 584 } 585 } 586 587 int index = fi.apply((int) a.byteSize()); 588 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 589 try { 590 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask); 591 if (shouldFail) { 592 Assert.fail("Failed to throw IndexOutOfBoundsException"); 593 } 594 } catch (IndexOutOfBoundsException e) { 595 if (!shouldFail) { 596 Assert.fail("Unexpected IndexOutOfBoundsException"); 597 } 598 } 599 } 600 601 @Test(dataProvider = "byteByteMaskProviderForIOOBE") 602 static void storeMemorySegmentMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 603 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 604 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 605 boolean[] mask = fm.apply(SPECIES.length()); 606 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 607 608 int l = (int) a.byteSize(); 609 int s = SPECIES.vectorByteSize(); 610 611 for (int ic = 0; ic < INVOC_COUNT; ic++) { 612 for (int i = 0; i < l; i += s) { 613 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 614 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask); 615 } 616 } 617 618 int index = fi.apply((int) a.byteSize()); 619 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 620 try { 621 ByteVector av = ByteVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 622 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask); 623 if (shouldFail) { 624 Assert.fail("Failed to throw IndexOutOfBoundsException"); 625 } 626 } catch (IndexOutOfBoundsException e) { 627 if (!shouldFail) { 628 Assert.fail("Unexpected IndexOutOfBoundsException"); 629 } 630 } 631 } 632 633 @Test(dataProvider = "byteMemorySegmentProvider") 634 static void loadStoreReadonlyMemorySegment(IntFunction<byte[]> fa, 635 IntFunction<MemorySegment> fb, 636 ByteOrder bo) { 637 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly(); 638 639 Assert.assertThrows( 640 UnsupportedOperationException.class, 641 () -> SPECIES.zero().intoMemorySegment(a, 0, bo) 642 ); 643 644 Assert.assertThrows( 645 UnsupportedOperationException.class, 646 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true)) 647 ); 648 649 Assert.assertThrows( 650 UnsupportedOperationException.class, 651 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false)) 652 ); 653 654 VectorMask<Byte> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 655 .laneIsValid(); 656 Assert.assertThrows( 657 UnsupportedOperationException.class, 658 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m) 659 ); 660 } 661 662 663 @Test(dataProvider = "maskProvider") 664 static void loadStoreMask(IntFunction<boolean[]> fm) { 665 boolean[] a = fm.apply(SPECIES.length()); 666 boolean[] r = new boolean[a.length]; 667 668 for (int ic = 0; ic < INVOC_COUNT; ic++) { 669 for (int i = 0; i < a.length; i += SPECIES.length()) { 670 VectorMask<Byte> vmask = SPECIES.loadMask(a, i); 671 vmask.intoArray(r, i); 672 } 673 } 674 Assert.assertEquals(r, a); 675 } 676 677 678 @Test 679 static void loadStoreShuffle() { 680 IntUnaryOperator fn = a -> a + 5; 681 for (int ic = 0; ic < INVOC_COUNT; ic++) { 682 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 683 int [] r = shuffle.toArray(); 684 685 int [] a = expectedShuffle(SPECIES.length(), fn); 686 Assert.assertEquals(r, a); 687 } 688 } 689 690 691 692 static void assertArraysEquals(boolean[] r, byte[] a) { 693 int i = 0; 694 try { 695 for (; i < a.length; i++) { 696 Assert.assertEquals(r[i], (a[i] & 1) == 1); 697 } 698 } catch (AssertionError e) { 699 Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); 700 } 701 } 702 703 static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { 704 int i = 0; 705 try { 706 for (; i < a.length; i++) { 707 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); 708 } 709 } catch (AssertionError e) { 710 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); 711 } 712 } 713 714 static boolean[] convertToBooleanArray(byte[] a) { 715 boolean[] r = new boolean[a.length]; 716 717 for (int i = 0; i < a.length; i++) { 718 r[i] = (a[i] & 1) == 1; 719 } 720 721 return r; 722 } 723 724 @Test(dataProvider = "byteProvider") 725 static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) { 726 byte[] a = fa.apply(SPECIES.length()); 727 boolean[] r = new boolean[a.length]; 728 729 for (int ic = 0; ic < INVOC_COUNT; ic++) { 730 for (int i = 0; i < a.length; i += SPECIES.length()) { 731 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 732 av.intoBooleanArray(r, i); 733 } 734 } 735 assertArraysEquals(r, a); 736 } 737 738 @Test(dataProvider = "byteProvider") 739 static void loadStoreBooleanArray(IntFunction<byte[]> fa) { 740 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 741 boolean[] r = new boolean[a.length]; 742 743 for (int ic = 0; ic < INVOC_COUNT; ic++) { 744 for (int i = 0; i < a.length; i += SPECIES.length()) { 745 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 746 av.intoBooleanArray(r, i); 747 } 748 } 749 Assert.assertEquals(r, a); 750 } 751 752 @Test(dataProvider = "byteMaskProvider") 753 static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa, 754 IntFunction<boolean[]> fm) { 755 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 756 boolean[] r = new boolean[a.length]; 757 boolean[] mask = fm.apply(SPECIES.length()); 758 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 759 760 for (int ic = 0; ic < INVOC_COUNT; ic++) { 761 for (int i = 0; i < a.length; i += SPECIES.length()) { 762 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); 763 av.intoBooleanArray(r, i); 764 } 765 } 766 assertArraysEquals(r, a, mask); 767 768 769 r = new boolean[a.length]; 770 771 for (int ic = 0; ic < INVOC_COUNT; ic++) { 772 for (int i = 0; i < a.length; i += SPECIES.length()) { 773 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 774 av.intoBooleanArray(r, i, vmask); 775 } 776 } 777 assertArraysEquals(r, a, mask); 778 } 779 780 781 // Gather/Scatter load/store tests 782 783 static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap) { 784 int i = 0; 785 int j = 0; 786 try { 787 for (; i < a.length; i += SPECIES.length()) { 788 j = i; 789 for (; j < i + SPECIES.length(); j++) { 790 Assert.assertEquals(r[j], a[i + indexMap[j]]); 791 } 792 } 793 } catch (AssertionError e) { 794 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 795 } 796 } 797 798 static void assertGatherArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) { 799 int i = 0; 800 int j = 0; 801 try { 802 for (; i < a.length; i += SPECIES.length()) { 803 j = i; 804 for (; j < i + SPECIES.length(); j++) { 805 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0); 806 } 807 } 808 } catch (AssertionError e) { 809 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (byte) 0, "at index #" + j); 810 } 811 } 812 813 static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap, boolean[] mask) { 814 byte[] expected = new byte[r.length]; 815 816 // Store before checking, since the same location may be stored to more than once 817 for (int i = 0; i < a.length; i += SPECIES.length()) { 818 for (int j = i; j < i + SPECIES.length(); j++) { 819 if (mask[j % SPECIES.length()]) { 820 expected[i + indexMap[j]] = a[j]; 821 } 822 } 823 } 824 825 Assert.assertEquals(r, expected); 826 } 827 828 static void assertScatterArraysEquals(byte[] r, byte[] a, int[] indexMap) { 829 byte[] expected = new byte[r.length]; 830 831 // Store before checking, since the same location may be stored to more than once 832 for (int i = 0; i < a.length; i += SPECIES.length()) { 833 for (int j = i; j < i + SPECIES.length(); j++) { 834 expected[i + indexMap[j]] = a[j]; 835 } 836 } 837 838 Assert.assertEquals(r, expected); 839 } 840 841 @DataProvider 842 public Object[][] gatherScatterProvider() { 843 return INT_INDEX_GENERATORS.stream(). 844 flatMap(fs -> BYTE_GENERATORS.stream().map(fa -> { 845 return new Object[] {fa, fs}; 846 })). 847 toArray(Object[][]::new); 848 } 849 850 @DataProvider 851 public Object[][] gatherScatterMaskProvider() { 852 return BOOLEAN_MASK_GENERATORS.stream(). 853 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 854 BYTE_GENERATORS.stream().map(fa -> { 855 return new Object[] {fa, fm, fs}; 856 }))). 857 toArray(Object[][]::new); 858 } 859 860 861 @Test(dataProvider = "gatherScatterProvider") 862 static void gather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 863 byte[] a = fa.apply(SPECIES.length()); 864 int[] b = fs.apply(a.length, SPECIES.length()); 865 byte[] r = new byte[a.length]; 866 867 for (int ic = 0; ic < INVOC_COUNT; ic++) { 868 for (int i = 0; i < a.length; i += SPECIES.length()) { 869 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i); 870 av.intoArray(r, i); 871 } 872 } 873 874 assertGatherArraysEquals(r, a, b); 875 } 876 877 @Test(dataProvider = "gatherScatterMaskProvider") 878 static void gatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 879 byte[] a = fa.apply(SPECIES.length()); 880 int[] b = fs.apply(a.length, SPECIES.length()); 881 byte[] r = new byte[a.length]; 882 boolean[] mask = fm.apply(SPECIES.length()); 883 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 884 885 for (int ic = 0; ic < INVOC_COUNT; ic++) { 886 for (int i = 0; i < a.length; i += SPECIES.length()) { 887 ByteVector av = ByteVector.fromArray(SPECIES, a, i, b, i, vmask); 888 av.intoArray(r, i); 889 } 890 } 891 892 assertGatherArraysEquals(r, a, b, mask); 893 } 894 895 @Test(dataProvider = "gatherScatterProvider") 896 static void scatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 897 byte[] a = fa.apply(SPECIES.length()); 898 int[] b = fs.apply(a.length, SPECIES.length()); 899 byte[] r = new byte[a.length]; 900 901 for (int ic = 0; ic < INVOC_COUNT; ic++) { 902 for (int i = 0; i < a.length; i += SPECIES.length()) { 903 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 904 av.intoArray(r, i, b, i); 905 } 906 } 907 908 assertScatterArraysEquals(r, a, b); 909 } 910 911 @Test(dataProvider = "gatherScatterMaskProvider") 912 static void scatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 913 byte[] a = fa.apply(SPECIES.length()); 914 int[] b = fs.apply(a.length, SPECIES.length()); 915 byte[] r = new byte[a.length]; 916 boolean[] mask = fm.apply(SPECIES.length()); 917 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 918 919 for (int ic = 0; ic < INVOC_COUNT; ic++) { 920 for (int i = 0; i < a.length; i += SPECIES.length()) { 921 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 922 av.intoArray(r, i, b, i, vmask); 923 } 924 } 925 926 assertScatterArraysEquals(r, a, b, mask); 927 } 928 929 930 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 931 int i = 0; 932 int j = 0; 933 try { 934 for (; i < a.length; i += SPECIES.length()) { 935 j = i; 936 for (; j < i + SPECIES.length(); j++) { 937 Assert.assertEquals(r[j], a[i + indexMap[j]]); 938 } 939 } 940 } catch (AssertionError e) { 941 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 942 } 943 } 944 945 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 946 int i = 0; 947 int j = 0; 948 try { 949 for (; i < a.length; i += SPECIES.length()) { 950 j = i; 951 for (; j < i + SPECIES.length(); j++) { 952 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false); 953 } 954 } 955 } catch (AssertionError e) { 956 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j); 957 } 958 } 959 960 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 961 boolean[] expected = new boolean[r.length]; 962 963 // Store before checking, since the same location may be stored to more than once 964 for (int i = 0; i < a.length; i += SPECIES.length()) { 965 for (int j = i; j < i + SPECIES.length(); j++) { 966 if (mask[j % SPECIES.length()]) { 967 expected[i + indexMap[j]] = a[j]; 968 } 969 } 970 } 971 972 Assert.assertEquals(r, expected); 973 } 974 975 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 976 boolean[] expected = new boolean[r.length]; 977 978 // Store before checking, since the same location may be stored to more than once 979 for (int i = 0; i < a.length; i += SPECIES.length()) { 980 for (int j = i; j < i + SPECIES.length(); j++) { 981 expected[i + indexMap[j]] = a[j]; 982 } 983 } 984 985 Assert.assertEquals(r, expected); 986 } 987 988 @Test(dataProvider = "gatherScatterProvider") 989 static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 990 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 991 int[] b = fs.apply(a.length, SPECIES.length()); 992 boolean[] r = new boolean[a.length]; 993 994 for (int ic = 0; ic < INVOC_COUNT; ic++) { 995 for (int i = 0; i < a.length; i += SPECIES.length()) { 996 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i); 997 av.intoBooleanArray(r, i); 998 } 999 } 1000 1001 assertGatherArraysEquals(r, a, b); 1002 } 1003 1004 @Test(dataProvider = "gatherScatterMaskProvider") 1005 static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1006 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1007 int[] b = fs.apply(a.length, SPECIES.length()); 1008 boolean[] r = new boolean[a.length]; 1009 boolean[] mask = fm.apply(SPECIES.length()); 1010 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1011 1012 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1013 for (int i = 0; i < a.length; i += SPECIES.length()) { 1014 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, b, i, vmask); 1015 av.intoBooleanArray(r, i); 1016 } 1017 } 1018 1019 assertGatherArraysEquals(r, a, b, mask); 1020 } 1021 1022 @Test(dataProvider = "gatherScatterProvider") 1023 static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1024 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1025 int[] b = fs.apply(a.length, SPECIES.length()); 1026 boolean[] r = new boolean[a.length]; 1027 1028 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1029 for (int i = 0; i < a.length; i += SPECIES.length()) { 1030 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1031 av.intoBooleanArray(r, i, b, i); 1032 } 1033 } 1034 1035 assertScatterArraysEquals(r, a, b); 1036 } 1037 1038 @Test(dataProvider = "gatherScatterMaskProvider") 1039 static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1040 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1041 int[] b = fs.apply(a.length, SPECIES.length()); 1042 boolean[] r = new boolean[a.length]; 1043 boolean[] mask = fm.apply(SPECIES.length()); 1044 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1045 1046 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1047 for (int i = 0; i < a.length; i += SPECIES.length()) { 1048 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1049 av.intoBooleanArray(r, i, b, i, vmask); 1050 } 1051 } 1052 1053 assertScatterArraysEquals(r, a, b, mask); 1054 } 1055 1056 }