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