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