1 /*
2 * Copyright (c) 2020, 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 import jdk.incubator.vector.*;
24 import jdk.internal.vm.annotation.ForceInline;
25 import org.testng.Assert;
26 import org.testng.annotations.Test;
27 import org.testng.annotations.DataProvider;
28
29 import java.lang.invoke.MethodHandles;
30 import java.lang.invoke.VarHandle;
31 import java.nio.ByteOrder;
32 import java.util.Arrays;
33 import java.util.List;
34 import java.util.function.IntFunction;
35 import jdk.incubator.vector.VectorShape;
36 import jdk.incubator.vector.VectorSpecies;
37
38 /**
39 * @test
40 * @modules jdk.incubator.vector
41 * @modules java.base/jdk.internal.vm.annotation
42 * @run testng/othervm/timeout=240 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
43 * -XX:-TieredCompilation VectorReshapeTests
44 */
45
46 @Test
47 public class VectorReshapeTests {
48 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
49 static final int NUM_ITER = 200 * INVOC_COUNT;
50
315 else if (asize < bsize) assert(partLimit < 0);
316 else assert(partLimit == 0);
317 return partLimit;
318 }
319
320 @ForceInline
321 static <E>
322 void testVectorReshape(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output) {
323 testVectorReshape(a, b, input, output, false);
324 testVectorReshapeLanewise(a, b, input, output);
325 }
326 @ForceInline
327 static <E>
328 void testVectorReshapeLanewise(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output) {
329 testVectorReshape(a, b, input, output, true);
330 }
331 @ForceInline
332 static <E>
333 void testVectorReshape(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output, boolean lanewise) {
334 Class<?> atype = a.elementType(), btype = b.elementType();
335 Vector<E> av = a.fromByteArray(input, 0, ByteOrder.nativeOrder());
336 int partLimit = partLimit(a, b, lanewise);
337 int block = Math.min(a.vectorByteSize(), b.vectorByteSize());
338 if (false)
339 System.out.println("testing "+a+"->"+b+
340 (lanewise?" (lanewise)":" (reinterpret)")+
341 ", partLimit=" + partLimit +
342 ", block=" + block);
343 byte[] expected;
344 int origin;
345 if (partLimit > 0) {
346 for (int part = 0; part < partLimit; part++) {
347 Vector<E> bv = (lanewise
348 ? av.castShape(b, part)
349 : av.reinterpretShape(b, part));
350 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
351 // expansion: slice some of the input
352 origin = part * block;
353 expected = Arrays.copyOfRange(input, origin, origin + block);
354 if (lanewise) {
355 expected = castByteArrayData(expected, atype, btype);
356 }
357 checkPartialResult(a, b, input, output, expected,
358 lanewise, part, origin);
359 }
360 } else if (partLimit < 0) {
361 for (int part = 0; part > partLimit; part--) {
362 Vector<E> bv = (lanewise
363 ? av.castShape(b, part)
364 : av.reinterpretShape(b, part));
365 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
366 // contraction: unslice the input into part of the output
367 byte[] logical = input;
368 if (lanewise) {
369 logical = castByteArrayData(input, atype, btype);
370 }
371 assert(logical.length == block);
372 expected = new byte[output.length];
373 origin = -part * block;
374 System.arraycopy(logical, 0, expected, origin, block);
375 checkPartialResult(a, b, input, output, expected,
376 lanewise, part, origin);
377 }
378 } else {
379 int part = 0;
380 Vector<E> bv = (lanewise
381 ? av.castShape(b, part)
382 : av.reinterpretShape(b, part));
383 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
384 // in-place copy, no resize
385 expected = input;
386 origin = 0;
387 if (lanewise) {
388 expected = castByteArrayData(expected, atype, btype);
389 }
390 checkPartialResult(a, b, input, output, expected,
391 lanewise, part, origin);
392 }
393 }
394
395 static
396 void checkPartialResult(VectorSpecies<?> a, VectorSpecies<?> b,
397 byte[] input, byte[] output, byte[] expected,
398 boolean lanewise, int part, int origin) {
399 if (Arrays.equals(expected, output)) {
400 return;
401 }
402 int partLimit = partLimit(a, b, lanewise);
403 int block;
692 testVectorReshape(dspecMax, dspec256, binMax, bout256);
693 testVectorReshape(dspecMax, dspec512, binMax, bout512);
694 testVectorReshape(dspecMax, dspecMax, binMax, boutMax);
695 }
696 }
697 @ForceInline
698 static <E,F>
699 void testVectorRebracket(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output) {
700 testVectorRebracket(a, b, input, output, false);
701 testVectorRebracketLanewise(a, b, input, output);
702 }
703 @ForceInline
704 static <E,F>
705 void testVectorRebracketLanewise(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output) {
706 testVectorRebracket(a, b, input, output, true);
707 }
708 @ForceInline
709 static <E,F>
710 void testVectorRebracket(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output, boolean lanewise) {
711 Class<?> atype = a.elementType(), btype = b.elementType();
712 Vector<E> av = a.fromByteArray(input, 0, ByteOrder.nativeOrder());
713 int partLimit = partLimit(a, b, lanewise);
714 int block;
715 assert(input.length == output.length);
716 if (!lanewise)
717 block = Math.min(a.vectorByteSize(), b.vectorByteSize());
718 else if (partLimit >= 0)
719 block = a.vectorByteSize() / Math.max(1, partLimit);
720 else
721 block = b.vectorByteSize() / -partLimit;
722 if (lanewise) {
723 if (atype == btype) return;
724 if (atype == float.class || atype == double.class) return;
725 if (btype == float.class || btype == double.class) return;
726 }
727 if (false)
728 System.out.println("testing "+a+"->"+b+
729 (lanewise?" (lanewise)":" (reinterpret)")+
730 ", partLimit=" + partLimit +
731 ", block=" + block);
732 byte[] expected;
733 int origin;
734 if (partLimit > 0) {
735 for (int part = 0; part < partLimit; part++) {
736 Vector<F> bv = (lanewise
737 ? av.castShape(b, part)
738 : av.reinterpretShape(b, part));
739 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
740 // expansion: slice some of the input
741 origin = part * block;
742 expected = Arrays.copyOfRange(input, origin, origin + block);
743 if (lanewise) {
744 expected = castByteArrayData(expected, atype, btype);
745 }
746 checkPartialResult(a, b, input, output, expected,
747 lanewise, part, origin);
748 }
749 } else if (partLimit < 0) {
750 for (int part = 0; part > partLimit; part--) {
751 Vector<F> bv = (lanewise
752 ? av.castShape(b, part)
753 : av.reinterpretShape(b, part));
754 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
755 // contraction: unslice the input into part of the output
756 byte[] logical = input;
757 if (lanewise) {
758 logical = castByteArrayData(input, atype, btype);
759 }
760 assert(logical.length == block);
761 expected = new byte[output.length];
762 origin = -part * block;
763 System.arraycopy(logical, 0, expected, origin, block);
764 checkPartialResult(a, b, input, output, expected,
765 lanewise, part, origin);
766 }
767 } else {
768 int part = 0;
769 Vector<F> bv = (lanewise
770 ? av.castShape(b, part)
771 : av.reinterpretShape(b, part));
772 bv.intoByteArray(output, 0, ByteOrder.nativeOrder());
773 // in-place copy, no resize
774 expected = input;
775 origin = 0;
776 if (lanewise) {
777 expected = castByteArrayData(expected, atype, btype);
778 }
779 checkPartialResult(a, b, input, output, expected,
780 lanewise, part, origin);
781 }
782 }
783
784 static int decodeType(Class<?> type) {
785 switch (type.getName().charAt(0)) {
786 case 'b': return 1;
787 case 's': return 2;
788 case 'i': return 4;
789 case 'l': return 8;
790 case 'f': return -4;
791 case 'd': return -8;
792 }
|
1 /*
2 * Copyright (c) 2020, 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 import jdk.incubator.foreign.MemorySegment;
24 import jdk.incubator.vector.*;
25 import jdk.internal.vm.annotation.ForceInline;
26 import org.testng.Assert;
27 import org.testng.annotations.Test;
28 import org.testng.annotations.DataProvider;
29
30 import java.nio.ByteOrder;
31 import java.util.Arrays;
32 import java.util.List;
33 import java.util.function.IntFunction;
34 import jdk.incubator.vector.VectorShape;
35 import jdk.incubator.vector.VectorSpecies;
36
37 /**
38 * @test
39 * @modules jdk.incubator.vector
40 * @modules java.base/jdk.internal.vm.annotation
41 * @run testng/othervm/timeout=240 --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
42 * -XX:-TieredCompilation VectorReshapeTests
43 */
44
45 @Test
46 public class VectorReshapeTests {
47 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
48 static final int NUM_ITER = 200 * INVOC_COUNT;
49
314 else if (asize < bsize) assert(partLimit < 0);
315 else assert(partLimit == 0);
316 return partLimit;
317 }
318
319 @ForceInline
320 static <E>
321 void testVectorReshape(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output) {
322 testVectorReshape(a, b, input, output, false);
323 testVectorReshapeLanewise(a, b, input, output);
324 }
325 @ForceInline
326 static <E>
327 void testVectorReshapeLanewise(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output) {
328 testVectorReshape(a, b, input, output, true);
329 }
330 @ForceInline
331 static <E>
332 void testVectorReshape(VectorSpecies<E> a, VectorSpecies<E> b, byte[] input, byte[] output, boolean lanewise) {
333 Class<?> atype = a.elementType(), btype = b.elementType();
334 MemorySegment inputMs = MemorySegment.ofArray(input);
335 MemorySegment outputMs = MemorySegment.ofArray(output);
336 Vector<E> av = a.fromMemorySegment(inputMs, 0, ByteOrder.nativeOrder());
337 int partLimit = partLimit(a, b, lanewise);
338 int block = Math.min(a.vectorByteSize(), b.vectorByteSize());
339 if (false)
340 System.out.println("testing "+a+"->"+b+
341 (lanewise?" (lanewise)":" (reinterpret)")+
342 ", partLimit=" + partLimit +
343 ", block=" + block);
344 byte[] expected;
345 int origin;
346 if (partLimit > 0) {
347 for (int part = 0; part < partLimit; part++) {
348 Vector<E> bv = (lanewise
349 ? av.castShape(b, part)
350 : av.reinterpretShape(b, part));
351 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
352 // expansion: slice some of the input
353 origin = part * block;
354 expected = Arrays.copyOfRange(input, origin, origin + block);
355 if (lanewise) {
356 expected = castByteArrayData(expected, atype, btype);
357 }
358 checkPartialResult(a, b, input, output, expected,
359 lanewise, part, origin);
360 }
361 } else if (partLimit < 0) {
362 for (int part = 0; part > partLimit; part--) {
363 Vector<E> bv = (lanewise
364 ? av.castShape(b, part)
365 : av.reinterpretShape(b, part));
366 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
367 // contraction: unslice the input into part of the output
368 byte[] logical = input;
369 if (lanewise) {
370 logical = castByteArrayData(input, atype, btype);
371 }
372 assert(logical.length == block);
373 expected = new byte[output.length];
374 origin = -part * block;
375 System.arraycopy(logical, 0, expected, origin, block);
376 checkPartialResult(a, b, input, output, expected,
377 lanewise, part, origin);
378 }
379 } else {
380 int part = 0;
381 Vector<E> bv = (lanewise
382 ? av.castShape(b, part)
383 : av.reinterpretShape(b, part));
384 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
385 // in-place copy, no resize
386 expected = input;
387 origin = 0;
388 if (lanewise) {
389 expected = castByteArrayData(expected, atype, btype);
390 }
391 checkPartialResult(a, b, input, output, expected,
392 lanewise, part, origin);
393 }
394 }
395
396 static
397 void checkPartialResult(VectorSpecies<?> a, VectorSpecies<?> b,
398 byte[] input, byte[] output, byte[] expected,
399 boolean lanewise, int part, int origin) {
400 if (Arrays.equals(expected, output)) {
401 return;
402 }
403 int partLimit = partLimit(a, b, lanewise);
404 int block;
693 testVectorReshape(dspecMax, dspec256, binMax, bout256);
694 testVectorReshape(dspecMax, dspec512, binMax, bout512);
695 testVectorReshape(dspecMax, dspecMax, binMax, boutMax);
696 }
697 }
698 @ForceInline
699 static <E,F>
700 void testVectorRebracket(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output) {
701 testVectorRebracket(a, b, input, output, false);
702 testVectorRebracketLanewise(a, b, input, output);
703 }
704 @ForceInline
705 static <E,F>
706 void testVectorRebracketLanewise(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output) {
707 testVectorRebracket(a, b, input, output, true);
708 }
709 @ForceInline
710 static <E,F>
711 void testVectorRebracket(VectorSpecies<E> a, VectorSpecies<F> b, byte[] input, byte[] output, boolean lanewise) {
712 Class<?> atype = a.elementType(), btype = b.elementType();
713 MemorySegment inputMs = MemorySegment.ofArray(input);
714 MemorySegment outputMs = MemorySegment.ofArray(output);
715 Vector<E> av = a.fromMemorySegment(inputMs, 0, ByteOrder.nativeOrder());
716 int partLimit = partLimit(a, b, lanewise);
717 int block;
718 assert(input.length == output.length);
719 if (!lanewise)
720 block = Math.min(a.vectorByteSize(), b.vectorByteSize());
721 else if (partLimit >= 0)
722 block = a.vectorByteSize() / Math.max(1, partLimit);
723 else
724 block = b.vectorByteSize() / -partLimit;
725 if (lanewise) {
726 if (atype == btype) return;
727 if (atype == float.class || atype == double.class) return;
728 if (btype == float.class || btype == double.class) return;
729 }
730 if (false)
731 System.out.println("testing "+a+"->"+b+
732 (lanewise?" (lanewise)":" (reinterpret)")+
733 ", partLimit=" + partLimit +
734 ", block=" + block);
735 byte[] expected;
736 int origin;
737 if (partLimit > 0) {
738 for (int part = 0; part < partLimit; part++) {
739 Vector<F> bv = (lanewise
740 ? av.castShape(b, part)
741 : av.reinterpretShape(b, part));
742 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
743 // expansion: slice some of the input
744 origin = part * block;
745 expected = Arrays.copyOfRange(input, origin, origin + block);
746 if (lanewise) {
747 expected = castByteArrayData(expected, atype, btype);
748 }
749 checkPartialResult(a, b, input, output, expected,
750 lanewise, part, origin);
751 }
752 } else if (partLimit < 0) {
753 for (int part = 0; part > partLimit; part--) {
754 Vector<F> bv = (lanewise
755 ? av.castShape(b, part)
756 : av.reinterpretShape(b, part));
757 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
758 // contraction: unslice the input into part of the output
759 byte[] logical = input;
760 if (lanewise) {
761 logical = castByteArrayData(input, atype, btype);
762 }
763 assert(logical.length == block);
764 expected = new byte[output.length];
765 origin = -part * block;
766 System.arraycopy(logical, 0, expected, origin, block);
767 checkPartialResult(a, b, input, output, expected,
768 lanewise, part, origin);
769 }
770 } else {
771 int part = 0;
772 Vector<F> bv = (lanewise
773 ? av.castShape(b, part)
774 : av.reinterpretShape(b, part));
775 bv.intoMemorySegment(outputMs, 0, ByteOrder.nativeOrder());
776 // in-place copy, no resize
777 expected = input;
778 origin = 0;
779 if (lanewise) {
780 expected = castByteArrayData(expected, atype, btype);
781 }
782 checkPartialResult(a, b, input, output, expected,
783 lanewise, part, origin);
784 }
785 }
786
787 static int decodeType(Class<?> type) {
788 switch (type.getName().charAt(0)) {
789 case 'b': return 1;
790 case 's': return 2;
791 case 'i': return 4;
792 case 'l': return 8;
793 case 'f': return -4;
794 case 'd': return -8;
795 }
|