1 /*
2 * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @modules jdk.incubator.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation
27 * @run testng/othervm -XX:-TieredCompilation Byte64VectorLoadStoreTests
28 *
29 */
30
31 // -- This file was mechanically generated: Do not edit! -- //
32
33 import jdk.incubator.vector.ByteVector;
34 import jdk.incubator.vector.VectorMask;
35 import jdk.incubator.vector.VectorSpecies;
36 import jdk.incubator.vector.VectorShuffle;
37 import jdk.internal.vm.annotation.DontInline;
38 import org.testng.Assert;
39 import org.testng.annotations.DataProvider;
40 import org.testng.annotations.Test;
41
42 import java.nio.ByteBuffer;
43 import java.nio.ByteOrder;
44 import java.nio.ReadOnlyBufferException;
45 import java.util.List;
46 import java.util.function.*;
47
48 @Test
49 public class Byte64VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
50 static final VectorSpecies<Byte> SPECIES =
51 ByteVector.SPECIES_64;
52
53 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
54
55
56 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 64);
57
58 static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
59 int i = 0;
60 try {
61 for (; i < a.length; i++) {
62 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0);
63 }
64 } catch (AssertionError e) {
65 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
66 }
67 }
68
69
70 static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
71 withToString("byte[i * 5]", (int s) -> {
72 return fill(s * BUFFER_REPS,
73 i -> (byte)(i * 5));
74 }),
75 withToString("byte[i + 1]", (int s) -> {
76 return fill(s * BUFFER_REPS,
77 i -> (((byte)(i + 1) == 0) ? 1 : (byte)(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 ByteBuffer.limit()
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) -> {
160 @DataProvider
161 public Object[][] byteMaskProvider() {
162 return BOOLEAN_MASK_GENERATORS.stream().
163 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> {
164 return new Object[] {fa, fm};
165 })).
166 toArray(Object[][]::new);
167 }
168
169 @DataProvider
170 public Object[][] byteMaskProviderForIOOBE() {
171 var f = BYTE_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[][] byteByteBufferProvider() {
181 return BYTE_GENERATORS.stream().
182 flatMap(fa -> BYTE_BUFFER_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[][] byteByteBufferMaskProvider() {
191 return BOOLEAN_MASK_GENERATORS.stream().
192 flatMap(fm -> BYTE_GENERATORS.stream().
193 flatMap(fa -> BYTE_BUFFER_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[][] byteByteArrayProvider() {
202 return BYTE_GENERATORS.stream().
203 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
204 return new Object[]{fa, bo};
205 })).
206 toArray(Object[][]::new);
207 }
208
209 @DataProvider
210 public Object[][] byteByteArrayMaskProvider() {
211 return BOOLEAN_MASK_GENERATORS.stream().
212 flatMap(fm -> BYTE_GENERATORS.stream().
213 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
214 return new Object[]{fa, fm, bo};
215 }))).
216 toArray(Object[][]::new);
217 }
218
219 @DataProvider
220 public Object[][] byteByteProviderForIOOBE() {
221 var f = BYTE_GENERATORS.get(0);
222 return BYTE_INDEX_GENERATORS.stream().map(fi -> {
223 return new Object[] {f, fi};
224 }).
225 toArray(Object[][]::new);
226 }
227
228 @DataProvider
229 public Object[][] byteByteMaskProviderForIOOBE() {
230 var f = BYTE_GENERATORS.get(0);
231 return BOOLEAN_MASK_GENERATORS.stream().
232 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
233 return new Object[] {f, fi, fm};
234 })).
235 toArray(Object[][]::new);
236 }
237
238 static ByteBuffer toBuffer(byte[] a, IntFunction<ByteBuffer> fb) {
239 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
240 for (byte v : a) {
241 bb.put(v);
242 }
243 return bb.clear();
244 }
245
246 static byte[] bufferToArray(ByteBuffer bb) {
247 ByteBuffer db = bb;
248 byte[] d = new byte[db.capacity()];
249 db.get(0, d);
250 return d;
251 }
252
253 static byte[] toByteArray(byte[] a, IntFunction<byte[]> fb, ByteOrder bo) {
254 byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
255 ByteBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo);
256 for (byte v : a) {
257 bb.put(v);
258 }
259 return b;
260 }
261
262
263 interface ToByteF {
264 byte apply(int i);
265 }
266
267 static byte[] fill(int s , ToByteF f) {
268 return fill(new byte[s], f);
269 }
270
271 static byte[] fill(byte[] a, ToByteF f) {
272 for (int i = 0; i < a.length; i++) {
273 a[i] = f.apply(i);
274 }
275 return a;
276 }
277
278 @DontInline
279 static ByteVector fromArray(byte[] a, int i) {
280 return ByteVector.fromArray(SPECIES, a, i);
281 }
282
283 @DontInline
284 static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) {
285 return ByteVector.fromArray(SPECIES, a, i, m);
286 }
287
288 @DontInline
289 static void intoArray(ByteVector v, byte[] a, int i) {
290 v.intoArray(a, i);
291 }
292
293 @DontInline
294 static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) {
295 v.intoArray(a, i, m);
296 }
297
298 @DontInline
299 static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo) {
300 return ByteVector.fromByteArray(SPECIES, a, i, bo);
301 }
302
303 @DontInline
304 static ByteVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
305 return ByteVector.fromByteArray(SPECIES, a, i, bo, m);
306 }
307
308 @DontInline
309 static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo) {
310 v.intoByteArray(a, i, bo);
311 }
312
313 @DontInline
314 static void intoByteArray(ByteVector v, byte[] a, int i, ByteOrder bo, VectorMask<Byte> m) {
315 v.intoByteArray(a, i, bo, m);
316 }
317
318 @DontInline
319 static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
320 return ByteVector.fromByteBuffer(SPECIES, a, i, bo);
321 }
322
323 @DontInline
324 static ByteVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
325 return ByteVector.fromByteBuffer(SPECIES, a, i, bo, m);
326 }
327
328 @DontInline
329 static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo) {
330 v.intoByteBuffer(a, i, bo);
331 }
332
333 @DontInline
334 static void intoByteBuffer(ByteVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Byte> m) {
335 v.intoByteBuffer(a, i, bo, m);
336 }
337
338
339 @Test(dataProvider = "byteProvider")
340 static void loadStoreArray(IntFunction<byte[]> fa) {
341 byte[] a = fa.apply(SPECIES.length());
342 byte[] r = new byte[a.length];
343
344 for (int ic = 0; ic < INVOC_COUNT; ic++) {
345 for (int i = 0; i < a.length; i += SPECIES.length()) {
346 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
347 av.intoArray(r, i);
348 }
349 }
350 Assert.assertEquals(r, a);
351 }
352
353 @Test(dataProvider = "byteProviderForIOOBE")
354 static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
355 byte[] a = fa.apply(SPECIES.length());
356 byte[] r = new byte[a.length];
357
358 for (int ic = 0; ic < INVOC_COUNT; ic++) {
489 }
490 }
491
492
493 @Test(dataProvider = "byteMaskProvider")
494 static void loadStoreMask(IntFunction<byte[]> fa,
495 IntFunction<boolean[]> fm) {
496 boolean[] mask = fm.apply(SPECIES.length());
497 boolean[] r = new boolean[mask.length];
498
499 for (int ic = 0; ic < INVOC_COUNT; ic++) {
500 for (int i = 0; i < mask.length; i += SPECIES.length()) {
501 VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i);
502 vmask.intoArray(r, i);
503 }
504 }
505 Assert.assertEquals(r, mask);
506 }
507
508
509 @Test(dataProvider = "byteByteBufferProvider")
510 static void loadStoreByteBuffer(IntFunction<byte[]> fa,
511 IntFunction<ByteBuffer> fb,
512 ByteOrder bo) {
513 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
514 ByteBuffer r = fb.apply(a.limit());
515
516 int l = a.limit();
517 int s = SPECIES.vectorByteSize();
518
519 for (int ic = 0; ic < INVOC_COUNT; ic++) {
520 for (int i = 0; i < l; i += s) {
521 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
522 av.intoByteBuffer(r, i, bo);
523 }
524 }
525 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
526 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
527 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
528 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
529 Assert.assertEquals(r, a, "Buffers not equal");
530 }
531
532 @Test(dataProvider = "byteByteProviderForIOOBE")
533 static void loadByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
534 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
535 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
536
537 int l = a.limit();
538 int s = SPECIES.vectorByteSize();
539
540 for (int ic = 0; ic < INVOC_COUNT; ic++) {
541 for (int i = 0; i < l; i += s) {
542 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
543 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
544 }
545 }
546
547 int index = fi.apply(a.limit());
548 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
549 try {
550 fromByteBuffer(a, index, ByteOrder.nativeOrder());
551 if (shouldFail) {
552 Assert.fail("Failed to throw IndexOutOfBoundsException");
553 }
554 } catch (IndexOutOfBoundsException e) {
555 if (!shouldFail) {
556 Assert.fail("Unexpected IndexOutOfBoundsException");
557 }
558 }
559 }
560
561 @Test(dataProvider = "byteByteProviderForIOOBE")
562 static void storeByteBufferIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
563 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
564 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
565
566 int l = a.limit();
567 int s = SPECIES.vectorByteSize();
568
569 for (int ic = 0; ic < INVOC_COUNT; ic++) {
570 for (int i = 0; i < l; i += s) {
571 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
572 intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
573 }
574 }
575
576 int index = fi.apply(a.limit());
577 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
578 try {
579 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
580 intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
581 if (shouldFail) {
582 Assert.fail("Failed to throw IndexOutOfBoundsException");
583 }
584 } catch (IndexOutOfBoundsException e) {
585 if (!shouldFail) {
586 Assert.fail("Unexpected IndexOutOfBoundsException");
587 }
588 }
589 }
590
591
592 @Test(dataProvider = "byteByteBufferMaskProvider")
593 static void loadStoreByteBufferMask(IntFunction<byte[]> fa,
594 IntFunction<ByteBuffer> fb,
595 IntFunction<boolean[]> fm,
596 ByteOrder bo) {
597 byte[] _a = fa.apply(SPECIES.length());
598 ByteBuffer a = toBuffer(_a, fb);
599 ByteBuffer r = fb.apply(a.limit());
600 boolean[] mask = fm.apply(SPECIES.length());
601 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
602
603 int l = a.limit();
604 int s = SPECIES.vectorByteSize();
605
606 for (int ic = 0; ic < INVOC_COUNT; ic++) {
607 for (int i = 0; i < l; i += s) {
608 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
609 av.intoByteBuffer(r, i, bo);
610 }
611 }
612 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
613 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
614 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
615 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
616 assertArraysEquals(bufferToArray(r), _a, mask);
617
618
619 r = fb.apply(a.limit());
620
621 for (int ic = 0; ic < INVOC_COUNT; ic++) {
622 for (int i = 0; i < l; i += s) {
623 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, bo);
624 av.intoByteBuffer(r, i, bo, vmask);
625 }
626 }
627 Assert.assertEquals(a.position(), 0, "Input buffer position changed");
628 Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
629 Assert.assertEquals(r.position(), 0, "Result buffer position changed");
630 Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
631 assertArraysEquals(bufferToArray(r), _a, mask);
632 }
633
634 @Test(dataProvider = "byteByteMaskProviderForIOOBE")
635 static void loadByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
636 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
637 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
638 boolean[] mask = fm.apply(SPECIES.length());
639 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
640
641 int l = a.limit();
642 int s = SPECIES.vectorByteSize();
643
644 for (int ic = 0; ic < INVOC_COUNT; ic++) {
645 for (int i = 0; i < l; i += s) {
646 ByteVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
647 av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
648 }
649 }
650
651 int index = fi.apply(a.limit());
652 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
653 try {
654 fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
655 if (shouldFail) {
656 Assert.fail("Failed to throw IndexOutOfBoundsException");
657 }
658 } catch (IndexOutOfBoundsException e) {
659 if (!shouldFail) {
660 Assert.fail("Unexpected IndexOutOfBoundsException");
661 }
662 }
663 }
664
665 @Test(dataProvider = "byteByteMaskProviderForIOOBE")
666 static void storeByteBufferMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
667 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
668 ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
669 boolean[] mask = fm.apply(SPECIES.length());
670 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
671
672 int l = a.limit();
673 int s = SPECIES.vectorByteSize();
674
675 for (int ic = 0; ic < INVOC_COUNT; ic++) {
676 for (int i = 0; i < l; i += s) {
677 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
678 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
679 }
680 }
681
682 int index = fi.apply(a.limit());
683 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
684 try {
685 ByteVector av = ByteVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
686 intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
687 if (shouldFail) {
688 Assert.fail("Failed to throw IndexOutOfBoundsException");
689 }
690 } catch (IndexOutOfBoundsException e) {
691 if (!shouldFail) {
692 Assert.fail("Unexpected IndexOutOfBoundsException");
693 }
694 }
695 }
696
697
698 @Test(dataProvider = "byteByteBufferProvider")
699 static void loadStoreReadonlyByteBuffer(IntFunction<byte[]> fa,
700 IntFunction<ByteBuffer> fb,
701 ByteOrder bo) {
702 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
703
704 try {
705 SPECIES.zero().intoByteBuffer(a, 0, bo);
706 Assert.fail("ReadOnlyBufferException expected");
707 } catch (ReadOnlyBufferException e) {
708 }
709
710 try {
711 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
712 Assert.fail("ReadOnlyBufferException expected");
713 } catch (ReadOnlyBufferException e) {
714 }
715
716 try {
717 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
718 Assert.fail("ReadOnlyBufferException expected");
719 } catch (ReadOnlyBufferException e) {
720 }
721
722 try {
723 VectorMask<Byte> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
724 .laneIsValid();
725 SPECIES.zero().intoByteBuffer(a, 0, bo, m);
726 Assert.fail("ReadOnlyBufferException expected");
727 } catch (ReadOnlyBufferException e) {
728 }
729 }
730
731
732 @Test(dataProvider = "byteByteArrayProvider")
733 static void loadStoreByteArray(IntFunction<byte[]> fa,
734 ByteOrder bo) {
735 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
736 byte[] r = new byte[a.length];
737
738 int s = SPECIES.vectorByteSize();
739 int l = a.length;
740
741 for (int ic = 0; ic < INVOC_COUNT; ic++) {
742 for (int i = 0; i < l; i += s) {
743 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
744 av.intoByteArray(r, i, bo);
745 }
746 }
747 Assert.assertEquals(r, a, "Byte arrays not equal");
748 }
749
750 @Test(dataProvider = "byteByteProviderForIOOBE")
751 static void loadByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
752 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
753 byte[] r = new byte[a.length];
754
755 int s = SPECIES.vectorByteSize();
756 int l = a.length;
757
758 for (int ic = 0; ic < INVOC_COUNT; ic++) {
759 for (int i = 0; i < l; i += s) {
760 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
761 av.intoByteArray(r, i, ByteOrder.nativeOrder());
762 }
763 }
764
765 int index = fi.apply(a.length);
766 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
767 try {
768 fromByteArray(a, index, ByteOrder.nativeOrder());
769 if (shouldFail) {
770 Assert.fail("Failed to throw IndexOutOfBoundsException");
771 }
772 } catch (IndexOutOfBoundsException e) {
773 if (!shouldFail) {
774 Assert.fail("Unexpected IndexOutOfBoundsException");
775 }
776 }
777 }
778
779 @Test(dataProvider = "byteByteProviderForIOOBE")
780 static void storeByteArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
781 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
782 byte[] r = new byte[a.length];
783
784 int s = SPECIES.vectorByteSize();
785 int l = a.length;
786
787 for (int ic = 0; ic < INVOC_COUNT; ic++) {
788 for (int i = 0; i < l; i += s) {
789 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
790 intoByteArray(av, r, i, ByteOrder.nativeOrder());
791 }
792 }
793
794 int index = fi.apply(a.length);
795 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
796 try {
797 ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
798 intoByteArray(av, r, index, ByteOrder.nativeOrder());
799 if (shouldFail) {
800 Assert.fail("Failed to throw IndexOutOfBoundsException");
801 }
802 } catch (IndexOutOfBoundsException e) {
803 if (!shouldFail) {
804 Assert.fail("Unexpected IndexOutOfBoundsException");
805 }
806 }
807 }
808
809
810 @Test(dataProvider = "byteByteArrayMaskProvider")
811 static void loadStoreByteArrayMask(IntFunction<byte[]> fa,
812 IntFunction<boolean[]> fm,
813 ByteOrder bo) {
814 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
815 byte[] r = new byte[a.length];
816 boolean[] mask = fm.apply(SPECIES.length());
817 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
818
819 int s = SPECIES.vectorByteSize();
820 int l = a.length;
821
822 for (int ic = 0; ic < INVOC_COUNT; ic++) {
823 for (int i = 0; i < l; i += s) {
824 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo, vmask);
825 av.intoByteArray(r, i, bo);
826 }
827 }
828 assertArraysEquals(r, a, mask);
829
830
831 r = new byte[a.length];
832
833 for (int ic = 0; ic < INVOC_COUNT; ic++) {
834 for (int i = 0; i < l; i += s) {
835 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, bo);
836 av.intoByteArray(r, i, bo, vmask);
837 }
838 }
839 assertArraysEquals(r, a, mask);
840 }
841
842 @Test(dataProvider = "byteByteMaskProviderForIOOBE")
843 static void loadByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
844 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
845 byte[] r = new byte[a.length];
846 boolean[] mask = fm.apply(SPECIES.length());
847 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
848
849 int s = SPECIES.vectorByteSize();
850 int l = a.length;
851
852 for (int ic = 0; ic < INVOC_COUNT; ic++) {
853 for (int i = 0; i < l; i += s) {
854 ByteVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
855 av.intoByteArray(r, i, ByteOrder.nativeOrder());
856 }
857 }
858
859 int index = fi.apply(a.length);
860 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
861 try {
862 fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
863 if (shouldFail) {
864 Assert.fail("Failed to throw IndexOutOfBoundsException");
865 }
866 } catch (IndexOutOfBoundsException e) {
867 if (!shouldFail) {
868 Assert.fail("Unexpected IndexOutOfBoundsException");
869 }
870 }
871 }
872
873 @Test(dataProvider = "byteByteMaskProviderForIOOBE")
874 static void storeByteArrayMaskIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
875 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
876 byte[] r = new byte[a.length];
877 boolean[] mask = fm.apply(SPECIES.length());
878 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask);
879
880 int s = SPECIES.vectorByteSize();
881 int l = a.length;
882
883 for (int ic = 0; ic < INVOC_COUNT; ic++) {
884 for (int i = 0; i < l; i += s) {
885 ByteVector av = ByteVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
886 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
887 }
888 }
889
890 int index = fi.apply(a.length);
891 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
892 try {
893 ByteVector av = ByteVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
894 intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
895 if (shouldFail) {
896 Assert.fail("Failed to throw IndexOutOfBoundsException");
897 }
898 } catch (IndexOutOfBoundsException e) {
899 if (!shouldFail) {
900 Assert.fail("Unexpected IndexOutOfBoundsException");
901 }
902 }
903 }
904
905 @Test(dataProvider = "maskProvider")
906 static void loadStoreMask(IntFunction<boolean[]> fm) {
907 boolean[] a = fm.apply(SPECIES.length());
908 boolean[] r = new boolean[a.length];
909
910 for (int ic = 0; ic < INVOC_COUNT; ic++) {
911 for (int i = 0; i < a.length; i += SPECIES.length()) {
912 VectorMask<Byte> vmask = SPECIES.loadMask(a, i);
913 vmask.intoArray(r, i);
914 }
915 }
916 Assert.assertEquals(r, a);
917 }
918
919 @Test
920 static void loadStoreShuffle() {
921 IntUnaryOperator fn = a -> a + 5;
922 for (int ic = 0; ic < INVOC_COUNT; ic++) {
923 var shuffle = VectorShuffle.fromOp(SPECIES, fn);
924 int [] r = shuffle.toArray();
925
926 int [] a = expectedShuffle(SPECIES.length(), fn);
927 Assert.assertEquals(r, a);
928 }
929 }
930
931
932
933 static void assertArraysEquals(boolean[] r, byte[] a) {
934 int i = 0;
935 try {
936 for (; i < a.length; i++) {
937 Assert.assertEquals(r[i], (a[i] & 1) == 1);
938 }
|
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 Byte64VectorLoadStoreTests
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.ByteVector;
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 Byte64VectorLoadStoreTests extends AbstractVectorLoadStoreTest {
51 static final VectorSpecies<Byte> SPECIES =
52 ByteVector.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(byte[] r, byte[] 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] : (byte) 0);
64 }
65 } catch (AssertionError e) {
66 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
67 }
68 }
69
70 static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
71 withToString("byte[i * 5]", (int s) -> {
72 return fill(s * BUFFER_REPS,
73 i -> (byte)(i * 5));
74 }),
75 withToString("byte[i + 1]", (int s) -> {
76 return fill(s * BUFFER_REPS,
77 i -> (((byte)(i + 1) == 0) ? 1 : (byte)(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) -> {
160 @DataProvider
161 public Object[][] byteMaskProvider() {
162 return BOOLEAN_MASK_GENERATORS.stream().
163 flatMap(fm -> BYTE_GENERATORS.stream().map(fa -> {
164 return new Object[] {fa, fm};
165 })).
166 toArray(Object[][]::new);
167 }
168
169 @DataProvider
170 public Object[][] byteMaskProviderForIOOBE() {
171 var f = BYTE_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[][] byteMemorySegmentProvider() {
181 return BYTE_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[][] byteMemorySegmentMaskProvider() {
191 return BOOLEAN_MASK_GENERATORS.stream().
192 flatMap(fm -> BYTE_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[][] byteByteProviderForIOOBE() {
202 var f = BYTE_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[][] byteByteMaskProviderForIOOBE() {
211 var f = BYTE_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(byte[] 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_BYTE, i * SPECIES.elementSize() / 8 , a[i]);
223 }
224 return ms;
225 }
226
227 static byte[] segmentToArray(MemorySegment ms) {
228 return ms.toArray(ValueLayout.JAVA_BYTE);
229 }
230
231
232 interface ToByteF {
233 byte apply(int i);
234 }
235
236 static byte[] fill(int s , ToByteF f) {
237 return fill(new byte[s], f);
238 }
239
240 static byte[] fill(byte[] a, ToByteF 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 ByteVector fromArray(byte[] a, int i) {
249 return ByteVector.fromArray(SPECIES, a, i);
250 }
251
252 @DontInline
253 static ByteVector fromArray(byte[] a, int i, VectorMask<Byte> m) {
254 return ByteVector.fromArray(SPECIES, a, i, m);
255 }
256
257 @DontInline
258 static void intoArray(ByteVector v, byte[] a, int i) {
259 v.intoArray(a, i);
260 }
261
262 @DontInline
263 static void intoArray(ByteVector v, byte[] a, int i, VectorMask<Byte> m) {
264 v.intoArray(a, i, m);
265 }
266
267 @DontInline
268 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) {
269 return ByteVector.fromMemorySegment(SPECIES, a, i, bo);
270 }
271
272 @DontInline
273 static ByteVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) {
274 return ByteVector.fromMemorySegment(SPECIES, a, i, bo, m);
275 }
276
277 @DontInline
278 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo) {
279 v.intoMemorySegment(a, i, bo);
280 }
281
282 @DontInline
283 static void intoMemorySegment(ByteVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Byte> m) {
284 v.intoMemorySegment(a, i, bo, m);
285 }
286
287 @Test(dataProvider = "byteProvider")
288 static void loadStoreArray(IntFunction<byte[]> fa) {
289 byte[] a = fa.apply(SPECIES.length());
290 byte[] r = new byte[a.length];
291
292 for (int ic = 0; ic < INVOC_COUNT; ic++) {
293 for (int i = 0; i < a.length; i += SPECIES.length()) {
294 ByteVector av = ByteVector.fromArray(SPECIES, a, i);
295 av.intoArray(r, i);
296 }
297 }
298 Assert.assertEquals(r, a);
299 }
300
301 @Test(dataProvider = "byteProviderForIOOBE")
302 static void loadArrayIOOBE(IntFunction<byte[]> fa, IntFunction<Integer> fi) {
303 byte[] a = fa.apply(SPECIES.length());
304 byte[] r = new byte[a.length];
305
306 for (int ic = 0; ic < INVOC_COUNT; ic++) {
437 }
438 }
439
440
441 @Test(dataProvider = "byteMaskProvider")
442 static void loadStoreMask(IntFunction<byte[]> 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<Byte> vmask = VectorMask.fromArray(SPECIES, mask, i);
450 vmask.intoArray(r, i);
451 }
452 }
453 Assert.assertEquals(r, mask);
454 }
455
456
457 @Test(dataProvider = "byteMemorySegmentProvider")
458 static void loadStoreMemorySegment(IntFunction<byte[]> 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 ByteVector av = ByteVector.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 = "byteByteProviderForIOOBE")
478 static void loadMemorySegmentIOOBE(IntFunction<byte[]> 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 ByteVector 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 = "byteByteProviderForIOOBE")
507 static void storeMemorySegmentIOOBE(IntFunction<byte[]> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMemorySegmentMaskProvider")
537 static void loadStoreMemorySegmentMask(IntFunction<byte[]> fa,
538 IntFunction<MemorySegment> fb,
539 IntFunction<boolean[]> fm,
540 ByteOrder bo) {
541 byte[] _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<Byte> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteByteMaskProviderForIOOBE")
571 static void loadMemorySegmentMaskIOOBE(IntFunction<byte[]> 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<Byte> 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 ByteVector 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 = "byteByteMaskProviderForIOOBE")
602 static void storeMemorySegmentMaskIOOBE(IntFunction<byte[]> 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<Byte> 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 ByteVector av = ByteVector.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 ByteVector av = ByteVector.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 = "byteMemorySegmentProvider")
634 static void loadStoreReadonlyMemorySegment(IntFunction<byte[]> 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<Byte> 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<Byte> 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 static void assertArraysEquals(boolean[] r, byte[] a) {
693 int i = 0;
694 try {
695 for (; i < a.length; i++) {
696 Assert.assertEquals(r[i], (a[i] & 1) == 1);
697 }
|