1 /*
  2  * Copyright (c) 2018, 2022, 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 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
 28  *      -XX:-TieredCompilation DoubleMaxVectorLoadStoreTests
 29  *
 30  */
 31 
 32 // -- This file was mechanically generated: Do not edit! -- //
 33 
 34 import jdk.incubator.foreign.MemorySegment;
 35 import jdk.incubator.foreign.ResourceScope;
 36 import jdk.incubator.foreign.ValueLayout;
 37 import jdk.incubator.vector.DoubleVector;
 38 import jdk.incubator.vector.VectorMask;
 39 import jdk.incubator.vector.VectorShape;
 40 import jdk.incubator.vector.VectorSpecies;
 41 import jdk.incubator.vector.VectorShuffle;
 42 import jdk.internal.vm.annotation.DontInline;
 43 import org.testng.Assert;
 44 import org.testng.annotations.DataProvider;
 45 import org.testng.annotations.Test;
 46 




 47 import java.nio.ByteOrder;

 48 import java.util.List;
 49 import java.util.function.*;
 50 
 51 @Test
 52 public class DoubleMaxVectorLoadStoreTests extends AbstractVectorLoadStoreTest {
 53     static final VectorSpecies<Double> SPECIES =
 54                 DoubleVector.SPECIES_MAX;
 55 
 56     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
 57 
 58     static VectorShape getMaxBit() {
 59         return VectorShape.S_Max_BIT;
 60     }
 61 
 62     private static final int Max = 256;  // juts so we can do N/Max
 63 
 64     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / Max);
 65 
 66     static void assertArraysEquals(double[] r, double[] a, boolean[] mask) {
 67         int i = 0;
 68         try {
 69             for (; i < a.length; i++) {
 70                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0);
 71             }
 72         } catch (AssertionError e) {
 73             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0, "at index #" + i);
 74         }
 75     }
 76 











 77     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
 78             withToString("double[i * 5]", (int s) -> {
 79                 return fill(s * BUFFER_REPS,
 80                             i -> (double)(i * 5));
 81             }),
 82             withToString("double[i + 1]", (int s) -> {
 83                 return fill(s * BUFFER_REPS,
 84                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
 85             })
 86     );
 87 
 88     // Relative to array.length
 89     static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
 90             withToString("-1", (int l) -> {
 91                 return -1;
 92             }),
 93             withToString("l", (int l) -> {
 94                 return l;
 95             }),
 96             withToString("l - 1", (int l) -> {
 97                 return l - 1;
 98             }),
 99             withToString("l + 1", (int l) -> {
100                 return l + 1;
101             }),
102             withToString("l - speciesl + 1", (int l) -> {
103                 return l - SPECIES.length() + 1;
104             }),
105             withToString("l + speciesl - 1", (int l) -> {
106                 return l + SPECIES.length() - 1;
107             }),
108             withToString("l + speciesl", (int l) -> {
109                 return l + SPECIES.length();
110             }),
111             withToString("l + speciesl + 1", (int l) -> {
112                 return l + SPECIES.length() + 1;
113             })
114     );
115 
116     // Relative to byte[] array.length or MemorySegment.byteSize()
117     static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
118             withToString("-1", (int l) -> {
119                 return -1;
120             }),
121             withToString("l", (int l) -> {
122                 return l;
123             }),
124             withToString("l - 1", (int l) -> {
125                 return l - 1;
126             }),
127             withToString("l + 1", (int l) -> {
128                 return l + 1;
129             }),
130             withToString("l - speciesl*ebsize + 1", (int l) -> {
131                 return l - SPECIES.vectorByteSize() + 1;
132             }),
133             withToString("l + speciesl*ebsize - 1", (int l) -> {
134                 return l + SPECIES.vectorByteSize() - 1;
135             }),
136             withToString("l + speciesl*ebsize", (int l) -> {
137                 return l + SPECIES.vectorByteSize();
138             }),
139             withToString("l + speciesl*ebsize + 1", (int l) -> {
140                 return l + SPECIES.vectorByteSize() + 1;
141             })
142     );
143 
144     @DataProvider
145     public Object[][] doubleProvider() {
146         return DOUBLE_GENERATORS.stream().
147                 map(f -> new Object[]{f}).
148                 toArray(Object[][]::new);
149     }
150 
151     @DataProvider
152     public Object[][] maskProvider() {
153         return BOOLEAN_MASK_GENERATORS.stream().
154                 map(f -> new Object[]{f}).
155                 toArray(Object[][]::new);
156     }
157 
158     @DataProvider
159     public Object[][] doubleProviderForIOOBE() {
160         var f = DOUBLE_GENERATORS.get(0);
161         return INDEX_GENERATORS.stream().map(fi -> {
162                     return new Object[] {f, fi};
163                 }).
164                 toArray(Object[][]::new);
165     }
166 
167     @DataProvider
168     public Object[][] doubleMaskProvider() {
169         return BOOLEAN_MASK_GENERATORS.stream().
170                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
171                     return new Object[] {fa, fm};
172                 })).
173                 toArray(Object[][]::new);
174     }
175 
176     @DataProvider
177     public Object[][] doubleMaskProviderForIOOBE() {
178         var f = DOUBLE_GENERATORS.get(0);
179         return BOOLEAN_MASK_GENERATORS.stream().
180                 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
181                     return new Object[] {f, fi, fm};
182                 })).
183                 toArray(Object[][]::new);
184     }
185 
186     @DataProvider
187     public Object[][] doubleMemorySegmentProvider() {
188         return DOUBLE_GENERATORS.stream().
189                 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
190                         flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
191                             return new Object[]{fa, fb, bo};
192                         }))).
193                 toArray(Object[][]::new);
194     }
195 
196     @DataProvider
197     public Object[][] doubleMemorySegmentMaskProvider() {
198         return BOOLEAN_MASK_GENERATORS.stream().
199                 flatMap(fm -> DOUBLE_GENERATORS.stream().
200                         flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
201                                 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
202                             return new Object[]{fa, fb, fm, bo};
203                         })))).
204                 toArray(Object[][]::new);
205     }
206 



















