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.foreign jdk.incubator.vector java.base/jdk.internal.vm.annotation 27 * @run testng/othervm -XX:-TieredCompilation Long512VectorLoadStoreTests 28 * 29 */ 30 31 // -- This file was mechanically generated: Do not edit! -- // 32 33 import jdk.incubator.foreign.MemorySegment; 34 import jdk.incubator.foreign.ResourceScope; 35 import jdk.incubator.foreign.ValueLayout; 36 import jdk.incubator.vector.LongVector; 37 import jdk.incubator.vector.VectorMask; 38 import jdk.incubator.vector.VectorSpecies; 39 import jdk.incubator.vector.VectorShuffle; 40 import jdk.internal.vm.annotation.DontInline; 41 import org.testng.Assert; 42 import org.testng.annotations.DataProvider; 43 import org.testng.annotations.Test; 44 45 import java.nio.ByteOrder; 46 import java.util.List; 47 import java.util.function.*; 48 49 @Test 50 public class Long512VectorLoadStoreTests extends AbstractVectorLoadStoreTest { 51 static final VectorSpecies<Long> SPECIES = 52 LongVector.SPECIES_512; 53 54 static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100); 55 56 57 static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 512); 58 59 static void assertArraysEquals(long[] r, long[] a, boolean[] mask) { 60 int i = 0; 61 try { 62 for (; i < a.length; i++) { 63 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (long) 0); 64 } 65 } catch (AssertionError e) { 66 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (long) 0, "at index #" + i); 67 } 68 } 69 70 static final List<IntFunction<long[]>> LONG_GENERATORS = List.of( 71 withToString("long[i * 5]", (int s) -> { 72 return fill(s * BUFFER_REPS, 73 i -> (long)(i * 5)); 74 }), 75 withToString("long[i + 1]", (int s) -> { 76 return fill(s * BUFFER_REPS, 77 i -> (((long)(i + 1) == 0) ? 1 : (long)(i + 1))); 78 }) 79 ); 80 81 // Relative to array.length 82 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 83 withToString("-1", (int l) -> { 84 return -1; 85 }), 86 withToString("l", (int l) -> { 87 return l; 88 }), 89 withToString("l - 1", (int l) -> { 90 return l - 1; 91 }), 92 withToString("l + 1", (int l) -> { 93 return l + 1; 94 }), 95 withToString("l - speciesl + 1", (int l) -> { 96 return l - SPECIES.length() + 1; 97 }), 98 withToString("l + speciesl - 1", (int l) -> { 99 return l + SPECIES.length() - 1; 100 }), 101 withToString("l + speciesl", (int l) -> { 102 return l + SPECIES.length(); 103 }), 104 withToString("l + speciesl + 1", (int l) -> { 105 return l + SPECIES.length() + 1; 106 }) 107 ); 108 109 // Relative to byte[] array.length or MemorySegment.byteSize() 110 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 111 withToString("-1", (int l) -> { 112 return -1; 113 }), 114 withToString("l", (int l) -> { 115 return l; 116 }), 117 withToString("l - 1", (int l) -> { 118 return l - 1; 119 }), 120 withToString("l + 1", (int l) -> { 121 return l + 1; 122 }), 123 withToString("l - speciesl*ebsize + 1", (int l) -> { 124 return l - SPECIES.vectorByteSize() + 1; 125 }), 126 withToString("l + speciesl*ebsize - 1", (int l) -> { 127 return l + SPECIES.vectorByteSize() - 1; 128 }), 129 withToString("l + speciesl*ebsize", (int l) -> { 130 return l + SPECIES.vectorByteSize(); 131 }), 132 withToString("l + speciesl*ebsize + 1", (int l) -> { 133 return l + SPECIES.vectorByteSize() + 1; 134 }) 135 ); 136 137 @DataProvider 138 public Object[][] longProvider() { 139 return LONG_GENERATORS.stream(). 140 map(f -> new Object[]{f}). 141 toArray(Object[][]::new); 142 } 143 144 @DataProvider 145 public Object[][] maskProvider() { 146 return BOOLEAN_MASK_GENERATORS.stream(). 147 map(f -> new Object[]{f}). 148 toArray(Object[][]::new); 149 } 150 151 @DataProvider 152 public Object[][] longProviderForIOOBE() { 153 var f = LONG_GENERATORS.get(0); 154 return INDEX_GENERATORS.stream().map(fi -> { 155 return new Object[] {f, fi}; 156 }). 157 toArray(Object[][]::new); 158 } 159 160 @DataProvider 161 public Object[][] longMaskProvider() { 162 return BOOLEAN_MASK_GENERATORS.stream(). 163 flatMap(fm -> LONG_GENERATORS.stream().map(fa -> { 164 return new Object[] {fa, fm}; 165 })). 166 toArray(Object[][]::new); 167 } 168 169 @DataProvider 170 public Object[][] longMaskProviderForIOOBE() { 171 var f = LONG_GENERATORS.get(0); 172 return BOOLEAN_MASK_GENERATORS.stream(). 173 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 174 return new Object[] {f, fi, fm}; 175 })). 176 toArray(Object[][]::new); 177 } 178 179 @DataProvider 180 public Object[][] longMemorySegmentProvider() { 181 return LONG_GENERATORS.stream(). 182 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 183 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 184 return new Object[]{fa, fb, bo}; 185 }))). 186 toArray(Object[][]::new); 187 } 188 189 @DataProvider 190 public Object[][] longMemorySegmentMaskProvider() { 191 return BOOLEAN_MASK_GENERATORS.stream(). 192 flatMap(fm -> LONG_GENERATORS.stream(). 193 flatMap(fa -> MEMORY_SEGMENT_GENERATORS.stream(). 194 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 195 return new Object[]{fa, fb, fm, bo}; 196 })))). 197 toArray(Object[][]::new); 198 } 199 200 @DataProvider 201 public Object[][] longByteProviderForIOOBE() { 202 var f = LONG_GENERATORS.get(0); 203 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 204 return new Object[] {f, fi}; 205 }). 206 toArray(Object[][]::new); 207 } 208 209 @DataProvider 210 public Object[][] longByteMaskProviderForIOOBE() { 211 var f = LONG_GENERATORS.get(0); 212 return BOOLEAN_MASK_GENERATORS.stream(). 213 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 214 return new Object[] {f, fi, fm}; 215 })). 216 toArray(Object[][]::new); 217 } 218 219 static MemorySegment toSegment(long[] a, IntFunction<MemorySegment> fb) { 220 MemorySegment ms = fb.apply(a.length * SPECIES.elementSize() / 8); 221 for (int i = 0; i < a.length; i++) { 222 ms.set(ValueLayout.JAVA_LONG, i * SPECIES.elementSize() / 8 , a[i]); 223 } 224 return ms; 225 } 226 227 static long[] segmentToArray(MemorySegment ms) { 228 return ms.toArray(ValueLayout.JAVA_LONG); 229 } 230 231 232 interface ToLongF { 233 long apply(int i); 234 } 235 236 static long[] fill(int s , ToLongF f) { 237 return fill(new long[s], f); 238 } 239 240 static long[] fill(long[] a, ToLongF f) { 241 for (int i = 0; i < a.length; i++) { 242 a[i] = f.apply(i); 243 } 244 return a; 245 } 246 247 @DontInline 248 static LongVector fromArray(long[] a, int i) { 249 return LongVector.fromArray(SPECIES, a, i); 250 } 251 252 @DontInline 253 static LongVector fromArray(long[] a, int i, VectorMask<Long> m) { 254 return LongVector.fromArray(SPECIES, a, i, m); 255 } 256 257 @DontInline 258 static void intoArray(LongVector v, long[] a, int i) { 259 v.intoArray(a, i); 260 } 261 262 @DontInline 263 static void intoArray(LongVector v, long[] a, int i, VectorMask<Long> m) { 264 v.intoArray(a, i, m); 265 } 266 267 @DontInline 268 static LongVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo) { 269 return LongVector.fromMemorySegment(SPECIES, a, i, bo); 270 } 271 272 @DontInline 273 static LongVector fromMemorySegment(MemorySegment a, int i, ByteOrder bo, VectorMask<Long> m) { 274 return LongVector.fromMemorySegment(SPECIES, a, i, bo, m); 275 } 276 277 @DontInline 278 static void intoMemorySegment(LongVector v, MemorySegment a, int i, ByteOrder bo) { 279 v.intoMemorySegment(a, i, bo); 280 } 281 282 @DontInline 283 static void intoMemorySegment(LongVector v, MemorySegment a, int i, ByteOrder bo, VectorMask<Long> m) { 284 v.intoMemorySegment(a, i, bo, m); 285 } 286 287 @Test(dataProvider = "longProvider") 288 static void loadStoreArray(IntFunction<long[]> fa) { 289 long[] a = fa.apply(SPECIES.length()); 290 long[] r = new long[a.length]; 291 292 for (int ic = 0; ic < INVOC_COUNT; ic++) { 293 for (int i = 0; i < a.length; i += SPECIES.length()) { 294 LongVector av = LongVector.fromArray(SPECIES, a, i); 295 av.intoArray(r, i); 296 } 297 } 298 Assert.assertEquals(r, a); 299 } 300 301 @Test(dataProvider = "longProviderForIOOBE") 302 static void loadArrayIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi) { 303 long[] a = fa.apply(SPECIES.length()); 304 long[] r = new long[a.length]; 305 306 for (int ic = 0; ic < INVOC_COUNT; ic++) { 307 for (int i = 0; i < a.length; i += SPECIES.length()) { 308 LongVector av = fromArray(a, i); 309 av.intoArray(r, i); 310 } 311 } 312 313 int index = fi.apply(a.length); 314 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 315 try { 316 fromArray(a, index); 317 if (shouldFail) { 318 Assert.fail("Failed to throw IndexOutOfBoundsException"); 319 } 320 } catch (IndexOutOfBoundsException e) { 321 if (!shouldFail) { 322 Assert.fail("Unexpected IndexOutOfBoundsException"); 323 } 324 } 325 } 326 327 @Test(dataProvider = "longProviderForIOOBE") 328 static void storeArrayIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi) { 329 long[] a = fa.apply(SPECIES.length()); 330 long[] r = new long[a.length]; 331 332 for (int ic = 0; ic < INVOC_COUNT; ic++) { 333 for (int i = 0; i < a.length; i += SPECIES.length()) { 334 LongVector av = LongVector.fromArray(SPECIES, a, i); 335 intoArray(av, r, i); 336 } 337 } 338 339 int index = fi.apply(a.length); 340 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 341 try { 342 LongVector av = LongVector.fromArray(SPECIES, a, 0); 343 intoArray(av, r, index); 344 if (shouldFail) { 345 Assert.fail("Failed to throw IndexOutOfBoundsException"); 346 } 347 } catch (IndexOutOfBoundsException e) { 348 if (!shouldFail) { 349 Assert.fail("Unexpected IndexOutOfBoundsException"); 350 } 351 } 352 } 353 354 355 @Test(dataProvider = "longMaskProvider") 356 static void loadStoreMaskArray(IntFunction<long[]> fa, 357 IntFunction<boolean[]> fm) { 358 long[] a = fa.apply(SPECIES.length()); 359 long[] r = new long[a.length]; 360 boolean[] mask = fm.apply(SPECIES.length()); 361 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 362 363 for (int ic = 0; ic < INVOC_COUNT; ic++) { 364 for (int i = 0; i < a.length; i += SPECIES.length()) { 365 LongVector av = LongVector.fromArray(SPECIES, a, i, vmask); 366 av.intoArray(r, i); 367 } 368 } 369 assertArraysEquals(r, a, mask); 370 371 372 r = new long[a.length]; 373 374 for (int ic = 0; ic < INVOC_COUNT; ic++) { 375 for (int i = 0; i < a.length; i += SPECIES.length()) { 376 LongVector av = LongVector.fromArray(SPECIES, a, i); 377 av.intoArray(r, i, vmask); 378 } 379 } 380 assertArraysEquals(r, a, mask); 381 } 382 383 @Test(dataProvider = "longMaskProviderForIOOBE") 384 static void loadArrayMaskIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 385 long[] a = fa.apply(SPECIES.length()); 386 long[] r = new long[a.length]; 387 boolean[] mask = fm.apply(SPECIES.length()); 388 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 389 390 for (int ic = 0; ic < INVOC_COUNT; ic++) { 391 for (int i = 0; i < a.length; i += SPECIES.length()) { 392 LongVector av = fromArray(a, i, vmask); 393 av.intoArray(r, i); 394 } 395 } 396 397 int index = fi.apply(a.length); 398 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 399 try { 400 fromArray(a, index, vmask); 401 if (shouldFail) { 402 Assert.fail("Failed to throw IndexOutOfBoundsException"); 403 } 404 } catch (IndexOutOfBoundsException e) { 405 if (!shouldFail) { 406 Assert.fail("Unexpected IndexOutOfBoundsException"); 407 } 408 } 409 } 410 411 @Test(dataProvider = "longMaskProviderForIOOBE") 412 static void storeArrayMaskIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 413 long[] a = fa.apply(SPECIES.length()); 414 long[] r = new long[a.length]; 415 boolean[] mask = fm.apply(SPECIES.length()); 416 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 417 418 for (int ic = 0; ic < INVOC_COUNT; ic++) { 419 for (int i = 0; i < a.length; i += SPECIES.length()) { 420 LongVector av = LongVector.fromArray(SPECIES, a, i); 421 intoArray(av, r, i, vmask); 422 } 423 } 424 425 int index = fi.apply(a.length); 426 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 427 try { 428 LongVector av = LongVector.fromArray(SPECIES, a, 0); 429 intoArray(av, a, index, vmask); 430 if (shouldFail) { 431 Assert.fail("Failed to throw IndexOutOfBoundsException"); 432 } 433 } catch (IndexOutOfBoundsException e) { 434 if (!shouldFail) { 435 Assert.fail("Unexpected IndexOutOfBoundsException"); 436 } 437 } 438 } 439 440 441 @Test(dataProvider = "longMaskProvider") 442 static void loadStoreMask(IntFunction<long[]> fa, 443 IntFunction<boolean[]> fm) { 444 boolean[] mask = fm.apply(SPECIES.length()); 445 boolean[] r = new boolean[mask.length]; 446 447 for (int ic = 0; ic < INVOC_COUNT; ic++) { 448 for (int i = 0; i < mask.length; i += SPECIES.length()) { 449 VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, i); 450 vmask.intoArray(r, i); 451 } 452 } 453 Assert.assertEquals(r, mask); 454 } 455 456 457 @Test(dataProvider = "longMemorySegmentProvider") 458 static void loadStoreMemorySegment(IntFunction<long[]> fa, 459 IntFunction<MemorySegment> fb, 460 ByteOrder bo) { 461 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb); 462 MemorySegment r = fb.apply((int) a.byteSize()); 463 464 int l = (int) a.byteSize(); 465 int s = SPECIES.vectorByteSize(); 466 467 for (int ic = 0; ic < INVOC_COUNT; ic++) { 468 for (int i = 0; i < l; i += s) { 469 LongVector av = LongVector.fromMemorySegment(SPECIES, a, i, bo); 470 av.intoMemorySegment(r, i, bo); 471 } 472 } 473 long m = r.mismatch(a); 474 Assert.assertEquals(m, -1, "Segments not equal"); 475 } 476 477 @Test(dataProvider = "longByteProviderForIOOBE") 478 static void loadMemorySegmentIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi) { 479 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 480 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 481 482 int l = (int) a.byteSize(); 483 int s = SPECIES.vectorByteSize(); 484 485 for (int ic = 0; ic < INVOC_COUNT; ic++) { 486 for (int i = 0; i < l; i += s) { 487 LongVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder()); 488 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 489 } 490 } 491 492 int index = fi.apply((int) a.byteSize()); 493 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 494 try { 495 fromMemorySegment(a, index, ByteOrder.nativeOrder()); 496 if (shouldFail) { 497 Assert.fail("Failed to throw IndexOutOfBoundsException"); 498 } 499 } catch (IndexOutOfBoundsException e) { 500 if (!shouldFail) { 501 Assert.fail("Unexpected IndexOutOfBoundsException"); 502 } 503 } 504 } 505 506 @Test(dataProvider = "longByteProviderForIOOBE") 507 static void storeMemorySegmentIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi) { 508 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 509 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 510 511 int l = (int) a.byteSize(); 512 int s = SPECIES.vectorByteSize(); 513 514 for (int ic = 0; ic < INVOC_COUNT; ic++) { 515 for (int i = 0; i < l; i += s) { 516 LongVector av = LongVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 517 intoMemorySegment(av, r, i, ByteOrder.nativeOrder()); 518 } 519 } 520 521 int index = fi.apply((int) a.byteSize()); 522 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, (int) a.byteSize()); 523 try { 524 LongVector av = LongVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 525 intoMemorySegment(av, r, index, ByteOrder.nativeOrder()); 526 if (shouldFail) { 527 Assert.fail("Failed to throw IndexOutOfBoundsException"); 528 } 529 } catch (IndexOutOfBoundsException e) { 530 if (!shouldFail) { 531 Assert.fail("Unexpected IndexOutOfBoundsException"); 532 } 533 } 534 } 535 536 @Test(dataProvider = "longMemorySegmentMaskProvider") 537 static void loadStoreMemorySegmentMask(IntFunction<long[]> fa, 538 IntFunction<MemorySegment> fb, 539 IntFunction<boolean[]> fm, 540 ByteOrder bo) { 541 long[] _a = fa.apply(SPECIES.length()); 542 MemorySegment a = toSegment(_a, fb); 543 MemorySegment r = fb.apply((int) a.byteSize()); 544 boolean[] mask = fm.apply(SPECIES.length()); 545 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 546 547 int l = (int) a.byteSize(); 548 int s = SPECIES.vectorByteSize(); 549 550 for (int ic = 0; ic < INVOC_COUNT; ic++) { 551 for (int i = 0; i < l; i += s) { 552 LongVector av = LongVector.fromMemorySegment(SPECIES, a, i, bo, vmask); 553 av.intoMemorySegment(r, i, bo); 554 } 555 } 556 assertArraysEquals(segmentToArray(r), _a, mask); 557 558 559 r = fb.apply((int) a.byteSize()); 560 561 for (int ic = 0; ic < INVOC_COUNT; ic++) { 562 for (int i = 0; i < l; i += s) { 563 LongVector av = LongVector.fromMemorySegment(SPECIES, a, i, bo); 564 av.intoMemorySegment(r, i, bo, vmask); 565 } 566 } 567 assertArraysEquals(segmentToArray(r), _a, mask); 568 } 569 570 @Test(dataProvider = "longByteMaskProviderForIOOBE") 571 static void loadMemorySegmentMaskIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 572 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 573 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 574 boolean[] mask = fm.apply(SPECIES.length()); 575 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 576 577 int l = (int) a.byteSize(); 578 int s = SPECIES.vectorByteSize(); 579 580 for (int ic = 0; ic < INVOC_COUNT; ic++) { 581 for (int i = 0; i < l; i += s) { 582 LongVector av = fromMemorySegment(a, i, ByteOrder.nativeOrder(), vmask); 583 av.intoMemorySegment(r, i, ByteOrder.nativeOrder()); 584 } 585 } 586 587 int index = fi.apply((int) a.byteSize()); 588 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 589 try { 590 fromMemorySegment(a, index, ByteOrder.nativeOrder(), vmask); 591 if (shouldFail) { 592 Assert.fail("Failed to throw IndexOutOfBoundsException"); 593 } 594 } catch (IndexOutOfBoundsException e) { 595 if (!shouldFail) { 596 Assert.fail("Unexpected IndexOutOfBoundsException"); 597 } 598 } 599 } 600 601 @Test(dataProvider = "longByteMaskProviderForIOOBE") 602 static void storeMemorySegmentMaskIOOBE(IntFunction<long[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 603 MemorySegment a = toSegment(fa.apply(SPECIES.length()), i -> MemorySegment.allocateNative(i, ResourceScope.newImplicitScope())); 604 MemorySegment r = MemorySegment.allocateNative(a.byteSize(), ResourceScope.newImplicitScope()); 605 boolean[] mask = fm.apply(SPECIES.length()); 606 VectorMask<Long> vmask = VectorMask.fromValues(SPECIES, mask); 607 608 int l = (int) a.byteSize(); 609 int s = SPECIES.vectorByteSize(); 610 611 for (int ic = 0; ic < INVOC_COUNT; ic++) { 612 for (int i = 0; i < l; i += s) { 613 LongVector av = LongVector.fromMemorySegment(SPECIES, a, i, ByteOrder.nativeOrder()); 614 intoMemorySegment(av, r, i, ByteOrder.nativeOrder(), vmask); 615 } 616 } 617 618 int index = fi.apply((int) a.byteSize()); 619 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, (int) a.byteSize(), SPECIES.elementSize() / 8); 620 try { 621 LongVector av = LongVector.fromMemorySegment(SPECIES, a, 0, ByteOrder.nativeOrder()); 622 intoMemorySegment(av, a, index, ByteOrder.nativeOrder(), vmask); 623 if (shouldFail) { 624 Assert.fail("Failed to throw IndexOutOfBoundsException"); 625 } 626 } catch (IndexOutOfBoundsException e) { 627 if (!shouldFail) { 628 Assert.fail("Unexpected IndexOutOfBoundsException"); 629 } 630 } 631 } 632 633 @Test(dataProvider = "longMemorySegmentProvider") 634 static void loadStoreReadonlyMemorySegment(IntFunction<long[]> fa, 635 IntFunction<MemorySegment> fb, 636 ByteOrder bo) { 637 MemorySegment a = toSegment(fa.apply(SPECIES.length()), fb).asReadOnly(); 638 639 Assert.assertThrows( 640 UnsupportedOperationException.class, 641 () -> SPECIES.zero().intoMemorySegment(a, 0, bo) 642 ); 643 644 Assert.assertThrows( 645 UnsupportedOperationException.class, 646 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(true)) 647 ); 648 649 Assert.assertThrows( 650 UnsupportedOperationException.class, 651 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, SPECIES.maskAll(false)) 652 ); 653 654 VectorMask<Long> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 655 .laneIsValid(); 656 Assert.assertThrows( 657 UnsupportedOperationException.class, 658 () -> SPECIES.zero().intoMemorySegment(a, 0, bo, m) 659 ); 660 } 661 662 663 @Test(dataProvider = "maskProvider") 664 static void loadStoreMask(IntFunction<boolean[]> fm) { 665 boolean[] a = fm.apply(SPECIES.length()); 666 boolean[] r = new boolean[a.length]; 667 668 for (int ic = 0; ic < INVOC_COUNT; ic++) { 669 for (int i = 0; i < a.length; i += SPECIES.length()) { 670 VectorMask<Long> vmask = SPECIES.loadMask(a, i); 671 vmask.intoArray(r, i); 672 } 673 } 674 Assert.assertEquals(r, a); 675 } 676 677 678 @Test 679 static void loadStoreShuffle() { 680 IntUnaryOperator fn = a -> a + 5; 681 for (int ic = 0; ic < INVOC_COUNT; ic++) { 682 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 683 int [] r = shuffle.toArray(); 684 685 int [] a = expectedShuffle(SPECIES.length(), fn); 686 Assert.assertEquals(r, a); 687 } 688 } 689 690 691 692 693 694 // Gather/Scatter load/store tests 695 696 static void assertGatherArraysEquals(long[] r, long[] a, int[] indexMap) { 697 int i = 0; 698 int j = 0; 699 try { 700 for (; i < a.length; i += SPECIES.length()) { 701 j = i; 702 for (; j < i + SPECIES.length(); j++) { 703 Assert.assertEquals(r[j], a[i + indexMap[j]]); 704 } 705 } 706 } catch (AssertionError e) { 707 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 708 } 709 } 710 711 static void assertGatherArraysEquals(long[] r, long[] a, int[] indexMap, boolean[] mask) { 712 int i = 0; 713 int j = 0; 714 try { 715 for (; i < a.length; i += SPECIES.length()) { 716 j = i; 717 for (; j < i + SPECIES.length(); j++) { 718 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (long) 0); 719 } 720 } 721 } catch (AssertionError e) { 722 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (long) 0, "at index #" + j); 723 } 724 } 725 726 static void assertScatterArraysEquals(long[] r, long[] a, int[] indexMap, boolean[] mask) { 727 long[] expected = new long[r.length]; 728 729 // Store before checking, since the same location may be stored to more than once 730 for (int i = 0; i < a.length; i += SPECIES.length()) { 731 for (int j = i; j < i + SPECIES.length(); j++) { 732 if (mask[j % SPECIES.length()]) { 733 expected[i + indexMap[j]] = a[j]; 734 } 735 } 736 } 737 738 Assert.assertEquals(r, expected); 739 } 740 741 static void assertScatterArraysEquals(long[] r, long[] a, int[] indexMap) { 742 long[] expected = new long[r.length]; 743 744 // Store before checking, since the same location may be stored to more than once 745 for (int i = 0; i < a.length; i += SPECIES.length()) { 746 for (int j = i; j < i + SPECIES.length(); j++) { 747 expected[i + indexMap[j]] = a[j]; 748 } 749 } 750 751 Assert.assertEquals(r, expected); 752 } 753 754 @DataProvider 755 public Object[][] gatherScatterProvider() { 756 return INT_INDEX_GENERATORS.stream(). 757 flatMap(fs -> LONG_GENERATORS.stream().map(fa -> { 758 return new Object[] {fa, fs}; 759 })). 760 toArray(Object[][]::new); 761 } 762 763 @DataProvider 764 public Object[][] gatherScatterMaskProvider() { 765 return BOOLEAN_MASK_GENERATORS.stream(). 766 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 767 LONG_GENERATORS.stream().map(fa -> { 768 return new Object[] {fa, fm, fs}; 769 }))). 770 toArray(Object[][]::new); 771 } 772 773 774 @Test(dataProvider = "gatherScatterProvider") 775 static void gather(IntFunction<long[]> fa, BiFunction<Integer,Integer,int[]> fs) { 776 long[] a = fa.apply(SPECIES.length()); 777 int[] b = fs.apply(a.length, SPECIES.length()); 778 long[] r = new long[a.length]; 779 780 for (int ic = 0; ic < INVOC_COUNT; ic++) { 781 for (int i = 0; i < a.length; i += SPECIES.length()) { 782 LongVector av = LongVector.fromArray(SPECIES, a, i, b, i); 783 av.intoArray(r, i); 784 } 785 } 786 787 assertGatherArraysEquals(r, a, b); 788 } 789 790 @Test(dataProvider = "gatherScatterMaskProvider") 791 static void gatherMask(IntFunction<long[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 792 long[] a = fa.apply(SPECIES.length()); 793 int[] b = fs.apply(a.length, SPECIES.length()); 794 long[] r = new long[a.length]; 795 boolean[] mask = fm.apply(SPECIES.length()); 796 VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0); 797 798 for (int ic = 0; ic < INVOC_COUNT; ic++) { 799 for (int i = 0; i < a.length; i += SPECIES.length()) { 800 LongVector av = LongVector.fromArray(SPECIES, a, i, b, i, vmask); 801 av.intoArray(r, i); 802 } 803 } 804 805 assertGatherArraysEquals(r, a, b, mask); 806 } 807 808 @Test(dataProvider = "gatherScatterProvider") 809 static void scatter(IntFunction<long[]> fa, BiFunction<Integer,Integer,int[]> fs) { 810 long[] a = fa.apply(SPECIES.length()); 811 int[] b = fs.apply(a.length, SPECIES.length()); 812 long[] r = new long[a.length]; 813 814 for (int ic = 0; ic < INVOC_COUNT; ic++) { 815 for (int i = 0; i < a.length; i += SPECIES.length()) { 816 LongVector av = LongVector.fromArray(SPECIES, a, i); 817 av.intoArray(r, i, b, i); 818 } 819 } 820 821 assertScatterArraysEquals(r, a, b); 822 } 823 824 @Test(dataProvider = "gatherScatterMaskProvider") 825 static void scatterMask(IntFunction<long[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 826 long[] a = fa.apply(SPECIES.length()); 827 int[] b = fs.apply(a.length, SPECIES.length()); 828 long[] r = new long[a.length]; 829 boolean[] mask = fm.apply(SPECIES.length()); 830 VectorMask<Long> vmask = VectorMask.fromArray(SPECIES, mask, 0); 831 832 for (int ic = 0; ic < INVOC_COUNT; ic++) { 833 for (int i = 0; i < a.length; i += SPECIES.length()) { 834 LongVector av = LongVector.fromArray(SPECIES, a, i); 835 av.intoArray(r, i, b, i, vmask); 836 } 837 } 838 839 assertScatterArraysEquals(r, a, b, mask); 840 } 841 842 843 844 } --- EOF ---