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