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