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