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 #if[MaxBit]
28 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
29 * -XX:-TieredCompilation $vectorteststype$
30 #else[MaxBit]
31 * @run testng/othervm -XX:-TieredCompilation $vectorteststype$
32 #end[MaxBit]
33 *
34 */
35
36 #warn This file is preprocessed before being compiled
37
38 import jdk.incubator.vector.$Type$Vector;
39 import jdk.incubator.vector.VectorMask;
40 #if[MaxBit]
41 import jdk.incubator.vector.VectorShape;
42 #end[MaxBit]
43 import jdk.incubator.vector.VectorSpecies;
44 import jdk.incubator.vector.VectorShuffle;
45 import jdk.internal.vm.annotation.DontInline;
46 import org.testng.Assert;
47 import org.testng.annotations.DataProvider;
48 import org.testng.annotations.Test;
49
50 #if[MaxBit]
51 import java.lang.invoke.MethodHandles;
52 import java.lang.invoke.VarHandle;
53 #end[MaxBit]
54 import java.nio.ByteBuffer;
55 #if[!byte]
56 import java.nio.$Type$Buffer;
57 #end[!byte]
58 import java.nio.ByteOrder;
59 import java.nio.ReadOnlyBufferException;
60 import java.util.List;
61 import java.util.function.*;
62
63 @Test
64 public class $vectorteststype$ extends AbstractVectorLoadStoreTest {
65 #if[MaxBit]
66 static final VectorSpecies<$Wideboxtype$> SPECIES =
67 $Type$Vector.SPECIES_MAX;
68 #else[MaxBit]
69 static final VectorSpecies<$Wideboxtype$> SPECIES =
70 $Type$Vector.SPECIES_$bits$;
71 #end[MaxBit]
72
73 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
74
75 #if[MaxBit]
76 static VectorShape getMaxBit() {
77 return VectorShape.S_Max_BIT;
78 }
79
80 private static final int Max = 256; // juts so we can do N/$bits$
81 #end[MaxBit]
82
83 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$);
84
85 static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask) {
86 int i = 0;
87 try {
88 for (; i < a.length; i++) {
89 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0);
90 }
91 } catch (AssertionError e) {
92 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0, "at index #" + i);
93 }
94 }
95
96 #if[!byte]
97 static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
98 int i = 0;
99 try {
100 for (; i < a.length; i++) {
101 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0);
102 }
103 } catch (AssertionError e) {
104 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
105 }
106 }
107 #end[!byte]
108
109 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
110 withToString("$type$[i * 5]", (int s) -> {
111 return fill(s * BUFFER_REPS,
112 i -> ($type$)(i * 5));
113 }),
114 withToString("$type$[i + 1]", (int s) -> {
115 return fill(s * BUFFER_REPS,
116 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
117 })
118 );
119
120 // Relative to array.length
121 static final List<IntFunction<Integer>> 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 + 1", (int l) -> {
135 return l - SPECIES.length() + 1;
136 }),
137 withToString("l + speciesl - 1", (int l) -> {
138 return l + SPECIES.length() - 1;
139 }),
140 withToString("l + speciesl", (int l) -> {
141 return l + SPECIES.length();
142 }),
143 withToString("l + speciesl + 1", (int l) -> {
144 return l + SPECIES.length() + 1;
145 })
146 );
147
148 // Relative to byte[] array.length or ByteBuffer.limit()
149 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
150 withToString("-1", (int l) -> {
151 return -1;
152 }),
153 withToString("l", (int l) -> {
154 return l;
155 }),
156 withToString("l - 1", (int l) -> {
157 return l - 1;
158 }),
159 withToString("l + 1", (int l) -> {
160 return l + 1;
161 }),
162 withToString("l - speciesl*ebsize + 1", (int l) -> {
163 return l - SPECIES.vectorByteSize() + 1;
164 }),
165 withToString("l + speciesl*ebsize - 1", (int l) -> {
166 return l + SPECIES.vectorByteSize() - 1;
167 }),
168 withToString("l + speciesl*ebsize", (int l) -> {
199 @DataProvider
200 public Object[][] $type$MaskProvider() {
201 return BOOLEAN_MASK_GENERATORS.stream().
202 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
203 return new Object[] {fa, fm};
204 })).
205 toArray(Object[][]::new);
206 }
207
208 @DataProvider
209 public Object[][] $type$MaskProviderForIOOBE() {
210 var f = $TYPE$_GENERATORS.get(0);
211 return BOOLEAN_MASK_GENERATORS.stream().
212 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
213 return new Object[] {f, fi, fm};
214 })).
215 toArray(Object[][]::new);
216 }
217
218 @DataProvider
219 public Object[][] $type$ByteBufferProvider() {
220 return $TYPE$_GENERATORS.stream().
221 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
222 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
223 return new Object[]{fa, fb, bo};
224 }))).
225 toArray(Object[][]::new);
226 }
227
228 @DataProvider
229 public Object[][] $type$ByteBufferMaskProvider() {
230 return BOOLEAN_MASK_GENERATORS.stream().
231 flatMap(fm -> $TYPE$_GENERATORS.stream().
232 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
233 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
234 return new Object[]{fa, fb, fm, bo};
235 })))).
236 toArray(Object[][]::new);
237 }
238
239 @DataProvider
240 public Object[][] $type$ByteArrayProvider() {
241 return $TYPE$_GENERATORS.stream().
242 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
243 return new Object[]{fa, bo};
244 })).
245 toArray(Object[][]::new);
246 }
247
248 @DataProvider
249 public Object[][] $type$ByteArrayMaskProvider() {
250 return BOOLEAN_MASK_GENERATORS.stream().
251 flatMap(fm -> $TYPE$_GENERATORS.stream().
252 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
253 return new Object[]{fa, fm, bo};
254 }))).
255 toArray(Object[][]::new);
256 }
257
258 @DataProvider
259 public Object[][] $type$ByteProviderForIOOBE() {
260 var f = $TYPE$_GENERATORS.get(0);
261 return BYTE_INDEX_GENERATORS.stream().map(fi -> {
262 return new Object[] {f, fi};
263 }).
264 toArray(Object[][]::new);
265 }
266
267 @DataProvider
268 public Object[][] $type$ByteMaskProviderForIOOBE() {
269 var f = $TYPE$_GENERATORS.get(0);
270 return BOOLEAN_MASK_GENERATORS.stream().
271 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
272 return new Object[] {f, fi, fm};
273 })).
274 toArray(Object[][]::new);
275 }
276
277 static ByteBuffer toBuffer($type$[] a, IntFunction<ByteBuffer> fb) {
278 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
279 for ($type$ v : a) {
280 bb.{#if[byte]?put(v):put$Type$(v)};
281 }
282 return bb.clear();
283 }
284
285 static $type$[] bufferToArray(ByteBuffer bb) {
286 $Type$Buffer db = bb{#if[byte]?;:.as$Type$Buffer();}
287 $type$[] d = new $type$[db.capacity()];
288 db.get(0, d);
289 return d;
290 }
291
292 static byte[] toByteArray($type$[] a, IntFunction<byte[]> fb, ByteOrder bo) {
293 byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
294 #if[byte]
295 $Type$Buffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo);
296 #else[byte]
297 $Type$Buffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).as$Type$Buffer();
298 #end[byte]
299 for ($type$ v : a) {
300 bb.put(v);
301 }
302 return b;
303 }
304
305
306 interface To$Type$F {
307 $type$ apply(int i);
308 }
309
310 static $type$[] fill(int s , To$Type$F f) {
311 return fill(new $type$[s], f);
312 }
313
314 static $type$[] fill($type$[] a, To$Type$F f) {
315 for (int i = 0; i < a.length; i++) {
316 a[i] = f.apply(i);
317 }
318 return a;
319 }
320
321 @DontInline
322 static $abstractvectortype$ fromArray($type$[] a, int i) {
323 return $abstractvectortype$.fromArray(SPECIES, a, i);
324 }
325
326 @DontInline
327 static $abstractvectortype$ fromArray($type$[] a, int i, VectorMask<$Boxtype$> m) {
328 return $abstractvectortype$.fromArray(SPECIES, a, i, m);
329 }
330
331 @DontInline
332 static void intoArray($abstractvectortype$ v, $type$[] a, int i) {
333 v.intoArray(a, i);
334 }
335
336 @DontInline
337 static void intoArray($abstractvectortype$ v, $type$[] a, int i, VectorMask<$Boxtype$> m) {
338 v.intoArray(a, i, m);
339 }
340
341 @DontInline
342 static $abstractvectortype$ fromByteArray(byte[] a, int i, ByteOrder bo) {
343 return $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
344 }
345
346 @DontInline
347 static $abstractvectortype$ fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
348 return $abstractvectortype$.fromByteArray(SPECIES, a, i, bo, m);
349 }
350
351 @DontInline
352 static void intoByteArray($abstractvectortype$ v, byte[] a, int i, ByteOrder bo) {
353 v.intoByteArray(a, i, bo);
354 }
355
356 @DontInline
357 static void intoByteArray($abstractvectortype$ v, byte[] a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
358 v.intoByteArray(a, i, bo, m);
359 }
360
361 @DontInline
362 static $abstractvectortype$ fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
363 return $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
364 }
365
366 @DontInline
367 static $abstractvectortype$ fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
368 return $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo, m);
369 }
370
371 @DontInline
372 static void intoByteBuffer($abstractvectortype$ v, ByteBuffer a, int i, ByteOrder bo) {
373 v.intoByteBuffer(a, i, bo);
374 }
375
376 @DontInline
377 static void intoByteBuffer($abstractvectortype$ v, ByteBuffer a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
378 v.intoByteBuffer(a, i, bo, m);
379 }
380
381
382 @Test(dataProvider = "$type$Provider")
383 static void loadStoreArray(IntFunction<$type$[]> fa) {
384 $type$[] a = fa.apply(SPECIES.length());
385 $type$[] r = new $type$[a.length];
386
387 for (int ic = 0; ic < INVOC_COUNT; ic++) {
388 for (int i = 0; i < a.length; i += SPECIES.length()) {
389 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
390 av.intoArray(r, i);
391 }
392 }
393 Assert.assertEquals(r, a);
394 }
395
396 @Test(dataProvider = "$type$ProviderForIOOBE")
397 static void loadArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
398 $type$[] a = fa.apply(SPECIES.length());
399 $type$[] r = new $type$[a.length];
400
401 for (int ic = 0; ic < INVOC_COUNT; ic++) {
532 }
533 }
534
535
536 @Test(dataProvider = "$type$MaskProvider")
537 static void loadStoreMask(IntFunction<$type$[]> fa,
538 IntFunction<boolean[]> fm) {
539 boolean[] mask = fm.apply(SPECIES.length());
540 boolean[] r = new boolean[mask.length];
541
542 for (int ic = 0; ic < INVOC_COUNT; ic++) {
543 for (int i = 0; i < mask.length; i += SPECIES.length()) {
544 VectorMask<$Boxtype$> vmask = VectorMask.fromArray(SPECIES, mask, i);
545 vmask.intoArray(r, i);
546 }
547 }
548 Assert.assertEquals(r, mask);
549 }
550
551
552 @Test(dataProvider = "$type$ByteBufferProvider")
553 static void loadStoreByteBuffer(IntFunction<$type$[]> fa,
554 IntFunction<ByteBuffer> fb,
555 ByteOrder bo) {
556 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
557 ByteBuffer r = fb.apply(a.limit());
558
559 int l = a.limit();
560 int s = SPECIES.vectorByteSize();
561
562 for (int ic = 0; ic < INVOC_COUNT; ic++) {
563 for (int i = 0; i < l; i += s) {
564 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
565 av.intoByteBuffer(r, i, bo);
566 }
567 }
568 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
569 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
570 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
571 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
572 Assert.assertEquals(r, a, "Buffers not equal");
573 }
574
575 @Test(dataProvider = "$type$ByteProviderForIOOBE")
576 static void loadByteBufferIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
577 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
578 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
579
580 int l = a.limit();
581 int s = SPECIES.vectorByteSize();
582
583 for (int ic = 0; ic < INVOC_COUNT; ic++) {
584 for (int i = 0; i < l; i += s) {
585 $abstractvectortype$ av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
586 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
587 }
588 }
589
590 int index = fi.apply(a.limit());
591 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
592 try {
593 fromByteBuffer(a, index, ByteOrder.nativeOrder());
594 if (shouldFail) {
595 Assert.fail("Failed to throw IndexOutOfBoundsException");
596 }
597 } catch (IndexOutOfBoundsException e) {
598 if (!shouldFail) {
599 Assert.fail("Unexpected IndexOutOfBoundsException");
600 }
601 }
602 }
603
604 @Test(dataProvider = "$type$ByteProviderForIOOBE")
605 static void storeByteBufferIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
606 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
607 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
608
609 int l = a.limit();
610 int s = SPECIES.vectorByteSize();
611
612 for (int ic = 0; ic < INVOC_COUNT; ic++) {
613 for (int i = 0; i < l; i += s) {
614 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
615 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
616 }
617 }
618
619 int index = fi.apply(a.limit());
620 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
621 try {
622 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
623 intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
624 if (shouldFail) {
625 Assert.fail("Failed to throw IndexOutOfBoundsException");
626 }
627 } catch (IndexOutOfBoundsException e) {
628 if (!shouldFail) {
629 Assert.fail("Unexpected IndexOutOfBoundsException");
630 }
631 }
632 }
633
634
635 @Test(dataProvider = "$type$ByteBufferMaskProvider")
636 static void loadStoreByteBufferMask(IntFunction<$type$[]> fa,
637 IntFunction<ByteBuffer> fb,
638 IntFunction<boolean[]> fm,
639 ByteOrder bo) {
640 $type$[] _a = fa.apply(SPECIES.length());
641 ByteBuffer a = toBuffer(_a, fb);
642 ByteBuffer r = fb.apply(a.limit());
643 boolean[] mask = fm.apply(SPECIES.length());
644 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
645
646 int l = a.limit();
647 int s = SPECIES.vectorByteSize();
648
649 for (int ic = 0; ic < INVOC_COUNT; ic++) {
650 for (int i = 0; i < l; i += s) {
651 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo, vmask);
652 av.intoByteBuffer(r, i, bo);
653 }
654 }
655 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
656 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
657 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
658 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
659 assertArraysEquals(bufferToArray(r), _a, mask);
660
661
662 r = fb.apply(a.limit());
663
664 for (int ic = 0; ic < INVOC_COUNT; ic++) {
665 for (int i = 0; i < l; i += s) {
666 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, bo);
667 av.intoByteBuffer(r, i, bo, vmask);
668 }
669 }
670 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
671 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
672 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
673 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
674 assertArraysEquals(bufferToArray(r), _a, mask);
675 }
676
677 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
678 static void loadByteBufferMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
679 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
680 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
681 boolean[] mask = fm.apply(SPECIES.length());
682 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
683
684 int l = a.limit();
685 int s = SPECIES.vectorByteSize();
686
687 for (int ic = 0; ic < INVOC_COUNT; ic++) {
688 for (int i = 0; i < l; i += s) {
689 $abstractvectortype$ av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
690 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
691 }
692 }
693
694 int index = fi.apply(a.limit());
695 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
696 try {
697 fromByteBuffer(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 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
709 static void storeByteBufferMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
710 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
711 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
712 boolean[] mask = fm.apply(SPECIES.length());
713 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
714
715 int l = a.limit();
716 int s = SPECIES.vectorByteSize();
717
718 for (int ic = 0; ic < INVOC_COUNT; ic++) {
719 for (int i = 0; i < l; i += s) {
720 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
721 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
722 }
723 }
724
725 int index = fi.apply(a.limit());
726 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
727 try {
728 $abstractvectortype$ av = $abstractvectortype$.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
729 intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
730 if (shouldFail) {
731 Assert.fail("Failed to throw IndexOutOfBoundsException");
732 }
733 } catch (IndexOutOfBoundsException e) {
734 if (!shouldFail) {
735 Assert.fail("Unexpected IndexOutOfBoundsException");
736 }
737 }
738 }
739
740
741 @Test(dataProvider = "$type$ByteBufferProvider")
742 static void loadStoreReadonlyByteBuffer(IntFunction<$type$[]> fa,
743 IntFunction<ByteBuffer> fb,
744 ByteOrder bo) {
745 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
746
747 try {
748 SPECIES.zero().intoByteBuffer(a, 0, bo);
749 Assert.fail("ReadOnlyBufferException expected");
750 } catch (ReadOnlyBufferException e) {
751 }
752
753 try {
754 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
755 Assert.fail("ReadOnlyBufferException expected");
756 } catch (ReadOnlyBufferException e) {
757 }
758
759 try {
760 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
761 Assert.fail("ReadOnlyBufferException expected");
762 } catch (ReadOnlyBufferException e) {
763 }
764
765 try {
766 VectorMask<$Boxtype$> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
767 .laneIsValid();
768 SPECIES.zero().intoByteBuffer(a, 0, bo, m);
769 Assert.fail("ReadOnlyBufferException expected");
770 } catch (ReadOnlyBufferException e) {
771 }
772 }
773
774
775 @Test(dataProvider = "$type$ByteArrayProvider")
776 static void loadStoreByteArray(IntFunction<$type$[]> fa,
777 ByteOrder bo) {
778 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
779 byte[] r = new byte[a.length];
780
781 int s = SPECIES.vectorByteSize();
782 int l = a.length;
783
784 for (int ic = 0; ic < INVOC_COUNT; ic++) {
785 for (int i = 0; i < l; i += s) {
786 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
787 av.intoByteArray(r, i, bo);
788 }
789 }
790 Assert.assertEquals(r, a, "Byte arrays not equal");
791 }
792
793 @Test(dataProvider = "$type$ByteProviderForIOOBE")
794 static void loadByteArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
795 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
796 byte[] r = new byte[a.length];
797
798 int s = SPECIES.vectorByteSize();
799 int l = a.length;
800
801 for (int ic = 0; ic < INVOC_COUNT; ic++) {
802 for (int i = 0; i < l; i += s) {
803 $abstractvectortype$ av = fromByteArray(a, i, ByteOrder.nativeOrder());
804 av.intoByteArray(r, i, ByteOrder.nativeOrder());
805 }
806 }
807
808 int index = fi.apply(a.length);
809 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
810 try {
811 fromByteArray(a, index, ByteOrder.nativeOrder());
812 if (shouldFail) {
813 Assert.fail("Failed to throw IndexOutOfBoundsException");
814 }
815 } catch (IndexOutOfBoundsException e) {
816 if (!shouldFail) {
817 Assert.fail("Unexpected IndexOutOfBoundsException");
818 }
819 }
820 }
821
822 @Test(dataProvider = "$type$ByteProviderForIOOBE")
823 static void storeByteArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
824 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
825 byte[] r = new byte[a.length];
826
827 int s = SPECIES.vectorByteSize();
828 int l = a.length;
829
830 for (int ic = 0; ic < INVOC_COUNT; ic++) {
831 for (int i = 0; i < l; i += s) {
832 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
833 intoByteArray(av, r, i, ByteOrder.nativeOrder());
834 }
835 }
836
837 int index = fi.apply(a.length);
838 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
839 try {
840 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
841 intoByteArray(av, r, index, ByteOrder.nativeOrder());
842 if (shouldFail) {
843 Assert.fail("Failed to throw IndexOutOfBoundsException");
844 }
845 } catch (IndexOutOfBoundsException e) {
846 if (!shouldFail) {
847 Assert.fail("Unexpected IndexOutOfBoundsException");
848 }
849 }
850 }
851
852
853 @Test(dataProvider = "$type$ByteArrayMaskProvider")
854 static void loadStoreByteArrayMask(IntFunction<$type$[]> fa,
855 IntFunction<boolean[]> fm,
856 ByteOrder bo) {
857 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
858 byte[] r = new byte[a.length];
859 boolean[] mask = fm.apply(SPECIES.length());
860 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
861
862 int s = SPECIES.vectorByteSize();
863 int l = a.length;
864
865 for (int ic = 0; ic < INVOC_COUNT; ic++) {
866 for (int i = 0; i < l; i += s) {
867 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo, vmask);
868 av.intoByteArray(r, i, bo);
869 }
870 }
871 assertArraysEquals(r, a, mask);
872
873
874 r = new byte[a.length];
875
876 for (int ic = 0; ic < INVOC_COUNT; ic++) {
877 for (int i = 0; i < l; i += s) {
878 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, bo);
879 av.intoByteArray(r, i, bo, vmask);
880 }
881 }
882 assertArraysEquals(r, a, mask);
883 }
884
885 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
886 static void loadByteArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
887 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
888 byte[] r = new byte[a.length];
889 boolean[] mask = fm.apply(SPECIES.length());
890 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
891
892 int s = SPECIES.vectorByteSize();
893 int l = a.length;
894
895 for (int ic = 0; ic < INVOC_COUNT; ic++) {
896 for (int i = 0; i < l; i += s) {
897 $abstractvectortype$ av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
898 av.intoByteArray(r, i, ByteOrder.nativeOrder());
899 }
900 }
901
902 int index = fi.apply(a.length);
903 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
904 try {
905 fromByteArray(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 = "$type$ByteMaskProviderForIOOBE")
917 static void storeByteArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
918 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
919 byte[] r = new byte[a.length];
920 boolean[] mask = fm.apply(SPECIES.length());
921 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
922
923 int s = SPECIES.vectorByteSize();
924 int l = a.length;
925
926 for (int ic = 0; ic < INVOC_COUNT; ic++) {
927 for (int i = 0; i < l; i += s) {
928 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
929 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
930 }
931 }
932
933 int index = fi.apply(a.length);
934 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
935 try {
936 $abstractvectortype$ av = $abstractvectortype$.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
937 intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
938 if (shouldFail) {
939 Assert.fail("Failed to throw IndexOutOfBoundsException");
940 }
941 } catch (IndexOutOfBoundsException e) {
942 if (!shouldFail) {
943 Assert.fail("Unexpected IndexOutOfBoundsException");
944 }
945 }
946 }
947
948 @Test(dataProvider = "maskProvider")
949 static void loadStoreMask(IntFunction<boolean[]> fm) {
950 boolean[] a = fm.apply(SPECIES.length());
951 boolean[] r = new boolean[a.length];
952
953 for (int ic = 0; ic < INVOC_COUNT; ic++) {
954 for (int i = 0; i < a.length; i += SPECIES.length()) {
955 VectorMask<$Boxtype$> vmask = SPECIES.loadMask(a, i);
956 vmask.intoArray(r, i);
957 }
958 }
959 Assert.assertEquals(r, a);
960 }
961
962 @Test
963 static void loadStoreShuffle() {
964 IntUnaryOperator fn = a -> a + 5;
965 for (int ic = 0; ic < INVOC_COUNT; ic++) {
966 var shuffle = VectorShuffle.fromOp(SPECIES, fn);
967 int [] r = shuffle.toArray();
968
969 int [] a = expectedShuffle(SPECIES.length(), fn);
970 Assert.assertEquals(r, a);
971 }
972 }
973
974
975 #if[short]
976 static void assertArraysEquals(char[] a, char[] r, boolean[] mask) {
977 int i = 0;
978 try {
979 for (; i < a.length; i++) {
980 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]);
981 }
|
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 #if[MaxBit]
28 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
29 * -XX:-TieredCompilation $vectorteststype$
30 #else[MaxBit]
31 * @run testng/othervm -XX:-TieredCompilation $vectorteststype$
32 #end[MaxBit]
33 *
34 */
35
36 #warn This file is preprocessed before being compiled
37
38 import jdk.incubator.foreign.MemorySegment;
39 import jdk.incubator.foreign.ResourceScope;
40 import jdk.incubator.foreign.ValueLayout;
41 import jdk.incubator.vector.$Type$Vector;
42 import jdk.incubator.vector.VectorMask;
43 #if[MaxBit]
44 import jdk.incubator.vector.VectorShape;
45 #end[MaxBit]
46 import jdk.incubator.vector.VectorSpecies;
47 import jdk.incubator.vector.VectorShuffle;
48 import jdk.internal.vm.annotation.DontInline;
49 import org.testng.Assert;
50 import org.testng.annotations.DataProvider;
51 import org.testng.annotations.Test;
52
53 import java.nio.ByteOrder;
54 import java.util.List;
55 import java.util.function.*;
56
57 @Test
58 public class $vectorteststype$ extends AbstractVectorLoadStoreTest {
59 #if[MaxBit]
60 static final VectorSpecies<$Wideboxtype$> SPECIES =
61 $Type$Vector.SPECIES_MAX;
62 #else[MaxBit]
63 static final VectorSpecies<$Wideboxtype$> SPECIES =
64 $Type$Vector.SPECIES_$bits$;
65 #end[MaxBit]
66
67 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
68
69 #if[MaxBit]
70 static VectorShape getMaxBit() {
71 return VectorShape.S_Max_BIT;
72 }
73
74 private static final int Max = 256; // juts so we can do N/$bits$
75 #end[MaxBit]
76
77 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$);
78
79 static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask) {
80 int i = 0;
81 try {
82 for (; i < a.length; i++) {
83 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0);
84 }
85 } catch (AssertionError e) {
86 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0, "at index #" + i);
87 }
88 }
89
90 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of(
91 withToString("$type$[i * 5]", (int s) -> {
92 return fill(s * BUFFER_REPS,
93 i -> ($type$)(i * 5));
94 }),
95 withToString("$type$[i + 1]", (int s) -> {
96 return fill(s * BUFFER_REPS,
97 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1)));
98 })
99 );
100
101 // Relative to array.length
102 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
103 withToString("-1", (int l) -> {
104 return -1;
105 }),
106 withToString("l", (int l) -> {
107 return l;
108 }),
109 withToString("l - 1", (int l) -> {
110 return l - 1;
111 }),
112 withToString("l + 1", (int l) -> {
113 return l + 1;
114 }),
115 withToString("l - speciesl + 1", (int l) -> {
116 return l - SPECIES.length() + 1;
117 }),
118 withToString("l + speciesl - 1", (int l) -> {
119 return l + SPECIES.length() - 1;
120 }),
121 withToString("l + speciesl", (int l) -> {
122 return l + SPECIES.length();
123 }),
124 withToString("l + speciesl + 1", (int l) -> {
125 return l + SPECIES.length() + 1;
126 })
127 );
128
129 // Relative to byte[] array.length or MemorySegment.byteSize()
130 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
131 withToString("-1", (int l) -> {
132 return -1;
133 }),
134 withToString("l", (int l) -> {
135 return l;
136 }),
137 withToString("l - 1", (int l) -> {
138 return l - 1;
139 }),
140 withToString("l + 1", (int l) -> {
141 return l + 1;
142 }),
143 withToString("l - speciesl*ebsize + 1", (int l) -> {
144 return l - SPECIES.vectorByteSize() + 1;
145 }),
146 withToString("l + speciesl*ebsize - 1", (int l) -> {
147 return l + SPECIES.vectorByteSize() - 1;
148 }),
149 withToString("l + speciesl*ebsize", (int l) -> {
180 @DataProvider
181 public Object[][] $type$MaskProvider() {
182 return BOOLEAN_MASK_GENERATORS.stream().
183 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> {
184 return new Object[] {fa, fm};
185 })).
186 toArray(Object[][]::new);
187 }
188
189 @DataProvider
190 public Object[][] $type$MaskProviderForIOOBE() {
191 var f = $TYPE$_GENERATORS.get(0);
192 return BOOLEAN_MASK_GENERATORS.stream().
193 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
194 return new Object[] {f, fi, fm};
195 })).
196 toArray(Object[][]::new);
197 }
198
199 @DataProvider
200 public Object[][] $type$MemorySegmentProvider() {
201 return $TYPE$_GENERATORS.stream().
202 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
203 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
204 return new Object[]{fa, fb, bo};
205 }))).
206 toArray(Object[][]::new);
207 }
208
209 @DataProvider
210 public Object[][] $type$MemorySegmentMaskProvider() {
211 return BOOLEAN_MASK_GENERATORS.stream().
212 flatMap(fm -> $TYPE$_GENERATORS.stream().
213 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream().
214 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
215 return new Object[]{fa, fb, fm, bo};
216 })))).
217 toArray(Object[][]::new);
218 }
219
220 @DataProvider
221 public Object[][] $type$ByteProviderForIOOBE() {
222 var f = $TYPE$_GENERATORS.get(0);
223 return BYTE_INDEX_GENERATORS.stream().map(fi -> {
224 return new Object[] {f, fi};
225 }).
226 toArray(Object[][]::new);
227 }
228
229 @DataProvider
230 public Object[][] $type$ByteMaskProviderForIOOBE() {
231 var f = $TYPE$_GENERATORS.get(0);
232 return BOOLEAN_MASK_GENERATORS.stream().
233 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
234 return new Object[] {f, fi, fm};
235 })).
236 toArray(Object[][]::new);
237 }
238
239 static MemorySegment toSegment($type$[] a, IntFunction<MemorySegment> fb) {
240 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8);
241 for (int i = 0; i < a.length; i++) {
242 ms.set(ValueLayout.JAVA_$TYPE$, i * SPECIES.elementSize() / 8 , a[i]);
243 }
244 return ms;
245 }
246
247 static $type$[] segmentToArray(MemorySegment ms) {
248 return ms.toArray(ValueLayout.JAVA_$TYPE$);
249 }
250
251
252 interface To$Type$F {
253 $type$ apply(int i);
254 }
255
256 static $type$[] fill(int s , To$Type$F f) {
257 return fill(new $type$[s], f);
258 }
259
260 static $type$[] fill($type$[] a, To$Type$F f) {
261 for (int i = 0; i < a.length; i++) {
262 a[i] = f.apply(i);
263 }
264 return a;
265 }
266
267 @DontInline
268 static $abstractvectortype$ fromArray($type$[] a, int i) {
269 return $abstractvectortype$.fromArray(SPECIES, a, i);
270 }
271
272 @DontInline
273 static $abstractvectortype$ fromArray($type$[] a, int i, VectorMask<$Boxtype$> m) {
274 return $abstractvectortype$.fromArray(SPECIES, a, i, m);
275 }
276
277 @DontInline
278 static void intoArray($abstractvectortype$ v, $type$[] a, int i) {
279 v.intoArray(a, i);
280 }
281
282 @DontInline
283 static void intoArray($abstractvectortype$ v, $type$[] a, int i, VectorMask<$Boxtype$> m) {
284 v.intoArray(a, i, m);
285 }
286
287 @DontInline
288 static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
289 return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
290 }
291
292 @DontInline
293 static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
294 return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, m);
295 }
296
297 @DontInline
298 static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo) {
299 v.intoMemorySegment(a, i, bo);
300 }
301
302 @DontInline
303 static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) {
304 v.intoMemorySegment(a, i, bo, m);
305 }
306
307 @Test(dataProvider = "$type$Provider")
308 static void loadStoreArray(IntFunction<$type$[]> fa) {
309 $type$[] a = fa.apply(SPECIES.length());
310 $type$[] r = new $type$[a.length];
311
312 for (int ic = 0; ic < INVOC_COUNT; ic++) {
313 for (int i = 0; i < a.length; i += SPECIES.length()) {
314 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
315 av.intoArray(r, i);
316 }
317 }
318 Assert.assertEquals(r, a);
319 }
320
321 @Test(dataProvider = "$type$ProviderForIOOBE")
322 static void loadArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
323 $type$[] a = fa.apply(SPECIES.length());
324 $type$[] r = new $type$[a.length];
325
326 for (int ic = 0; ic < INVOC_COUNT; ic++) {
457 }
458 }
459
460
461 @Test(dataProvider = "$type$MaskProvider")
462 static void loadStoreMask(IntFunction<$type$[]> fa,
463 IntFunction<boolean[]> fm) {
464 boolean[] mask = fm.apply(SPECIES.length());
465 boolean[] r = new boolean[mask.length];
466
467 for (int ic = 0; ic < INVOC_COUNT; ic++) {
468 for (int i = 0; i < mask.length; i += SPECIES.length()) {
469 VectorMask<$Boxtype$> vmask = VectorMask.fromArray(SPECIES, mask, i);
470 vmask.intoArray(r, i);
471 }
472 }
473 Assert.assertEquals(r, mask);
474 }
475
476
477 @Test(dataProvider = "$type$MemorySegmentProvider")
478 static void loadStoreMemorySegment(IntFunction<$type$[]> fa,
479 IntFunction<MemorySegment> fb,
480 ByteOrder bo) {
481 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb);
482 MemorySegment r = fb.apply((int) a.byteSize());
483
484 int l = (int) a.byteSize();
485 int s = SPECIES.vectorByteSize();
486
487 for (int ic = 0; ic < INVOC_COUNT; ic++) {
488 for (int i = 0; i < l; i += s) {
489 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
490 av.intoMemorySegment(r, i, bo);
491 }
492 }
493 long m = r.mismatch(a);
494 Assert.assertEquals(m, -1, "Segments not equal");
495 }
496
497 @Test(dataProvider = "$type$ByteProviderForIOOBE")
498 static void loadMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
499 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
500 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
501
502 int l = (int) a.byteSize();
503 int s = SPECIES.vectorByteSize();
504
505 for (int ic = 0; ic < INVOC_COUNT; ic++) {
506 for (int i = 0; i < l; i += s) {
507 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder());
508 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
509 }
510 }
511
512 int index = fi.apply((int) a.byteSize());
513 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
514 try {
515 fromMemorySegment(a, index, ByteOrder.nativeOrder());
516 if (shouldFail) {
517 Assert.fail("Failed to throw IndexOutOfBoundsException");
518 }
519 } catch (IndexOutOfBoundsException e) {
520 if (!shouldFail) {
521 Assert.fail("Unexpected IndexOutOfBoundsException");
522 }
523 }
524 }
525
526 @Test(dataProvider = "$type$ByteProviderForIOOBE")
527 static void storeMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) {
528 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
529 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
530
531 int l = (int) a.byteSize();
532 int s = SPECIES.vectorByteSize();
533
534 for (int ic = 0; ic < INVOC_COUNT; ic++) {
535 for (int i = 0; i < l; i += s) {
536 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
537 intoMemorySegment(av, r, i, ByteOrder.nativeOrder());
538 }
539 }
540
541 int index = fi.apply((int) a.byteSize());
542 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize());
543 try {
544 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
545 intoMemorySegment(av, r, index, ByteOrder.nativeOrder());
546 if (shouldFail) {
547 Assert.fail("Failed to throw IndexOutOfBoundsException");
548 }
549 } catch (IndexOutOfBoundsException e) {
550 if (!shouldFail) {
551 Assert.fail("Unexpected IndexOutOfBoundsException");
552 }
553 }
554 }
555
556 @Test(dataProvider = "$type$MemorySegmentMaskProvider")
557 static void loadStoreMemorySegmentMask(IntFunction<$type$[]> fa,
558 IntFunction<MemorySegment> fb,
559 IntFunction<boolean[]> fm,
560 ByteOrder bo) {
561 $type$[] _a = fa.apply(SPECIES.length());
562 MemorySegment a = toSegment(_a, fb);
563 MemorySegment r = fb.apply((int) a.byteSize());
564 boolean[] mask = fm.apply(SPECIES.length());
565 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
566
567 int l = (int) a.byteSize();
568 int s = SPECIES.vectorByteSize();
569
570 for (int ic = 0; ic < INVOC_COUNT; ic++) {
571 for (int i = 0; i < l; i += s) {
572 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, vmask);
573 av.intoMemorySegment(r, i, bo);
574 }
575 }
576 assertArraysEquals(segmentToArray(r), _a, mask);
577
578
579 r = fb.apply((int) a.byteSize());
580
581 for (int ic = 0; ic < INVOC_COUNT; ic++) {
582 for (int i = 0; i < l; i += s) {
583 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo);
584 av.intoMemorySegment(r, i, bo, vmask);
585 }
586 }
587 assertArraysEquals(segmentToArray(r), _a, mask);
588 }
589
590 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
591 static void loadMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
592 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
593 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
594 boolean[] mask = fm.apply(SPECIES.length());
595 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
596
597 int l = (int) a.byteSize();
598 int s = SPECIES.vectorByteSize();
599
600 for (int ic = 0; ic < INVOC_COUNT; ic++) {
601 for (int i = 0; i < l; i += s) {
602 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask);
603 av.intoMemorySegment(r, i, ByteOrder.nativeOrder());
604 }
605 }
606
607 int index = fi.apply((int) a.byteSize());
608 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
609 try {
610 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask);
611 if (shouldFail) {
612 Assert.fail("Failed to throw IndexOutOfBoundsException");
613 }
614 } catch (IndexOutOfBoundsException e) {
615 if (!shouldFail) {
616 Assert.fail("Unexpected IndexOutOfBoundsException");
617 }
618 }
619 }
620
621 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE")
622 static void storeMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
623 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope()));
624 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope());
625 boolean[] mask = fm.apply(SPECIES.length());
626 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask);
627
628 int l = (int) a.byteSize();
629 int s = SPECIES.vectorByteSize();
630
631 for (int ic = 0; ic < INVOC_COUNT; ic++) {
632 for (int i = 0; i < l; i += s) {
633 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder());
634 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask);
635 }
636 }
637
638 int index = fi.apply((int) a.byteSize());
639 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8);
640 try {
641 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder());
642 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask);
643 if (shouldFail) {
644 Assert.fail("Failed to throw IndexOutOfBoundsException");
645 }
646 } catch (IndexOutOfBoundsException e) {
647 if (!shouldFail) {
648 Assert.fail("Unexpected IndexOutOfBoundsException");
649 }
650 }
651 }
652
653 @Test(dataProvider = "$type$MemorySegmentProvider")
654 static void loadStoreReadonlyMemorySegment(IntFunction<$type$[]> fa,
655 IntFunction<MemorySegment> fb,
656 ByteOrder bo) {
657 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly();
658
659 Assert.assertThrows(
660 UnsupportedOperationException.class,
661 () -> SPECIES.zero().intoMemorySegment(a, 0, bo)
662 );
663
664 Assert.assertThrows(
665 UnsupportedOperationException.class,
666 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true))
667 );
668
669 Assert.assertThrows(
670 UnsupportedOperationException.class,
671 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false))
672 );
673
674 VectorMask<$Boxtype$> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
675 .laneIsValid();
676 Assert.assertThrows(
677 UnsupportedOperationException.class,
678 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m)
679 );
680 }
681
682
683 @Test(dataProvider = "maskProvider")
684 static void loadStoreMask(IntFunction<boolean[]> fm) {
685 boolean[] a = fm.apply(SPECIES.length());
686 boolean[] r = new boolean[a.length];
687
688 for (int ic = 0; ic < INVOC_COUNT; ic++) {
689 for (int i = 0; i < a.length; i += SPECIES.length()) {
690 VectorMask<$Boxtype$> vmask = SPECIES.loadMask(a, i);
691 vmask.intoArray(r, i);
692 }
693 }
694 Assert.assertEquals(r, a);
695 }
696
697
698 @Test
699 static void loadStoreShuffle() {
700 IntUnaryOperator fn = a -> a + 5;
701 for (int ic = 0; ic < INVOC_COUNT; ic++) {
702 var shuffle = VectorShuffle.fromOp(SPECIES, fn);
703 int [] r = shuffle.toArray();
704
705 int [] a = expectedShuffle(SPECIES.length(), fn);
706 Assert.assertEquals(r, a);
707 }
708 }
709
710
711 #if[short]
712 static void assertArraysEquals(char[] a, char[] r, boolean[] mask) {
713 int i = 0;
714 try {
715 for (; i < a.length; i++) {
716 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]);
717 }
|