207     @DataProvider
208     public Object[][] doubleByteProviderForIOOBE() {
209         var f = DOUBLE_GENERATORS.get(0);
210         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
211                     return new Object[] {f, fi};
212                 }).
213                 toArray(Object[][]::new);
214     }
215 
216     @DataProvider
217     public Object[][] doubleByteMaskProviderForIOOBE() {
218         var f = DOUBLE_GENERATORS.get(0);
219         return BOOLEAN_MASK_GENERATORS.stream().
220                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
221                     return new Object[] {f, fi, fm};
222                 })).
223                 toArray(Object[][]::new);
224     }
225 
226     static MemorySegment toSegment(double[] a, IntFunction<MemorySegment> fb) {
227         MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
228         for (int i = 0; i < a.length; i++) {
229             ms.set(ValueLayout.JAVA_DOUBLE, i * SPECIES.elementSize() / 8 , a[i]);
230         }
231         return ms;
232     }
233 
234     static double[] segmentToArray(MemorySegment ms) {
235         return ms.toArray(ValueLayout.JAVA_DOUBLE);












236     }
237 
238 
239     interface ToDoubleF {
240         double apply(int i);
241     }
242 
243     static double[] fill(int s , ToDoubleF f) {
244         return fill(new double[s], f);
245     }
246 
247     static double[] fill(double[] a, ToDoubleF f) {
248         for (int i = 0; i < a.length; i++) {
249             a[i] = f.apply(i);
250         }
251         return a;
252     }
253 
254     @DontInline
255     static DoubleVector fromArray(double[] a, int i) {
256         return DoubleVector.fromArray(SPECIES, a, i);
257     }
258 
259     @DontInline
260     static DoubleVector fromArray(double[] a, int i, VectorMask<Double> m) {
261         return DoubleVector.fromArray(SPECIES, a, i, m);
262     }
263 
264     @DontInline
265     static void intoArray(DoubleVector v, double[] a, int i) {
266         v.intoArray(a, i);
267     }
268 
269     @DontInline
270     static void intoArray(DoubleVector v, double[] a, int i, VectorMask<Double> m) {
271         v.intoArray(a, i, m);
272     }
273 
274     @DontInline
275     static DoubleVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
276         return DoubleVector.fromMemorySegment(SPECIES, a, i, bo);




















