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 -XX:-TieredCompilation Float64VectorLoadStoreTests
 28  *
 29  */
 30 
 31 // -- This file was mechanically generated: Do not edit! -- //
 32 
 33 import jdk.incubator.foreign.MemorySegment;
 34 import jdk.incubator.foreign.ResourceScope;
 35 import jdk.incubator.foreign.ValueLayout;
 36 import jdk.incubator.vector.FloatVector;
 37 import jdk.incubator.vector.VectorMask;
 38 import jdk.incubator.vector.VectorSpecies;
 39 import jdk.incubator.vector.VectorShuffle;
 40 import jdk.internal.vm.annotation.DontInline;
 41 import org.testng.Assert;
 42 import org.testng.annotations.DataProvider;
 43 import org.testng.annotations.Test;
 44 


 45 import java.nio.ByteOrder;

 46 import java.util.List;
 47 import java.util.function.*;
 48 
 49 @Test
 50 public class Float64VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
 51     static final VectorSpecies<Float> SPECIES =
 52                 FloatVector.SPECIES_64;
 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 / 64);
 58 
 59     static void assertArraysEquals(float[] r, float[] 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] : (float) 0);
 64             }
 65         } catch (AssertionError e) {
 66             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (float) 0, "at index #" + i);
 67         }
 68     }
 69 











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



















200     @DataProvider
201     public Object[][] floatByteProviderForIOOBE() {
202         var f = FLOAT_GENERATORS.get(0);
203         return BYTE_INDEX_GENERATORS.stream().map(fi -> {
204                     return new Object[] {f, fi};
205                 }).
206                 toArray(Object[][]::new);
207     }
208 
209     @DataProvider
210     public Object[][] floatByteMaskProviderForIOOBE() {
211         var f = FLOAT_GENERATORS.get(0);
212         return BOOLEAN_MASK_GENERATORS.stream().
213                 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
214                     return new Object[] {f, fi, fm};
215                 })).
216                 toArray(Object[][]::new);
217     }
218 
219     static MemorySegment toSegment(float[] a, IntFunction<MemorySegment> fb) {
220         MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
221         for (int i = 0; i < a.length; i++) {
222             ms.set(ValueLayout.JAVA_FLOAT, i * SPECIES.elementSize() / 8 , a[i]);
223         }
224         return ms;
225     }
226 
227     static float[] segmentToArray(MemorySegment ms) {
228         return ms.toArray(ValueLayout.JAVA_FLOAT);












229     }
230 
231 
232     interface ToFloatF {
233         float apply(int i);
234     }
235 
236     static float[] fill(int s , ToFloatF f) {
237         return fill(new float[s], f);
238     }
239 
240     static float[] fill(float[] a, ToFloatF f) {
241         for (int i = 0; i < a.length; i++) {
242             a[i] = f.apply(i);
243         }
244         return a;
245     }
246 
247     @DontInline
248     static FloatVector fromArray(float[] a, int i) {
249         return FloatVector.fromArray(SPECIES, a, i);
250     }
251 
252     @DontInline
253     static FloatVector fromArray(float[] a, int i, VectorMask<Float> m) {
254         return FloatVector.fromArray(SPECIES, a, i, m);
255     }
256 
257     @DontInline
258     static void intoArray(FloatVector v, float[] a, int i) {
259         v.intoArray(a, i);
260     }
261 
262     @DontInline
263     static void intoArray(FloatVector v, float[] a, int i, VectorMask<Float> m) {
264         v.intoArray(a, i, m);
265     }
266 
267     @DontInline
268     static FloatVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
269         return FloatVector.fromMemorySegment(SPECIES, a, i, bo);




















270     }
271 
272     @DontInline
273     static FloatVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Float> m) {
274         return FloatVector.fromMemorySegment(SPECIES, a, i, bo, m);
275     }
276 
277     @DontInline
278     static void intoMemorySegment(FloatVector v, MemorySegment a, int i, ByteOrder bo) {
279         v.intoMemorySegment(a, i, bo);
280     }
281 
282     @DontInline
283     static void intoMemorySegment(FloatVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Float> m) {
284         v.intoMemorySegment(a, i, bo, m);
285     }
286 

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



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

541         float[] _a = fa.apply(SPECIES.length());
542         MemorySegment a = toSegment(_a, fb);
543         MemorySegment r = fb.apply((int) a.byteSize());
544         boolean[] mask = fm.apply(SPECIES.length());
545         VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
546 
547         int l = (int) a.byteSize();
548         int s = SPECIES.vectorByteSize();
549 
550         for (int ic = 0; ic < INVOC_COUNT; ic++) {
551             for (int i = 0; i < l; i += s) {
552                 FloatVector av = FloatVector.fromMemorySegment(SPECIES, a, i, bo, vmask);
553                 av.intoMemorySegment(r, i, bo);
554             }
555         }
556         assertArraysEquals(segmentToArray(r), _a, mask);




557 
558 
559         r = fb.apply((int) a.byteSize());
560 
561         for (int ic = 0; ic < INVOC_COUNT; ic++) {
562             for (int i = 0; i < l; i += s) {
563                 FloatVector av = FloatVector.fromMemorySegment(SPECIES, a, i, bo);
564                 av.intoMemorySegment(r, i, bo, vmask);
565             }
566         }
567         assertArraysEquals(segmentToArray(r), _a, mask);




568     }
569 
570     @Test(dataProvider = "floatByteMaskProviderForIOOBE")
571     static void loadMemorySegmentMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
572         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
573         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
574         boolean[] mask = fm.apply(SPECIES.length());
575         VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
576 
577         int l = (int) a.byteSize();
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                 FloatVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
583                 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
584             }
585         }
586 
587         int index = fi.apply((int) a.byteSize());
588         boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
589         try {
590             fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
591             if (shouldFail) {
592                 Assert.fail("Failed to throw IndexOutOfBoundsException");
593             }
594         } catch (IndexOutOfBoundsException e) {
595             if (!shouldFail) {
596                 Assert.fail("Unexpected IndexOutOfBoundsException");
597             }
598         }
599     }
600 
601     @Test(dataProvider = "floatByteMaskProviderForIOOBE")
602     static void storeMemorySegmentMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
603         MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
604         MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
605         boolean[] mask = fm.apply(SPECIES.length());
606         VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
607 
608         int l = (int) a.byteSize();


















































































609         int s = SPECIES.vectorByteSize();

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

























































638 
639         Assert.assertThrows(
640                 UnsupportedOperationException.class,
641                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
642         );


643 
644         Assert.assertThrows(
645                 UnsupportedOperationException.class,
646                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
647         );
648 
649         Assert.assertThrows(
650                 UnsupportedOperationException.class,
651                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
652         );


653 
654         VectorMask<Float> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
655                 .laneIsValid();
656         Assert.assertThrows(
657                 UnsupportedOperationException.class,
658                 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
659         );






660     }
661 































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