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