277     }
278 
279     @DontInline
280     static DoubleVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Double> m) {
281         return DoubleVector.fromMemorySegment(SPECIES, a, i, bo, m);
282     }
283 
284     @DontInline
285     static void intoMemorySegment(DoubleVector v, MemorySegment a, int i, ByteOrder bo) {
286         v.intoMemorySegment(a, i, bo);
287     }
288 
289     @DontInline
290     static void intoMemorySegment(DoubleVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Double> m) {
291         v.intoMemorySegment(a, i, bo, m);
292     }
293 

294     @Test(dataProvider = "doubleProvider")
295     static void loadStoreArray(IntFunction<double[]> fa) {
296         double[] a = fa.apply(SPECIES.length());
297         double[] r = new double[a.length];
298 
299         for (int ic = 0; ic < INVOC_COUNT; ic++) {
300             for (int i = 0; i < a.length; i += SPECIES.length()) {
301                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
302                 av.intoArray(r, i);
303             }
304         }
305         Assert.assertEquals(r, a);
306     }
307 
308     @Test(dataProvider = "doubleProviderForIOOBE")
309     static void loadArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
310         double[] a = fa.apply(SPECIES.length());
311         double[] r = new double[a.length];
312 
313         for (int ic = 0; ic < INVOC_COUNT; ic++) {
314             for (int i = 0; i < a.length; i += SPECIES.length()) {
315                 DoubleVector av = fromArray(a, i);
316                 av.intoArray(r, i);
317             }
318         }
319 
320         int index = fi.apply(a.length);
321         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
322         try {
323             fromArray(a, index);
324             if (shouldFail) {
325                 Assert.fail("Failed to throw IndexOutOfBoundsException");
326             }
327         } catch (IndexOutOfBoundsException e) {
328             if (!shouldFail) {
329                 Assert.fail("Unexpected IndexOutOfBoundsException");
330             }
331         }
332     }
333 
334     @Test(dataProvider = "doubleProviderForIOOBE")
335     static void storeArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
336         double[] a = fa.apply(SPECIES.length());
337         double[] r = new double[a.length];
338 
339         for (int ic = 0; ic < INVOC_COUNT; ic++) {
340             for (int i = 0; i < a.length; i += SPECIES.length()) {
341                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
342                 intoArray(av, r, i);
343             }
344         }
345 
346         int index = fi.apply(a.length);
347         boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
348         try {
349             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
350             intoArray(av, r, index);
351             if (shouldFail) {
352                 Assert.fail("Failed to throw IndexOutOfBoundsException");
353             }
354         } catch (IndexOutOfBoundsException e) {
355             if (!shouldFail) {
356                 Assert.fail("Unexpected IndexOutOfBoundsException");
357             }
358         }
359     }
360 
361 
362     @Test(dataProvider = "doubleMaskProvider")
363     static void loadStoreMaskArray(IntFunction<double[]> fa,
364                                    IntFunction<boolean[]> fm) {
365         double[] a = fa.apply(SPECIES.length());
366         double[] r = new double[a.length];
367         boolean[] mask = fm.apply(SPECIES.length());
368         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
369 
370         for (int ic = 0; ic < INVOC_COUNT; ic++) {
371             for (int i = 0; i < a.length; i += SPECIES.length()) {
372                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask);
373                 av.intoArray(r, i);
374             }
375         }
376         assertArraysEquals(r, a, mask);
377 
378 
379         r = new double[a.length];
380 
381         for (int ic = 0; ic < INVOC_COUNT; ic++) {
382             for (int i = 0; i < a.length; i += SPECIES.length()) {
383                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
384                 av.intoArray(r, i, vmask);
385             }
386         }
387         assertArraysEquals(r, a, mask);
388     }
389 
390     @Test(dataProvider = "doubleMaskProviderForIOOBE")
391     static void loadArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
392         double[] a = fa.apply(SPECIES.length());
393         double[] r = new double[a.length];
394         boolean[] mask = fm.apply(SPECIES.length());
395         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
396 
397         for (int ic = 0; ic < INVOC_COUNT; ic++) {
398             for (int i = 0; i < a.length; i += SPECIES.length()) {
399                 DoubleVector av = fromArray(a, i, vmask);
400                 av.intoArray(r, i);
401             }
402         }
403 
404         int index = fi.apply(a.length);
405         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
406         try {
407             fromArray(a, index, vmask);
408             if (shouldFail) {
409                 Assert.fail("Failed to throw IndexOutOfBoundsException");
410             }
411         } catch (IndexOutOfBoundsException e) {
412             if (!shouldFail) {
413                 Assert.fail("Unexpected IndexOutOfBoundsException");
414             }
415         }
416     }
417 
418     @Test(dataProvider = "doubleMaskProviderForIOOBE")
419     static void storeArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
420         double[] a = fa.apply(SPECIES.length());
421         double[] r = new double[a.length];
422         boolean[] mask = fm.apply(SPECIES.length());
423         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
424 
425         for (int ic = 0; ic < INVOC_COUNT; ic++) {
426             for (int i = 0; i < a.length; i += SPECIES.length()) {
427                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
428                 intoArray(av, r, i, vmask);
429             }
430         }
431 
432         int index = fi.apply(a.length);
433         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
434         try {
435             DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0);
436             intoArray(av, a, index, vmask);
437             if (shouldFail) {
438                 Assert.fail("Failed to throw IndexOutOfBoundsException");
439             }
440         } catch (IndexOutOfBoundsException e) {
441             if (!shouldFail) {
442                 Assert.fail("Unexpected IndexOutOfBoundsException");
443             }
444         }
445     }
446 
447 
448     @Test(dataProvider = "doubleMaskProvider")
449     static void loadStoreMask(IntFunction<double[]> fa,
450                               IntFunction<boolean[]> fm) {
451         boolean[] mask = fm.apply(SPECIES.length());
452         boolean[] r = new boolean[mask.length];
453 
454         for (int ic = 0; ic < INVOC_COUNT; ic++) {
455             for (int i = 0; i < mask.length; i += SPECIES.length()) {
456                 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, i);
457                 vmask.intoArray(r, i);
458             }
459         }
460         Assert.assertEquals(r, mask);
461     }
462 
463 
464     @Test(dataProvider = "doubleMemorySegmentProvider")
465     static void loadStoreMemorySegment(IntFunction<double[]> fa,
466                                        IntFunction<MemorySegment> fb,
467                                        ByteOrder bo) {
468         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb);
469         MemorySegment r = fb.apply((int) a.byteSize());
470 
471         int l = (int) a.byteSize();
472         int s = SPECIES.vectorByteSize();
473 
474         for (int ic = 0; ic < INVOC_COUNT; ic++) {
475             for (int i = 0; i < l; i += s) {
476                 DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, i, bo);
477                 av.intoMemorySegment(r, i, bo);
478             }
479         }
480         long m = r.mismatch(a);
481         Assert.assertEquals(m, -1, "Segments not equal");



