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