1 /* 2 * Copyright (c) 2018, 2021, 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 Double256VectorLoadStoreTests 28 * 29 */ 30 31 // -- This file was mechanically generated: Do not edit! -- // 32 33 import jdk.incubator.vector.DoubleVector; 34 import jdk.incubator.vector.VectorMask; 35 import jdk.incubator.vector.VectorSpecies; 36 import jdk.incubator.vector.VectorShuffle; 37 import jdk.internal.vm.annotation.DontInline; 38 import org.testng.Assert; 39 import org.testng.annotations.DataProvider; 40 import org.testng.annotations.Test; 41 42 import java.nio.ByteBuffer; 43 import java.nio.DoubleBuffer; 44 import java.nio.ByteOrder; 45 import java.nio.ReadOnlyBufferException; 46 import java.util.List; 47 import java.util.function.*; 48 49 @Test 50 public class Double256VectorLoadStoreTests extends AbstractVectorLoadStoreTest { 51 static final VectorSpecies<Double> SPECIES = 52 DoubleVector.SPECIES_256; 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 / 256); 58 assertArraysEquals(double[] r, double[] a, boolean[] mask)59 static void assertArraysEquals(double[] r, double[] 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] : (double) 0); 64 } 65 } catch (AssertionError e) { 66 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (double) 0, "at index #" + i); 67 } 68 } 69 assertArraysEquals(byte[] r, byte[] a, boolean[] mask)70 static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) { 71 int i = 0; 72 try { 73 for (; i < a.length; i++) { 74 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0); 75 } 76 } catch (AssertionError e) { 77 Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i); 78 } 79 } 80 81 static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of( 82 withToString("double[i * 5]", (int s) -> { 83 return fill(s * BUFFER_REPS, 84 i -> (double)(i * 5)); 85 }), 86 withToString("double[i + 1]", (int s) -> { 87 return fill(s * BUFFER_REPS, 88 i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1))); 89 }) 90 ); 91 92 // Relative to array.length 93 static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of( 94 withToString("-1", (int l) -> { 95 return -1; 96 }), 97 withToString("l", (int l) -> { 98 return l; 99 }), 100 withToString("l - 1", (int l) -> { 101 return l - 1; 102 }), 103 withToString("l + 1", (int l) -> { 104 return l + 1; 105 }), 106 withToString("l - speciesl + 1", (int l) -> { 107 return l - SPECIES.length() + 1; 108 }), 109 withToString("l + speciesl - 1", (int l) -> { 110 return l + SPECIES.length() - 1; 111 }), 112 withToString("l + speciesl", (int l) -> { 113 return l + SPECIES.length(); 114 }), 115 withToString("l + speciesl + 1", (int l) -> { 116 return l + SPECIES.length() + 1; 117 }) 118 ); 119 120 // Relative to byte[] array.length or ByteBuffer.limit() 121 static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of( 122 withToString("-1", (int l) -> { 123 return -1; 124 }), 125 withToString("l", (int l) -> { 126 return l; 127 }), 128 withToString("l - 1", (int l) -> { 129 return l - 1; 130 }), 131 withToString("l + 1", (int l) -> { 132 return l + 1; 133 }), 134 withToString("l - speciesl*ebsize + 1", (int l) -> { 135 return l - SPECIES.vectorByteSize() + 1; 136 }), 137 withToString("l + speciesl*ebsize - 1", (int l) -> { 138 return l + SPECIES.vectorByteSize() - 1; 139 }), 140 withToString("l + speciesl*ebsize", (int l) -> { 141 return l + SPECIES.vectorByteSize(); 142 }), 143 withToString("l + speciesl*ebsize + 1", (int l) -> { 144 return l + SPECIES.vectorByteSize() + 1; 145 }) 146 ); 147 148 @DataProvider doubleProvider()149 public Object[][] doubleProvider() { 150 return DOUBLE_GENERATORS.stream(). 151 map(f -> new Object[]{f}). 152 toArray(Object[][]::new); 153 } 154 155 @DataProvider maskProvider()156 public Object[][] maskProvider() { 157 return BOOLEAN_MASK_GENERATORS.stream(). 158 map(f -> new Object[]{f}). 159 toArray(Object[][]::new); 160 } 161 162 @DataProvider doubleProviderForIOOBE()163 public Object[][] doubleProviderForIOOBE() { 164 var f = DOUBLE_GENERATORS.get(0); 165 return INDEX_GENERATORS.stream().map(fi -> { 166 return new Object[] {f, fi}; 167 }). 168 toArray(Object[][]::new); 169 } 170 171 @DataProvider doubleMaskProvider()172 public Object[][] doubleMaskProvider() { 173 return BOOLEAN_MASK_GENERATORS.stream(). 174 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> { 175 return new Object[] {fa, fm}; 176 })). 177 toArray(Object[][]::new); 178 } 179 180 @DataProvider 181 public Object[][] doubleMaskProviderForIOOBE() { 182 var f = DOUBLE_GENERATORS.get(0); 183 return BOOLEAN_MASK_GENERATORS.stream(). 184 flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> { 185 return new Object[] {f, fi, fm}; 186 })). 187 toArray(Object[][]::new); 188 } 189 190 @DataProvider 191 public Object[][] doubleByteBufferProvider() { 192 return DOUBLE_GENERATORS.stream(). 193 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream(). 194 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 195 return new Object[]{fa, fb, bo}; 196 }))). 197 toArray(Object[][]::new); 198 } 199 200 @DataProvider 201 public Object[][] doubleByteBufferMaskProvider() { 202 return BOOLEAN_MASK_GENERATORS.stream(). 203 flatMap(fm -> DOUBLE_GENERATORS.stream(). 204 flatMap(fa -> BYTE_BUFFER_GENERATORS.stream(). 205 flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> { 206 return new Object[]{fa, fb, fm, bo}; 207 })))). 208 toArray(Object[][]::new); 209 } 210 211 @DataProvider 212 public Object[][] doubleByteArrayProvider() { 213 return DOUBLE_GENERATORS.stream(). 214 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> { 215 return new Object[]{fa, bo}; 216 })). 217 toArray(Object[][]::new); 218 } 219 220 @DataProvider 221 public Object[][] doubleByteArrayMaskProvider() { 222 return BOOLEAN_MASK_GENERATORS.stream(). 223 flatMap(fm -> DOUBLE_GENERATORS.stream(). 224 flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> { 225 return new Object[]{fa, fm, bo}; 226 }))). 227 toArray(Object[][]::new); 228 } 229 230 @DataProvider 231 public Object[][] doubleByteProviderForIOOBE() { 232 var f = DOUBLE_GENERATORS.get(0); 233 return BYTE_INDEX_GENERATORS.stream().map(fi -> { 234 return new Object[] {f, fi}; 235 }). 236 toArray(Object[][]::new); 237 } 238 239 @DataProvider 240 public Object[][] doubleByteMaskProviderForIOOBE() { 241 var f = DOUBLE_GENERATORS.get(0); 242 return BOOLEAN_MASK_GENERATORS.stream(). 243 flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> { 244 return new Object[] {f, fi, fm}; 245 })). 246 toArray(Object[][]::new); 247 } 248 249 static ByteBuffer toBuffer(double[] a, IntFunction<ByteBuffer> fb) { 250 ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8); 251 for (double v : a) { 252 bb.putDouble(v); 253 } 254 return bb.clear(); 255 } 256 257 static double[] bufferToArray(ByteBuffer bb) { 258 DoubleBuffer db = bb.asDoubleBuffer(); 259 double[] d = new double[db.capacity()]; 260 db.get(0, d); 261 return d; 262 } 263 264 static byte[] toByteArray(double[] a, IntFunction<byte[]> fb, ByteOrder bo) { 265 byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8); 266 DoubleBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).asDoubleBuffer(); 267 for (double v : a) { 268 bb.put(v); 269 } 270 return b; 271 } 272 273 274 interface ToDoubleF { 275 double apply(int i); 276 } 277 278 static double[] fill(int s , ToDoubleF f) { 279 return fill(new double[s], f); 280 } 281 282 static double[] fill(double[] a, ToDoubleF f) { 283 for (int i = 0; i < a.length; i++) { 284 a[i] = f.apply(i); 285 } 286 return a; 287 } 288 289 @DontInline 290 static DoubleVector fromArray(double[] a, int i) { 291 return DoubleVector.fromArray(SPECIES, a, i); 292 } 293 294 @DontInline 295 static DoubleVector fromArray(double[] a, int i, VectorMask<Double> m) { 296 return DoubleVector.fromArray(SPECIES, a, i, m); 297 } 298 299 @DontInline 300 static void intoArray(DoubleVector v, double[] a, int i) { 301 v.intoArray(a, i); 302 } 303 304 @DontInline 305 static void intoArray(DoubleVector v, double[] a, int i, VectorMask<Double> m) { 306 v.intoArray(a, i, m); 307 } 308 309 @DontInline 310 static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo) { 311 return DoubleVector.fromByteArray(SPECIES, a, i, bo); 312 } 313 314 @DontInline 315 static DoubleVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Double> m) { 316 return DoubleVector.fromByteArray(SPECIES, a, i, bo, m); 317 } 318 319 @DontInline 320 static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo) { 321 v.intoByteArray(a, i, bo); 322 } 323 324 @DontInline 325 static void intoByteArray(DoubleVector v, byte[] a, int i, ByteOrder bo, VectorMask<Double> m) { 326 v.intoByteArray(a, i, bo, m); 327 } 328 329 @DontInline 330 static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) { 331 return DoubleVector.fromByteBuffer(SPECIES, a, i, bo); 332 } 333 334 @DontInline 335 static DoubleVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) { 336 return DoubleVector.fromByteBuffer(SPECIES, a, i, bo, m); 337 } 338 339 @DontInline 340 static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo) { 341 v.intoByteBuffer(a, i, bo); 342 } 343 344 @DontInline 345 static void intoByteBuffer(DoubleVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Double> m) { 346 v.intoByteBuffer(a, i, bo, m); 347 } 348 349 350 @Test(dataProvider = "doubleProvider") 351 static void loadStoreArray(IntFunction<double[]> fa) { 352 double[] a = fa.apply(SPECIES.length()); 353 double[] r = new double[a.length]; 354 355 for (int ic = 0; ic < INVOC_COUNT; ic++) { 356 for (int i = 0; i < a.length; i += SPECIES.length()) { 357 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 358 av.intoArray(r, i); 359 } 360 } 361 Assert.assertEquals(r, a); 362 } 363 364 @Test(dataProvider = "doubleProviderForIOOBE") 365 static void loadArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 366 double[] a = fa.apply(SPECIES.length()); 367 double[] r = new double[a.length]; 368 369 for (int ic = 0; ic < INVOC_COUNT; ic++) { 370 for (int i = 0; i < a.length; i += SPECIES.length()) { 371 DoubleVector av = fromArray(a, i); 372 av.intoArray(r, i); 373 } 374 } 375 376 int index = fi.apply(a.length); 377 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 378 try { 379 fromArray(a, index); 380 if (shouldFail) { 381 Assert.fail("Failed to throw IndexOutOfBoundsException"); 382 } 383 } catch (IndexOutOfBoundsException e) { 384 if (!shouldFail) { 385 Assert.fail("Unexpected IndexOutOfBoundsException"); 386 } 387 } 388 } 389 390 @Test(dataProvider = "doubleProviderForIOOBE") 391 static void storeArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 392 double[] a = fa.apply(SPECIES.length()); 393 double[] r = new double[a.length]; 394 395 for (int ic = 0; ic < INVOC_COUNT; ic++) { 396 for (int i = 0; i < a.length; i += SPECIES.length()) { 397 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 398 intoArray(av, r, i); 399 } 400 } 401 402 int index = fi.apply(a.length); 403 boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length); 404 try { 405 DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0); 406 intoArray(av, r, index); 407 if (shouldFail) { 408 Assert.fail("Failed to throw IndexOutOfBoundsException"); 409 } 410 } catch (IndexOutOfBoundsException e) { 411 if (!shouldFail) { 412 Assert.fail("Unexpected IndexOutOfBoundsException"); 413 } 414 } 415 } 416 417 418 @Test(dataProvider = "doubleMaskProvider") 419 static void loadStoreMaskArray(IntFunction<double[]> fa, 420 IntFunction<boolean[]> fm) { 421 double[] a = fa.apply(SPECIES.length()); 422 double[] r = new double[a.length]; 423 boolean[] mask = fm.apply(SPECIES.length()); 424 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 425 426 for (int ic = 0; ic < INVOC_COUNT; ic++) { 427 for (int i = 0; i < a.length; i += SPECIES.length()) { 428 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, vmask); 429 av.intoArray(r, i); 430 } 431 } 432 assertArraysEquals(r, a, mask); 433 434 435 r = new double[a.length]; 436 437 for (int ic = 0; ic < INVOC_COUNT; ic++) { 438 for (int i = 0; i < a.length; i += SPECIES.length()) { 439 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 440 av.intoArray(r, i, vmask); 441 } 442 } 443 assertArraysEquals(r, a, mask); 444 } 445 446 @Test(dataProvider = "doubleMaskProviderForIOOBE") 447 static void loadArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 448 double[] a = fa.apply(SPECIES.length()); 449 double[] r = new double[a.length]; 450 boolean[] mask = fm.apply(SPECIES.length()); 451 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 452 453 for (int ic = 0; ic < INVOC_COUNT; ic++) { 454 for (int i = 0; i < a.length; i += SPECIES.length()) { 455 DoubleVector av = fromArray(a, i, vmask); 456 av.intoArray(r, i); 457 } 458 } 459 460 int index = fi.apply(a.length); 461 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 462 try { 463 fromArray(a, index, vmask); 464 if (shouldFail) { 465 Assert.fail("Failed to throw IndexOutOfBoundsException"); 466 } 467 } catch (IndexOutOfBoundsException e) { 468 if (!shouldFail) { 469 Assert.fail("Unexpected IndexOutOfBoundsException"); 470 } 471 } 472 } 473 474 @Test(dataProvider = "doubleMaskProviderForIOOBE") 475 static void storeArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 476 double[] a = fa.apply(SPECIES.length()); 477 double[] r = new double[a.length]; 478 boolean[] mask = fm.apply(SPECIES.length()); 479 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 480 481 for (int ic = 0; ic < INVOC_COUNT; ic++) { 482 for (int i = 0; i < a.length; i += SPECIES.length()) { 483 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 484 intoArray(av, r, i, vmask); 485 } 486 } 487 488 int index = fi.apply(a.length); 489 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length); 490 try { 491 DoubleVector av = DoubleVector.fromArray(SPECIES, a, 0); 492 intoArray(av, a, index, vmask); 493 if (shouldFail) { 494 Assert.fail("Failed to throw IndexOutOfBoundsException"); 495 } 496 } catch (IndexOutOfBoundsException e) { 497 if (!shouldFail) { 498 Assert.fail("Unexpected IndexOutOfBoundsException"); 499 } 500 } 501 } 502 503 504 @Test(dataProvider = "doubleMaskProvider") 505 static void loadStoreMask(IntFunction<double[]> fa, 506 IntFunction<boolean[]> fm) { 507 boolean[] mask = fm.apply(SPECIES.length()); 508 boolean[] r = new boolean[mask.length]; 509 510 for (int ic = 0; ic < INVOC_COUNT; ic++) { 511 for (int i = 0; i < mask.length; i += SPECIES.length()) { 512 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, i); 513 vmask.intoArray(r, i); 514 } 515 } 516 Assert.assertEquals(r, mask); 517 } 518 519 520 @Test(dataProvider = "doubleByteBufferProvider") 521 static void loadStoreByteBuffer(IntFunction<double[]> fa, 522 IntFunction<ByteBuffer> fb, 523 ByteOrder bo) { 524 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb); 525 ByteBuffer r = fb.apply(a.limit()); 526 527 int l = a.limit(); 528 int s = SPECIES.vectorByteSize(); 529 530 for (int ic = 0; ic < INVOC_COUNT; ic++) { 531 for (int i = 0; i < l; i += s) { 532 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo); 533 av.intoByteBuffer(r, i, bo); 534 } 535 } 536 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 537 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 538 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 539 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 540 Assert.assertEquals(r, a, "Buffers not equal"); 541 } 542 543 @Test(dataProvider = "doubleByteProviderForIOOBE") 544 static void loadByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 545 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 546 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 547 548 int l = a.limit(); 549 int s = SPECIES.vectorByteSize(); 550 551 for (int ic = 0; ic < INVOC_COUNT; ic++) { 552 for (int i = 0; i < l; i += s) { 553 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder()); 554 av.intoByteBuffer(r, i, ByteOrder.nativeOrder()); 555 } 556 } 557 558 int index = fi.apply(a.limit()); 559 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit()); 560 try { 561 fromByteBuffer(a, index, ByteOrder.nativeOrder()); 562 if (shouldFail) { 563 Assert.fail("Failed to throw IndexOutOfBoundsException"); 564 } 565 } catch (IndexOutOfBoundsException e) { 566 if (!shouldFail) { 567 Assert.fail("Unexpected IndexOutOfBoundsException"); 568 } 569 } 570 } 571 572 @Test(dataProvider = "doubleByteProviderForIOOBE") 573 static void storeByteBufferIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 574 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 575 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 576 577 int l = a.limit(); 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 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder()); 583 intoByteBuffer(av, r, i, ByteOrder.nativeOrder()); 584 } 585 } 586 587 int index = fi.apply(a.limit()); 588 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit()); 589 try { 590 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder()); 591 intoByteBuffer(av, r, index, ByteOrder.nativeOrder()); 592 if (shouldFail) { 593 Assert.fail("Failed to throw IndexOutOfBoundsException"); 594 } 595 } catch (IndexOutOfBoundsException e) { 596 if (!shouldFail) { 597 Assert.fail("Unexpected IndexOutOfBoundsException"); 598 } 599 } 600 } 601 602 603 @Test(dataProvider = "doubleByteBufferMaskProvider") 604 static void loadStoreByteBufferMask(IntFunction<double[]> fa, 605 IntFunction<ByteBuffer> fb, 606 IntFunction<boolean[]> fm, 607 ByteOrder bo) { 608 double[] _a = fa.apply(SPECIES.length()); 609 ByteBuffer a = toBuffer(_a, fb); 610 ByteBuffer r = fb.apply(a.limit()); 611 boolean[] mask = fm.apply(SPECIES.length()); 612 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 613 614 int l = a.limit(); 615 int s = SPECIES.vectorByteSize(); 616 617 for (int ic = 0; ic < INVOC_COUNT; ic++) { 618 for (int i = 0; i < l; i += s) { 619 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo, vmask); 620 av.intoByteBuffer(r, i, bo); 621 } 622 } 623 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 624 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 625 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 626 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 627 assertArraysEquals(bufferToArray(r), _a, mask); 628 629 630 r = fb.apply(a.limit()); 631 632 for (int ic = 0; ic < INVOC_COUNT; ic++) { 633 for (int i = 0; i < l; i += s) { 634 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, bo); 635 av.intoByteBuffer(r, i, bo, vmask); 636 } 637 } 638 Assert.assertEquals(a.position(), 0, "Input buffer position changed"); 639 Assert.assertEquals(a.limit(), l, "Input buffer limit changed"); 640 Assert.assertEquals(r.position(), 0, "Result buffer position changed"); 641 Assert.assertEquals(r.limit(), l, "Result buffer limit changed"); 642 assertArraysEquals(bufferToArray(r), _a, mask); 643 } 644 645 @Test(dataProvider = "doubleByteMaskProviderForIOOBE") 646 static void loadByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 647 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 648 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 649 boolean[] mask = fm.apply(SPECIES.length()); 650 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 651 652 int l = a.limit(); 653 int s = SPECIES.vectorByteSize(); 654 655 for (int ic = 0; ic < INVOC_COUNT; ic++) { 656 for (int i = 0; i < l; i += s) { 657 DoubleVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask); 658 av.intoByteBuffer(r, i, ByteOrder.nativeOrder()); 659 } 660 } 661 662 int index = fi.apply(a.limit()); 663 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8); 664 try { 665 fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask); 666 if (shouldFail) { 667 Assert.fail("Failed to throw IndexOutOfBoundsException"); 668 } 669 } catch (IndexOutOfBoundsException e) { 670 if (!shouldFail) { 671 Assert.fail("Unexpected IndexOutOfBoundsException"); 672 } 673 } 674 } 675 676 @Test(dataProvider = "doubleByteMaskProviderForIOOBE") 677 static void storeByteBufferMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 678 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect); 679 ByteBuffer r = ByteBuffer.allocateDirect(a.limit()); 680 boolean[] mask = fm.apply(SPECIES.length()); 681 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 682 683 int l = a.limit(); 684 int s = SPECIES.vectorByteSize(); 685 686 for (int ic = 0; ic < INVOC_COUNT; ic++) { 687 for (int i = 0; i < l; i += s) { 688 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder()); 689 intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask); 690 } 691 } 692 693 int index = fi.apply(a.limit()); 694 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8); 695 try { 696 DoubleVector av = DoubleVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder()); 697 intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask); 698 if (shouldFail) { 699 Assert.fail("Failed to throw IndexOutOfBoundsException"); 700 } 701 } catch (IndexOutOfBoundsException e) { 702 if (!shouldFail) { 703 Assert.fail("Unexpected IndexOutOfBoundsException"); 704 } 705 } 706 } 707 708 709 @Test(dataProvider = "doubleByteBufferProvider") 710 static void loadStoreReadonlyByteBuffer(IntFunction<double[]> fa, 711 IntFunction<ByteBuffer> fb, 712 ByteOrder bo) { 713 ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer(); 714 715 try { 716 SPECIES.zero().intoByteBuffer(a, 0, bo); 717 Assert.fail("ReadOnlyBufferException expected"); 718 } catch (ReadOnlyBufferException e) { 719 } 720 721 try { 722 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true)); 723 Assert.fail("ReadOnlyBufferException expected"); 724 } catch (ReadOnlyBufferException e) { 725 } 726 727 try { 728 SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false)); 729 Assert.fail("ReadOnlyBufferException expected"); 730 } catch (ReadOnlyBufferException e) { 731 } 732 733 try { 734 VectorMask<Double> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1) 735 .laneIsValid(); 736 SPECIES.zero().intoByteBuffer(a, 0, bo, m); 737 Assert.fail("ReadOnlyBufferException expected"); 738 } catch (ReadOnlyBufferException e) { 739 } 740 } 741 742 743 @Test(dataProvider = "doubleByteArrayProvider") 744 static void loadStoreByteArray(IntFunction<double[]> fa, 745 ByteOrder bo) { 746 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo); 747 byte[] r = new byte[a.length]; 748 749 int s = SPECIES.vectorByteSize(); 750 int l = a.length; 751 752 for (int ic = 0; ic < INVOC_COUNT; ic++) { 753 for (int i = 0; i < l; i += s) { 754 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo); 755 av.intoByteArray(r, i, bo); 756 } 757 } 758 Assert.assertEquals(r, a, "Byte arrays not equal"); 759 } 760 761 @Test(dataProvider = "doubleByteProviderForIOOBE") 762 static void loadByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 763 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 764 byte[] r = new byte[a.length]; 765 766 int s = SPECIES.vectorByteSize(); 767 int l = a.length; 768 769 for (int ic = 0; ic < INVOC_COUNT; ic++) { 770 for (int i = 0; i < l; i += s) { 771 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder()); 772 av.intoByteArray(r, i, ByteOrder.nativeOrder()); 773 } 774 } 775 776 int index = fi.apply(a.length); 777 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length); 778 try { 779 fromByteArray(a, index, ByteOrder.nativeOrder()); 780 if (shouldFail) { 781 Assert.fail("Failed to throw IndexOutOfBoundsException"); 782 } 783 } catch (IndexOutOfBoundsException e) { 784 if (!shouldFail) { 785 Assert.fail("Unexpected IndexOutOfBoundsException"); 786 } 787 } 788 } 789 790 @Test(dataProvider = "doubleByteProviderForIOOBE") 791 static void storeByteArrayIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi) { 792 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 793 byte[] r = new byte[a.length]; 794 795 int s = SPECIES.vectorByteSize(); 796 int l = a.length; 797 798 for (int ic = 0; ic < INVOC_COUNT; ic++) { 799 for (int i = 0; i < l; i += s) { 800 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder()); 801 intoByteArray(av, r, i, ByteOrder.nativeOrder()); 802 } 803 } 804 805 int index = fi.apply(a.length); 806 boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length); 807 try { 808 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder()); 809 intoByteArray(av, r, index, ByteOrder.nativeOrder()); 810 if (shouldFail) { 811 Assert.fail("Failed to throw IndexOutOfBoundsException"); 812 } 813 } catch (IndexOutOfBoundsException e) { 814 if (!shouldFail) { 815 Assert.fail("Unexpected IndexOutOfBoundsException"); 816 } 817 } 818 } 819 820 821 @Test(dataProvider = "doubleByteArrayMaskProvider") 822 static void loadStoreByteArrayMask(IntFunction<double[]> fa, 823 IntFunction<boolean[]> fm, 824 ByteOrder bo) { 825 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo); 826 byte[] r = new byte[a.length]; 827 boolean[] mask = fm.apply(SPECIES.length()); 828 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 829 830 int s = SPECIES.vectorByteSize(); 831 int l = a.length; 832 833 for (int ic = 0; ic < INVOC_COUNT; ic++) { 834 for (int i = 0; i < l; i += s) { 835 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo, vmask); 836 av.intoByteArray(r, i, bo); 837 } 838 } 839 assertArraysEquals(r, a, mask); 840 841 842 r = new byte[a.length]; 843 844 for (int ic = 0; ic < INVOC_COUNT; ic++) { 845 for (int i = 0; i < l; i += s) { 846 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, bo); 847 av.intoByteArray(r, i, bo, vmask); 848 } 849 } 850 assertArraysEquals(r, a, mask); 851 } 852 853 @Test(dataProvider = "doubleByteMaskProviderForIOOBE") 854 static void loadByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 855 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 856 byte[] r = new byte[a.length]; 857 boolean[] mask = fm.apply(SPECIES.length()); 858 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 859 860 int s = SPECIES.vectorByteSize(); 861 int l = a.length; 862 863 for (int ic = 0; ic < INVOC_COUNT; ic++) { 864 for (int i = 0; i < l; i += s) { 865 DoubleVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask); 866 av.intoByteArray(r, i, ByteOrder.nativeOrder()); 867 } 868 } 869 870 int index = fi.apply(a.length); 871 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8); 872 try { 873 fromByteArray(a, index, ByteOrder.nativeOrder(), vmask); 874 if (shouldFail) { 875 Assert.fail("Failed to throw IndexOutOfBoundsException"); 876 } 877 } catch (IndexOutOfBoundsException e) { 878 if (!shouldFail) { 879 Assert.fail("Unexpected IndexOutOfBoundsException"); 880 } 881 } 882 } 883 884 @Test(dataProvider = "doubleByteMaskProviderForIOOBE") 885 static void storeByteArrayMaskIOOBE(IntFunction<double[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) { 886 byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder()); 887 byte[] r = new byte[a.length]; 888 boolean[] mask = fm.apply(SPECIES.length()); 889 VectorMask<Double> vmask = VectorMask.fromValues(SPECIES, mask); 890 891 int s = SPECIES.vectorByteSize(); 892 int l = a.length; 893 894 for (int ic = 0; ic < INVOC_COUNT; ic++) { 895 for (int i = 0; i < l; i += s) { 896 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder()); 897 intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask); 898 } 899 } 900 901 int index = fi.apply(a.length); 902 boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8); 903 try { 904 DoubleVector av = DoubleVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder()); 905 intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask); 906 if (shouldFail) { 907 Assert.fail("Failed to throw IndexOutOfBoundsException"); 908 } 909 } catch (IndexOutOfBoundsException e) { 910 if (!shouldFail) { 911 Assert.fail("Unexpected IndexOutOfBoundsException"); 912 } 913 } 914 } 915 916 @Test(dataProvider = "maskProvider") 917 static void loadStoreMask(IntFunction<boolean[]> fm) { 918 boolean[] a = fm.apply(SPECIES.length()); 919 boolean[] r = new boolean[a.length]; 920 921 for (int ic = 0; ic < INVOC_COUNT; ic++) { 922 for (int i = 0; i < a.length; i += SPECIES.length()) { 923 VectorMask<Double> vmask = SPECIES.loadMask(a, i); 924 vmask.intoArray(r, i); 925 } 926 } 927 Assert.assertEquals(r, a); 928 } 929 930 @Test 931 static void loadStoreShuffle() { 932 IntUnaryOperator fn = a -> a + 5; 933 for (int ic = 0; ic < INVOC_COUNT; ic++) { 934 var shuffle = VectorShuffle.fromOp(SPECIES, fn); 935 int [] r = shuffle.toArray(); 936 937 int [] a = expectedShuffle(SPECIES.length(), fn); 938 Assert.assertEquals(r, a); 939 } 940 } 941 942 943 944 945 946 // Gather/Scatter load/store tests 947 948 static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap) { 949 int i = 0; 950 int j = 0; 951 try { 952 for (; i < a.length; i += SPECIES.length()) { 953 j = i; 954 for (; j < i + SPECIES.length(); j++) { 955 Assert.assertEquals(r[j], a[i + indexMap[j]]); 956 } 957 } 958 } catch (AssertionError e) { 959 Assert.assertEquals(r[j], a[i + indexMap[j]], "at index #" + j); 960 } 961 } 962 963 static void assertGatherArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) { 964 int i = 0; 965 int j = 0; 966 try { 967 for (; i < a.length; i += SPECIES.length()) { 968 j = i; 969 for (; j < i + SPECIES.length(); j++) { 970 Assert.assertEquals(r[j], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0); 971 } 972 } 973 } catch (AssertionError e) { 974 Assert.assertEquals(r[i], mask[j % SPECIES.length()] ? a[i + indexMap[j]]: (double) 0, "at index #" + j); 975 } 976 } 977 978 static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap, boolean[] mask) { 979 double[] expected = new double[r.length]; 980 981 // Store before checking, since the same location may be stored to more than once 982 for (int i = 0; i < a.length; i += SPECIES.length()) { 983 for (int j = i; j < i + SPECIES.length(); j++) { 984 if (mask[j % SPECIES.length()]) { 985 expected[i + indexMap[j]] = a[j]; 986 } 987 } 988 } 989 990 Assert.assertEquals(r, expected); 991 } 992 993 static void assertScatterArraysEquals(double[] r, double[] a, int[] indexMap) { 994 double[] expected = new double[r.length]; 995 996 // Store before checking, since the same location may be stored to more than once 997 for (int i = 0; i < a.length; i += SPECIES.length()) { 998 for (int j = i; j < i + SPECIES.length(); j++) { 999 expected[i + indexMap[j]] = a[j]; 1000 } 1001 } 1002 1003 Assert.assertEquals(r, expected); 1004 } 1005 1006 @DataProvider 1007 public Object[][] gatherScatterProvider() { 1008 return INT_INDEX_GENERATORS.stream(). 1009 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> { 1010 return new Object[] {fa, fs}; 1011 })). 1012 toArray(Object[][]::new); 1013 } 1014 1015 @DataProvider 1016 public Object[][] gatherScatterMaskProvider() { 1017 return BOOLEAN_MASK_GENERATORS.stream(). 1018 flatMap(fs -> INT_INDEX_GENERATORS.stream().flatMap(fm -> 1019 DOUBLE_GENERATORS.stream().map(fa -> { 1020 return new Object[] {fa, fm, fs}; 1021 }))). 1022 toArray(Object[][]::new); 1023 } 1024 1025 1026 @Test(dataProvider = "gatherScatterProvider") 1027 static void gather(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1028 double[] a = fa.apply(SPECIES.length()); 1029 int[] b = fs.apply(a.length, SPECIES.length()); 1030 double[] r = new double[a.length]; 1031 1032 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1033 for (int i = 0; i < a.length; i += SPECIES.length()) { 1034 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i); 1035 av.intoArray(r, i); 1036 } 1037 } 1038 1039 assertGatherArraysEquals(r, a, b); 1040 } 1041 1042 @Test(dataProvider = "gatherScatterMaskProvider") 1043 static void gatherMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1044 double[] a = fa.apply(SPECIES.length()); 1045 int[] b = fs.apply(a.length, SPECIES.length()); 1046 double[] r = new double[a.length]; 1047 boolean[] mask = fm.apply(SPECIES.length()); 1048 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1049 1050 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1051 for (int i = 0; i < a.length; i += SPECIES.length()) { 1052 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i, b, i, vmask); 1053 av.intoArray(r, i); 1054 } 1055 } 1056 1057 assertGatherArraysEquals(r, a, b, mask); 1058 } 1059 1060 @Test(dataProvider = "gatherScatterProvider") 1061 static void scatter(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs) { 1062 double[] a = fa.apply(SPECIES.length()); 1063 int[] b = fs.apply(a.length, SPECIES.length()); 1064 double[] r = new double[a.length]; 1065 1066 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1067 for (int i = 0; i < a.length; i += SPECIES.length()) { 1068 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 1069 av.intoArray(r, i, b, i); 1070 } 1071 } 1072 1073 assertScatterArraysEquals(r, a, b); 1074 } 1075 1076 @Test(dataProvider = "gatherScatterMaskProvider") 1077 static void scatterMask(IntFunction<double[]> fa, BiFunction<Integer,Integer,int[]> fs, IntFunction<boolean[]> fm) { 1078 double[] a = fa.apply(SPECIES.length()); 1079 int[] b = fs.apply(a.length, SPECIES.length()); 1080 double[] r = new double[a.length]; 1081 boolean[] mask = fm.apply(SPECIES.length()); 1082 VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0); 1083 1084 for (int ic = 0; ic < INVOC_COUNT; ic++) { 1085 for (int i = 0; i < a.length; i += SPECIES.length()) { 1086 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i); 1087 av.intoArray(r, i, b, i, vmask); 1088 } 1089 } 1090 1091 assertScatterArraysEquals(r, a, b, mask); 1092 } 1093 1094 1095 1096 } 1097