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