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