482     }
483 
484     @Test(dataProvider = "doubleByteProviderForIOOBE")
485     static void loadMemorySegmentIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
486         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
487         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
488 
489         int l = (int) a.byteSize();
490         int s = SPECIES.vectorByteSize();
491 
492         for (int ic = 0; ic < INVOC_COUNT; ic++) {
493             for (int i = 0; i < l; i += s) {
494                 DoubleVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder());
495                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
496             }
497         }
498 
499         int index = fi.apply((int) a.byteSize());
500         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
501         try {
502             fromMemorySegment(a, index, ByteOrder.nativeOrder());
503             if (shouldFail) {
504                 Assert.fail("Failed to throw IndexOutOfBoundsException");
505             }
506         } catch (IndexOutOfBoundsException e) {
507             if (!shouldFail) {
508                 Assert.fail("Unexpected IndexOutOfBoundsException");
509             }
510         }
511     }
512 
513     @Test(dataProvider = "doubleByteProviderForIOOBE")
514     static void storeMemorySegmentIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) {
515         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
516         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
517 
518         int l = (int) a.byteSize();
519         int s = SPECIES.vectorByteSize();
520 
521         for (int ic = 0; ic < INVOC_COUNT; ic++) {
522             for (int i = 0; i < l; i += s) {
523                 DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
524                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder());
525             }
526         }
527 
528         int index = fi.apply((int) a.byteSize());
529         boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
530         try {
531             DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
532             intoMemorySegment(av, r, index, ByteOrder.nativeOrder());
533             if (shouldFail) {
534                 Assert.fail("Failed to throw IndexOutOfBoundsException");
535             }
536         } catch (IndexOutOfBoundsException e) {
537             if (!shouldFail) {
538                 Assert.fail("Unexpected IndexOutOfBoundsException");
539             }
540         }
541     }
542 
543     @Test(dataProvider = "doubleMemorySegmentMaskProvider")
544     static void loadStoreMemorySegmentMask(IntFunction<double[]> fa,
545                                            IntFunction<MemorySegment> fb,
546                                            IntFunction<boolean[]> fm,
547                                            ByteOrder bo) {

548         double[] _a = fa.apply(SPECIES.length());
549         MemorySegment a = toSegment(_a, fb);
550         MemorySegment r = fb.apply((int) a.byteSize());
551         boolean[] mask = fm.apply(SPECIES.length());
552         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
553 
554         int l = (int) a.byteSize();
555         int s = SPECIES.vectorByteSize();
556 
557         for (int ic = 0; ic < INVOC_COUNT; ic++) {
558             for (int i = 0; i < l; i += s) {
559                 DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, i, bo, vmask);
560                 av.intoMemorySegment(r, i, bo);
561             }
562         }
563         assertArraysEquals(segmentToArray(r), _a, mask);




