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