1 /*
  2  * Copyright (c) 2018, 2024, 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 #warn This file is preprocessed before being compiled
 27 
 28 import java.util.concurrent.TimeUnit;
 29 import java.util.function.IntFunction;
 30 import jdk.incubator.vector.VectorMath;
 31 
 32 import org.openjdk.jmh.annotations.*;
 33 import org.openjdk.jmh.infra.Blackhole;
 34 
 35 @BenchmarkMode(Mode.Throughput)
 36 @OutputTimeUnit(TimeUnit.MILLISECONDS)
 37 @State(Scope.Benchmark)
 38 @Warmup(iterations = 3, time = 1)
 39 @Measurement(iterations = 5, time = 1)
 40 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
 41 public class $Type$Scalar extends AbstractVectorBenchmark {
 42     static final int INVOC_COUNT = 1; // To align with vector benchmarks.
 43 
 44 #if[BITWISE]
 45     private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2;
 46 #end[BITWISE]
 47 
 48     @Param("1024")
 49     int size;
 50 
 51     $type$[] fill(IntFunction<$Wideboxtype$> f) {
 52         $type$[] array = new $type$[size];
 53         for (int i = 0; i < array.length; i++) {
 54             array[i] = f.apply(i);
 55         }
 56         return array;
 57     }
 58 
 59     static $bitstype$ bits($type$ e) {
 60         return {#if[FP]?$Type$.$type$To$Bitstype$Bits(e):e};
 61     }
 62 
 63     $type$[] as, bs, cs, rs;
 64     boolean[] ms, mt, rms;
 65     int[] ss;
 66 
 67     @Setup
 68     public void init() {
 69         as = fill(i -> ($type$)(2*i));
 70         bs = fill(i -> ($type$)(i+1));
 71         cs = fill(i -> ($type$)(i+5));
 72         rs = fill(i -> ($type$)0);
 73         ms = fillMask(size, i -> (i % 2) == 0);
 74         mt = fillMask(size, i -> true);
 75         rms = fillMask(size, i -> false);
 76 
 77         ss = fillInt(size, i -> RAND.nextInt(Math.max(i,1)));
 78     }
 79 
 80     final IntFunction<$type$[]> fa = vl -> as;
 81     final IntFunction<$type$[]> fb = vl -> bs;
 82     final IntFunction<$type$[]> fc = vl -> cs;
 83     final IntFunction<$type$[]> fr = vl -> rs;
 84     final IntFunction<boolean[]> fm = vl -> ms;
 85     final IntFunction<boolean[]> fmt = vl -> mt;
 86     final IntFunction<boolean[]> fmr = vl -> rms;
 87     final IntFunction<int[]> fs = vl -> ss;
 88 
 89     static boolean eq($type$ a, $type$ b) {
 90         return a == b;
 91     }
 92 
 93     static boolean neq($type$ a, $type$ b) {
 94         return a != b;
 95     }
 96 
 97     static boolean lt($type$ a, $type$ b) {
 98         return a < b;
 99     }
100 
101     static boolean le($type$ a, $type$ b) {
102         return a <= b;
103     }
104 
105     static boolean gt($type$ a, $type$ b) {
106         return a > b;
107     }
108 
109     static boolean ge($type$ a, $type$ b) {
110         return a >= b;
111     }
112 
113 #if[!FP]
114     static boolean ult($type$ a, $type$ b) {
115         return $Boxtype$.compareUnsigned(a, b) < 0;
116     }
117 
118     static boolean ule($type$ a, $type$ b) {
119         return $Boxtype$.compareUnsigned(a, b) <= 0;
120     }
121 
122     static boolean ugt($type$ a, $type$ b) {
123         return $Boxtype$.compareUnsigned(a, b) > 0;
124     }
125 
126     static boolean uge($type$ a, $type$ b) {
127         return $Boxtype$.compareUnsigned(a, b) >= 0;
128     }
129 #end[!FP]
130 
131 #if[BITWISE]
132     static $type$ ROL_scalar($type$ a, $type$ b) {
133 #if[intOrLong]
134         return $Wideboxtype$.rotateLeft(a, ((int)b));
135 #else[intOrLong]
136 #if[short]
137         return (short)(((((short)a) & 0xFFFF) << (b & 15)) | ((((short)a) & 0xFFFF) >>> (16 - (b & 15))));
138 #else[short]
139         return (byte)(((((byte)a) & 0xFF) << (b & 7)) | ((((byte)a) & 0xFF) >>> (8 - (b & 7))));
140 #end[short]
141 #end[intOrLong]
142     }
143 
144     static $type$ ROR_scalar($type$ a, $type$ b) {
145 #if[intOrLong]
146         return $Wideboxtype$.rotateRight(a, ((int)b));
147 #else[intOrLong]
148 #if[short]
149         return (short)(((((short)a) & 0xFFFF) >>> (b & 15)) | ((((short)a) & 0xFFFF) << (16 - (b & 15))));
150 #else[short]
151         return (byte)(((((byte)a) & 0xFF) >>> (b & 7)) | ((((byte)a) & 0xFF) << (8 - (b & 7))));
152 #end[short]
153 #end[intOrLong]
154     }
155 
156     static $type$ TRAILING_ZEROS_COUNT_scalar($type$ a) {
157 #if[intOrLong]
158         return $Wideboxtype$.numberOfTrailingZeros(a);
159 #else[intOrLong]
160 #if[short]
161         return (short) (a != 0 ? Integer.numberOfTrailingZeros(a) : 16);
162 #else[short]
163         return (byte) (a != 0 ? Integer.numberOfTrailingZeros(a) : 8);
164 #end[short]
165 #end[intOrLong]
166     }
167 
168     static $type$ LEADING_ZEROS_COUNT_scalar($type$ a) {
169 #if[intOrLong]
170         return $Wideboxtype$.numberOfLeadingZeros(a);
171 #else[intOrLong]
172 #if[short]
173         return (short) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 16 : 0);
174 #else[short]
175         return (byte) (a >= 0 ? Integer.numberOfLeadingZeros(a) - 24 : 0);
176 #end[short]
177 #end[intOrLong]
178     }
179 
180     static $type$ REVERSE_scalar($type$ a) {
181 #if[intOrLong]
182         return $Wideboxtype$.reverse(a);
183 #else[intOrLong]
184 #if[short]
185         $type$ b = ROL_scalar(a, ($type$) 8);
186         b = (short)(((b & 0x5555) << 1) | ((b & 0xAAAA) >>> 1));
187         b = (short)(((b & 0x3333) << 2) | ((b & 0xCCCC) >>> 2));
188         b = (short)(((b & 0x0F0F) << 4) | ((b & 0xF0F0) >>> 4));
189         return b;
190 #else[short]
191         $type$ b = ROL_scalar(a, ($type$) 4);
192         b = (byte)(((b & 0x55) << 1) | ((b & 0xAA) >>> 1));
193         b = (byte)(((b & 0x33) << 2) | ((b & 0xCC) >>> 2));
194         return b;
195 #end[short]
196 #end[intOrLong]
197     }
198 #end[BITWISE]