564 
565 
566         r = fb.apply((int) a.byteSize());
567 
568         for (int ic = 0; ic < INVOC_COUNT; ic++) {
569             for (int i = 0; i < l; i += s) {
570                 DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, i, bo);
571                 av.intoMemorySegment(r, i, bo, vmask);
572             }
573         }
574         assertArraysEquals(segmentToArray(r), _a, mask);




575     }
576 
577     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
578     static void loadMemorySegmentMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
579         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
580         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
581         boolean[] mask = fm.apply(SPECIES.length());
582         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
583 
584         int l = (int) a.byteSize();
585         int s = SPECIES.vectorByteSize();
586 
587         for (int ic = 0; ic < INVOC_COUNT; ic++) {
588             for (int i = 0; i < l; i += s) {
589                 DoubleVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
590                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
591             }
592         }
593 
594         int index = fi.apply((int) a.byteSize());
595         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
596         try {
597             fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
598             if (shouldFail) {
599                 Assert.fail("Failed to throw IndexOutOfBoundsException");
600             }
601         } catch (IndexOutOfBoundsException e) {
602             if (!shouldFail) {
603                 Assert.fail("Unexpected IndexOutOfBoundsException");
604             }
605         }
606     }
607 
608     @Test(dataProvider = "doubleByteMaskProviderForIOOBE")
609     static void storeMemorySegmentMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
610         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
611         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
612         boolean[] mask = fm.apply(SPECIES.length());
613         VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask);
614 
615         int l = (int) a.byteSize();


















































































