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