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