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     static double max(double a, double b) {
 738         return (double)(Math.max(a, b));
 739     }
 740 
 741     @Test(dataProvider = "doubleBinaryOpProvider")
 742     static void maxDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 743         double[] a = fa.apply(SPECIES.length());
 744         double[] b = fb.apply(SPECIES.length());
 745         double[] r = fr.apply(SPECIES.length());
 746 
 747         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 748             for (int i = 0; i < a.length; i += SPECIES.length()) {
 749                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 750                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 751                 av.max(bv).intoArray(r, i);
 752             }
 753         }
 754 
 755         assertArraysEquals(a, b, r, DoubleMaxVectorTests::max);
 756     }
 757     static double min(double a, double b) {
 758         return (double)(Math.min(a, b));
 759     }
 760 
 761     @Test(dataProvider = "doubleBinaryOpProvider")
 762     static void minDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 763         double[] a = fa.apply(SPECIES.length());
 764         double[] b = fb.apply(SPECIES.length());
 765         double[] r = fr.apply(SPECIES.length());
 766 
 767         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 768             for (int i = 0; i < a.length; i += SPECIES.length()) {
 769                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 770                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 771                 av.min(bv).intoArray(r, i);
 772             }
 773         }
 774 
 775         assertArraysEquals(a, b, r, DoubleMaxVectorTests::min);
 776     }
 777 
 778 
 779 
 780 
 781 
 782 
 783     static double addAll(double[] a, int idx) {
 784         double res = 0;
 785         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 786             res += a[i];
 787         }
 788 
 789         return res;
 790     }
 791 
 792     static double addAll(double[] a) {
 793         double res = 0;
 794         for (int i = 0; i < a.length; i += SPECIES.length()) {
 795             double tmp = 0;
 796             for (int j = 0; j < SPECIES.length(); j++) {
 797                 tmp += a[i + j];
 798             }
 799             res += tmp;
 800         }
 801 
 802         return res;
 803     }
 804     @Test(dataProvider = "doubleUnaryOpProvider")
 805     static void addAllDoubleMaxVectorTests(IntFunction<double[]> fa) {
 806         double[] a = fa.apply(SPECIES.length());
 807         double[] r = fr.apply(SPECIES.length());
 808         double ra = 0;
 809 
 810         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 811             for (int i = 0; i < a.length; i += SPECIES.length()) {
 812                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 813                 r[i] = av.addAll();
 814             }
 815         }
 816 
 817         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 818             ra = 0;
 819             for (int i = 0; i < a.length; i += SPECIES.length()) {
 820                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 821                 ra += av.addAll();
 822             }
 823         }
 824 
 825         assertReductionArraysEquals(a, r, ra, DoubleMaxVectorTests::addAll, DoubleMaxVectorTests::addAll);
 826     }
 827     static double mulAll(double[] a, int idx) {
 828         double res = 1;
 829         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 830             res *= a[i];
 831         }
 832 
 833         return res;
 834     }
 835 
 836     static double mulAll(double[] a) {
 837         double res = 1;
 838         for (int i = 0; i < a.length; i += SPECIES.length()) {
 839             double tmp = 1;
 840             for (int j = 0; j < SPECIES.length(); j++) {
 841                 tmp *= a[i + j];
 842             }
 843             res *= tmp;
 844         }
 845 
 846         return res;
 847     }
 848     @Test(dataProvider = "doubleUnaryOpProvider")
 849     static void mulAllDoubleMaxVectorTests(IntFunction<double[]> fa) {
 850         double[] a = fa.apply(SPECIES.length());
 851         double[] r = fr.apply(SPECIES.length());
 852         double ra = 1;
 853 
 854         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 855             for (int i = 0; i < a.length; i += SPECIES.length()) {
 856                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 857                 r[i] = av.mulAll();
 858             }
 859         }
 860 
 861         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 862             ra = 1;
 863             for (int i = 0; i < a.length; i += SPECIES.length()) {
 864                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 865                 ra *= av.mulAll();
 866             }
 867         }
 868 
 869         assertReductionArraysEquals(a, r, ra, DoubleMaxVectorTests::mulAll, DoubleMaxVectorTests::mulAll);
 870     }
 871     static double minAll(double[] a, int idx) {
 872         double res = Double.POSITIVE_INFINITY;
 873         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 874             res = (double)Math.min(res, a[i]);
 875         }
 876 
 877         return res;
 878     }
 879 
 880     static double minAll(double[] a) {
 881         double res = Double.POSITIVE_INFINITY;
 882         for (int i = 0; i < a.length; i++) {
 883             res = (double)Math.min(res, a[i]);
 884         }
 885 
 886         return res;
 887     }
 888     @Test(dataProvider = "doubleUnaryOpProvider")
 889     static void minAllDoubleMaxVectorTests(IntFunction<double[]> fa) {
 890         double[] a = fa.apply(SPECIES.length());
 891         double[] r = fr.apply(SPECIES.length());
 892         double ra = Double.POSITIVE_INFINITY;
 893 
 894         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 895             for (int i = 0; i < a.length; i += SPECIES.length()) {
 896                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 897                 r[i] = av.minAll();
 898             }
 899         }
 900 
 901         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 902             ra = Double.POSITIVE_INFINITY;
 903             for (int i = 0; i < a.length; i += SPECIES.length()) {
 904                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 905                 ra = (double)Math.min(ra, av.minAll());
 906             }
 907         }
 908 
 909         assertReductionArraysEquals(a, r, ra, DoubleMaxVectorTests::minAll, DoubleMaxVectorTests::minAll);
 910     }
 911     static double maxAll(double[] a, int idx) {
 912         double res = Double.NEGATIVE_INFINITY;
 913         for (int i = idx; i < (idx + SPECIES.length()); i++) {
 914             res = (double)Math.max(res, a[i]);
 915         }
 916 
 917         return res;
 918     }
 919 
 920     static double maxAll(double[] a) {
 921         double res = Double.NEGATIVE_INFINITY;
 922         for (int i = 0; i < a.length; i++) {
 923             res = (double)Math.max(res, a[i]);
 924         }
 925 
 926         return res;
 927     }
 928     @Test(dataProvider = "doubleUnaryOpProvider")
 929     static void maxAllDoubleMaxVectorTests(IntFunction<double[]> fa) {
 930         double[] a = fa.apply(SPECIES.length());
 931         double[] r = fr.apply(SPECIES.length());
 932         double ra = Double.NEGATIVE_INFINITY;
 933 
 934         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 935             for (int i = 0; i < a.length; i += SPECIES.length()) {
 936                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 937                 r[i] = av.maxAll();
 938             }
 939         }
 940 
 941         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 942             ra = Double.NEGATIVE_INFINITY;
 943             for (int i = 0; i < a.length; i += SPECIES.length()) {
 944                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 945                 ra = (double)Math.max(ra, av.maxAll());
 946             }
 947         }
 948 
 949         assertReductionArraysEquals(a, r, ra, DoubleMaxVectorTests::maxAll, DoubleMaxVectorTests::maxAll);
 950     }
 951 
 952 
 953 
 954 
 955 
 956     @Test(dataProvider = "doubleUnaryOpProvider")
 957     static void withDoubleMaxVectorTests(IntFunction<double []> fa) {
 958         double[] a = fa.apply(SPECIES.length());
 959         double[] r = fr.apply(SPECIES.length());
 960 
 961         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 962             for (int i = 0; i < a.length; i += SPECIES.length()) {
 963                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 964                 av.with(0, (double)4).intoArray(r, i);
 965             }
 966         }
 967 
 968         assertInsertArraysEquals(a, r, (double)4, 0);
 969     }
 970 
 971     @Test(dataProvider = "doubleCompareOpProvider")
 972     static void lessThanDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 973         double[] a = fa.apply(SPECIES.length());
 974         double[] b = fb.apply(SPECIES.length());
 975 
 976         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 977             for (int i = 0; i < a.length; i += SPECIES.length()) {
 978                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 979                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
 980                 VectorMask<Double> mv = av.lessThan(bv);
 981 
 982                 // Check results as part of computation.
 983                 for (int j = 0; j < SPECIES.length(); j++) {
 984                     Assert.assertEquals(mv.getElement(j), a[i + j] < b[i + j]);
 985                 }
 986             }
 987         }
 988     }
 989 
 990 
 991     @Test(dataProvider = "doubleCompareOpProvider")
 992     static void greaterThanDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
 993         double[] a = fa.apply(SPECIES.length());
 994         double[] b = fb.apply(SPECIES.length());
 995 
 996         for (int ic = 0; ic < INVOC_COUNT; ic++) {
 997             for (int i = 0; i < a.length; i += SPECIES.length()) {
 998                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
 999                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1000                 VectorMask<Double> mv = av.greaterThan(bv);
1001 
1002                 // Check results as part of computation.
1003                 for (int j = 0; j < SPECIES.length(); j++) {
1004                     Assert.assertEquals(mv.getElement(j), a[i + j] > b[i + j]);
1005                 }
1006             }
1007         }
1008     }
1009 
1010 
1011     @Test(dataProvider = "doubleCompareOpProvider")
1012     static void equalDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1013         double[] a = fa.apply(SPECIES.length());
1014         double[] b = fb.apply(SPECIES.length());
1015 
1016         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1017             for (int i = 0; i < a.length; i += SPECIES.length()) {
1018                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1019                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1020                 VectorMask<Double> mv = av.equal(bv);
1021 
1022                 // Check results as part of computation.
1023                 for (int j = 0; j < SPECIES.length(); j++) {
1024                     Assert.assertEquals(mv.getElement(j), a[i + j] == b[i + j]);
1025                 }
1026             }
1027         }
1028     }
1029 
1030 
1031     @Test(dataProvider = "doubleCompareOpProvider")
1032     static void notEqualDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1033         double[] a = fa.apply(SPECIES.length());
1034         double[] b = fb.apply(SPECIES.length());
1035 
1036         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1037             for (int i = 0; i < a.length; i += SPECIES.length()) {
1038                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1039                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1040                 VectorMask<Double> mv = av.notEqual(bv);
1041 
1042                 // Check results as part of computation.
1043                 for (int j = 0; j < SPECIES.length(); j++) {
1044                     Assert.assertEquals(mv.getElement(j), a[i + j] != b[i + j]);
1045                 }
1046             }
1047         }
1048     }
1049 
1050 
1051     @Test(dataProvider = "doubleCompareOpProvider")
1052     static void lessThanEqDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1053         double[] a = fa.apply(SPECIES.length());
1054         double[] b = fb.apply(SPECIES.length());
1055 
1056         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1057             for (int i = 0; i < a.length; i += SPECIES.length()) {
1058                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1059                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1060                 VectorMask<Double> mv = av.lessThanEq(bv);
1061 
1062                 // Check results as part of computation.
1063                 for (int j = 0; j < SPECIES.length(); j++) {
1064                     Assert.assertEquals(mv.getElement(j), a[i + j] <= b[i + j]);
1065                 }
1066             }
1067         }
1068     }
1069 
1070 
1071     @Test(dataProvider = "doubleCompareOpProvider")
1072     static void greaterThanEqDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1073         double[] a = fa.apply(SPECIES.length());
1074         double[] b = fb.apply(SPECIES.length());
1075 
1076         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1077             for (int i = 0; i < a.length; i += SPECIES.length()) {
1078                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1079                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1080                 VectorMask<Double> mv = av.greaterThanEq(bv);
1081 
1082                 // Check results as part of computation.
1083                 for (int j = 0; j < SPECIES.length(); j++) {
1084                     Assert.assertEquals(mv.getElement(j), a[i + j] >= b[i + j]);
1085                 }
1086             }
1087         }
1088     }
1089 
1090 
1091     static double blend(double a, double b, boolean mask) {
1092         return mask ? b : a;
1093     }
1094 
1095     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1096     static void blendDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
1097                                           IntFunction<boolean[]> fm) {
1098         double[] a = fa.apply(SPECIES.length());
1099         double[] b = fb.apply(SPECIES.length());
1100         double[] r = fr.apply(SPECIES.length());
1101         boolean[] mask = fm.apply(SPECIES.length());
1102         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1103 
1104         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1105             for (int i = 0; i < a.length; i += SPECIES.length()) {
1106                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1107                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1108                 av.blend(bv, vmask).intoArray(r, i);
1109             }
1110         }
1111 
1112         assertArraysEquals(a, b, r, mask, DoubleMaxVectorTests::blend);
1113     }
1114 
1115     @Test(dataProvider = "doubleUnaryOpShuffleProvider")
1116     static void RearrangeDoubleMaxVectorTests(IntFunction<double[]> fa,
1117                                            BiFunction<Integer,Integer,int[]> fs) {
1118         double[] a = fa.apply(SPECIES.length());
1119         int[] order = fs.apply(a.length, SPECIES.length());
1120         double[] r = fr.apply(SPECIES.length());
1121 
1122         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1123             for (int i = 0; i < a.length; i += SPECIES.length()) {
1124                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1125                 av.rearrange(VectorShuffle.fromArray(SPECIES, order, i)).intoArray(r, i);
1126             }
1127         }
1128 
1129         assertRearrangeArraysEquals(a, r, order, SPECIES.length());
1130     }
1131 
1132 
1133 
1134 
1135     @Test(dataProvider = "doubleUnaryOpProvider")
1136     static void getDoubleMaxVectorTests(IntFunction<double[]> fa) {
1137         double[] a = fa.apply(SPECIES.length());
1138         double[] r = fr.apply(SPECIES.length());
1139 
1140         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1141             for (int i = 0; i < a.length; i += SPECIES.length()) {
1142                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1143                 int num_lanes = SPECIES.length();
1144                 // Manually unroll because full unroll happens after intrinsification.
1145                 // Unroll is needed because get intrinsic requires for index to be a known constant.
1146                 if (num_lanes == 1) {
1147                     r[i]=av.get(0);
1148                 } else if (num_lanes == 2) {
1149                     r[i]=av.get(0);
1150                     r[i+1]=av.get(1);
1151                 } else if (num_lanes == 4) {
1152                     r[i]=av.get(0);
1153                     r[i+1]=av.get(1);
1154                     r[i+2]=av.get(2);
1155                     r[i+3]=av.get(3);
1156                 } else if (num_lanes == 8) {
1157                     r[i]=av.get(0);
1158                     r[i+1]=av.get(1);
1159                     r[i+2]=av.get(2);
1160                     r[i+3]=av.get(3);
1161                     r[i+4]=av.get(4);
1162                     r[i+5]=av.get(5);
1163                     r[i+6]=av.get(6);
1164                     r[i+7]=av.get(7);
1165                 } else if (num_lanes == 16) {
1166                     r[i]=av.get(0);
1167                     r[i+1]=av.get(1);
1168                     r[i+2]=av.get(2);
1169                     r[i+3]=av.get(3);
1170                     r[i+4]=av.get(4);
1171                     r[i+5]=av.get(5);
1172                     r[i+6]=av.get(6);
1173                     r[i+7]=av.get(7);
1174                     r[i+8]=av.get(8);
1175                     r[i+9]=av.get(9);
1176                     r[i+10]=av.get(10);
1177                     r[i+11]=av.get(11);
1178                     r[i+12]=av.get(12);
1179                     r[i+13]=av.get(13);
1180                     r[i+14]=av.get(14);
1181                     r[i+15]=av.get(15);
1182                 } else if (num_lanes == 32) {
1183                     r[i]=av.get(0);
1184                     r[i+1]=av.get(1);
1185                     r[i+2]=av.get(2);
1186                     r[i+3]=av.get(3);
1187                     r[i+4]=av.get(4);
1188                     r[i+5]=av.get(5);
1189                     r[i+6]=av.get(6);
1190                     r[i+7]=av.get(7);
1191                     r[i+8]=av.get(8);
1192                     r[i+9]=av.get(9);
1193                     r[i+10]=av.get(10);
1194                     r[i+11]=av.get(11);
1195                     r[i+12]=av.get(12);
1196                     r[i+13]=av.get(13);
1197                     r[i+14]=av.get(14);
1198                     r[i+15]=av.get(15);
1199                     r[i+16]=av.get(16);
1200                     r[i+17]=av.get(17);
1201                     r[i+18]=av.get(18);
1202                     r[i+19]=av.get(19);
1203                     r[i+20]=av.get(20);
1204                     r[i+21]=av.get(21);
1205                     r[i+22]=av.get(22);
1206                     r[i+23]=av.get(23);
1207                     r[i+24]=av.get(24);
1208                     r[i+25]=av.get(25);
1209                     r[i+26]=av.get(26);
1210                     r[i+27]=av.get(27);
1211                     r[i+28]=av.get(28);
1212                     r[i+29]=av.get(29);
1213                     r[i+30]=av.get(30);
1214                     r[i+31]=av.get(31);
1215                 } else if (num_lanes == 64) {
1216                     r[i]=av.get(0);
1217                     r[i+1]=av.get(1);
1218                     r[i+2]=av.get(2);
1219                     r[i+3]=av.get(3);
1220                     r[i+4]=av.get(4);
1221                     r[i+5]=av.get(5);
1222                     r[i+6]=av.get(6);
1223                     r[i+7]=av.get(7);
1224                     r[i+8]=av.get(8);
1225                     r[i+9]=av.get(9);
1226                     r[i+10]=av.get(10);
1227                     r[i+11]=av.get(11);
1228                     r[i+12]=av.get(12);
1229                     r[i+13]=av.get(13);
1230                     r[i+14]=av.get(14);
1231                     r[i+15]=av.get(15);
1232                     r[i+16]=av.get(16);
1233                     r[i+17]=av.get(17);
1234                     r[i+18]=av.get(18);
1235                     r[i+19]=av.get(19);
1236                     r[i+20]=av.get(20);
1237                     r[i+21]=av.get(21);
1238                     r[i+22]=av.get(22);
1239                     r[i+23]=av.get(23);
1240                     r[i+24]=av.get(24);
1241                     r[i+25]=av.get(25);
1242                     r[i+26]=av.get(26);
1243                     r[i+27]=av.get(27);
1244                     r[i+28]=av.get(28);
1245                     r[i+29]=av.get(29);
1246                     r[i+30]=av.get(30);
1247                     r[i+31]=av.get(31);
1248                     r[i+32]=av.get(32);
1249                     r[i+33]=av.get(33);
1250                     r[i+34]=av.get(34);
1251                     r[i+35]=av.get(35);
1252                     r[i+36]=av.get(36);
1253                     r[i+37]=av.get(37);
1254                     r[i+38]=av.get(38);
1255                     r[i+39]=av.get(39);
1256                     r[i+40]=av.get(40);
1257                     r[i+41]=av.get(41);
1258                     r[i+42]=av.get(42);
1259                     r[i+43]=av.get(43);
1260                     r[i+44]=av.get(44);
1261                     r[i+45]=av.get(45);
1262                     r[i+46]=av.get(46);
1263                     r[i+47]=av.get(47);
1264                     r[i+48]=av.get(48);
1265                     r[i+49]=av.get(49);
1266                     r[i+50]=av.get(50);
1267                     r[i+51]=av.get(51);
1268                     r[i+52]=av.get(52);
1269                     r[i+53]=av.get(53);
1270                     r[i+54]=av.get(54);
1271                     r[i+55]=av.get(55);
1272                     r[i+56]=av.get(56);
1273                     r[i+57]=av.get(57);
1274                     r[i+58]=av.get(58);
1275                     r[i+59]=av.get(59);
1276                     r[i+60]=av.get(60);
1277                     r[i+61]=av.get(61);
1278                     r[i+62]=av.get(62);
1279                     r[i+63]=av.get(63);
1280                 } else {
1281                     for (int j = 0; j < SPECIES.length(); j++) {
1282                         r[i+j]=av.get(j);
1283                     }
1284                 }
1285             }
1286         }
1287 
1288         assertArraysEquals(a, r, DoubleMaxVectorTests::get);
1289     }
1290 
1291     static double sin(double a) {
1292         return (double)(Math.sin((double)a));
1293     }
1294 
1295     static double strictsin(double a) {
1296         return (double)(StrictMath.sin((double)a));
1297     }
1298 
1299     @Test(dataProvider = "doubleUnaryOpProvider")
1300     static void sinDoubleMaxVectorTests(IntFunction<double[]> fa) {
1301         double[] a = fa.apply(SPECIES.length());
1302         double[] r = fr.apply(SPECIES.length());
1303 
1304         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1305             for (int i = 0; i < a.length; i += SPECIES.length()) {
1306                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1307                 av.sin().intoArray(r, i);
1308             }
1309         }
1310 
1311         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::sin, DoubleMaxVectorTests::strictsin);
1312     }
1313 
1314 
1315     static double exp(double a) {
1316         return (double)(Math.exp((double)a));
1317     }
1318 
1319     static double strictexp(double a) {
1320         return (double)(StrictMath.exp((double)a));
1321     }
1322 
1323     @Test(dataProvider = "doubleUnaryOpProvider")
1324     static void expDoubleMaxVectorTests(IntFunction<double[]> fa) {
1325         double[] a = fa.apply(SPECIES.length());
1326         double[] r = fr.apply(SPECIES.length());
1327 
1328         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1329             for (int i = 0; i < a.length; i += SPECIES.length()) {
1330                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1331                 av.exp().intoArray(r, i);
1332             }
1333         }
1334 
1335         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::exp, DoubleMaxVectorTests::strictexp);
1336     }
1337 
1338 
1339     static double log1p(double a) {
1340         return (double)(Math.log1p((double)a));
1341     }
1342 
1343     static double strictlog1p(double a) {
1344         return (double)(StrictMath.log1p((double)a));
1345     }
1346 
1347     @Test(dataProvider = "doubleUnaryOpProvider")
1348     static void log1pDoubleMaxVectorTests(IntFunction<double[]> fa) {
1349         double[] a = fa.apply(SPECIES.length());
1350         double[] r = fr.apply(SPECIES.length());
1351 
1352         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1353             for (int i = 0; i < a.length; i += SPECIES.length()) {
1354                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1355                 av.log1p().intoArray(r, i);
1356             }
1357         }
1358 
1359         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::log1p, DoubleMaxVectorTests::strictlog1p);
1360     }
1361 
1362 
1363     static double log(double a) {
1364         return (double)(Math.log((double)a));
1365     }
1366 
1367     static double strictlog(double a) {
1368         return (double)(StrictMath.log((double)a));
1369     }
1370 
1371     @Test(dataProvider = "doubleUnaryOpProvider")
1372     static void logDoubleMaxVectorTests(IntFunction<double[]> fa) {
1373         double[] a = fa.apply(SPECIES.length());
1374         double[] r = fr.apply(SPECIES.length());
1375 
1376         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1377             for (int i = 0; i < a.length; i += SPECIES.length()) {
1378                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1379                 av.log().intoArray(r, i);
1380             }
1381         }
1382 
1383         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::log, DoubleMaxVectorTests::strictlog);
1384     }
1385 
1386 
1387     static double log10(double a) {
1388         return (double)(Math.log10((double)a));
1389     }
1390 
1391     static double strictlog10(double a) {
1392         return (double)(StrictMath.log10((double)a));
1393     }
1394 
1395     @Test(dataProvider = "doubleUnaryOpProvider")
1396     static void log10DoubleMaxVectorTests(IntFunction<double[]> fa) {
1397         double[] a = fa.apply(SPECIES.length());
1398         double[] r = fr.apply(SPECIES.length());
1399 
1400         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1401             for (int i = 0; i < a.length; i += SPECIES.length()) {
1402                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1403                 av.log10().intoArray(r, i);
1404             }
1405         }
1406 
1407         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::log10, DoubleMaxVectorTests::strictlog10);
1408     }
1409 
1410 
1411     static double expm1(double a) {
1412         return (double)(Math.expm1((double)a));
1413     }
1414 
1415     static double strictexpm1(double a) {
1416         return (double)(StrictMath.expm1((double)a));
1417     }
1418 
1419     @Test(dataProvider = "doubleUnaryOpProvider")
1420     static void expm1DoubleMaxVectorTests(IntFunction<double[]> fa) {
1421         double[] a = fa.apply(SPECIES.length());
1422         double[] r = fr.apply(SPECIES.length());
1423 
1424         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1425             for (int i = 0; i < a.length; i += SPECIES.length()) {
1426                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1427                 av.expm1().intoArray(r, i);
1428             }
1429         }
1430 
1431         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::expm1, DoubleMaxVectorTests::strictexpm1);
1432     }
1433 
1434 
1435     static double cos(double a) {
1436         return (double)(Math.cos((double)a));
1437     }
1438 
1439     static double strictcos(double a) {
1440         return (double)(StrictMath.cos((double)a));
1441     }
1442 
1443     @Test(dataProvider = "doubleUnaryOpProvider")
1444     static void cosDoubleMaxVectorTests(IntFunction<double[]> fa) {
1445         double[] a = fa.apply(SPECIES.length());
1446         double[] r = fr.apply(SPECIES.length());
1447 
1448         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1449             for (int i = 0; i < a.length; i += SPECIES.length()) {
1450                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1451                 av.cos().intoArray(r, i);
1452             }
1453         }
1454 
1455         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::cos, DoubleMaxVectorTests::strictcos);
1456     }
1457 
1458 
1459     static double tan(double a) {
1460         return (double)(Math.tan((double)a));
1461     }
1462 
1463     static double stricttan(double a) {
1464         return (double)(StrictMath.tan((double)a));
1465     }
1466 
1467     @Test(dataProvider = "doubleUnaryOpProvider")
1468     static void tanDoubleMaxVectorTests(IntFunction<double[]> fa) {
1469         double[] a = fa.apply(SPECIES.length());
1470         double[] r = fr.apply(SPECIES.length());
1471 
1472         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1473             for (int i = 0; i < a.length; i += SPECIES.length()) {
1474                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1475                 av.tan().intoArray(r, i);
1476             }
1477         }
1478 
1479         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::tan, DoubleMaxVectorTests::stricttan);
1480     }
1481 
1482 
1483     static double sinh(double a) {
1484         return (double)(Math.sinh((double)a));
1485     }
1486 
1487     static double strictsinh(double a) {
1488         return (double)(StrictMath.sinh((double)a));
1489     }
1490 
1491     @Test(dataProvider = "doubleUnaryOpProvider")
1492     static void sinhDoubleMaxVectorTests(IntFunction<double[]> fa) {
1493         double[] a = fa.apply(SPECIES.length());
1494         double[] r = fr.apply(SPECIES.length());
1495 
1496         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1497             for (int i = 0; i < a.length; i += SPECIES.length()) {
1498                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1499                 av.sinh().intoArray(r, i);
1500             }
1501         }
1502 
1503         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::sinh, DoubleMaxVectorTests::strictsinh);
1504     }
1505 
1506 
1507     static double cosh(double a) {
1508         return (double)(Math.cosh((double)a));
1509     }
1510 
1511     static double strictcosh(double a) {
1512         return (double)(StrictMath.cosh((double)a));
1513     }
1514 
1515     @Test(dataProvider = "doubleUnaryOpProvider")
1516     static void coshDoubleMaxVectorTests(IntFunction<double[]> fa) {
1517         double[] a = fa.apply(SPECIES.length());
1518         double[] r = fr.apply(SPECIES.length());
1519 
1520         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1521             for (int i = 0; i < a.length; i += SPECIES.length()) {
1522                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1523                 av.cosh().intoArray(r, i);
1524             }
1525         }
1526 
1527         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::cosh, DoubleMaxVectorTests::strictcosh);
1528     }
1529 
1530 
1531     static double tanh(double a) {
1532         return (double)(Math.tanh((double)a));
1533     }
1534 
1535     static double stricttanh(double a) {
1536         return (double)(StrictMath.tanh((double)a));
1537     }
1538 
1539     @Test(dataProvider = "doubleUnaryOpProvider")
1540     static void tanhDoubleMaxVectorTests(IntFunction<double[]> fa) {
1541         double[] a = fa.apply(SPECIES.length());
1542         double[] r = fr.apply(SPECIES.length());
1543 
1544         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1545             for (int i = 0; i < a.length; i += SPECIES.length()) {
1546                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1547                 av.tanh().intoArray(r, i);
1548             }
1549         }
1550 
1551         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::tanh, DoubleMaxVectorTests::stricttanh);
1552     }
1553 
1554 
1555     static double asin(double a) {
1556         return (double)(Math.asin((double)a));
1557     }
1558 
1559     static double strictasin(double a) {
1560         return (double)(StrictMath.asin((double)a));
1561     }
1562 
1563     @Test(dataProvider = "doubleUnaryOpProvider")
1564     static void asinDoubleMaxVectorTests(IntFunction<double[]> fa) {
1565         double[] a = fa.apply(SPECIES.length());
1566         double[] r = fr.apply(SPECIES.length());
1567 
1568         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1569             for (int i = 0; i < a.length; i += SPECIES.length()) {
1570                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1571                 av.asin().intoArray(r, i);
1572             }
1573         }
1574 
1575         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::asin, DoubleMaxVectorTests::strictasin);
1576     }
1577 
1578 
1579     static double acos(double a) {
1580         return (double)(Math.acos((double)a));
1581     }
1582 
1583     static double strictacos(double a) {
1584         return (double)(StrictMath.acos((double)a));
1585     }
1586 
1587     @Test(dataProvider = "doubleUnaryOpProvider")
1588     static void acosDoubleMaxVectorTests(IntFunction<double[]> fa) {
1589         double[] a = fa.apply(SPECIES.length());
1590         double[] r = fr.apply(SPECIES.length());
1591 
1592         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1593             for (int i = 0; i < a.length; i += SPECIES.length()) {
1594                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1595                 av.acos().intoArray(r, i);
1596             }
1597         }
1598 
1599         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::acos, DoubleMaxVectorTests::strictacos);
1600     }
1601 
1602 
1603     static double atan(double a) {
1604         return (double)(Math.atan((double)a));
1605     }
1606 
1607     static double strictatan(double a) {
1608         return (double)(StrictMath.atan((double)a));
1609     }
1610 
1611     @Test(dataProvider = "doubleUnaryOpProvider")
1612     static void atanDoubleMaxVectorTests(IntFunction<double[]> fa) {
1613         double[] a = fa.apply(SPECIES.length());
1614         double[] r = fr.apply(SPECIES.length());
1615 
1616         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1617             for (int i = 0; i < a.length; i += SPECIES.length()) {
1618                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1619                 av.atan().intoArray(r, i);
1620             }
1621         }
1622 
1623         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::atan, DoubleMaxVectorTests::strictatan);
1624     }
1625 
1626 
1627     static double cbrt(double a) {
1628         return (double)(Math.cbrt((double)a));
1629     }
1630 
1631     static double strictcbrt(double a) {
1632         return (double)(StrictMath.cbrt((double)a));
1633     }
1634 
1635     @Test(dataProvider = "doubleUnaryOpProvider")
1636     static void cbrtDoubleMaxVectorTests(IntFunction<double[]> fa) {
1637         double[] a = fa.apply(SPECIES.length());
1638         double[] r = fr.apply(SPECIES.length());
1639 
1640         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1641             for (int i = 0; i < a.length; i += SPECIES.length()) {
1642                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1643                 av.cbrt().intoArray(r, i);
1644             }
1645         }
1646 
1647         assertArraysEqualsWithinOneUlp(a, r, DoubleMaxVectorTests::cbrt, DoubleMaxVectorTests::strictcbrt);
1648     }
1649 
1650 
1651     static double hypot(double a, double b) {
1652         return (double)(Math.hypot((double)a, (double)b));
1653     }
1654 
1655     static double stricthypot(double a, double b) {
1656         return (double)(StrictMath.hypot((double)a, (double)b));
1657     }
1658 
1659     @Test(dataProvider = "doubleBinaryOpProvider")
1660     static void hypotDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1661         double[] a = fa.apply(SPECIES.length());
1662         double[] b = fb.apply(SPECIES.length());
1663         double[] r = fr.apply(SPECIES.length());
1664 
1665         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1666             for (int i = 0; i < a.length; i += SPECIES.length()) {
1667                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1668                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1669                 av.hypot(bv).intoArray(r, i);
1670             }
1671         }
1672 
1673         assertArraysEqualsWithinOneUlp(a, b, r, DoubleMaxVectorTests::hypot, DoubleMaxVectorTests::stricthypot);
1674     }
1675 
1676 
1677 
1678     static double pow(double a, double b) {
1679         return (double)(Math.pow((double)a, (double)b));
1680     }
1681 
1682     static double strictpow(double a, double b) {
1683         return (double)(StrictMath.pow((double)a, (double)b));
1684     }
1685 
1686     @Test(dataProvider = "doubleBinaryOpProvider")
1687     static void powDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1688         double[] a = fa.apply(SPECIES.length());
1689         double[] b = fb.apply(SPECIES.length());
1690         double[] r = fr.apply(SPECIES.length());
1691 
1692         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1693             for (int i = 0; i < a.length; i += SPECIES.length()) {
1694                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1695                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1696                 av.pow(bv).intoArray(r, i);
1697             }
1698         }
1699 
1700         assertArraysEqualsWithinOneUlp(a, b, r, DoubleMaxVectorTests::pow, DoubleMaxVectorTests::strictpow);
1701     }
1702 
1703 
1704 
1705     static double atan2(double a, double b) {
1706         return (double)(Math.atan2((double)a, (double)b));
1707     }
1708 
1709     static double strictatan2(double a, double b) {
1710         return (double)(StrictMath.atan2((double)a, (double)b));
1711     }
1712 
1713     @Test(dataProvider = "doubleBinaryOpProvider")
1714     static void atan2DoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1715         double[] a = fa.apply(SPECIES.length());
1716         double[] b = fb.apply(SPECIES.length());
1717         double[] r = fr.apply(SPECIES.length());
1718 
1719         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1720             for (int i = 0; i < a.length; i += SPECIES.length()) {
1721                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1722                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1723                 av.atan2(bv).intoArray(r, i);
1724             }
1725         }
1726 
1727         assertArraysEqualsWithinOneUlp(a, b, r, DoubleMaxVectorTests::atan2, DoubleMaxVectorTests::strictatan2);
1728     }
1729 
1730 
1731 
1732     static double fma(double a, double b, double c) {
1733         return (double)(Math.fma(a, b, c));
1734     }
1735 
1736 
1737     @Test(dataProvider = "doubleTernaryOpProvider")
1738     static void fmaDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
1739         double[] a = fa.apply(SPECIES.length());
1740         double[] b = fb.apply(SPECIES.length());
1741         double[] c = fc.apply(SPECIES.length());
1742         double[] r = fr.apply(SPECIES.length());
1743 
1744         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1745             for (int i = 0; i < a.length; i += SPECIES.length()) {
1746                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1747                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1748                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
1749                 av.fma(bv, cv).intoArray(r, i);
1750             }
1751         }
1752 
1753         assertArraysEquals(a, b, c, r, DoubleMaxVectorTests::fma);
1754     }
1755 
1756 
1757     @Test(dataProvider = "doubleTernaryOpMaskProvider")
1758     static void fmaDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
1759                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
1760         double[] a = fa.apply(SPECIES.length());
1761         double[] b = fb.apply(SPECIES.length());
1762         double[] c = fc.apply(SPECIES.length());
1763         double[] r = fr.apply(SPECIES.length());
1764         boolean[] mask = fm.apply(SPECIES.length());
1765         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1766 
1767         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1768             for (int i = 0; i < a.length; i += SPECIES.length()) {
1769                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1770                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1771                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
1772                 av.fma(bv, cv, vmask).intoArray(r, i);
1773             }
1774         }
1775 
1776         assertArraysEquals(a, b, c, r, mask, DoubleMaxVectorTests::fma);
1777     }
1778 
1779 
1780     static double neg(double a) {
1781         return (double)(-((double)a));
1782     }
1783 
1784     @Test(dataProvider = "doubleUnaryOpProvider")
1785     static void negDoubleMaxVectorTests(IntFunction<double[]> fa) {
1786         double[] a = fa.apply(SPECIES.length());
1787         double[] r = fr.apply(SPECIES.length());
1788 
1789         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1790             for (int i = 0; i < a.length; i += SPECIES.length()) {
1791                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1792                 av.neg().intoArray(r, i);
1793             }
1794         }
1795 
1796         assertArraysEquals(a, r, DoubleMaxVectorTests::neg);
1797     }
1798 
1799     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1800     static void negMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
1801                                                 IntFunction<boolean[]> fm) {
1802         double[] a = fa.apply(SPECIES.length());
1803         double[] r = fr.apply(SPECIES.length());
1804         boolean[] mask = fm.apply(SPECIES.length());
1805         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1806 
1807         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1808             for (int i = 0; i < a.length; i += SPECIES.length()) {
1809                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1810                 av.neg(vmask).intoArray(r, i);
1811             }
1812         }
1813 
1814         assertArraysEquals(a, r, mask, DoubleMaxVectorTests::neg);
1815     }
1816 
1817     static double abs(double a) {
1818         return (double)(Math.abs((double)a));
1819     }
1820 
1821     @Test(dataProvider = "doubleUnaryOpProvider")
1822     static void absDoubleMaxVectorTests(IntFunction<double[]> fa) {
1823         double[] a = fa.apply(SPECIES.length());
1824         double[] r = fr.apply(SPECIES.length());
1825 
1826         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1827             for (int i = 0; i < a.length; i += SPECIES.length()) {
1828                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1829                 av.abs().intoArray(r, i);
1830             }
1831         }
1832 
1833         assertArraysEquals(a, r, DoubleMaxVectorTests::abs);
1834     }
1835 
1836     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1837     static void absMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
1838                                                 IntFunction<boolean[]> fm) {
1839         double[] a = fa.apply(SPECIES.length());
1840         double[] r = fr.apply(SPECIES.length());
1841         boolean[] mask = fm.apply(SPECIES.length());
1842         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1843 
1844         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1845             for (int i = 0; i < a.length; i += SPECIES.length()) {
1846                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1847                 av.abs(vmask).intoArray(r, i);
1848             }
1849         }
1850 
1851         assertArraysEquals(a, r, mask, DoubleMaxVectorTests::abs);
1852     }
1853 
1854 
1855 
1856 
1857 
1858     static double sqrt(double a) {
1859         return (double)(Math.sqrt((double)a));
1860     }
1861 
1862 
1863 
1864     @Test(dataProvider = "doubleUnaryOpProvider")
1865     static void sqrtDoubleMaxVectorTests(IntFunction<double[]> fa) {
1866         double[] a = fa.apply(SPECIES.length());
1867         double[] r = fr.apply(SPECIES.length());
1868 
1869         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1870             for (int i = 0; i < a.length; i += SPECIES.length()) {
1871                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1872                 av.sqrt().intoArray(r, i);
1873             }
1874         }
1875 
1876         assertArraysEquals(a, r, DoubleMaxVectorTests::sqrt);
1877     }
1878 
1879 
1880 
1881     @Test(dataProvider = "doubleUnaryOpMaskProvider")
1882     static void sqrtMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
1883                                                 IntFunction<boolean[]> fm) {
1884         double[] a = fa.apply(SPECIES.length());
1885         double[] r = fr.apply(SPECIES.length());
1886         boolean[] mask = fm.apply(SPECIES.length());
1887         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
1888 
1889         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1890             for (int i = 0; i < a.length; i += SPECIES.length()) {
1891                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1892                 av.sqrt(vmask).intoArray(r, i);
1893             }
1894         }
1895 
1896         assertArraysEquals(a, r, mask, DoubleMaxVectorTests::sqrt);
1897     }
1898 
1899 
1900     static double[] gather(double a[], int ix, int[] b, int iy) {
1901         double[] res = new double[SPECIES.length()];
1902         for (int i = 0; i < SPECIES.length(); i++) {
1903             int bi = iy + i;
1904             res[i] = a[b[bi] + ix];
1905         }
1906         return res;
1907     }
1908 
1909     @Test(dataProvider = "doubleUnaryOpIndexProvider")
1910     static void gatherDoubleMaxVectorTests(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1911         double[] a = fa.apply(SPECIES.length());
1912         int[] b    = fs.apply(a.length, SPECIES.length());
1913         double[] r = new double[a.length];
1914 
1915         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1916             for (int i = 0; i < a.length; i += SPECIES.length()) {
1917                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i);
1918                 av.intoArray(r, i);
1919             }
1920         }
1921 
1922         assertArraysEquals(a, b, r, DoubleMaxVectorTests::gather);
1923     }
1924 
1925 
1926     static double[] scatter(double a[], int ix, int[] b, int iy) {
1927       double[] res = new double[SPECIES.length()];
1928       for (int i = 0; i < SPECIES.length(); i++) {
1929         int bi = iy + i;
1930         res[b[bi]] = a[i + ix];
1931       }
1932       return res;
1933     }
1934 
1935     @Test(dataProvider = "doubleUnaryOpIndexProvider")
1936     static void scatterDoubleMaxVectorTests(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1937         double[] a = fa.apply(SPECIES.length());
1938         int[] b = fs.apply(a.length, SPECIES.length());
1939         double[] r = new double[a.length];
1940 
1941         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1942             for (int i = 0; i < a.length; i += SPECIES.length()) {
1943                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1944                 av.intoArray(r, i, b, i);
1945             }
1946         }
1947 
1948         assertArraysEquals(a, b, r, DoubleMaxVectorTests::scatter);
1949     }
1950 
1951 }
1952