1 /*
   2  * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.vector java.base/jdk.internal.vm.annotation
  27 #if[MaxBit]
  28  * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
  29  *      -XX:-TieredCompilation $vectorteststype$
  30 #else[MaxBit]
  31  * @run testng/othervm -XX:-TieredCompilation $vectorteststype$
  32 #end[MaxBit]
  33  *
  34  */
  35 
  36 #warn This file is preprocessed before being compiled
  37 
  38 import java.lang.foreign.MemorySegment;
  39 import java.lang.foreign.Arena;
  40 import java.lang.foreign.ValueLayout;
  41 import jdk.incubator.vector.$Type$Vector;
  42 import jdk.incubator.vector.VectorMask;
  43 #if[MaxBit]
  44 import jdk.incubator.vector.VectorShape;
  45 #end[MaxBit]
  46 import jdk.incubator.vector.VectorSpecies;
  47 import jdk.incubator.vector.VectorShuffle;
  48 import jdk.internal.vm.annotation.DontInline;
  49 import org.testng.Assert;
  50 import org.testng.annotations.DataProvider;
  51 import org.testng.annotations.Test;
  52 
  53 import java.nio.ByteOrder;
  54 import java.util.List;
  55 import java.util.function.*;
  56 
  57 @Test
  58 public class $vectorteststype$ extends AbstractVectorLoadStoreTest {
  59 #if[MaxBit]
  60     static final VectorSpecies<$Wideboxtype$> SPECIES =
  61                 $Type$Vector.SPECIES_MAX;
  62 #else[MaxBit]
  63     static final VectorSpecies<$Wideboxtype$> SPECIES =
  64                 $Type$Vector.SPECIES_$bits$;
  65 #end[MaxBit]
  66 
  67     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  68 
  69     static final ValueLayout.Of$Type$ ELEMENT_LAYOUT = ValueLayout.JAVA_$TYPE$.withByteAlignment(1);
  70 
  71 #if[MaxBit]
  72     static VectorShape getMaxBit() {
  73         return VectorShape.S_Max_BIT;
  74     }
  75 
  76     private static final int Max = 256;  // juts so we can do N/$bits$
  77 #end[MaxBit]
  78 
  79     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$);
  80 
  81     static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask) {
  82         int i = 0;
  83         try {
  84             for (; i < a.length; i++) {
  85                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0);
  86             }
  87         } catch (AssertionError e) {
  88             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0, "at index #" + i);
  89         }
  90     }
  91 
  92     static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
  93             withToString("$type$[i * 5]", (int s) -> {
  94                 return fill(s * BUFFER_REPS,
  95                             i -> ($type$)(i * 5));
  96             }),
  97             withToString("$type$[i + 1]", (int s) -> {
  98                 return fill(s * BUFFER_REPS,
  99                             i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
 100             })
 101     );
 102 
 103     // Relative to array.length
 104     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
 105             withToString("-1", (int l) -> {
 106                 return -1;
 107             }),
 108             withToString("l", (int l) -> {
 109                 return l;
 110             }),
 111             withToString("l - 1", (int l) -> {
 112                 return l - 1;
 113             }),
 114             withToString("l + 1", (int l) -> {
 115                 return l + 1;
 116             }),
 117             withToString("l - speciesl + 1", (int l) -> {
 118                 return l - SPECIES.length() + 1;
 119             }),
 120             withToString("l + speciesl - 1", (int l) -> {
 121                 return l + SPECIES.length() - 1;
 122             }),
 123             withToString("l + speciesl", (int l) -> {
 124                 return l + SPECIES.length();
 125             }),
 126             withToString("l + speciesl + 1", (int l) -> {
 127                 return l + SPECIES.length() + 1;
 128             })
 129     );
 130 
 131     // Relative to byte[] array.length or MemorySegment.byteSize()
 132     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 133             withToString("-1", (int l) -> {
 134                 return -1;
 135             }),
 136             withToString("l", (int l) -> {
 137                 return l;
 138             }),
 139             withToString("l - 1", (int l) -> {
 140                 return l - 1;
 141             }),
 142             withToString("l + 1", (int l) -> {
 143                 return l + 1;
 144             }),
 145             withToString("l - speciesl*ebsize + 1", (int l) -> {
 146                 return l - SPECIES.vectorByteSize() + 1;
 147             }),
 148             withToString("l + speciesl*ebsize - 1", (int l) -> {
 149                 return l + SPECIES.vectorByteSize() - 1;
 150             }),
 151             withToString("l + speciesl*ebsize", (int l) -> {
 152                 return l + SPECIES.vectorByteSize();
 153             }),
 154             withToString("l + speciesl*ebsize + 1", (int l) -> {
 155                 return l + SPECIES.vectorByteSize() + 1;
 156             })
 157     );
 158 
 159     @DataProvider
 160     public Object[][] $type$Provider() {
 161         return $TYPE$_GENERATORS.stream().
 162                 map(f -> new Object[]{f}).
 163                 toArray(Object[][]::new);
 164     }
 165 
 166     @DataProvider
 167     public Object[][] maskProvider() {
 168         return BOOLEAN_MASK_GENERATORS.stream().
 169                 map(f -> new Object[]{f}).
 170                 toArray(Object[][]::new);
 171     }
 172 
 173     @DataProvider
 174     public Object[][] $type$ProviderForIOOBE() {
 175         var f = $TYPE$_GENERATORS.get(0);
 176         return INDEX_GENERATORS.stream().map(fi -> {
 177                     return new Object[] {f, fi};
 178                 }).
 179                 toArray(Object[][]::new);
 180     }
 181 
 182     @DataProvider
 183     public Object[][] $type$MaskProvider() {
 184         return BOOLEAN_MASK_GENERATORS.stream().
 185                 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
 186                     return new Object[] {fa, fm};
 187                 })).
 188                 toArray(Object[][]::new);
 189     }
 190 
 191     @DataProvider
 192     public Object[][] $type$MaskProviderForIOOBE() {
 193         var f = $TYPE$_GENERATORS.get(0);
 194         return BOOLEAN_MASK_GENERATORS.stream().
 195                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 196                     return new Object[] {f, fi, fm};
 197                 })).
 198                 toArray(Object[][]::new);
 199     }
 200 
 201     @DataProvider
 202     public Object[][] $type$MemorySegmentProvider() {
 203         return $TYPE$_GENERATORS.stream().
 204                 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 205                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 206                             return new Object[]{fa, fb, bo};
 207                         }))).
 208                 toArray(Object[][]::new);
 209     }
 210 
 211     @DataProvider
 212     public Object[][] $type$MemorySegmentMaskProvider() {
 213         return BOOLEAN_MASK_GENERATORS.stream().
 214                 flatMap(fm -> $TYPE$_GENERATORS.stream().
 215                         flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
 216                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 217                             return new Object[]{fa, fb, fm, bo};
 218                         })))).
 219                 toArray(Object[][]::new);
 220     }
 221 
 222     @DataProvider
 223     public Object[][] $type$ByteProviderForIOOBE() {
 224         var f = $TYPE$_GENERATORS.get(0);
 225         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 226                     return new Object[] {f, fi};
 227                 }).
 228                 toArray(Object[][]::new);
 229     }
 230 
 231     @DataProvider
 232     public Object[][] $type$ByteMaskProviderForIOOBE() {
 233         var f = $TYPE$_GENERATORS.get(0);
 234         return BOOLEAN_MASK_GENERATORS.stream().
 235                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 236                     return new Object[] {f, fi, fm};
 237                 })).
 238                 toArray(Object[][]::new);
 239     }
 240 
 241     static MemorySegment toSegment($type$[] a, IntFunction<MemorySegment> fb) {
 242         MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
 243         for (int i = 0; i < a.length; i++) {
 244             ms.set(ELEMENT_LAYOUT, i * SPECIES.elementSize() / 8 , a[i]);
 245         }
 246         return ms;
 247     }
 248 
 249     static $type$[] segmentToArray(MemorySegment ms) {
 250         return ms.toArray(ELEMENT_LAYOUT);
 251     }
 252 
 253 
 254     interface To$Type$F {
 255         $type$ apply(int i);
 256     }
 257 
 258     static $type$[] fill(int s , To$Type$F f) {
 259         return fill(new $type$[s], f);
 260     }
 261 
 262     static $type$[] fill($type$[] a, To$Type$F f) {
 263         for (int i = 0; i < a.length; i++) {
 264             a[i] = f.apply(i);
 265         }
 266         return a;
 267     }
 268 
 269     @DontInline
 270     static $abstractvectortype$ fromArray($type$[] a, int i) {
 271         return $abstractvectortype$.fromArray(SPECIES, a, i);
 272     }
 273 
 274     @DontInline
 275     static $abstractvectortype$ fromArray($type$[] a, int i, VectorMask<$Boxtype$> m) {
 276         return $abstractvectortype$.fromArray(SPECIES, a, i, m);
 277     }
 278 
 279     @DontInline
 280     static void intoArray($abstractvectortype$ v, $type$[] a, int i) {
 281         v.intoArray(a, i);
 282     }
 283 
 284     @DontInline
 285     static void intoArray($abstractvectortype$ v, $type$[] a, int i, VectorMask<$Boxtype$> m) {
 286         v.intoArray(a, i, m);
 287     }
 288 
 289     @DontInline
 290     static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
 291         return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
 292     }
 293 
 294     @DontInline
 295     static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 296         return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, m);
 297     }
 298 
 299     @DontInline
 300     static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo) {
 301         v.intoMemorySegment(a, i, bo);
 302     }
 303 
 304     @DontInline
 305     static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
 306         v.intoMemorySegment(a, i, bo, m);
 307     }
 308 
 309     @Test(dataProvider = "$type$Provider")
 310     static void loadStoreArray(IntFunction<$type$[]> fa) {
 311         $type$[] a = fa.apply(SPECIES.length());
 312         $type$[] r = new $type$[a.length];
 313 
 314         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 315             for (int i = 0; i < a.length; i += SPECIES.length()) {
 316                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 317                 av.intoArray(r, i);
 318             }
 319         }
 320         Assert.assertEquals(r, a);
 321     }
 322 
 323     @Test(dataProvider = "$type$ProviderForIOOBE")
 324     static void loadArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 325         $type$[] a = fa.apply(SPECIES.length());
 326         $type$[] r = new $type$[a.length];
 327 
 328         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 329             for (int i = 0; i < a.length; i += SPECIES.length()) {
 330                 $abstractvectortype$ av = fromArray(a, i);
 331                 av.intoArray(r, i);
 332             }
 333         }
 334 
 335         int index = fi.apply(a.length);
 336         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 337         try {
 338             fromArray(a, index);
 339             if (shouldFail) {
 340                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 341             }
 342         } catch (IndexOutOfBoundsException e) {
 343             if (!shouldFail) {
 344                 Assert.fail("Unexpected IndexOutOfBoundsException");
 345             }
 346         }
 347     }
 348 
 349     @Test(dataProvider = "$type$ProviderForIOOBE")
 350     static void storeArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 351         $type$[] a = fa.apply(SPECIES.length());
 352         $type$[] r = new $type$[a.length];
 353 
 354         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 355             for (int i = 0; i < a.length; i += SPECIES.length()) {
 356                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 357                 intoArray(av, r, i);
 358             }
 359         }
 360 
 361         int index = fi.apply(a.length);
 362         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 363         try {
 364             $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0);
 365             intoArray(av, r, index);
 366             if (shouldFail) {
 367                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 368             }
 369         } catch (IndexOutOfBoundsException e) {
 370             if (!shouldFail) {
 371                 Assert.fail("Unexpected IndexOutOfBoundsException");
 372             }
 373         }
 374     }
 375 
 376 
 377     @Test(dataProvider = "$type$MaskProvider")
 378     static void loadStoreMaskArray(IntFunction<$type$[]> fa,
 379                                    IntFunction<boolean[]> fm) {
 380         $type$[] a = fa.apply(SPECIES.length());
 381         $type$[] r = new $type$[a.length];
 382         boolean[] mask = fm.apply(SPECIES.length());
 383         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 384 
 385         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 386             for (int i = 0; i < a.length; i += SPECIES.length()) {
 387                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, vmask);
 388                 av.intoArray(r, i);
 389             }
 390         }
 391         assertArraysEquals(r, a, mask);
 392 
 393 
 394         r = new $type$[a.length];
 395 
 396         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 397             for (int i = 0; i < a.length; i += SPECIES.length()) {
 398                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 399                 av.intoArray(r, i, vmask);
 400             }
 401         }
 402         assertArraysEquals(r, a, mask);
 403     }
 404 
 405     @Test(dataProvider = "$type$MaskProviderForIOOBE")
 406     static void loadArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 407         $type$[] a = fa.apply(SPECIES.length());
 408         $type$[] r = new $type$[a.length];
 409         boolean[] mask = fm.apply(SPECIES.length());
 410         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 411 
 412         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 413             for (int i = 0; i < a.length; i += SPECIES.length()) {
 414                 $abstractvectortype$ av = fromArray(a, i, vmask);
 415                 av.intoArray(r, i);
 416             }
 417         }
 418 
 419         int index = fi.apply(a.length);
 420         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 421         try {
 422             fromArray(a, index, vmask);
 423             if (shouldFail) {
 424                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 425             }
 426         } catch (IndexOutOfBoundsException e) {
 427             if (!shouldFail) {
 428                 Assert.fail("Unexpected IndexOutOfBoundsException");
 429             }
 430         }
 431     }
 432 
 433     @Test(dataProvider = "$type$MaskProviderForIOOBE")
 434     static void storeArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 435         $type$[] a = fa.apply(SPECIES.length());
 436         $type$[] r = new $type$[a.length];
 437         boolean[] mask = fm.apply(SPECIES.length());
 438         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 439 
 440         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 441             for (int i = 0; i < a.length; i += SPECIES.length()) {
 442                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
 443                 intoArray(av, r, i, vmask);
 444             }
 445         }
 446 
 447         int index = fi.apply(a.length);
 448         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 449         try {
 450             $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0);
 451             intoArray(av, a, index, vmask);
 452             if (shouldFail) {
 453                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 454             }
 455         } catch (IndexOutOfBoundsException e) {
 456             if (!shouldFail) {
 457                 Assert.fail("Unexpected IndexOutOfBoundsException");
 458             }
 459         }
 460     }
 461 
 462 
 463     @Test(dataProvider = "$type$MaskProvider")
 464     static void loadStoreMask(IntFunction<$type$[]> fa,
 465                               IntFunction<boolean[]> fm) {
 466         boolean[] mask = fm.apply(SPECIES.length());
 467         boolean[] r = new boolean[mask.length];
 468 
 469         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 470             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 471                 VectorMask<$Boxtype$> vmask = VectorMask.fromArray(SPECIES, mask, i);
 472                 vmask.intoArray(r, i);
 473             }
 474         }
 475         Assert.assertEquals(r, mask);
 476     }
 477 
 478 
 479     @Test(dataProvider = "$type$MemorySegmentProvider")
 480     static void loadStoreMemorySegment(IntFunction<$type$[]> fa,
 481                                        IntFunction<MemorySegment> fb,
 482                                        ByteOrder bo) {
 483         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb);
 484         MemorySegment r = fb.apply((int) a.byteSize());
 485 
 486         int l = (int) a.byteSize();
 487         int s = SPECIES.vectorByteSize();
 488 
 489         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 490             for (int i = 0; i < l; i += s) {
 491                 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
 492                 av.intoMemorySegment(r, i, bo);
 493             }
 494         }
 495         long m = r.mismatch(a);
 496         Assert.assertEquals(m, -1, "Segments not equal");
 497     }
 498 
 499     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 500     static void loadMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 501         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE));
 502         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE);
 503 
 504         int l = (int) a.byteSize();
 505         int s = SPECIES.vectorByteSize();
 506 
 507         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 508             for (int i = 0; i < l; i += s) {
 509                 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder());
 510                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 511             }
 512         }
 513 
 514         int index = fi.apply((int) a.byteSize());
 515         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 516         try {
 517             fromMemorySegment(a, index, ByteOrder.nativeOrder());
 518             if (shouldFail) {
 519                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 520             }
 521         } catch (IndexOutOfBoundsException e) {
 522             if (!shouldFail) {
 523                 Assert.fail("Unexpected IndexOutOfBoundsException");
 524             }
 525         }
 526     }
 527 
 528     @Test(dataProvider = "$type$ByteProviderForIOOBE")
 529     static void storeMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
 530         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE));
 531         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE);
 532 
 533         int l = (int) a.byteSize();
 534         int s = SPECIES.vectorByteSize();
 535 
 536         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 537             for (int i = 0; i < l; i += s) {
 538                 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 539                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder());
 540             }
 541         }
 542 
 543         int index = fi.apply((int) a.byteSize());
 544         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
 545         try {
 546             $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 547             intoMemorySegment(av, r, index, ByteOrder.nativeOrder());
 548             if (shouldFail) {
 549                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 550             }
 551         } catch (IndexOutOfBoundsException e) {
 552             if (!shouldFail) {
 553                 Assert.fail("Unexpected IndexOutOfBoundsException");
 554             }
 555         }
 556     }
 557 
 558     @Test(dataProvider = "$type$MemorySegmentMaskProvider")
 559     static void loadStoreMemorySegmentMask(IntFunction<$type$[]> fa,
 560                                            IntFunction<MemorySegment> fb,
 561                                            IntFunction<boolean[]> fm,
 562                                            ByteOrder bo) {
 563         $type$[] _a = fa.apply(SPECIES.length());
 564         MemorySegment a = toSegment(_a, fb);
 565         MemorySegment r = fb.apply((int) a.byteSize());
 566         boolean[] mask = fm.apply(SPECIES.length());
 567         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 568 
 569         int l = (int) a.byteSize();
 570         int s = SPECIES.vectorByteSize();
 571 
 572         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 573             for (int i = 0; i < l; i += s) {
 574                 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, vmask);
 575                 av.intoMemorySegment(r, i, bo);
 576             }
 577         }
 578         assertArraysEquals(segmentToArray(r), _a, mask);
 579 
 580 
 581         r = fb.apply((int) a.byteSize());
 582 
 583         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 584             for (int i = 0; i < l; i += s) {
 585                 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
 586                 av.intoMemorySegment(r, i, bo, vmask);
 587             }
 588         }
 589         assertArraysEquals(segmentToArray(r), _a, mask);
 590     }
 591 
 592     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 593     static void loadMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 594         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE));
 595         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE);
 596         boolean[] mask = fm.apply(SPECIES.length());
 597         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 598 
 599         int l = (int) a.byteSize();
 600         int s = SPECIES.vectorByteSize();
 601 
 602         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 603             for (int i = 0; i < l; i += s) {
 604                 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
 605                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
 606             }
 607         }
 608 
 609         int index = fi.apply((int) a.byteSize());
 610         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 611         try {
 612             fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
 613             if (shouldFail) {
 614                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 615             }
 616         } catch (IndexOutOfBoundsException e) {
 617             if (!shouldFail) {
 618                 Assert.fail("Unexpected IndexOutOfBoundsException");
 619             }
 620         }
 621     }
 622 
 623     @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
 624     static void storeMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 625         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE));
 626         MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE);
 627         boolean[] mask = fm.apply(SPECIES.length());
 628         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 629 
 630         int l = (int) a.byteSize();
 631         int s = SPECIES.vectorByteSize();
 632 
 633         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 634             for (int i = 0; i < l; i += s) {
 635                 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
 636                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask);
 637             }
 638         }
 639 
 640         int index = fi.apply((int) a.byteSize());
 641         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
 642         try {
 643             $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
 644             intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask);
 645             if (shouldFail) {
 646                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 647             }
 648         } catch (IndexOutOfBoundsException e) {
 649             if (!shouldFail) {
 650                 Assert.fail("Unexpected IndexOutOfBoundsException");
 651             }
 652         }
 653     }
 654 
 655     @Test(dataProvider = "$type$MemorySegmentProvider")
 656     static void loadStoreReadonlyMemorySegment(IntFunction<$type$[]> fa,
 657                                                IntFunction<MemorySegment> fb,
 658                                                ByteOrder bo) {
 659         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly();
 660 
 661         Assert.assertThrows(
 662                 UnsupportedOperationException.class,
 663                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
 664         );
 665 
 666         Assert.assertThrows(
 667                 UnsupportedOperationException.class,
 668                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
 669         );
 670 
 671         Assert.assertThrows(
 672                 UnsupportedOperationException.class,
 673                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
 674         );
 675 
 676         VectorMask<$Boxtype$> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 677                 .laneIsValid();
 678         Assert.assertThrows(
 679                 UnsupportedOperationException.class,
 680                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
 681         );
 682     }
 683 
 684 
 685     @Test(dataProvider = "maskProvider")
 686     static void loadStoreMask(IntFunction<boolean[]> fm) {
 687         boolean[] a = fm.apply(SPECIES.length());
 688         boolean[] r = new boolean[a.length];
 689 
 690         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 691             for (int i = 0; i < a.length; i += SPECIES.length()) {
 692                 VectorMask<$Boxtype$> vmask = SPECIES.loadMask(a, i);
 693                 vmask.intoArray(r, i);
 694             }
 695         }
 696         Assert.assertEquals(r, a);
 697     }
 698 
 699 
 700     @Test
 701     static void loadStoreShuffle() {
 702         IntUnaryOperator fn = a -> a + 5;
 703         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 704             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 705             int [] r = shuffle.toArray();
 706 
 707             int [] a = expectedShuffle(SPECIES.length(), fn);
 708             Assert.assertEquals(r, a);
 709        }
 710     }
 711 
 712 
 713 #if[short]
 714     static void assertArraysEquals(char[] a, char[] r, boolean[] mask) {
 715         int i = 0;
 716         try {
 717             for (; i < a.length; i++) {
 718                 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]);
 719             }
 720         } catch (AssertionError e) {
 721             Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i);
 722         }
 723     }
 724 
 725     static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of(
 726             withToString("char[i * 5]", (int s) -> {
 727                 return fillChar(s * BUFFER_REPS,
 728                             i -> (char)(i * 5));
 729             }),
 730             withToString("char[i + 1]", (int s) -> {
 731                 return fillChar(s * BUFFER_REPS,
 732                             i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1)));
 733             })
 734     );
 735 
 736     @DataProvider
 737     public Object[][] charProvider() {
 738         return CHAR_GENERATORS.stream().
 739                 map(f -> new Object[]{f}).
 740                 toArray(Object[][]::new);
 741     }
 742 
 743     @DataProvider
 744     public Object[][] charProviderForIOOBE() {
 745         var f = CHAR_GENERATORS.get(0);
 746         return INDEX_GENERATORS.stream().map(fi -> {
 747                     return new Object[] {f, fi};
 748                 }).
 749                 toArray(Object[][]::new);
 750     }
 751 
 752     @DataProvider
 753     public Object[][] charMaskProvider() {
 754         return BOOLEAN_MASK_GENERATORS.stream().
 755                 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> {
 756                     return new Object[] {fa, fm};
 757                 })).
 758                 toArray(Object[][]::new);
 759     }
 760 
 761     @DataProvider
 762     public Object[][] charMaskProviderForIOOBE() {
 763         var f = CHAR_GENERATORS.get(0);
 764         return BOOLEAN_MASK_GENERATORS.stream().
 765                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 766                     return new Object[] {f, fi, fm};
 767                 })).
 768                 toArray(Object[][]::new);
 769     }
 770 
 771     interface ToCharF {
 772         char apply(int i);
 773     }
 774 
 775     static char[] fillChar(int s , ToCharF f) {
 776         return fillChar(new char[s], f);
 777     }
 778 
 779     static char[] fillChar(char[] a, ToCharF f) {
 780         for (int i = 0; i < a.length; i++) {
 781             a[i] = f.apply(i);
 782         }
 783         return a;
 784     }
 785 
 786     @DontInline
 787     static $abstractvectortype$ fromCharArray(char[] a, int i) {
 788         return $abstractvectortype$.fromCharArray(SPECIES, a, i);
 789     }
 790 
 791     @DontInline
 792     static $abstractvectortype$ fromCharArray(char[] a, int i, VectorMask<$Boxtype$> m) {
 793         return $abstractvectortype$.fromCharArray(SPECIES, a, i, m);
 794     }
 795 
 796     @DontInline
 797     static void intoCharArray($abstractvectortype$ v, char[] a, int i) {
 798         v.intoCharArray(a, i);
 799     }
 800 
 801     @DontInline
 802     static void intoCharArray($abstractvectortype$ v, char[] a, int i, VectorMask<$Boxtype$> m) {
 803         v.intoCharArray(a, i, m);
 804     }
 805 
 806     @Test(dataProvider = "charProvider")
 807     static void loadStoreCharArray(IntFunction<char[]> fa) {
 808         char[] a = fa.apply(SPECIES.length());
 809         char[] r = new char[a.length];
 810 
 811         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 812             for (int i = 0; i < a.length; i += SPECIES.length()) {
 813                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
 814                 av.intoCharArray(r, i);
 815             }
 816         }
 817         Assert.assertEquals(a, r);
 818     }
 819 
 820     @Test(dataProvider = "charProviderForIOOBE")
 821     static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
 822         char[] a = fa.apply(SPECIES.length());
 823         char[] r = new char[a.length];
 824 
 825         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 826             for (int i = 0; i < a.length; i += SPECIES.length()) {
 827                 $abstractvectortype$ av = fromCharArray(a, i);
 828                 av.intoCharArray(r, i);
 829             }
 830         }
 831 
 832         int index = fi.apply(a.length);
 833         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 834         try {
 835             fromCharArray(a, index);
 836             if (shouldFail) {
 837                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 838             }
 839         } catch (IndexOutOfBoundsException e) {
 840             if (!shouldFail) {
 841                 Assert.fail("Unexpected IndexOutOfBoundsException");
 842             }
 843         }
 844     }
 845 
 846     @Test(dataProvider = "charProviderForIOOBE")
 847     static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) {
 848         char[] a = fa.apply(SPECIES.length());
 849         char[] r = new char[a.length];
 850 
 851         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 852             for (int i = 0; i < a.length; i += SPECIES.length()) {
 853                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
 854                 intoCharArray(av, r, i);
 855             }
 856         }
 857 
 858         int index = fi.apply(a.length);
 859         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 860         try {
 861             $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0);
 862             intoCharArray(av, r, index);
 863             if (shouldFail) {
 864                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 865             }
 866         } catch (IndexOutOfBoundsException e) {
 867             if (!shouldFail) {
 868                 Assert.fail("Unexpected IndexOutOfBoundsException");
 869             }
 870         }
 871     }
 872 
 873     @Test(dataProvider = "charMaskProvider")
 874     static void loadStoreMaskCharArray(IntFunction<char[]> fa,
 875                                        IntFunction<boolean[]> fm) {
 876         char[] a = fa.apply(SPECIES.length());
 877         char[] r = new char[a.length];
 878         boolean[] mask = fm.apply(SPECIES.length());
 879         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 880 
 881         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 882             for (int i = 0; i < a.length; i += SPECIES.length()) {
 883                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, vmask);
 884                 av.intoCharArray(r, i);
 885             }
 886         }
 887         assertArraysEquals(a, r, mask);
 888 
 889 
 890         r = new char[a.length];
 891 
 892         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 893             for (int i = 0; i < a.length; i += SPECIES.length()) {
 894                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
 895                 av.intoCharArray(r, i, vmask);
 896             }
 897         }
 898         assertArraysEquals(a, r, mask);
 899     }
 900 
 901     @Test(dataProvider = "charMaskProviderForIOOBE")
 902     static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 903         char[] a = fa.apply(SPECIES.length());
 904         char[] r = new char[a.length];
 905         boolean[] mask = fm.apply(SPECIES.length());
 906         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 907 
 908         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 909             for (int i = 0; i < a.length; i += SPECIES.length()) {
 910                 $abstractvectortype$ av = fromCharArray(a, i, vmask);
 911                 av.intoCharArray(r, i);
 912             }
 913         }
 914 
 915         int index = fi.apply(a.length);
 916         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 917         try {
 918             fromCharArray(a, index, vmask);
 919             if (shouldFail) {
 920                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 921             }
 922         } catch (IndexOutOfBoundsException e) {
 923             if (!shouldFail) {
 924                 Assert.fail("Unexpected IndexOutOfBoundsException");
 925             }
 926         }
 927     }
 928 
 929     @Test(dataProvider = "charMaskProviderForIOOBE")
 930     static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 931         char[] a = fa.apply(SPECIES.length());
 932         char[] r = new char[a.length];
 933         boolean[] mask = fm.apply(SPECIES.length());
 934         VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
 935 
 936         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 937             for (int i = 0; i < a.length; i += SPECIES.length()) {
 938                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
 939                 intoCharArray(av, r, i, vmask);
 940             }
 941         }
 942 
 943         int index = fi.apply(a.length);
 944         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 945         try {
 946             $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0);
 947             intoCharArray(av, a, index, vmask);
 948             if (shouldFail) {
 949                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 950             }
 951         } catch (IndexOutOfBoundsException e) {
 952             if (!shouldFail) {
 953                 Assert.fail("Unexpected IndexOutOfBoundsException");
 954             }
 955         }
 956     }
 957 
 958 #end[short]
 959 
 960 #if[byte]
 961     static void assertArraysEquals(boolean[] r, byte[] a) {
 962         int i = 0;
 963         try {
 964             for (; i < a.length; i++) {
 965                 Assert.assertEquals(r[i], (a[i] & 1) == 1);
 966             }
 967         } catch (AssertionError e) {
 968             Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i);
 969         }
 970     }
 971 
 972     static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) {
 973         int i = 0;
 974         try {
 975             for (; i < a.length; i++) {
 976                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]);
 977             }
 978         } catch (AssertionError e) {
 979             Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i);
 980         }
 981     }
 982 
 983     static boolean[] convertToBooleanArray(byte[] a) {
 984         boolean[] r = new boolean[a.length];
 985 
 986         for (int i = 0; i < a.length; i++) {
 987             r[i] = (a[i] & 1) == 1;
 988         }
 989 
 990         return r;
 991     }
 992 
 993     @Test(dataProvider = "byteProvider")
 994     static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) {
 995         byte[] a = fa.apply(SPECIES.length());
 996         boolean[] r = new boolean[a.length];
 997 
 998         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 999             for (int i = 0; i < a.length; i += SPECIES.length()) {
1000                 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
1001                 av.intoBooleanArray(r, i);
1002             }
1003         }
1004         assertArraysEquals(r, a);
1005     }
1006 
1007     @Test(dataProvider = "byteProvider")
1008     static void loadStoreBooleanArray(IntFunction<byte[]> fa) {
1009         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1010         boolean[] r = new boolean[a.length];
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);
1015                 av.intoBooleanArray(r, i);
1016             }
1017         }
1018         Assert.assertEquals(r, a);
1019     }
1020 
1021     @Test(dataProvider = "byteMaskProvider")
1022     static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa,
1023                                           IntFunction<boolean[]> fm) {
1024         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1025         boolean[] r = new boolean[a.length];
1026         boolean[] mask = fm.apply(SPECIES.length());
1027         VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
1028 
1029         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1030             for (int i = 0; i < a.length; i += SPECIES.length()) {
1031                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask);
1032                 av.intoBooleanArray(r, i);
1033             }
1034         }
1035         assertArraysEquals(r, a, mask);
1036 
1037 
1038         r = new boolean[a.length];
1039 
1040         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1041             for (int i = 0; i < a.length; i += SPECIES.length()) {
1042                 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i);
1043                 av.intoBooleanArray(r, i, vmask);
1044             }
1045         }
1046         assertArraysEquals(r, a, mask);
1047     }
1048 #end[byte]
1049 
1050 
1051     // Gather/Scatter load/store tests
1052 
1053     static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap) {
1054         int i = 0;
1055         int j = 0;
1056         try {
1057             for (; i < a.length; i += SPECIES.length()) {
1058                 j = i;
1059                 for (; j < i + SPECIES.length(); j++) {
1060                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1061                 }
1062             }
1063         } catch (AssertionError e) {
1064             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1065         }
1066     }
1067 
1068     static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) {
1069         int i = 0;
1070         int j = 0;
1071         try {
1072             for (; i < a.length; i += SPECIES.length()) {
1073                 j = i;
1074                 for (; j < i + SPECIES.length(); j++) {
1075                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0);
1076                 }
1077             }
1078         } catch (AssertionError e) {
1079             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0, "at index #" + j);
1080         }
1081     }
1082 
1083     static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) {
1084         $type$[] expected = new $type$[r.length];
1085 
1086         // Store before checking, since the same location may be stored to more than once
1087         for (int i = 0; i < a.length; i += SPECIES.length()) {
1088             for (int j = i; j < i + SPECIES.length(); j++) {
1089                 if (mask[j % SPECIES.length()]) {
1090                     expected[i + indexMap[j]] = a[j];
1091                 }
1092             }
1093         }
1094 
1095         Assert.assertEquals(r, expected);
1096     }
1097 
1098     static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap) {
1099         $type$[] expected = new $type$[r.length];
1100 
1101         // Store before checking, since the same location may be stored to more than once
1102         for (int i = 0; i < a.length; i += SPECIES.length()) {
1103             for (int j = i; j < i + SPECIES.length(); j++) {
1104                 expected[i + indexMap[j]] = a[j];
1105             }
1106         }
1107 
1108         Assert.assertEquals(r, expected);
1109     }
1110 
1111     @DataProvider
1112     public Object[][] gatherScatterProvider() {
1113         return INT_INDEX_GENERATORS.stream().
1114                 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> {
1115                     return new Object[] {fa, fs};
1116                 })).
1117                 toArray(Object[][]::new);
1118     }
1119 
1120     @DataProvider
1121     public Object[][] gatherScatterMaskProvider() {
1122         return BOOLEAN_MASK_GENERATORS.stream().
1123           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1124             $TYPE$_GENERATORS.stream().map(fa -> {
1125                     return new Object[] {fa, fm, fs};
1126             }))).
1127             toArray(Object[][]::new);
1128     }
1129 
1130 
1131     @Test(dataProvider = "gatherScatterProvider")
1132     static void gather(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1133         $type$[] a = fa.apply(SPECIES.length());
1134         int[] b = fs.apply(a.length, SPECIES.length());
1135         $type$[] r = new $type$[a.length];
1136 
1137         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1138             for (int i = 0; i < a.length; i += SPECIES.length()) {
1139                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i);
1140                 av.intoArray(r, i);
1141             }
1142         }
1143 
1144         assertGatherArraysEquals(r, a, b);
1145     }
1146 
1147     @Test(dataProvider = "gatherScatterMaskProvider")
1148     static void gatherMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1149         $type$[] a = fa.apply(SPECIES.length());
1150         int[] b = fs.apply(a.length, SPECIES.length());
1151         $type$[] r = new $type$[a.length];
1152         boolean[] mask = fm.apply(SPECIES.length());
1153         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1154 
1155         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1156             for (int i = 0; i < a.length; i += SPECIES.length()) {
1157                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i, vmask);
1158                 av.intoArray(r, i);
1159             }
1160         }
1161 
1162         assertGatherArraysEquals(r, a, b, mask);
1163     }
1164 
1165     @Test(dataProvider = "gatherScatterProvider")
1166     static void scatter(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1167         $type$[] a = fa.apply(SPECIES.length());
1168         int[] b = fs.apply(a.length, SPECIES.length());
1169         $type$[] r = new $type$[a.length];
1170 
1171         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1172             for (int i = 0; i < a.length; i += SPECIES.length()) {
1173                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
1174                 av.intoArray(r, i, b, i);
1175             }
1176         }
1177 
1178         assertScatterArraysEquals(r, a, b);
1179     }
1180 
1181     @Test(dataProvider = "gatherScatterMaskProvider")
1182     static void scatterMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1183         $type$[] a = fa.apply(SPECIES.length());
1184         int[] b = fs.apply(a.length, SPECIES.length());
1185         $type$[] r = new $type$[a.length];
1186         boolean[] mask = fm.apply(SPECIES.length());
1187         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1188 
1189         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1190             for (int i = 0; i < a.length; i += SPECIES.length()) {
1191                 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
1192                 av.intoArray(r, i, b, i, vmask);
1193             }
1194         }
1195 
1196         assertScatterArraysEquals(r, a, b, mask);
1197     }
1198 
1199 #if[short]
1200     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) {
1201         int i = 0;
1202         int j = 0;
1203         try {
1204             for (; i < a.length; i += SPECIES.length()) {
1205                 j = i;
1206                 for (; j < i + SPECIES.length(); j++) {
1207                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1208                 }
1209             }
1210         } catch (AssertionError e) {
1211             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1212         }
1213     }
1214 
1215     static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1216         int i = 0;
1217         int j = 0;
1218         try {
1219             for (; i < a.length; i += SPECIES.length()) {
1220                 j = i;
1221                 for (; j < i + SPECIES.length(); j++) {
1222                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0);
1223                 }
1224             }
1225         } catch (AssertionError e) {
1226             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j);
1227         }
1228     }
1229 
1230     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) {
1231         char[] expected = new char[r.length];
1232 
1233         // Store before checking, since the same location may be stored to more than once
1234         for (int i = 0; i < a.length; i += SPECIES.length()) {
1235             for (int j = i; j < i + SPECIES.length(); j++) {
1236                 if (mask[j % SPECIES.length()]) {
1237                     expected[i + indexMap[j]] = a[j];
1238                 }
1239             }
1240         }
1241 
1242         Assert.assertEquals(r, expected);
1243     }
1244 
1245     static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) {
1246         char[] expected = new char[r.length];
1247 
1248         // Store before checking, since the same location may be stored to more than once
1249         for (int i = 0; i < a.length; i += SPECIES.length()) {
1250             for (int j = i; j < i + SPECIES.length(); j++) {
1251                 expected[i + indexMap[j]] = a[j];
1252             }
1253         }
1254 
1255         Assert.assertEquals(r, expected);
1256     }
1257 
1258     @DataProvider
1259     public Object[][] charGatherScatterProvider() {
1260         return INT_INDEX_GENERATORS.stream().
1261                 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> {
1262                     return new Object[] {fa, fs};
1263                 })).
1264                 toArray(Object[][]::new);
1265     }
1266 
1267     @DataProvider
1268     public Object[][] charGatherScatterMaskProvider() {
1269         return BOOLEAN_MASK_GENERATORS.stream().
1270           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1271             CHAR_GENERATORS.stream().map(fa -> {
1272                     return new Object[] {fa, fm, fs};
1273             }))).
1274             toArray(Object[][]::new);
1275     }
1276 
1277 
1278     @Test(dataProvider = "charGatherScatterProvider")
1279     static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1280         char[] a = fa.apply(SPECIES.length());
1281         int[] b = fs.apply(a.length, SPECIES.length());
1282         char[] r = new char[a.length];
1283 
1284         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1285             for (int i = 0; i < a.length; i += SPECIES.length()) {
1286                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i);
1287                 av.intoCharArray(r, i);
1288             }
1289         }
1290 
1291         assertGatherArraysEquals(r, a, b);
1292     }
1293 
1294     @Test(dataProvider = "charGatherScatterMaskProvider")
1295     static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1296         char[] a = fa.apply(SPECIES.length());
1297         int[] b = fs.apply(a.length, SPECIES.length());
1298         char[] r = new char[a.length];
1299         boolean[] mask = fm.apply(SPECIES.length());
1300         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1301 
1302         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1303             for (int i = 0; i < a.length; i += SPECIES.length()) {
1304                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i, vmask);
1305                 av.intoCharArray(r, i);
1306             }
1307         }
1308 
1309         assertGatherArraysEquals(r, a, b, mask);
1310     }
1311 
1312     @Test(dataProvider = "charGatherScatterProvider")
1313     static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1314         char[] a = fa.apply(SPECIES.length());
1315         int[] b = fs.apply(a.length, SPECIES.length());
1316         char[] r = new char[a.length];
1317 
1318         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1319             for (int i = 0; i < a.length; i += SPECIES.length()) {
1320                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1321                 av.intoCharArray(r, i, b, i);
1322             }
1323         }
1324 
1325         assertScatterArraysEquals(r, a, b);
1326     }
1327 
1328     @Test(dataProvider = "charGatherScatterMaskProvider")
1329     static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1330         char[] a = fa.apply(SPECIES.length());
1331         int[] b = fs.apply(a.length, SPECIES.length());
1332         char[] r = new char[a.length];
1333         boolean[] mask = fm.apply(SPECIES.length());
1334         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1335 
1336         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1337             for (int i = 0; i < a.length; i += SPECIES.length()) {
1338                 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i);
1339                 av.intoCharArray(r, i, b, i, vmask);
1340             }
1341         }
1342 
1343         assertScatterArraysEquals(r, a, b, mask);
1344     }
1345 #end[short]
1346 
1347 #if[byte]
1348     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1349         int i = 0;
1350         int j = 0;
1351         try {
1352             for (; i < a.length; i += SPECIES.length()) {
1353                 j = i;
1354                 for (; j < i + SPECIES.length(); j++) {
1355                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
1356                 }
1357             }
1358         } catch (AssertionError e) {
1359             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
1360         }
1361     }
1362 
1363     static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1364         int i = 0;
1365         int j = 0;
1366         try {
1367             for (; i < a.length; i += SPECIES.length()) {
1368                 j = i;
1369                 for (; j < i + SPECIES.length(); j++) {
1370                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false);
1371                 }
1372             }
1373         } catch (AssertionError e) {
1374             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j);
1375         }
1376     }
1377 
1378     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) {
1379         boolean[] expected = new boolean[r.length];
1380 
1381         // Store before checking, since the same location may be stored to more than once
1382         for (int i = 0; i < a.length; i += SPECIES.length()) {
1383             for (int j = i; j < i + SPECIES.length(); j++) {
1384                 if (mask[j % SPECIES.length()]) {
1385                     expected[i + indexMap[j]] = a[j];
1386                 }
1387             }
1388         }
1389 
1390         Assert.assertEquals(r, expected);
1391     }
1392 
1393     static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) {
1394         boolean[] expected = new boolean[r.length];
1395 
1396         // Store before checking, since the same location may be stored to more than once
1397         for (int i = 0; i < a.length; i += SPECIES.length()) {
1398             for (int j = i; j < i + SPECIES.length(); j++) {
1399                 expected[i + indexMap[j]] = a[j];
1400             }
1401         }
1402 
1403         Assert.assertEquals(r, expected);
1404     }
1405 
1406     @Test(dataProvider = "gatherScatterProvider")
1407     static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1408         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1409         int[] b = fs.apply(a.length, SPECIES.length());
1410         boolean[] r = new boolean[a.length];
1411 
1412         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1413             for (int i = 0; i < a.length; i += SPECIES.length()) {
1414                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i);
1415                 av.intoBooleanArray(r, i);
1416             }
1417         }
1418 
1419         assertGatherArraysEquals(r, a, b);
1420     }
1421 
1422     @Test(dataProvider = "gatherScatterMaskProvider")
1423     static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1424         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1425         int[] b = fs.apply(a.length, SPECIES.length());
1426         boolean[] r = new boolean[a.length];
1427         boolean[] mask = fm.apply(SPECIES.length());
1428         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1429 
1430         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1431             for (int i = 0; i < a.length; i += SPECIES.length()) {
1432                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i, vmask);
1433                 av.intoBooleanArray(r, i);
1434             }
1435         }
1436 
1437         assertGatherArraysEquals(r, a, b, mask);
1438     }
1439 
1440     @Test(dataProvider = "gatherScatterProvider")
1441     static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1442         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1443         int[] b = fs.apply(a.length, SPECIES.length());
1444         boolean[] r = new boolean[a.length];
1445 
1446         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1447             for (int i = 0; i < a.length; i += SPECIES.length()) {
1448                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i);
1449                 av.intoBooleanArray(r, i, b, i);
1450             }
1451         }
1452 
1453         assertScatterArraysEquals(r, a, b);
1454     }
1455 
1456     @Test(dataProvider = "gatherScatterMaskProvider")
1457     static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1458         boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length()));
1459         int[] b = fs.apply(a.length, SPECIES.length());
1460         boolean[] r = new boolean[a.length];
1461         boolean[] mask = fm.apply(SPECIES.length());
1462         VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1463 
1464         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1465             for (int i = 0; i < a.length; i += SPECIES.length()) {
1466                 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i);
1467                 av.intoBooleanArray(r, i, b, i, vmask);
1468             }
1469         }
1470 
1471         assertScatterArraysEquals(r, a, b, mask);
1472     }
1473 #end[byte]
1474 
1475 }