1 /*
   2  * Copyright (c) 2018, 2024, 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 any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @key randomness
  27  *
  28  * @library /test/lib
  29  * @modules jdk.incubator.vector
  30  * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation DoubleMaxVectorTests
  31  */
  32 
  33 // -- This file was mechanically generated: Do not edit! -- //
  34 
  35 import jdk.incubator.vector.VectorShape;
  36 import jdk.incubator.vector.VectorSpecies;
  37 import jdk.incubator.vector.VectorShuffle;
  38 import jdk.incubator.vector.VectorMask;
  39 import jdk.incubator.vector.VectorOperators;
  40 import jdk.incubator.vector.Vector;
  41 
  42 import jdk.incubator.vector.DoubleVector;
  43 
  44 import org.testng.Assert;
  45 import org.testng.annotations.DataProvider;
  46 import org.testng.annotations.Test;
  47 
  48 import java.lang.Integer;
  49 import java.util.List;
  50 import java.util.Arrays;
  51 import java.util.function.BiFunction;
  52 import java.util.function.IntFunction;
  53 import java.util.Objects;
  54 import java.util.stream.Collectors;
  55 import java.util.stream.Stream;
  56 
  57 @Test
  58 public class DoubleMaxVectorTests extends AbstractVectorTest {
  59 
  60     static final VectorSpecies<Double> SPECIES =
  61                 DoubleVector.SPECIES_MAX;
  62 
  63     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  64 
  65     static VectorShape getMaxBit() {
  66         return VectorShape.S_Max_BIT;
  67     }
  68 
  69     private static final int Max = 256;  // juts so we can do N/Max
  70 
  71     // for floating point addition reduction ops that may introduce rounding errors
  72     private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
  73 
  74     // for floating point multiplication reduction ops that may introduce rounding errors
  75     private static final double RELATIVE_ROUNDING_ERROR_FACTOR_MUL = (double)50.0;
  76 
  77     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max);
  78 
  79     static void assertArraysStrictlyEquals(double[] r, double[] a) {
  80         for (int i = 0; i < a.length; i++) {
  81             long ir = Double.doubleToRawLongBits(r[i]);
  82             long ia = Double.doubleToRawLongBits(a[i]);
  83             if (ir != ia) {
  84                 Assert.fail(String.format("at index #%d, expected = %016X, actual = %016X", i, ia, ir));
  85             }
  86         }
  87     }
  88 
  89     interface FUnOp {
  90         double apply(double a);
  91     }
  92 
  93     static void assertArraysEquals(double[] r, double[] a, FUnOp f) {
  94         int i = 0;
  95         try {
  96             for (; i < a.length; i++) {
  97                 Assert.assertEquals(r[i], f.apply(a[i]));
  98             }
  99         } catch (AssertionError e) {
 100             Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]);
 101         }
 102     }
 103 
 104     interface FUnArrayOp {
 105         double[] apply(double a);
 106     }
 107 
 108     static void assertArraysEquals(double[] r, double[] a, FUnArrayOp f) {
 109         int i = 0;
 110         try {
 111             for (; i < a.length; i += SPECIES.length()) {
 112                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 113                   f.apply(a[i]));
 114             }
 115         } catch (AssertionError e) {
 116             double[] ref = f.apply(a[i]);
 117             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 118             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 119               + ", res: " + Arrays.toString(res)
 120               + "), at index #" + i);
 121         }
 122     }
 123 
 124     static void assertArraysEquals(double[] r, double[] a, boolean[] mask, FUnOp f) {
 125         int i = 0;
 126         try {
 127             for (; i < a.length; i++) {
 128                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]);
 129             }
 130         } catch (AssertionError e) {
 131             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()]);
 132         }
 133     }
 134 
 135     interface FReductionOp {
 136         double apply(double[] a, int idx);
 137     }
 138 
 139     interface FReductionAllOp {
 140         double apply(double[] a);
 141     }
 142 
 143     static void assertReductionArraysEquals(double[] r, double rc, double[] a,
 144                                             FReductionOp f, FReductionAllOp fa) {
 145         assertReductionArraysEquals(r, rc, a, f, fa, (double)0.0);
 146     }
 147 
 148     static void assertReductionArraysEquals(double[] r, double rc, double[] a,
 149                                             FReductionOp f, FReductionAllOp fa,
 150                                             double relativeErrorFactor) {
 151         int i = 0;
 152         try {
 153             Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor);
 154             for (; i < a.length; i += SPECIES.length()) {
 155                 Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor);
 156             }
 157         } catch (AssertionError e) {
 158             Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor, "Final result is incorrect!");
 159             Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor, "at index #" + i);
 160         }
 161     }
 162 
 163     interface FReductionMaskedOp {
 164         double apply(double[] a, int idx, boolean[] mask);
 165     }
 166 
 167     interface FReductionAllMaskedOp {
 168         double apply(double[] a, boolean[] mask);
 169     }
 170 
 171     static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
 172                                             FReductionMaskedOp f, FReductionAllMaskedOp fa) {
 173         assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, (double)0.0);
 174     }
 175 
 176     static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
 177                                             FReductionMaskedOp f, FReductionAllMaskedOp fa,
 178                                             double relativeError) {
 179         int i = 0;
 180         try {
 181             Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
 182             for (; i < a.length; i += SPECIES.length()) {
 183                 Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
 184 relativeError));
 185             }
 186         } catch (AssertionError e) {
 187             Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
 188             Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
 189         }
 190     }
 191 
 192     interface FReductionOpLong {
 193         long apply(double[] a, int idx);
 194     }
 195 
 196     interface FReductionAllOpLong {
 197         long apply(double[] a);
 198     }
 199 
 200     static void assertReductionLongArraysEquals(long[] r, long rc, double[] a,
 201                                             FReductionOpLong f, FReductionAllOpLong fa) {
 202         int i = 0;
 203         try {
 204             Assert.assertEquals(rc, fa.apply(a));
 205             for (; i < a.length; i += SPECIES.length()) {
 206                 Assert.assertEquals(r[i], f.apply(a, i));
 207             }
 208         } catch (AssertionError e) {
 209             Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
 210             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 211         }
 212     }
 213 
 214     interface FReductionMaskedOpLong {
 215         long apply(double[] a, int idx, boolean[] mask);
 216     }
 217 
 218     interface FReductionAllMaskedOpLong {
 219         long apply(double[] a, boolean[] mask);
 220     }
 221 
 222     static void assertReductionLongArraysEqualsMasked(long[] r, long rc, double[] a, boolean[] mask,
 223                                             FReductionMaskedOpLong f, FReductionAllMaskedOpLong fa) {
 224         int i = 0;
 225         try {
 226             Assert.assertEquals(rc, fa.apply(a, mask));
 227             for (; i < a.length; i += SPECIES.length()) {
 228                 Assert.assertEquals(r[i], f.apply(a, i, mask));
 229             }
 230         } catch (AssertionError e) {
 231             Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
 232             Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
 233         }
 234     }
 235 
 236     interface FBoolReductionOp {
 237         boolean apply(boolean[] a, int idx);
 238     }
 239 
 240     static void assertReductionBoolArraysEquals(boolean[] r, boolean[] a, FBoolReductionOp f) {
 241         int i = 0;
 242         try {
 243             for (; i < a.length; i += SPECIES.length()) {
 244                 Assert.assertEquals(r[i], f.apply(a, i));
 245             }
 246         } catch (AssertionError e) {
 247             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 248         }
 249     }
 250 
 251     interface FMaskReductionOp {
 252         int apply(boolean[] a, int idx);
 253     }
 254 
 255     static void assertMaskReductionArraysEquals(int[] r, boolean[] a, FMaskReductionOp f) {
 256         int i = 0;
 257         try {
 258             for (; i < a.length; i += SPECIES.length()) {
 259                 Assert.assertEquals(r[i], f.apply(a, i));
 260             }
 261         } catch (AssertionError e) {
 262             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 263         }
 264     }
 265 
 266     static void assertRearrangeArraysEquals(double[] r, double[] a, int[] order, int vector_len) {
 267         int i = 0, j = 0;
 268         try {
 269             for (; i < a.length; i += vector_len) {
 270                 for (j = 0; j < vector_len; j++) {
 271                     Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 272                 }
 273             }
 274         } catch (AssertionError e) {
 275             int idx = i + j;
 276             Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]);
 277         }
 278     }
 279 
 280     static void assertcompressArraysEquals(double[] r, double[] a, boolean[] m, int vector_len) {
 281         int i = 0, j = 0, k = 0;
 282         try {
 283             for (; i < a.length; i += vector_len) {
 284                 k = 0;
 285                 for (j = 0; j < vector_len; j++) {
 286                     if (m[(i + j) % SPECIES.length()]) {
 287                         Assert.assertEquals(r[i + k], a[i + j]);
 288                         k++;
 289                     }
 290                 }
 291                 for (; k < vector_len; k++) {
 292                     Assert.assertEquals(r[i + k], (double)0);
 293                 }
 294             }
 295         } catch (AssertionError e) {
 296             int idx = i + k;
 297             if (m[(i + j) % SPECIES.length()]) {
 298                 Assert.assertEquals(r[idx], a[i + j], "at index #" + idx);
 299             } else {
 300                 Assert.assertEquals(r[idx], (double)0, "at index #" + idx);
 301             }
 302         }
 303     }
 304 
 305     static void assertexpandArraysEquals(double[] r, double[] a, boolean[] m, int vector_len) {
 306         int i = 0, j = 0, k = 0;
 307         try {
 308             for (; i < a.length; i += vector_len) {
 309                 k = 0;
 310                 for (j = 0; j < vector_len; j++) {
 311                     if (m[(i + j) % SPECIES.length()]) {
 312                         Assert.assertEquals(r[i + j], a[i + k]);
 313                         k++;
 314                     } else {
 315                         Assert.assertEquals(r[i + j], (double)0);
 316                     }
 317                 }
 318             }
 319         } catch (AssertionError e) {
 320             int idx = i + j;
 321             if (m[idx % SPECIES.length()]) {
 322                 Assert.assertEquals(r[idx], a[i + k], "at index #" + idx);
 323             } else {
 324                 Assert.assertEquals(r[idx], (double)0, "at index #" + idx);
 325             }
 326         }
 327     }
 328 
 329     static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
 330         int i = 0, j = 0;
 331         boolean is_exceptional_idx = false;
 332         int idx = 0, wrapped_index = 0, oidx = 0;
 333         try {
 334             for (; i < a.length; i += vector_len) {
 335                 for (j = 0; j < vector_len; j++) {
 336                     idx = i + j;
 337                     wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
 338                     is_exceptional_idx = wrapped_index >= vector_len;
 339                     oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
 340                     Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
 341                 }
 342             }
 343         } catch (AssertionError e) {
 344             Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
 345         }
 346     }
 347 
 348     static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
 349         int i = 0, j = 0;
 350         try {
 351             for (; i < a.length; i += vector_len) {
 352                 for (j = 0; j < vector_len; j++) {
 353                     Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
 354                 }
 355             }
 356         } catch (AssertionError e) {
 357             int idx = i + j;
 358             Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]]);
 359         }
 360     }
 361 
 362     static void assertRearrangeArraysEquals(double[] r, double[] a, int[] order, boolean[] mask, int vector_len) {
 363         int i = 0, j = 0;
 364         try {
 365             for (; i < a.length; i += vector_len) {
 366                 for (j = 0; j < vector_len; j++) {
 367                     if (mask[j % SPECIES.length()])
 368                          Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 369                     else
 370                          Assert.assertEquals(r[i+j], (double)0);
 371                 }
 372             }
 373         } catch (AssertionError e) {
 374             int idx = i + j;
 375             if (mask[j % SPECIES.length()])
 376                 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 377             else
 378                 Assert.assertEquals(r[i+j], (double)0, "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 379         }
 380     }
 381 
 382     static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, boolean[] mask, int vector_len) {
 383         int i = 0, j = 0;
 384         try {
 385             for (; i < a.length; i += vector_len) {
 386                 for (j = 0; j < vector_len; j++) {
 387                     if (mask[j % SPECIES.length()])
 388                          Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
 389                     else
 390                          Assert.assertEquals(r[i+j], (double)0);
 391                 }
 392             }
 393         } catch (AssertionError e) {
 394             int idx = i + j;
 395             if (mask[j % SPECIES.length()])
 396                 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 397             else
 398                 Assert.assertEquals(r[i+j], (double)0, "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 399         }
 400     }
 401 
 402     static void assertBroadcastArraysEquals(double[] r, double[] a) {
 403         int i = 0;
 404         for (; i < a.length; i += SPECIES.length()) {
 405             int idx = i;
 406             for (int j = idx; j < (idx + SPECIES.length()); j++)
 407                 a[j]=a[idx];
 408         }
 409 
 410         try {
 411             for (i = 0; i < a.length; i++) {
 412                 Assert.assertEquals(r[i], a[i]);
 413             }
 414         } catch (AssertionError e) {
 415             Assert.assertEquals(r[i], a[i], "at index #" + i + ", input = " + a[i]);
 416         }
 417     }
 418 
 419     interface FBinOp {
 420         double apply(double a, double b);
 421     }
 422 
 423     interface FBinMaskOp {
 424         double apply(double a, double b, boolean m);
 425 
 426         static FBinMaskOp lift(FBinOp f) {
 427             return (a, b, m) -> m ? f.apply(a, b) : a;
 428         }
 429     }
 430 
 431     static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) {
 432         int i = 0;
 433         try {
 434             for (; i < a.length; i++) {
 435                 //Left associative
 436                 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]));
 437 
 438                 //Right associative
 439                 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])));
 440 
 441                 //Results equal sanity check
 442                 Assert.assertEquals(rl[i], rr[i]);
 443             }
 444         } catch (AssertionError e) {
 445             Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 446             Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 447             Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
 448         }
 449     }
 450 
 451    static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) {
 452        assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f));
 453    }
 454 
 455     static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) {
 456         int i = 0;
 457         boolean mask_bit = false;
 458         try {
 459             for (; i < a.length; i++) {
 460                 mask_bit = mask[i % SPECIES.length()];
 461                 //Left associative
 462                 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit));
 463 
 464                 //Right associative
 465                 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit));
 466 
 467                 //Results equal sanity check
 468                 Assert.assertEquals(rl[i], rr[i]);
 469             }
 470         } catch (AssertionError e) {
 471             Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
 472             Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
 473             Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
 474         }
 475     }
 476 
 477     static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 478         int i = 0;
 479         try {
 480             for (; i < a.length; i++) {
 481                 Assert.assertEquals(r[i], f.apply(a[i], b[i]));
 482             }
 483         } catch (AssertionError e) {
 484             Assert.assertEquals(r[i], f.apply(a[i], b[i]), "(" + a[i] + ", " + b[i] + ") at index #" + i);
 485         }
 486     }
 487 
 488     static void assertArraysEquals(double[] r, double[] a, double b, FBinOp f) {
 489         int i = 0;
 490         try {
 491             for (; i < a.length; i++) {
 492                 Assert.assertEquals(r[i], f.apply(a[i], b));
 493             }
 494         } catch (AssertionError e) {
 495             Assert.assertEquals(r[i], f.apply(a[i], b), "(" + a[i] + ", " + b + ") at index #" + i);
 496         }
 497     }
 498 
 499     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 500         int i = 0;
 501         try {
 502             for (; i < a.length; i++) {
 503                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
 504             }
 505         } catch (AssertionError e) {
 506             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]),
 507                                 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
 508         }
 509     }
 510 
 511     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 512         int i = 0;
 513         try {
 514             for (; i < a.length; i++) {
 515                 Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()])));
 516             }
 517         } catch (AssertionError e) {
 518             Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()])),
 519                                 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
 520         }
 521     }
 522 
 523     static void assertArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 524         assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 525     }
 526 
 527     static void assertArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 528         int i = 0;
 529         try {
 530             for (; i < a.length; i++) {
 531                 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]));
 532             }
 533         } catch (AssertionError err) {
 534             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()]);
 535         }
 536     }
 537 
 538     static void assertArraysEquals(double[] r, double[] a, double b, boolean[] mask, FBinOp f) {
 539         assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 540     }
 541 
 542     static void assertArraysEquals(double[] r, double[] a, double b, boolean[] mask, FBinMaskOp f) {
 543         int i = 0;
 544         try {
 545             for (; i < a.length; i++) {
 546                 Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]));
 547             }
 548         } catch (AssertionError err) {
 549             Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b + ", mask = " + mask[i % SPECIES.length()]);
 550         }
 551     }
 552 
 553     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 554         assertBroadcastArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 555     }
 556 
 557     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 558         int i = 0;
 559         try {
 560             for (; i < a.length; i++) {
 561                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
 562             }
 563         } catch (AssertionError err) {
 564             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 565                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 566                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 567                                 mask[i % SPECIES.length()]);
 568         }
 569     }
 570 
 571     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 572         assertBroadcastLongArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 573     }
 574 
 575     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 576         int i = 0;
 577         try {
 578             for (; i < a.length; i++) {
 579                 Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()]), mask[i % SPECIES.length()]));
 580             }
 581         } catch (AssertionError err) {
 582             Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()]),
 583                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 584                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 585                                 mask[i % SPECIES.length()]);
 586         }
 587     }
 588 
 589     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 590         int i = 0;
 591         int j = 0;
 592         try {
 593             for (; j < a.length; j += SPECIES.length()) {
 594                 for (i = 0; i < SPECIES.length(); i++) {
 595                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]));
 596                 }
 597             }
 598         } catch (AssertionError e) {
 599             Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]), "at index #" + i + ", " + j);
 600         }
 601     }
 602 
 603     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 604         assertShiftArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 605     }
 606 
 607     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 608         int i = 0;
 609         int j = 0;
 610         try {
 611             for (; j < a.length; j += SPECIES.length()) {
 612                 for (i = 0; i < SPECIES.length(); i++) {
 613                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]));
 614                 }
 615             }
 616         } catch (AssertionError err) {
 617             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]);
 618         }
 619     }
 620 
 621     interface FBinConstOp {
 622         double apply(double a);
 623     }
 624 
 625     interface FBinConstMaskOp {
 626         double apply(double a, boolean m);
 627 
 628         static FBinConstMaskOp lift(FBinConstOp f) {
 629             return (a, m) -> m ? f.apply(a) : a;
 630         }
 631     }
 632 
 633     static void assertShiftConstEquals(double[] r, double[] a, FBinConstOp f) {
 634         int i = 0;
 635         int j = 0;
 636         try {
 637             for (; j < a.length; j += SPECIES.length()) {
 638                 for (i = 0; i < SPECIES.length(); i++) {
 639                     Assert.assertEquals(r[i+j], f.apply(a[i+j]));
 640                 }
 641             }
 642         } catch (AssertionError e) {
 643             Assert.assertEquals(r[i+j], f.apply(a[i+j]), "at index #" + i + ", " + j);
 644         }
 645     }
 646 
 647     static void assertShiftConstEquals(double[] r, double[] a, boolean[] mask, FBinConstOp f) {
 648         assertShiftConstEquals(r, a, mask, FBinConstMaskOp.lift(f));
 649     }
 650 
 651     static void assertShiftConstEquals(double[] r, double[] a, boolean[] mask, FBinConstMaskOp f) {
 652         int i = 0;
 653         int j = 0;
 654         try {
 655             for (; j < a.length; j += SPECIES.length()) {
 656                 for (i = 0; i < SPECIES.length(); i++) {
 657                     Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]));
 658                 }
 659             }
 660         } catch (AssertionError err) {
 661             Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", mask = " + mask[i]);
 662         }
 663     }
 664 
 665     interface FTernOp {
 666         double apply(double a, double b, double c);
 667     }
 668 
 669     interface FTernMaskOp {
 670         double apply(double a, double b, double c, boolean m);
 671 
 672         static FTernMaskOp lift(FTernOp f) {
 673             return (a, b, c, m) -> m ? f.apply(a, b, c) : a;
 674         }
 675     }
 676 
 677     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 678         int i = 0;
 679         try {
 680             for (; i < a.length; i++) {
 681                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]));
 682             }
 683         } catch (AssertionError e) {
 684             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 685         }
 686     }
 687 
 688     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask, FTernOp f) {
 689         assertArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 690     }
 691 
 692     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask, FTernMaskOp f) {
 693         int i = 0;
 694         try {
 695             for (; i < a.length; i++) {
 696                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]));
 697             }
 698         } catch (AssertionError err) {
 699             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = "
 700               + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 701         }
 702     }
 703 
 704     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 705         int i = 0;
 706         try {
 707             for (; i < a.length; i++) {
 708                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]));
 709             }
 710         } catch (AssertionError e) {
 711             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" +
 712                                 i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " +
 713                                 c[(i / SPECIES.length()) * SPECIES.length()]);
 714         }
 715     }
 716 
 717     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 718         int i = 0;
 719         try {
 720             for (; i < a.length; i++) {
 721                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]));
 722             }
 723         } catch (AssertionError e) {
 724             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]), "at index #" +
 725                                 i + ", input1 = " + a[i] + ", input2 = " +
 726                                 b[(i / SPECIES.length()) * SPECIES.length()] + ",  input3 = " + c[i]);
 727         }
 728     }
 729 
 730     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 731                                             FTernOp f) {
 732         assertBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 733     }
 734 
 735     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 736                                             FTernMaskOp f) {
 737         int i = 0;
 738         try {
 739             for (; i < a.length; i++) {
 740                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
 741                                     mask[i % SPECIES.length()]));
 742             }
 743         } catch (AssertionError err) {
 744             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
 745                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 746                                 b[i] + ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 747                                 mask[i % SPECIES.length()]);
 748         }
 749     }
 750 
 751     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 752                                             FTernOp f) {
 753         assertAltBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 754     }
 755 
 756     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 757                                             FTernMaskOp f) {
 758         int i = 0;
 759         try {
 760             for (; i < a.length; i++) {
 761                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
 762                                     mask[i % SPECIES.length()]));
 763             }
 764         } catch (AssertionError err) {
 765             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
 766                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 767                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
 768                                 ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 769         }
 770     }
 771 
 772     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 773         int i = 0;
 774         try {
 775             for (; i < a.length; i++) {
 776                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 777                                     c[(i / SPECIES.length()) * SPECIES.length()]));
 778             }
 779         } catch (AssertionError e) {
 780             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 781                                 c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" + i + ", input1 = " + a[i]
 782                                 + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " +
 783                                 c[(i / SPECIES.length()) * SPECIES.length()]);
 784         }
 785     }
 786 
 787     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 788                                                   FTernOp f) {
 789         assertDoubleBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 790     }
 791 
 792     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 793                                                   FTernMaskOp f) {
 794         int i = 0;
 795         try {
 796             for (; i < a.length; i++) {
 797                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 798                                     c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
 799             }
 800         } catch (AssertionError err) {
 801             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 802                                 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]), "at index #"
 803                                 + i + ", input1 = " + a[i] + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
 804                                 ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 805                                 mask[i % SPECIES.length()]);
 806         }
 807     }
 808 
 809 
 810     static boolean isWithin1Ulp(double actual, double expected) {
 811         if (Double.isNaN(expected) && !Double.isNaN(actual)) {
 812             return false;
 813         } else if (!Double.isNaN(expected) && Double.isNaN(actual)) {
 814             return false;
 815         }
 816 
 817         double low = Math.nextDown(expected);
 818         double high = Math.nextUp(expected);
 819 
 820         if (Double.compare(low, expected) > 0) {
 821             return false;
 822         }
 823 
 824         if (Double.compare(high, expected) < 0) {
 825             return false;
 826         }
 827 
 828         return true;
 829     }
 830 
 831     static void assertArraysEqualsWithinOneUlp(double[] r, double[] a, FUnOp mathf, FUnOp strictmathf) {
 832         int i = 0;
 833         try {
 834             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 835             for (; i < a.length; i++) {
 836                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i])) == 0 ||
 837                                     isWithin1Ulp(r[i], strictmathf.apply(a[i])));
 838             }
 839         } catch (AssertionError e) {
 840             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]));
 841             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]));
 842         }
 843     }
 844 
 845     static void assertArraysEqualsWithinOneUlp(double[] r, double[] a, double[] b, FBinOp mathf, FBinOp strictmathf) {
 846         int i = 0;
 847         try {
 848             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 849             for (; i < a.length; i++) {
 850                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i], b[i])) == 0 ||
 851                                     isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])));
 852             }
 853         } catch (AssertionError e) {
 854             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]));
 855             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]));
 856         }
 857     }
 858 
 859     static void assertBroadcastArraysEqualsWithinOneUlp(double[] r, double[] a, double[] b,
 860                                                         FBinOp mathf, FBinOp strictmathf) {
 861         int i = 0;
 862         try {
 863             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 864             for (; i < a.length; i++) {
 865                 Assert.assertTrue(Double.compare(r[i],
 866                                   mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0 ||
 867                                   isWithin1Ulp(r[i],
 868                                   strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])));
 869             }
 870         } catch (AssertionError e) {
 871             Assert.assertTrue(Double.compare(r[i],
 872                               mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0,
 873                               "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 874                               b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
 875                               ", expected = " + mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
 876             Assert.assertTrue(isWithin1Ulp(r[i],
 877                               strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])),
 878                              "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 879                              b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
 880                              ", expected (within 1 ulp) = " + strictmathf.apply(a[i],
 881                              b[(i / SPECIES.length()) * SPECIES.length()]));
 882         }
 883     }
 884 
 885     interface FGatherScatterOp {
 886         double[] apply(double[] a, int ix, int[] b, int iy);
 887     }
 888 
 889     static void assertArraysEquals(double[] r, double[] a, int[] b, FGatherScatterOp f) {
 890         int i = 0;
 891         try {
 892             for (; i < a.length; i += SPECIES.length()) {
 893                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 894                   f.apply(a, i, b, i));
 895             }
 896         } catch (AssertionError e) {
 897             double[] ref = f.apply(a, i, b, i);
 898             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 899             Assert.assertEquals(res, ref,
 900               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 901               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 902               + ", b: "
 903               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 904               + " at index #" + i);
 905         }
 906     }
 907 
 908     interface FGatherMaskedOp {
 909         double[] apply(double[] a, int ix, boolean[] mask, int[] b, int iy);
 910     }
 911 
 912     interface FScatterMaskedOp {
 913         double[] apply(double[] r, double[] a, int ix, boolean[] mask, int[] b, int iy);
 914     }
 915 
 916     static void assertArraysEquals(double[] r, double[] a, int[] b, boolean[] mask, FGatherMaskedOp f) {
 917         int i = 0;
 918         try {
 919             for (; i < a.length; i += SPECIES.length()) {
 920                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 921                   f.apply(a, i, mask, b, i));
 922             }
 923         } catch (AssertionError e) {
 924             double[] ref = f.apply(a, i, mask, b, i);
 925             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 926             Assert.assertEquals(res, ref,
 927               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 928               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 929               + ", b: "
 930               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 931               + ", mask: "
 932               + Arrays.toString(mask)
 933               + " at index #" + i);
 934         }
 935     }
 936 
 937     static void assertArraysEquals(double[] r, double[] a, int[] b, boolean[] mask, FScatterMaskedOp f) {
 938         int i = 0;
 939         try {
 940             for (; i < a.length; i += SPECIES.length()) {
 941                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 942                   f.apply(r, a, i, mask, b, i));
 943             }
 944         } catch (AssertionError e) {
 945             double[] ref = f.apply(r, a, i, mask, b, i);
 946             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 947             Assert.assertEquals(res, ref,
 948               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 949               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 950               + ", b: "
 951               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 952               + ", r: "
 953               + Arrays.toString(Arrays.copyOfRange(r, i, i+SPECIES.length()))
 954               + ", mask: "
 955               + Arrays.toString(mask)
 956               + " at index #" + i);
 957         }
 958     }
 959 
 960     interface FLaneOp {
 961         double[] apply(double[] a, int origin, int idx);
 962     }
 963 
 964     static void assertArraysEquals(double[] r, double[] a, int origin, FLaneOp f) {
 965         int i = 0;
 966         try {
 967             for (; i < a.length; i += SPECIES.length()) {
 968                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 969                   f.apply(a, origin, i));
 970             }
 971         } catch (AssertionError e) {
 972             double[] ref = f.apply(a, origin, i);
 973             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 974             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 975               + ", res: " + Arrays.toString(res)
 976               + "), at index #" + i);
 977         }
 978     }
 979 
 980     interface FLaneBop {
 981         double[] apply(double[] a, double[] b, int origin, int idx);
 982     }
 983 
 984     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, FLaneBop f) {
 985         int i = 0;
 986         try {
 987             for (; i < a.length; i += SPECIES.length()) {
 988                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 989                   f.apply(a, b, origin, i));
 990             }
 991         } catch (AssertionError e) {
 992             double[] ref = f.apply(a, b, origin, i);
 993             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 994             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 995               + ", res: " + Arrays.toString(res)
 996               + "), at index #" + i
 997               + ", at origin #" + origin);
 998         }
 999     }
