1 /* 2 * Copyright (c) 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import jdk.internal.vm.annotation.ForceInline; 28 29 import java.nio.ByteBuffer; 30 import java.nio.ByteOrder; 31 import java.nio.IntBuffer; 32 import java.util.concurrent.ThreadLocalRandom; 33 34 @SuppressWarnings("cast") 35 public abstract class IntVector<S extends Vector.Shape> extends Vector<Integer,S> { 36 37 IntVector() {} 38 39 // Unary operator 40 41 interface FUnOp { 42 int apply(int i, int a); 43 } 44 45 abstract IntVector<S> uOp(FUnOp f); 46 47 abstract IntVector<S> uOp(Mask<Integer, S> m, FUnOp f); 48 49 // Binary operator 50 51 interface FBinOp { 52 int apply(int i, int a, int b); 53 } 54 55 abstract IntVector<S> bOp(Vector<Integer,S> o, FBinOp f); 56 57 abstract IntVector<S> bOp(Vector<Integer,S> o, Mask<Integer, S> m, FBinOp f); 58 59 // Trinary operator 60 61 interface FTriOp { 62 int apply(int i, int a, int b, int c); 63 } 64 65 abstract IntVector<S> tOp(Vector<Integer,S> o1, Vector<Integer,S> o2, FTriOp f); 66 67 abstract IntVector<S> tOp(Vector<Integer,S> o1, Vector<Integer,S> o2, Mask<Integer, S> m, FTriOp f); 68 69 // Reduction operator 70 71 abstract int rOp(int v, FBinOp f); 72 73 // Binary test 74 75 interface FBinTest { 76 boolean apply(int i, int a, int b); 77 } 78 79 abstract Mask<Integer, S> bTest(Vector<Integer,S> o, FBinTest f); 80 81 // Foreach 82 83 interface FUnCon { 84 void apply(int i, int a); 85 } 86 87 abstract void forEach(FUnCon f); 88 89 abstract void forEach(Mask<Integer, S> m, FUnCon f); 90 91 // 92 93 @Override 94 public IntVector<S> add(Vector<Integer,S> o) { 95 return bOp(o, (i, a, b) -> (int) (a + b)); 96 } 97 98 public abstract IntVector<S> add(int o); 99 100 @Override 101 public IntVector<S> add(Vector<Integer,S> o, Mask<Integer, S> m) { 102 return bOp(o, m, (i, a, b) -> (int) (a + b)); 103 } 104 105 public abstract IntVector<S> add(int o, Mask<Integer, S> m); 106 107 @Override 108 public IntVector<S> addSaturate(Vector<Integer,S> o) { 109 return bOp(o, (i, a, b) -> (int) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 110 } 111 112 public abstract IntVector<S> addSaturate(int o); 113 114 @Override 115 public IntVector<S> addSaturate(Vector<Integer,S> o, Mask<Integer, S> m) { 116 return bOp(o, m, (i, a, b) -> (int) ((a >= Integer.MAX_VALUE || Integer.MAX_VALUE - b > a) ? Integer.MAX_VALUE : a + b)); 117 } 118 119 public abstract IntVector<S> addSaturate(int o, Mask<Integer, S> m); 120 121 @Override 122 public IntVector<S> sub(Vector<Integer,S> o) { 123 return bOp(o, (i, a, b) -> (int) (a - b)); 124 } 125 126 public abstract IntVector<S> sub(int o); 127 128 @Override 129 public IntVector<S> sub(Vector<Integer,S> o, Mask<Integer, S> m) { 130 return bOp(o, m, (i, a, b) -> (int) (a - b)); 131 } 132 133 public abstract IntVector<S> sub(int o, Mask<Integer, S> m); 134 135 @Override 136 public IntVector<S> subSaturate(Vector<Integer,S> o) { 137 return bOp(o, (i, a, b) -> (int) ((a >= Integer.MIN_VALUE || Integer.MIN_VALUE + b > a) ? Integer.MAX_VALUE : a - b)); 138 } 139 140 public abstract IntVector<S> subSaturate(int o); 141 142 @Override 143 public IntVector<S> subSaturate(Vector<Integer,S> o, Mask<Integer, S> m) { 144 return bOp(o, m, (i, a, b) -> (int) ((a >= Integer.MIN_VALUE || Integer.MIN_VALUE + b > a) ? Integer.MAX_VALUE : a - b)); 145 } 146 147 public abstract IntVector<S> subSaturate(int o, Mask<Integer, S> m); 148 149 @Override 150 public IntVector<S> mul(Vector<Integer,S> o) { 151 return bOp(o, (i, a, b) -> (int) (a * b)); 152 } 153 154 public abstract IntVector<S> mul(int o); 155 156 @Override 157 public IntVector<S> mul(Vector<Integer,S> o, Mask<Integer, S> m) { 158 return bOp(o, m, (i, a, b) -> (int) (a * b)); 159 } 160 161 public abstract IntVector<S> mul(int o, Mask<Integer, S> m); 162 163 @Override 164 public IntVector<S> neg() { 165 return uOp((i, a) -> (int) (-a)); 166 } 167 168 @Override 169 public IntVector<S> neg(Mask<Integer, S> m) { 170 return uOp(m, (i, a) -> (int) (-a)); 171 } 172 173 @Override 174 public IntVector<S> abs() { 175 return uOp((i, a) -> (int) Math.abs(a)); 176 } 177 178 @Override 179 public IntVector<S> abs(Mask<Integer, S> m) { 180 return uOp(m, (i, a) -> (int) Math.abs(a)); 181 } 182 183 @Override 184 public IntVector<S> min(Vector<Integer,S> o) { 185 return bOp(o, (i, a, b) -> (a <= b) ? a : b); 186 } 187 188 public abstract IntVector<S> min(int o); 189 190 @Override 191 public IntVector<S> max(Vector<Integer,S> o) { 192 return bOp(o, (i, a, b) -> (a >= b) ? a : b); 193 } 194 195 public abstract IntVector<S> max(int o); 196 197 @Override 198 public Mask<Integer, S> equal(Vector<Integer,S> o) { 199 return bTest(o, (i, a, b) -> a == b); 200 } 201 202 public abstract Mask<Integer, S> equal(int o); 203 204 @Override 205 public Mask<Integer, S> notEqual(Vector<Integer,S> o) { 206 return bTest(o, (i, a, b) -> a != b); 207 } 208 209 public abstract Mask<Integer, S> notEqual(int o); 210 211 @Override 212 public Mask<Integer, S> lessThan(Vector<Integer,S> o) { 213 return bTest(o, (i, a, b) -> a < b); 214 } 215 216 public abstract Mask<Integer, S> lessThan(int o); 217 218 @Override 219 public Mask<Integer, S> lessThanEq(Vector<Integer,S> o) { 220 return bTest(o, (i, a, b) -> a <= b); 221 } 222 223 public abstract Mask<Integer, S> lessThanEq(int o); 224 225 @Override 226 public Mask<Integer, S> greaterThan(Vector<Integer,S> o) { 227 return bTest(o, (i, a, b) -> a > b); 228 } 229 230 public abstract Mask<Integer, S> greaterThan(int o); 231 232 @Override 233 public Mask<Integer, S> greaterThanEq(Vector<Integer,S> o) { 234 return bTest(o, (i, a, b) -> a >= b); 235 } 236 237 public abstract Mask<Integer, S> greaterThanEq(int o); 238 239 @Override 240 public IntVector<S> blend(Vector<Integer,S> o, Mask<Integer, S> m) { 241 return bOp(o, (i, a, b) -> m.getElement(i) ? b : a); 242 } 243 244 public abstract IntVector<S> blend(int o, Mask<Integer, S> m); 245 246 @Override 247 public abstract IntVector<S> shuffle(Vector<Integer,S> o, Shuffle<Integer, S> m); 248 249 @Override 250 public abstract IntVector<S> swizzle(Shuffle<Integer, S> m); 251 252 @Override 253 @ForceInline 254 public <T extends Shape> IntVector<T> resize(Species<Integer, T> species) { 255 return (IntVector<T>) species.reshape(this); 256 } 257 258 @Override 259 public abstract IntVector<S> rotateEL(int i); 260 261 @Override 262 public abstract IntVector<S> rotateER(int i); 263 264 @Override 265 public abstract IntVector<S> shiftEL(int i); 266 267 @Override 268 public abstract IntVector<S> shiftER(int i); 269 270 271 public IntVector<S> and(Vector<Integer,S> o) { 272 return bOp(o, (i, a, b) -> (int) (a & b)); 273 } 274 275 public abstract IntVector<S> and(int o); 276 277 public IntVector<S> and(Vector<Integer,S> o, Mask<Integer, S> m) { 278 return bOp(o, m, (i, a, b) -> (int) (a & b)); 279 } 280 281 public abstract IntVector<S> and(int o, Mask<Integer, S> m); 282 283 public IntVector<S> or(Vector<Integer,S> o) { 284 return bOp(o, (i, a, b) -> (int) (a | b)); 285 } 286 287 public abstract IntVector<S> or(int o); 288 289 public IntVector<S> or(Vector<Integer,S> o, Mask<Integer, S> m) { 290 return bOp(o, m, (i, a, b) -> (int) (a | b)); 291 } 292 293 public abstract IntVector<S> or(int o, Mask<Integer, S> m); 294 295 public IntVector<S> xor(Vector<Integer,S> o) { 296 return bOp(o, (i, a, b) -> (int) (a ^ b)); 297 } 298 299 public abstract IntVector<S> xor(int o); 300 301 public IntVector<S> xor(Vector<Integer,S> o, Mask<Integer, S> m) { 302 return bOp(o, m, (i, a, b) -> (int) (a ^ b)); 303 } 304 305 public abstract IntVector<S> xor(int o, Mask<Integer, S> m); 306 307 public IntVector<S> not() { 308 return uOp((i, a) -> (int) (~a)); 309 } 310 311 public IntVector<S> not(Mask<Integer, S> m) { 312 return uOp(m, (i, a) -> (int) (~a)); 313 } 314 315 // logical shift left 316 public IntVector<S> shiftL(Vector<Integer,S> o) { 317 return bOp(o, (i, a, b) -> (int) (a << b)); 318 } 319 320 public IntVector<S> shiftL(int s) { 321 return uOp((i, a) -> (int) (a << s)); 322 } 323 324 public IntVector<S> shiftL(Vector<Integer,S> o, Mask<Integer, S> m) { 325 return bOp(o, m, (i, a, b) -> (int) (a << b)); 326 } 327 328 public IntVector<S> shiftL(int s, Mask<Integer, S> m) { 329 return uOp(m, (i, a) -> (int) (a << s)); 330 } 331 332 // logical, or unsigned, shift right 333 public IntVector<S> shiftR(Vector<Integer,S> o) { 334 return bOp(o, (i, a, b) -> (int) (a >>> b)); 335 } 336 337 public IntVector<S> shiftR(int s) { 338 return uOp((i, a) -> (int) (a >>> s)); 339 } 340 341 public IntVector<S> shiftR(Vector<Integer,S> o, Mask<Integer, S> m) { 342 return bOp(o, m, (i, a, b) -> (int) (a >>> b)); 343 } 344 345 public IntVector<S> shiftR(int s, Mask<Integer, S> m) { 346 return uOp(m, (i, a) -> (int) (a >>> s)); 347 } 348 349 // arithmetic, or signed, shift right 350 public IntVector<S> ashiftR(Vector<Integer,S> o) { 351 return bOp(o, (i, a, b) -> (int) (a >> b)); 352 } 353 354 public IntVector<S> aShiftR(int s) { 355 return uOp((i, a) -> (int) (a >> s)); 356 } 357 358 public IntVector<S> ashiftR(Vector<Integer,S> o, Mask<Integer, S> m) { 359 return bOp(o, m, (i, a, b) -> (int) (a >> b)); 360 } 361 362 public IntVector<S> aShiftR(int s, Mask<Integer, S> m) { 363 return uOp(m, (i, a) -> (int) (a >> s)); 364 } 365 366 public IntVector<S> rotateL(int j) { 367 return uOp((i, a) -> (int) Integer.rotateLeft(a, j)); 368 } 369 370 public IntVector<S> rotateR(int j) { 371 return uOp((i, a) -> (int) Integer.rotateRight(a, j)); 372 } 373 374 @Override 375 public void intoByteArray(byte[] a, int ix) { 376 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix); 377 intoByteBuffer(bb); 378 } 379 380 @Override 381 public void intoByteArray(byte[] a, int ix, Mask<Integer, S> m) { 382 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix); 383 intoByteBuffer(bb, m); 384 } 385 386 @Override 387 public void intoByteBuffer(ByteBuffer bb) { 388 IntBuffer fb = bb.asIntBuffer(); 389 forEach((i, a) -> fb.put(a)); 390 } 391 392 @Override 393 public void intoByteBuffer(ByteBuffer bb, Mask<Integer, S> m) { 394 IntBuffer fb = bb.asIntBuffer(); 395 forEach((i, a) -> { 396 if (m.getElement(i)) 397 fb.put(a); 398 else 399 fb.position(fb.position() + 1); 400 }); 401 } 402 403 @Override 404 public void intoByteBuffer(ByteBuffer bb, int ix) { 405 bb = bb.duplicate().position(ix); 406 IntBuffer fb = bb.asIntBuffer(); 407 forEach((i, a) -> fb.put(i, a)); 408 } 409 410 @Override 411 public void intoByteBuffer(ByteBuffer bb, int ix, Mask<Integer, S> m) { 412 bb = bb.duplicate().position(ix); 413 IntBuffer fb = bb.asIntBuffer(); 414 forEach(m, (i, a) -> fb.put(i, a)); 415 } 416 417 418 // Type specific horizontal reductions 419 420 public int addAll() { 421 return rOp((int) 0, (i, a, b) -> (int) (a + b)); 422 } 423 424 public int subAll() { 425 return rOp((int) 0, (i, a, b) -> (int) (a - b)); 426 } 427 428 public int mulAll() { 429 return rOp((int) 1, (i, a, b) -> (int) (a * b)); 430 } 431 432 public int minAll() { 433 return rOp(Integer.MAX_VALUE, (i, a, b) -> a > b ? b : a); 434 } 435 436 public int maxAll() { 437 return rOp(Integer.MIN_VALUE, (i, a, b) -> a < b ? b : a); 438 } 439 440 public int orAll() { 441 return rOp((int) 0, (i, a, b) -> (int) (a | b)); 442 } 443 444 public int andAll() { 445 return rOp((int) -1, (i, a, b) -> (int) (a & b)); 446 } 447 448 public int xorAll() { 449 return rOp((int) 0, (i, a, b) -> (int) (a ^ b)); 450 } 451 452 // Type specific accessors 453 454 public abstract int get(int i); 455 456 public abstract IntVector<S> with(int i, int e); 457 458 // Type specific extractors 459 460 @ForceInline 461 public int[] toArray() { 462 int[] a = new int[species().length()]; 463 intoArray(a, 0); 464 return a; 465 } 466 467 public void intoArray(int[] a, int ax) { 468 forEach((i, a_) -> a[ax + i] = a_); 469 } 470 471 public void intoArray(int[] a, int ax, Mask<Integer, S> m) { 472 forEach(m, (i, a_) -> a[ax + i] = a_); 473 } 474 475 public void intoArray(int[] a, int ax, int[] indexMap, int mx) { 476 forEach((i, a_) -> a[ax + indexMap[mx + i]] = a_); 477 } 478 479 public void intoArray(int[] a, int ax, Mask<Integer, S> m, int[] indexMap, int mx) { 480 forEach(m, (i, a_) -> a[ax + indexMap[mx + i]] = a_); 481 } 482 483 // Species 484 485 @Override 486 public abstract IntSpecies<S> species(); 487 488 public static abstract class IntSpecies<S extends Vector.Shape> extends Vector.Species<Integer, S> { 489 interface FOp { 490 int apply(int i); 491 } 492 493 abstract IntVector<S> op(FOp f); 494 495 abstract IntVector<S> op(Mask<Integer, S> m, FOp f); 496 497 // Factories 498 499 @Override 500 public IntVector<S> zero() { 501 return op(i -> 0); 502 } 503 504 public IntVector<S> broadcast(int e) { 505 return op(i -> e); 506 } 507 508 public IntVector<S> single(int e) { 509 return op(i -> i == 0 ? e : (int) 0); 510 } 511 512 public IntVector<S> random() { 513 ThreadLocalRandom r = ThreadLocalRandom.current(); 514 return op(i -> (int) r.nextInt()); 515 } 516 517 public IntVector<S> scalars(int... es) { 518 return op(i -> es[i]); 519 } 520 521 public IntVector<S> fromArray(int[] a, int ax) { 522 return op(i -> a[ax + i]); 523 } 524 525 public IntVector<S> fromArray(int[] a, int ax, Mask<Integer, S> m) { 526 return op(m, i -> a[ax + i]); 527 } 528 529 public IntVector<S> fromArray(int[] a, int ax, int[] indexMap, int mx) { 530 return op(i -> a[ax + indexMap[mx + i]]); 531 } 532 533 public IntVector<S> fromArray(int[] a, int ax, Mask<Integer, S> m, int[] indexMap, int mx) { 534 return op(m, i -> a[ax + indexMap[mx + i]]); 535 } 536 537 @Override 538 public IntVector<S> fromByteArray(byte[] a, int ix) { 539 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix); 540 return fromByteBuffer(bb); 541 } 542 543 @Override 544 public IntVector<S> fromByteArray(byte[] a, int ix, Mask<Integer, S> m) { 545 ByteBuffer bb = ByteBuffer.wrap(a, ix, a.length - ix); 546 return fromByteBuffer(bb, m); 547 } 548 549 @Override 550 public IntVector<S> fromByteBuffer(ByteBuffer bb) { 551 IntBuffer fb = bb.asIntBuffer(); 552 return op(i -> fb.get()); 553 } 554 555 @Override 556 public IntVector<S> fromByteBuffer(ByteBuffer bb, Mask<Integer, S> m) { 557 IntBuffer fb = bb.asIntBuffer(); 558 return op(i -> { 559 if(m.getElement(i)) 560 return fb.get(); 561 else { 562 fb.position(fb.position() + 1); 563 return (int) 0; 564 } 565 }); 566 } 567 568 @Override 569 public IntVector<S> fromByteBuffer(ByteBuffer bb, int ix) { 570 bb = bb.duplicate().position(ix); 571 IntBuffer fb = bb.asIntBuffer(); 572 return op(i -> fb.get(i)); 573 } 574 575 @Override 576 public IntVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Integer, S> m) { 577 bb = bb.duplicate().position(ix); 578 IntBuffer fb = bb.asIntBuffer(); 579 return op(m, i -> fb.get(i)); 580 } 581 582 @Override 583 @ForceInline 584 public <F, T extends Shape> IntVector<S> reshape(Vector<F, T> o) { 585 int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE; 586 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder()); 587 o.intoByteBuffer(bb, 0); 588 return fromByteBuffer(bb, 0); 589 } 590 591 @Override 592 @ForceInline 593 public <F> IntVector<S> rebracket(Vector<F, S> o) { 594 return reshape(o); 595 } 596 597 @Override 598 @ForceInline 599 public <T extends Shape> IntVector<S> resize(Vector<Integer, T> o) { 600 return reshape(o); 601 } 602 603 @Override 604 @SuppressWarnings("unchecked") 605 public <F, T extends Shape> IntVector<S> cast(Vector<F, T> v) { 606 // Allocate array of required size 607 int[] a = new int[length()]; 608 609 Class<?> vtype = v.species().elementType(); 610 int limit = Math.min(v.species().length(), length()); 611 if (vtype == Byte.class) { 612 ByteVector<T> tv = (ByteVector<T>)v; 613 for (int i = 0; i < limit; i++) { 614 a[i] = (int) tv.get(i); 615 } 616 } else if (vtype == Short.class) { 617 ShortVector<T> tv = (ShortVector<T>)v; 618 for (int i = 0; i < limit; i++) { 619 a[i] = (int) tv.get(i); 620 } 621 } else if (vtype == Integer.class) { 622 IntVector<T> tv = (IntVector<T>)v; 623 for (int i = 0; i < limit; i++) { 624 a[i] = (int) tv.get(i); 625 } 626 } else if (vtype == Long.class){ 627 LongVector<T> tv = (LongVector<T>)v; 628 for (int i = 0; i < limit; i++) { 629 a[i] = (int) tv.get(i); 630 } 631 } else if (vtype == Float.class){ 632 FloatVector<T> tv = (FloatVector<T>)v; 633 for (int i = 0; i < limit; i++) { 634 a[i] = (int) tv.get(i); 635 } 636 } else if (vtype == Double.class){ 637 DoubleVector<T> tv = (DoubleVector<T>)v; 638 for (int i = 0; i < limit; i++) { 639 a[i] = (int) tv.get(i); 640 } 641 } else { 642 throw new UnsupportedOperationException("Bad lane type for casting."); 643 } 644 645 return scalars(a); 646 } 647 648 } 649 }