1 /* 2 * Copyright (c) 2018, 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 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules jdk.incubator.vector 27 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED 28 * ShortMaxVectorLoadStoreTests 29 * 30 */ 31 32 import jdk.incubator.vector.VectorShape; 33 import jdk.incubator.vector.VectorSpecies; 34 import jdk.incubator.vector.VectorMask; 35 import jdk.incubator.vector.Vector; 36 37 import jdk.incubator.vector.ShortVector; 38 39 import org.testng.Assert; 40 import org.testng.annotations.DataProvider; 41 import org.testng.annotations.Test; 42 43 import java.lang.invoke.MethodHandles; 44 import java.lang.invoke.VarHandle; 45 import java.nio.ByteBuffer; 46 import java.nio.ShortBuffer; 47 import java.nio.ByteOrder; 48 import java.util.List; 49 import java.util.function.IntFunction; 50 51 @Test 52 public class ShortMaxVectorLoadStoreTests extends AbstractVectorTest { 53 static final VectorSpecies<Short> SPECIES = 54 ShortVector.SPECIES_MAX; 55 56 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 10); 57 58 static VectorShape getMaxBit() { 59 return VectorShape.S_Max_BIT; 60 } 61 62 static void assertArraysEquals(short[] a, short[] r, boolean[] mask) { 63 int i = 0; 64 try { 65 for (; i < a.length; i++) { 66 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (short) 0, r[i]); 67 } 68 } catch (AssertionError e) { 69 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (short) 0, r[i], "at index #" + i); 70 } 71 } 72 73 static void assertArraysEquals(short[] a, short[] r, int[] im) { 74 int i = 0; 75 try { 76 for (; i < a.length; i++) { 77 Assert.assertEquals(a[im[i]], r[i]); 78 } 79 } catch (AssertionError e) { 80 Assert.assertEquals(a[im[i]], r[i], "at index #" + i); 81 } 82 } 83 84 static void assertArraysEquals(short[] a, short[] r, int[] im, boolean[] mask) { 85 int i = 0; 86 try { 87 for (; i < a.length; i++) { 88 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (short) 0, r[i]); 89 } 90 } catch (AssertionError e) { 91 Assert.assertEquals(mask[i % SPECIES.length()] ? a[im[i]] : (short) 0, r[i], "at index #" + i); 92 } 93 } 94 95 static final List<IntFunction<short[]>> SHORT_GENERATORS = List.of( 96 withToString("short[i * 5]", (int s) -> { 97 return fill(s * 1000, 98 i -> (short)(i * 5)); 99 }), 100 withToString("short[i + 1]", (int s) -> { 101 return fill(s * 1000, 102 i -> (((short)(i + 1) == 0) ? 1 : (short)(i + 1))); 103 }) 104 ); 105 106 @DataProvider 107 public Object[][] shortProvider() { 108 return SHORT_GENERATORS.stream(). 109 map(f -> new Object[]{f}). 110 toArray(Object[][]::new); 111 } 112 113 @DataProvider 114 public Object[][] shortMaskProvider() { 115 return BOOLEAN_MASK_GENERATORS.stream(). 116 flatMap(fm -> SHORT_GENERATORS.stream().map(fa -> { 117 return new Object[] {fa, fm}; 118 })). 119 toArray(Object[][]::new); 120 } 121 122 @DataProvider 123 public Object[][] shortIndexMapProvider() { 124 return INDEX_GENERATORS.stream(). 125 flatMap(fim -> SHORT_GENERATORS.stream().map(fa -> { 126 return new Object[] {fa, fim}; 127 })). 128 toArray(Object[][]::new); 129 } 130 131 @DataProvider 132 public Object[][] shortIndexMapMaskProvider() { 133 return BOOLEAN_MASK_GENERATORS.stream(). 134 flatMap(fm -> INDEX_GENERATORS.stream(). 135 flatMap(fim -> SHORT_GENERATORS.stream().map(fa -> { 136 return new Object[] {fa, fim, fm}; 137 }))). 138 toArray(Object[][]::new); 139 } 140 141 @DataProvider 142 public Object[][] shortByteBufferProvider() { 143 return SHORT_GENERATORS.stream(). 144 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 145 return new Object[]{fa, fb}; 146 })). 147 toArray(Object[][]::new); 148 } 149 150 @DataProvider 151 public Object[][] shortByteBufferMaskProvider() { 152 return BOOLEAN_MASK_GENERATORS.stream(). 153 flatMap(fm -> SHORT_GENERATORS.stream(). 154 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().map(fb -> { 155 return new Object[]{fa, fb, fm}; 156 }))). 157 toArray(Object[][]::new); 158 } 159 160 static ByteBuffer toBuffer(short[] a, IntFunction<ByteBuffer> fb) { 161 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 162 for (short v : a) { 163 bb.putShort(v); 164 } 165 return bb.clear(); 166 } 167 168 static short[] bufferToArray(ByteBuffer bb) { 169 ShortBuffer db = bb.asShortBuffer(); 170 short[] d = new short[db.capacity()]; 171 db.get(d); 172 return d; 173 } 174 175 interface ToShortF { 176 short apply(int i); 177 } 178 179 static short[] fill(int s , ToShortF f) { 180 return fill(new short[s], f); 181 } 182 183 static short[] fill(short[] a, ToShortF f) { 184 for (int i = 0; i < a.length; i++) { 185 a[i] = f.apply(i); 186 } 187 return a; 188 } 189 190 @Test(dataProvider = "shortProvider") 191 static void loadStoreArray(IntFunction<short[]> fa) { 192 short[] a = fa.apply(SPECIES.length()); 193 short[] r = new short[a.length]; 194 195 for (int ic = 0; ic < INVOC_COUNT; ic++) { 196 for (int i = 0; i < a.length; i += SPECIES.length()) { 197 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 198 av.intoArray(r, i); 199 } 200 } 201 Assert.assertEquals(a, r); 202 } 203 204 @Test(dataProvider = "shortMaskProvider") 205 static void loadStoreMaskArray(IntFunction<short[]> fa, 206 IntFunction<boolean[]> fm) { 207 short[] a = fa.apply(SPECIES.length()); 208 short[] r = new short[a.length]; 209 boolean[] mask = fm.apply(SPECIES.length()); 210 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 211 212 for (int ic = 0; ic < INVOC_COUNT; ic++) { 213 for (int i = 0; i < a.length; i += SPECIES.length()) { 214 ShortVector av = ShortVector.fromArray(SPECIES, a, i, vmask); 215 av.intoArray(r, i); 216 } 217 } 218 assertArraysEquals(a, r, mask); 219 220 r = new short[a.length]; 221 for (int ic = 0; ic < INVOC_COUNT; ic++) { 222 for (int i = 0; i < a.length; i += SPECIES.length()) { 223 ShortVector av = ShortVector.fromArray(SPECIES, a, i); 224 av.intoArray(r, i, vmask); 225 } 226 } 227 228 assertArraysEquals(a, r, mask); 229 } 230 231 232 @Test(dataProvider = "shortByteBufferProvider") 233 static void loadStoreByteBuffer(IntFunction<short[]> fa, 234 IntFunction<ByteBuffer> fb) { 235 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 236 ByteBuffer r = fb.apply(a.limit()); 237 238 int l = a.limit(); 239 int s = SPECIES.length() * SPECIES.elementSize() / 8; 240 241 for (int ic = 0; ic < INVOC_COUNT; ic++) { 242 for (int i = 0; i < l; i += s) { 243 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i); 244 av.intoByteBuffer(r, i); 245 } 246 } 247 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 248 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 249 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 250 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 251 Assert.assertEquals(a, r, "Buffers not equal"); 252 } 253 254 @Test(dataProvider = "shortByteBufferProvider") 255 static void loadReadOnlyStoreByteBuffer(IntFunction<short[]> fa, 256 IntFunction<ByteBuffer> fb) { 257 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 258 a = a.asReadOnlyBuffer().order(a.order()); 259 ByteBuffer r = fb.apply(a.limit()); 260 261 int l = a.limit(); 262 int s = SPECIES.length() * SPECIES.elementSize() / 8; 263 264 for (int ic = 0; ic < INVOC_COUNT; ic++) { 265 for (int i = 0; i < l; i += s) { 266 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i); 267 av.intoByteBuffer(r, i); 268 } 269 } 270 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 271 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 272 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 273 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 274 Assert.assertEquals(a, r, "Buffers not equal"); 275 } 276 277 @Test(dataProvider = "shortByteBufferMaskProvider") 278 static void loadStoreByteBufferMask(IntFunction<short[]> fa, 279 IntFunction<ByteBuffer> fb, 280 IntFunction<boolean[]> fm) { 281 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 282 ByteBuffer r = fb.apply(a.limit()); 283 boolean[] mask = fm.apply(SPECIES.length()); 284 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 285 286 int l = a.limit(); 287 int s = SPECIES.length() * SPECIES.elementSize() / 8; 288 289 for (int ic = 0; ic < INVOC_COUNT; ic++) { 290 for (int i = 0; i < l; i += s) { 291 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, vmask); 292 av.intoByteBuffer(r, i); 293 } 294 } 295 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 296 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 297 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 298 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 299 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 300 301 a = toBuffer(fa.apply(SPECIES.length()), fb); 302 r = fb.apply(a.limit()); 303 for (int ic = 0; ic < INVOC_COUNT; ic++) { 304 for (int i = 0; i < l; i += s) { 305 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i); 306 av.intoByteBuffer(r, i, vmask); 307 } 308 } 309 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 310 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 311 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 312 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 313 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 314 } 315 316 @Test(dataProvider = "shortByteBufferMaskProvider") 317 static void loadReadOnlyStoreByteBufferMask(IntFunction<short[]> fa, 318 IntFunction<ByteBuffer> fb, 319 IntFunction<boolean[]> fm) { 320 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 321 a = a.asReadOnlyBuffer().order(a.order()); 322 ByteBuffer r = fb.apply(a.limit()); 323 boolean[] mask = fm.apply(SPECIES.length()); 324 VectorMask<Short> vmask = VectorMask.fromValues(SPECIES, mask); 325 326 int l = a.limit(); 327 int s = SPECIES.length() * SPECIES.elementSize() / 8; 328 329 for (int ic = 0; ic < INVOC_COUNT; ic++) { 330 for (int i = 0; i < l; i += s) { 331 ShortVector av = ShortVector.fromByteBuffer(SPECIES, a, i, vmask); 332 av.intoByteBuffer(r, i); 333 } 334 } 335 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 336 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 337 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 338 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 339 assertArraysEquals(bufferToArray(a), bufferToArray(r), mask); 340 } 341 }