1 /* 2 * Copyright (c) 2018, 2022, 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 any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @modules jdk.incubator.vector java.base/jdk.internal.vm.annotation 27 #if[MaxBit] 28 * @run testng/othervm --add-opens jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED 29 * -XX:-TieredCompilation $vectorteststype$ 30 #else[MaxBit] 31 * @run testng/othervm -XX:-TieredCompilation $vectorteststype$ 32 #end[MaxBit] 33 * 34 */ 35 36 #warn This file is preprocessed before being compiled 37 38 import java.lang.foreign.MemorySegment; 39 import java.lang.foreign.Arena; 40 import java.lang.foreign.ValueLayout; 41 import jdk.incubator.vector.$Type$Vector; 42 import jdk.incubator.vector.VectorMask; 43 #if[MaxBit] 44 import jdk.incubator.vector.VectorShape; 45 #end[MaxBit] 46 import jdk.incubator.vector.VectorSpecies; 47 import jdk.incubator.vector.VectorShuffle; 48 import jdk.internal.vm.annotation.DontInline; 49 import org.testng.Assert; 50 import org.testng.annotations.DataProvider; 51 import org.testng.annotations.Test; 52 53 import java.nio.ByteOrder; 54 import java.util.List; 55 import java.util.function.*; 56 57 @Test 58 public class $vectorteststype$ extends AbstractVectorLoadStoreTest { 59 #if[MaxBit] 60 static final VectorSpecies<$Wideboxtype$> SPECIES = 61 $Type$Vector.SPECIES_MAX; 62 #else[MaxBit] 63 static final VectorSpecies<$Wideboxtype$> SPECIES = 64 $Type$Vector.SPECIES_$bits$; 65 #end[MaxBit] 66 67 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 68 69 static final ValueLayout.Of$Type$ ELEMENT_LAYOUT = ValueLayout.JAVA_$TYPE$.withByteAlignment(1); 70 71 #if[MaxBit] 72 static VectorShape getMaxBit() { 73 return VectorShape.S_Max_BIT; 74 } 75 76 private static final int Max = 256; // juts so we can do N/$bits$ 77 #end[MaxBit] 78 79 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / $bits$); 80 81 static void assertArraysEquals($type$[] r, $type$[] a, boolean[] mask) { 82 int i = 0; 83 try { 84 for (; i < a.length; i++) { 85 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0); 86 } 87 } catch (AssertionError e) { 88 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : ($type$) 0, "at index #" + i); 89 } 90 } 91 92 static final List<IntFunction<$type$[]>> $TYPE$_GENERATORS = List.of( 93 withToString("$type$[i * 5]", (int s) -> { 94 return fill(s * BUFFER_REPS, 95 i -> ($type$)(i * 5)); 96 }), 97 withToString("$type$[i + 1]", (int s) -> { 98 return fill(s * BUFFER_REPS, 99 i -> ((($type$)(i + 1) == 0) ? 1 : ($type$)(i + 1))); 100 }) 101 ); 102 103 // Relative to array.length 104 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 105 withToString("-1", (int l) -> { 106 return -1; 107 }), 108 withToString("l", (int l) -> { 109 return l; 110 }), 111 withToString("l - 1", (int l) -> { 112 return l - 1; 113 }), 114 withToString("l + 1", (int l) -> { 115 return l + 1; 116 }), 117 withToString("l - speciesl + 1", (int l) -> { 118 return l - SPECIES.length() + 1; 119 }), 120 withToString("l + speciesl - 1", (int l) -> { 121 return l + SPECIES.length() - 1; 122 }), 123 withToString("l + speciesl", (int l) -> { 124 return l + SPECIES.length(); 125 }), 126 withToString("l + speciesl + 1", (int l) -> { 127 return l + SPECIES.length() + 1; 128 }) 129 ); 130 131 // Relative to byte[] array.length or MemorySegment.byteSize() 132 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 133 withToString("-1", (int l) -> { 134 return -1; 135 }), 136 withToString("l", (int l) -> { 137 return l; 138 }), 139 withToString("l - 1", (int l) -> { 140 return l - 1; 141 }), 142 withToString("l + 1", (int l) -> { 143 return l + 1; 144 }), 145 withToString("l - speciesl*ebsize + 1", (int l) -> { 146 return l - SPECIES.vectorByteSize() + 1; 147 }), 148 withToString("l + speciesl*ebsize - 1", (int l) -> { 149 return l + SPECIES.vectorByteSize() - 1; 150 }), 151 withToString("l + speciesl*ebsize", (int l) -> { 152 return l + SPECIES.vectorByteSize(); 153 }), 154 withToString("l + speciesl*ebsize + 1", (int l) -> { 155 return l + SPECIES.vectorByteSize() + 1; 156 }) 157 ); 158 159 @DataProvider 160 public Object[][] $type$Provider() { 161 return $TYPE$_GENERATORS.stream(). 162 map(f -> new Object[]{f}). 163 toArray(Object[][]::new); 164 } 165 166 @DataProvider 167 public Object[][] maskProvider() { 168 return BOOLEAN_MASK_GENERATORS.stream(). 169 map(f -> new Object[]{f}). 170 toArray(Object[][]::new); 171 } 172 173 @DataProvider 174 public Object[][] $type$ProviderForIOOBE() { 175 var f = $TYPE$_GENERATORS.get(0); 176 return INDEX_GENERATORS.stream().map(fi -> { 177 return new Object[] {f, fi}; 178 }). 179 toArray(Object[][]::new); 180 } 181 182 @DataProvider 183 public Object[][] $type$MaskProvider() { 184 return BOOLEAN_MASK_GENERATORS.stream(). 185 flatMap(fm -> $TYPE$_GENERATORS.stream().map(fa -> { 186 return new Object[] {fa, fm}; 187 })). 188 toArray(Object[][]::new); 189 } 190 191 @DataProvider 192 public Object[][] $type$MaskProviderForIOOBE() { 193 var f = $TYPE$_GENERATORS.get(0); 194 return BOOLEAN_MASK_GENERATORS.stream(). 195 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 196 return new Object[] {f, fi, fm}; 197 })). 198 toArray(Object[][]::new); 199 } 200 201 @DataProvider 202 public Object[][] $type$MemorySegmentProvider() { 203 return $TYPE$_GENERATORS.stream(). 204 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 205 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 206 return new Object[]{fa, fb, bo}; 207 }))). 208 toArray(Object[][]::new); 209 } 210 211 @DataProvider 212 public Object[][] $type$MemorySegmentMaskProvider() { 213 return BOOLEAN_MASK_GENERATORS.stream(). 214 flatMap(fm -> $TYPE$_GENERATORS.stream(). 215 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 216 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 217 return new Object[]{fa, fb, fm, bo}; 218 })))). 219 toArray(Object[][]::new); 220 } 221 222 @DataProvider 223 public Object[][] $type$ByteProviderForIOOBE() { 224 var f = $TYPE$_GENERATORS.get(0); 225 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 226 return new Object[] {f, fi}; 227 }). 228 toArray(Object[][]::new); 229 } 230 231 @DataProvider 232 public Object[][] $type$ByteMaskProviderForIOOBE() { 233 var f = $TYPE$_GENERATORS.get(0); 234 return BOOLEAN_MASK_GENERATORS.stream(). 235 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 236 return new Object[] {f, fi, fm}; 237 })). 238 toArray(Object[][]::new); 239 } 240 241 static MemorySegment toSegment($type$[] a, IntFunction<MemorySegment> fb) { 242 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8); 243 for (int i = 0; i < a.length; i++) { 244 ms.set(ELEMENT_LAYOUT, i * SPECIES.elementSize() / 8 , a[i]); 245 } 246 return ms; 247 } 248 249 static $type$[] segmentToArray(MemorySegment ms) { 250 return ms.toArray(ELEMENT_LAYOUT); 251 } 252 253 254 interface To$Type$F { 255 $type$ apply(int i); 256 } 257 258 static $type$[] fill(int s , To$Type$F f) { 259 return fill(new $type$[s], f); 260 } 261 262 static $type$[] fill($type$[] a, To$Type$F f) { 263 for (int i = 0; i < a.length; i++) { 264 a[i] = f.apply(i); 265 } 266 return a; 267 } 268 269 @DontInline 270 static $abstractvectortype$ fromArray($type$[] a, int i) { 271 return $abstractvectortype$.fromArray(SPECIES, a, i); 272 } 273 274 @DontInline 275 static $abstractvectortype$ fromArray($type$[] a, int i, VectorMask<$Boxtype$> m) { 276 return $abstractvectortype$.fromArray(SPECIES, a, i, m); 277 } 278 279 @DontInline 280 static void intoArray($abstractvectortype$ v, $type$[] a, int i) { 281 v.intoArray(a, i); 282 } 283 284 @DontInline 285 static void intoArray($abstractvectortype$ v, $type$[] a, int i, VectorMask<$Boxtype$> m) { 286 v.intoArray(a, i, m); 287 } 288 289 @DontInline 290 static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 291 return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo); 292 } 293 294 @DontInline 295 static $abstractvectortype$ fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) { 296 return $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, m); 297 } 298 299 @DontInline 300 static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo) { 301 v.intoMemorySegment(a, i, bo); 302 } 303 304 @DontInline 305 static void intoMemorySegment($abstractvectortype$ v, MemorySegment a, int i, ByteOrder bo, VectorMask<$Boxtype$> m) { 306 v.intoMemorySegment(a, i, bo, m); 307 } 308 309 @Test(dataProvider = "$type$Provider") 310 static void loadStoreArray(IntFunction<$type$[]> fa) { 311 $type$[] a = fa.apply(SPECIES.length()); 312 $type$[] r = new $type$[a.length]; 313 314 for (int ic = 0; ic < INVOC_COUNT; ic++) { 315 for (int i = 0; i < a.length; i += SPECIES.length()) { 316 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 317 av.intoArray(r, i); 318 } 319 } 320 Assert.assertEquals(r, a); 321 } 322 323 @Test(dataProvider = "$type$ProviderForIOOBE") 324 static void loadArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) { 325 $type$[] a = fa.apply(SPECIES.length()); 326 $type$[] r = new $type$[a.length]; 327 328 for (int ic = 0; ic < INVOC_COUNT; ic++) { 329 for (int i = 0; i < a.length; i += SPECIES.length()) { 330 $abstractvectortype$ av = fromArray(a, i); 331 av.intoArray(r, i); 332 } 333 } 334 335 int index = fi.apply(a.length); 336 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 337 try { 338 fromArray(a, index); 339 if (shouldFail) { 340 Assert.fail("Failed to throw IndexOutOfBoundsException"); 341 } 342 } catch (IndexOutOfBoundsException e) { 343 if (!shouldFail) { 344 Assert.fail("Unexpected IndexOutOfBoundsException"); 345 } 346 } 347 } 348 349 @Test(dataProvider = "$type$ProviderForIOOBE") 350 static void storeArrayIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) { 351 $type$[] a = fa.apply(SPECIES.length()); 352 $type$[] r = new $type$[a.length]; 353 354 for (int ic = 0; ic < INVOC_COUNT; ic++) { 355 for (int i = 0; i < a.length; i += SPECIES.length()) { 356 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 357 intoArray(av, r, i); 358 } 359 } 360 361 int index = fi.apply(a.length); 362 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 363 try { 364 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0); 365 intoArray(av, r, index); 366 if (shouldFail) { 367 Assert.fail("Failed to throw IndexOutOfBoundsException"); 368 } 369 } catch (IndexOutOfBoundsException e) { 370 if (!shouldFail) { 371 Assert.fail("Unexpected IndexOutOfBoundsException"); 372 } 373 } 374 } 375 376 377 @Test(dataProvider = "$type$MaskProvider") 378 static void loadStoreMaskArray(IntFunction<$type$[]> fa, 379 IntFunction<boolean[]> fm) { 380 $type$[] a = fa.apply(SPECIES.length()); 381 $type$[] r = new $type$[a.length]; 382 boolean[] mask = fm.apply(SPECIES.length()); 383 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 384 385 for (int ic = 0; ic < INVOC_COUNT; ic++) { 386 for (int i = 0; i < a.length; i += SPECIES.length()) { 387 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, vmask); 388 av.intoArray(r, i); 389 } 390 } 391 assertArraysEquals(r, a, mask); 392 393 394 r = new $type$[a.length]; 395 396 for (int ic = 0; ic < INVOC_COUNT; ic++) { 397 for (int i = 0; i < a.length; i += SPECIES.length()) { 398 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 399 av.intoArray(r, i, vmask); 400 } 401 } 402 assertArraysEquals(r, a, mask); 403 } 404 405 @Test(dataProvider = "$type$MaskProviderForIOOBE") 406 static void loadArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 407 $type$[] a = fa.apply(SPECIES.length()); 408 $type$[] r = new $type$[a.length]; 409 boolean[] mask = fm.apply(SPECIES.length()); 410 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 411 412 for (int ic = 0; ic < INVOC_COUNT; ic++) { 413 for (int i = 0; i < a.length; i += SPECIES.length()) { 414 $abstractvectortype$ av = fromArray(a, i, vmask); 415 av.intoArray(r, i); 416 } 417 } 418 419 int index = fi.apply(a.length); 420 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 421 try { 422 fromArray(a, index, vmask); 423 if (shouldFail) { 424 Assert.fail("Failed to throw IndexOutOfBoundsException"); 425 } 426 } catch (IndexOutOfBoundsException e) { 427 if (!shouldFail) { 428 Assert.fail("Unexpected IndexOutOfBoundsException"); 429 } 430 } 431 } 432 433 @Test(dataProvider = "$type$MaskProviderForIOOBE") 434 static void storeArrayMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 435 $type$[] a = fa.apply(SPECIES.length()); 436 $type$[] r = new $type$[a.length]; 437 boolean[] mask = fm.apply(SPECIES.length()); 438 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 439 440 for (int ic = 0; ic < INVOC_COUNT; ic++) { 441 for (int i = 0; i < a.length; i += SPECIES.length()) { 442 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 443 intoArray(av, r, i, vmask); 444 } 445 } 446 447 int index = fi.apply(a.length); 448 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 449 try { 450 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, 0); 451 intoArray(av, a, index, vmask); 452 if (shouldFail) { 453 Assert.fail("Failed to throw IndexOutOfBoundsException"); 454 } 455 } catch (IndexOutOfBoundsException e) { 456 if (!shouldFail) { 457 Assert.fail("Unexpected IndexOutOfBoundsException"); 458 } 459 } 460 } 461 462 463 @Test(dataProvider = "$type$MaskProvider") 464 static void loadStoreMask(IntFunction<$type$[]> fa, 465 IntFunction<boolean[]> fm) { 466 boolean[] mask = fm.apply(SPECIES.length()); 467 boolean[] r = new boolean[mask.length]; 468 469 for (int ic = 0; ic < INVOC_COUNT; ic++) { 470 for (int i = 0; i < mask.length; i += SPECIES.length()) { 471 VectorMask<$Boxtype$> vmask = VectorMask.fromArray(SPECIES, mask, i); 472 vmask.intoArray(r, i); 473 } 474 } 475 Assert.assertEquals(r, mask); 476 } 477 478 479 @Test(dataProvider = "$type$MemorySegmentProvider") 480 static void loadStoreMemorySegment(IntFunction<$type$[]> fa, 481 IntFunction<MemorySegment> fb, 482 ByteOrder bo) { 483 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb); 484 MemorySegment r = fb.apply((int) a.byteSize()); 485 486 int l = (int) a.byteSize(); 487 int s = SPECIES.vectorByteSize(); 488 489 for (int ic = 0; ic < INVOC_COUNT; ic++) { 490 for (int i = 0; i < l; i += s) { 491 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo); 492 av.intoMemorySegment(r, i, bo); 493 } 494 } 495 long m = r.mismatch(a); 496 Assert.assertEquals(m, -1, "Segments not equal"); 497 } 498 499 @Test(dataProvider = "$type$ByteProviderForIOOBE") 500 static void loadMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) { 501 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE)); 502 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE); 503 504 int l = (int) a.byteSize(); 505 int s = SPECIES.vectorByteSize(); 506 507 for (int ic = 0; ic < INVOC_COUNT; ic++) { 508 for (int i = 0; i < l; i += s) { 509 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder()); 510 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 511 } 512 } 513 514 int index = fi.apply((int) a.byteSize()); 515 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 516 try { 517 fromMemorySegment(a, index, ByteOrder.nativeOrder()); 518 if (shouldFail) { 519 Assert.fail("Failed to throw IndexOutOfBoundsException"); 520 } 521 } catch (IndexOutOfBoundsException e) { 522 if (!shouldFail) { 523 Assert.fail("Unexpected IndexOutOfBoundsException"); 524 } 525 } 526 } 527 528 @Test(dataProvider = "$type$ByteProviderForIOOBE") 529 static void storeMemorySegmentIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi) { 530 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE)); 531 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE); 532 533 int l = (int) a.byteSize(); 534 int s = SPECIES.vectorByteSize(); 535 536 for (int ic = 0; ic < INVOC_COUNT; ic++) { 537 for (int i = 0; i < l; i += s) { 538 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 539 intoMemorySegment(av, r, i, ByteOrder.nativeOrder()); 540 } 541 } 542 543 int index = fi.apply((int) a.byteSize()); 544 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 545 try { 546 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 547 intoMemorySegment(av, r, index, ByteOrder.nativeOrder()); 548 if (shouldFail) { 549 Assert.fail("Failed to throw IndexOutOfBoundsException"); 550 } 551 } catch (IndexOutOfBoundsException e) { 552 if (!shouldFail) { 553 Assert.fail("Unexpected IndexOutOfBoundsException"); 554 } 555 } 556 } 557 558 @Test(dataProvider = "$type$MemorySegmentMaskProvider") 559 static void loadStoreMemorySegmentMask(IntFunction<$type$[]> fa, 560 IntFunction<MemorySegment> fb, 561 IntFunction<boolean[]> fm, 562 ByteOrder bo) { 563 $type$[] _a = fa.apply(SPECIES.length()); 564 MemorySegment a = toSegment(_a, fb); 565 MemorySegment r = fb.apply((int) a.byteSize()); 566 boolean[] mask = fm.apply(SPECIES.length()); 567 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 568 569 int l = (int) a.byteSize(); 570 int s = SPECIES.vectorByteSize(); 571 572 for (int ic = 0; ic < INVOC_COUNT; ic++) { 573 for (int i = 0; i < l; i += s) { 574 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo, vmask); 575 av.intoMemorySegment(r, i, bo); 576 } 577 } 578 assertArraysEquals(segmentToArray(r), _a, mask); 579 580 581 r = fb.apply((int) a.byteSize()); 582 583 for (int ic = 0; ic < INVOC_COUNT; ic++) { 584 for (int i = 0; i < l; i += s) { 585 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, bo); 586 av.intoMemorySegment(r, i, bo, vmask); 587 } 588 } 589 assertArraysEquals(segmentToArray(r), _a, mask); 590 } 591 592 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE") 593 static void loadMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 594 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE)); 595 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE); 596 boolean[] mask = fm.apply(SPECIES.length()); 597 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 598 599 int l = (int) a.byteSize(); 600 int s = SPECIES.vectorByteSize(); 601 602 for (int ic = 0; ic < INVOC_COUNT; ic++) { 603 for (int i = 0; i < l; i += s) { 604 $abstractvectortype$ av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask); 605 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 606 } 607 } 608 609 int index = fi.apply((int) a.byteSize()); 610 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 611 try { 612 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask); 613 if (shouldFail) { 614 Assert.fail("Failed to throw IndexOutOfBoundsException"); 615 } 616 } catch (IndexOutOfBoundsException e) { 617 if (!shouldFail) { 618 Assert.fail("Unexpected IndexOutOfBoundsException"); 619 } 620 } 621 } 622 623 @Test(dataProvider = "$type$ByteMaskProviderForIOOBE") 624 static void storeMemorySegmentMaskIOOBE(IntFunction<$type$[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 625 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> Arena.ofAuto().allocate(i, $Boxtype$.SIZE)); 626 MemorySegment r = Arena.ofAuto().allocate(a.byteSize(), $Boxtype$.SIZE); 627 boolean[] mask = fm.apply(SPECIES.length()); 628 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 629 630 int l = (int) a.byteSize(); 631 int s = SPECIES.vectorByteSize(); 632 633 for (int ic = 0; ic < INVOC_COUNT; ic++) { 634 for (int i = 0; i < l; i += s) { 635 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 636 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask); 637 } 638 } 639 640 int index = fi.apply((int) a.byteSize()); 641 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 642 try { 643 $abstractvectortype$ av = $abstractvectortype$.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 644 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask); 645 if (shouldFail) { 646 Assert.fail("Failed to throw IndexOutOfBoundsException"); 647 } 648 } catch (IndexOutOfBoundsException e) { 649 if (!shouldFail) { 650 Assert.fail("Unexpected IndexOutOfBoundsException"); 651 } 652 } 653 } 654 655 @Test(dataProvider = "$type$MemorySegmentProvider") 656 static void loadStoreReadonlyMemorySegment(IntFunction<$type$[]> fa, 657 IntFunction<MemorySegment> fb, 658 ByteOrder bo) { 659 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly(); 660 661 Assert.assertThrows( 662 UnsupportedOperationException.class, 663 () -> SPECIES.zero().intoMemorySegment(a, 0, bo) 664 ); 665 666 Assert.assertThrows( 667 UnsupportedOperationException.class, 668 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true)) 669 ); 670 671 Assert.assertThrows( 672 UnsupportedOperationException.class, 673 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false)) 674 ); 675 676 VectorMask<$Boxtype$> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 677 .laneIsValid(); 678 Assert.assertThrows( 679 UnsupportedOperationException.class, 680 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m) 681 ); 682 } 683 684 685 @Test(dataProvider = "maskProvider") 686 static void loadStoreMask(IntFunction<boolean[]> fm) { 687 boolean[] a = fm.apply(SPECIES.length()); 688 boolean[] r = new boolean[a.length]; 689 690 for (int ic = 0; ic < INVOC_COUNT; ic++) { 691 for (int i = 0; i < a.length; i += SPECIES.length()) { 692 VectorMask<$Boxtype$> vmask = SPECIES.loadMask(a, i); 693 vmask.intoArray(r, i); 694 } 695 } 696 Assert.assertEquals(r, a); 697 } 698 699 700 @Test 701 static void loadStoreShuffle() { 702 IntUnaryOperator fn = a -> a + 5; 703 for (int ic = 0; ic < INVOC_COUNT; ic++) { 704 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 705 int [] r = shuffle.toArray(); 706 707 int [] a = expectedShuffle(SPECIES.length(), fn); 708 Assert.assertEquals(r, a); 709 } 710 } 711 712 713 #if[short] 714 static void assertArraysEquals(char[] a, char[] r, boolean[] mask) { 715 int i = 0; 716 try { 717 for (; i < a.length; i++) { 718 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i]); 719 } 720 } catch (AssertionError e) { 721 Assert.assertEquals(mask[i % SPECIES.length()] ? a[i] : (char) 0, r[i], "at index #" + i); 722 } 723 } 724 725 static final List<IntFunction<char[]>> CHAR_GENERATORS = List.of( 726 withToString("char[i * 5]", (int s) -> { 727 return fillChar(s * BUFFER_REPS, 728 i -> (char)(i * 5)); 729 }), 730 withToString("char[i + 1]", (int s) -> { 731 return fillChar(s * BUFFER_REPS, 732 i -> (((char)(i + 1) == 0) ? 1 : (char)(i + 1))); 733 }) 734 ); 735 736 @DataProvider 737 public Object[][] charProvider() { 738 return CHAR_GENERATORS.stream(). 739 map(f -> new Object[]{f}). 740 toArray(Object[][]::new); 741 } 742 743 @DataProvider 744 public Object[][] charProviderForIOOBE() { 745 var f = CHAR_GENERATORS.get(0); 746 return INDEX_GENERATORS.stream().map(fi -> { 747 return new Object[] {f, fi}; 748 }). 749 toArray(Object[][]::new); 750 } 751 752 @DataProvider 753 public Object[][] charMaskProvider() { 754 return BOOLEAN_MASK_GENERATORS.stream(). 755 flatMap(fm -> CHAR_GENERATORS.stream().map(fa -> { 756 return new Object[] {fa, fm}; 757 })). 758 toArray(Object[][]::new); 759 } 760 761 @DataProvider 762 public Object[][] charMaskProviderForIOOBE() { 763 var f = CHAR_GENERATORS.get(0); 764 return BOOLEAN_MASK_GENERATORS.stream(). 765 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 766 return new Object[] {f, fi, fm}; 767 })). 768 toArray(Object[][]::new); 769 } 770 771 interface ToCharF { 772 char apply(int i); 773 } 774 775 static char[] fillChar(int s , ToCharF f) { 776 return fillChar(new char[s], f); 777 } 778 779 static char[] fillChar(char[] a, ToCharF f) { 780 for (int i = 0; i < a.length; i++) { 781 a[i] = f.apply(i); 782 } 783 return a; 784 } 785 786 @DontInline 787 static $abstractvectortype$ fromCharArray(char[] a, int i) { 788 return $abstractvectortype$.fromCharArray(SPECIES, a, i); 789 } 790 791 @DontInline 792 static $abstractvectortype$ fromCharArray(char[] a, int i, VectorMask<$Boxtype$> m) { 793 return $abstractvectortype$.fromCharArray(SPECIES, a, i, m); 794 } 795 796 @DontInline 797 static void intoCharArray($abstractvectortype$ v, char[] a, int i) { 798 v.intoCharArray(a, i); 799 } 800 801 @DontInline 802 static void intoCharArray($abstractvectortype$ v, char[] a, int i, VectorMask<$Boxtype$> m) { 803 v.intoCharArray(a, i, m); 804 } 805 806 @Test(dataProvider = "charProvider") 807 static void loadStoreCharArray(IntFunction<char[]> fa) { 808 char[] a = fa.apply(SPECIES.length()); 809 char[] r = new char[a.length]; 810 811 for (int ic = 0; ic < INVOC_COUNT; ic++) { 812 for (int i = 0; i < a.length; i += SPECIES.length()) { 813 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 814 av.intoCharArray(r, i); 815 } 816 } 817 Assert.assertEquals(a, r); 818 } 819 820 @Test(dataProvider = "charProviderForIOOBE") 821 static void loadCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 822 char[] a = fa.apply(SPECIES.length()); 823 char[] r = new char[a.length]; 824 825 for (int ic = 0; ic < INVOC_COUNT; ic++) { 826 for (int i = 0; i < a.length; i += SPECIES.length()) { 827 $abstractvectortype$ av = fromCharArray(a, i); 828 av.intoCharArray(r, i); 829 } 830 } 831 832 int index = fi.apply(a.length); 833 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 834 try { 835 fromCharArray(a, index); 836 if (shouldFail) { 837 Assert.fail("Failed to throw IndexOutOfBoundsException"); 838 } 839 } catch (IndexOutOfBoundsException e) { 840 if (!shouldFail) { 841 Assert.fail("Unexpected IndexOutOfBoundsException"); 842 } 843 } 844 } 845 846 @Test(dataProvider = "charProviderForIOOBE") 847 static void storeCharArrayIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi) { 848 char[] a = fa.apply(SPECIES.length()); 849 char[] r = new char[a.length]; 850 851 for (int ic = 0; ic < INVOC_COUNT; ic++) { 852 for (int i = 0; i < a.length; i += SPECIES.length()) { 853 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 854 intoCharArray(av, r, i); 855 } 856 } 857 858 int index = fi.apply(a.length); 859 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 860 try { 861 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0); 862 intoCharArray(av, r, index); 863 if (shouldFail) { 864 Assert.fail("Failed to throw IndexOutOfBoundsException"); 865 } 866 } catch (IndexOutOfBoundsException e) { 867 if (!shouldFail) { 868 Assert.fail("Unexpected IndexOutOfBoundsException"); 869 } 870 } 871 } 872 873 @Test(dataProvider = "charMaskProvider") 874 static void loadStoreMaskCharArray(IntFunction<char[]> fa, 875 IntFunction<boolean[]> fm) { 876 char[] a = fa.apply(SPECIES.length()); 877 char[] r = new char[a.length]; 878 boolean[] mask = fm.apply(SPECIES.length()); 879 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 880 881 for (int ic = 0; ic < INVOC_COUNT; ic++) { 882 for (int i = 0; i < a.length; i += SPECIES.length()) { 883 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, vmask); 884 av.intoCharArray(r, i); 885 } 886 } 887 assertArraysEquals(a, r, mask); 888 889 890 r = new char[a.length]; 891 892 for (int ic = 0; ic < INVOC_COUNT; ic++) { 893 for (int i = 0; i < a.length; i += SPECIES.length()) { 894 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 895 av.intoCharArray(r, i, vmask); 896 } 897 } 898 assertArraysEquals(a, r, mask); 899 } 900 901 @Test(dataProvider = "charMaskProviderForIOOBE") 902 static void loadCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 903 char[] a = fa.apply(SPECIES.length()); 904 char[] r = new char[a.length]; 905 boolean[] mask = fm.apply(SPECIES.length()); 906 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 907 908 for (int ic = 0; ic < INVOC_COUNT; ic++) { 909 for (int i = 0; i < a.length; i += SPECIES.length()) { 910 $abstractvectortype$ av = fromCharArray(a, i, vmask); 911 av.intoCharArray(r, i); 912 } 913 } 914 915 int index = fi.apply(a.length); 916 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 917 try { 918 fromCharArray(a, index, vmask); 919 if (shouldFail) { 920 Assert.fail("Failed to throw IndexOutOfBoundsException"); 921 } 922 } catch (IndexOutOfBoundsException e) { 923 if (!shouldFail) { 924 Assert.fail("Unexpected IndexOutOfBoundsException"); 925 } 926 } 927 } 928 929 @Test(dataProvider = "charMaskProviderForIOOBE") 930 static void storeCharArrayMaskIOOBE(IntFunction<char[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 931 char[] a = fa.apply(SPECIES.length()); 932 char[] r = new char[a.length]; 933 boolean[] mask = fm.apply(SPECIES.length()); 934 VectorMask<$Boxtype$> vmask = VectorMask.fromValues(SPECIES, mask); 935 936 for (int ic = 0; ic < INVOC_COUNT; ic++) { 937 for (int i = 0; i < a.length; i += SPECIES.length()) { 938 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 939 intoCharArray(av, r, i, vmask); 940 } 941 } 942 943 int index = fi.apply(a.length); 944 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 945 try { 946 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, 0); 947 intoCharArray(av, a, index, vmask); 948 if (shouldFail) { 949 Assert.fail("Failed to throw IndexOutOfBoundsException"); 950 } 951 } catch (IndexOutOfBoundsException e) { 952 if (!shouldFail) { 953 Assert.fail("Unexpected IndexOutOfBoundsException"); 954 } 955 } 956 } 957 958 #end[short] 959 960 #if[byte] 961 static void assertArraysEquals(boolean[] r, byte[] a) { 962 int i = 0; 963 try { 964 for (; i < a.length; i++) { 965 Assert.assertEquals(r[i], (a[i] & 1) == 1); 966 } 967 } catch (AssertionError e) { 968 Assert.assertEquals(r[i], (a[i] & 1) == 1, "at index #" + i); 969 } 970 } 971 972 static void assertArraysEquals(boolean[] r, boolean[] a, boolean[] mask) { 973 int i = 0; 974 try { 975 for (; i < a.length; i++) { 976 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i]); 977 } 978 } catch (AssertionError e) { 979 Assert.assertEquals(r[i], mask[i % SPECIES.length()] && a[i], "at index #" + i); 980 } 981 } 982 983 static boolean[] convertToBooleanArray(byte[] a) { 984 boolean[] r = new boolean[a.length]; 985 986 for (int i = 0; i < a.length; i++) { 987 r[i] = (a[i] & 1) == 1; 988 } 989 990 return r; 991 } 992 993 @Test(dataProvider = "byteProvider") 994 static void loadByteStoreBooleanArray(IntFunction<byte[]> fa) { 995 byte[] a = fa.apply(SPECIES.length()); 996 boolean[] r = new boolean[a.length]; 997 998 for (int ic = 0; ic < INVOC_COUNT; ic++) { 999 for (int i = 0; i < a.length; i += SPECIES.length()) { 1000 ByteVector av = ByteVector.fromArray(SPECIES, a, i); 1001 av.intoBooleanArray(r, i); 1002 } 1003 } 1004 assertArraysEquals(r, a); 1005 } 1006 1007 @Test(dataProvider = "byteProvider") 1008 static void loadStoreBooleanArray(IntFunction<byte[]> fa) { 1009 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1010 boolean[] r = new boolean[a.length]; 1011 1012 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1013 for (int i = 0; i < a.length; i += SPECIES.length()) { 1014 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1015 av.intoBooleanArray(r, i); 1016 } 1017 } 1018 Assert.assertEquals(r, a); 1019 } 1020 1021 @Test(dataProvider = "byteMaskProvider") 1022 static void loadStoreMaskBooleanArray(IntFunction<byte[]> fa, 1023 IntFunction<boolean[]> fm) { 1024 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1025 boolean[] r = new boolean[a.length]; 1026 boolean[] mask = fm.apply(SPECIES.length()); 1027 VectorMask<Byte> vmask = VectorMask.fromValues(SPECIES, mask); 1028 1029 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1030 for (int i = 0; i < a.length; i += SPECIES.length()) { 1031 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i, vmask); 1032 av.intoBooleanArray(r, i); 1033 } 1034 } 1035 assertArraysEquals(r, a, mask); 1036 1037 1038 r = new boolean[a.length]; 1039 1040 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1041 for (int i = 0; i < a.length; i += SPECIES.length()) { 1042 ByteVector av = ByteVector.fromBooleanArray(SPECIES, a, i); 1043 av.intoBooleanArray(r, i, vmask); 1044 } 1045 } 1046 assertArraysEquals(r, a, mask); 1047 } 1048 #end[byte] 1049 1050 1051 // Gather/Scatter load/store tests 1052 1053 static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap) { 1054 int i = 0; 1055 int j = 0; 1056 try { 1057 for (; i < a.length; i += SPECIES.length()) { 1058 j = i; 1059 for (; j < i + SPECIES.length(); j++) { 1060 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1061 } 1062 } 1063 } catch (AssertionError e) { 1064 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1065 } 1066 } 1067 1068 static void assertGatherArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) { 1069 int i = 0; 1070 int j = 0; 1071 try { 1072 for (; i < a.length; i += SPECIES.length()) { 1073 j = i; 1074 for (; j < i + SPECIES.length(); j++) { 1075 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0); 1076 } 1077 } 1078 } catch (AssertionError e) { 1079 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: ($type$) 0, "at index #" + j); 1080 } 1081 } 1082 1083 static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap, boolean[] mask) { 1084 $type$[] expected = new $type$[r.length]; 1085 1086 // Store before checking, since the same location may be stored to more than once 1087 for (int i = 0; i < a.length; i += SPECIES.length()) { 1088 for (int j = i; j < i + SPECIES.length(); j++) { 1089 if (mask[j % SPECIES.length()]) { 1090 expected[i + indexMap[j]] = a[j]; 1091 } 1092 } 1093 } 1094 1095 Assert.assertEquals(r, expected); 1096 } 1097 1098 static void assertScatterArraysEquals($type$[] r, $type$[] a, int[] indexMap) { 1099 $type$[] expected = new $type$[r.length]; 1100 1101 // Store before checking, since the same location may be stored to more than once 1102 for (int i = 0; i < a.length; i += SPECIES.length()) { 1103 for (int j = i; j < i + SPECIES.length(); j++) { 1104 expected[i + indexMap[j]] = a[j]; 1105 } 1106 } 1107 1108 Assert.assertEquals(r, expected); 1109 } 1110 1111 @DataProvider 1112 public Object[][] gatherScatterProvider() { 1113 return INT_INDEX_GENERATORS.stream(). 1114 flatMap(fs -> $TYPE$_GENERATORS.stream().map(fa -> { 1115 return new Object[] {fa, fs}; 1116 })). 1117 toArray(Object[][]::new); 1118 } 1119 1120 @DataProvider 1121 public Object[][] gatherScatterMaskProvider() { 1122 return BOOLEAN_MASK_GENERATORS.stream(). 1123 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1124 $TYPE$_GENERATORS.stream().map(fa -> { 1125 return new Object[] {fa, fm, fs}; 1126 }))). 1127 toArray(Object[][]::new); 1128 } 1129 1130 1131 @Test(dataProvider = "gatherScatterProvider") 1132 static void gather(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1133 $type$[] a = fa.apply(SPECIES.length()); 1134 int[] b = fs.apply(a.length, SPECIES.length()); 1135 $type$[] r = new $type$[a.length]; 1136 1137 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1138 for (int i = 0; i < a.length; i += SPECIES.length()) { 1139 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i); 1140 av.intoArray(r, i); 1141 } 1142 } 1143 1144 assertGatherArraysEquals(r, a, b); 1145 } 1146 1147 @Test(dataProvider = "gatherScatterMaskProvider") 1148 static void gatherMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1149 $type$[] a = fa.apply(SPECIES.length()); 1150 int[] b = fs.apply(a.length, SPECIES.length()); 1151 $type$[] r = new $type$[a.length]; 1152 boolean[] mask = fm.apply(SPECIES.length()); 1153 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1154 1155 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1156 for (int i = 0; i < a.length; i += SPECIES.length()) { 1157 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i, b, i, vmask); 1158 av.intoArray(r, i); 1159 } 1160 } 1161 1162 assertGatherArraysEquals(r, a, b, mask); 1163 } 1164 1165 @Test(dataProvider = "gatherScatterProvider") 1166 static void scatter(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1167 $type$[] a = fa.apply(SPECIES.length()); 1168 int[] b = fs.apply(a.length, SPECIES.length()); 1169 $type$[] r = new $type$[a.length]; 1170 1171 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1172 for (int i = 0; i < a.length; i += SPECIES.length()) { 1173 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 1174 av.intoArray(r, i, b, i); 1175 } 1176 } 1177 1178 assertScatterArraysEquals(r, a, b); 1179 } 1180 1181 @Test(dataProvider = "gatherScatterMaskProvider") 1182 static void scatterMask(IntFunction<$type$[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1183 $type$[] a = fa.apply(SPECIES.length()); 1184 int[] b = fs.apply(a.length, SPECIES.length()); 1185 $type$[] r = new $type$[a.length]; 1186 boolean[] mask = fm.apply(SPECIES.length()); 1187 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1188 1189 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1190 for (int i = 0; i < a.length; i += SPECIES.length()) { 1191 $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); 1192 av.intoArray(r, i, b, i, vmask); 1193 } 1194 } 1195 1196 assertScatterArraysEquals(r, a, b, mask); 1197 } 1198 1199 #if[short] 1200 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap) { 1201 int i = 0; 1202 int j = 0; 1203 try { 1204 for (; i < a.length; i += SPECIES.length()) { 1205 j = i; 1206 for (; j < i + SPECIES.length(); j++) { 1207 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1208 } 1209 } 1210 } catch (AssertionError e) { 1211 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1212 } 1213 } 1214 1215 static void assertGatherArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1216 int i = 0; 1217 int j = 0; 1218 try { 1219 for (; i < a.length; i += SPECIES.length()) { 1220 j = i; 1221 for (; j < i + SPECIES.length(); j++) { 1222 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0); 1223 } 1224 } 1225 } catch (AssertionError e) { 1226 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (char) 0, "at index #" + j); 1227 } 1228 } 1229 1230 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap, boolean[] mask) { 1231 char[] expected = new char[r.length]; 1232 1233 // Store before checking, since the same location may be stored to more than once 1234 for (int i = 0; i < a.length; i += SPECIES.length()) { 1235 for (int j = i; j < i + SPECIES.length(); j++) { 1236 if (mask[j % SPECIES.length()]) { 1237 expected[i + indexMap[j]] = a[j]; 1238 } 1239 } 1240 } 1241 1242 Assert.assertEquals(r, expected); 1243 } 1244 1245 static void assertScatterArraysEquals(char[] r, char[] a, int[] indexMap) { 1246 char[] expected = new char[r.length]; 1247 1248 // Store before checking, since the same location may be stored to more than once 1249 for (int i = 0; i < a.length; i += SPECIES.length()) { 1250 for (int j = i; j < i + SPECIES.length(); j++) { 1251 expected[i + indexMap[j]] = a[j]; 1252 } 1253 } 1254 1255 Assert.assertEquals(r, expected); 1256 } 1257 1258 @DataProvider 1259 public Object[][] charGatherScatterProvider() { 1260 return INT_INDEX_GENERATORS.stream(). 1261 flatMap(fs -> CHAR_GENERATORS.stream().map(fa -> { 1262 return new Object[] {fa, fs}; 1263 })). 1264 toArray(Object[][]::new); 1265 } 1266 1267 @DataProvider 1268 public Object[][] charGatherScatterMaskProvider() { 1269 return BOOLEAN_MASK_GENERATORS.stream(). 1270 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1271 CHAR_GENERATORS.stream().map(fa -> { 1272 return new Object[] {fa, fm, fs}; 1273 }))). 1274 toArray(Object[][]::new); 1275 } 1276 1277 1278 @Test(dataProvider = "charGatherScatterProvider") 1279 static void charGather(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1280 char[] a = fa.apply(SPECIES.length()); 1281 int[] b = fs.apply(a.length, SPECIES.length()); 1282 char[] r = new char[a.length]; 1283 1284 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1285 for (int i = 0; i < a.length; i += SPECIES.length()) { 1286 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i); 1287 av.intoCharArray(r, i); 1288 } 1289 } 1290 1291 assertGatherArraysEquals(r, a, b); 1292 } 1293 1294 @Test(dataProvider = "charGatherScatterMaskProvider") 1295 static void charGatherMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1296 char[] a = fa.apply(SPECIES.length()); 1297 int[] b = fs.apply(a.length, SPECIES.length()); 1298 char[] r = new char[a.length]; 1299 boolean[] mask = fm.apply(SPECIES.length()); 1300 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1301 1302 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1303 for (int i = 0; i < a.length; i += SPECIES.length()) { 1304 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i, b, i, vmask); 1305 av.intoCharArray(r, i); 1306 } 1307 } 1308 1309 assertGatherArraysEquals(r, a, b, mask); 1310 } 1311 1312 @Test(dataProvider = "charGatherScatterProvider") 1313 static void charScatter(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1314 char[] a = fa.apply(SPECIES.length()); 1315 int[] b = fs.apply(a.length, SPECIES.length()); 1316 char[] r = new char[a.length]; 1317 1318 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1319 for (int i = 0; i < a.length; i += SPECIES.length()) { 1320 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 1321 av.intoCharArray(r, i, b, i); 1322 } 1323 } 1324 1325 assertScatterArraysEquals(r, a, b); 1326 } 1327 1328 @Test(dataProvider = "charGatherScatterMaskProvider") 1329 static void charScatterMask(IntFunction<char[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1330 char[] a = fa.apply(SPECIES.length()); 1331 int[] b = fs.apply(a.length, SPECIES.length()); 1332 char[] r = new char[a.length]; 1333 boolean[] mask = fm.apply(SPECIES.length()); 1334 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1335 1336 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1337 for (int i = 0; i < a.length; i += SPECIES.length()) { 1338 $abstractvectortype$ av = $abstractvectortype$.fromCharArray(SPECIES, a, i); 1339 av.intoCharArray(r, i, b, i, vmask); 1340 } 1341 } 1342 1343 assertScatterArraysEquals(r, a, b, mask); 1344 } 1345 #end[short] 1346 1347 #if[byte] 1348 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 1349 int i = 0; 1350 int j = 0; 1351 try { 1352 for (; i < a.length; i += SPECIES.length()) { 1353 j = i; 1354 for (; j < i + SPECIES.length(); j++) { 1355 Assert.assertEquals(r[j], a[i + indexMap[j]]); 1356 } 1357 } 1358 } catch (AssertionError e) { 1359 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 1360 } 1361 } 1362 1363 static void assertGatherArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 1364 int i = 0; 1365 int j = 0; 1366 try { 1367 for (; i < a.length; i += SPECIES.length()) { 1368 j = i; 1369 for (; j < i + SPECIES.length(); j++) { 1370 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false); 1371 } 1372 } 1373 } catch (AssertionError e) { 1374 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: false, "at index #" + j); 1375 } 1376 } 1377 1378 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap, boolean[] mask) { 1379 boolean[] expected = new boolean[r.length]; 1380 1381 // Store before checking, since the same location may be stored to more than once 1382 for (int i = 0; i < a.length; i += SPECIES.length()) { 1383 for (int j = i; j < i + SPECIES.length(); j++) { 1384 if (mask[j % SPECIES.length()]) { 1385 expected[i + indexMap[j]] = a[j]; 1386 } 1387 } 1388 } 1389 1390 Assert.assertEquals(r, expected); 1391 } 1392 1393 static void assertScatterArraysEquals(boolean[] r, boolean[] a, int[] indexMap) { 1394 boolean[] expected = new boolean[r.length]; 1395 1396 // Store before checking, since the same location may be stored to more than once 1397 for (int i = 0; i < a.length; i += SPECIES.length()) { 1398 for (int j = i; j < i + SPECIES.length(); j++) { 1399 expected[i + indexMap[j]] = a[j]; 1400 } 1401 } 1402 1403 Assert.assertEquals(r, expected); 1404 } 1405 1406 @Test(dataProvider = "gatherScatterProvider") 1407 static void booleanGather(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1408 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1409 int[] b = fs.apply(a.length, SPECIES.length()); 1410 boolean[] r = new boolean[a.length]; 1411 1412 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1413 for (int i = 0; i < a.length; i += SPECIES.length()) { 1414 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i); 1415 av.intoBooleanArray(r, i); 1416 } 1417 } 1418 1419 assertGatherArraysEquals(r, a, b); 1420 } 1421 1422 @Test(dataProvider = "gatherScatterMaskProvider") 1423 static void booleanGatherMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1424 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1425 int[] b = fs.apply(a.length, SPECIES.length()); 1426 boolean[] r = new boolean[a.length]; 1427 boolean[] mask = fm.apply(SPECIES.length()); 1428 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1429 1430 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1431 for (int i = 0; i < a.length; i += SPECIES.length()) { 1432 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i, b, i, vmask); 1433 av.intoBooleanArray(r, i); 1434 } 1435 } 1436 1437 assertGatherArraysEquals(r, a, b, mask); 1438 } 1439 1440 @Test(dataProvider = "gatherScatterProvider") 1441 static void booleanScatter(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1442 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1443 int[] b = fs.apply(a.length, SPECIES.length()); 1444 boolean[] r = new boolean[a.length]; 1445 1446 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1447 for (int i = 0; i < a.length; i += SPECIES.length()) { 1448 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i); 1449 av.intoBooleanArray(r, i, b, i); 1450 } 1451 } 1452 1453 assertScatterArraysEquals(r, a, b); 1454 } 1455 1456 @Test(dataProvider = "gatherScatterMaskProvider") 1457 static void booleanScatterMask(IntFunction<byte[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1458 boolean[] a = convertToBooleanArray(fa.apply(SPECIES.length())); 1459 int[] b = fs.apply(a.length, SPECIES.length()); 1460 boolean[] r = new boolean[a.length]; 1461 boolean[] mask = fm.apply(SPECIES.length()); 1462 VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1463 1464 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1465 for (int i = 0; i < a.length; i += SPECIES.length()) { 1466 $abstractvectortype$ av = $abstractvectortype$.fromBooleanArray(SPECIES, a, i); 1467 av.intoBooleanArray(r, i, b, i, vmask); 1468 } 1469 } 1470 1471 assertScatterArraysEquals(r, a, b, mask); 1472 } 1473 #end[byte] 1474 1475 }