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 }