616         int s = SPECIES.vectorByteSize();

617 
618         for (int ic = 0; ic < INVOC_COUNT; ic++) {
619             for (int i = 0; i < l; i += s) {
620                 DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
621                 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask);
622             }
623         }
624 
625         int index = fi.apply((int) a.byteSize());
626         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
627         try {
628             DoubleVector av = DoubleVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
629             intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask);
630             if (shouldFail) {
631                 Assert.fail("Failed to throw IndexOutOfBoundsException");
632             }
633         } catch (IndexOutOfBoundsException e) {
634             if (!shouldFail) {
635                 Assert.fail("Unexpected IndexOutOfBoundsException");
636             }
637         }
638     }
639 
640     @Test(dataProvider = "doubleMemorySegmentProvider")
641     static void loadStoreReadonlyMemorySegment(IntFunction<double[]> fa,
642                                                IntFunction<MemorySegment> fb,
643                                                ByteOrder bo) {
644         MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly();

























































645 
646         Assert.assertThrows(
647                 UnsupportedOperationException.class,
648                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
649         );


650 
651         Assert.assertThrows(
652                 UnsupportedOperationException.class,
653                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
654         );
655 
656         Assert.assertThrows(
657                 UnsupportedOperationException.class,
658                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
659         );


660 
661         VectorMask<Double> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
662                 .laneIsValid();
663         Assert.assertThrows(
664                 UnsupportedOperationException.class,
665                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
666         );






667     }
668 































