1 /*
   2  * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation
  27  * @run testng/othervm -XX:-TieredCompilation Double256VectorLoadStoreTests
  28  *
  29  */
  30 
  31 // -- This file was mechanically generated: Do not edit! -- //
  32 



  33 import jdk.incubator.vector.DoubleVector;
  34 import jdk.incubator.vector.VectorMask;
  35 import jdk.incubator.vector.VectorSpecies;
  36 import jdk.incubator.vector.VectorShuffle;
  37 import jdk.internal.vm.annotation.DontInline;
  38 import org.testng.Assert;
  39 import org.testng.annotations.DataProvider;
  40 import org.testng.annotations.Test;
  41 
  42 import java.nio.ByteBuffer;
  43 import java.nio.DoubleBuffer;
  44 import java.nio.ByteOrder;
  45 import java.nio.ReadOnlyBufferException;
  46 import java.util.List;
  47 import java.util.function.*;
  48 
  49 @Test
  50 public class Double256VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
  51     static final VectorSpecies<Double> SPECIES =
  52                 DoubleVector.SPECIES_256;
  53 
  54     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  55 
  56 
  57     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 256);
  58 
  59     static void assertArraysEquals(double[] r, double[] a, boolean[] mask) {
  60         int i = 0;
  61         try {
  62             for (; i < a.length; i++) {
  63                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0);
  64             }
  65         } catch (AssertionError e) {
  66             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0, "at index #" + i);
  67         }
  68     }
  69 
  70     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
  71         int i = 0;
  72         try {
  73             for (; i < a.length; i++) {
  74                 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0);
  75             }
  76         } catch (AssertionError e) {
  77             Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
  78         }
  79     }
  80 
  81     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
  82             withToString("double[i * 5]", (int s) -> {
  83                 return fill(s * BUFFER_REPS,
  84                             i -> (double)(i * 5));
  85             }),
  86             withToString("double[i + 1]", (int s) -> {
  87                 return fill(s * BUFFER_REPS,
  88                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
  89             })
  90     );
  91 
  92     // Relative to array.length
  93     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
  94             withToString("-1", (int l) -> {
  95                 return -1;
  96             }),
  97             withToString("l", (int l) -> {
  98                 return l;
  99             }),
 100             withToString("l - 1", (int l) -> {
 101                 return l - 1;
 102             }),
 103             withToString("l + 1", (int l) -> {
 104                 return l + 1;
 105             }),
 106             withToString("l - speciesl + 1", (int l) -> {
 107                 return l - SPECIES.length() + 1;
 108             }),
 109             withToString("l + speciesl - 1", (int l) -> {
 110                 return l + SPECIES.length() - 1;
 111             }),
 112             withToString("l + speciesl", (int l) -> {
 113                 return l + SPECIES.length();
 114             }),
 115             withToString("l + speciesl + 1", (int l) -> {
 116                 return l + SPECIES.length() + 1;
 117             })
 118     );
 119 
 120     // Relative to byte[] array.length or ByteBuffer.limit()
 121     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
 122             withToString("-1", (int l) -> {
 123                 return -1;
 124             }),
 125             withToString("l", (int l) -> {
 126                 return l;
 127             }),
 128             withToString("l - 1", (int l) -> {
 129                 return l - 1;
 130             }),
 131             withToString("l + 1", (int l) -> {
 132                 return l + 1;
 133             }),
 134             withToString("l - speciesl*ebsize + 1", (int l) -> {
 135                 return l - SPECIES.vectorByteSize() + 1;
 136             }),
 137             withToString("l + speciesl*ebsize - 1", (int l) -> {
 138                 return l + SPECIES.vectorByteSize() - 1;
 139             }),
 140             withToString("l + speciesl*ebsize", (int l) -> {
 141                 return l + SPECIES.vectorByteSize();
 142             }),
 143             withToString("l + speciesl*ebsize + 1", (int l) -> {
 144                 return l + SPECIES.vectorByteSize() + 1;
 145             })
 146     );
 147 
 148     @DataProvider
 149     public Object[][] doubleProvider() {
 150         return DOUBLE_GENERATORS.stream().
 151                 map(f -> new Object[]{f}).
 152                 toArray(Object[][]::new);
 153     }
 154 
 155     @DataProvider
 156     public Object[][] maskProvider() {
 157         return BOOLEAN_MASK_GENERATORS.stream().
 158                 map(f -> new Object[]{f}).
 159                 toArray(Object[][]::new);
 160     }
 161 
 162     @DataProvider
 163     public Object[][] doubleProviderForIOOBE() {
 164         var f = DOUBLE_GENERATORS.get(0);
 165         return INDEX_GENERATORS.stream().map(fi -> {
 166                     return new Object[] {f, fi};
 167                 }).
 168                 toArray(Object[][]::new);
 169     }
 170 
 171     @DataProvider
 172     public Object[][] doubleMaskProvider() {
 173         return BOOLEAN_MASK_GENERATORS.stream().
 174                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
 175                     return new Object[] {fa, fm};
 176                 })).
 177                 toArray(Object[][]::new);
 178     }
 179 
 180     @DataProvider
 181     public Object[][] doubleMaskProviderForIOOBE() {
 182         var f = DOUBLE_GENERATORS.get(0);
 183         return BOOLEAN_MASK_GENERATORS.stream().
 184                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
 185                     return new Object[] {f, fi, fm};
 186                 })).
 187                 toArray(Object[][]::new);
 188     }
 189 
 190     @DataProvider
 191     public Object[][] doubleByteBufferProvider() {
 192         return DOUBLE_GENERATORS.stream().
 193                 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 194                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 195                             return new Object[]{fa, fb, bo};
 196                         }))).
 197                 toArray(Object[][]::new);
 198     }
 199 
 200     @DataProvider
 201     public Object[][] doubleByteBufferMaskProvider() {
 202         return BOOLEAN_MASK_GENERATORS.stream().
 203                 flatMap(fm -> DOUBLE_GENERATORS.stream().
 204                         flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
 205                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
 206                             return new Object[]{fa, fb, fm, bo};
 207                         })))).
 208                 toArray(Object[][]::new);
 209     }
 210 
 211     @DataProvider
 212     public Object[][] doubleByteArrayProvider() {
 213         return DOUBLE_GENERATORS.stream().
 214                 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 215                     return new Object[]{fa, bo};
 216                 })).
 217                 toArray(Object[][]::new);
 218     }
 219 
 220     @DataProvider
 221     public Object[][] doubleByteArrayMaskProvider() {
 222         return BOOLEAN_MASK_GENERATORS.stream().
 223                 flatMap(fm -> DOUBLE_GENERATORS.stream().
 224                     flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
 225                         return new Object[]{fa, fm, bo};
 226                     }))).
 227                 toArray(Object[][]::new);
 228     }
 229 
 230     @DataProvider
 231     public Object[][] doubleByteProviderForIOOBE() {
 232         var f = DOUBLE_GENERATORS.get(0);
 233         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
 234                     return new Object[] {f, fi};
 235                 }).
 236                 toArray(Object[][]::new);
 237     }
 238 
 239     @DataProvider
 240     public Object[][] doubleByteMaskProviderForIOOBE() {
 241         var f = DOUBLE_GENERATORS.get(0);
 242         return BOOLEAN_MASK_GENERATORS.stream().
 243                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
 244                     return new Object[] {f, fi, fm};
 245                 })).
 246                 toArray(Object[][]::new);
 247     }
 248 
 249     static ByteBuffer toBuffer(double[] a, IntFunction<ByteBuffer> fb) {
 250         ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
 251         for (double v : a) {
 252             bb.putDouble(v);
 253         }
 254         return bb.clear();
 255     }
 256 
 257     static double[] bufferToArray(ByteBuffer bb) {
 258         DoubleBuffer db = bb.asDoubleBuffer();
 259         double[] d = new double[db.capacity()];
 260         db.get(0, d);
 261         return d;
 262     }
 263 
 264     static byte[] toByteArray(double[] a, IntFunction<byte[]> fb, ByteOrder bo) {
 265         byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
 266         DoubleBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).asDoubleBuffer();
 267         for (double v : a) {
 268             bb.put(v);
 269         }
 270         return b;
 271     }
 272 
 273 
 274     interface ToDoubleF {
 275         double apply(int i);
 276     }
 277 
 278     static double[] fill(int s , ToDoubleF f) {
 279         return fill(new double[s], f);
 280     }
 281 
 282     static double[] fill(double[] a, ToDoubleF f) {
 283         for (int i = 0; i < a.length; i++) {
 284             a[i] = f.apply(i);
 285         }
 286         return a;
 287     }
 288 
 289     @DontInline
 290     static DoubleVector fromArray(double[] a, int i) {
 291         return DoubleVector.fromArray(SPECIES, a, i);
 292     }
 293 
 294     @DontInline
 295     static DoubleVector fromArray(double[] a, int i, VectorMask<Double> m) {
 296         return DoubleVector.fromArray(SPECIES, a, i, m);
 297     }
 298 
 299     @DontInline
 300     static void intoArray(DoubleVector v, double[] a, int i) {
 301         v.intoArray(a, i);
 302     }
 303 
 304     @DontInline
 305     static void intoArray(DoubleVector v, double[] a, int i, VectorMask<Double> m) {
 306         v.intoArray(a, i, m);
 307     }
 308 
 309     @DontInline
 310     static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo) {
 311         return DoubleVector.fromByteArray(SPECIES, a, i, bo);
 312     }
 313 
 314     @DontInline
 315     static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Double> m) {
 316         return DoubleVector.fromByteArray(SPECIES, a, i, bo, m);
 317     }
 318 
 319     @DontInline
 320     static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo) {
 321         v.intoByteArray(a, i, bo);
 322     }
 323 
 324     @DontInline
 325     static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo, VectorMask<Double> m) {
 326         v.intoByteArray(a, i, bo, m);
 327     }
 328 
 329     @DontInline
 330     static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
 331         return DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
 332     }
 333 
 334     @DontInline
 335     static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) {
 336         return DoubleVector.fromByteBuffer(SPECIES, a, i, bo, m);
 337     }
 338 
 339     @DontInline
 340     static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo) {
 341         v.intoByteBuffer(a, i, bo);
 342     }
 343 
 344     @DontInline
 345     static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) {
 346         v.intoByteBuffer(a, i, bo, m);
 347     }
 348 
 349 
 350     @Test(dataProvider = "doubleProvider")
 351     static void loadStoreArray(IntFunction<double[]> fa) {
 352         double[] a = fa.apply(SPECIES.length());
 353         double[] r = new double[a.length];
 354 
 355         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 356             for (int i = 0; i < a.length; i += SPECIES.length()) {
 357                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 358                 av.intoArray(r, i);
 359             }
 360         }
 361         Assert.assertEquals(r, a);
 362     }
 363 
 364     @Test(dataProvider = "doubleProviderForIOOBE")
 365     static void loadArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 366         double[] a = fa.apply(SPECIES.length());
 367         double[] r = new double[a.length];
 368 
 369         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 370             for (int i = 0; i < a.length; i += SPECIES.length()) {
 371                 DoubleVector av = fromArray(a, i);
 372                 av.intoArray(r, i);
 373             }
 374         }
 375 
 376         int index = fi.apply(a.length);
 377         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 378         try {
 379             fromArray(a, index);
 380             if (shouldFail) {
 381                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 382             }
 383         } catch (IndexOutOfBoundsException e) {
 384             if (!shouldFail) {
 385                 Assert.fail("Unexpected IndexOutOfBoundsException");
 386             }
 387         }
 388     }
 389 
 390     @Test(dataProvider = "doubleProviderForIOOBE")
 391     static void storeArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 392         double[] a = fa.apply(SPECIES.length());
 393         double[] r = new double[a.length];
 394 
 395         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 396             for (int i = 0; i < a.length; i += SPECIES.length()) {
 397                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 398                 intoArray(av, r, i);
 399             }
 400         }
 401 
 402         int index = fi.apply(a.length);
 403         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
 404         try {
 405             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
 406             intoArray(av, r, index);
 407             if (shouldFail) {
 408                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 409             }
 410         } catch (IndexOutOfBoundsException e) {
 411             if (!shouldFail) {
 412                 Assert.fail("Unexpected IndexOutOfBoundsException");
 413             }
 414         }
 415     }
 416 
 417 
 418     @Test(dataProvider = "doubleMaskProvider")
 419     static void loadStoreMaskArray(IntFunction<double[]> fa,
 420                                    IntFunction<boolean[]> fm) {
 421         double[] a = fa.apply(SPECIES.length());
 422         double[] r = new double[a.length];
 423         boolean[] mask = fm.apply(SPECIES.length());
 424         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 425 
 426         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 427             for (int i = 0; i < a.length; i += SPECIES.length()) {
 428                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask);
 429                 av.intoArray(r, i);
 430             }
 431         }
 432         assertArraysEquals(r, a, mask);
 433 
 434 
 435         r = new double[a.length];
 436 
 437         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 438             for (int i = 0; i < a.length; i += SPECIES.length()) {
 439                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 440                 av.intoArray(r, i, vmask);
 441             }
 442         }
 443         assertArraysEquals(r, a, mask);
 444     }
 445 
 446     @Test(dataProvider = "doubleMaskProviderForIOOBE")
 447     static void loadArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 448         double[] a = fa.apply(SPECIES.length());
 449         double[] r = new double[a.length];
 450         boolean[] mask = fm.apply(SPECIES.length());
 451         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 452 
 453         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 454             for (int i = 0; i < a.length; i += SPECIES.length()) {
 455                 DoubleVector av = fromArray(a, i, vmask);
 456                 av.intoArray(r, i);
 457             }
 458         }
 459 
 460         int index = fi.apply(a.length);
 461         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 462         try {
 463             fromArray(a, index, vmask);
 464             if (shouldFail) {
 465                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 466             }
 467         } catch (IndexOutOfBoundsException e) {
 468             if (!shouldFail) {
 469                 Assert.fail("Unexpected IndexOutOfBoundsException");
 470             }
 471         }
 472     }
 473 
 474     @Test(dataProvider = "doubleMaskProviderForIOOBE")
 475     static void storeArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 476         double[] a = fa.apply(SPECIES.length());
 477         double[] r = new double[a.length];
 478         boolean[] mask = fm.apply(SPECIES.length());
 479         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 480 
 481         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 482             for (int i = 0; i < a.length; i += SPECIES.length()) {
 483                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 484                 intoArray(av, r, i, vmask);
 485             }
 486         }
 487 
 488         int index = fi.apply(a.length);
 489         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
 490         try {
 491             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
 492             intoArray(av, a, index, vmask);
 493             if (shouldFail) {
 494                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 495             }
 496         } catch (IndexOutOfBoundsException e) {
 497             if (!shouldFail) {
 498                 Assert.fail("Unexpected IndexOutOfBoundsException");
 499             }
 500         }
 501     }
 502 
 503 
 504     @Test(dataProvider = "doubleMaskProvider")
 505     static void loadStoreMask(IntFunction<double[]> fa,
 506                               IntFunction<boolean[]> fm) {
 507         boolean[] mask = fm.apply(SPECIES.length());
 508         boolean[] r = new boolean[mask.length];
 509 
 510         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 511             for (int i = 0; i < mask.length; i += SPECIES.length()) {
 512                 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, i);
 513                 vmask.intoArray(r, i);
 514             }
 515         }
 516         Assert.assertEquals(r, mask);
 517     }
 518 
 519 
 520     @Test(dataProvider = "doubleByteBufferProvider")
 521     static void loadStoreByteBuffer(IntFunction<double[]> fa,
 522                                     IntFunction<ByteBuffer> fb,
 523                                     ByteOrder bo) {
 524         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
 525         ByteBuffer r = fb.apply(a.limit());
 526 
 527         int l = a.limit();
 528         int s = SPECIES.vectorByteSize();
 529 
 530         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 531             for (int i = 0; i < l; i += s) {
 532                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
 533                 av.intoByteBuffer(r, i, bo);
 534             }
 535         }
 536         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 537         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 538         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 539         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 540         Assert.assertEquals(r, a, "Buffers not equal");
 541     }
 542 
 543     @Test(dataProvider = "doubleByteProviderForIOOBE")
 544     static void loadByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 545         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 546         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 547 
 548         int l = a.limit();
 549         int s = SPECIES.vectorByteSize();
 550 
 551         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 552             for (int i = 0; i < l; i += s) {
 553                 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
 554                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 555             }
 556         }
 557 
 558         int index = fi.apply(a.limit());
 559         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 560         try {
 561             fromByteBuffer(a, index, ByteOrder.nativeOrder());
 562             if (shouldFail) {
 563                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 564             }
 565         } catch (IndexOutOfBoundsException e) {
 566             if (!shouldFail) {
 567                 Assert.fail("Unexpected IndexOutOfBoundsException");
 568             }
 569         }
 570     }
 571 
 572     @Test(dataProvider = "doubleByteProviderForIOOBE")
 573     static void storeByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 574         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 575         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 576 
 577         int l = a.limit();
 578         int s = SPECIES.vectorByteSize();
 579 
 580         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 581             for (int i = 0; i < l; i += s) {
 582                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 583                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
 584             }
 585         }
 586 
 587         int index = fi.apply(a.limit());
 588         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
 589         try {
 590             DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 591             intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
 592             if (shouldFail) {
 593                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 594             }
 595         } catch (IndexOutOfBoundsException e) {
 596             if (!shouldFail) {
 597                 Assert.fail("Unexpected IndexOutOfBoundsException");
 598             }
 599         }
 600     }
 601 
 602 
 603     @Test(dataProvider = "doubleByteBufferMaskProvider")
 604     static void loadStoreByteBufferMask(IntFunction<double[]> fa,
 605                                         IntFunction<ByteBuffer> fb,
 606                                         IntFunction<boolean[]> fm,
 607                                         ByteOrder bo) {
 608         double[] _a = fa.apply(SPECIES.length());
 609         ByteBuffer a = toBuffer(_a, fb);
 610         ByteBuffer r = fb.apply(a.limit());
 611         boolean[] mask = fm.apply(SPECIES.length());
 612         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 613 
 614         int l = a.limit();
 615         int s = SPECIES.vectorByteSize();
 616 
 617         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 618             for (int i = 0; i < l; i += s) {
 619                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
 620                 av.intoByteBuffer(r, i, bo);
 621             }
 622         }
 623         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 624         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 625         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 626         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 627         assertArraysEquals(bufferToArray(r), _a, mask);
 628 
 629 
 630         r = fb.apply(a.limit());
 631 
 632         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 633             for (int i = 0; i < l; i += s) {
 634                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
 635                 av.intoByteBuffer(r, i, bo, vmask);
 636             }
 637         }
 638         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
 639         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
 640         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
 641         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
 642         assertArraysEquals(bufferToArray(r), _a, mask);
 643     }
 644 
 645     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
 646     static void loadByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 647         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 648         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 649         boolean[] mask = fm.apply(SPECIES.length());
 650         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 651 
 652         int l = a.limit();
 653         int s = SPECIES.vectorByteSize();
 654 
 655         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 656             for (int i = 0; i < l; i += s) {
 657                 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
 658                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
 659             }
 660         }
 661 
 662         int index = fi.apply(a.limit());
 663         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 664         try {
 665             fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
 666             if (shouldFail) {
 667                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 668             }
 669         } catch (IndexOutOfBoundsException e) {
 670             if (!shouldFail) {
 671                 Assert.fail("Unexpected IndexOutOfBoundsException");
 672             }
 673         }
 674     }
 675 
 676     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
 677     static void storeByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 678         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
 679         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
 680         boolean[] mask = fm.apply(SPECIES.length());
 681         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 682 
 683         int l = a.limit();
 684         int s = SPECIES.vectorByteSize();
 685 
 686         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 687             for (int i = 0; i < l; i += s) {
 688                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
 689                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
 690             }
 691         }
 692 
 693         int index = fi.apply(a.limit());
 694         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
 695         try {
 696             DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
 697             intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
 698             if (shouldFail) {
 699                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 700             }
 701         } catch (IndexOutOfBoundsException e) {
 702             if (!shouldFail) {
 703                 Assert.fail("Unexpected IndexOutOfBoundsException");
 704             }
 705         }
 706     }
 707 
 708 
 709     @Test(dataProvider = "doubleByteBufferProvider")
 710     static void loadStoreReadonlyByteBuffer(IntFunction<double[]> fa,
 711                                     IntFunction<ByteBuffer> fb,
 712                                     ByteOrder bo) {
 713         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
 714 
 715         try {
 716             SPECIES.zero().intoByteBuffer(a, 0, bo);
 717             Assert.fail("ReadOnlyBufferException expected");
 718         } catch (ReadOnlyBufferException e) {
 719         }
 720 
 721         try {
 722             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
 723             Assert.fail("ReadOnlyBufferException expected");
 724         } catch (ReadOnlyBufferException e) {
 725         }
 726 
 727         try {
 728             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
 729             Assert.fail("ReadOnlyBufferException expected");
 730         } catch (ReadOnlyBufferException e) {
 731         }
 732 
 733         try {
 734             VectorMask<Double> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
 735                     .laneIsValid();
 736             SPECIES.zero().intoByteBuffer(a, 0, bo, m);
 737             Assert.fail("ReadOnlyBufferException expected");
 738         } catch (ReadOnlyBufferException e) {
 739         }
 740     }
 741 
 742 
 743     @Test(dataProvider = "doubleByteArrayProvider")
 744     static void loadStoreByteArray(IntFunction<double[]> fa,
 745                                     ByteOrder bo) {
 746         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 747         byte[] r = new byte[a.length];
 748 
 749         int s = SPECIES.vectorByteSize();
 750         int l = a.length;
 751 
 752         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 753             for (int i = 0; i < l; i += s) {
 754                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo);
 755                 av.intoByteArray(r, i, bo);
 756             }
 757         }
 758         Assert.assertEquals(r, a, "Byte arrays not equal");
 759     }
 760 
 761     @Test(dataProvider = "doubleByteProviderForIOOBE")
 762     static void loadByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 763         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 764         byte[] r = new byte[a.length];
 765 
 766         int s = SPECIES.vectorByteSize();
 767         int l = a.length;
 768 
 769         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 770             for (int i = 0; i < l; i += s) {
 771                 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
 772                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 773             }
 774         }
 775 
 776         int index = fi.apply(a.length);
 777         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 778         try {
 779             fromByteArray(a, index, ByteOrder.nativeOrder());

 780             if (shouldFail) {
 781                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 782             }
 783         } catch (IndexOutOfBoundsException e) {
 784             if (!shouldFail) {
 785                 Assert.fail("Unexpected IndexOutOfBoundsException");
 786             }
 787         }
 788     }
 789 
 790     @Test(dataProvider = "doubleByteProviderForIOOBE")
 791     static void storeByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
 792         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 793         byte[] r = new byte[a.length];
 794 
 795         int s = SPECIES.vectorByteSize();
 796         int l = a.length;
 797 
 798         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 799             for (int i = 0; i < l; i += s) {
 800                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 801                 intoByteArray(av, r, i, ByteOrder.nativeOrder());
 802             }
 803         }
 804 
 805         int index = fi.apply(a.length);
 806         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
 807         try {
 808             DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 809             intoByteArray(av, r, index, ByteOrder.nativeOrder());
 810             if (shouldFail) {
 811                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 812             }
 813         } catch (IndexOutOfBoundsException e) {
 814             if (!shouldFail) {
 815                 Assert.fail("Unexpected IndexOutOfBoundsException");
 816             }
 817         }
 818     }
 819 
 820 
 821     @Test(dataProvider = "doubleByteArrayMaskProvider")
 822     static void loadStoreByteArrayMask(IntFunction<double[]> fa,
 823                                   IntFunction<boolean[]> fm,
 824                                   ByteOrder bo) {
 825         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
 826         byte[] r = new byte[a.length];
 827         boolean[] mask = fm.apply(SPECIES.length());
 828         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 829 
 830         int s = SPECIES.vectorByteSize();
 831         int l = a.length;
 832 
 833         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 834           for (int i = 0; i < l; i += s) {
 835               DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo, vmask);
 836               av.intoByteArray(r, i, bo);
 837           }
 838         }
 839         assertArraysEquals(r, a, mask);
 840 
 841 
 842         r = new byte[a.length];
 843 
 844         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 845             for (int i = 0; i < l; i += s) {
 846                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo);
 847                 av.intoByteArray(r, i, bo, vmask);
 848             }
 849         }
 850         assertArraysEquals(r, a, mask);
 851     }
 852 
 853     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
 854     static void loadByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 855         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 856         byte[] r = new byte[a.length];
 857         boolean[] mask = fm.apply(SPECIES.length());
 858         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 859 
 860         int s = SPECIES.vectorByteSize();
 861         int l = a.length;


 862 
 863         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 864             for (int i = 0; i < l; i += s) {
 865                 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
 866                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
 867             }
 868         }
 869 
 870         int index = fi.apply(a.length);
 871         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 872         try {
 873             fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
 874             if (shouldFail) {
 875                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 876             }
 877         } catch (IndexOutOfBoundsException e) {
 878             if (!shouldFail) {
 879                 Assert.fail("Unexpected IndexOutOfBoundsException");
 880             }
 881         }
 882     }
 883 
 884     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
 885     static void storeByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
 886         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
 887         byte[] r = new byte[a.length];
 888         boolean[] mask = fm.apply(SPECIES.length());
 889         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 890 
 891         int s = SPECIES.vectorByteSize();
 892         int l = a.length;
 893 
 894         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 895             for (int i = 0; i < l; i += s) {
 896                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
 897                 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
 898             }
 899         }
 900 
 901         int index = fi.apply(a.length);
 902         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
 903         try {
 904             DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
 905             intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
 906             if (shouldFail) {
 907                 Assert.fail("Failed to throw IndexOutOfBoundsException");
 908             }
 909         } catch (IndexOutOfBoundsException e) {
 910             if (!shouldFail) {
 911                 Assert.fail("Unexpected IndexOutOfBoundsException");
 912             }
 913         }
 914     }
 915 
 916     @Test(dataProvider = "maskProvider")
 917     static void loadStoreMask(IntFunction<boolean[]> fm) {
 918         boolean[] a = fm.apply(SPECIES.length());
 919         boolean[] r = new boolean[a.length];
 920 
 921         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 922             for (int i = 0; i < a.length; i += SPECIES.length()) {
 923                 VectorMask<Double> vmask = SPECIES.loadMask(a, i);
 924                 vmask.intoArray(r, i);
 925             }
 926         }
 927         Assert.assertEquals(r, a);
 928     }
 929 

 930     @Test
 931     static void loadStoreShuffle() {
 932         IntUnaryOperator fn = a -> a + 5;
 933         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 934             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
 935             int [] r = shuffle.toArray();
 936 
 937             int [] a = expectedShuffle(SPECIES.length(), fn);
 938             Assert.assertEquals(r, a);
 939        }
 940     }
 941 
 942 
 943 
 944 
 945 
 946     // Gather/Scatter load/store tests
 947 
 948     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap) {
 949         int i = 0;
 950         int j = 0;
 951         try {
 952             for (; i < a.length; i += SPECIES.length()) {
 953                 j = i;
 954                 for (; j < i + SPECIES.length(); j++) {
 955                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
 956                 }
 957             }
 958         } catch (AssertionError e) {
 959             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
 960         }
 961     }
 962 
 963     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
 964         int i = 0;
 965         int j = 0;
 966         try {
 967             for (; i < a.length; i += SPECIES.length()) {
 968                 j = i;
 969                 for (; j < i + SPECIES.length(); j++) {
 970                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0);
 971                 }
 972             }
 973         } catch (AssertionError e) {
 974             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0, "at index #" + j);
 975         }
 976     }
 977 
 978     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
 979         double[] expected = new double[r.length];
 980 
 981         // Store before checking, since the same location may be stored to more than once
 982         for (int i = 0; i < a.length; i += SPECIES.length()) {
 983             for (int j = i; j < i + SPECIES.length(); j++) {
 984                 if (mask[j % SPECIES.length()]) {
 985                     expected[i + indexMap[j]] = a[j];
 986                 }
 987             }
 988         }
 989 
 990         Assert.assertEquals(r, expected);
 991     }
 992 
 993     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap) {
 994         double[] expected = new double[r.length];
 995 
 996         // Store before checking, since the same location may be stored to more than once
 997         for (int i = 0; i < a.length; i += SPECIES.length()) {
 998             for (int j = i; j < i + SPECIES.length(); j++) {
 999                 expected[i + indexMap[j]] = a[j];
1000             }
1001         }
1002 
1003         Assert.assertEquals(r, expected);
1004     }
1005 
1006     @DataProvider
1007     public Object[][] gatherScatterProvider() {
1008         return INT_INDEX_GENERATORS.stream().
1009                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1010                     return new Object[] {fa, fs};
1011                 })).
1012                 toArray(Object[][]::new);
1013     }
1014 
1015     @DataProvider
1016     public Object[][] gatherScatterMaskProvider() {
1017         return BOOLEAN_MASK_GENERATORS.stream().
1018           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1019             DOUBLE_GENERATORS.stream().map(fa -> {
1020                     return new Object[] {fa, fm, fs};
1021             }))).
1022             toArray(Object[][]::new);
1023     }
1024 
1025 
1026     @Test(dataProvider = "gatherScatterProvider")
1027     static void gather(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1028         double[] a = fa.apply(SPECIES.length());
1029         int[] b = fs.apply(a.length, SPECIES.length());
1030         double[] r = new double[a.length];
1031 
1032         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1033             for (int i = 0; i < a.length; i += SPECIES.length()) {
1034                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i);
1035                 av.intoArray(r, i);
1036             }
1037         }
1038 
1039         assertGatherArraysEquals(r, a, b);
1040     }
1041 
1042     @Test(dataProvider = "gatherScatterMaskProvider")
1043     static void gatherMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1044         double[] a = fa.apply(SPECIES.length());
1045         int[] b = fs.apply(a.length, SPECIES.length());
1046         double[] r = new double[a.length];
1047         boolean[] mask = fm.apply(SPECIES.length());
1048         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1049 
1050         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1051             for (int i = 0; i < a.length; i += SPECIES.length()) {
1052                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i, vmask);
1053                 av.intoArray(r, i);
1054             }
1055         }
1056 
1057         assertGatherArraysEquals(r, a, b, mask);
1058     }
1059 
1060     @Test(dataProvider = "gatherScatterProvider")
1061     static void scatter(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1062         double[] a = fa.apply(SPECIES.length());
1063         int[] b = fs.apply(a.length, SPECIES.length());
1064         double[] r = new double[a.length];
1065 
1066         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1067             for (int i = 0; i < a.length; i += SPECIES.length()) {
1068                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1069                 av.intoArray(r, i, b, i);
1070             }
1071         }
1072 
1073         assertScatterArraysEquals(r, a, b);
1074     }
1075 
1076     @Test(dataProvider = "gatherScatterMaskProvider")
1077     static void scatterMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1078         double[] a = fa.apply(SPECIES.length());
1079         int[] b = fs.apply(a.length, SPECIES.length());
1080         double[] r = new double[a.length];
1081         boolean[] mask = fm.apply(SPECIES.length());
1082         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1083 
1084         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1085             for (int i = 0; i < a.length; i += SPECIES.length()) {
1086                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1087                 av.intoArray(r, i, b, i, vmask);
1088             }
1089         }
1090 
1091         assertScatterArraysEquals(r, a, b, mask);
1092     }
1093 
1094 
1095 
1096 }
--- EOF ---