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