669 
670     @Test(dataProvider = "maskProvider")
671     static void loadStoreMask(IntFunction<boolean[]> fm) {
672         boolean[] a = fm.apply(SPECIES.length());
673         boolean[] r = new boolean[a.length];
674 
675         for (int ic = 0; ic < INVOC_COUNT; ic++) {
676             for (int i = 0; i < a.length; i += SPECIES.length()) {
677                 VectorMask<Double> vmask = SPECIES.loadMask(a, i);
678                 vmask.intoArray(r, i);
679             }
680         }
681         Assert.assertEquals(r, a);
682     }
683 
684 
685     @Test
686     static void loadStoreShuffle() {
687         IntUnaryOperator fn = a -> a + 5;
688         for (int ic = 0; ic < INVOC_COUNT; ic++) {
689             var shuffle = VectorShuffle.fromOp(SPECIES, fn);
690             int [] r = shuffle.toArray();
691 
692             int [] a = expectedShuffle(SPECIES.length(), fn);
693             Assert.assertEquals(r, a);
694        }
695     }
696 
697 
698 
699 
700 
701     // Gather/Scatter load/store tests
702 
703     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap) {
704         int i = 0;
705         int j = 0;
706         try {
707             for (; i < a.length; i += SPECIES.length()) {
708                 j = i;
709                 for (; j < i + SPECIES.length(); j++) {
710                     Assert.assertEquals(r[j], a[i + indexMap[j]]);
711                 }
712             }
713         } catch (AssertionError e) {
714             Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j);
715         }
716     }
717 
718     static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
719         int i = 0;
720         int j = 0;
721         try {
722             for (; i < a.length; i += SPECIES.length()) {
723                 j = i;
724                 for (; j < i + SPECIES.length(); j++) {
725                     Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0);
726                 }
727             }
728         } catch (AssertionError e) {
729             Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0, "at index #" + j);
730         }
731     }
732 
733     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) {
734         double[] expected = new double[r.length];
735 
736         // Store before checking, since the same location may be stored to more than once
737         for (int i = 0; i < a.length; i += SPECIES.length()) {
738             for (int j = i; j < i + SPECIES.length(); j++) {
739                 if (mask[j % SPECIES.length()]) {
740                     expected[i + indexMap[j]] = a[j];
741                 }
742             }
743         }
744 
745         Assert.assertEquals(r, expected);
746     }
747 
748     static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap) {
749         double[] expected = new double[r.length];
750 
751         // Store before checking, since the same location may be stored to more than once
752         for (int i = 0; i < a.length; i += SPECIES.length()) {
753             for (int j = i; j < i + SPECIES.length(); j++) {
754                 expected[i + indexMap[j]] = a[j];
755             }
756         }
757 
758         Assert.assertEquals(r, expected);
759     }
760 
761     @DataProvider
762     public Object[][] gatherScatterProvider() {
763         return INT_INDEX_GENERATORS.stream().
764                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
765                     return new Object[] {fa, fs};
766                 })).
767                 toArray(Object[][]::new);
768     }
769 
770     @DataProvider
771     public Object[][] gatherScatterMaskProvider() {
772         return BOOLEAN_MASK_GENERATORS.stream().
773           flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm ->
774             DOUBLE_GENERATORS.stream().map(fa -> {
775                     return new Object[] {fa, fm, fs};
776             }))).
777             toArray(Object[][]::new);
778     }
779 
780 
781     @Test(dataProvider = "gatherScatterProvider")
782     static void gather(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
783         double[] a = fa.apply(SPECIES.length());
784         int[] b = fs.apply(a.length, SPECIES.length());
785         double[] r = new double[a.length];
786 
787         for (int ic = 0; ic < INVOC_COUNT; ic++) {
788             for (int i = 0; i < a.length; i += SPECIES.length()) {
789                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i);
790                 av.intoArray(r, i);
791             }
792         }
793 
794         assertGatherArraysEquals(r, a, b);
795     }
796 
797     @Test(dataProvider = "gatherScatterMaskProvider")
798     static void gatherMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
799         double[] a = fa.apply(SPECIES.length());
800         int[] b = fs.apply(a.length, SPECIES.length());
801         double[] r = new double[a.length];
802         boolean[] mask = fm.apply(SPECIES.length());
803         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
804 
805         for (int ic = 0; ic < INVOC_COUNT; ic++) {
806             for (int i = 0; i < a.length; i += SPECIES.length()) {
807                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i, vmask);
808                 av.intoArray(r, i);
809             }
810         }
811 
812         assertGatherArraysEquals(r, a, b, mask);
813     }
814 
815     @Test(dataProvider = "gatherScatterProvider")
816     static void scatter(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) {
817         double[] a = fa.apply(SPECIES.length());
818         int[] b = fs.apply(a.length, SPECIES.length());
819         double[] r = new double[a.length];
820 
821         for (int ic = 0; ic < INVOC_COUNT; ic++) {
822             for (int i = 0; i < a.length; i += SPECIES.length()) {
823                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
824                 av.intoArray(r, i, b, i);
825             }
826         }
827 
828         assertScatterArraysEquals(r, a, b);
829     }
830 
831     @Test(dataProvider = "gatherScatterMaskProvider")
832     static void scatterMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) {
833         double[] a = fa.apply(SPECIES.length());
834         int[] b = fs.apply(a.length, SPECIES.length());
835         double[] r = new double[a.length];
836         boolean[] mask = fm.apply(SPECIES.length());
837         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
838 
839         for (int ic = 0; ic < INVOC_COUNT; ic++) {
840             for (int i = 0; i < a.length; i += SPECIES.length()) {
841                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
842                 av.intoArray(r, i, b, i, vmask);
843             }
844         }
845 
846         assertScatterArraysEquals(r, a, b, mask);
847     }
848 
849 
850 
851 }
--- EOF ---