1 /*
   2  * Copyright (c) 2018, 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
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @modules jdk.incubator.vector
  27  * @run testng/othervm -ea -esa Double512VectorTests
  28  */
  29 
  30 import jdk.incubator.vector.VectorShape;
  31 import jdk.incubator.vector.VectorSpecies;
  32 import jdk.incubator.vector.VectorShuffle;
  33 import jdk.incubator.vector.VectorMask;
  34 import jdk.incubator.vector.Vector;
  35 
  36 import jdk.incubator.vector.DoubleVector;
  37 
  38 import org.testng.Assert;
  39 import org.testng.annotations.DataProvider;
  40 import org.testng.annotations.Test;
  41 
  42 import java.lang.Integer;
  43 import java.util.List;
  44 import java.util.Arrays;
  45 import java.util.function.BiFunction;
  46 import java.util.function.IntFunction;
  47 import java.util.stream.Collectors;
  48 import java.util.stream.Stream;
  49 
  50 @Test
  51 public class Double512VectorTests extends AbstractVectorTest {
  52 
  53     static final VectorSpecies<Double> SPECIES =
  54                 DoubleVector.SPECIES_512;
  55 
  56     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  57 
  58     interface FUnOp {
  59         double apply(double a);
  60     }
  61 
  62     static void assertArraysEquals(double[] a, double[] r, FUnOp f) {
  63         int i = 0;
  64         try {
  65             for (; i < a.length; i++) {
  66                 Assert.assertEquals(r[i], f.apply(a[i]));
  67             }
  68         } catch (AssertionError e) {
  69             Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]);
  70         }
  71     }
  72 
  73     static void assertArraysEquals(double[] a, double[] r, boolean[] mask, FUnOp f) {
  74         int i = 0;
  75         try {
  76             for (; i < a.length; i++) {
  77                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]);
  78             }
  79         } catch (AssertionError e) {
  80             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i], "at index #" + i + ", input = " + a[i] + ", mask = " + mask[i % SPECIES.length()]);
  81         }
  82     }
  83 
  84     interface FReductionOp {
  85         double apply(double[] a, int idx);
  86     }
  87 
  88     interface FReductionAllOp {
  89         double apply(double[] a);
  90     }
  91 
  92     static void assertReductionArraysEquals(double[] a, double[] b, double c,
  93                                             FReductionOp f, FReductionAllOp fa) {
  94         int i = 0;
  95         try {
  96             Assert.assertEquals(c, fa.apply(a));
  97             for (; i < a.length; i += SPECIES.length()) {
  98                 Assert.assertEquals(b[i], f.apply(a, i));
  99             }
 100         } catch (AssertionError e) {
 101             Assert.assertEquals(c, fa.apply(a), "Final result is incorrect!");
 102             Assert.assertEquals(b[i], f.apply(a, i), "at index #" + i);
 103         }
 104     }
 105 
 106     interface FBoolReductionOp {
 107         boolean apply(boolean[] a, int idx);
 108     }
 109 
 110     static void assertReductionBoolArraysEquals(boolean[] a, boolean[] b, FBoolReductionOp f) {
 111         int i = 0;
 112         try {
 113             for (; i < a.length; i += SPECIES.length()) {
 114                 Assert.assertEquals(f.apply(a, i), b[i]);
 115             }
 116         } catch (AssertionError e) {
 117             Assert.assertEquals(f.apply(a, i), b[i], "at index #" + i);
 118         }
 119     }
 120 
 121     static void assertInsertArraysEquals(double[] a, double[] b, double element, int index) {
 122         int i = 0;
 123         try {
 124             for (; i < a.length; i += 1) {
 125                 if(i%SPECIES.length() == index) {
 126                     Assert.assertEquals(b[i], element);
 127                 } else {
 128                     Assert.assertEquals(b[i], a[i]);
 129                 }
 130             }
 131         } catch (AssertionError e) {
 132             if (i%SPECIES.length() == index) {
 133                 Assert.assertEquals(b[i], element, "at index #" + i);
 134             } else {
 135                 Assert.assertEquals(b[i], a[i], "at index #" + i);
 136             }
 137         }
 138     }
 139 
 140     static void assertRearrangeArraysEquals(double[] a, double[] r, int[] order, int vector_len) {
 141         int i = 0, j = 0;
 142         try {
 143             for (; i < a.length; i += vector_len) {
 144                 for (j = 0; j < vector_len; j++) {
 145                     Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 146                 }
 147             }
 148         } catch (AssertionError e) {
 149             int idx = i + j;
 150             Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]);
 151         }
 152     }
 153 
 154     interface FBinOp {
 155         double apply(double a, double b);
 156     }
 157 
 158     interface FBinMaskOp {
 159         double apply(double a, double b, boolean m);
 160 
 161         static FBinMaskOp lift(FBinOp f) {
 162             return (a, b, m) -> m ? f.apply(a, b) : a;
 163         }
 164     }
 165 
 166     static void assertArraysEquals(double[] a, double[] b, double[] r, FBinOp f) {
 167         int i = 0;
 168         try {
 169             for (; i < a.length; i++) {
 170                 Assert.assertEquals(r[i], f.apply(a[i], b[i]));
 171             }
 172         } catch (AssertionError e) {
 173             Assert.assertEquals(f.apply(a[i], b[i]), r[i], "(" + a[i] + ", " + b[i] + ") at index #" + i);
 174         }
 175     }
 176 
 177     static void assertArraysEquals(double[] a, double[] b, double[] r, boolean[] mask, FBinOp f) {
 178         assertArraysEquals(a, b, r, mask, FBinMaskOp.lift(f));
 179     }
 180 
 181     static void assertArraysEquals(double[] a, double[] b, double[] r, boolean[] mask, FBinMaskOp f) {
 182         int i = 0;
 183         try {
 184             for (; i < a.length; i++) {
 185                 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]));
 186             }
 187         } catch (AssertionError err) {
 188             Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", mask = " + mask[i % SPECIES.length()]);
 189         }
 190     }
 191 
 192     static void assertShiftArraysEquals(double[] a, double[] b, double[] r, FBinOp f) {
 193         int i = 0;
 194         int j = 0;
 195         try {
 196             for (; j < a.length; j += SPECIES.length()) {
 197                 for (i = 0; i < SPECIES.length(); i++) {
 198                     Assert.assertEquals(f.apply(a[i+j], b[j]), r[i+j]);
 199                 }
 200             }
 201         } catch (AssertionError e) {
 202             Assert.assertEquals(f.apply(a[i+j], b[j]), r[i+j], "at index #" + i + ", " + j);
 203         }
 204     }
 205 
 206     static void assertShiftArraysEquals(double[] a, double[] b, double[] r, boolean[] mask, FBinOp f) {
 207         assertShiftArraysEquals(a, b, r, mask, FBinMaskOp.lift(f));
 208     }
 209 
 210     static void assertShiftArraysEquals(double[] a, double[] b, double[] r, boolean[] mask, FBinMaskOp f) {
 211         int i = 0;
 212         int j = 0;
 213         try {
 214             for (; j < a.length; j += SPECIES.length()) {
 215                 for (i = 0; i < SPECIES.length(); i++) {
 216                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]));
 217                 }
 218             }
 219         } catch (AssertionError err) {
 220             Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", input2 = " + b[j] + ", mask = " + mask[i]);
 221         }
 222     }
 223 
 224     interface FTernOp {
 225         double apply(double a, double b, double c);
 226     }
 227 
 228     interface FTernMaskOp {
 229         double apply(double a, double b, double c, boolean m);
 230 
 231         static FTernMaskOp lift(FTernOp f) {
 232             return (a, b, c, m) -> m ? f.apply(a, b, c) : a;
 233         }
 234     }
 235 
 236     static void assertArraysEquals(double[] a, double[] b, double[] c, double[] r, FTernOp f) {
 237         int i = 0;
 238         try {
 239             for (; i < a.length; i++) {
 240                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]));
 241             }
 242         } catch (AssertionError e) {
 243             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 244         }
 245     }
 246 
 247     static void assertArraysEquals(double[] a, double[] b, double[] c, double[] r, boolean[] mask, FTernOp f) {
 248         assertArraysEquals(a, b, c, r, mask, FTernMaskOp.lift(f));
 249     }
 250 
 251     static void assertArraysEquals(double[] a, double[] b, double[] c, double[] r, boolean[] mask, FTernMaskOp f) {
 252         int i = 0;
 253         try {
 254             for (; i < a.length; i++) {
 255                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]));
 256             }
 257         } catch (AssertionError err) {
 258             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = "
 259               + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 260         }
 261     }
 262 
 263     static boolean isWithin1Ulp(double actual, double expected) {
 264         if (Double.isNaN(expected) && !Double.isNaN(actual)) {
 265             return false;
 266         } else if (!Double.isNaN(expected) && Double.isNaN(actual)) {
 267             return false;
 268         }
 269 
 270         double low = Math.nextDown(expected);
 271         double high = Math.nextUp(expected);
 272 
 273         if (Double.compare(low, expected) > 0) {
 274             return false;
 275         }
 276 
 277         if (Double.compare(high, expected) < 0) {
 278             return false;
 279         }
 280 
 281         return true;
 282     }
 283 
 284     static void assertArraysEqualsWithinOneUlp(double[] a, double[] r, FUnOp mathf, FUnOp strictmathf) {
 285         int i = 0;
 286         try {
 287             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 288             for (; i < a.length; i++) {
 289                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i])) == 0 ||
 290                                     isWithin1Ulp(r[i], strictmathf.apply(a[i])));
 291             }
 292         } catch (AssertionError e) {
 293             Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i])) == 0, "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i]));
 294             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i])), "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i]));
 295         }
 296     }
 297 
 298     static void assertArraysEqualsWithinOneUlp(double[] a, double[] b, double[] r, FBinOp mathf, FBinOp strictmathf) {
 299         int i = 0;
 300         try {
 301             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 302             for (; i < a.length; i++) {
 303                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i], b[i])) == 0 ||
 304                                     isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])));
 305             }
 306         } catch (AssertionError e) {
 307             Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i], b[i])) == 0, "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i], b[i]));
 308             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i], b[i]));
 309         }
 310     }
 311 
 312     interface FBinArrayOp {
 313         double apply(double[] a, int b);
 314     }
 315 
 316     static void assertArraysEquals(double[] a, double[] r, FBinArrayOp f) {
 317         int i = 0;
 318         try {
 319             for (; i < a.length; i++) {
 320                 Assert.assertEquals(f.apply(a, i), r[i]);
 321             }
 322         } catch (AssertionError e) {
 323             Assert.assertEquals(f.apply(a,i), r[i], "at index #" + i);
 324         }
 325     }
 326     interface FGatherScatterOp {
 327         double[] apply(double[] a, int ix, int[] b, int iy);
 328     }
 329 
 330     static void assertArraysEquals(double[] a, int[] b, double[] r, FGatherScatterOp f) {
 331         int i = 0;
 332         try {
 333             for (; i < a.length; i += SPECIES.length()) {
 334                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 335                   f.apply(a, i, b, i));
 336             }
 337         } catch (AssertionError e) {
 338             double[] ref = f.apply(a, i, b, i);
 339             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 340             Assert.assertEquals(ref, res,
 341               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 342               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 343               + ", b: "
 344               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 345               + " at index #" + i);
 346         }
 347     }
 348 
 349 
 350     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
 351             withToString("double[-i * 5]", (int s) -> {
 352                 return fill(s * 1000,
 353                             i -> (double)(-i * 5));
 354             }),
 355             withToString("double[i * 5]", (int s) -> {
 356                 return fill(s * 1000,
 357                             i -> (double)(i * 5));
 358             }),
 359             withToString("double[i + 1]", (int s) -> {
 360                 return fill(s * 1000,
 361                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
 362             }),
 363             withToString("double[cornerCaseValue(i)]", (int s) -> {
 364                 return fill(s * 1000,
 365                             i -> cornerCaseValue(i));
 366             })
 367     );
 368 
 369     // Create combinations of pairs
 370     // @@@ Might be sensitive to order e.g. div by 0
 371     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_PAIRS =
 372         Stream.of(DOUBLE_GENERATORS.get(0)).
 373                 flatMap(fa -> DOUBLE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
 374                 collect(Collectors.toList());
 375 
 376     @DataProvider
 377     public Object[][] boolUnaryOpProvider() {
 378         return BOOL_ARRAY_GENERATORS.stream().
 379                 map(f -> new Object[]{f}).
 380                 toArray(Object[][]::new);
 381     }
 382 
 383     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_TRIPLES =
 384         DOUBLE_GENERATOR_PAIRS.stream().
 385                 flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
 386                 collect(Collectors.toList());
 387 
 388     @DataProvider
 389     public Object[][] doubleBinaryOpProvider() {
 390         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
 391                 toArray(Object[][]::new);
 392     }
 393 
 394     @DataProvider
 395     public Object[][] doubleIndexedOpProvider() {
 396         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
 397                 toArray(Object[][]::new);
 398     }
 399 
 400     @DataProvider
 401     public Object[][] doubleBinaryOpMaskProvider() {
 402         return BOOLEAN_MASK_GENERATORS.stream().
 403                 flatMap(fm -> DOUBLE_GENERATOR_PAIRS.stream().map(lfa -> {
 404                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
 405                 })).
 406                 toArray(Object[][]::new);
 407     }
 408 
 409     @DataProvider
 410     public Object[][] doubleTernaryOpProvider() {
 411         return DOUBLE_GENERATOR_TRIPLES.stream().map(List::toArray).
 412                 toArray(Object[][]::new);
 413     }
 414 
 415     @DataProvider
 416     public Object[][] doubleTernaryOpMaskProvider() {
 417         return BOOLEAN_MASK_GENERATORS.stream().
 418                 flatMap(fm -> DOUBLE_GENERATOR_TRIPLES.stream().map(lfa -> {
 419                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
 420                 })).
 421                 toArray(Object[][]::new);
 422     }
 423 
 424     @DataProvider
 425     public Object[][] doubleUnaryOpProvider() {
 426         return DOUBLE_GENERATORS.stream().
 427                 map(f -> new Object[]{f}).
 428                 toArray(Object[][]::new);
 429     }
 430 
 431     @DataProvider
 432     public Object[][] doubleUnaryOpMaskProvider() {
 433         return BOOLEAN_MASK_GENERATORS.stream().
 434                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
 435                     return new Object[] {fa, fm};
 436                 })).
 437                 toArray(Object[][]::new);
 438     }
 439 
 440     @DataProvider
 441     public Object[][] doubleUnaryOpShuffleProvider() {
 442         return INT_SHUFFLE_GENERATORS.stream().
 443                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
 444                     return new Object[] {fa, fs};
 445                 })).
 446                 toArray(Object[][]::new);
 447     }
 448 
 449     @DataProvider
 450     public Object[][] doubleUnaryOpIndexProvider() {
 451         return INT_INDEX_GENERATORS.stream().
 452                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
 453                     return new Object[] {fa, fs};
 454                 })).
 455                 toArray(Object[][]::new);
 456     }
 457 
 458 
 459     static final List<IntFunction<double[]>> DOUBLE_COMPARE_GENERATORS = List.of(
 460             withToString("double[i]", (int s) -> {
 461                 return fill(s * 1000,
 462                             i -> (double)i);
 463             }),
 464             withToString("double[i + 1]", (int s) -> {
 465                 return fill(s * 1000,
 466                             i -> (double)(i + 1));
 467             }),
 468             withToString("double[i - 2]", (int s) -> {
 469                 return fill(s * 1000,
 470                             i -> (double)(i - 2));
 471             }),
 472             withToString("double[zigZag(i)]", (int s) -> {
 473                 return fill(s * 1000,
 474                             i -> i%3 == 0 ? (double)i : (i%3 == 1 ? (double)(i + 1) : (double)(i - 2)));
 475             }),
 476             withToString("double[cornerCaseValue(i)]", (int s) -> {
 477                 return fill(s * 1000,
 478                             i -> cornerCaseValue(i));
 479             })
 480     );
 481 
 482     static final List<List<IntFunction<double[]>>> DOUBLE_COMPARE_GENERATOR_PAIRS =
 483         DOUBLE_COMPARE_GENERATORS.stream().
 484                 flatMap(fa -> DOUBLE_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))).
 485                 collect(Collectors.toList());
 486 
 487     @DataProvider
 488     public Object[][] doubleCompareOpProvider() {
 489         return DOUBLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
 490                 toArray(Object[][]::new);
 491     }
 492 
 493     interface ToDoubleF {
 494         double apply(int i);
 495     }
 496 
 497     static double[] fill(int s , ToDoubleF f) {
 498         return fill(new double[s], f);
 499     }
 500 
 501     static double[] fill(double[] a, ToDoubleF f) {
 502         for (int i = 0; i < a.length; i++) {
 503             a[i] = f.apply(i);
 504         }
 505         return a;
 506     }
 507 
 508     static double cornerCaseValue(int i) {
 509         switch(i % 7) {
 510             case 0:
 511                 return Double.MAX_VALUE;
 512             case 1:
 513                 return Double.MIN_VALUE;
 514             case 2:
 515                 return Double.NEGATIVE_INFINITY;
 516             case 3:
 517                 return Double.POSITIVE_INFINITY;
 518             case 4:
 519                 return Double.NaN;
 520             case 5:
 521                 return (double)0.0;
 522             default:
 523                 return (double)-0.0;
 524         }
 525     }
 526    static double get(double[] a, int i) {
 527        return (double) a[i];
 528    }
 529 
 530    static final IntFunction<double[]> fr = (vl) -> {
 531         int length = 1000 * vl;
 532         return new double[length];
 533     };
 534 
 535     static final IntFunction<boolean[]> fmr = (vl) -> {
 536         int length = 1000 * vl;
 537         return new boolean[length];
 538     };
 539     static double add(double a, double b) {
 540         return (double)(a + b);
 541     }
 542 
 543     @Test(dataProvider = "doubleBinaryOpProvider")
 544     static void addDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 545         double[] a = fa.apply(SPECIES.length());
 546         double[] b = fb.apply(SPECIES.length());
 547         double[] r = fr.apply(SPECIES.length());
 548 
 549         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 550             for (int i = 0; i < a.length; i += SPECIES.length()) {
 551                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 552                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 553                 av.add(bv).intoArray(r, i);
 554             }
 555         }
 556 
 557         assertArraysEquals(a, b, r, Double512VectorTests::add);
 558     }
 559 
 560     @Test(dataProvider = "doubleBinaryOpMaskProvider")
 561     static void addDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
 562                                           IntFunction<boolean[]> fm) {
 563         double[] a = fa.apply(SPECIES.length());
 564         double[] b = fb.apply(SPECIES.length());
 565         double[] r = fr.apply(SPECIES.length());
 566         boolean[] mask = fm.apply(SPECIES.length());
 567         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 568 
 569         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 570             for (int i = 0; i < a.length; i += SPECIES.length()) {
 571                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 572                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 573                 av.add(bv, vmask).intoArray(r, i);
 574             }
 575         }
 576 
 577         assertArraysEquals(a, b, r, mask, Double512VectorTests::add);
 578     }
 579     static double sub(double a, double b) {
 580         return (double)(a - b);
 581     }
 582 
 583     @Test(dataProvider = "doubleBinaryOpProvider")
 584     static void subDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 585         double[] a = fa.apply(SPECIES.length());
 586         double[] b = fb.apply(SPECIES.length());
 587         double[] r = fr.apply(SPECIES.length());
 588 
 589         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 590             for (int i = 0; i < a.length; i += SPECIES.length()) {
 591                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 592                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 593                 av.sub(bv).intoArray(r, i);
 594             }
 595         }
 596 
 597         assertArraysEquals(a, b, r, Double512VectorTests::sub);
 598     }
 599 
 600     @Test(dataProvider = "doubleBinaryOpMaskProvider")
 601     static void subDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
 602                                           IntFunction<boolean[]> fm) {
 603         double[] a = fa.apply(SPECIES.length());
 604         double[] b = fb.apply(SPECIES.length());
 605         double[] r = fr.apply(SPECIES.length());
 606         boolean[] mask = fm.apply(SPECIES.length());
 607         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 608 
 609         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 610             for (int i = 0; i < a.length; i += SPECIES.length()) {
 611                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 612                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 613                 av.sub(bv, vmask).intoArray(r, i);
 614             }
 615         }
 616 
 617         assertArraysEquals(a, b, r, mask, Double512VectorTests::sub);
 618     }
 619 
 620     static double div(double a, double b) {
 621         return (double)(a / b);
 622     }
 623 
 624     @Test(dataProvider = "doubleBinaryOpProvider")
 625     static void divDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 626         double[] a = fa.apply(SPECIES.length());
 627         double[] b = fb.apply(SPECIES.length());
 628         double[] r = fr.apply(SPECIES.length());
 629 
 630         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 631             for (int i = 0; i < a.length; i += SPECIES.length()) {
 632                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 633                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 634                 av.div(bv).intoArray(r, i);
 635             }
 636         }
 637 
 638         assertArraysEquals(a, b, r, Double512VectorTests::div);
 639     }
 640 
 641 
 642 
 643     @Test(dataProvider = "doubleBinaryOpMaskProvider")
 644     static void divDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
 645                                           IntFunction<boolean[]> fm) {
 646         double[] a = fa.apply(SPECIES.length());
 647         double[] b = fb.apply(SPECIES.length());
 648         double[] r = fr.apply(SPECIES.length());
 649         boolean[] mask = fm.apply(SPECIES.length());
 650         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 651 
 652         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 653             for (int i = 0; i < a.length; i += SPECIES.length()) {
 654                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 655                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 656                 av.div(bv, vmask).intoArray(r, i);
 657             }
 658         }
 659 
 660         assertArraysEquals(a, b, r, mask, Double512VectorTests::div);
 661     }
 662 
 663     static double mul(double a, double b) {
 664         return (double)(a * b);
 665     }
 666 
 667     @Test(dataProvider = "doubleBinaryOpProvider")
 668     static void mulDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 669         double[] a = fa.apply(SPECIES.length());
 670         double[] b = fb.apply(SPECIES.length());
 671         double[] r = fr.apply(SPECIES.length());
 672 
 673         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 674             for (int i = 0; i < a.length; i += SPECIES.length()) {
 675                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 676                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 677                 av.mul(bv).intoArray(r, i);
 678             }
 679         }
 680 
 681         assertArraysEquals(a, b, r, Double512VectorTests::mul);
 682     }
 683 
 684     @Test(dataProvider = "doubleBinaryOpMaskProvider")
 685     static void mulDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
 686                                           IntFunction<boolean[]> fm) {
 687         double[] a = fa.apply(SPECIES.length());
 688         double[] b = fb.apply(SPECIES.length());
 689         double[] r = fr.apply(SPECIES.length());
 690         boolean[] mask = fm.apply(SPECIES.length());
 691         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
 692 
 693         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 694             for (int i = 0; i < a.length; i += SPECIES.length()) {
 695                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 696                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 697                 av.mul(bv, vmask).intoArray(r, i);
 698             }
 699         }
 700 
 701         assertArraysEquals(a, b, r, mask, Double512VectorTests::mul);
 702     }
 703 
 704 
 705 
 706 
 707 
 708 
 709 
 710 
 711 
 712 
 713 
 714 
 715 
 716 
 717 
 718 
 719 
 720 
 721 
 722 
 723 
 724 
 725 
 726 
 727 
 728 
 729 
 730 
 731 
 732 
 733 
 734 
 735 
 736 
 737 
 738 
 739 
 740 
 741 
 742 
 743 
 744 
 745     static double max(double a, double b) {
 746         return (double)(Math.max(a, b));
 747     }
 748 
 749     @Test(dataProvider = "doubleBinaryOpProvider")
 750     static void maxDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 751         double[] a = fa.apply(SPECIES.length());
 752         double[] b = fb.apply(SPECIES.length());
 753         double[] r = fr.apply(SPECIES.length());
 754 
 755         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 756             for (int i = 0; i < a.length; i += SPECIES.length()) {
 757                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 758                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 759                 av.max(bv).intoArray(r, i);
 760             }
 761         }
 762 
 763         assertArraysEquals(a, b, r, Double512VectorTests::max);
 764     }
 765     static double min(double a, double b) {
 766         return (double)(Math.min(a, b));
 767     }
 768 
 769     @Test(dataProvider = "doubleBinaryOpProvider")
 770     static void minDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 771         double[] a = fa.apply(SPECIES.length());
 772         double[] b = fb.apply(SPECIES.length());
 773         double[] r = fr.apply(SPECIES.length());
 774 
 775         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 776             for (int i = 0; i < a.length; i += SPECIES.length()) {
 777                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 778                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 779                 av.min(bv).intoArray(r, i);
 780             }
 781         }
 782 
 783         assertArraysEquals(a, b, r, Double512VectorTests::min);
 784     }
 785 
 786 
 787 
 788 
 789 
 790 
 791     static double addLanes(double[] a, int idx) {
 792         double res = 0;
 793         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 794             res += a[i];
 795         }
 796 
 797         return res;
 798     }
 799 
 800     static double addLanes(double[] a) {
 801         double res = 0;
 802         for (int i = 0; i < a.length; i += SPECIES.length()) {
 803             double tmp = 0;
 804             for (int j = 0; j < SPECIES.length(); j++) {
 805                 tmp += a[i + j];
 806             }
 807             res += tmp;
 808         }
 809 
 810         return res;
 811     }
 812     @Test(dataProvider = "doubleUnaryOpProvider")
 813     static void addLanesDouble512VectorTests(IntFunction<double[]> fa) {
 814         double[] a = fa.apply(SPECIES.length());
 815         double[] r = fr.apply(SPECIES.length());
 816         double ra = 0;
 817 
 818         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 819             for (int i = 0; i < a.length; i += SPECIES.length()) {
 820                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 821                 r[i] = av.addLanes();
 822             }
 823         }
 824 
 825         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 826             ra = 0;
 827             for (int i = 0; i < a.length; i += SPECIES.length()) {
 828                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 829                 ra += av.addLanes();
 830             }
 831         }
 832 
 833         assertReductionArraysEquals(a, r, ra, Double512VectorTests::addLanes, Double512VectorTests::addLanes);
 834     }
 835     static double mulLanes(double[] a, int idx) {
 836         double res = 1;
 837         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 838             res *= a[i];
 839         }
 840 
 841         return res;
 842     }
 843 
 844     static double mulLanes(double[] a) {
 845         double res = 1;
 846         for (int i = 0; i < a.length; i += SPECIES.length()) {
 847             double tmp = 1;
 848             for (int j = 0; j < SPECIES.length(); j++) {
 849                 tmp *= a[i + j];
 850             }
 851             res *= tmp;
 852         }
 853 
 854         return res;
 855     }
 856     @Test(dataProvider = "doubleUnaryOpProvider")
 857     static void mulLanesDouble512VectorTests(IntFunction<double[]> fa) {
 858         double[] a = fa.apply(SPECIES.length());
 859         double[] r = fr.apply(SPECIES.length());
 860         double ra = 1;
 861 
 862         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 863             for (int i = 0; i < a.length; i += SPECIES.length()) {
 864                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 865                 r[i] = av.mulLanes();
 866             }
 867         }
 868 
 869         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 870             ra = 1;
 871             for (int i = 0; i < a.length; i += SPECIES.length()) {
 872                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 873                 ra *= av.mulLanes();
 874             }
 875         }
 876 
 877         assertReductionArraysEquals(a, r, ra, Double512VectorTests::mulLanes, Double512VectorTests::mulLanes);
 878     }
 879     static double minLanes(double[] a, int idx) {
 880         double res = Double.POSITIVE_INFINITY;
 881         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 882             res = (double)Math.min(res, a[i]);
 883         }
 884 
 885         return res;
 886     }
 887 
 888     static double minLanes(double[] a) {
 889         double res = Double.POSITIVE_INFINITY;
 890         for (int i = 0; i < a.length; i++) {
 891             res = (double)Math.min(res, a[i]);
 892         }
 893 
 894         return res;
 895     }
 896     @Test(dataProvider = "doubleUnaryOpProvider")
 897     static void minLanesDouble512VectorTests(IntFunction<double[]> fa) {
 898         double[] a = fa.apply(SPECIES.length());
 899         double[] r = fr.apply(SPECIES.length());
 900         double ra = Double.POSITIVE_INFINITY;
 901 
 902         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 903             for (int i = 0; i < a.length; i += SPECIES.length()) {
 904                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 905                 r[i] = av.minLanes();
 906             }
 907         }
 908 
 909         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 910             ra = Double.POSITIVE_INFINITY;
 911             for (int i = 0; i < a.length; i += SPECIES.length()) {
 912                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 913                 ra = (double)Math.min(ra, av.minLanes());
 914             }
 915         }
 916 
 917         assertReductionArraysEquals(a, r, ra, Double512VectorTests::minLanes, Double512VectorTests::minLanes);
 918     }
 919     static double maxLanes(double[] a, int idx) {
 920         double res = Double.NEGATIVE_INFINITY;
 921         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 922             res = (double)Math.max(res, a[i]);
 923         }
 924 
 925         return res;
 926     }
 927 
 928     static double maxLanes(double[] a) {
 929         double res = Double.NEGATIVE_INFINITY;
 930         for (int i = 0; i < a.length; i++) {
 931             res = (double)Math.max(res, a[i]);
 932         }
 933 
 934         return res;
 935     }
 936     @Test(dataProvider = "doubleUnaryOpProvider")
 937     static void maxLanesDouble512VectorTests(IntFunction<double[]> fa) {
 938         double[] a = fa.apply(SPECIES.length());
 939         double[] r = fr.apply(SPECIES.length());
 940         double ra = Double.NEGATIVE_INFINITY;
 941 
 942         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 943             for (int i = 0; i < a.length; i += SPECIES.length()) {
 944                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 945                 r[i] = av.maxLanes();
 946             }
 947         }
 948 
 949         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 950             ra = Double.NEGATIVE_INFINITY;
 951             for (int i = 0; i < a.length; i += SPECIES.length()) {
 952                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 953                 ra = (double)Math.max(ra, av.maxLanes());
 954             }
 955         }
 956 
 957         assertReductionArraysEquals(a, r, ra, Double512VectorTests::maxLanes, Double512VectorTests::maxLanes);
 958     }
 959 
 960 
 961 
 962 
 963 
 964     @Test(dataProvider = "doubleUnaryOpProvider")
 965     static void withDouble512VectorTests(IntFunction<double []> fa) {
 966         double[] a = fa.apply(SPECIES.length());
 967         double[] r = fr.apply(SPECIES.length());
 968 
 969         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 970             for (int i = 0; i < a.length; i += SPECIES.length()) {
 971                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 972                 av.with(0, (double)4).intoArray(r, i);
 973             }
 974         }
 975 
 976         assertInsertArraysEquals(a, r, (double)4, 0);
 977     }
 978 
 979     @Test(dataProvider = "doubleCompareOpProvider")
 980     static void lessThanDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 981         double[] a = fa.apply(SPECIES.length());
 982         double[] b = fb.apply(SPECIES.length());
 983 
 984         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 985             for (int i = 0; i < a.length; i += SPECIES.length()) {
 986                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 987                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 988                 VectorMask<Double> mv = av.lessThan(bv);
 989 
 990                 // Check results as part of computation.
 991                 for (int j = 0; j < SPECIES.length(); j++) {
 992                     Assert.assertEquals(mv.lane(j), a[i + j] < b[i + j]);
 993                 }
 994             }
 995         }
 996     }
 997 
 998 
 999     @Test(dataProvider = "doubleCompareOpProvider")
