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 }
--- EOF ---