1 /*
2  * Copyright (c) 2018, 2021, 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  * @modules jdk.incubator.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation
27  * @run testng/othervm -XX:-TieredCompilation Double256VectorLoadStoreTests
28  *
29  */
30 
31 // -- This file was mechanically generated: Do not edit! -- //
32 
33 import jdk.incubator.vector.DoubleVector;
34 import jdk.incubator.vector.VectorMask;
35 import jdk.incubator.vector.VectorSpecies;
36 import jdk.incubator.vector.VectorShuffle;
37 import jdk.internal.vm.annotation.DontInline;
38 import org.testng.Assert;
39 import org.testng.annotations.DataProvider;
40 import org.testng.annotations.Test;
41 
42 import java.nio.ByteBuffer;
43 import java.nio.DoubleBuffer;
44 import java.nio.ByteOrder;
45 import java.nio.ReadOnlyBufferException;
46 import java.util.List;
47 import java.util.function.*;
48 
49 @Test
50 public class Double256VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
51     static final VectorSpecies<Double> SPECIES =
52                 DoubleVector.SPECIES_256;
53 
54     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
55 
56 
57     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 256);
58 
assertArraysEquals(double[] r, double[] a, boolean[] mask)59     static void assertArraysEquals(double[] r, double[] a, boolean[] mask) {
60         int i = 0;
61         try {
62             for (; i < a.length; i++) {
63                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0);
64             }
65         } catch (AssertionError e) {
66             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0, "at index #" + i);
67         }
68     }
69 
assertArraysEquals(byte[] r, byte[] a, boolean[] mask)70     static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
71         int i = 0;
72         try {
73             for (; i < a.length; i++) {
74                 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0);
75             }
76         } catch (AssertionError e) {
77             Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
78         }
79     }
80 
81     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
82             withToString("double[i * 5]", (int s) -> {
83                 return fill(s * BUFFER_REPS,
84                             i -> (double)(i * 5));
85             }),
86             withToString("double[i + 1]", (int s) -> {
87                 return fill(s * BUFFER_REPS,
88                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
89             })
90     );
91 
92     // Relative to array.length
93     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
94             withToString("-1", (int l) -> {
95                 return -1;
96             }),
97             withToString("l", (int l) -> {
98                 return l;
99             }),
100             withToString("l - 1", (int l) -> {
101                 return l - 1;
102             }),
103             withToString("l + 1", (int l) -> {
104                 return l + 1;
105             }),
106             withToString("l - speciesl + 1", (int l) -> {
107                 return l - SPECIES.length() + 1;
108             }),
109             withToString("l + speciesl - 1", (int l) -> {
110                 return l + SPECIES.length() - 1;
111             }),
112             withToString("l + speciesl", (int l) -> {
113                 return l + SPECIES.length();
114             }),
115             withToString("l + speciesl + 1", (int l) -> {
116                 return l + SPECIES.length() + 1;
117             })
118     );
119 
120     // Relative to byte[] array.length or ByteBuffer.limit()
121     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
122             withToString("-1", (int l) -> {
123                 return -1;
124             }),
125             withToString("l", (int l) -> {
126                 return l;
127             }),
128             withToString("l - 1", (int l) -> {
129                 return l - 1;
130             }),
131             withToString("l + 1", (int l) -> {
132                 return l + 1;
133             }),
134             withToString("l - speciesl*ebsize + 1", (int l) -> {
135                 return l - SPECIES.vectorByteSize() + 1;
136             }),
137             withToString("l + speciesl*ebsize - 1", (int l) -> {
138                 return l + SPECIES.vectorByteSize() - 1;
139             }),
140             withToString("l + speciesl*ebsize", (int l) -> {
141                 return l + SPECIES.vectorByteSize();
142             }),
143             withToString("l + speciesl*ebsize + 1", (int l) -> {
144                 return l + SPECIES.vectorByteSize() + 1;
145             })
146     );
147 
148     @DataProvider
doubleProvider()149     public Object[][] doubleProvider() {
150         return DOUBLE_GENERATORS.stream().
151                 map(f -> new Object[]{f}).
152                 toArray(Object[][]::new);
153     }
154 
155     @DataProvider
maskProvider()156     public Object[][] maskProvider() {
157         return BOOLEAN_MASK_GENERATORS.stream().
158                 map(f -> new Object[]{f}).
159                 toArray(Object[][]::new);
160     }
161 
162     @DataProvider
doubleProviderForIOOBE()163     public Object[][] doubleProviderForIOOBE() {
164         var f = DOUBLE_GENERATORS.get(0);
165         return INDEX_GENERATORS.stream().map(fi -> {
166                     return new Object[] {f, fi};
167                 }).
168                 toArray(Object[][]::new);
169     }
170 
171     @DataProvider
doubleMaskProvider()172     public Object[][] doubleMaskProvider() {
173         return BOOLEAN_MASK_GENERATORS.stream().
174                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
175                     return new Object[] {fa, fm};
176                 })).
177                 toArray(Object[][]::new);
178     }
179 
180     @DataProvider
181     public Object[][] doubleMaskProviderForIOOBE() {
182         var f = DOUBLE_GENERATORS.get(0);
183         return BOOLEAN_MASK_GENERATORS.stream().
184                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
185                     return new Object[] {f, fi, fm};
186                 })).
187                 toArray(Object[][]::new);
188     }
189 
190     @DataProvider
191     public Object[][] doubleByteBufferProvider() {
192         return DOUBLE_GENERATORS.stream().
193                 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
194                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
195                             return new Object[]{fa, fb, bo};
196                         }))).
197                 toArray(Object[][]::new);
198     }
199 
200     @DataProvider
201     public Object[][] doubleByteBufferMaskProvider() {
202         return BOOLEAN_MASK_GENERATORS.stream().
203                 flatMap(fm -> DOUBLE_GENERATORS.stream().
204                         flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
205                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
206                             return new Object[]{fa, fb, fm, bo};
207                         })))).
208                 toArray(Object[][]::new);
209     }
210 
211     @DataProvider
212     public Object[][] doubleByteArrayProvider() {
213         return DOUBLE_GENERATORS.stream().
214                 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
215                     return new Object[]{fa, bo};
216                 })).
217                 toArray(Object[][]::new);
218     }
219 
220     @DataProvider
221     public Object[][] doubleByteArrayMaskProvider() {
222         return BOOLEAN_MASK_GENERATORS.stream().
223                 flatMap(fm -> DOUBLE_GENERATORS.stream().
224                     flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
225                         return new Object[]{fa, fm, bo};
226                     }))).
227                 toArray(Object[][]::new);
228     }
229 
230     @DataProvider
231     public Object[][] doubleByteProviderForIOOBE() {
232         var f = DOUBLE_GENERATORS.get(0);
233         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
234                     return new Object[] {f, fi};
235                 }).
236                 toArray(Object[][]::new);
237     }
238 
239     @DataProvider
240     public Object[][] doubleByteMaskProviderForIOOBE() {
241         var f = DOUBLE_GENERATORS.get(0);
242         return BOOLEAN_MASK_GENERATORS.stream().
243                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
244                     return new Object[] {f, fi, fm};
245                 })).
246                 toArray(Object[][]::new);
247     }
248 
249     static ByteBuffer toBuffer(double[] a, IntFunction<ByteBuffer> fb) {
250         ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
251         for (double v : a) {
252             bb.putDouble(v);
253         }
254         return bb.clear();
255     }
256 
257     static double[] bufferToArray(ByteBuffer bb) {
258         DoubleBuffer db = bb.asDoubleBuffer();
259         double[] d = new double[db.capacity()];
260         db.get(0, d);
261         return d;
262     }
263 
264     static byte[] toByteArray(double[] a, IntFunction<byte[]> fb, ByteOrder bo) {
265         byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
266         DoubleBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).asDoubleBuffer();
267         for (double v : a) {
268             bb.put(v);
269         }
270         return b;
271     }
272 
273 
274     interface ToDoubleF {
275         double apply(int i);
276     }
277 
278     static double[] fill(int s , ToDoubleF f) {
279         return fill(new double[s], f);
280     }
281 
282     static double[] fill(double[] a, ToDoubleF f) {
283         for (int i = 0; i < a.length; i++) {
284             a[i] = f.apply(i);
285         }
286         return a;
287     }
288 
289     @DontInline
290     static DoubleVector fromArray(double[] a, int i) {
291         return DoubleVector.fromArray(SPECIES, a, i);
292     }
293 
294     @DontInline
295     static DoubleVector fromArray(double[] a, int i, VectorMask<Double> m) {
296         return DoubleVector.fromArray(SPECIES, a, i, m);
297     }
298 
299     @DontInline
300     static void intoArray(DoubleVector v, double[] a, int i) {
301         v.intoArray(a, i);
302     }
303 
304     @DontInline
305     static void intoArray(DoubleVector v, double[] a, int i, VectorMask<Double> m) {
306         v.intoArray(a, i, m);
307     }
308 
309     @DontInline
310     static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo) {
311         return DoubleVector.fromByteArray(SPECIES, a, i, bo);
312     }
313 
314     @DontInline
315     static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Double> m) {
316         return DoubleVector.fromByteArray(SPECIES, a, i, bo, m);
317     }
318 
319     @DontInline
320     static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo) {
321         v.intoByteArray(a, i, bo);
322     }
323 
324     @DontInline
325     static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo, VectorMask<Double> m) {
326         v.intoByteArray(a, i, bo, m);
327     }
328 
329     @DontInline
330     static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
331         return DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
332     }
333 
334     @DontInline
335     static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) {
336         return DoubleVector.fromByteBuffer(SPECIES, a, i, bo, m);
337     }
338 
339     @DontInline
340     static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo) {
341         v.intoByteBuffer(a, i, bo);
342     }
343 
344     @DontInline
345     static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) {
346         v.intoByteBuffer(a, i, bo, m);
347     }
348 
349 
350     @Test(dataProvider = "doubleProvider")
351     static void loadStoreArray(IntFunction<double[]> fa) {
352         double[] a = fa.apply(SPECIES.length());
353         double[] r = new double[a.length];
354 
355         for (int ic = 0; ic < INVOC_COUNT; ic++) {
356             for (int i = 0; i < a.length; i += SPECIES.length()) {
357                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
358                 av.intoArray(r, i);
359             }
360         }
361         Assert.assertEquals(r, a);
362     }
363 
364     @Test(dataProvider = "doubleProviderForIOOBE")
365     static void loadArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
366         double[] a = fa.apply(SPECIES.length());
367         double[] r = new double[a.length];
368 
369         for (int ic = 0; ic < INVOC_COUNT; ic++) {
370             for (int i = 0; i < a.length; i += SPECIES.length()) {
371                 DoubleVector av = fromArray(a, i);
372                 av.intoArray(r, i);
373             }
374         }
375 
376         int index = fi.apply(a.length);
377         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
378         try {
379             fromArray(a, index);
380             if (shouldFail) {
381                 Assert.fail("Failed to throw IndexOutOfBoundsException");
382             }
383         } catch (IndexOutOfBoundsException e) {
384             if (!shouldFail) {
385                 Assert.fail("Unexpected IndexOutOfBoundsException");
386             }
387         }
388     }
389 
390     @Test(dataProvider = "doubleProviderForIOOBE")
391     static void storeArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
392         double[] a = fa.apply(SPECIES.length());
393         double[] r = new double[a.length];
394 
395         for (int ic = 0; ic < INVOC_COUNT; ic++) {
396             for (int i = 0; i < a.length; i += SPECIES.length()) {
397                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
398                 intoArray(av, r, i);
399             }
400         }
401 
402         int index = fi.apply(a.length);
403         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
404         try {
405             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
406             intoArray(av, r, index);
407             if (shouldFail) {
408                 Assert.fail("Failed to throw IndexOutOfBoundsException");
409             }
410         } catch (IndexOutOfBoundsException e) {
411             if (!shouldFail) {
412                 Assert.fail("Unexpected IndexOutOfBoundsException");
413             }
414         }
415     }
416 
417 
418     @Test(dataProvider = "doubleMaskProvider")
419     static void loadStoreMaskArray(IntFunction<double[]> fa,
420                                    IntFunction<boolean[]> fm) {
421         double[] a = fa.apply(SPECIES.length());
422         double[] r = new double[a.length];
423         boolean[] mask = fm.apply(SPECIES.length());
424         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
425 
426         for (int ic = 0; ic < INVOC_COUNT; ic++) {
427             for (int i = 0; i < a.length; i += SPECIES.length()) {
428                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask);
429                 av.intoArray(r, i);
430             }
431         }
432         assertArraysEquals(r, a, mask);
433 
434 
435         r = new double[a.length];
436 
437         for (int ic = 0; ic < INVOC_COUNT; ic++) {
438             for (int i = 0; i < a.length; i += SPECIES.length()) {
439                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
440                 av.intoArray(r, i, vmask);
441             }
442         }
443         assertArraysEquals(r, a, mask);
444     }
445 
446     @Test(dataProvider = "doubleMaskProviderForIOOBE")
447     static void loadArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
448         double[] a = fa.apply(SPECIES.length());
449         double[] r = new double[a.length];
450         boolean[] mask = fm.apply(SPECIES.length());
451         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
452 
453         for (int ic = 0; ic < INVOC_COUNT; ic++) {
454             for (int i = 0; i < a.length; i += SPECIES.length()) {
455                 DoubleVector av = fromArray(a, i, vmask);
456                 av.intoArray(r, i);
457             }
458         }
459 
460         int index = fi.apply(a.length);
461         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
462         try {
463             fromArray(a, index, vmask);
464             if (shouldFail) {
465                 Assert.fail("Failed to throw IndexOutOfBoundsException");
466             }
467         } catch (IndexOutOfBoundsException e) {
468             if (!shouldFail) {
469                 Assert.fail("Unexpected IndexOutOfBoundsException");
470             }
471         }
472     }
473 
474     @Test(dataProvider = "doubleMaskProviderForIOOBE")
475     static void storeArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
476         double[] a = fa.apply(SPECIES.length());
477         double[] r = new double[a.length];
478         boolean[] mask = fm.apply(SPECIES.length());
479         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
480 
481         for (int ic = 0; ic < INVOC_COUNT; ic++) {
482             for (int i = 0; i < a.length; i += SPECIES.length()) {
483                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
484                 intoArray(av, r, i, vmask);
485             }
486         }
487 
488         int index = fi.apply(a.length);
489         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
490         try {
491             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
492             intoArray(av, a, index, vmask);
493             if (shouldFail) {
494                 Assert.fail("Failed to throw IndexOutOfBoundsException");
495             }
496         } catch (IndexOutOfBoundsException e) {
497             if (!shouldFail) {
498                 Assert.fail("Unexpected IndexOutOfBoundsException");
499             }
500         }
501     }
502 
503 
504     @Test(dataProvider = "doubleMaskProvider")
505     static void loadStoreMask(IntFunction<double[]> fa,
506                               IntFunction<boolean[]> fm) {
507         boolean[] mask = fm.apply(SPECIES.length());
508         boolean[] r = new boolean[mask.length];
509 
510         for (int ic = 0; ic < INVOC_COUNT; ic++) {
511             for (int i = 0; i < mask.length; i += SPECIES.length()) {
512                 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, i);
513                 vmask.intoArray(r, i);
514             }
515         }
516         Assert.assertEquals(r, mask);
517     }
518 
519 
520     @Test(dataProvider = "doubleByteBufferProvider")
521     static void loadStoreByteBuffer(IntFunction<double[]> fa,
522                                     IntFunction<ByteBuffer> fb,
523                                     ByteOrder bo) {
524         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
525         ByteBuffer r = fb.apply(a.limit());
526 
527         int l = a.limit();
528         int s = SPECIES.vectorByteSize();
529 
530         for (int ic = 0; ic < INVOC_COUNT; ic++) {
531             for (int i = 0; i < l; i += s) {
532                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
533                 av.intoByteBuffer(r, i, bo);
534             }
535         }
536         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
537         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
538         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
539         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
540         Assert.assertEquals(r, a, "Buffers not equal");
541     }
542 
543     @Test(dataProvider = "doubleByteProviderForIOOBE")
544     static void loadByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
545         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
546         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
547 
548         int l = a.limit();
549         int s = SPECIES.vectorByteSize();
550 
551         for (int ic = 0; ic < INVOC_COUNT; ic++) {
552             for (int i = 0; i < l; i += s) {
553                 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
554                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
555             }
556         }
557 
558         int index = fi.apply(a.limit());
559         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
560         try {
561             fromByteBuffer(a, index, ByteOrder.nativeOrder());
562             if (shouldFail) {
563                 Assert.fail("Failed to throw IndexOutOfBoundsException");
564             }
565         } catch (IndexOutOfBoundsException e) {
566             if (!shouldFail) {
567                 Assert.fail("Unexpected IndexOutOfBoundsException");
568             }
569         }
570     }
571 
572     @Test(dataProvider = "doubleByteProviderForIOOBE")
573     static void storeByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
574         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
575         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
576 
577         int l = a.limit();
578         int s = SPECIES.vectorByteSize();
579 
580         for (int ic = 0; ic < INVOC_COUNT; ic++) {
581             for (int i = 0; i < l; i += s) {
582                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
583                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
584             }
585         }
586 
587         int index = fi.apply(a.limit());
588         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
589         try {
590             DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
591             intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
592             if (shouldFail) {
593                 Assert.fail("Failed to throw IndexOutOfBoundsException");
594             }
595         } catch (IndexOutOfBoundsException e) {
596             if (!shouldFail) {
597                 Assert.fail("Unexpected IndexOutOfBoundsException");
598             }
599         }
600     }
601 
602 
603     @Test(dataProvider = "doubleByteBufferMaskProvider")
604     static void loadStoreByteBufferMask(IntFunction<double[]> fa,
605                                         IntFunction<ByteBuffer> fb,
606                                         IntFunction<boolean[]> fm,
607                                         ByteOrder bo) {
608         double[] _a = fa.apply(SPECIES.length());
609         ByteBuffer a = toBuffer(_a, fb);
610         ByteBuffer r = fb.apply(a.limit());
611         boolean[] mask = fm.apply(SPECIES.length());
612         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
613 
614         int l = a.limit();
615         int s = SPECIES.vectorByteSize();
616 
617         for (int ic = 0; ic < INVOC_COUNT; ic++) {
618             for (int i = 0; i < l; i += s) {
619                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
620                 av.intoByteBuffer(r, i, bo);
621             }
622         }
623         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
624         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
625         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
626         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
627         assertArraysEquals(bufferToArray(r), _a, mask);
628 
629 
630         r = fb.apply(a.limit());
631 
632         for (int ic = 0; ic < INVOC_COUNT; ic++) {
633             for (int i = 0; i < l; i += s) {
634                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo);
635                 av.intoByteBuffer(r, i, bo, vmask);
636             }
637         }
638         Assert.assertEquals(a.position(), 0, "Input buffer position changed");
639         Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
640         Assert.assertEquals(r.position(), 0, "Result buffer position changed");
641         Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
642         assertArraysEquals(bufferToArray(r), _a, mask);
643     }
644 
645     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
646     static void loadByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
647         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
648         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
649         boolean[] mask = fm.apply(SPECIES.length());
650         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
651 
652         int l = a.limit();
653         int s = SPECIES.vectorByteSize();
654 
655         for (int ic = 0; ic < INVOC_COUNT; ic++) {
656             for (int i = 0; i < l; i += s) {
657                 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
658                 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
659             }
660         }
661 
662         int index = fi.apply(a.limit());
663         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
664         try {
665             fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
666             if (shouldFail) {
667                 Assert.fail("Failed to throw IndexOutOfBoundsException");
668             }
669         } catch (IndexOutOfBoundsException e) {
670             if (!shouldFail) {
671                 Assert.fail("Unexpected IndexOutOfBoundsException");
672             }
673         }
674     }
675 
676     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
677     static void storeByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
678         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
679         ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
680         boolean[] mask = fm.apply(SPECIES.length());
681         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
682 
683         int l = a.limit();
684         int s = SPECIES.vectorByteSize();
685 
686         for (int ic = 0; ic < INVOC_COUNT; ic++) {
687             for (int i = 0; i < l; i += s) {
688                 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
689                 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
690             }
691         }
692 
693         int index = fi.apply(a.limit());
694         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
695         try {
696             DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
697             intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
698             if (shouldFail) {
699                 Assert.fail("Failed to throw IndexOutOfBoundsException");
700             }
701         } catch (IndexOutOfBoundsException e) {
702             if (!shouldFail) {
703                 Assert.fail("Unexpected IndexOutOfBoundsException");
704             }
705         }
706     }
707 
708 
709     @Test(dataProvider = "doubleByteBufferProvider")
710     static void loadStoreReadonlyByteBuffer(IntFunction<double[]> fa,
711                                     IntFunction<ByteBuffer> fb,
712                                     ByteOrder bo) {
713         ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
714 
715         try {
716             SPECIES.zero().intoByteBuffer(a, 0, bo);
717             Assert.fail("ReadOnlyBufferException expected");
718         } catch (ReadOnlyBufferException e) {
719         }
720 
721         try {
722             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
723             Assert.fail("ReadOnlyBufferException expected");
724         } catch (ReadOnlyBufferException e) {
725         }
726 
727         try {
728             SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
729             Assert.fail("ReadOnlyBufferException expected");
730         } catch (ReadOnlyBufferException e) {
731         }
732 
733         try {
734             VectorMask<Double> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
735                     .laneIsValid();
736             SPECIES.zero().intoByteBuffer(a, 0, bo, m);
737             Assert.fail("ReadOnlyBufferException expected");
738         } catch (ReadOnlyBufferException e) {
739         }
740     }
741 
742 
743     @Test(dataProvider = "doubleByteArrayProvider")
744     static void loadStoreByteArray(IntFunction<double[]> fa,
745                                     ByteOrder bo) {
746         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
747         byte[] r = new byte[a.length];
748 
749         int s = SPECIES.vectorByteSize();
750         int l = a.length;
751 
752         for (int ic = 0; ic < INVOC_COUNT; ic++) {
753             for (int i = 0; i < l; i += s) {
754                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo);
755                 av.intoByteArray(r, i, bo);
756             }
757         }
758         Assert.assertEquals(r, a, "Byte arrays not equal");
759     }
760 
761     @Test(dataProvider = "doubleByteProviderForIOOBE")
762     static void loadByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
763         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
764         byte[] r = new byte[a.length];
765 
766         int s = SPECIES.vectorByteSize();
767         int l = a.length;
768 
769         for (int ic = 0; ic < INVOC_COUNT; ic++) {
770             for (int i = 0; i < l; i += s) {
771                 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
772                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
773             }
774         }
775 
776         int index = fi.apply(a.length);
777         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
778         try {
779             fromByteArray(a, index, ByteOrder.nativeOrder());
780             if (shouldFail) {
781                 Assert.fail("Failed to throw IndexOutOfBoundsException");
782             }
783         } catch (IndexOutOfBoundsException e) {
784             if (!shouldFail) {
785                 Assert.fail("Unexpected IndexOutOfBoundsException");
786             }
787         }
788     }
789 
790     @Test(dataProvider = "doubleByteProviderForIOOBE")
791     static void storeByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
792         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
793         byte[] r = new byte[a.length];
794 
795         int s = SPECIES.vectorByteSize();
796         int l = a.length;
797 
798         for (int ic = 0; ic < INVOC_COUNT; ic++) {
799             for (int i = 0; i < l; i += s) {
800                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
801                 intoByteArray(av, r, i, ByteOrder.nativeOrder());
802             }
803         }
804 
805         int index = fi.apply(a.length);
806         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
807         try {
808             DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
809             intoByteArray(av, r, index, ByteOrder.nativeOrder());
810             if (shouldFail) {
811                 Assert.fail("Failed to throw IndexOutOfBoundsException");
812             }
813         } catch (IndexOutOfBoundsException e) {
814             if (!shouldFail) {
815                 Assert.fail("Unexpected IndexOutOfBoundsException");
816             }
817         }
818     }
819 
820 
821     @Test(dataProvider = "doubleByteArrayMaskProvider")
822     static void loadStoreByteArrayMask(IntFunction<double[]> fa,
823                                   IntFunction<boolean[]> fm,
824                                   ByteOrder bo) {
825         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
826         byte[] r = new byte[a.length];
827         boolean[] mask = fm.apply(SPECIES.length());
828         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
829 
830         int s = SPECIES.vectorByteSize();
831         int l = a.length;
832 
833         for (int ic = 0; ic < INVOC_COUNT; ic++) {
834           for (int i = 0; i < l; i += s) {
835               DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo, vmask);
836               av.intoByteArray(r, i, bo);
837           }
838         }
839         assertArraysEquals(r, a, mask);
840 
841 
842         r = new byte[a.length];
843 
844         for (int ic = 0; ic < INVOC_COUNT; ic++) {
845             for (int i = 0; i < l; i += s) {
846                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo);
847                 av.intoByteArray(r, i, bo, vmask);
848             }
849         }
850         assertArraysEquals(r, a, mask);
851     }
852 
853     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
854     static void loadByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
855         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
856         byte[] r = new byte[a.length];
857         boolean[] mask = fm.apply(SPECIES.length());
858         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
859 
860         int s = SPECIES.vectorByteSize();
861         int l = a.length;
862 
863         for (int ic = 0; ic < INVOC_COUNT; ic++) {
864             for (int i = 0; i < l; i += s) {
865                 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
866                 av.intoByteArray(r, i, ByteOrder.nativeOrder());
867             }
868         }
869 
870         int index = fi.apply(a.length);
871         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
872         try {
873             fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
874             if (shouldFail) {
875                 Assert.fail("Failed to throw IndexOutOfBoundsException");
876             }
877         } catch (IndexOutOfBoundsException e) {
878             if (!shouldFail) {
879                 Assert.fail("Unexpected IndexOutOfBoundsException");
880             }
881         }
882     }
883 
884     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
885     static void storeByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
886         byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
887         byte[] r = new byte[a.length];
888         boolean[] mask = fm.apply(SPECIES.length());
889         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
890 
891         int s = SPECIES.vectorByteSize();
892         int l = a.length;
893 
894         for (int ic = 0; ic < INVOC_COUNT; ic++) {
895             for (int i = 0; i < l; i += s) {
896                 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
897                 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
898             }
899         }
900 
901         int index = fi.apply(a.length);
902         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
903         try {
904             DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
905             intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
906             if (shouldFail) {
907                 Assert.fail("Failed to throw IndexOutOfBoundsException");
908             }
909         } catch (IndexOutOfBoundsException e) {
910             if (!shouldFail) {
911                 Assert.fail("Unexpected IndexOutOfBoundsException");
912             }
913         }
914     }
915 
916     @Test(dataProvider = "maskProvider")
917     static void loadStoreMask(IntFunction<boolean[]> fm) {
918         boolean[] a = fm.apply(SPECIES.length());
919         boolean[] r = new boolean[a.length];
920 
921         for (int ic = 0; ic < INVOC_COUNT; ic++) {
922             for (int i = 0; i < a.length; i += SPECIES.length()) {
923                 VectorMask<Double> vmask = SPECIES.loadMask(a, i);
924                 vmask.intoArray(r, i);
925             }
926         }
927         Assert.assertEquals(r, a);
928     }
929 
930     @Test
931     static void loadStoreShuffle() {
932         IntUnaryOperator fn = a -> a + 5;
933         for (int ic = 0; ic < INVOC_COUNT; ic++) {
934             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
935             int [] r = shuffle.toArray();
936 
937             int [] a = expectedShuffle(SPECIES.length(), fn);
938             Assert.assertEquals(r, a);
939        }
940     }
941 
942 
943 
944 
945 
946     // Gather/Scatter load/store tests
947 
948     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap) {
949         int i = 0;
950         int j = 0;
951         try {
952             for (; i < a.length; i += SPECIES.length()) {
953                 j = i;
954                 for (; j < i + SPECIES.length(); j++) {
955                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
956                 }
957             }
958         } catch (AssertionError e) {
959             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
960         }
961     }
962 
963     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
964         int i = 0;
965         int j = 0;
966         try {
967             for (; i < a.length; i += SPECIES.length()) {
968                 j = i;
969                 for (; j < i + SPECIES.length(); j++) {
970                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0);
971                 }
972             }
973         } catch (AssertionError e) {
974             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0, "at index #" + j);
975         }
976     }
977 
978     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
979         double[] expected = new double[r.length];
980 
981         // Store before checking, since the same location may be stored to more than once
982         for (int i = 0; i < a.length; i += SPECIES.length()) {
983             for (int j = i; j < i + SPECIES.length(); j++) {
984                 if (mask[j % SPECIES.length()]) {
985                     expected[i + indexMap[j]] = a[j];
986                 }
987             }
988         }
989 
990         Assert.assertEquals(r, expected);
991     }
992 
993     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap) {
994         double[] expected = new double[r.length];
995 
996         // Store before checking, since the same location may be stored to more than once
997         for (int i = 0; i < a.length; i += SPECIES.length()) {
998             for (int j = i; j < i + SPECIES.length(); j++) {
999                 expected[i + indexMap[j]] = a[j];
1000             }
1001         }
1002 
1003         Assert.assertEquals(r, expected);
1004     }
1005 
1006     @DataProvider
1007     public Object[][] gatherScatterProvider() {
1008         return INT_INDEX_GENERATORS.stream().
1009                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1010                     return new Object[] {fa, fs};
1011                 })).
1012                 toArray(Object[][]::new);
1013     }
1014 
1015     @DataProvider
1016     public Object[][] gatherScatterMaskProvider() {
1017         return BOOLEAN_MASK_GENERATORS.stream().
1018           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
1019             DOUBLE_GENERATORS.stream().map(fa -> {
1020                     return new Object[] {fa, fm, fs};
1021             }))).
1022             toArray(Object[][]::new);
1023     }
1024 
1025 
1026     @Test(dataProvider = "gatherScatterProvider")
1027     static void gather(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1028         double[] a = fa.apply(SPECIES.length());
1029         int[] b = fs.apply(a.length, SPECIES.length());
1030         double[] r = new double[a.length];
1031 
1032         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1033             for (int i = 0; i < a.length; i += SPECIES.length()) {
1034                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i);
1035                 av.intoArray(r, i);
1036             }
1037         }
1038 
1039         assertGatherArraysEquals(r, a, b);
1040     }
1041 
1042     @Test(dataProvider = "gatherScatterMaskProvider")
1043     static void gatherMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1044         double[] a = fa.apply(SPECIES.length());
1045         int[] b = fs.apply(a.length, SPECIES.length());
1046         double[] r = new double[a.length];
1047         boolean[] mask = fm.apply(SPECIES.length());
1048         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1049 
1050         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1051             for (int i = 0; i < a.length; i += SPECIES.length()) {
1052                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i, vmask);
1053                 av.intoArray(r, i);
1054             }
1055         }
1056 
1057         assertGatherArraysEquals(r, a, b, mask);
1058     }
1059 
1060     @Test(dataProvider = "gatherScatterProvider")
1061     static void scatter(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
1062         double[] a = fa.apply(SPECIES.length());
1063         int[] b = fs.apply(a.length, SPECIES.length());
1064         double[] r = new double[a.length];
1065 
1066         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1067             for (int i = 0; i < a.length; i += SPECIES.length()) {
1068                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1069                 av.intoArray(r, i, b, i);
1070             }
1071         }
1072 
1073         assertScatterArraysEquals(r, a, b);
1074     }
1075 
1076     @Test(dataProvider = "gatherScatterMaskProvider")
1077     static void scatterMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
1078         double[] a = fa.apply(SPECIES.length());
1079         int[] b = fs.apply(a.length, SPECIES.length());
1080         double[] r = new double[a.length];
1081         boolean[] mask = fm.apply(SPECIES.length());
1082         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1083 
1084         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1085             for (int i = 0; i < a.length; i += SPECIES.length()) {
1086                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1087                 av.intoArray(r, i, b, i, vmask);
1088             }
1089         }
1090 
1091         assertScatterArraysEquals(r, a, b, mask);
1092     }
1093 
1094 
1095 
1096 }
1097