1000     static void greaterThanDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1001         double[] a = fa.apply(SPECIES.length());
1002         double[] b = fb.apply(SPECIES.length());
1003 
1004         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1005             for (int i = 0; i < a.length; i += SPECIES.length()) {
1006                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1007                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1008                 VectorMask<Double> mv = av.greaterThan(bv);
1009 
1010                 // Check results as part of computation.
1011                 for (int j = 0; j < SPECIES.length(); j++) {
1012                     Assert.assertEquals(mv.lane(j), a[i + j] > b[i + j]);
1013                 }
1014             }
1015         }
1016     }
1017 
1018 
1019     @Test(dataProvider = "doubleCompareOpProvider")
1020     static void equalDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1021         double[] a = fa.apply(SPECIES.length());
1022         double[] b = fb.apply(SPECIES.length());
1023 
1024         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1025             for (int i = 0; i < a.length; i += SPECIES.length()) {
1026                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1027                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1028                 VectorMask<Double> mv = av.equal(bv);
1029 
1030                 // Check results as part of computation.
1031                 for (int j = 0; j < SPECIES.length(); j++) {
1032                     Assert.assertEquals(mv.lane(j), a[i + j] == b[i + j]);
1033                 }
1034             }
1035         }
1036     }
1037 
1038 
1039     @Test(dataProvider = "doubleCompareOpProvider")
1040     static void notEqualDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1041         double[] a = fa.apply(SPECIES.length());
1042         double[] b = fb.apply(SPECIES.length());
1043 
1044         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1045             for (int i = 0; i < a.length; i += SPECIES.length()) {
1046                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1047                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1048                 VectorMask<Double> mv = av.notEqual(bv);
1049 
1050                 // Check results as part of computation.
1051                 for (int j = 0; j < SPECIES.length(); j++) {
1052                     Assert.assertEquals(mv.lane(j), a[i + j] != b[i + j]);
1053                 }
1054             }
1055         }
1056     }
1057 
1058 
1059     @Test(dataProvider = "doubleCompareOpProvider")
1060     static void lessThanEqDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1061         double[] a = fa.apply(SPECIES.length());
1062         double[] b = fb.apply(SPECIES.length());
1063 
1064         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1065             for (int i = 0; i < a.length; i += SPECIES.length()) {
1066                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1067                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1068                 VectorMask<Double> mv = av.lessThanEq(bv);
1069 
1070                 // Check results as part of computation.
1071                 for (int j = 0; j < SPECIES.length(); j++) {
1072                     Assert.assertEquals(mv.lane(j), a[i + j] <= b[i + j]);
1073                 }
1074             }
1075         }
1076     }
1077 
1078 
1079     @Test(dataProvider = "doubleCompareOpProvider")
1080     static void greaterThanEqDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1081         double[] a = fa.apply(SPECIES.length());
1082         double[] b = fb.apply(SPECIES.length());
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                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1088                 VectorMask<Double> mv = av.greaterThanEq(bv);
1089 
1090                 // Check results as part of computation.
1091                 for (int j = 0; j < SPECIES.length(); j++) {
1092                     Assert.assertEquals(mv.lane(j), a[i + j] >= b[i + j]);
1093                 }
1094             }
1095         }
1096     }
1097 
1098 
1099     static double blend(double a, double b, boolean mask) {
1100         return mask ? b : a;
1101     }
1102 
1103     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1104     static void blendDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
1105                                           IntFunction<boolean[]> fm) {
1106         double[] a = fa.apply(SPECIES.length());
1107         double[] b = fb.apply(SPECIES.length());
1108         double[] r = fr.apply(SPECIES.length());
1109         boolean[] mask = fm.apply(SPECIES.length());
1110         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1111 
1112         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1113             for (int i = 0; i < a.length; i += SPECIES.length()) {
1114                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1115                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1116                 av.blend(bv, vmask).intoArray(r, i);
1117             }
1118         }
1119 
1120         assertArraysEquals(a, b, r, mask, Double512VectorTests::blend);
1121     }
1122 
1123     @Test(dataProvider = "doubleUnaryOpShuffleProvider")
1124     static void RearrangeDouble512VectorTests(IntFunction<double[]> fa,
1125                                            BiFunction<Integer,Integer,int[]> fs) {
1126         double[] a = fa.apply(SPECIES.length());
1127         int[] order = fs.apply(a.length, SPECIES.length());
1128         double[] r = fr.apply(SPECIES.length());
1129 
1130         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1131             for (int i = 0; i < a.length; i += SPECIES.length()) {
1132                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1133                 av.rearrange(VectorShuffle.fromArray(SPECIES, order, i)).intoArray(r, i);
1134             }
1135         }
1136 
1137         assertRearrangeArraysEquals(a, r, order, SPECIES.length());
1138     }
1139 
1140 
1141 
1142 
1143     @Test(dataProvider = "doubleUnaryOpProvider")
1144     static void getDouble512VectorTests(IntFunction<double[]> fa) {
1145         double[] a = fa.apply(SPECIES.length());
1146         double[] r = fr.apply(SPECIES.length());
1147 
1148         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1149             for (int i = 0; i < a.length; i += SPECIES.length()) {
1150                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1151                 int num_lanes = SPECIES.length();
1152                 // Manually unroll because full unroll happens after intrinsification.
1153                 // Unroll is needed because get intrinsic requires for index to be a known constant.
1154                 if (num_lanes == 1) {
1155                     r[i]=av.lane(0);
1156                 } else if (num_lanes == 2) {
1157                     r[i]=av.lane(0);
1158                     r[i+1]=av.lane(1);
1159                 } else if (num_lanes == 4) {
1160                     r[i]=av.lane(0);
1161                     r[i+1]=av.lane(1);
1162                     r[i+2]=av.lane(2);
1163                     r[i+3]=av.lane(3);
1164                 } else if (num_lanes == 8) {
1165                     r[i]=av.lane(0);
1166                     r[i+1]=av.lane(1);
1167                     r[i+2]=av.lane(2);
1168                     r[i+3]=av.lane(3);
1169                     r[i+4]=av.lane(4);
1170                     r[i+5]=av.lane(5);
1171                     r[i+6]=av.lane(6);
1172                     r[i+7]=av.lane(7);
1173                 } else if (num_lanes == 16) {
1174                     r[i]=av.lane(0);
1175                     r[i+1]=av.lane(1);
1176                     r[i+2]=av.lane(2);
1177                     r[i+3]=av.lane(3);
1178                     r[i+4]=av.lane(4);
1179                     r[i+5]=av.lane(5);
1180                     r[i+6]=av.lane(6);
1181                     r[i+7]=av.lane(7);
1182                     r[i+8]=av.lane(8);
1183                     r[i+9]=av.lane(9);
1184                     r[i+10]=av.lane(10);
1185                     r[i+11]=av.lane(11);
1186                     r[i+12]=av.lane(12);
1187                     r[i+13]=av.lane(13);
1188                     r[i+14]=av.lane(14);
1189                     r[i+15]=av.lane(15);
1190                 } else if (num_lanes == 32) {
1191                     r[i]=av.lane(0);
1192                     r[i+1]=av.lane(1);
1193                     r[i+2]=av.lane(2);
1194                     r[i+3]=av.lane(3);
1195                     r[i+4]=av.lane(4);
1196                     r[i+5]=av.lane(5);
1197                     r[i+6]=av.lane(6);
1198                     r[i+7]=av.lane(7);
1199                     r[i+8]=av.lane(8);
1200                     r[i+9]=av.lane(9);
1201                     r[i+10]=av.lane(10);
1202                     r[i+11]=av.lane(11);
1203                     r[i+12]=av.lane(12);
1204                     r[i+13]=av.lane(13);
1205                     r[i+14]=av.lane(14);
1206                     r[i+15]=av.lane(15);
1207                     r[i+16]=av.lane(16);
1208                     r[i+17]=av.lane(17);
1209                     r[i+18]=av.lane(18);
1210                     r[i+19]=av.lane(19);
1211                     r[i+20]=av.lane(20);
1212                     r[i+21]=av.lane(21);
1213                     r[i+22]=av.lane(22);
1214                     r[i+23]=av.lane(23);
1215                     r[i+24]=av.lane(24);
1216                     r[i+25]=av.lane(25);
1217                     r[i+26]=av.lane(26);
1218                     r[i+27]=av.lane(27);
1219                     r[i+28]=av.lane(28);
1220                     r[i+29]=av.lane(29);
1221                     r[i+30]=av.lane(30);
1222                     r[i+31]=av.lane(31);
1223                 } else if (num_lanes == 64) {
1224                     r[i]=av.lane(0);
1225                     r[i+1]=av.lane(1);
1226                     r[i+2]=av.lane(2);
1227                     r[i+3]=av.lane(3);
1228                     r[i+4]=av.lane(4);
1229                     r[i+5]=av.lane(5);
1230                     r[i+6]=av.lane(6);
1231                     r[i+7]=av.lane(7);
1232                     r[i+8]=av.lane(8);
1233                     r[i+9]=av.lane(9);
1234                     r[i+10]=av.lane(10);
1235                     r[i+11]=av.lane(11);
1236                     r[i+12]=av.lane(12);
1237                     r[i+13]=av.lane(13);
1238                     r[i+14]=av.lane(14);
1239                     r[i+15]=av.lane(15);
1240                     r[i+16]=av.lane(16);
1241                     r[i+17]=av.lane(17);
1242                     r[i+18]=av.lane(18);
1243                     r[i+19]=av.lane(19);
1244                     r[i+20]=av.lane(20);
1245                     r[i+21]=av.lane(21);
1246                     r[i+22]=av.lane(22);
1247                     r[i+23]=av.lane(23);
1248                     r[i+24]=av.lane(24);
1249                     r[i+25]=av.lane(25);
1250                     r[i+26]=av.lane(26);
1251                     r[i+27]=av.lane(27);
1252                     r[i+28]=av.lane(28);
1253                     r[i+29]=av.lane(29);
1254                     r[i+30]=av.lane(30);
1255                     r[i+31]=av.lane(31);
1256                     r[i+32]=av.lane(32);
1257                     r[i+33]=av.lane(33);
1258                     r[i+34]=av.lane(34);
1259                     r[i+35]=av.lane(35);
1260                     r[i+36]=av.lane(36);
1261                     r[i+37]=av.lane(37);
1262                     r[i+38]=av.lane(38);
1263                     r[i+39]=av.lane(39);
1264                     r[i+40]=av.lane(40);
1265                     r[i+41]=av.lane(41);
1266                     r[i+42]=av.lane(42);
1267                     r[i+43]=av.lane(43);
1268                     r[i+44]=av.lane(44);
1269                     r[i+45]=av.lane(45);
1270                     r[i+46]=av.lane(46);
1271                     r[i+47]=av.lane(47);
1272                     r[i+48]=av.lane(48);
1273                     r[i+49]=av.lane(49);
1274                     r[i+50]=av.lane(50);
1275                     r[i+51]=av.lane(51);
1276                     r[i+52]=av.lane(52);
1277                     r[i+53]=av.lane(53);
1278                     r[i+54]=av.lane(54);
1279                     r[i+55]=av.lane(55);
1280                     r[i+56]=av.lane(56);
1281                     r[i+57]=av.lane(57);
1282                     r[i+58]=av.lane(58);
1283                     r[i+59]=av.lane(59);
1284                     r[i+60]=av.lane(60);
1285                     r[i+61]=av.lane(61);
1286                     r[i+62]=av.lane(62);
1287                     r[i+63]=av.lane(63);
1288                 } else {
1289                     for (int j = 0; j < SPECIES.length(); j++) {
1290                         r[i+j]=av.lane(j);
1291                     }
1292                 }
1293             }
1294         }
1295 
1296         assertArraysEquals(a, r, Double512VectorTests::get);
1297     }
1298 
1299     static double sin(double a) {
1300         return (double)(Math.sin((double)a));
1301     }
1302 
1303     static double strictsin(double a) {
1304         return (double)(StrictMath.sin((double)a));
1305     }
1306 
1307     @Test(dataProvider = "doubleUnaryOpProvider")
1308     static void sinDouble512VectorTests(IntFunction<double[]> fa) {
1309         double[] a = fa.apply(SPECIES.length());
1310         double[] r = fr.apply(SPECIES.length());
1311 
1312         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1313             for (int i = 0; i < a.length; i += SPECIES.length()) {
1314                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1315                 av.sin().intoArray(r, i);
1316             }
1317         }
1318 
1319         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::sin, Double512VectorTests::strictsin);
1320     }
1321 
1322 
1323     static double exp(double a) {
1324         return (double)(Math.exp((double)a));
1325     }
1326 
1327     static double strictexp(double a) {
1328         return (double)(StrictMath.exp((double)a));
1329     }
1330 
1331     @Test(dataProvider = "doubleUnaryOpProvider")
1332     static void expDouble512VectorTests(IntFunction<double[]> fa) {
1333         double[] a = fa.apply(SPECIES.length());
1334         double[] r = fr.apply(SPECIES.length());
1335 
1336         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1337             for (int i = 0; i < a.length; i += SPECIES.length()) {
1338                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1339                 av.exp().intoArray(r, i);
1340             }
1341         }
1342 
1343         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::exp, Double512VectorTests::strictexp);
1344     }
1345 
1346 
1347     static double log1p(double a) {
1348         return (double)(Math.log1p((double)a));
1349     }
1350 
1351     static double strictlog1p(double a) {
1352         return (double)(StrictMath.log1p((double)a));
1353     }
1354 
1355     @Test(dataProvider = "doubleUnaryOpProvider")
1356     static void log1pDouble512VectorTests(IntFunction<double[]> fa) {
1357         double[] a = fa.apply(SPECIES.length());
1358         double[] r = fr.apply(SPECIES.length());
1359 
1360         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1361             for (int i = 0; i < a.length; i += SPECIES.length()) {
1362                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1363                 av.log1p().intoArray(r, i);
1364             }
1365         }
1366 
1367         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::log1p, Double512VectorTests::strictlog1p);
1368     }
1369 
1370 
1371     static double log(double a) {
1372         return (double)(Math.log((double)a));
1373     }
1374 
1375     static double strictlog(double a) {
1376         return (double)(StrictMath.log((double)a));
1377     }
1378 
1379     @Test(dataProvider = "doubleUnaryOpProvider")
1380     static void logDouble512VectorTests(IntFunction<double[]> fa) {
1381         double[] a = fa.apply(SPECIES.length());
1382         double[] r = fr.apply(SPECIES.length());
1383 
1384         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1385             for (int i = 0; i < a.length; i += SPECIES.length()) {
1386                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1387                 av.log().intoArray(r, i);
1388             }
1389         }
1390 
1391         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::log, Double512VectorTests::strictlog);
1392     }
1393 
1394 
1395     static double log10(double a) {
1396         return (double)(Math.log10((double)a));
1397     }
1398 
1399     static double strictlog10(double a) {
1400         return (double)(StrictMath.log10((double)a));
1401     }
1402 
1403     @Test(dataProvider = "doubleUnaryOpProvider")
1404     static void log10Double512VectorTests(IntFunction<double[]> fa) {
1405         double[] a = fa.apply(SPECIES.length());
1406         double[] r = fr.apply(SPECIES.length());
1407 
1408         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1409             for (int i = 0; i < a.length; i += SPECIES.length()) {
1410                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1411                 av.log10().intoArray(r, i);
1412             }
1413         }
1414 
1415         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::log10, Double512VectorTests::strictlog10);
1416     }
1417 
1418 
1419     static double expm1(double a) {
1420         return (double)(Math.expm1((double)a));
1421     }
1422 
1423     static double strictexpm1(double a) {
1424         return (double)(StrictMath.expm1((double)a));
1425     }
1426 
1427     @Test(dataProvider = "doubleUnaryOpProvider")
1428     static void expm1Double512VectorTests(IntFunction<double[]> fa) {
1429         double[] a = fa.apply(SPECIES.length());
1430         double[] r = fr.apply(SPECIES.length());
1431 
1432         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1433             for (int i = 0; i < a.length; i += SPECIES.length()) {
1434                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1435                 av.expm1().intoArray(r, i);
1436             }
1437         }
1438 
1439         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::expm1, Double512VectorTests::strictexpm1);
1440     }
1441 
1442 
1443     static double cos(double a) {
1444         return (double)(Math.cos((double)a));
1445     }
1446 
1447     static double strictcos(double a) {
1448         return (double)(StrictMath.cos((double)a));
1449     }
1450 
1451     @Test(dataProvider = "doubleUnaryOpProvider")
1452     static void cosDouble512VectorTests(IntFunction<double[]> fa) {
1453         double[] a = fa.apply(SPECIES.length());
1454         double[] r = fr.apply(SPECIES.length());
1455 
1456         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1457             for (int i = 0; i < a.length; i += SPECIES.length()) {
1458                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1459                 av.cos().intoArray(r, i);
1460             }
1461         }
1462 
1463         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::cos, Double512VectorTests::strictcos);
1464     }
1465 
1466 
1467     static double tan(double a) {
1468         return (double)(Math.tan((double)a));
1469     }
1470 
1471     static double stricttan(double a) {
1472         return (double)(StrictMath.tan((double)a));
1473     }
1474 
1475     @Test(dataProvider = "doubleUnaryOpProvider")
1476     static void tanDouble512VectorTests(IntFunction<double[]> fa) {
1477         double[] a = fa.apply(SPECIES.length());
1478         double[] r = fr.apply(SPECIES.length());
1479 
1480         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1481             for (int i = 0; i < a.length; i += SPECIES.length()) {
1482                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1483                 av.tan().intoArray(r, i);
1484             }
1485         }
1486 
1487         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::tan, Double512VectorTests::stricttan);
1488     }
1489 
1490 
1491     static double sinh(double a) {
1492         return (double)(Math.sinh((double)a));
1493     }
1494 
1495     static double strictsinh(double a) {
1496         return (double)(StrictMath.sinh((double)a));
1497     }
1498 
1499     @Test(dataProvider = "doubleUnaryOpProvider")
1500     static void sinhDouble512VectorTests(IntFunction<double[]> fa) {
1501         double[] a = fa.apply(SPECIES.length());
1502         double[] r = fr.apply(SPECIES.length());
1503 
1504         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1505             for (int i = 0; i < a.length; i += SPECIES.length()) {
1506                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1507                 av.sinh().intoArray(r, i);
1508             }
1509         }
1510 
1511         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::sinh, Double512VectorTests::strictsinh);
1512     }
1513 
1514 
1515     static double cosh(double a) {
1516         return (double)(Math.cosh((double)a));
1517     }
1518 
1519     static double strictcosh(double a) {
1520         return (double)(StrictMath.cosh((double)a));
1521     }
1522 
1523     @Test(dataProvider = "doubleUnaryOpProvider")
1524     static void coshDouble512VectorTests(IntFunction<double[]> fa) {
1525         double[] a = fa.apply(SPECIES.length());
1526         double[] r = fr.apply(SPECIES.length());
1527 
1528         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1529             for (int i = 0; i < a.length; i += SPECIES.length()) {
1530                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1531                 av.cosh().intoArray(r, i);
1532             }
1533         }
1534 
1535         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::cosh, Double512VectorTests::strictcosh);
1536     }
1537 
1538 
1539     static double tanh(double a) {
1540         return (double)(Math.tanh((double)a));
1541     }
1542 
1543     static double stricttanh(double a) {
1544         return (double)(StrictMath.tanh((double)a));
1545     }
1546 
1547     @Test(dataProvider = "doubleUnaryOpProvider")
1548     static void tanhDouble512VectorTests(IntFunction<double[]> fa) {
1549         double[] a = fa.apply(SPECIES.length());
1550         double[] r = fr.apply(SPECIES.length());
1551 
1552         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1553             for (int i = 0; i < a.length; i += SPECIES.length()) {
1554                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1555                 av.tanh().intoArray(r, i);
1556             }
1557         }
1558 
1559         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::tanh, Double512VectorTests::stricttanh);
1560     }
1561 
1562 
1563     static double asin(double a) {
1564         return (double)(Math.asin((double)a));
1565     }
1566 
1567     static double strictasin(double a) {
1568         return (double)(StrictMath.asin((double)a));
1569     }
1570 
1571     @Test(dataProvider = "doubleUnaryOpProvider")
1572     static void asinDouble512VectorTests(IntFunction<double[]> fa) {
1573         double[] a = fa.apply(SPECIES.length());
1574         double[] r = fr.apply(SPECIES.length());
1575 
1576         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1577             for (int i = 0; i < a.length; i += SPECIES.length()) {
1578                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1579                 av.asin().intoArray(r, i);
1580             }
1581         }
1582 
1583         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::asin, Double512VectorTests::strictasin);
1584     }
1585 
1586 
1587     static double acos(double a) {
1588         return (double)(Math.acos((double)a));
1589     }
1590 
1591     static double strictacos(double a) {
1592         return (double)(StrictMath.acos((double)a));
1593     }
1594 
1595     @Test(dataProvider = "doubleUnaryOpProvider")
1596     static void acosDouble512VectorTests(IntFunction<double[]> fa) {
1597         double[] a = fa.apply(SPECIES.length());
1598         double[] r = fr.apply(SPECIES.length());
1599 
1600         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1601             for (int i = 0; i < a.length; i += SPECIES.length()) {
1602                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1603                 av.acos().intoArray(r, i);
1604             }
1605         }
1606 
1607         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::acos, Double512VectorTests::strictacos);
1608     }
1609 
1610 
1611     static double atan(double a) {
1612         return (double)(Math.atan((double)a));
1613     }
1614 
1615     static double strictatan(double a) {
1616         return (double)(StrictMath.atan((double)a));
1617     }
1618 
1619     @Test(dataProvider = "doubleUnaryOpProvider")
1620     static void atanDouble512VectorTests(IntFunction<double[]> fa) {
1621         double[] a = fa.apply(SPECIES.length());
1622         double[] r = fr.apply(SPECIES.length());
1623 
1624         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1625             for (int i = 0; i < a.length; i += SPECIES.length()) {
1626                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1627                 av.atan().intoArray(r, i);
1628             }
1629         }
1630 
1631         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::atan, Double512VectorTests::strictatan);
1632     }
1633 
1634 
1635     static double cbrt(double a) {
1636         return (double)(Math.cbrt((double)a));
1637     }
1638 
1639     static double strictcbrt(double a) {
1640         return (double)(StrictMath.cbrt((double)a));
1641     }
1642 
1643     @Test(dataProvider = "doubleUnaryOpProvider")
1644     static void cbrtDouble512VectorTests(IntFunction<double[]> fa) {
1645         double[] a = fa.apply(SPECIES.length());
1646         double[] r = fr.apply(SPECIES.length());
1647 
1648         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1649             for (int i = 0; i < a.length; i += SPECIES.length()) {
1650                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1651                 av.cbrt().intoArray(r, i);
1652             }
1653         }
1654 
1655         assertArraysEqualsWithinOneUlp(a, r, Double512VectorTests::cbrt, Double512VectorTests::strictcbrt);
1656     }
1657 
1658 
1659     static double hypot(double a, double b) {
1660         return (double)(Math.hypot((double)a, (double)b));
1661     }
1662 
1663     static double stricthypot(double a, double b) {
1664         return (double)(StrictMath.hypot((double)a, (double)b));
1665     }
1666 
1667     @Test(dataProvider = "doubleBinaryOpProvider")
1668     static void hypotDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1669         double[] a = fa.apply(SPECIES.length());
1670         double[] b = fb.apply(SPECIES.length());
1671         double[] r = fr.apply(SPECIES.length());
1672 
1673         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1674             for (int i = 0; i < a.length; i += SPECIES.length()) {
1675                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1676                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1677                 av.hypot(bv).intoArray(r, i);
1678             }
1679         }
1680 
1681         assertArraysEqualsWithinOneUlp(a, b, r, Double512VectorTests::hypot, Double512VectorTests::stricthypot);
1682     }
1683 
1684 
1685 
1686     static double pow(double a, double b) {
1687         return (double)(Math.pow((double)a, (double)b));
1688     }
1689 
1690     static double strictpow(double a, double b) {
1691         return (double)(StrictMath.pow((double)a, (double)b));
1692     }
1693 
1694     @Test(dataProvider = "doubleBinaryOpProvider")
1695     static void powDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1696         double[] a = fa.apply(SPECIES.length());
1697         double[] b = fb.apply(SPECIES.length());
1698         double[] r = fr.apply(SPECIES.length());
1699 
1700         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1701             for (int i = 0; i < a.length; i += SPECIES.length()) {
1702                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1703                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1704                 av.pow(bv).intoArray(r, i);
1705             }
1706         }
1707 
1708         assertArraysEqualsWithinOneUlp(a, b, r, Double512VectorTests::pow, Double512VectorTests::strictpow);
1709     }
1710 
1711 
1712 
1713     static double atan2(double a, double b) {
1714         return (double)(Math.atan2((double)a, (double)b));
1715     }
1716 
1717     static double strictatan2(double a, double b) {
1718         return (double)(StrictMath.atan2((double)a, (double)b));
1719     }
1720 
1721     @Test(dataProvider = "doubleBinaryOpProvider")
1722     static void atan2Double512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1723         double[] a = fa.apply(SPECIES.length());
1724         double[] b = fb.apply(SPECIES.length());
1725         double[] r = fr.apply(SPECIES.length());
1726 
1727         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1728             for (int i = 0; i < a.length; i += SPECIES.length()) {
1729                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1730                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1731                 av.atan2(bv).intoArray(r, i);
1732             }
1733         }
1734 
1735         assertArraysEqualsWithinOneUlp(a, b, r, Double512VectorTests::atan2, Double512VectorTests::strictatan2);
1736     }
1737 
1738 
1739 
1740     static double fma(double a, double b, double c) {
1741         return (double)(Math.fma(a, b, c));
1742     }
1743 
1744 
1745     @Test(dataProvider = "doubleTernaryOpProvider")
1746     static void fmaDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
1747         double[] a = fa.apply(SPECIES.length());
1748         double[] b = fb.apply(SPECIES.length());
1749         double[] c = fc.apply(SPECIES.length());
1750         double[] r = fr.apply(SPECIES.length());
1751 
1752         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1753             for (int i = 0; i < a.length; i += SPECIES.length()) {
1754                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1755                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1756                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
1757                 av.fma(bv, cv).intoArray(r, i);
1758             }
1759         }
1760 
1761         assertArraysEquals(a, b, c, r, Double512VectorTests::fma);
1762     }
1763 
1764 
1765     @Test(dataProvider = "doubleTernaryOpMaskProvider")
1766     static void fmaDouble512VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
1767                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
1768         double[] a = fa.apply(SPECIES.length());
1769         double[] b = fb.apply(SPECIES.length());
1770         double[] c = fc.apply(SPECIES.length());
1771         double[] r = fr.apply(SPECIES.length());
1772         boolean[] mask = fm.apply(SPECIES.length());
1773         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1774 
1775         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1776             for (int i = 0; i < a.length; i += SPECIES.length()) {
1777                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1778                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1779                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
1780                 av.fma(bv, cv, vmask).intoArray(r, i);
1781             }
1782         }
1783 
1784         assertArraysEquals(a, b, c, r, mask, Double512VectorTests::fma);
1785     }
1786 
1787 
1788     static double neg(double a) {
1789         return (double)(-((double)a));
1790     }
1791 
1792     @Test(dataProvider = "doubleUnaryOpProvider")
1793     static void negDouble512VectorTests(IntFunction<double[]> fa) {
1794         double[] a = fa.apply(SPECIES.length());
1795         double[] r = fr.apply(SPECIES.length());
1796 
1797         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1798             for (int i = 0; i < a.length; i += SPECIES.length()) {
1799                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1800                 av.neg().intoArray(r, i);
1801             }
1802         }
1803 
1804         assertArraysEquals(a, r, Double512VectorTests::neg);
1805     }
1806 
1807     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1808     static void negMaskedDouble512VectorTests(IntFunction<double[]> fa,
1809                                                 IntFunction<boolean[]> fm) {
1810         double[] a = fa.apply(SPECIES.length());
1811         double[] r = fr.apply(SPECIES.length());
1812         boolean[] mask = fm.apply(SPECIES.length());
1813         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1814 
1815         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1816             for (int i = 0; i < a.length; i += SPECIES.length()) {
1817                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1818                 av.neg(vmask).intoArray(r, i);
1819             }
1820         }
1821 
1822         assertArraysEquals(a, r, mask, Double512VectorTests::neg);
1823     }
1824 
1825     static double abs(double a) {
1826         return (double)(Math.abs((double)a));
1827     }
1828 
1829     @Test(dataProvider = "doubleUnaryOpProvider")
1830     static void absDouble512VectorTests(IntFunction<double[]> fa) {
1831         double[] a = fa.apply(SPECIES.length());
1832         double[] r = fr.apply(SPECIES.length());
1833 
1834         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1835             for (int i = 0; i < a.length; i += SPECIES.length()) {
1836                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1837                 av.abs().intoArray(r, i);
1838             }
1839         }
1840 
1841         assertArraysEquals(a, r, Double512VectorTests::abs);
1842     }
1843 
1844     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1845     static void absMaskedDouble512VectorTests(IntFunction<double[]> fa,
1846                                                 IntFunction<boolean[]> fm) {
1847         double[] a = fa.apply(SPECIES.length());
1848         double[] r = fr.apply(SPECIES.length());
1849         boolean[] mask = fm.apply(SPECIES.length());
1850         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1851 
1852         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1853             for (int i = 0; i < a.length; i += SPECIES.length()) {
1854                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1855                 av.abs(vmask).intoArray(r, i);
1856             }
1857         }
1858 
1859         assertArraysEquals(a, r, mask, Double512VectorTests::abs);
1860     }
1861 
1862 
1863 
1864 
1865 
1866     static double sqrt(double a) {
1867         return (double)(Math.sqrt((double)a));
1868     }
1869 
1870 
1871 
1872     @Test(dataProvider = "doubleUnaryOpProvider")
1873     static void sqrtDouble512VectorTests(IntFunction<double[]> fa) {
1874         double[] a = fa.apply(SPECIES.length());
1875         double[] r = fr.apply(SPECIES.length());
1876 
1877         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1878             for (int i = 0; i < a.length; i += SPECIES.length()) {
1879                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1880                 av.sqrt().intoArray(r, i);
1881             }
1882         }
1883 
1884         assertArraysEquals(a, r, Double512VectorTests::sqrt);
1885     }
1886 
1887 
1888 
1889     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1890     static void sqrtMaskedDouble512VectorTests(IntFunction<double[]> fa,
1891                                                 IntFunction<boolean[]> fm) {
1892         double[] a = fa.apply(SPECIES.length());
1893         double[] r = fr.apply(SPECIES.length());
1894         boolean[] mask = fm.apply(SPECIES.length());
1895         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1896 
1897         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1898             for (int i = 0; i < a.length; i += SPECIES.length()) {
1899                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1900                 av.sqrt(vmask).intoArray(r, i);
1901             }
1902         }
1903 
1904         assertArraysEquals(a, r, mask, Double512VectorTests::sqrt);
1905     }
1906 
1907 
1908     static double[] gather(double a[], int ix, int[] b, int iy) {
1909         double[] res = new double[SPECIES.length()];
1910         for (int i = 0; i < SPECIES.length(); i++) {
1911             int bi = iy + i;
1912             res[i] = a[b[bi] + ix];
1913         }
1914         return res;
1915     }
1916 
1917     @Test(dataProvider = "doubleUnaryOpIndexProvider")
1918     static void gatherDouble512VectorTests(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1919         double[] a = fa.apply(SPECIES.length());
1920         int[] b    = fs.apply(a.length, SPECIES.length());
1921         double[] r = new double[a.length];
1922 
1923         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1924             for (int i = 0; i < a.length; i += SPECIES.length()) {
1925                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i);
1926                 av.intoArray(r, i);
1927             }
1928         }
1929 
1930         assertArraysEquals(a, b, r, Double512VectorTests::gather);
1931     }
1932 
1933 
1934     static double[] scatter(double a[], int ix, int[] b, int iy) {
1935       double[] res = new double[SPECIES.length()];
1936       for (int i = 0; i < SPECIES.length(); i++) {
1937         int bi = iy + i;
1938         res[b[bi]] = a[i + ix];
1939       }
1940       return res;
1941     }
1942 
1943     @Test(dataProvider = "doubleUnaryOpIndexProvider")
1944     static void scatterDouble512VectorTests(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1945         double[] a = fa.apply(SPECIES.length());
1946         int[] b = fs.apply(a.length, SPECIES.length());
1947         double[] r = new double[a.length];
1948 
1949         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1950             for (int i = 0; i < a.length; i += SPECIES.length()) {
1951                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1952                 av.intoArray(r, i, b, i);
1953             }
1954         }
1955 
1956         assertArraysEquals(a, b, r, Double512VectorTests::scatter);
1957     }
1958 
1959 }
1960