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