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