1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2019, Arm Limited. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have
  22  * questions.
  23  */
  24 
  25 /*
  26  * @test
  27  * @modules jdk.incubator.vector
  28  * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED
  29  *      ByteMaxVectorExceptionTests
  30  *
  31  */
  32 
  33 import jdk.incubator.vector.Vector.Shape;
  34 import jdk.incubator.vector.Vector;
  35 import jdk.incubator.vector.ByteVector;
  36 
  37 import org.testng.Assert;
  38 import org.testng.annotations.DataProvider;
  39 import org.testng.annotations.Test;
  40 
  41 import java.util.List;
  42 import java.util.function.IntFunction;
  43 
  44 @Test
  45 public class ByteMaxVectorExceptionTests extends AbstractVectorTest {
  46     static final Shape S_Max_BIT = getMaxBit();
  47 
  48     static final ByteVector.ByteSpecies SPECIES =
  49                 ByteVector.species(S_Max_BIT);
  50 
  51     static final int LOAD_STORE_ARRAY_LENGTH = SPECIES.length() / 2;
  52     static final int GATHER_SCATTER_ARRAY_LENGTH = SPECIES.length();
  53 
  54     static Shape getMaxBit() {
  55         return Shape.S_Max_BIT;
  56     }
  57 
  58     static final Vector.Mask<Byte> LOAD_STORE_MASK = ByteVector.maskFromValues(
  59         SPECIES, fill_boolean(SPECIES.length(), i -> (i < LOAD_STORE_ARRAY_LENGTH)));
  60 
  61     static final Vector.Mask<Byte> GATHER_SCATTER_MASK = ByteVector.maskFromValues(
  62         SPECIES, fill_boolean(SPECIES.length(), i -> ((i * 2 + 1) < GATHER_SCATTER_ARRAY_LENGTH)));
  63 
  64     static final Vector.Mask<Byte> ALL_TRUE_MASK = ByteVector.maskFromValues(
  65         SPECIES, fill_boolean(SPECIES.length(), i -> true));
  66 
  67     interface ToByteF {
  68         byte apply(int i);
  69     }
  70 
  71     static byte[] fill(int s , ToByteF f) {
  72         return fill(new byte[s], f);
  73     }
  74 
  75     static byte[] fill(byte[] a, ToByteF f) {
  76         for (int i = 0; i < a.length; i++) {
  77             a[i] = f.apply(i);
  78         }
  79         return a;
  80     }
  81 
  82     static final List<IntFunction<byte[]>> BYTE_GENERATORS = List.of(
  83             withToString("byte[i + 1]", (int s) -> {
  84                 return fill(s,
  85                     i -> (((byte)(i + 1) == 0) ? 1 : (byte)(i + 1)));
  86             })
  87     );
  88 
  89     static final List<IntFunction<int[]>> INDEX_GENERATORS = List.of(
  90             withToString("index[i * 2 + 1]", (int s) -> {
  91                 return fillInts(s, i -> (i * 2 + 1));
  92             })
  93     );
  94 
  95     @DataProvider
  96     public Object[][] byteProvider() {
  97         return BYTE_GENERATORS.stream().
  98                 map(f -> new Object[]{f}).
  99                 toArray(Object[][]::new);
 100     }
 101 
 102     @DataProvider
 103     public Object[][] byteIndexMapProvider() {
 104         return INDEX_GENERATORS.stream().
 105                 flatMap(fim -> BYTE_GENERATORS.stream().map(fa -> {
 106                     return new Object[] {fa, fim};
 107                 })).
 108                 toArray(Object[][]::new);
 109     }
 110 
 111     @Test(dataProvider = "byteProvider")
 112     static void loadStoreArrayWithMask(IntFunction<byte[]> fa) {
 113         byte[] a = fa.apply(SPECIES.length() / 2);
 114         byte[] r = new byte[a.length];
 115 
 116         // case 1: No IndexOutOfBoundsException for unset mask lanes.
 117         ByteVector av = ByteVector.fromArray(SPECIES, a, 0, LOAD_STORE_MASK);
 118         av.intoArray(r, 0, LOAD_STORE_MASK);
 119         Assert.assertEquals(a, r);
 120 
 121         // case 2:
 122         byte[] new_a = new byte[a.length];
 123         av = ByteVector.fromArray(SPECIES, new_a, 0, LOAD_STORE_MASK);
 124         try {
 125             // Result in IndexOutOfBoundsException for intoArray().
 126             av.intoArray(r, 0, ALL_TRUE_MASK);
 127             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 128         } catch(IndexOutOfBoundsException e) {
 129         }
 130 
 131         // case 3:
 132         try {
 133             // Result in IndexOutOfBoundsException for fromArray().
 134             av = ByteVector.fromArray(SPECIES, a, 0, ALL_TRUE_MASK);
 135             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 136         } catch(IndexOutOfBoundsException e) {
 137         }
 138     }
 139 
 140     @Test(dataProvider = "byteIndexMapProvider")
 141     static void gatherScatterArrayWithMask(IntFunction<byte[]> fa,
 142                                            IntFunction<int[]> fb) {
 143         byte[] a = fa.apply(SPECIES.length());
 144         int[] indexMap = fb.apply(SPECIES.length());
 145         byte[] r = new byte[a.length];
 146 
 147         // case 1: No IndexOutOfBoundsException for unset mask lanes.
 148         ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 149         av.intoArray(r, 0, GATHER_SCATTER_MASK, indexMap, 0);
 150 
 151         av = ByteVector.fromArray(SPECIES, a, 0, GATHER_SCATTER_MASK, indexMap, 0);
 152 
 153         // case 2:
 154         byte[] r1 = new byte[a.length];
 155         byte[] r2 = new byte[a.length];
 156         av = ByteVector.fromArray(SPECIES, a, 0);
 157         try {
 158             // Result in IndexOutOfBoundsException for scatter.
 159             av.intoArray(r2, 0, ALL_TRUE_MASK, indexMap, 0);
 160             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 161         } catch(IndexOutOfBoundsException e) {
 162         }
 163 
 164         // case 3:
 165         try {
 166             // Result in IndexOutOfBoundsException for gather.
 167             av = ByteVector.fromArray(SPECIES, a, 0, ALL_TRUE_MASK, indexMap, 0);
 168             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 169         } catch(IndexOutOfBoundsException e) {
 170         }
 171     }
 172 
 173     @Test(dataProvider = "byteProvider")
 174     static void loadStoreArray(IntFunction<byte[]> fa) {
 175         byte[] a = fa.apply(SPECIES.length() / 2);
 176         byte[] r = new byte[a.length];
 177 
 178         // case 1:
 179         try {
 180             // Result in IndexOutOfBoundsException for fromArray().
 181             ByteVector av = ByteVector.fromArray(SPECIES, a, 0);
 182             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 183         } catch(IndexOutOfBoundsException e) {
 184         }
 185 
 186         // case 2:
 187         ByteVector av = ByteVector.fromArray(SPECIES, a, 0, LOAD_STORE_MASK);
 188         try {
 189             // Result in IndexOutOfBoundsException for intoArray().
 190             av.intoArray(r, 0);
 191             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 192         } catch(IndexOutOfBoundsException e) {
 193         }
 194     }
 195 
 196     @Test(dataProvider = "byteIndexMapProvider")
 197     static void gatherScatterArray(IntFunction<byte[]> fa,
 198                                    IntFunction<int[]> fb) {
 199         byte[] a = fa.apply(SPECIES.length());
 200         int[] indexMap = fb.apply(SPECIES.length());
 201         byte[] r = new byte[a.length];
 202 
 203         // case 1:
 204         try {
 205             // Result in IndexOutOfBoundsException for gather.
 206             ByteVector av = ByteVector.fromArray(SPECIES, a, 0, indexMap, 0);
 207             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 208         } catch(IndexOutOfBoundsException e) {
 209         }
 210 
 211         // case 2:
 212         ByteVector av = ByteVector.fromArray(SPECIES, a, 0, GATHER_SCATTER_MASK, indexMap, 0);
 213         try {
 214             // Result in IndexOutOfBoundsException for scatter.
 215             av.intoArray(r, 0, indexMap, 0);
 216             Assert.fail("Expected IndexOutOfBoundsException not thrown");
 217         } catch(IndexOutOfBoundsException e) {
 218         }
 219     }
 220 }