1 /*
   2  * Copyright (c) 2018, 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
  21  * questions.
  22  */
  23 
  24 package benchmark.jdk.incubator.vector;
  25 
  26 import jdk.incubator.vector.ByteVector;
  27 import jdk.incubator.vector.IntVector;
  28 import jdk.incubator.vector.ShortVector;
  29 import jdk.incubator.vector.LongVector;
  30 import jdk.incubator.vector.Vector;
  31 import jdk.incubator.vector.Vector.Shape;
  32 import jdk.incubator.vector.Vector.Species;
  33 
  34 import java.util.Random;
  35 import java.util.function.IntFunction;
  36 
  37 public class AbstractVectorBenchmark {
  38     static final Random RANDOM = new Random(Integer.getInteger("jdk.incubator.vector.random-seed", 1337));
  39 
  40     static final Species<Byte> B64  = ByteVector.SPECIES_64;
  41     static final Species<Byte> B128 = ByteVector.SPECIES_128;
  42     static final Species<Byte> B256 = ByteVector.SPECIES_256;
  43     static final Species<Byte> B512 = ByteVector.SPECIES_512;
  44 
  45     static final Species<Short> S64  = ShortVector.SPECIES_64;
  46     static final Species<Short> S128 = ShortVector.SPECIES_128;
  47     static final Species<Short> S256 = ShortVector.SPECIES_256;
  48     static final Species<Short> S512 = ShortVector.SPECIES_512;
  49 
  50     static final Species<Integer> I64  = IntVector.SPECIES_64;
  51     static final Species<Integer> I128 = IntVector.SPECIES_128;
  52     static final Species<Integer> I256 = IntVector.SPECIES_256;
  53     static final Species<Integer> I512 = IntVector.SPECIES_512;
  54 
  55     static final Species<Long> L64  = LongVector.SPECIES_64;
  56     static final Species<Long> L128 = LongVector.SPECIES_128;
  57     static final Species<Long> L256 = LongVector.SPECIES_256;
  58     static final Species<Long> L512 = LongVector.SPECIES_512;
  59 
  60     static Shape widen(Shape s) {
  61         switch (s) {
  62             case S_64_BIT:  return Shape.S_128_BIT;
  63             case S_128_BIT: return Shape.S_256_BIT;
  64             case S_256_BIT: return Shape.S_512_BIT;
  65             default: throw new IllegalArgumentException("" + s);
  66         }
  67     }
  68 
  69     static Shape narrow(Shape s) {
  70         switch (s) {
  71             case S_512_BIT: return Shape.S_256_BIT;
  72             case S_256_BIT: return Shape.S_128_BIT;
  73             case S_128_BIT: return Shape.S_64_BIT;
  74             default: throw new IllegalArgumentException("" + s);
  75         }
  76     }
  77 
  78     static <E> Species<E> widen(Species<E> s) {
  79         return Vector.Species.of(s.elementType(), widen(s.shape()));
  80     }
  81 
  82     static <E> Species<E> narrow(Species<E> s) {
  83         return Vector.Species.of(s.elementType(), narrow(s.shape()));
  84     }
  85 
  86     static IntVector join(Species<Integer> from, Species<Integer> to, IntVector lo, IntVector hi) {
  87         assert 2 * from.length() == to.length();
  88 
  89         int vlen = from.length();
  90         var lo_mask = mask(from, to, 0);
  91 
  92         var v1 = lo.reshape(to);
  93         var v2 = hi.reshape(to).shiftER(vlen);
  94         var r = v2.blend(v1, lo_mask);
  95         return r;
  96     }
  97 
  98     static Vector.Mask<Integer> mask(Species<Integer> from, Species<Integer> to, int i) {
  99         int vlen = from.length();
 100         var v1 = IntVector.broadcast(from, 1);    //                         [1 1 ... 1]
 101         var v2 = v1.reshape(to);                  // [0 0 ... 0 |   ...     | 1 1 ... 1]
 102         var v3 = v2.shiftER(i * vlen);            // [0 0 ... 0 | 1 1 ... 1 | 0 0 ... 0]
 103         return v3.notEqual(0);                    // [F F ... F | T T ... T | F F ... F]
 104     }
 105 
 106     static <E> IntVector sum(ByteVector va) {
 107         Species<Integer> species = Species.of(Integer.class, va.shape());
 108         var acc = IntVector.zero(species);
 109         int limit = va.length() / species.length();
 110         for (int k = 0; k < limit; k++) {
 111             var vb = ((IntVector)(va.shiftEL(k * B64.length()).reshape(B64).cast(species))).and(0xFF);
 112             acc = acc.add(vb);
 113         }
 114         return acc;
 115     }
 116 
 117     /* ============================================================================================================== */
 118 
 119     boolean[] fillMask(int size, IntFunction<Boolean> f) {
 120         boolean[] array = new boolean[size];
 121         for (int i = 0; i < array.length; i++) {
 122             array[i] = f.apply(i);
 123         }
 124         return array;
 125     }
 126 
 127     byte[] fillByte(int size, IntFunction<Byte> f) {
 128         byte[] array = new byte[size];
 129         for (int i = 0; i < size; i++) {
 130             array[i] = f.apply(i);
 131         }
 132         return array;
 133     }
 134 
 135     int[] fillInt(int size, IntFunction<Integer> f) {
 136         int[] array = new int[size];
 137         for (int i = 0; i < array.length; i++) {
 138             array[i] = f.apply(i);
 139         }
 140         return array;
 141     }
 142 
 143     long[] fillLong(int size, IntFunction<Long> f) {
 144         long[] array = new long[size];
 145         for (int i = 0; i < array.length; i++) {
 146             array[i] = f.apply(i);
 147         }
 148         return array;
 149     }
 150 }