1000 
1001     interface FLaneMaskedBop {
1002         double[] apply(double[] a, double[] b, int origin, boolean[] mask, int idx);
1003     }
1004 
1005     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, boolean[] mask, FLaneMaskedBop f) {
1006         int i = 0;
1007         try {
1008             for (; i < a.length; i += SPECIES.length()) {
1009                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1010                   f.apply(a, b, origin, mask, i));
1011             }
1012         } catch (AssertionError e) {
1013             double[] ref = f.apply(a, b, origin, mask, i);
1014             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1015             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1016               + ", res: " + Arrays.toString(res)
1017               + "), at index #" + i
1018               + ", at origin #" + origin);
1019         }
1020     }
1021 
1022     interface FLanePartBop {
1023         double[] apply(double[] a, double[] b, int origin, int part, int idx);
1024     }
1025 
1026     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, int part, FLanePartBop f) {
1027         int i = 0;
1028         try {
1029             for (; i < a.length; i += SPECIES.length()) {
1030                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1031                   f.apply(a, b, origin, part, i));
1032             }
1033         } catch (AssertionError e) {
1034             double[] ref = f.apply(a, b, origin, part, i);
1035             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1036             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1037               + ", res: " + Arrays.toString(res)
1038               + "), at index #" + i
1039               + ", at origin #" + origin
1040               + ", with part #" + part);
1041         }
1042     }
1043 
1044     interface FLanePartMaskedBop {
1045         double[] apply(double[] a, double[] b, int origin, int part, boolean[] mask, int idx);
1046     }
1047 
1048     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, int part, boolean[] mask, FLanePartMaskedBop f) {
1049         int i = 0;
1050         try {
1051             for (; i < a.length; i += SPECIES.length()) {
1052                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1053                   f.apply(a, b, origin, part, mask, i));
1054             }
1055         } catch (AssertionError e) {
1056             double[] ref = f.apply(a, b, origin, part, mask, i);
1057             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1058             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1059               + ", res: " + Arrays.toString(res)
1060               + "), at index #" + i
1061               + ", at origin #" + origin
1062               + ", with part #" + part);
1063         }
1064     }
1065 
1066     static int intCornerCaseValue(int i) {
1067         switch(i % 5) {
1068             case 0:
1069                 return Integer.MAX_VALUE;
1070             case 1:
1071                 return Integer.MIN_VALUE;
1072             case 2:
1073                 return Integer.MIN_VALUE;
1074             case 3:
1075                 return Integer.MAX_VALUE;
1076             default:
1077                 return (int)0;
1078         }
1079     }
1080 
1081     static final List<IntFunction<double[]>> INT_DOUBLE_GENERATORS = List.of(
1082             withToString("double[-i * 5]", (int s) -> {
1083                 return fill(s * BUFFER_REPS,
1084                             i -> (double)(-i * 5));
1085             }),
1086             withToString("double[i * 5]", (int s) -> {
1087                 return fill(s * BUFFER_REPS,
1088                             i -> (double)(i * 5));
1089             }),
1090             withToString("double[i + 1]", (int s) -> {
1091                 return fill(s * BUFFER_REPS,
1092                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1093             }),
1094             withToString("double[intCornerCaseValue(i)]", (int s) -> {
1095                 return fill(s * BUFFER_REPS,
1096                             i -> (double)intCornerCaseValue(i));
1097             })
1098     );
1099 
1100     static void assertArraysEquals(int[] r, double[] a, int offs) {
1101         int i = 0;
1102         try {
1103             for (; i < r.length; i++) {
1104                 Assert.assertEquals(r[i], (int)(a[i+offs]));
1105             }
1106         } catch (AssertionError e) {
1107             Assert.assertEquals(r[i], (int)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1108         }
1109     }
1110 
1111     static long longCornerCaseValue(int i) {
1112         switch(i % 5) {
1113             case 0:
1114                 return Long.MAX_VALUE;
1115             case 1:
1116                 return Long.MIN_VALUE;
1117             case 2:
1118                 return Long.MIN_VALUE;
1119             case 3:
1120                 return Long.MAX_VALUE;
1121             default:
1122                 return (long)0;
1123         }
1124     }
1125 
1126     static final List<IntFunction<double[]>> LONG_DOUBLE_GENERATORS = List.of(
1127             withToString("double[-i * 5]", (int s) -> {
1128                 return fill(s * BUFFER_REPS,
1129                             i -> (double)(-i * 5));
1130             }),
1131             withToString("double[i * 5]", (int s) -> {
1132                 return fill(s * BUFFER_REPS,
1133                             i -> (double)(i * 5));
1134             }),
1135             withToString("double[i + 1]", (int s) -> {
1136                 return fill(s * BUFFER_REPS,
1137                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1138             }),
1139             withToString("double[cornerCaseValue(i)]", (int s) -> {
1140                 return fill(s * BUFFER_REPS,
1141                             i -> (double)longCornerCaseValue(i));
1142             })
1143     );
1144 
1145 
1146     static void assertArraysEquals(long[] r, double[] a, int offs) {
1147         int i = 0;
1148         try {
1149             for (; i < r.length; i++) {
1150                 Assert.assertEquals(r[i], (long)(a[i+offs]));
1151             }
1152         } catch (AssertionError e) {
1153             Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1154         }
1155     }
1156 
1157     static long bits(double e) {
1158         return  Double.doubleToLongBits(e);
1159     }
1160 
1161     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
1162             withToString("double[-i * 5]", (int s) -> {
1163                 return fill(s * BUFFER_REPS,
1164                             i -> (double)(-i * 5));
1165             }),
1166             withToString("double[i * 5]", (int s) -> {
1167                 return fill(s * BUFFER_REPS,
1168                             i -> (double)(i * 5));
1169             }),
1170             withToString("double[i + 1]", (int s) -> {
1171                 return fill(s * BUFFER_REPS,
1172                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1173             }),
1174             withToString("double[0.01 + (i / (i + 1))]", (int s) -> {
1175                 return fill(s * BUFFER_REPS,
1176                             i -> (double)0.01 + ((double)i / (i + 1)));
1177             }),
1178             withToString("double[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
1179                 return fill(s * BUFFER_REPS,
1180                             i -> i % 17 == 0 ? cornerCaseValue(i) : (double)0.01 + ((double)i / (i + 1)));
1181             }),
1182             withToString("double[cornerCaseValue(i)]", (int s) -> {
1183                 return fill(s * BUFFER_REPS,
1184                             i -> cornerCaseValue(i));
1185             })
1186     );
1187 
1188     // Create combinations of pairs
1189     // @@@ Might be sensitive to order e.g. div by 0
1190     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_PAIRS =
1191         Stream.of(DOUBLE_GENERATORS.get(0)).
1192                 flatMap(fa -> DOUBLE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
1193                 collect(Collectors.toList());
1194 
1195     @DataProvider
1196     public Object[][] boolUnaryOpProvider() {
1197         return BOOL_ARRAY_GENERATORS.stream().
1198                 map(f -> new Object[]{f}).
1199                 toArray(Object[][]::new);
1200     }
1201 
1202     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_TRIPLES =
1203         DOUBLE_GENERATOR_PAIRS.stream().
1204                 flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1205                 collect(Collectors.toList());
1206 
1207     static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
1208             withToString("double[0..VECLEN*2)", (int s) -> {
1209                 return fill(s * BUFFER_REPS,
1210                             i -> (double)(RAND.nextInt()));
1211             })
1212     );
1213 
1214     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
1215         DOUBLE_GENERATOR_PAIRS.stream().
1216                 flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1217                 collect(Collectors.toList());
1218 
1219     @DataProvider
1220     public Object[][] doubleBinaryOpProvider() {
1221         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
1222                 toArray(Object[][]::new);
1223     }
1224 
1225     @DataProvider
1226     public Object[][] doubleIndexedOpProvider() {
1227         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
1228                 toArray(Object[][]::new);
1229     }
1230 
1231     @DataProvider
1232     public Object[][] doubleBinaryOpMaskProvider() {
1233         return BOOLEAN_MASK_GENERATORS.stream().
1234                 flatMap(fm -> DOUBLE_GENERATOR_PAIRS.stream().map(lfa -> {
1235                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1236                 })).
1237                 toArray(Object[][]::new);
1238     }
1239 
1240     @DataProvider
1241     public Object[][] doubleTernaryOpProvider() {
1242         return DOUBLE_GENERATOR_TRIPLES.stream().map(List::toArray).
1243                 toArray(Object[][]::new);
1244     }
1245 
1246     @DataProvider
1247     public Object[][] doubleSelectFromTwoVectorOpProvider() {
1248         return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
1249                 toArray(Object[][]::new);
1250     }
1251 
1252     @DataProvider
1253     public Object[][] doubleTernaryOpMaskProvider() {
1254         return BOOLEAN_MASK_GENERATORS.stream().
1255                 flatMap(fm -> DOUBLE_GENERATOR_TRIPLES.stream().map(lfa -> {
1256                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1257                 })).
1258                 toArray(Object[][]::new);
1259     }
1260 
1261     @DataProvider
1262     public Object[][] doubleUnaryOpProvider() {
1263         return DOUBLE_GENERATORS.stream().
1264                 map(f -> new Object[]{f}).
1265                 toArray(Object[][]::new);
1266     }
1267 
1268     @DataProvider
1269     public Object[][] doubleUnaryOpMaskProvider() {
1270         return BOOLEAN_MASK_GENERATORS.stream().
1271                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
1272                     return new Object[] {fa, fm};
1273                 })).
1274                 toArray(Object[][]::new);
1275     }
1276 
1277     @DataProvider
1278     public Object[][] doubletoIntUnaryOpProvider() {
1279         return INT_DOUBLE_GENERATORS.stream().
1280                 map(f -> new Object[]{f}).
1281                 toArray(Object[][]::new);
1282     }
1283 
1284     @DataProvider
1285     public Object[][] doubletoLongUnaryOpProvider() {
1286         return LONG_DOUBLE_GENERATORS.stream().
1287                 map(f -> new Object[]{f}).
1288                 toArray(Object[][]::new);
1289     }
1290 
1291     @DataProvider
1292     public Object[][] maskProvider() {
1293         return BOOLEAN_MASK_GENERATORS.stream().
1294                 map(f -> new Object[]{f}).
1295                 toArray(Object[][]::new);
1296     }
1297 
1298     @DataProvider
1299     public Object[][] maskCompareOpProvider() {
1300         return BOOLEAN_MASK_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1301                 toArray(Object[][]::new);
1302     }
1303 
1304     @DataProvider
1305     public Object[][] shuffleProvider() {
1306         return INT_SHUFFLE_GENERATORS.stream().
1307                 map(f -> new Object[]{f}).
1308                 toArray(Object[][]::new);
1309     }
1310 
1311     @DataProvider
1312     public Object[][] shuffleCompareOpProvider() {
1313         return INT_SHUFFLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1314                 toArray(Object[][]::new);
1315     }
1316 
1317     @DataProvider
1318     public Object[][] doubleUnaryOpShuffleProvider() {
1319         return INT_SHUFFLE_GENERATORS.stream().
1320                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1321                     return new Object[] {fa, fs};
1322                 })).
1323                 toArray(Object[][]::new);
1324     }
1325 
1326     @DataProvider
1327     public Object[][] doubleUnaryOpShuffleMaskProvider() {
1328         return BOOLEAN_MASK_GENERATORS.stream().
1329                 flatMap(fm -> INT_SHUFFLE_GENERATORS.stream().
1330                     flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1331                         return new Object[] {fa, fs, fm};
1332                 }))).
1333                 toArray(Object[][]::new);
1334     }
1335 
1336     static final List<BiFunction<Integer,Integer,double[]>> DOUBLE_SHUFFLE_GENERATORS = List.of(
1337             withToStringBi("shuffle[random]", (Integer l, Integer m) -> {
1338                 double[] a = new double[l];
1339                 int upper = m;
1340                 for (int i = 0; i < 1; i++) {
1341                     a[i] = (double)RAND.nextInt(upper);
1342                 }
1343                 return a;
1344             })
1345     );
1346 
1347     @DataProvider
1348     public Object[][] doubleUnaryOpSelectFromProvider() {
1349         return DOUBLE_SHUFFLE_GENERATORS.stream().
1350                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1351                     return new Object[] {fa, fs};
1352                 })).
1353                 toArray(Object[][]::new);
1354     }
1355 
1356     @DataProvider
1357     public Object[][] doubleUnaryOpSelectFromMaskProvider() {
1358         return BOOLEAN_MASK_GENERATORS.stream().
1359                 flatMap(fm -> DOUBLE_SHUFFLE_GENERATORS.stream().
1360                     flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1361                         return new Object[] {fa, fs, fm};
1362                 }))).
1363                 toArray(Object[][]::new);
1364     }
1365 
1366     static final List<IntFunction<double[]>> DOUBLE_COMPARE_GENERATORS = List.of(
1367             withToString("double[i]", (int s) -> {
1368                 return fill(s * BUFFER_REPS,
1369                             i -> (double)i);
1370             }),
1371             withToString("double[i - length / 2]", (int s) -> {
1372                 return fill(s * BUFFER_REPS,
1373                             i -> (double)(i - (s * BUFFER_REPS / 2)));
1374             }),
1375             withToString("double[i + 1]", (int s) -> {
1376                 return fill(s * BUFFER_REPS,
1377                             i -> (double)(i + 1));
1378             }),
1379             withToString("double[i - 2]", (int s) -> {
1380                 return fill(s * BUFFER_REPS,
1381                             i -> (double)(i - 2));
1382             }),
1383             withToString("double[zigZag(i)]", (int s) -> {
1384                 return fill(s * BUFFER_REPS,
1385                             i -> i%3 == 0 ? (double)i : (i%3 == 1 ? (double)(i + 1) : (double)(i - 2)));
1386             }),
1387             withToString("double[cornerCaseValue(i)]", (int s) -> {
1388                 return fill(s * BUFFER_REPS,
1389                             i -> cornerCaseValue(i));
1390             })
1391     );
1392 
1393     static final List<List<IntFunction<double[]>>> DOUBLE_TEST_GENERATOR_ARGS =
1394         DOUBLE_COMPARE_GENERATORS.stream().
1395                 map(fa -> List.of(fa)).
1396                 collect(Collectors.toList());
1397 
1398     @DataProvider
1399     public Object[][] doubleTestOpProvider() {
1400         return DOUBLE_TEST_GENERATOR_ARGS.stream().map(List::toArray).
1401                 toArray(Object[][]::new);
1402     }
1403 
1404     @DataProvider
1405     public Object[][] doubleTestOpMaskProvider() {
1406         return BOOLEAN_MASK_GENERATORS.stream().
1407                 flatMap(fm -> DOUBLE_TEST_GENERATOR_ARGS.stream().map(lfa -> {
1408                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1409                 })).
1410                 toArray(Object[][]::new);
1411     }
1412 
1413     static final List<List<IntFunction<double[]>>> DOUBLE_COMPARE_GENERATOR_PAIRS =
1414         DOUBLE_COMPARE_GENERATORS.stream().
1415                 flatMap(fa -> DOUBLE_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))).
1416                 collect(Collectors.toList());
1417 
1418     @DataProvider
1419     public Object[][] doubleCompareOpProvider() {
1420         return DOUBLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1421                 toArray(Object[][]::new);
1422     }
1423 
1424     @DataProvider
1425     public Object[][] doubleCompareOpMaskProvider() {
1426         return BOOLEAN_MASK_GENERATORS.stream().
1427                 flatMap(fm -> DOUBLE_COMPARE_GENERATOR_PAIRS.stream().map(lfa -> {
1428                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1429                 })).
1430                 toArray(Object[][]::new);
1431     }
1432 
1433     interface ToDoubleF {
1434         double apply(int i);
1435     }
1436 
1437     static double[] fill(int s , ToDoubleF f) {
1438         return fill(new double[s], f);
1439     }
1440 
1441     static double[] fill(double[] a, ToDoubleF f) {
1442         for (int i = 0; i < a.length; i++) {
1443             a[i] = f.apply(i);
1444         }
1445         return a;
1446     }
1447 
1448     static double cornerCaseValue(int i) {
1449         return switch(i % 8) {
1450             case 0  -> Double.MAX_VALUE;
1451             case 1  -> Double.MIN_VALUE;
1452             case 2  -> Double.NEGATIVE_INFINITY;
1453             case 3  -> Double.POSITIVE_INFINITY;
1454             case 4  -> Double.NaN;
1455             case 5  -> Double.longBitsToDouble(0x7FF123456789ABCDL);
1456             case 6  -> (double)0.0;
1457             default -> (double)-0.0;
1458         };
1459     }
1460 
1461     static final IntFunction<double[]> fr = (vl) -> {
1462         int length = BUFFER_REPS * vl;
1463         return new double[length];
1464     };
1465 
1466     static final IntFunction<boolean[]> fmr = (vl) -> {
1467         int length = BUFFER_REPS * vl;
1468         return new boolean[length];
1469     };
1470 
1471     static final IntFunction<long[]> lfr = (vl) -> {
1472         int length = BUFFER_REPS * vl;
1473         return new long[length];
1474     };
1475 
1476     static boolean eq(double a, double b) {
1477         return a == b;
1478     }
1479 
1480     static boolean neq(double a, double b) {
1481         return a != b;
1482     }
1483 
1484     static boolean lt(double a, double b) {
1485         return a < b;
1486     }
1487 
1488     static boolean le(double a, double b) {
1489         return a <= b;
1490     }
1491 
1492     static boolean gt(double a, double b) {
1493         return a > b;
1494     }
1495 
1496     static boolean ge(double a, double b) {
1497         return a >= b;
1498     }
1499 
1500     static double firstNonZero(double a, double b) {
1501         return Double.compare(a, (double) 0) != 0 ? a : b;
1502     }
1503 
1504     @Test
1505     static void smokeTest1() {
1506         DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3);
1507         DoubleVector three2 = (DoubleVector) SPECIES.broadcast(-3);
1508         assert(three.eq(three2).allTrue());
1509         DoubleVector three3 = three2.broadcast(1).broadcast(-3);
1510         assert(three.eq(three3).allTrue());
1511         int scale = 2;
1512         Class<?> ETYPE = double.class;
1513         if (ETYPE == double.class || ETYPE == long.class)
1514             scale = 1000000;
1515         else if (ETYPE == byte.class && SPECIES.length() >= 64)
1516             scale = 1;
1517         DoubleVector higher = three.addIndex(scale);
1518         VectorMask<Double> m = three.compare(VectorOperators.LE, higher);
1519         assert(m.allTrue());
1520         m = higher.min((double)-1).test(VectorOperators.IS_NEGATIVE);
1521         assert(m.allTrue());
1522         m = higher.test(VectorOperators.IS_FINITE);
1523         assert(m.allTrue());
1524         double max = higher.reduceLanes(VectorOperators.MAX);
1525         assert(max == -3 + scale * (SPECIES.length()-1));
1526     }
1527 
1528     private static double[]
1529     bothToArray(DoubleVector a, DoubleVector b) {
1530         double[] r = new double[a.length() + b.length()];
1531         a.intoArray(r, 0);
1532         b.intoArray(r, a.length());
1533         return r;
1534     }
1535 
1536     @Test
1537     static void smokeTest2() {
1538         // Do some zipping and shuffling.
1539         DoubleVector io = (DoubleVector) SPECIES.broadcast(0).addIndex(1);
1540         DoubleVector io2 = (DoubleVector) VectorShuffle.iota(SPECIES,0,1,false).toVector();
1541         Assert.assertEquals(io, io2);
1542         DoubleVector a = io.add((double)1); //[1,2]
1543         DoubleVector b = a.neg();  //[-1,-2]
1544         double[] abValues = bothToArray(a,b); //[1,2,-1,-2]
1545         VectorShuffle<Double> zip0 = VectorShuffle.makeZip(SPECIES, 0);
1546         VectorShuffle<Double> zip1 = VectorShuffle.makeZip(SPECIES, 1);
1547         DoubleVector zab0 = a.rearrange(zip0,b); //[1,-1]
1548         DoubleVector zab1 = a.rearrange(zip1,b); //[2,-2]
1549         double[] zabValues = bothToArray(zab0, zab1); //[1,-1,2,-2]
1550         // manually zip
1551         double[] manual = new double[zabValues.length];
1552         for (int i = 0; i < manual.length; i += 2) {
1553             manual[i+0] = abValues[i/2];
1554             manual[i+1] = abValues[a.length() + i/2];
1555         }
1556         Assert.assertEquals(Arrays.toString(zabValues), Arrays.toString(manual));
1557         VectorShuffle<Double> unz0 = VectorShuffle.makeUnzip(SPECIES, 0);
1558         VectorShuffle<Double> unz1 = VectorShuffle.makeUnzip(SPECIES, 1);
1559         DoubleVector uab0 = zab0.rearrange(unz0,zab1);
1560         DoubleVector uab1 = zab0.rearrange(unz1,zab1);
1561         double[] abValues1 = bothToArray(uab0, uab1);
1562         Assert.assertEquals(Arrays.toString(abValues), Arrays.toString(abValues1));
1563     }
1564 
1565     static void iotaShuffle() {
1566         DoubleVector io = (DoubleVector) SPECIES.broadcast(0).addIndex(1);
1567         DoubleVector io2 = (DoubleVector) VectorShuffle.iota(SPECIES, 0 , 1, false).toVector();
1568         Assert.assertEquals(io, io2);
1569     }
1570 
1571     @Test
1572     // Test all shuffle related operations.
1573     static void shuffleTest() {
1574         // To test backend instructions, make sure that C2 is used.
1575         for (int loop = 0; loop < INVOC_COUNT * INVOC_COUNT; loop++) {
1576             iotaShuffle();
1577         }
1578     }
1579 
1580     @Test
1581     void viewAsIntegeralLanesTest() {
1582         Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes();
1583         VectorSpecies<?> asIntegralSpecies = asIntegral.species();
1584         Assert.assertNotEquals(asIntegralSpecies.elementType(), SPECIES.elementType());
1585         Assert.assertEquals(asIntegralSpecies.vectorShape(), SPECIES.vectorShape());
1586         Assert.assertEquals(asIntegralSpecies.length(), SPECIES.length());
1587         Assert.assertEquals(asIntegral.viewAsFloatingLanes().species(), SPECIES);
1588     }
1589 
1590     @Test
1591     void viewAsFloatingLanesTest() {
1592         Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes();
1593         Assert.assertEquals(asFloating.species(), SPECIES);
1594     }
1595 
1596     static double ADD(double a, double b) {
1597         return (double)(a + b);
1598     }
1599 
1600     @Test(dataProvider = "doubleBinaryOpProvider")
1601     static void ADDDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1602         double[] a = fa.apply(SPECIES.length());
1603         double[] b = fb.apply(SPECIES.length());
1604         double[] r = fr.apply(SPECIES.length());
1605 
1606         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1607             for (int i = 0; i < a.length; i += SPECIES.length()) {
1608                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1609                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1610                 av.lanewise(VectorOperators.ADD, bv).intoArray(r, i);
1611             }
1612         }
1613 
1614         assertArraysEquals(r, a, b, DoubleMaxVectorTests::ADD);
1615     }
1616 
1617     static double add(double a, double b) {
1618         return (double)(a + b);
1619     }
1620 
1621     @Test(dataProvider = "doubleBinaryOpProvider")
1622     static void addDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1623         double[] a = fa.apply(SPECIES.length());
1624         double[] b = fb.apply(SPECIES.length());
1625         double[] r = fr.apply(SPECIES.length());
1626 
1627         for (int i = 0; i < a.length; i += SPECIES.length()) {
1628             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1629             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1630             av.add(bv).intoArray(r, i);
1631         }
1632 
1633         assertArraysEquals(r, a, b, DoubleMaxVectorTests::add);
1634     }
1635 
1636     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1637     static void ADDDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1638                                           IntFunction<boolean[]> fm) {
1639         double[] a = fa.apply(SPECIES.length());
1640         double[] b = fb.apply(SPECIES.length());
1641         double[] r = fr.apply(SPECIES.length());
1642         boolean[] mask = fm.apply(SPECIES.length());
1643         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1644 
1645         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1646             for (int i = 0; i < a.length; i += SPECIES.length()) {
1647                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1648                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1649                 av.lanewise(VectorOperators.ADD, bv, vmask).intoArray(r, i);
1650             }
1651         }
1652 
1653         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::ADD);
1654     }
1655 
1656     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1657     static void addDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1658                                           IntFunction<boolean[]> fm) {
1659         double[] a = fa.apply(SPECIES.length());
1660         double[] b = fb.apply(SPECIES.length());
1661         double[] r = fr.apply(SPECIES.length());
1662         boolean[] mask = fm.apply(SPECIES.length());
1663         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1664 
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.add(bv, vmask).intoArray(r, i);
1669         }
1670 
1671         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::add);
1672     }
1673 
1674     static double SUB(double a, double b) {
1675         return (double)(a - b);
1676     }
1677 
1678     @Test(dataProvider = "doubleBinaryOpProvider")
1679     static void SUBDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1680         double[] a = fa.apply(SPECIES.length());
1681         double[] b = fb.apply(SPECIES.length());
1682         double[] r = fr.apply(SPECIES.length());
1683 
1684         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1685             for (int i = 0; i < a.length; i += SPECIES.length()) {
1686                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1687                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1688                 av.lanewise(VectorOperators.SUB, bv).intoArray(r, i);
1689             }
1690         }
1691 
1692         assertArraysEquals(r, a, b, DoubleMaxVectorTests::SUB);
1693     }
1694 
1695     static double sub(double a, double b) {
1696         return (double)(a - b);
1697     }
1698 
1699     @Test(dataProvider = "doubleBinaryOpProvider")
1700     static void subDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1701         double[] a = fa.apply(SPECIES.length());
1702         double[] b = fb.apply(SPECIES.length());
1703         double[] r = fr.apply(SPECIES.length());
1704 
1705         for (int i = 0; i < a.length; i += SPECIES.length()) {
1706             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1707             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1708             av.sub(bv).intoArray(r, i);
1709         }
1710 
1711         assertArraysEquals(r, a, b, DoubleMaxVectorTests::sub);
1712     }
1713 
1714     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1715     static void SUBDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1716                                           IntFunction<boolean[]> fm) {
1717         double[] a = fa.apply(SPECIES.length());
1718         double[] b = fb.apply(SPECIES.length());
1719         double[] r = fr.apply(SPECIES.length());
1720         boolean[] mask = fm.apply(SPECIES.length());
1721         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1722 
1723         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1724             for (int i = 0; i < a.length; i += SPECIES.length()) {
1725                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1726                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1727                 av.lanewise(VectorOperators.SUB, bv, vmask).intoArray(r, i);
1728             }
1729         }
1730 
1731         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::SUB);
1732     }
1733 
1734     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1735     static void subDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1736                                           IntFunction<boolean[]> fm) {
1737         double[] a = fa.apply(SPECIES.length());
1738         double[] b = fb.apply(SPECIES.length());
1739         double[] r = fr.apply(SPECIES.length());
1740         boolean[] mask = fm.apply(SPECIES.length());
1741         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1742 
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             av.sub(bv, vmask).intoArray(r, i);
1747         }
1748 
1749         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::sub);
1750     }
1751 
1752     static double MUL(double a, double b) {
1753         return (double)(a * b);
1754     }
1755 
1756     @Test(dataProvider = "doubleBinaryOpProvider")
1757     static void MULDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1758         double[] a = fa.apply(SPECIES.length());
1759         double[] b = fb.apply(SPECIES.length());
1760         double[] r = fr.apply(SPECIES.length());
1761 
1762         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1763             for (int i = 0; i < a.length; i += SPECIES.length()) {
1764                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1765                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1766                 av.lanewise(VectorOperators.MUL, bv).intoArray(r, i);
1767             }
1768         }
1769 
1770         assertArraysEquals(r, a, b, DoubleMaxVectorTests::MUL);
1771     }
1772 
1773     static double mul(double a, double b) {
1774         return (double)(a * b);
1775     }
1776 
1777     @Test(dataProvider = "doubleBinaryOpProvider")
1778     static void mulDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1779         double[] a = fa.apply(SPECIES.length());
1780         double[] b = fb.apply(SPECIES.length());
1781         double[] r = fr.apply(SPECIES.length());
1782 
1783         for (int i = 0; i < a.length; i += SPECIES.length()) {
1784             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1785             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1786             av.mul(bv).intoArray(r, i);
1787         }
1788 
1789         assertArraysEquals(r, a, b, DoubleMaxVectorTests::mul);
1790     }
1791 
1792     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1793     static void MULDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1794                                           IntFunction<boolean[]> fm) {
1795         double[] a = fa.apply(SPECIES.length());
1796         double[] b = fb.apply(SPECIES.length());
1797         double[] r = fr.apply(SPECIES.length());
1798         boolean[] mask = fm.apply(SPECIES.length());
1799         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1800 
1801         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1802             for (int i = 0; i < a.length; i += SPECIES.length()) {
1803                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1804                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1805                 av.lanewise(VectorOperators.MUL, bv, vmask).intoArray(r, i);
1806             }
1807         }
1808 
1809         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::MUL);
1810     }
1811 
1812     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1813     static void mulDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1814                                           IntFunction<boolean[]> fm) {
1815         double[] a = fa.apply(SPECIES.length());
1816         double[] b = fb.apply(SPECIES.length());
1817         double[] r = fr.apply(SPECIES.length());
1818         boolean[] mask = fm.apply(SPECIES.length());
1819         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1820 
1821         for (int i = 0; i < a.length; i += SPECIES.length()) {
1822             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1823             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1824             av.mul(bv, vmask).intoArray(r, i);
1825         }
1826 
1827         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::mul);
1828     }
1829 
1830     static double DIV(double a, double b) {
1831         return (double)(a / b);
1832     }
1833 
1834     @Test(dataProvider = "doubleBinaryOpProvider")
1835     static void DIVDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1836         double[] a = fa.apply(SPECIES.length());
1837         double[] b = fb.apply(SPECIES.length());
1838         double[] r = fr.apply(SPECIES.length());
1839 
1840         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1841             for (int i = 0; i < a.length; i += SPECIES.length()) {
1842                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1843                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1844                 av.lanewise(VectorOperators.DIV, bv).intoArray(r, i);
1845             }
1846         }
1847 
1848         assertArraysEquals(r, a, b, DoubleMaxVectorTests::DIV);
1849     }
1850 
1851     static double div(double a, double b) {
1852         return (double)(a / b);
1853     }
1854 
1855     @Test(dataProvider = "doubleBinaryOpProvider")
1856     static void divDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1857         double[] a = fa.apply(SPECIES.length());
1858         double[] b = fb.apply(SPECIES.length());
1859         double[] r = fr.apply(SPECIES.length());
1860 
1861         for (int i = 0; i < a.length; i += SPECIES.length()) {
1862             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1863             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1864             av.div(bv).intoArray(r, i);
1865         }
1866 
1867         assertArraysEquals(r, a, b, DoubleMaxVectorTests::div);
1868     }
1869 
1870     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1871     static void DIVDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1872                                           IntFunction<boolean[]> fm) {
1873         double[] a = fa.apply(SPECIES.length());
1874         double[] b = fb.apply(SPECIES.length());
1875         double[] r = fr.apply(SPECIES.length());
1876         boolean[] mask = fm.apply(SPECIES.length());
1877         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1878 
1879         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1880             for (int i = 0; i < a.length; i += SPECIES.length()) {
1881                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1882                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1883                 av.lanewise(VectorOperators.DIV, bv, vmask).intoArray(r, i);
1884             }
1885         }
1886 
1887         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::DIV);
1888     }
1889 
1890     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1891     static void divDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1892                                           IntFunction<boolean[]> fm) {
1893         double[] a = fa.apply(SPECIES.length());
1894         double[] b = fb.apply(SPECIES.length());
1895         double[] r = fr.apply(SPECIES.length());
1896         boolean[] mask = fm.apply(SPECIES.length());
1897         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1898 
1899         for (int i = 0; i < a.length; i += SPECIES.length()) {
1900             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1901             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1902             av.div(bv, vmask).intoArray(r, i);
1903         }
1904 
1905         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::div);
1906     }
1907 
1908     static double FIRST_NONZERO(double a, double b) {
1909         return (double)(Double.doubleToLongBits(a)!=0?a:b);
1910     }
1911 
1912     @Test(dataProvider = "doubleBinaryOpProvider")
1913     static void FIRST_NONZERODoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1914         double[] a = fa.apply(SPECIES.length());
1915         double[] b = fb.apply(SPECIES.length());
1916         double[] r = fr.apply(SPECIES.length());
1917 
1918         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1919             for (int i = 0; i < a.length; i += SPECIES.length()) {
1920                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1921                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1922                 av.lanewise(VectorOperators.FIRST_NONZERO, bv).intoArray(r, i);
1923             }
1924         }
1925 
1926         assertArraysEquals(r, a, b, DoubleMaxVectorTests::FIRST_NONZERO);
1927     }
1928 
1929     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1930     static void FIRST_NONZERODoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1931                                           IntFunction<boolean[]> fm) {
1932         double[] a = fa.apply(SPECIES.length());
1933         double[] b = fb.apply(SPECIES.length());
1934         double[] r = fr.apply(SPECIES.length());
1935         boolean[] mask = fm.apply(SPECIES.length());
1936         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1937 
1938         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1939             for (int i = 0; i < a.length; i += SPECIES.length()) {
1940                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1941                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1942                 av.lanewise(VectorOperators.FIRST_NONZERO, bv, vmask).intoArray(r, i);
1943             }
1944         }
1945 
1946         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::FIRST_NONZERO);
1947     }
1948 
1949     @Test(dataProvider = "doubleBinaryOpProvider")
1950     static void addDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1951         double[] a = fa.apply(SPECIES.length());
1952         double[] b = fb.apply(SPECIES.length());
1953         double[] r = fr.apply(SPECIES.length());
1954 
1955         for (int i = 0; i < a.length; i += SPECIES.length()) {
1956             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1957             av.add(b[i]).intoArray(r, i);
1958         }
1959 
1960         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::add);
1961     }
1962 
1963     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1964     static void addDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
1965                                           IntFunction<boolean[]> fm) {
1966         double[] a = fa.apply(SPECIES.length());
1967         double[] b = fb.apply(SPECIES.length());
1968         double[] r = fr.apply(SPECIES.length());
1969         boolean[] mask = fm.apply(SPECIES.length());
1970         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1971 
1972         for (int i = 0; i < a.length; i += SPECIES.length()) {
1973             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1974             av.add(b[i], vmask).intoArray(r, i);
1975         }
1976 
1977         assertBroadcastArraysEquals(r, a, b, mask, DoubleMaxVectorTests::add);
1978     }
1979 
1980     @Test(dataProvider = "doubleBinaryOpProvider")
1981     static void subDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1982         double[] a = fa.apply(SPECIES.length());
1983         double[] b = fb.apply(SPECIES.length());
1984         double[] r = fr.apply(SPECIES.length());
1985 
1986         for (int i = 0; i < a.length; i += SPECIES.length()) {
1987             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1988             av.sub(b[i]).intoArray(r, i);
1989         }
1990 
1991         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::sub);
1992     }
1993 
1994     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1995     static void subDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
1996                                           IntFunction<boolean[]> fm) {
1997         double[] a = fa.apply(SPECIES.length());
1998         double[] b = fb.apply(SPECIES.length());
1999         double[] r = fr.apply(SPECIES.length());
2000         boolean[] mask = fm.apply(SPECIES.length());
2001         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2002 
2003         for (int i = 0; i < a.length; i += SPECIES.length()) {
2004             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2005             av.sub(b[i], vmask).intoArray(r, i);
2006         }
2007 
2008         assertBroadcastArraysEquals(r, a, b, mask, DoubleMaxVectorTests::sub);
2009     }
2010 
2011     @Test(dataProvider = "doubleBinaryOpProvider")
2012     static void mulDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2013         double[] a = fa.apply(SPECIES.length());
2014         double[] b = fb.apply(SPECIES.length());
2015         double[] r = fr.apply(SPECIES.length());
2016 
2017         for (int i = 0; i < a.length; i += SPECIES.length()) {
2018             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2019             av.mul(b[i]).intoArray(r, i);
2020         }
2021 
2022         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::mul);
2023     }
2024 
2025     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2026     static void mulDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2027                                           IntFunction<boolean[]> fm) {
2028         double[] a = fa.apply(SPECIES.length());
2029         double[] b = fb.apply(SPECIES.length());
2030         double[] r = fr.apply(SPECIES.length());
2031         boolean[] mask = fm.apply(SPECIES.length());
2032         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2033 
2034         for (int i = 0; i < a.length; i += SPECIES.length()) {
2035             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2036             av.mul(b[i], vmask).intoArray(r, i);
2037         }
2038 
2039         assertBroadcastArraysEquals(r, a, b, mask, DoubleMaxVectorTests::mul);
2040     }
2041 
2042     @Test(dataProvider = "doubleBinaryOpProvider")
2043     static void divDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2044         double[] a = fa.apply(SPECIES.length());
2045         double[] b = fb.apply(SPECIES.length());
2046         double[] r = fr.apply(SPECIES.length());
2047 
2048         for (int i = 0; i < a.length; i += SPECIES.length()) {
2049             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2050             av.div(b[i]).intoArray(r, i);
2051         }
2052 
2053         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::div);
2054     }
2055 
2056     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2057     static void divDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2058                                           IntFunction<boolean[]> fm) {
2059         double[] a = fa.apply(SPECIES.length());
2060         double[] b = fb.apply(SPECIES.length());
2061         double[] r = fr.apply(SPECIES.length());
2062         boolean[] mask = fm.apply(SPECIES.length());
2063         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2064 
2065         for (int i = 0; i < a.length; i += SPECIES.length()) {
2066             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2067             av.div(b[i], vmask).intoArray(r, i);
2068         }
2069 
2070         assertBroadcastArraysEquals(r, a, b, mask, DoubleMaxVectorTests::div);
2071     }
2072 
2073     @Test(dataProvider = "doubleBinaryOpProvider")
2074     static void ADDDoubleMaxVectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2075         double[] a = fa.apply(SPECIES.length());
2076         double[] b = fb.apply(SPECIES.length());
2077         double[] r = fr.apply(SPECIES.length());
2078 
2079         for (int i = 0; i < a.length; i += SPECIES.length()) {
2080             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2081             av.lanewise(VectorOperators.ADD, (long)b[i]).intoArray(r, i);
2082         }
2083 
2084         assertBroadcastLongArraysEquals(r, a, b, DoubleMaxVectorTests::ADD);
2085     }
2086 
2087     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2088     static void ADDDoubleMaxVectorTestsBroadcastMaskedLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2089                                           IntFunction<boolean[]> fm) {
2090         double[] a = fa.apply(SPECIES.length());
2091         double[] b = fb.apply(SPECIES.length());
2092         double[] r = fr.apply(SPECIES.length());
2093         boolean[] mask = fm.apply(SPECIES.length());
2094         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2095 
2096         for (int i = 0; i < a.length; i += SPECIES.length()) {
2097             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2098             av.lanewise(VectorOperators.ADD, (long)b[i], vmask).intoArray(r, i);
2099         }
2100 
2101         assertBroadcastLongArraysEquals(r, a, b, mask, DoubleMaxVectorTests::ADD);
2102     }
2103 
2104     static DoubleVector bv_MIN = DoubleVector.broadcast(SPECIES, (double)10);
2105 
2106     @Test(dataProvider = "doubleUnaryOpProvider")
2107     static void MINDoubleMaxVectorTestsWithMemOp(IntFunction<double[]> fa) {
2108         double[] a = fa.apply(SPECIES.length());
2109         double[] r = fr.apply(SPECIES.length());
2110 
2111         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2112             for (int i = 0; i < a.length; i += SPECIES.length()) {
2113                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2114                 av.lanewise(VectorOperators.MIN, bv_MIN).intoArray(r, i);
2115             }
2116         }
2117 
2118         assertArraysEquals(r, a, (double)10, DoubleMaxVectorTests::MIN);
2119     }
2120 
2121     static DoubleVector bv_min = DoubleVector.broadcast(SPECIES, (double)10);
2122 
2123     @Test(dataProvider = "doubleUnaryOpProvider")
2124     static void minDoubleMaxVectorTestsWithMemOp(IntFunction<double[]> fa) {
2125         double[] a = fa.apply(SPECIES.length());
2126         double[] r = fr.apply(SPECIES.length());
2127 
2128         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2129             for (int i = 0; i < a.length; i += SPECIES.length()) {
2130                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2131                 av.min(bv_min).intoArray(r, i);
2132             }
2133         }
2134 
2135         assertArraysEquals(r, a, (double)10, DoubleMaxVectorTests::min);
2136     }
2137 
2138     static DoubleVector bv_MIN_M = DoubleVector.broadcast(SPECIES, (double)10);
2139 
2140     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2141     static void MINDoubleMaxVectorTestsMaskedWithMemOp(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2142         double[] a = fa.apply(SPECIES.length());
2143         double[] r = fr.apply(SPECIES.length());
2144         boolean[] mask = fm.apply(SPECIES.length());
2145         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2146 
2147         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2148             for (int i = 0; i < a.length; i += SPECIES.length()) {
2149                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2150                 av.lanewise(VectorOperators.MIN, bv_MIN_M, vmask).intoArray(r, i);
2151             }
2152         }
2153 
2154         assertArraysEquals(r, a, (double)10, mask, DoubleMaxVectorTests::MIN);
2155     }
2156 
2157     static DoubleVector bv_MAX = DoubleVector.broadcast(SPECIES, (double)10);
2158 
2159     @Test(dataProvider = "doubleUnaryOpProvider")
2160     static void MAXDoubleMaxVectorTestsWithMemOp(IntFunction<double[]> fa) {
2161         double[] a = fa.apply(SPECIES.length());
2162         double[] r = fr.apply(SPECIES.length());
2163 
2164         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2165             for (int i = 0; i < a.length; i += SPECIES.length()) {
2166                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2167                 av.lanewise(VectorOperators.MAX, bv_MAX).intoArray(r, i);
2168             }
2169         }
2170 
2171         assertArraysEquals(r, a, (double)10, DoubleMaxVectorTests::MAX);
2172     }
2173 
2174     static DoubleVector bv_max = DoubleVector.broadcast(SPECIES, (double)10);
2175 
2176     @Test(dataProvider = "doubleUnaryOpProvider")
2177     static void maxDoubleMaxVectorTestsWithMemOp(IntFunction<double[]> fa) {
2178         double[] a = fa.apply(SPECIES.length());
2179         double[] r = fr.apply(SPECIES.length());
2180 
2181         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2182             for (int i = 0; i < a.length; i += SPECIES.length()) {
2183                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2184                 av.max(bv_max).intoArray(r, i);
2185             }
2186         }
2187 
2188         assertArraysEquals(r, a, (double)10, DoubleMaxVectorTests::max);
2189     }
2190 
2191     static DoubleVector bv_MAX_M = DoubleVector.broadcast(SPECIES, (double)10);
2192 
2193     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2194     static void MAXDoubleMaxVectorTestsMaskedWithMemOp(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2195         double[] a = fa.apply(SPECIES.length());
2196         double[] r = fr.apply(SPECIES.length());
2197         boolean[] mask = fm.apply(SPECIES.length());
2198         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2199 
2200         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2201             for (int i = 0; i < a.length; i += SPECIES.length()) {
2202                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2203                 av.lanewise(VectorOperators.MAX, bv_MAX_M, vmask).intoArray(r, i);
2204             }
2205         }
2206 
2207         assertArraysEquals(r, a, (double)10, mask, DoubleMaxVectorTests::MAX);
2208     }
2209 
2210     static double MIN(double a, double b) {
2211         return (double)(Math.min(a, b));
2212     }
2213 
2214     @Test(dataProvider = "doubleBinaryOpProvider")
2215     static void MINDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2216         double[] a = fa.apply(SPECIES.length());
2217         double[] b = fb.apply(SPECIES.length());
2218         double[] r = fr.apply(SPECIES.length());
2219 
2220         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2221             for (int i = 0; i < a.length; i += SPECIES.length()) {
2222                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2223                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2224                 av.lanewise(VectorOperators.MIN, bv).intoArray(r, i);
2225             }
2226         }
2227 
2228         assertArraysEquals(r, a, b, DoubleMaxVectorTests::MIN);
2229     }
2230 
2231     static double min(double a, double b) {
2232         return (double)(Math.min(a, b));
2233     }
2234 
2235     @Test(dataProvider = "doubleBinaryOpProvider")
2236     static void minDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2237         double[] a = fa.apply(SPECIES.length());
2238         double[] b = fb.apply(SPECIES.length());
2239         double[] r = fr.apply(SPECIES.length());
2240 
2241         for (int i = 0; i < a.length; i += SPECIES.length()) {
2242             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2243             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2244             av.min(bv).intoArray(r, i);
2245         }
2246 
2247         assertArraysEquals(r, a, b, DoubleMaxVectorTests::min);
2248     }
2249 
2250     static double MAX(double a, double b) {
2251         return (double)(Math.max(a, b));
2252     }
2253 
2254     @Test(dataProvider = "doubleBinaryOpProvider")
2255     static void MAXDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2256         double[] a = fa.apply(SPECIES.length());
2257         double[] b = fb.apply(SPECIES.length());
2258         double[] r = fr.apply(SPECIES.length());
2259 
2260         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2261             for (int i = 0; i < a.length; i += SPECIES.length()) {
2262                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2263                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2264                 av.lanewise(VectorOperators.MAX, bv).intoArray(r, i);
2265             }
2266         }
2267 
2268         assertArraysEquals(r, a, b, DoubleMaxVectorTests::MAX);
2269     }
2270 
2271     static double max(double a, double b) {
2272         return (double)(Math.max(a, b));
2273     }
2274 
2275     @Test(dataProvider = "doubleBinaryOpProvider")
2276     static void maxDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2277         double[] a = fa.apply(SPECIES.length());
2278         double[] b = fb.apply(SPECIES.length());
2279         double[] r = fr.apply(SPECIES.length());
2280 
2281         for (int i = 0; i < a.length; i += SPECIES.length()) {
2282             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2283             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2284             av.max(bv).intoArray(r, i);
2285         }
2286 
2287         assertArraysEquals(r, a, b, DoubleMaxVectorTests::max);
2288     }
2289 
2290     @Test(dataProvider = "doubleBinaryOpProvider")
2291     static void MINDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2292         double[] a = fa.apply(SPECIES.length());
2293         double[] b = fb.apply(SPECIES.length());
2294         double[] r = fr.apply(SPECIES.length());
2295 
2296         for (int i = 0; i < a.length; i += SPECIES.length()) {
2297             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2298             av.lanewise(VectorOperators.MIN, b[i]).intoArray(r, i);
2299         }
2300 
2301         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::MIN);
2302     }
2303 
2304     @Test(dataProvider = "doubleBinaryOpProvider")
2305     static void minDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2306         double[] a = fa.apply(SPECIES.length());
2307         double[] b = fb.apply(SPECIES.length());
2308         double[] r = fr.apply(SPECIES.length());
2309 
2310         for (int i = 0; i < a.length; i += SPECIES.length()) {
2311             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2312             av.min(b[i]).intoArray(r, i);
2313         }
2314 
2315         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::min);
2316     }
2317 
2318     @Test(dataProvider = "doubleBinaryOpProvider")
2319     static void MAXDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2320         double[] a = fa.apply(SPECIES.length());
2321         double[] b = fb.apply(SPECIES.length());
2322         double[] r = fr.apply(SPECIES.length());
2323 
2324         for (int i = 0; i < a.length; i += SPECIES.length()) {
2325             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2326             av.lanewise(VectorOperators.MAX, b[i]).intoArray(r, i);
2327         }
2328 
2329         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::MAX);
2330     }
2331 
2332     @Test(dataProvider = "doubleBinaryOpProvider")
2333     static void maxDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2334         double[] a = fa.apply(SPECIES.length());
2335         double[] b = fb.apply(SPECIES.length());
2336         double[] r = fr.apply(SPECIES.length());
2337 
2338         for (int i = 0; i < a.length; i += SPECIES.length()) {
2339             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2340             av.max(b[i]).intoArray(r, i);
2341         }
2342 
2343         assertBroadcastArraysEquals(r, a, b, DoubleMaxVectorTests::max);
2344     }
2345 
2346     static double ADDReduce(double[] a, int idx) {
2347         double res = 0;
2348         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2349             res += a[i];
2350         }
2351 
2352         return res;
2353     }
2354 
2355     static double ADDReduceAll(double[] a) {
2356         double res = 0;
2357         for (int i = 0; i < a.length; i += SPECIES.length()) {
2358             res += ADDReduce(a, i);
2359         }
2360 
2361         return res;
2362     }
2363 
2364     @Test(dataProvider = "doubleUnaryOpProvider")
2365     static void ADDReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
2366         double[] a = fa.apply(SPECIES.length());
2367         double[] r = fr.apply(SPECIES.length());
2368         double ra = 0;
2369 
2370         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2371             for (int i = 0; i < a.length; i += SPECIES.length()) {
2372                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2373                 r[i] = av.reduceLanes(VectorOperators.ADD);
2374             }
2375         }
2376 
2377         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2378             ra = 0;
2379             for (int i = 0; i < a.length; i += SPECIES.length()) {
2380                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2381                 ra += av.reduceLanes(VectorOperators.ADD);
2382             }
2383         }
2384 
2385         assertReductionArraysEquals(r, ra, a,
2386                 DoubleMaxVectorTests::ADDReduce, DoubleMaxVectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
2387     }
2388 
2389     static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
2390         double res = 0;
2391         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2392             if (mask[i % SPECIES.length()])
2393                 res += a[i];
2394         }
2395 
2396         return res;
2397     }
2398 
2399     static double ADDReduceAllMasked(double[] a, boolean[] mask) {
2400         double res = 0;
2401         for (int i = 0; i < a.length; i += SPECIES.length()) {
2402             res += ADDReduceMasked(a, i, mask);
2403         }
2404 
2405         return res;
2406     }
2407 
2408     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2409     static void ADDReduceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2410         double[] a = fa.apply(SPECIES.length());
2411         double[] r = fr.apply(SPECIES.length());
2412         boolean[] mask = fm.apply(SPECIES.length());
2413         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2414         double ra = 0;
2415 
2416         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2417             for (int i = 0; i < a.length; i += SPECIES.length()) {
2418                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2419                 r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
2420             }
2421         }
2422 
2423         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2424             ra = 0;
2425             for (int i = 0; i < a.length; i += SPECIES.length()) {
2426                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2427                 ra += av.reduceLanes(VectorOperators.ADD, vmask);
2428             }
2429         }
2430 
2431         assertReductionArraysEqualsMasked(r, ra, a, mask,
2432                 DoubleMaxVectorTests::ADDReduceMasked, DoubleMaxVectorTests::ADDReduceAllMasked, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
2433     }
2434 
2435     static double MULReduce(double[] a, int idx) {
2436         double res = 1;
2437         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2438             res *= a[i];
2439         }
2440 
2441         return res;
2442     }
2443 
2444     static double MULReduceAll(double[] a) {
2445         double res = 1;
2446         for (int i = 0; i < a.length; i += SPECIES.length()) {
2447             res *= MULReduce(a, i);
2448         }
2449 
2450         return res;
2451     }
2452 
2453     @Test(dataProvider = "doubleUnaryOpProvider")
2454     static void MULReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
2455         double[] a = fa.apply(SPECIES.length());
2456         double[] r = fr.apply(SPECIES.length());
2457         double ra = 1;
2458 
2459         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2460             for (int i = 0; i < a.length; i += SPECIES.length()) {
2461                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2462                 r[i] = av.reduceLanes(VectorOperators.MUL);
2463             }
2464         }
2465 
2466         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2467             ra = 1;
2468             for (int i = 0; i < a.length; i += SPECIES.length()) {
2469                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2470                 ra *= av.reduceLanes(VectorOperators.MUL);
2471             }
2472         }
2473 
2474         assertReductionArraysEquals(r, ra, a,
2475                 DoubleMaxVectorTests::MULReduce, DoubleMaxVectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
2476     }
2477 
2478     static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
2479         double res = 1;
2480         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2481             if (mask[i % SPECIES.length()])
2482                 res *= a[i];
2483         }
2484 
2485         return res;
2486     }
2487 
2488     static double MULReduceAllMasked(double[] a, boolean[] mask) {
2489         double res = 1;
2490         for (int i = 0; i < a.length; i += SPECIES.length()) {
2491             res *= MULReduceMasked(a, i, mask);
2492         }
2493 
2494         return res;
2495     }
2496 
2497     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2498     static void MULReduceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2499         double[] a = fa.apply(SPECIES.length());
2500         double[] r = fr.apply(SPECIES.length());
2501         boolean[] mask = fm.apply(SPECIES.length());
2502         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2503         double ra = 1;
2504 
2505         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2506             for (int i = 0; i < a.length; i += SPECIES.length()) {
2507                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2508                 r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
2509             }
2510         }
2511 
2512         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2513             ra = 1;
2514             for (int i = 0; i < a.length; i += SPECIES.length()) {
2515                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2516                 ra *= av.reduceLanes(VectorOperators.MUL, vmask);
2517             }
2518         }
2519 
2520         assertReductionArraysEqualsMasked(r, ra, a, mask,
2521                 DoubleMaxVectorTests::MULReduceMasked, DoubleMaxVectorTests::MULReduceAllMasked, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
2522     }
2523 
2524     static double MINReduce(double[] a, int idx) {
2525         double res = Double.POSITIVE_INFINITY;
2526         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2527             res = (double) Math.min(res, a[i]);
2528         }
2529 
2530         return res;
2531     }
2532 
2533     static double MINReduceAll(double[] a) {
2534         double res = Double.POSITIVE_INFINITY;
2535         for (int i = 0; i < a.length; i += SPECIES.length()) {
2536             res = (double) Math.min(res, MINReduce(a, i));
2537         }
2538 
2539         return res;
2540     }
2541 
2542     @Test(dataProvider = "doubleUnaryOpProvider")
2543     static void MINReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
2544         double[] a = fa.apply(SPECIES.length());
2545         double[] r = fr.apply(SPECIES.length());
2546         double ra = Double.POSITIVE_INFINITY;
2547 
2548         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2549             for (int i = 0; i < a.length; i += SPECIES.length()) {
2550                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2551                 r[i] = av.reduceLanes(VectorOperators.MIN);
2552             }
2553         }
2554 
2555         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2556             ra = Double.POSITIVE_INFINITY;
2557             for (int i = 0; i < a.length; i += SPECIES.length()) {
2558                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2559                 ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
2560             }
2561         }
2562 
2563         assertReductionArraysEquals(r, ra, a,
2564                 DoubleMaxVectorTests::MINReduce, DoubleMaxVectorTests::MINReduceAll);
2565     }
2566 
2567     static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
2568         double res = Double.POSITIVE_INFINITY;
2569         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2570             if (mask[i % SPECIES.length()])
2571                 res = (double) Math.min(res, a[i]);
2572         }
2573 
2574         return res;
2575     }
2576 
2577     static double MINReduceAllMasked(double[] a, boolean[] mask) {
2578         double res = Double.POSITIVE_INFINITY;
2579         for (int i = 0; i < a.length; i += SPECIES.length()) {
2580             res = (double) Math.min(res, MINReduceMasked(a, i, mask));
2581         }
2582 
2583         return res;
2584     }
2585 
2586     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2587     static void MINReduceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2588         double[] a = fa.apply(SPECIES.length());
2589         double[] r = fr.apply(SPECIES.length());
2590         boolean[] mask = fm.apply(SPECIES.length());
2591         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2592         double ra = Double.POSITIVE_INFINITY;
2593 
2594         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2595             for (int i = 0; i < a.length; i += SPECIES.length()) {
2596                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2597                 r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
2598             }
2599         }
2600 
2601         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2602             ra = Double.POSITIVE_INFINITY;
2603             for (int i = 0; i < a.length; i += SPECIES.length()) {
2604                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2605                 ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
2606             }
2607         }
2608 
2609         assertReductionArraysEqualsMasked(r, ra, a, mask,
2610                 DoubleMaxVectorTests::MINReduceMasked, DoubleMaxVectorTests::MINReduceAllMasked);
2611     }
2612 
2613     static double MAXReduce(double[] a, int idx) {
2614         double res = Double.NEGATIVE_INFINITY;
2615         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2616             res = (double) Math.max(res, a[i]);
2617         }
2618 
2619         return res;
2620     }
2621 
2622     static double MAXReduceAll(double[] a) {
2623         double res = Double.NEGATIVE_INFINITY;
2624         for (int i = 0; i < a.length; i += SPECIES.length()) {
2625             res = (double) Math.max(res, MAXReduce(a, i));
2626         }
2627 
2628         return res;
2629     }
2630 
2631     @Test(dataProvider = "doubleUnaryOpProvider")
2632     static void MAXReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
2633         double[] a = fa.apply(SPECIES.length());
2634         double[] r = fr.apply(SPECIES.length());
2635         double ra = Double.NEGATIVE_INFINITY;
2636 
2637         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2638             for (int i = 0; i < a.length; i += SPECIES.length()) {
2639                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2640                 r[i] = av.reduceLanes(VectorOperators.MAX);
2641             }
2642         }
2643 
2644         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2645             ra = Double.NEGATIVE_INFINITY;
2646             for (int i = 0; i < a.length; i += SPECIES.length()) {
2647                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2648                 ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
2649             }
2650         }
2651 
2652         assertReductionArraysEquals(r, ra, a,
2653                 DoubleMaxVectorTests::MAXReduce, DoubleMaxVectorTests::MAXReduceAll);
2654     }
2655 
2656     static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
2657         double res = Double.NEGATIVE_INFINITY;
2658         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2659             if (mask[i % SPECIES.length()])
2660                 res = (double) Math.max(res, a[i]);
2661         }
2662 
2663         return res;
2664     }
2665 
2666     static double MAXReduceAllMasked(double[] a, boolean[] mask) {
2667         double res = Double.NEGATIVE_INFINITY;
2668         for (int i = 0; i < a.length; i += SPECIES.length()) {
2669             res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
2670         }
2671 
2672         return res;
2673     }
2674 
2675     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2676     static void MAXReduceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2677         double[] a = fa.apply(SPECIES.length());
2678         double[] r = fr.apply(SPECIES.length());
2679         boolean[] mask = fm.apply(SPECIES.length());
2680         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2681         double ra = Double.NEGATIVE_INFINITY;
2682 
2683         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2684             for (int i = 0; i < a.length; i += SPECIES.length()) {
2685                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2686                 r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
2687             }
2688         }
2689 
2690         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2691             ra = Double.NEGATIVE_INFINITY;
2692             for (int i = 0; i < a.length; i += SPECIES.length()) {
2693                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2694                 ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
2695             }
2696         }
2697 
2698         assertReductionArraysEqualsMasked(r, ra, a, mask,
2699                 DoubleMaxVectorTests::MAXReduceMasked, DoubleMaxVectorTests::MAXReduceAllMasked);
2700     }
2701 
2702     static double FIRST_NONZEROReduce(double[] a, int idx) {
2703         double res = (double) 0;
2704         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2705             res = firstNonZero(res, a[i]);
2706         }
2707 
2708         return res;
2709     }
2710 
2711     static double FIRST_NONZEROReduceAll(double[] a) {
2712         double res = (double) 0;
2713         for (int i = 0; i < a.length; i += SPECIES.length()) {
2714             res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
2715         }
2716 
2717         return res;
2718     }
2719 
2720     @Test(dataProvider = "doubleUnaryOpProvider")
2721     static void FIRST_NONZEROReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
2722         double[] a = fa.apply(SPECIES.length());
2723         double[] r = fr.apply(SPECIES.length());
2724         double ra = (double) 0;
2725 
2726         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2727             for (int i = 0; i < a.length; i += SPECIES.length()) {
2728                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2729                 r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
2730             }
2731         }
2732 
2733         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2734             ra = (double) 0;
2735             for (int i = 0; i < a.length; i += SPECIES.length()) {
2736                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2737                 ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
2738             }
2739         }
2740 
2741         assertReductionArraysEquals(r, ra, a,
2742                 DoubleMaxVectorTests::FIRST_NONZEROReduce, DoubleMaxVectorTests::FIRST_NONZEROReduceAll);
2743     }
2744 
2745     static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
2746         double res = (double) 0;
2747         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2748             if (mask[i % SPECIES.length()])
2749                 res = firstNonZero(res, a[i]);
2750         }
2751 
2752         return res;
2753     }
2754 
2755     static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
2756         double res = (double) 0;
2757         for (int i = 0; i < a.length; i += SPECIES.length()) {
2758             res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
2759         }
2760 
2761         return res;
2762     }
2763 
2764     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2765     static void FIRST_NONZEROReduceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2766         double[] a = fa.apply(SPECIES.length());
2767         double[] r = fr.apply(SPECIES.length());
2768         boolean[] mask = fm.apply(SPECIES.length());
2769         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2770         double ra = (double) 0;
2771 
2772         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2773             for (int i = 0; i < a.length; i += SPECIES.length()) {
2774                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2775                 r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
2776             }
2777         }
2778 
2779         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2780             ra = (double) 0;
2781             for (int i = 0; i < a.length; i += SPECIES.length()) {
2782                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2783                 ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
2784             }
2785         }
2786 
2787         assertReductionArraysEqualsMasked(r, ra, a, mask,
2788                 DoubleMaxVectorTests::FIRST_NONZEROReduceMasked, DoubleMaxVectorTests::FIRST_NONZEROReduceAllMasked);
2789     }
2790 
2791     @Test(dataProvider = "doubleBinaryOpProvider")
2792     static void withDoubleMaxVectorTests(IntFunction<double []> fa, IntFunction<double []> fb) {
2793         double[] a = fa.apply(SPECIES.length());
2794         double[] b = fb.apply(SPECIES.length());
2795         double[] r = fr.apply(SPECIES.length());
2796 
2797         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2798             for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) {
2799                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2800                 av.withLane(j, b[i + j]).intoArray(r, i);
2801                 a[i + j] = b[i + j];
2802                 j = (j + 1) & (SPECIES.length() - 1);
2803             }
2804         }
2805 
2806 
2807         assertArraysStrictlyEquals(r, a);
2808     }
2809 
2810     static boolean testIS_DEFAULT(double a) {
2811         return bits(a)==0;
2812     }
2813 
2814     @Test(dataProvider = "doubleTestOpProvider")
2815     static void IS_DEFAULTDoubleMaxVectorTests(IntFunction<double[]> fa) {
2816         double[] a = fa.apply(SPECIES.length());
2817 
2818         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2819             for (int i = 0; i < a.length; i += SPECIES.length()) {
2820                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2821                 VectorMask<Double> mv = av.test(VectorOperators.IS_DEFAULT);
2822 
2823                 // Check results as part of computation.
2824                 for (int j = 0; j < SPECIES.length(); j++) {
2825                     Assert.assertEquals(mv.laneIsSet(j), testIS_DEFAULT(a[i + j]));
2826                 }
2827             }
2828         }
2829     }
2830 
2831     @Test(dataProvider = "doubleTestOpMaskProvider")
2832     static void IS_DEFAULTMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
2833                                           IntFunction<boolean[]> fm) {
2834         double[] a = fa.apply(SPECIES.length());
2835         boolean[] mask = fm.apply(SPECIES.length());
2836         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2837 
2838         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2839             for (int i = 0; i < a.length; i += SPECIES.length()) {
2840                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2841                 VectorMask<Double> mv = av.test(VectorOperators.IS_DEFAULT, vmask);
2842 
2843                 // Check results as part of computation.
2844                 for (int j = 0; j < SPECIES.length(); j++) {
2845                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_DEFAULT(a[i + j]));
2846                 }
2847             }
2848         }
2849     }
2850 
2851     static boolean testIS_NEGATIVE(double a) {
2852         return bits(a)<0;
2853     }
2854 
2855     @Test(dataProvider = "doubleTestOpProvider")
2856     static void IS_NEGATIVEDoubleMaxVectorTests(IntFunction<double[]> fa) {
2857         double[] a = fa.apply(SPECIES.length());
2858 
2859         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2860             for (int i = 0; i < a.length; i += SPECIES.length()) {
2861                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2862                 VectorMask<Double> mv = av.test(VectorOperators.IS_NEGATIVE);
2863 
2864                 // Check results as part of computation.
2865                 for (int j = 0; j < SPECIES.length(); j++) {
2866                     Assert.assertEquals(mv.laneIsSet(j), testIS_NEGATIVE(a[i + j]));
2867                 }
2868             }
2869         }
2870     }
2871 
2872     @Test(dataProvider = "doubleTestOpMaskProvider")
2873     static void IS_NEGATIVEMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
2874                                           IntFunction<boolean[]> fm) {
2875         double[] a = fa.apply(SPECIES.length());
2876         boolean[] mask = fm.apply(SPECIES.length());
2877         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2878 
2879         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2880             for (int i = 0; i < a.length; i += SPECIES.length()) {
2881                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2882                 VectorMask<Double> mv = av.test(VectorOperators.IS_NEGATIVE, vmask);
2883 
2884                 // Check results as part of computation.
2885                 for (int j = 0; j < SPECIES.length(); j++) {
2886                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_NEGATIVE(a[i + j]));
2887                 }
2888             }
2889         }
2890     }
2891 
2892     static boolean testIS_FINITE(double a) {
2893         return Double.isFinite(a);
2894     }
2895 
2896     @Test(dataProvider = "doubleTestOpProvider")
2897     static void IS_FINITEDoubleMaxVectorTests(IntFunction<double[]> fa) {
2898         double[] a = fa.apply(SPECIES.length());
2899 
2900         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2901             for (int i = 0; i < a.length; i += SPECIES.length()) {
2902                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2903                 VectorMask<Double> mv = av.test(VectorOperators.IS_FINITE);
2904 
2905                 // Check results as part of computation.
2906                 for (int j = 0; j < SPECIES.length(); j++) {
2907                     Assert.assertEquals(mv.laneIsSet(j), testIS_FINITE(a[i + j]));
2908                 }
2909             }
2910         }
2911     }
2912 
2913     @Test(dataProvider = "doubleTestOpMaskProvider")
2914     static void IS_FINITEMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
2915                                           IntFunction<boolean[]> fm) {
2916         double[] a = fa.apply(SPECIES.length());
2917         boolean[] mask = fm.apply(SPECIES.length());
2918         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2919 
2920         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2921             for (int i = 0; i < a.length; i += SPECIES.length()) {
2922                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2923                 VectorMask<Double> mv = av.test(VectorOperators.IS_FINITE, vmask);
2924 
2925                 // Check results as part of computation.
2926                 for (int j = 0; j < SPECIES.length(); j++) {
2927                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_FINITE(a[i + j]));
2928                 }
2929             }
2930         }
2931     }
2932 
2933     static boolean testIS_NAN(double a) {
2934         return Double.isNaN(a);
2935     }
2936 
2937     @Test(dataProvider = "doubleTestOpProvider")
2938     static void IS_NANDoubleMaxVectorTests(IntFunction<double[]> fa) {
2939         double[] a = fa.apply(SPECIES.length());
2940 
2941         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2942             for (int i = 0; i < a.length; i += SPECIES.length()) {
2943                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2944                 VectorMask<Double> mv = av.test(VectorOperators.IS_NAN);
2945 
2946                 // Check results as part of computation.
2947                 for (int j = 0; j < SPECIES.length(); j++) {
2948                     Assert.assertEquals(mv.laneIsSet(j), testIS_NAN(a[i + j]));
2949                 }
2950             }
2951         }
2952     }
2953 
2954     @Test(dataProvider = "doubleTestOpMaskProvider")
2955     static void IS_NANMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
2956                                           IntFunction<boolean[]> fm) {
2957         double[] a = fa.apply(SPECIES.length());
2958         boolean[] mask = fm.apply(SPECIES.length());
2959         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2960 
2961         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2962             for (int i = 0; i < a.length; i += SPECIES.length()) {
2963                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2964                 VectorMask<Double> mv = av.test(VectorOperators.IS_NAN, vmask);
2965 
2966                 // Check results as part of computation.
2967                 for (int j = 0; j < SPECIES.length(); j++) {
2968                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_NAN(a[i + j]));
2969                 }
2970             }
2971         }
2972     }
2973 
2974     static boolean testIS_INFINITE(double a) {
2975         return Double.isInfinite(a);
2976     }
2977 
2978     @Test(dataProvider = "doubleTestOpProvider")
2979     static void IS_INFINITEDoubleMaxVectorTests(IntFunction<double[]> fa) {
2980         double[] a = fa.apply(SPECIES.length());
2981 
2982         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2983             for (int i = 0; i < a.length; i += SPECIES.length()) {
2984                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2985                 VectorMask<Double> mv = av.test(VectorOperators.IS_INFINITE);
2986 
2987                 // Check results as part of computation.
2988                 for (int j = 0; j < SPECIES.length(); j++) {
2989                     Assert.assertEquals(mv.laneIsSet(j), testIS_INFINITE(a[i + j]));
2990                 }
2991             }
2992         }
2993     }
2994 
2995     @Test(dataProvider = "doubleTestOpMaskProvider")
2996     static void IS_INFINITEMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
2997                                           IntFunction<boolean[]> fm) {
2998         double[] a = fa.apply(SPECIES.length());
2999         boolean[] mask = fm.apply(SPECIES.length());
3000         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3001 
3002         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3003             for (int i = 0; i < a.length; i += SPECIES.length()) {
3004                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3005                 VectorMask<Double> mv = av.test(VectorOperators.IS_INFINITE, vmask);
3006 
3007                 // Check results as part of computation.
3008                 for (int j = 0; j < SPECIES.length(); j++) {
3009                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_INFINITE(a[i + j]));
3010                 }
3011             }
3012         }
3013     }
3014 
3015     @Test(dataProvider = "doubleCompareOpProvider")
3016     static void LTDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3017         double[] a = fa.apply(SPECIES.length());
3018         double[] b = fb.apply(SPECIES.length());
3019 
3020         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3021             for (int i = 0; i < a.length; i += SPECIES.length()) {
3022                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3023                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3024                 VectorMask<Double> mv = av.compare(VectorOperators.LT, bv);
3025 
3026                 // Check results as part of computation.
3027                 for (int j = 0; j < SPECIES.length(); j++) {
3028                     Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j]));
3029                 }
3030             }
3031         }
3032     }
3033 
3034     @Test(dataProvider = "doubleCompareOpProvider")
3035     static void ltDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3036         double[] a = fa.apply(SPECIES.length());
3037         double[] b = fb.apply(SPECIES.length());
3038 
3039         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3040             for (int i = 0; i < a.length; i += SPECIES.length()) {
3041                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3042                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3043                 VectorMask<Double> mv = av.lt(bv);
3044 
3045                 // Check results as part of computation.
3046                 for (int j = 0; j < SPECIES.length(); j++) {
3047                     Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j]));
3048                 }
3049             }
3050         }
3051     }
3052 
3053     @Test(dataProvider = "doubleCompareOpMaskProvider")
3054     static void LTDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3055                                                 IntFunction<boolean[]> fm) {
3056         double[] a = fa.apply(SPECIES.length());
3057         double[] b = fb.apply(SPECIES.length());
3058         boolean[] mask = fm.apply(SPECIES.length());
3059 
3060         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3061 
3062         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3063             for (int i = 0; i < a.length; i += SPECIES.length()) {
3064                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3065                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3066                 VectorMask<Double> mv = av.compare(VectorOperators.LT, bv, vmask);
3067 
3068                 // Check results as part of computation.
3069                 for (int j = 0; j < SPECIES.length(); j++) {
3070                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j]));
3071                 }
3072             }
3073         }
3074     }
3075 
3076     @Test(dataProvider = "doubleCompareOpProvider")
3077     static void GTDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3078         double[] a = fa.apply(SPECIES.length());
3079         double[] b = fb.apply(SPECIES.length());
3080 
3081         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3082             for (int i = 0; i < a.length; i += SPECIES.length()) {
3083                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3084                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3085                 VectorMask<Double> mv = av.compare(VectorOperators.GT, bv);
3086 
3087                 // Check results as part of computation.
3088                 for (int j = 0; j < SPECIES.length(); j++) {
3089                     Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j]));
3090                 }
3091             }
3092         }
3093     }
3094 
3095     @Test(dataProvider = "doubleCompareOpMaskProvider")
3096     static void GTDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3097                                                 IntFunction<boolean[]> fm) {
3098         double[] a = fa.apply(SPECIES.length());
3099         double[] b = fb.apply(SPECIES.length());
3100         boolean[] mask = fm.apply(SPECIES.length());
3101 
3102         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3103 
3104         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3105             for (int i = 0; i < a.length; i += SPECIES.length()) {
3106                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3107                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3108                 VectorMask<Double> mv = av.compare(VectorOperators.GT, bv, vmask);
3109 
3110                 // Check results as part of computation.
3111                 for (int j = 0; j < SPECIES.length(); j++) {
3112                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j]));
3113                 }
3114             }
3115         }
3116     }
3117 
3118     @Test(dataProvider = "doubleCompareOpProvider")
3119     static void EQDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3120         double[] a = fa.apply(SPECIES.length());
3121         double[] b = fb.apply(SPECIES.length());
3122 
3123         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3124             for (int i = 0; i < a.length; i += SPECIES.length()) {
3125                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3126                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3127                 VectorMask<Double> mv = av.compare(VectorOperators.EQ, bv);
3128 
3129                 // Check results as part of computation.
3130                 for (int j = 0; j < SPECIES.length(); j++) {
3131                     Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j]));
3132                 }
3133             }
3134         }
3135     }
3136 
3137     @Test(dataProvider = "doubleCompareOpProvider")
3138     static void eqDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3139         double[] a = fa.apply(SPECIES.length());
3140         double[] b = fb.apply(SPECIES.length());
3141 
3142         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3143             for (int i = 0; i < a.length; i += SPECIES.length()) {
3144                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3145                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3146                 VectorMask<Double> mv = av.eq(bv);
3147 
3148                 // Check results as part of computation.
3149                 for (int j = 0; j < SPECIES.length(); j++) {
3150                     Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j]));
3151                 }
3152             }
3153         }
3154     }
3155 
3156     @Test(dataProvider = "doubleCompareOpMaskProvider")
3157     static void EQDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3158                                                 IntFunction<boolean[]> fm) {
3159         double[] a = fa.apply(SPECIES.length());
3160         double[] b = fb.apply(SPECIES.length());
3161         boolean[] mask = fm.apply(SPECIES.length());
3162 
3163         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3164 
3165         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3166             for (int i = 0; i < a.length; i += SPECIES.length()) {
3167                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3168                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3169                 VectorMask<Double> mv = av.compare(VectorOperators.EQ, bv, vmask);
3170 
3171                 // Check results as part of computation.
3172                 for (int j = 0; j < SPECIES.length(); j++) {
3173                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j]));
3174                 }
3175             }
3176         }
3177     }
3178 
3179     @Test(dataProvider = "doubleCompareOpProvider")
3180     static void NEDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3181         double[] a = fa.apply(SPECIES.length());
3182         double[] b = fb.apply(SPECIES.length());
3183 
3184         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3185             for (int i = 0; i < a.length; i += SPECIES.length()) {
3186                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3187                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3188                 VectorMask<Double> mv = av.compare(VectorOperators.NE, bv);
3189 
3190                 // Check results as part of computation.
3191                 for (int j = 0; j < SPECIES.length(); j++) {
3192                     Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j]));
3193                 }
3194             }
3195         }
3196     }
3197 
3198     @Test(dataProvider = "doubleCompareOpMaskProvider")
3199     static void NEDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3200                                                 IntFunction<boolean[]> fm) {
3201         double[] a = fa.apply(SPECIES.length());
3202         double[] b = fb.apply(SPECIES.length());
3203         boolean[] mask = fm.apply(SPECIES.length());
3204 
3205         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3206 
3207         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3208             for (int i = 0; i < a.length; i += SPECIES.length()) {
3209                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3210                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3211                 VectorMask<Double> mv = av.compare(VectorOperators.NE, bv, vmask);
3212 
3213                 // Check results as part of computation.
3214                 for (int j = 0; j < SPECIES.length(); j++) {
3215                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j]));
3216                 }
3217             }
3218         }
3219     }
3220 
3221     @Test(dataProvider = "doubleCompareOpProvider")
3222     static void LEDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3223         double[] a = fa.apply(SPECIES.length());
3224         double[] b = fb.apply(SPECIES.length());
3225 
3226         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3227             for (int i = 0; i < a.length; i += SPECIES.length()) {
3228                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3229                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3230                 VectorMask<Double> mv = av.compare(VectorOperators.LE, bv);
3231 
3232                 // Check results as part of computation.
3233                 for (int j = 0; j < SPECIES.length(); j++) {
3234                     Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j]));
3235                 }
3236             }
3237         }
3238     }
3239 
3240     @Test(dataProvider = "doubleCompareOpMaskProvider")
3241     static void LEDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3242                                                 IntFunction<boolean[]> fm) {
3243         double[] a = fa.apply(SPECIES.length());
3244         double[] b = fb.apply(SPECIES.length());
3245         boolean[] mask = fm.apply(SPECIES.length());
3246 
3247         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3248 
3249         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3250             for (int i = 0; i < a.length; i += SPECIES.length()) {
3251                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3252                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3253                 VectorMask<Double> mv = av.compare(VectorOperators.LE, bv, vmask);
3254 
3255                 // Check results as part of computation.
3256                 for (int j = 0; j < SPECIES.length(); j++) {
3257                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j]));
3258                 }
3259             }
3260         }
3261     }
3262 
3263     @Test(dataProvider = "doubleCompareOpProvider")
3264     static void GEDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3265         double[] a = fa.apply(SPECIES.length());
3266         double[] b = fb.apply(SPECIES.length());
3267 
3268         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3269             for (int i = 0; i < a.length; i += SPECIES.length()) {
3270                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3271                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3272                 VectorMask<Double> mv = av.compare(VectorOperators.GE, bv);
3273 
3274                 // Check results as part of computation.
3275                 for (int j = 0; j < SPECIES.length(); j++) {
3276                     Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j]));
3277                 }
3278             }
3279         }
3280     }
3281 
3282     @Test(dataProvider = "doubleCompareOpMaskProvider")
3283     static void GEDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3284                                                 IntFunction<boolean[]> fm) {
3285         double[] a = fa.apply(SPECIES.length());
3286         double[] b = fb.apply(SPECIES.length());
3287         boolean[] mask = fm.apply(SPECIES.length());
3288 
3289         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3290 
3291         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3292             for (int i = 0; i < a.length; i += SPECIES.length()) {
3293                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3294                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3295                 VectorMask<Double> mv = av.compare(VectorOperators.GE, bv, vmask);
3296 
3297                 // Check results as part of computation.
3298                 for (int j = 0; j < SPECIES.length(); j++) {
3299                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j]));
3300                 }
3301             }
3302         }
3303     }
3304 
3305     @Test(dataProvider = "doubleCompareOpProvider")
3306     static void LTDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3307         double[] a = fa.apply(SPECIES.length());
3308         double[] b = fb.apply(SPECIES.length());
3309 
3310         for (int i = 0; i < a.length; i += SPECIES.length()) {
3311             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3312             VectorMask<Double> mv = av.compare(VectorOperators.LT, b[i]);
3313 
3314             // Check results as part of computation.
3315             for (int j = 0; j < SPECIES.length(); j++) {
3316                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i]);
3317             }
3318         }
3319     }
3320 
3321     @Test(dataProvider = "doubleCompareOpMaskProvider")
3322     static void LTDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa,
3323                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3324         double[] a = fa.apply(SPECIES.length());
3325         double[] b = fb.apply(SPECIES.length());
3326         boolean[] mask = fm.apply(SPECIES.length());
3327 
3328         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3329 
3330         for (int i = 0; i < a.length; i += SPECIES.length()) {
3331             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3332             VectorMask<Double> mv = av.compare(VectorOperators.LT, b[i], vmask);
3333 
3334             // Check results as part of computation.
3335             for (int j = 0; j < SPECIES.length(); j++) {
3336                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i]));
3337             }
3338         }
3339     }
3340 
3341     @Test(dataProvider = "doubleCompareOpProvider")
3342     static void LTDoubleMaxVectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3343         double[] a = fa.apply(SPECIES.length());
3344         double[] b = fb.apply(SPECIES.length());
3345 
3346         for (int i = 0; i < a.length; i += SPECIES.length()) {
3347             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3348             VectorMask<Double> mv = av.compare(VectorOperators.LT, (long)b[i]);
3349 
3350             // Check results as part of computation.
3351             for (int j = 0; j < SPECIES.length(); j++) {
3352                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < (double)((long)b[i]));
3353             }
3354         }
3355     }
3356 
3357     @Test(dataProvider = "doubleCompareOpMaskProvider")
3358     static void LTDoubleMaxVectorTestsBroadcastLongMaskedSmokeTest(IntFunction<double[]> fa,
3359                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3360         double[] a = fa.apply(SPECIES.length());
3361         double[] b = fb.apply(SPECIES.length());
3362         boolean[] mask = fm.apply(SPECIES.length());
3363 
3364         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3365 
3366         for (int i = 0; i < a.length; i += SPECIES.length()) {
3367             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3368             VectorMask<Double> mv = av.compare(VectorOperators.LT, (long)b[i], vmask);
3369 
3370             // Check results as part of computation.
3371             for (int j = 0; j < SPECIES.length(); j++) {
3372                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < (double)((long)b[i])));
3373             }
3374         }
3375     }
3376 
3377     @Test(dataProvider = "doubleCompareOpProvider")
3378     static void EQDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3379         double[] a = fa.apply(SPECIES.length());
3380         double[] b = fb.apply(SPECIES.length());
3381 
3382         for (int i = 0; i < a.length; i += SPECIES.length()) {
3383             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3384             VectorMask<Double> mv = av.compare(VectorOperators.EQ, b[i]);
3385 
3386             // Check results as part of computation.
3387             for (int j = 0; j < SPECIES.length(); j++) {
3388                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i]);
3389             }
3390         }
3391     }
3392 
3393     @Test(dataProvider = "doubleCompareOpMaskProvider")
3394     static void EQDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa,
3395                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3396         double[] a = fa.apply(SPECIES.length());
3397         double[] b = fb.apply(SPECIES.length());
3398         boolean[] mask = fm.apply(SPECIES.length());
3399 
3400         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3401 
3402         for (int i = 0; i < a.length; i += SPECIES.length()) {
3403             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3404             VectorMask<Double> mv = av.compare(VectorOperators.EQ, b[i], vmask);
3405 
3406             // Check results as part of computation.
3407             for (int j = 0; j < SPECIES.length(); j++) {
3408                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i]));
3409             }
3410         }
3411     }
3412 
3413     @Test(dataProvider = "doubleCompareOpProvider")
3414     static void EQDoubleMaxVectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3415         double[] a = fa.apply(SPECIES.length());
3416         double[] b = fb.apply(SPECIES.length());
3417 
3418         for (int i = 0; i < a.length; i += SPECIES.length()) {
3419             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3420             VectorMask<Double> mv = av.compare(VectorOperators.EQ, (long)b[i]);
3421 
3422             // Check results as part of computation.
3423             for (int j = 0; j < SPECIES.length(); j++) {
3424                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == (double)((long)b[i]));
3425             }
3426         }
3427     }
3428 
3429     @Test(dataProvider = "doubleCompareOpMaskProvider")
3430     static void EQDoubleMaxVectorTestsBroadcastLongMaskedSmokeTest(IntFunction<double[]> fa,
3431                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3432         double[] a = fa.apply(SPECIES.length());
3433         double[] b = fb.apply(SPECIES.length());
3434         boolean[] mask = fm.apply(SPECIES.length());
3435 
3436         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3437 
3438         for (int i = 0; i < a.length; i += SPECIES.length()) {
3439             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3440             VectorMask<Double> mv = av.compare(VectorOperators.EQ, (long)b[i], vmask);
3441 
3442             // Check results as part of computation.
3443             for (int j = 0; j < SPECIES.length(); j++) {
3444                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == (double)((long)b[i])));
3445             }
3446         }
3447     }
3448 
3449     static double blend(double a, double b, boolean mask) {
3450         return mask ? b : a;
3451     }
3452 
3453     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3454     static void blendDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
3455                                           IntFunction<boolean[]> fm) {
3456         double[] a = fa.apply(SPECIES.length());
3457         double[] b = fb.apply(SPECIES.length());
3458         double[] r = fr.apply(SPECIES.length());
3459         boolean[] mask = fm.apply(SPECIES.length());
3460         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3461 
3462         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3463             for (int i = 0; i < a.length; i += SPECIES.length()) {
3464                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3465                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3466                 av.blend(bv, vmask).intoArray(r, i);
3467             }
3468         }
3469 
3470         assertArraysEquals(r, a, b, mask, DoubleMaxVectorTests::blend);
3471     }
3472 
3473     @Test(dataProvider = "doubleUnaryOpShuffleProvider")
3474     static void RearrangeDoubleMaxVectorTests(IntFunction<double[]> fa,
3475                                            BiFunction<Integer,Integer,int[]> fs) {
3476         double[] a = fa.apply(SPECIES.length());
3477         int[] order = fs.apply(a.length, SPECIES.length());
3478         double[] r = fr.apply(SPECIES.length());
3479 
3480         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3481             for (int i = 0; i < a.length; i += SPECIES.length()) {
3482                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3483                 av.rearrange(VectorShuffle.fromArray(SPECIES, order, i)).intoArray(r, i);
3484             }
3485         }
3486 
3487         assertRearrangeArraysEquals(r, a, order, SPECIES.length());
3488     }
3489 
3490     @Test(dataProvider = "doubleUnaryOpShuffleMaskProvider")
3491     static void RearrangeDoubleMaxVectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
3492                                                           BiFunction<Integer,Integer,int[]> fs,
3493                                                           IntFunction<boolean[]> fm) {
3494         double[] a = fa.apply(SPECIES.length());
3495         int[] order = fs.apply(a.length, SPECIES.length());
3496         double[] r = fr.apply(SPECIES.length());
3497         boolean[] mask = fm.apply(SPECIES.length());
3498         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3499 
3500         for (int i = 0; i < a.length; i += SPECIES.length()) {
3501             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3502             av.rearrange(VectorShuffle.fromArray(SPECIES, order, i), vmask).intoArray(r, i);
3503         }
3504 
3505         assertRearrangeArraysEquals(r, a, order, mask, SPECIES.length());
3506     }
3507 
3508     @Test(dataProvider = "doubleUnaryOpMaskProvider")
3509     static void compressDoubleMaxVectorTests(IntFunction<double[]> fa,
3510                                                 IntFunction<boolean[]> fm) {
3511         double[] a = fa.apply(SPECIES.length());
3512         double[] r = fr.apply(SPECIES.length());
3513         boolean[] mask = fm.apply(SPECIES.length());
3514         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3515 
3516         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3517             for (int i = 0; i < a.length; i += SPECIES.length()) {
3518                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3519                 av.compress(vmask).intoArray(r, i);
3520             }
3521         }
3522 
3523         assertcompressArraysEquals(r, a, mask, SPECIES.length());
3524     }
3525 
3526     @Test(dataProvider = "doubleUnaryOpMaskProvider")
3527     static void expandDoubleMaxVectorTests(IntFunction<double[]> fa,
3528                                                 IntFunction<boolean[]> fm) {
3529         double[] a = fa.apply(SPECIES.length());
3530         double[] r = fr.apply(SPECIES.length());
3531         boolean[] mask = fm.apply(SPECIES.length());
3532         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3533 
3534         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3535             for (int i = 0; i < a.length; i += SPECIES.length()) {
3536                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3537                 av.expand(vmask).intoArray(r, i);
3538             }
3539         }
3540 
3541         assertexpandArraysEquals(r, a, mask, SPECIES.length());
3542     }
3543 
3544     @Test(dataProvider = "doubleUnaryOpProvider")
3545     static void getDoubleMaxVectorTests(IntFunction<double[]> fa) {
3546         double[] a = fa.apply(SPECIES.length());
3547         double[] r = fr.apply(SPECIES.length());
3548 
3549         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3550             for (int i = 0; i < a.length; i += SPECIES.length()) {
3551                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3552                 int num_lanes = SPECIES.length();
3553                 // Manually unroll because full unroll happens after intrinsification.
3554                 // Unroll is needed because get intrinsic requires for index to be a known constant.
3555                 if (num_lanes == 1) {
3556                     r[i]=av.lane(0);
3557                 } else if (num_lanes == 2) {
3558                     r[i]=av.lane(0);
3559                     r[i+1]=av.lane(1);
3560                 } else if (num_lanes == 4) {
3561                     r[i]=av.lane(0);
3562                     r[i+1]=av.lane(1);
3563                     r[i+2]=av.lane(2);
3564                     r[i+3]=av.lane(3);
3565                 } else if (num_lanes == 8) {
3566                     r[i]=av.lane(0);
3567                     r[i+1]=av.lane(1);
3568                     r[i+2]=av.lane(2);
3569                     r[i+3]=av.lane(3);
3570                     r[i+4]=av.lane(4);
3571                     r[i+5]=av.lane(5);
3572                     r[i+6]=av.lane(6);
3573                     r[i+7]=av.lane(7);
3574                 } else if (num_lanes == 16) {
3575                     r[i]=av.lane(0);
3576                     r[i+1]=av.lane(1);
3577                     r[i+2]=av.lane(2);
3578                     r[i+3]=av.lane(3);
3579                     r[i+4]=av.lane(4);
3580                     r[i+5]=av.lane(5);
3581                     r[i+6]=av.lane(6);
3582                     r[i+7]=av.lane(7);
3583                     r[i+8]=av.lane(8);
3584                     r[i+9]=av.lane(9);
3585                     r[i+10]=av.lane(10);
3586                     r[i+11]=av.lane(11);
3587                     r[i+12]=av.lane(12);
3588                     r[i+13]=av.lane(13);
3589                     r[i+14]=av.lane(14);
3590                     r[i+15]=av.lane(15);
3591                 } else if (num_lanes == 32) {
3592                     r[i]=av.lane(0);
3593                     r[i+1]=av.lane(1);
3594                     r[i+2]=av.lane(2);
3595                     r[i+3]=av.lane(3);
3596                     r[i+4]=av.lane(4);
3597                     r[i+5]=av.lane(5);
3598                     r[i+6]=av.lane(6);
3599                     r[i+7]=av.lane(7);
3600                     r[i+8]=av.lane(8);
3601                     r[i+9]=av.lane(9);
3602                     r[i+10]=av.lane(10);
3603                     r[i+11]=av.lane(11);
3604                     r[i+12]=av.lane(12);
3605                     r[i+13]=av.lane(13);
3606                     r[i+14]=av.lane(14);
3607                     r[i+15]=av.lane(15);
3608                     r[i+16]=av.lane(16);
3609                     r[i+17]=av.lane(17);
3610                     r[i+18]=av.lane(18);
3611                     r[i+19]=av.lane(19);
3612                     r[i+20]=av.lane(20);
3613                     r[i+21]=av.lane(21);
3614                     r[i+22]=av.lane(22);
3615                     r[i+23]=av.lane(23);
3616                     r[i+24]=av.lane(24);
3617                     r[i+25]=av.lane(25);
3618                     r[i+26]=av.lane(26);
3619                     r[i+27]=av.lane(27);
3620                     r[i+28]=av.lane(28);
3621                     r[i+29]=av.lane(29);
3622                     r[i+30]=av.lane(30);
3623                     r[i+31]=av.lane(31);
3624                 } else if (num_lanes == 64) {
3625                     r[i]=av.lane(0);
3626                     r[i+1]=av.lane(1);
3627                     r[i+2]=av.lane(2);
3628                     r[i+3]=av.lane(3);
3629                     r[i+4]=av.lane(4);
3630                     r[i+5]=av.lane(5);
3631                     r[i+6]=av.lane(6);
3632                     r[i+7]=av.lane(7);
3633                     r[i+8]=av.lane(8);
3634                     r[i+9]=av.lane(9);
3635                     r[i+10]=av.lane(10);
3636                     r[i+11]=av.lane(11);
3637                     r[i+12]=av.lane(12);
3638                     r[i+13]=av.lane(13);
3639                     r[i+14]=av.lane(14);
3640                     r[i+15]=av.lane(15);
3641                     r[i+16]=av.lane(16);
3642                     r[i+17]=av.lane(17);
3643                     r[i+18]=av.lane(18);
3644                     r[i+19]=av.lane(19);
3645                     r[i+20]=av.lane(20);
3646                     r[i+21]=av.lane(21);
3647                     r[i+22]=av.lane(22);
3648                     r[i+23]=av.lane(23);
3649                     r[i+24]=av.lane(24);
3650                     r[i+25]=av.lane(25);
3651                     r[i+26]=av.lane(26);
3652                     r[i+27]=av.lane(27);
3653                     r[i+28]=av.lane(28);
3654                     r[i+29]=av.lane(29);
3655                     r[i+30]=av.lane(30);
3656                     r[i+31]=av.lane(31);
3657                     r[i+32]=av.lane(32);
3658                     r[i+33]=av.lane(33);
3659                     r[i+34]=av.lane(34);
3660                     r[i+35]=av.lane(35);
3661                     r[i+36]=av.lane(36);
3662                     r[i+37]=av.lane(37);
3663                     r[i+38]=av.lane(38);
3664                     r[i+39]=av.lane(39);
3665                     r[i+40]=av.lane(40);
3666                     r[i+41]=av.lane(41);
3667                     r[i+42]=av.lane(42);
3668                     r[i+43]=av.lane(43);
3669                     r[i+44]=av.lane(44);
3670                     r[i+45]=av.lane(45);
3671                     r[i+46]=av.lane(46);
3672                     r[i+47]=av.lane(47);
3673                     r[i+48]=av.lane(48);
3674                     r[i+49]=av.lane(49);
3675                     r[i+50]=av.lane(50);
3676                     r[i+51]=av.lane(51);
3677                     r[i+52]=av.lane(52);
3678                     r[i+53]=av.lane(53);
3679                     r[i+54]=av.lane(54);
3680                     r[i+55]=av.lane(55);
3681                     r[i+56]=av.lane(56);
3682                     r[i+57]=av.lane(57);
3683                     r[i+58]=av.lane(58);
3684                     r[i+59]=av.lane(59);
3685                     r[i+60]=av.lane(60);
3686                     r[i+61]=av.lane(61);
3687                     r[i+62]=av.lane(62);
3688                     r[i+63]=av.lane(63);
3689                 } else {
3690                     for (int j = 0; j < SPECIES.length(); j++) {
3691                         r[i+j]=av.lane(j);
3692                     }
3693                 }
3694             }
3695         }
3696 
3697         assertArraysStrictlyEquals(r, a);
3698     }
3699 
3700     @Test(dataProvider = "doubleUnaryOpProvider")
3701     static void BroadcastDoubleMaxVectorTests(IntFunction<double[]> fa) {
3702         double[] a = fa.apply(SPECIES.length());
3703         double[] r = new double[a.length];
3704 
3705         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3706             for (int i = 0; i < a.length; i += SPECIES.length()) {
3707                 DoubleVector.broadcast(SPECIES, a[i]).intoArray(r, i);
3708             }
3709         }
3710 
3711         assertBroadcastArraysEquals(r, a);
3712     }
3713 
3714     @Test(dataProvider = "doubleUnaryOpProvider")
3715     static void ZeroDoubleMaxVectorTests(IntFunction<double[]> fa) {
3716         double[] a = fa.apply(SPECIES.length());
3717         double[] r = new double[a.length];
3718 
3719         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3720             for (int i = 0; i < a.length; i += SPECIES.length()) {
3721                 DoubleVector.zero(SPECIES).intoArray(a, i);
3722             }
3723         }
3724 
3725         Assert.assertEquals(a, r);
3726     }
3727 
3728     static double[] sliceUnary(double[] a, int origin, int idx) {
3729         double[] res = new double[SPECIES.length()];
3730         for (int i = 0; i < SPECIES.length(); i++){
3731             if(i+origin < SPECIES.length())
3732                 res[i] = a[idx+i+origin];
3733             else
3734                 res[i] = (double)0;
3735         }
3736         return res;
3737     }
3738 
3739     @Test(dataProvider = "doubleUnaryOpProvider")
3740     static void sliceUnaryDoubleMaxVectorTests(IntFunction<double[]> fa) {
3741         double[] a = fa.apply(SPECIES.length());
3742         double[] r = new double[a.length];
3743         int origin = RAND.nextInt(SPECIES.length());
3744         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3745             for (int i = 0; i < a.length; i += SPECIES.length()) {
3746                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3747                 av.slice(origin).intoArray(r, i);
3748             }
3749         }
3750 
3751         assertArraysEquals(r, a, origin, DoubleMaxVectorTests::sliceUnary);
3752     }
3753 
3754     static double[] sliceBinary(double[] a, double[] b, int origin, int idx) {
3755         double[] res = new double[SPECIES.length()];
3756         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3757             if(i+origin < SPECIES.length())
3758                 res[i] = a[idx+i+origin];
3759             else {
3760                 res[i] = b[idx+j];
3761                 j++;
3762             }
3763         }
3764         return res;
3765     }
3766 
3767     @Test(dataProvider = "doubleBinaryOpProvider")
3768     static void sliceBinaryDoubleMaxVectorTestsBinary(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3769         double[] a = fa.apply(SPECIES.length());
3770         double[] b = fb.apply(SPECIES.length());
3771         double[] r = new double[a.length];
3772         int origin = RAND.nextInt(SPECIES.length());
3773         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3774             for (int i = 0; i < a.length; i += SPECIES.length()) {
3775                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3776                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3777                 av.slice(origin, bv).intoArray(r, i);
3778             }
3779         }
3780 
3781         assertArraysEquals(r, a, b, origin, DoubleMaxVectorTests::sliceBinary);
3782     }
3783 
3784     static double[] slice(double[] a, double[] b, int origin, boolean[] mask, int idx) {
3785         double[] res = new double[SPECIES.length()];
3786         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3787             if(i+origin < SPECIES.length())
3788                 res[i] = mask[i] ? a[idx+i+origin] : (double)0;
3789             else {
3790                 res[i] = mask[i] ? b[idx+j] : (double)0;
3791                 j++;
3792             }
3793         }
3794         return res;
3795     }
3796 
3797     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3798     static void sliceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3799     IntFunction<boolean[]> fm) {
3800         double[] a = fa.apply(SPECIES.length());
3801         double[] b = fb.apply(SPECIES.length());
3802         boolean[] mask = fm.apply(SPECIES.length());
3803         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3804 
3805         double[] r = new double[a.length];
3806         int origin = RAND.nextInt(SPECIES.length());
3807         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3808             for (int i = 0; i < a.length; i += SPECIES.length()) {
3809                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3810                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3811                 av.slice(origin, bv, vmask).intoArray(r, i);
3812             }
3813         }
3814 
3815         assertArraysEquals(r, a, b, origin, mask, DoubleMaxVectorTests::slice);
3816     }
3817 
3818     static double[] unsliceUnary(double[] a, int origin, int idx) {
3819         double[] res = new double[SPECIES.length()];
3820         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3821             if(i < origin)
3822                 res[i] = (double)0;
3823             else {
3824                 res[i] = a[idx+j];
3825                 j++;
3826             }
3827         }
3828         return res;
3829     }
3830 
3831     @Test(dataProvider = "doubleUnaryOpProvider")
3832     static void unsliceUnaryDoubleMaxVectorTests(IntFunction<double[]> fa) {
3833         double[] a = fa.apply(SPECIES.length());
3834         double[] r = new double[a.length];
3835         int origin = RAND.nextInt(SPECIES.length());
3836         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3837             for (int i = 0; i < a.length; i += SPECIES.length()) {
3838                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3839                 av.unslice(origin).intoArray(r, i);
3840             }
3841         }
3842 
3843         assertArraysEquals(r, a, origin, DoubleMaxVectorTests::unsliceUnary);
3844     }
3845 
3846     static double[] unsliceBinary(double[] a, double[] b, int origin, int part, int idx) {
3847         double[] res = new double[SPECIES.length()];
3848         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3849             if (part == 0) {
3850                 if (i < origin)
3851                     res[i] = b[idx+i];
3852                 else {
3853                     res[i] = a[idx+j];
3854                     j++;
3855                 }
3856             } else if (part == 1) {
3857                 if (i < origin)
3858                     res[i] = a[idx+SPECIES.length()-origin+i];
3859                 else {
3860                     res[i] = b[idx+origin+j];
3861                     j++;
3862                 }
3863             }
3864         }
3865         return res;
3866     }
3867 
3868     @Test(dataProvider = "doubleBinaryOpProvider")
3869     static void unsliceBinaryDoubleMaxVectorTestsBinary(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3870         double[] a = fa.apply(SPECIES.length());
3871         double[] b = fb.apply(SPECIES.length());
3872         double[] r = new double[a.length];
3873         int origin = RAND.nextInt(SPECIES.length());
3874         int part = RAND.nextInt(2);
3875         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3876             for (int i = 0; i < a.length; i += SPECIES.length()) {
3877                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3878                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3879                 av.unslice(origin, bv, part).intoArray(r, i);
3880             }
3881         }
3882 
3883         assertArraysEquals(r, a, b, origin, part, DoubleMaxVectorTests::unsliceBinary);
3884     }
3885 
3886     static double[] unslice(double[] a, double[] b, int origin, int part, boolean[] mask, int idx) {
3887         double[] res = new double[SPECIES.length()];
3888         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3889             if(i+origin < SPECIES.length())
3890                 res[i] = b[idx+i+origin];
3891             else {
3892                 res[i] = b[idx+j];
3893                 j++;
3894             }
3895         }
3896         for (int i = 0; i < SPECIES.length(); i++){
3897             res[i] = mask[i] ? a[idx+i] : res[i];
3898         }
3899         double[] res1 = new double[SPECIES.length()];
3900         if (part == 0) {
3901             for (int i = 0, j = 0; i < SPECIES.length(); i++){
3902                 if (i < origin)
3903                     res1[i] = b[idx+i];
3904                 else {
3905                    res1[i] = res[j];
3906                    j++;
3907                 }
3908             }
3909         } else if (part == 1) {
3910             for (int i = 0, j = 0; i < SPECIES.length(); i++){
3911                 if (i < origin)
3912                     res1[i] = res[SPECIES.length()-origin+i];
3913                 else {
3914                     res1[i] = b[idx+origin+j];
3915                     j++;
3916                 }
3917             }
3918         }
3919         return res1;
3920     }
3921 
3922     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3923     static void unsliceDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3924     IntFunction<boolean[]> fm) {
3925         double[] a = fa.apply(SPECIES.length());
3926         double[] b = fb.apply(SPECIES.length());
3927         boolean[] mask = fm.apply(SPECIES.length());
3928         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3929         double[] r = new double[a.length];
3930         int origin = RAND.nextInt(SPECIES.length());
3931         int part = RAND.nextInt(2);
3932         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3933             for (int i = 0; i < a.length; i += SPECIES.length()) {
3934                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3935                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3936                 av.unslice(origin, bv, part, vmask).intoArray(r, i);
3937             }
3938         }
3939 
3940         assertArraysEquals(r, a, b, origin, part, mask, DoubleMaxVectorTests::unslice);
3941     }
3942 
3943     static double SIN(double a) {
3944         return (double)(Math.sin((double)a));
3945     }
3946 
3947     static double strictSIN(double a) {
3948         return (double)(StrictMath.sin((double)a));
3949     }
3950 
3951     @Test(dataProvider = "doubleUnaryOpProvider")
3952     static void SINDoubleMaxVectorTests(IntFunction<double[]> fa) {
3953         double[] a = fa.apply(SPECIES.length());
3954         double[] r = fr.apply(SPECIES.length());
3955 
3956         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3957             for (int i = 0; i < a.length; i += SPECIES.length()) {
3958                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3959                 av.lanewise(VectorOperators.SIN).intoArray(r, i);
3960             }
3961         }
3962 
3963         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::SIN, DoubleMaxVectorTests::strictSIN);
3964     }
3965 
3966     static double EXP(double a) {
3967         return (double)(Math.exp((double)a));
3968     }
3969 
3970     static double strictEXP(double a) {
3971         return (double)(StrictMath.exp((double)a));
3972     }
3973 
3974     @Test(dataProvider = "doubleUnaryOpProvider")
3975     static void EXPDoubleMaxVectorTests(IntFunction<double[]> fa) {
3976         double[] a = fa.apply(SPECIES.length());
3977         double[] r = fr.apply(SPECIES.length());
3978 
3979         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3980             for (int i = 0; i < a.length; i += SPECIES.length()) {
3981                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3982                 av.lanewise(VectorOperators.EXP).intoArray(r, i);
3983             }
3984         }
3985 
3986         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::EXP, DoubleMaxVectorTests::strictEXP);
3987     }
3988 
3989     static double LOG1P(double a) {
3990         return (double)(Math.log1p((double)a));
3991     }
3992 
3993     static double strictLOG1P(double a) {
3994         return (double)(StrictMath.log1p((double)a));
3995     }
3996 
3997     @Test(dataProvider = "doubleUnaryOpProvider")
3998     static void LOG1PDoubleMaxVectorTests(IntFunction<double[]> fa) {
3999         double[] a = fa.apply(SPECIES.length());
4000         double[] r = fr.apply(SPECIES.length());
4001 
4002         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4003             for (int i = 0; i < a.length; i += SPECIES.length()) {
4004                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4005                 av.lanewise(VectorOperators.LOG1P).intoArray(r, i);
4006             }
4007         }
4008 
4009         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::LOG1P, DoubleMaxVectorTests::strictLOG1P);
4010     }
4011 
4012     static double LOG(double a) {
4013         return (double)(Math.log((double)a));
4014     }
4015 
4016     static double strictLOG(double a) {
4017         return (double)(StrictMath.log((double)a));
4018     }
4019 
4020     @Test(dataProvider = "doubleUnaryOpProvider")
4021     static void LOGDoubleMaxVectorTests(IntFunction<double[]> fa) {
4022         double[] a = fa.apply(SPECIES.length());
4023         double[] r = fr.apply(SPECIES.length());
4024 
4025         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4026             for (int i = 0; i < a.length; i += SPECIES.length()) {
4027                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4028                 av.lanewise(VectorOperators.LOG).intoArray(r, i);
4029             }
4030         }
4031 
4032         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::LOG, DoubleMaxVectorTests::strictLOG);
4033     }
4034 
4035     static double LOG10(double a) {
4036         return (double)(Math.log10((double)a));
4037     }
4038 
4039     static double strictLOG10(double a) {
4040         return (double)(StrictMath.log10((double)a));
4041     }
4042 
4043     @Test(dataProvider = "doubleUnaryOpProvider")
4044     static void LOG10DoubleMaxVectorTests(IntFunction<double[]> fa) {
4045         double[] a = fa.apply(SPECIES.length());
4046         double[] r = fr.apply(SPECIES.length());
4047 
4048         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4049             for (int i = 0; i < a.length; i += SPECIES.length()) {
4050                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4051                 av.lanewise(VectorOperators.LOG10).intoArray(r, i);
4052             }
4053         }
4054 
4055         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::LOG10, DoubleMaxVectorTests::strictLOG10);
4056     }
4057 
4058     static double EXPM1(double a) {
4059         return (double)(Math.expm1((double)a));
4060     }
4061 
4062     static double strictEXPM1(double a) {
4063         return (double)(StrictMath.expm1((double)a));
4064     }
4065 
4066     @Test(dataProvider = "doubleUnaryOpProvider")
4067     static void EXPM1DoubleMaxVectorTests(IntFunction<double[]> fa) {
4068         double[] a = fa.apply(SPECIES.length());
4069         double[] r = fr.apply(SPECIES.length());
4070 
4071         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4072             for (int i = 0; i < a.length; i += SPECIES.length()) {
4073                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4074                 av.lanewise(VectorOperators.EXPM1).intoArray(r, i);
4075             }
4076         }
4077 
4078         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::EXPM1, DoubleMaxVectorTests::strictEXPM1);
4079     }
4080 
4081     static double COS(double a) {
4082         return (double)(Math.cos((double)a));
4083     }
4084 
4085     static double strictCOS(double a) {
4086         return (double)(StrictMath.cos((double)a));
4087     }
4088 
4089     @Test(dataProvider = "doubleUnaryOpProvider")
4090     static void COSDoubleMaxVectorTests(IntFunction<double[]> fa) {
4091         double[] a = fa.apply(SPECIES.length());
4092         double[] r = fr.apply(SPECIES.length());
4093 
4094         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4095             for (int i = 0; i < a.length; i += SPECIES.length()) {
4096                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4097                 av.lanewise(VectorOperators.COS).intoArray(r, i);
4098             }
4099         }
4100 
4101         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::COS, DoubleMaxVectorTests::strictCOS);
4102     }
4103 
4104     static double TAN(double a) {
4105         return (double)(Math.tan((double)a));
4106     }
4107 
4108     static double strictTAN(double a) {
4109         return (double)(StrictMath.tan((double)a));
4110     }
4111 
4112     @Test(dataProvider = "doubleUnaryOpProvider")
4113     static void TANDoubleMaxVectorTests(IntFunction<double[]> fa) {
4114         double[] a = fa.apply(SPECIES.length());
4115         double[] r = fr.apply(SPECIES.length());
4116 
4117         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4118             for (int i = 0; i < a.length; i += SPECIES.length()) {
4119                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4120                 av.lanewise(VectorOperators.TAN).intoArray(r, i);
4121             }
4122         }
4123 
4124         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::TAN, DoubleMaxVectorTests::strictTAN);
4125     }
4126 
4127     static double SINH(double a) {
4128         return (double)(Math.sinh((double)a));
4129     }
4130 
4131     static double strictSINH(double a) {
4132         return (double)(StrictMath.sinh((double)a));
4133     }
4134 
4135     @Test(dataProvider = "doubleUnaryOpProvider")
4136     static void SINHDoubleMaxVectorTests(IntFunction<double[]> fa) {
4137         double[] a = fa.apply(SPECIES.length());
4138         double[] r = fr.apply(SPECIES.length());
4139 
4140         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4141             for (int i = 0; i < a.length; i += SPECIES.length()) {
4142                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4143                 av.lanewise(VectorOperators.SINH).intoArray(r, i);
4144             }
4145         }
4146 
4147         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::SINH, DoubleMaxVectorTests::strictSINH);
4148     }
4149 
4150     static double COSH(double a) {
4151         return (double)(Math.cosh((double)a));
4152     }
4153 
4154     static double strictCOSH(double a) {
4155         return (double)(StrictMath.cosh((double)a));
4156     }
4157 
4158     @Test(dataProvider = "doubleUnaryOpProvider")
4159     static void COSHDoubleMaxVectorTests(IntFunction<double[]> fa) {
4160         double[] a = fa.apply(SPECIES.length());
4161         double[] r = fr.apply(SPECIES.length());
4162 
4163         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4164             for (int i = 0; i < a.length; i += SPECIES.length()) {
4165                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4166                 av.lanewise(VectorOperators.COSH).intoArray(r, i);
4167             }
4168         }
4169 
4170         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::COSH, DoubleMaxVectorTests::strictCOSH);
4171     }
4172 
4173     static double TANH(double a) {
4174         return (double)(Math.tanh((double)a));
4175     }
4176 
4177     static double strictTANH(double a) {
4178         return (double)(StrictMath.tanh((double)a));
4179     }
4180 
4181     @Test(dataProvider = "doubleUnaryOpProvider")
4182     static void TANHDoubleMaxVectorTests(IntFunction<double[]> fa) {
4183         double[] a = fa.apply(SPECIES.length());
4184         double[] r = fr.apply(SPECIES.length());
4185 
4186         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4187             for (int i = 0; i < a.length; i += SPECIES.length()) {
4188                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4189                 av.lanewise(VectorOperators.TANH).intoArray(r, i);
4190             }
4191         }
4192 
4193         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::TANH, DoubleMaxVectorTests::strictTANH);
4194     }
4195 
4196     static double ASIN(double a) {
4197         return (double)(Math.asin((double)a));
4198     }
4199 
4200     static double strictASIN(double a) {
4201         return (double)(StrictMath.asin((double)a));
4202     }
4203 
4204     @Test(dataProvider = "doubleUnaryOpProvider")
4205     static void ASINDoubleMaxVectorTests(IntFunction<double[]> fa) {
4206         double[] a = fa.apply(SPECIES.length());
4207         double[] r = fr.apply(SPECIES.length());
4208 
4209         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4210             for (int i = 0; i < a.length; i += SPECIES.length()) {
4211                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4212                 av.lanewise(VectorOperators.ASIN).intoArray(r, i);
4213             }
4214         }
4215 
4216         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::ASIN, DoubleMaxVectorTests::strictASIN);
4217     }
4218 
4219     static double ACOS(double a) {
4220         return (double)(Math.acos((double)a));
4221     }
4222 
4223     static double strictACOS(double a) {
4224         return (double)(StrictMath.acos((double)a));
4225     }
4226 
4227     @Test(dataProvider = "doubleUnaryOpProvider")
4228     static void ACOSDoubleMaxVectorTests(IntFunction<double[]> fa) {
4229         double[] a = fa.apply(SPECIES.length());
4230         double[] r = fr.apply(SPECIES.length());
4231 
4232         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4233             for (int i = 0; i < a.length; i += SPECIES.length()) {
4234                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4235                 av.lanewise(VectorOperators.ACOS).intoArray(r, i);
4236             }
4237         }
4238 
4239         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::ACOS, DoubleMaxVectorTests::strictACOS);
4240     }
4241 
4242     static double ATAN(double a) {
4243         return (double)(Math.atan((double)a));
4244     }
4245 
4246     static double strictATAN(double a) {
4247         return (double)(StrictMath.atan((double)a));
4248     }
4249 
4250     @Test(dataProvider = "doubleUnaryOpProvider")
4251     static void ATANDoubleMaxVectorTests(IntFunction<double[]> fa) {
4252         double[] a = fa.apply(SPECIES.length());
4253         double[] r = fr.apply(SPECIES.length());
4254 
4255         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4256             for (int i = 0; i < a.length; i += SPECIES.length()) {
4257                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4258                 av.lanewise(VectorOperators.ATAN).intoArray(r, i);
4259             }
4260         }
4261 
4262         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::ATAN, DoubleMaxVectorTests::strictATAN);
4263     }
4264 
4265     static double CBRT(double a) {
4266         return (double)(Math.cbrt((double)a));
4267     }
4268 
4269     static double strictCBRT(double a) {
4270         return (double)(StrictMath.cbrt((double)a));
4271     }
4272 
4273     @Test(dataProvider = "doubleUnaryOpProvider")
4274     static void CBRTDoubleMaxVectorTests(IntFunction<double[]> fa) {
4275         double[] a = fa.apply(SPECIES.length());
4276         double[] r = fr.apply(SPECIES.length());
4277 
4278         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4279             for (int i = 0; i < a.length; i += SPECIES.length()) {
4280                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4281                 av.lanewise(VectorOperators.CBRT).intoArray(r, i);
4282             }
4283         }
4284 
4285         assertArraysEqualsWithinOneUlp(r, a, DoubleMaxVectorTests::CBRT, DoubleMaxVectorTests::strictCBRT);
4286     }
4287 
4288     static double HYPOT(double a, double b) {
4289         return (double)(Math.hypot((double)a, (double)b));
4290     }
4291 
4292     static double strictHYPOT(double a, double b) {
4293         return (double)(StrictMath.hypot((double)a, (double)b));
4294     }
4295 
4296     @Test(dataProvider = "doubleBinaryOpProvider")
4297     static void HYPOTDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4298         double[] a = fa.apply(SPECIES.length());
4299         double[] b = fb.apply(SPECIES.length());
4300         double[] r = fr.apply(SPECIES.length());
4301 
4302         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4303             for (int i = 0; i < a.length; i += SPECIES.length()) {
4304                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4305                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4306                 av.lanewise(VectorOperators.HYPOT, bv).intoArray(r, i);
4307             }
4308         }
4309 
4310         assertArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::HYPOT, DoubleMaxVectorTests::strictHYPOT);
4311     }
4312 
4313 
4314     static double POW(double a, double b) {
4315         return (double)(Math.pow((double)a, (double)b));
4316     }
4317 
4318     static double strictPOW(double a, double b) {
4319         return (double)(StrictMath.pow((double)a, (double)b));
4320     }
4321 
4322     @Test(dataProvider = "doubleBinaryOpProvider")
4323     static void POWDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4324         double[] a = fa.apply(SPECIES.length());
4325         double[] b = fb.apply(SPECIES.length());
4326         double[] r = fr.apply(SPECIES.length());
4327 
4328         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4329             for (int i = 0; i < a.length; i += SPECIES.length()) {
4330                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4331                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4332                 av.lanewise(VectorOperators.POW, bv).intoArray(r, i);
4333             }
4334         }
4335 
4336         assertArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::POW, DoubleMaxVectorTests::strictPOW);
4337     }
4338 
4339 
4340     static double pow(double a, double b) {
4341         return (double)(Math.pow((double)a, (double)b));
4342     }
4343 
4344     static double strictpow(double a, double b) {
4345         return (double)(StrictMath.pow((double)a, (double)b));
4346     }
4347 
4348     @Test(dataProvider = "doubleBinaryOpProvider")
4349     static void powDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4350         double[] a = fa.apply(SPECIES.length());
4351         double[] b = fb.apply(SPECIES.length());
4352         double[] r = fr.apply(SPECIES.length());
4353 
4354         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4355             for (int i = 0; i < a.length; i += SPECIES.length()) {
4356                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4357                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4358                 av.pow(bv).intoArray(r, i);
4359             }
4360         }
4361 
4362         assertArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::pow, DoubleMaxVectorTests::strictpow);
4363     }
4364 
4365 
4366     static double ATAN2(double a, double b) {
4367         return (double)(Math.atan2((double)a, (double)b));
4368     }
4369 
4370     static double strictATAN2(double a, double b) {
4371         return (double)(StrictMath.atan2((double)a, (double)b));
4372     }
4373 
4374     @Test(dataProvider = "doubleBinaryOpProvider")
4375     static void ATAN2DoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4376         double[] a = fa.apply(SPECIES.length());
4377         double[] b = fb.apply(SPECIES.length());
4378         double[] r = fr.apply(SPECIES.length());
4379 
4380         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4381             for (int i = 0; i < a.length; i += SPECIES.length()) {
4382                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4383                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4384                 av.lanewise(VectorOperators.ATAN2, bv).intoArray(r, i);
4385             }
4386         }
4387 
4388         assertArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::ATAN2, DoubleMaxVectorTests::strictATAN2);
4389     }
4390 
4391 
4392     @Test(dataProvider = "doubleBinaryOpProvider")
4393     static void POWDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4394         double[] a = fa.apply(SPECIES.length());
4395         double[] b = fb.apply(SPECIES.length());
4396         double[] r = fr.apply(SPECIES.length());
4397 
4398         for (int i = 0; i < a.length; i += SPECIES.length()) {
4399             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4400             av.lanewise(VectorOperators.POW, b[i]).intoArray(r, i);
4401         }
4402 
4403         assertBroadcastArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::POW, DoubleMaxVectorTests::strictPOW);
4404     }
4405 
4406 
4407     @Test(dataProvider = "doubleBinaryOpProvider")
4408     static void powDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4409         double[] a = fa.apply(SPECIES.length());
4410         double[] b = fb.apply(SPECIES.length());
4411         double[] r = fr.apply(SPECIES.length());
4412 
4413         for (int i = 0; i < a.length; i += SPECIES.length()) {
4414             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4415             av.pow(b[i]).intoArray(r, i);
4416         }
4417 
4418         assertBroadcastArraysEqualsWithinOneUlp(r, a, b, DoubleMaxVectorTests::pow, DoubleMaxVectorTests::strictpow);
4419     }
4420 
4421 
4422     static double FMA(double a, double b, double c) {
4423         return (double)(Math.fma(a, b, c));
4424     }
4425 
4426     static double fma(double a, double b, double c) {
4427         return (double)(Math.fma(a, b, c));
4428     }
4429 
4430     @Test(dataProvider = "doubleTernaryOpProvider")
4431     static void FMADoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4432         int count = INVOC_COUNT;
4433         switch ("FMA") {
4434         case "fma": case "lanewise_FMA":
4435            // Math.fma uses BigDecimal
4436            count = Math.max(5, count/20); break;
4437         }
4438         final int INVOC_COUNT = count;
4439         double[] a = fa.apply(SPECIES.length());
4440         double[] b = fb.apply(SPECIES.length());
4441         double[] c = fc.apply(SPECIES.length());
4442         double[] r = fr.apply(SPECIES.length());
4443 
4444         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4445             for (int i = 0; i < a.length; i += SPECIES.length()) {
4446                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4447                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4448                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4449                 av.lanewise(VectorOperators.FMA, bv, cv).intoArray(r, i);
4450             }
4451         }
4452 
4453         assertArraysEquals(r, a, b, c, DoubleMaxVectorTests::FMA);
4454     }
4455 
4456     @Test(dataProvider = "doubleTernaryOpProvider")
4457     static void fmaDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4458         int count = INVOC_COUNT;
4459         switch ("fma") {
4460         case "fma": case "lanewise_FMA":
4461            // Math.fma uses BigDecimal
4462            count = Math.max(5, count/20); break;
4463         }
4464         final int INVOC_COUNT = count;
4465         double[] a = fa.apply(SPECIES.length());
4466         double[] b = fb.apply(SPECIES.length());
4467         double[] c = fc.apply(SPECIES.length());
4468         double[] r = fr.apply(SPECIES.length());
4469 
4470         for (int i = 0; i < a.length; i += SPECIES.length()) {
4471             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4472             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4473             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4474             av.fma(bv, cv).intoArray(r, i);
4475         }
4476 
4477         assertArraysEquals(r, a, b, c, DoubleMaxVectorTests::fma);
4478     }
4479 
4480     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4481     static void FMADoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
4482                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4483         int count = INVOC_COUNT;
4484         switch ("FMA") {
4485         case "fma": case "lanewise_FMA":
4486            // Math.fma uses BigDecimal
4487            count = Math.max(5, count/20); break;
4488         }
4489         final int INVOC_COUNT = count;
4490         double[] a = fa.apply(SPECIES.length());
4491         double[] b = fb.apply(SPECIES.length());
4492         double[] c = fc.apply(SPECIES.length());
4493         double[] r = fr.apply(SPECIES.length());
4494         boolean[] mask = fm.apply(SPECIES.length());
4495         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4496 
4497         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4498             for (int i = 0; i < a.length; i += SPECIES.length()) {
4499                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4500                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4501                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4502                 av.lanewise(VectorOperators.FMA, bv, cv, vmask).intoArray(r, i);
4503             }
4504         }
4505 
4506         assertArraysEquals(r, a, b, c, mask, DoubleMaxVectorTests::FMA);
4507     }
4508 
4509     @Test(dataProvider = "doubleTernaryOpProvider")
4510     static void FMADoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4511         double[] a = fa.apply(SPECIES.length());
4512         double[] b = fb.apply(SPECIES.length());
4513         double[] c = fc.apply(SPECIES.length());
4514         double[] r = fr.apply(SPECIES.length());
4515 
4516         for (int i = 0; i < a.length; i += SPECIES.length()) {
4517             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4518             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4519             av.lanewise(VectorOperators.FMA, bv, c[i]).intoArray(r, i);
4520         }
4521         assertBroadcastArraysEquals(r, a, b, c, DoubleMaxVectorTests::FMA);
4522     }
4523 
4524     @Test(dataProvider = "doubleTernaryOpProvider")
4525     static void FMADoubleMaxVectorTestsAltBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4526         double[] a = fa.apply(SPECIES.length());
4527         double[] b = fb.apply(SPECIES.length());
4528         double[] c = fc.apply(SPECIES.length());
4529         double[] r = fr.apply(SPECIES.length());
4530 
4531         for (int i = 0; i < a.length; i += SPECIES.length()) {
4532             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4533             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4534             av.lanewise(VectorOperators.FMA, b[i], cv).intoArray(r, i);
4535         }
4536         assertAltBroadcastArraysEquals(r, a, b, c, DoubleMaxVectorTests::FMA);
4537     }
4538 
4539     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4540     static void FMADoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4541                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4542         double[] a = fa.apply(SPECIES.length());
4543         double[] b = fb.apply(SPECIES.length());
4544         double[] c = fc.apply(SPECIES.length());
4545         double[] r = fr.apply(SPECIES.length());
4546         boolean[] mask = fm.apply(SPECIES.length());
4547         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4548 
4549         for (int i = 0; i < a.length; i += SPECIES.length()) {
4550             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4551             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4552             av.lanewise(VectorOperators.FMA, bv, c[i], vmask).intoArray(r, i);
4553         }
4554 
4555         assertBroadcastArraysEquals(r, a, b, c, mask, DoubleMaxVectorTests::FMA);
4556     }
4557 
4558     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4559     static void FMADoubleMaxVectorTestsAltBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4560                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4561         double[] a = fa.apply(SPECIES.length());
4562         double[] b = fb.apply(SPECIES.length());
4563         double[] c = fc.apply(SPECIES.length());
4564         double[] r = fr.apply(SPECIES.length());
4565         boolean[] mask = fm.apply(SPECIES.length());
4566         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4567 
4568         for (int i = 0; i < a.length; i += SPECIES.length()) {
4569             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4570             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4571             av.lanewise(VectorOperators.FMA, b[i], cv, vmask).intoArray(r, i);
4572         }
4573 
4574         assertAltBroadcastArraysEquals(r, a, b, c, mask, DoubleMaxVectorTests::FMA);
4575     }
4576 
4577     @Test(dataProvider = "doubleTernaryOpProvider")
4578     static void FMADoubleMaxVectorTestsDoubleBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4579         int count = INVOC_COUNT;
4580         switch ("FMA") {
4581         case "fma": case "lanewise_FMA":
4582            // Math.fma uses BigDecimal
4583            count = Math.max(5, count/20); break;
4584         }
4585         final int INVOC_COUNT = count;
4586         double[] a = fa.apply(SPECIES.length());
4587         double[] b = fb.apply(SPECIES.length());
4588         double[] c = fc.apply(SPECIES.length());
4589         double[] r = fr.apply(SPECIES.length());
4590 
4591         for (int i = 0; i < a.length; i += SPECIES.length()) {
4592             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4593             av.lanewise(VectorOperators.FMA, b[i], c[i]).intoArray(r, i);
4594         }
4595 
4596         assertDoubleBroadcastArraysEquals(r, a, b, c, DoubleMaxVectorTests::FMA);
4597     }
4598 
4599     @Test(dataProvider = "doubleTernaryOpProvider")
4600     static void fmaDoubleMaxVectorTestsDoubleBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4601         int count = INVOC_COUNT;
4602         switch ("fma") {
4603         case "fma": case "lanewise_FMA":
4604            // Math.fma uses BigDecimal
4605            count = Math.max(5, count/20); break;
4606         }
4607         final int INVOC_COUNT = count;
4608         double[] a = fa.apply(SPECIES.length());
4609         double[] b = fb.apply(SPECIES.length());
4610         double[] c = fc.apply(SPECIES.length());
4611         double[] r = fr.apply(SPECIES.length());
4612 
4613         for (int i = 0; i < a.length; i += SPECIES.length()) {
4614             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4615             av.fma(b[i], c[i]).intoArray(r, i);
4616         }
4617 
4618         assertDoubleBroadcastArraysEquals(r, a, b, c, DoubleMaxVectorTests::fma);
4619     }
4620 
4621     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4622     static void FMADoubleMaxVectorTestsDoubleBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4623                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4624         int count = INVOC_COUNT;
4625         switch ("FMA") {
4626         case "fma": case "lanewise_FMA":
4627            // Math.fma uses BigDecimal
4628            count = Math.max(5, count/20); break;
4629         }
4630         final int INVOC_COUNT = count;
4631         double[] a = fa.apply(SPECIES.length());
4632         double[] b = fb.apply(SPECIES.length());
4633         double[] c = fc.apply(SPECIES.length());
4634         double[] r = fr.apply(SPECIES.length());
4635         boolean[] mask = fm.apply(SPECIES.length());
4636         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4637 
4638         for (int i = 0; i < a.length; i += SPECIES.length()) {
4639             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4640             av.lanewise(VectorOperators.FMA, b[i], c[i], vmask).intoArray(r, i);
4641         }
4642 
4643         assertDoubleBroadcastArraysEquals(r, a, b, c, mask, DoubleMaxVectorTests::FMA);
4644     }
4645 
4646     static double NEG(double a) {
4647         return (double)(-((double)a));
4648     }
4649 
4650     static double neg(double a) {
4651         return (double)(-((double)a));
4652     }
4653 
4654     @Test(dataProvider = "doubleUnaryOpProvider")
4655     static void NEGDoubleMaxVectorTests(IntFunction<double[]> fa) {
4656         double[] a = fa.apply(SPECIES.length());
4657         double[] r = fr.apply(SPECIES.length());
4658 
4659         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4660             for (int i = 0; i < a.length; i += SPECIES.length()) {
4661                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4662                 av.lanewise(VectorOperators.NEG).intoArray(r, i);
4663             }
4664         }
4665 
4666         assertArraysEquals(r, a, DoubleMaxVectorTests::NEG);
4667     }
4668 
4669     @Test(dataProvider = "doubleUnaryOpProvider")
4670     static void negDoubleMaxVectorTests(IntFunction<double[]> fa) {
4671         double[] a = fa.apply(SPECIES.length());
4672         double[] r = fr.apply(SPECIES.length());
4673 
4674         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4675             for (int i = 0; i < a.length; i += SPECIES.length()) {
4676                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4677                 av.neg().intoArray(r, i);
4678             }
4679         }
4680 
4681         assertArraysEquals(r, a, DoubleMaxVectorTests::neg);
4682     }
4683 
4684     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4685     static void NEGMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
4686                                                 IntFunction<boolean[]> fm) {
4687         double[] a = fa.apply(SPECIES.length());
4688         double[] r = fr.apply(SPECIES.length());
4689         boolean[] mask = fm.apply(SPECIES.length());
4690         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4691 
4692         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4693             for (int i = 0; i < a.length; i += SPECIES.length()) {
4694                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4695                 av.lanewise(VectorOperators.NEG, vmask).intoArray(r, i);
4696             }
4697         }
4698 
4699         assertArraysEquals(r, a, mask, DoubleMaxVectorTests::NEG);
4700     }
4701 
4702     static double ABS(double a) {
4703         return (double)(Math.abs((double)a));
4704     }
4705 
4706     static double abs(double a) {
4707         return (double)(Math.abs((double)a));
4708     }
4709 
4710     @Test(dataProvider = "doubleUnaryOpProvider")
4711     static void ABSDoubleMaxVectorTests(IntFunction<double[]> fa) {
4712         double[] a = fa.apply(SPECIES.length());
4713         double[] r = fr.apply(SPECIES.length());
4714 
4715         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4716             for (int i = 0; i < a.length; i += SPECIES.length()) {
4717                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4718                 av.lanewise(VectorOperators.ABS).intoArray(r, i);
4719             }
4720         }
4721 
4722         assertArraysEquals(r, a, DoubleMaxVectorTests::ABS);
4723     }
4724 
4725     @Test(dataProvider = "doubleUnaryOpProvider")
4726     static void absDoubleMaxVectorTests(IntFunction<double[]> fa) {
4727         double[] a = fa.apply(SPECIES.length());
4728         double[] r = fr.apply(SPECIES.length());
4729 
4730         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4731             for (int i = 0; i < a.length; i += SPECIES.length()) {
4732                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4733                 av.abs().intoArray(r, i);
4734             }
4735         }
4736 
4737         assertArraysEquals(r, a, DoubleMaxVectorTests::abs);
4738     }
4739 
4740     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4741     static void ABSMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
4742                                                 IntFunction<boolean[]> fm) {
4743         double[] a = fa.apply(SPECIES.length());
4744         double[] r = fr.apply(SPECIES.length());
4745         boolean[] mask = fm.apply(SPECIES.length());
4746         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4747 
4748         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4749             for (int i = 0; i < a.length; i += SPECIES.length()) {
4750                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4751                 av.lanewise(VectorOperators.ABS, vmask).intoArray(r, i);
4752             }
4753         }
4754 
4755         assertArraysEquals(r, a, mask, DoubleMaxVectorTests::ABS);
4756     }
4757 
4758     static double SQRT(double a) {
4759         return (double)(Math.sqrt((double)a));
4760     }
4761 
4762     static double sqrt(double a) {
4763         return (double)(Math.sqrt((double)a));
4764     }
4765 
4766     @Test(dataProvider = "doubleUnaryOpProvider")
4767     static void SQRTDoubleMaxVectorTests(IntFunction<double[]> fa) {
4768         double[] a = fa.apply(SPECIES.length());
4769         double[] r = fr.apply(SPECIES.length());
4770 
4771         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4772             for (int i = 0; i < a.length; i += SPECIES.length()) {
4773                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4774                 av.lanewise(VectorOperators.SQRT).intoArray(r, i);
4775             }
4776         }
4777 
4778         assertArraysEquals(r, a, DoubleMaxVectorTests::SQRT);
4779     }
4780 
4781     @Test(dataProvider = "doubleUnaryOpProvider")
4782     static void sqrtDoubleMaxVectorTests(IntFunction<double[]> fa) {
4783         double[] a = fa.apply(SPECIES.length());
4784         double[] r = fr.apply(SPECIES.length());
4785 
4786         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4787             for (int i = 0; i < a.length; i += SPECIES.length()) {
4788                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4789                 av.sqrt().intoArray(r, i);
4790             }
4791         }
4792 
4793         assertArraysEquals(r, a, DoubleMaxVectorTests::sqrt);
4794     }
4795 
4796     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4797     static void SQRTMaskedDoubleMaxVectorTests(IntFunction<double[]> fa,
4798                                                 IntFunction<boolean[]> fm) {
4799         double[] a = fa.apply(SPECIES.length());
4800         double[] r = fr.apply(SPECIES.length());
4801         boolean[] mask = fm.apply(SPECIES.length());
4802         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4803 
4804         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4805             for (int i = 0; i < a.length; i += SPECIES.length()) {
4806                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4807                 av.lanewise(VectorOperators.SQRT, vmask).intoArray(r, i);
4808             }
4809         }
4810 
4811         assertArraysEquals(r, a, mask, DoubleMaxVectorTests::SQRT);
4812     }
4813 
4814     @Test(dataProvider = "doubleCompareOpProvider")
4815     static void ltDoubleMaxVectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4816         double[] a = fa.apply(SPECIES.length());
4817         double[] b = fb.apply(SPECIES.length());
4818 
4819         for (int i = 0; i < a.length; i += SPECIES.length()) {
4820             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4821             VectorMask<Double> mv = av.lt(b[i]);
4822 
4823             // Check results as part of computation.
4824             for (int j = 0; j < SPECIES.length(); j++) {
4825                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i]);
4826             }
4827         }
4828     }
4829 
4830     @Test(dataProvider = "doubleCompareOpProvider")
4831     static void eqDoubleMaxVectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4832         double[] a = fa.apply(SPECIES.length());
4833         double[] b = fb.apply(SPECIES.length());
4834 
4835         for (int i = 0; i < a.length; i += SPECIES.length()) {
4836             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4837             VectorMask<Double> mv = av.eq(b[i]);
4838 
4839             // Check results as part of computation.
4840             for (int j = 0; j < SPECIES.length(); j++) {
4841                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i]);
4842             }
4843         }
4844     }
4845 
4846     @Test(dataProvider = "doubletoIntUnaryOpProvider")
4847     static void toIntArrayDoubleMaxVectorTestsSmokeTest(IntFunction<double[]> fa) {
4848         double[] a = fa.apply(SPECIES.length());
4849 
4850         for (int i = 0; i < a.length; i += SPECIES.length()) {
4851             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4852             int[] r = av.toIntArray();
4853             assertArraysEquals(r, a, i);
4854         }
4855     }
4856 
4857     @Test(dataProvider = "doubletoLongUnaryOpProvider")
4858     static void toLongArrayDoubleMaxVectorTestsSmokeTest(IntFunction<double[]> fa) {
4859         double[] a = fa.apply(SPECIES.length());
4860 
4861         for (int i = 0; i < a.length; i += SPECIES.length()) {
4862             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4863             long[] r = av.toLongArray();
4864             assertArraysEquals(r, a, i);
4865         }
4866     }
4867 
4868 
4869     @Test(dataProvider = "doubleUnaryOpProvider")
4870     static void toStringDoubleMaxVectorTestsSmokeTest(IntFunction<double[]> fa) {
4871         double[] a = fa.apply(SPECIES.length());
4872 
4873         for (int i = 0; i < a.length; i += SPECIES.length()) {
4874             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4875             String str = av.toString();
4876 
4877             double subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
4878             Assert.assertTrue(str.equals(Arrays.toString(subarr)), "at index " + i + ", string should be = " + Arrays.toString(subarr) + ", but is = " + str);
4879         }
4880     }
4881 
4882     @Test(dataProvider = "doubleUnaryOpProvider")
4883     static void hashCodeDoubleMaxVectorTestsSmokeTest(IntFunction<double[]> fa) {
4884         double[] a = fa.apply(SPECIES.length());
4885 
4886         for (int i = 0; i < a.length; i += SPECIES.length()) {
4887             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4888             int hash = av.hashCode();
4889 
4890             double subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
4891             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
4892             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
4893         }
4894     }
4895 
4896 
4897     static long ADDReduceLong(double[] a, int idx) {
4898         double res = 0;
4899         for (int i = idx; i < (idx + SPECIES.length()); i++) {
4900             res += a[i];
4901         }
4902 
4903         return (long)res;
4904     }
4905 
4906     static long ADDReduceAllLong(double[] a) {
4907         long res = 0;
4908         for (int i = 0; i < a.length; i += SPECIES.length()) {
4909             res += ADDReduceLong(a, i);
4910         }
4911 
4912         return res;
4913     }
4914 
4915     @Test(dataProvider = "doubleUnaryOpProvider")
4916     static void ADDReduceLongDoubleMaxVectorTests(IntFunction<double[]> fa) {
4917         double[] a = fa.apply(SPECIES.length());
4918         long[] r = lfr.apply(SPECIES.length());
4919         long ra = 0;
4920 
4921         for (int i = 0; i < a.length; i += SPECIES.length()) {
4922             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4923             r[i] = av.reduceLanesToLong(VectorOperators.ADD);
4924         }
4925 
4926         ra = 0;
4927         for (int i = 0; i < a.length; i ++) {
4928             ra += r[i];
4929         }
4930 
4931         assertReductionLongArraysEquals(r, ra, a,
4932                 DoubleMaxVectorTests::ADDReduceLong, DoubleMaxVectorTests::ADDReduceAllLong);
4933     }
4934 
4935     static long ADDReduceLongMasked(double[] a, int idx, boolean[] mask) {
4936         double res = 0;
4937         for (int i = idx; i < (idx + SPECIES.length()); i++) {
4938             if(mask[i % SPECIES.length()])
4939                 res += a[i];
4940         }
4941 
4942         return (long)res;
4943     }
4944 
4945     static long ADDReduceAllLongMasked(double[] a, boolean[] mask) {
4946         long res = 0;
4947         for (int i = 0; i < a.length; i += SPECIES.length()) {
4948             res += ADDReduceLongMasked(a, i, mask);
4949         }
4950 
4951         return res;
4952     }
4953 
4954     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4955     static void ADDReduceLongDoubleMaxVectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
4956         double[] a = fa.apply(SPECIES.length());
4957         long[] r = lfr.apply(SPECIES.length());
4958         boolean[] mask = fm.apply(SPECIES.length());
4959         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4960         long ra = 0;
4961 
4962         for (int i = 0; i < a.length; i += SPECIES.length()) {
4963             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4964             r[i] = av.reduceLanesToLong(VectorOperators.ADD, vmask);
4965         }
4966 
4967         ra = 0;
4968         for (int i = 0; i < a.length; i ++) {
4969             ra += r[i];
4970         }
4971 
4972         assertReductionLongArraysEqualsMasked(r, ra, a, mask,
4973                 DoubleMaxVectorTests::ADDReduceLongMasked, DoubleMaxVectorTests::ADDReduceAllLongMasked);
4974     }
4975 
4976     @Test(dataProvider = "doubletoLongUnaryOpProvider")
4977     static void BroadcastLongDoubleMaxVectorTestsSmokeTest(IntFunction<double[]> fa) {
4978         double[] a = fa.apply(SPECIES.length());
4979         double[] r = new double[a.length];
4980 
4981         for (int i = 0; i < a.length; i += SPECIES.length()) {
4982             DoubleVector.broadcast(SPECIES, (long)a[i]).intoArray(r, i);
4983         }
4984         assertBroadcastArraysEquals(r, a);
4985     }
4986 
4987     @Test(dataProvider = "doubleBinaryOpMaskProvider")
4988     static void blendDoubleMaxVectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4989                                           IntFunction<boolean[]> fm) {
4990         double[] a = fa.apply(SPECIES.length());
4991         double[] b = fb.apply(SPECIES.length());
4992         double[] r = fr.apply(SPECIES.length());
4993         boolean[] mask = fm.apply(SPECIES.length());
4994         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4995 
4996         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4997             for (int i = 0; i < a.length; i += SPECIES.length()) {
4998                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4999                 av.blend((long)b[i], vmask).intoArray(r, i);
5000             }
5001         }
5002         assertBroadcastLongArraysEquals(r, a, b, mask, DoubleMaxVectorTests::blend);
5003     }
5004 
5005 
5006     @Test(dataProvider = "doubleUnaryOpSelectFromProvider")
5007     static void SelectFromDoubleMaxVectorTests(IntFunction<double[]> fa,
5008                                            BiFunction<Integer,Integer,double[]> fs) {
5009         double[] a = fa.apply(SPECIES.length());
5010         double[] order = fs.apply(a.length, SPECIES.length());
5011         double[] r = fr.apply(SPECIES.length());
5012 
5013         for (int i = 0; i < a.length; i += SPECIES.length()) {
5014             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5015             DoubleVector bv = DoubleVector.fromArray(SPECIES, order, i);
5016             bv.selectFrom(av).intoArray(r, i);
5017         }
5018 
5019         assertSelectFromArraysEquals(r, a, order, SPECIES.length());
5020     }
5021 
5022     @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
5023     static void SelectFromTwoVectorDoubleMaxVectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
5024         double[] a = fa.apply(SPECIES.length());
5025         double[] b = fb.apply(SPECIES.length());
5026         double[] idx = fc.apply(SPECIES.length());
5027         double[] r = fr.apply(SPECIES.length());
5028 
5029         for (int ic = 0; ic < INVOC_COUNT; ic++) {
5030             for (int i = 0; i < idx.length; i += SPECIES.length()) {
5031                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5032                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
5033                 DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
5034                 idxv.selectFrom(av, bv).intoArray(r, i);
5035             }
5036         }
5037         assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
5038     }
5039 
5040     @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
5041     static void SelectFromDoubleMaxVectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
5042                                                            BiFunction<Integer,Integer,double[]> fs,
5043                                                            IntFunction<boolean[]> fm) {
5044         double[] a = fa.apply(SPECIES.length());
5045         double[] order = fs.apply(a.length, SPECIES.length());
5046         double[] r = fr.apply(SPECIES.length());
5047         boolean[] mask = fm.apply(SPECIES.length());
5048         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
5049 
5050         for (int i = 0; i < a.length; i += SPECIES.length()) {
5051             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5052             DoubleVector bv = DoubleVector.fromArray(SPECIES, order, i);
5053             bv.selectFrom(av, vmask).intoArray(r, i);
5054         }
5055 
5056         assertSelectFromArraysEquals(r, a, order, mask, SPECIES.length());
5057     }
5058 
5059     @Test(dataProvider = "shuffleProvider")
5060     static void shuffleMiscellaneousDoubleMaxVectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fs) {
5061         int[] a = fs.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5062 
5063         for (int i = 0; i < a.length; i += SPECIES.length()) {
5064             var shuffle = VectorShuffle.fromArray(SPECIES, a, i);
5065             int hash = shuffle.hashCode();
5066             int length = shuffle.length();
5067 
5068             int subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5069             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
5070             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
5071             Assert.assertEquals(length, SPECIES.length());
5072         }
5073     }
5074 
5075     @Test(dataProvider = "shuffleProvider")
5076     static void shuffleToStringDoubleMaxVectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fs) {
5077         int[] a = fs.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5078 
5079         for (int i = 0; i < a.length; i += SPECIES.length()) {
5080             var shuffle = VectorShuffle.fromArray(SPECIES, a, i);
5081             String str = shuffle.toString();
5082 
5083             int subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5084             Assert.assertTrue(str.equals("Shuffle" + Arrays.toString(subarr)), "at index " +
5085                 i + ", string should be = " + Arrays.toString(subarr) + ", but is = " + str);
5086         }
5087     }
5088 
5089     @Test(dataProvider = "shuffleCompareOpProvider")
5090     static void shuffleEqualsDoubleMaxVectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fa, BiFunction<Integer,Integer,int[]> fb) {
5091         int[] a = fa.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5092         int[] b = fb.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5093 
5094         for (int i = 0; i < a.length; i += SPECIES.length()) {
5095             var av = VectorShuffle.fromArray(SPECIES, a, i);
5096             var bv = VectorShuffle.fromArray(SPECIES, b, i);
5097             boolean eq = av.equals(bv);
5098             int to = i + SPECIES.length();
5099             Assert.assertEquals(eq, Arrays.equals(a, i, to, b, i, to));
5100         }
5101     }
5102 
5103     @Test(dataProvider = "maskCompareOpProvider")
5104     static void maskEqualsDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5105         boolean[] a = fa.apply(SPECIES.length());
5106         boolean[] b = fb.apply(SPECIES.length());
5107 
5108         for (int i = 0; i < a.length; i += SPECIES.length()) {
5109             var av = SPECIES.loadMask(a, i);
5110             var bv = SPECIES.loadMask(b, i);
5111             boolean equals = av.equals(bv);
5112             int to = i + SPECIES.length();
5113             Assert.assertEquals(equals, Arrays.equals(a, i, to, b, i, to));
5114         }
5115     }
5116 
5117     static boolean band(boolean a, boolean b) {
5118         return a & b;
5119     }
5120 
5121     @Test(dataProvider = "maskCompareOpProvider")
5122     static void maskAndDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5123         boolean[] a = fa.apply(SPECIES.length());
5124         boolean[] b = fb.apply(SPECIES.length());
5125         boolean[] r = new boolean[a.length];
5126 
5127         for (int i = 0; i < a.length; i += SPECIES.length()) {
5128             var av = SPECIES.loadMask(a, i);
5129             var bv = SPECIES.loadMask(b, i);
5130             var cv = av.and(bv);
5131             cv.intoArray(r, i);
5132         }
5133         assertArraysEquals(r, a, b, DoubleMaxVectorTests::band);
5134     }
5135 
5136     static boolean bor(boolean a, boolean b) {
5137         return a | b;
5138     }
5139 
5140     @Test(dataProvider = "maskCompareOpProvider")
5141     static void maskOrDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5142         boolean[] a = fa.apply(SPECIES.length());
5143         boolean[] b = fb.apply(SPECIES.length());
5144         boolean[] r = new boolean[a.length];
5145 
5146         for (int i = 0; i < a.length; i += SPECIES.length()) {
5147             var av = SPECIES.loadMask(a, i);
5148             var bv = SPECIES.loadMask(b, i);
5149             var cv = av.or(bv);
5150             cv.intoArray(r, i);
5151         }
5152         assertArraysEquals(r, a, b, DoubleMaxVectorTests::bor);
5153     }
5154 
5155     static boolean bxor(boolean a, boolean b) {
5156         return a != b;
5157     }
5158 
5159     @Test(dataProvider = "maskCompareOpProvider")
5160     static void maskXorDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5161         boolean[] a = fa.apply(SPECIES.length());
5162         boolean[] b = fb.apply(SPECIES.length());
5163         boolean[] r = new boolean[a.length];
5164 
5165         for (int i = 0; i < a.length; i += SPECIES.length()) {
5166             var av = SPECIES.loadMask(a, i);
5167             var bv = SPECIES.loadMask(b, i);
5168             var cv = av.xor(bv);
5169             cv.intoArray(r, i);
5170         }
5171         assertArraysEquals(r, a, b, DoubleMaxVectorTests::bxor);
5172     }
5173 
5174     static boolean bandNot(boolean a, boolean b) {
5175         return a & !b;
5176     }
5177 
5178     @Test(dataProvider = "maskCompareOpProvider")
5179     static void maskAndNotDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5180         boolean[] a = fa.apply(SPECIES.length());
5181         boolean[] b = fb.apply(SPECIES.length());
5182         boolean[] r = new boolean[a.length];
5183 
5184         for (int i = 0; i < a.length; i += SPECIES.length()) {
5185             var av = SPECIES.loadMask(a, i);
5186             var bv = SPECIES.loadMask(b, i);
5187             var cv = av.andNot(bv);
5188             cv.intoArray(r, i);
5189         }
5190         assertArraysEquals(r, a, b, DoubleMaxVectorTests::bandNot);
5191     }
5192 
5193     static boolean beq(boolean a, boolean b) {
5194         return (a == b);
5195     }
5196 
5197     @Test(dataProvider = "maskCompareOpProvider")
5198     static void maskEqDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5199         boolean[] a = fa.apply(SPECIES.length());
5200         boolean[] b = fb.apply(SPECIES.length());
5201         boolean[] r = new boolean[a.length];
5202 
5203         for (int i = 0; i < a.length; i += SPECIES.length()) {
5204             var av = SPECIES.loadMask(a, i);
5205             var bv = SPECIES.loadMask(b, i);
5206             var cv = av.eq(bv);
5207             cv.intoArray(r, i);
5208         }
5209         assertArraysEquals(r, a, b, DoubleMaxVectorTests::beq);
5210     }
5211 
5212     @Test(dataProvider = "maskProvider")
5213     static void maskHashCodeDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5214         boolean[] a = fa.apply(SPECIES.length());
5215 
5216         for (int i = 0; i < a.length; i += SPECIES.length()) {
5217             var vmask = SPECIES.loadMask(a, i);
5218             int hash = vmask.hashCode();
5219 
5220             boolean subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5221             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
5222             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
5223         }
5224     }
5225 
5226     static int maskTrueCount(boolean[] a, int idx) {
5227         int trueCount = 0;
5228         for (int i = idx; i < idx + SPECIES.length(); i++) {
5229             trueCount += a[i] ? 1 : 0;
5230         }
5231         return trueCount;
5232     }
5233 
5234     @Test(dataProvider = "maskProvider")
5235     static void maskTrueCountDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5236         boolean[] a = fa.apply(SPECIES.length());
5237         int[] r = new int[a.length];
5238 
5239         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5240             for (int i = 0; i < a.length; i += SPECIES.length()) {
5241                 var vmask = SPECIES.loadMask(a, i);
5242                 r[i] = vmask.trueCount();
5243             }
5244         }
5245 
5246         assertMaskReductionArraysEquals(r, a, DoubleMaxVectorTests::maskTrueCount);
5247     }
5248 
5249     static int maskLastTrue(boolean[] a, int idx) {
5250         int i = idx + SPECIES.length() - 1;
5251         for (; i >= idx; i--) {
5252             if (a[i]) {
5253                 break;
5254             }
5255         }
5256         return i - idx;
5257     }
5258 
5259     @Test(dataProvider = "maskProvider")
5260     static void maskLastTrueDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5261         boolean[] a = fa.apply(SPECIES.length());
5262         int[] r = new int[a.length];
5263 
5264         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5265             for (int i = 0; i < a.length; i += SPECIES.length()) {
5266                 var vmask = SPECIES.loadMask(a, i);
5267                 r[i] = vmask.lastTrue();
5268             }
5269         }
5270 
5271         assertMaskReductionArraysEquals(r, a, DoubleMaxVectorTests::maskLastTrue);
5272     }
5273 
5274     static int maskFirstTrue(boolean[] a, int idx) {
5275         int i = idx;
5276         for (; i < idx + SPECIES.length(); i++) {
5277             if (a[i]) {
5278                 break;
5279             }
5280         }
5281         return i - idx;
5282     }
5283 
5284     @Test(dataProvider = "maskProvider")
5285     static void maskFirstTrueDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5286         boolean[] a = fa.apply(SPECIES.length());
5287         int[] r = new int[a.length];
5288 
5289         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5290             for (int i = 0; i < a.length; i += SPECIES.length()) {
5291                 var vmask = SPECIES.loadMask(a, i);
5292                 r[i] = vmask.firstTrue();
5293             }
5294         }
5295 
5296         assertMaskReductionArraysEquals(r, a, DoubleMaxVectorTests::maskFirstTrue);
5297     }
5298 
5299     @Test(dataProvider = "maskProvider")
5300     static void maskCompressDoubleMaxVectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5301         int trueCount = 0;
5302         boolean[] a = fa.apply(SPECIES.length());
5303 
5304         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5305             for (int i = 0; i < a.length; i += SPECIES.length()) {
5306                 var vmask = SPECIES.loadMask(a, i);
5307                 trueCount = vmask.trueCount();
5308                 var rmask = vmask.compress();
5309                 for (int j = 0; j < SPECIES.length(); j++)  {
5310                     Assert.assertEquals(rmask.laneIsSet(j), j < trueCount);
5311                 }
5312             }
5313         }
5314     }
5315 
5316 
5317     @DataProvider
5318     public static Object[][] offsetProvider() {
5319         return new Object[][]{
5320                 {0},
5321                 {-1},
5322                 {+1},
5323                 {+2},
5324                 {-2},
5325         };
5326     }
5327 
5328     @Test(dataProvider = "offsetProvider")
5329     static void indexInRangeDoubleMaxVectorTestsSmokeTest(int offset) {
5330         int limit = SPECIES.length() * BUFFER_REPS;
5331         for (int i = 0; i < limit; i += SPECIES.length()) {
5332             var actualMask = SPECIES.indexInRange(i + offset, limit);
5333             var expectedMask = SPECIES.maskAll(true).indexInRange(i + offset, limit);
5334             assert(actualMask.equals(expectedMask));
5335             for (int j = 0; j < SPECIES.length(); j++)  {
5336                 int index = i + j + offset;
5337                 Assert.assertEquals(actualMask.laneIsSet(j), index >= 0 && index < limit);
5338             }
5339         }
5340     }
5341 
5342     @Test(dataProvider = "offsetProvider")
5343     static void indexInRangeLongDoubleMaxVectorTestsSmokeTest(int offset) {
5344         long limit = SPECIES.length() * BUFFER_REPS;
5345         for (long i = 0; i < limit; i += SPECIES.length()) {
5346             var actualMask = SPECIES.indexInRange(i + offset, limit);
5347             var expectedMask = SPECIES.maskAll(true).indexInRange(i + offset, limit);
5348             assert(actualMask.equals(expectedMask));
5349             for (int j = 0; j < SPECIES.length(); j++)  {
5350                 long index = i + j + offset;
5351                 Assert.assertEquals(actualMask.laneIsSet(j), index >= 0 && index < limit);
5352             }
5353         }
5354     }
5355 
5356     @DataProvider
5357     public static Object[][] lengthProvider() {
5358         return new Object[][]{
5359                 {0},
5360                 {1},
5361                 {32},
5362                 {37},
5363                 {1024},
5364                 {1024+1},
5365                 {1024+5},
5366         };
5367     }
5368 
5369     @Test(dataProvider = "lengthProvider")
5370     static void loopBoundDoubleMaxVectorTestsSmokeTest(int length) {
5371         int actualLoopBound = SPECIES.loopBound(length);
5372         int expectedLoopBound = length - Math.floorMod(length, SPECIES.length());
5373         Assert.assertEquals(actualLoopBound, expectedLoopBound);
5374     }
5375 
5376     @Test(dataProvider = "lengthProvider")
5377     static void loopBoundLongDoubleMaxVectorTestsSmokeTest(int _length) {
5378         long length = _length;
5379         long actualLoopBound = SPECIES.loopBound(length);
5380         long expectedLoopBound = length - Math.floorMod(length, SPECIES.length());
5381         Assert.assertEquals(actualLoopBound, expectedLoopBound);
5382     }
5383 
5384     @Test
5385     static void ElementSizeDoubleMaxVectorTestsSmokeTest() {
5386         DoubleVector av = DoubleVector.zero(SPECIES);
5387         int elsize = av.elementSize();
5388         Assert.assertEquals(elsize, Double.SIZE);
5389     }
5390 
5391     @Test
5392     static void VectorShapeDoubleMaxVectorTestsSmokeTest() {
5393         DoubleVector av = DoubleVector.zero(SPECIES);
5394         VectorShape vsh = av.shape();
5395         assert(vsh.equals(VectorShape.S_Max_BIT));
5396     }
5397 
5398     @Test
5399     static void ShapeWithLanesDoubleMaxVectorTestsSmokeTest() {
5400         DoubleVector av = DoubleVector.zero(SPECIES);
5401         VectorShape vsh = av.shape();
5402         VectorSpecies species = vsh.withLanes(double.class);
5403         assert(species.equals(SPECIES));
5404     }
5405 
5406     @Test
5407     static void ElementTypeDoubleMaxVectorTestsSmokeTest() {
5408         DoubleVector av = DoubleVector.zero(SPECIES);
5409         assert(av.species().elementType() == double.class);
5410     }
5411 
5412     @Test
5413     static void SpeciesElementSizeDoubleMaxVectorTestsSmokeTest() {
5414         DoubleVector av = DoubleVector.zero(SPECIES);
5415         assert(av.species().elementSize() == Double.SIZE);
5416     }
5417 
5418     @Test
5419     static void VectorTypeDoubleMaxVectorTestsSmokeTest() {
5420         DoubleVector av = DoubleVector.zero(SPECIES);
5421         assert(av.species().vectorType() == av.getClass());
5422     }
5423 
5424     @Test
5425     static void WithLanesDoubleMaxVectorTestsSmokeTest() {
5426         DoubleVector av = DoubleVector.zero(SPECIES);
5427         VectorSpecies species = av.species().withLanes(double.class);
5428         assert(species.equals(SPECIES));
5429     }
5430 
5431     @Test
5432     static void WithShapeDoubleMaxVectorTestsSmokeTest() {
5433         DoubleVector av = DoubleVector.zero(SPECIES);
5434         VectorShape vsh = av.shape();
5435         VectorSpecies species = av.species().withShape(vsh);
5436         assert(species.equals(SPECIES));
5437     }
5438 
5439     @Test
5440     static void MaskAllTrueDoubleMaxVectorTestsSmokeTest() {
5441         for (int ic = 0; ic < INVOC_COUNT; ic++) {
5442           Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length()));
5443         }
5444     }
5445 }