1 /* 2 * Copyright (c) 2017, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import jdk.internal.misc.Unsafe; 28 import jdk.internal.vm.annotation.ForceInline; 29 import java.util.function.Function; 30 import java.util.function.IntUnaryOperator; 31 32 /** 33 * Class representing vectors of same element type, {@code E} and {@link VectorShape shape}. 34 * 35 * @param <E> the boxed element type of this species 36 */ 37 public abstract class VectorSpecies<E> { 38 39 @FunctionalInterface 40 interface fShuffleFromArray<E> { 41 VectorShuffle<E> apply(int[] reorder, int idx); 42 } 43 44 final Function<boolean[], VectorMask<E>> maskFactory; 45 final Function<IntUnaryOperator, VectorShuffle<E>> shuffleFromOpFactory; 46 final fShuffleFromArray<E> shuffleFromArrayFactory; 47 48 VectorSpecies(Function<boolean[], VectorMask<E>> maskFactory, 49 Function<IntUnaryOperator, VectorShuffle<E>> shuffleFromOpFactory, 50 fShuffleFromArray<E> shuffleFromArrayFactory) { 51 this.maskFactory = maskFactory; 52 this.shuffleFromOpFactory = shuffleFromOpFactory; 53 this.shuffleFromArrayFactory = shuffleFromArrayFactory; 54 } 55 56 /** 57 * Returns the primitive element type of vectors produced by this 58 * species. 59 * 60 * @return the primitive element type 61 */ 62 public abstract Class<E> elementType(); 63 64 /** 65 * Returns the vector box type for this species 66 * 67 * @return the box type 68 */ 69 abstract Class<?> boxType(); 70 71 /** 72 * Returns the vector mask type for this species 73 * 74 * @return the box type 75 */ 76 abstract Class<?> maskType(); 77 78 /** 79 * Returns the element size, in bits, of vectors produced by this 80 * species. 81 * 82 * @return the element size, in bits 83 */ 84 public abstract int elementSize(); 85 86 /** 87 * Returns the shape of masks, shuffles, and vectors produced by this 88 * species. 89 * 90 * @return the primitive element type 91 */ 92 public abstract VectorShape shape(); 93 94 /** 95 * Returns the shape of the corresponding index species 96 * @return the shape 97 */ 98 @ForceInline 99 public abstract VectorShape indexShape(); 100 101 /** 102 * Returns the mask, shuffe, or vector lanes produced by this species. 103 * 104 * @return the the number of lanes 105 */ 106 public int length() { return shape().length(this); } 107 108 /** 109 * Returns the total vector size, in bits, of vectors produced by this 110 * species. 111 * 112 * @return the total vector size, in bits 113 */ 114 public int bitSize() { return shape().bitSize(); } 115 116 // Factory 117 118 /** 119 * Finds a species for an element type and shape. 120 * 121 * @param c the element type 122 * @param s the shape 123 * @param <E> the boxed element type 124 * @return a species for an element type and shape 125 * @throws IllegalArgumentException if no such species exists for the 126 * element type and/or shape 127 */ 128 @SuppressWarnings("unchecked") 129 public static <E> VectorSpecies<E> of(Class<E> c, VectorShape s) { 130 if (c == float.class) { 131 return (VectorSpecies<E>) FloatVector.species(s); 132 } 133 else if (c == double.class) { 134 return (VectorSpecies<E>) DoubleVector.species(s); 135 } 136 else if (c == byte.class) { 137 return (VectorSpecies<E>) ByteVector.species(s); 138 } 139 else if (c == short.class) { 140 return (VectorSpecies<E>) ShortVector.species(s); 141 } 142 else if (c == int.class) { 143 return (VectorSpecies<E>) IntVector.species(s); 144 } 145 else if (c == long.class) { 146 return (VectorSpecies<E>) LongVector.species(s); 147 } 148 else { 149 throw new IllegalArgumentException("Bad vector element type: " + c.getName()); 150 } 151 } 152 153 /** 154 * Finds a preferred species for an element type. 155 * <p> 156 * A preferred species is a species chosen by the platform that has a 157 * shape of maximal bit size. A preferred species for different element 158 * types will have the same shape, and therefore vectors created from 159 * such species will be shape compatible. 160 * 161 * @param c the element type 162 * @param <E> the boxed element type 163 * @return a preferred species for an element type 164 * @throws IllegalArgumentException if no such species exists for the 165 * element type 166 */ 167 public static <E> VectorSpecies<E> ofPreferred(Class<E> c) { 168 Unsafe u = Unsafe.getUnsafe(); 169 170 int vectorLength = u.getMaxVectorSize(c); 171 int vectorBitSize = Vector.bitSizeForVectorLength(c, vectorLength); 172 VectorShape s = VectorShape.forBitSize(vectorBitSize); 173 return VectorSpecies.of(c, s); 174 } 175 176 interface FOpm { 177 boolean apply(int i); 178 } 179 180 VectorMask<E> opm(VectorSpecies.FOpm f) { 181 boolean[] res = new boolean[length()]; 182 for (int i = 0; i < length(); i++) { 183 res[i] = f.apply(i); 184 } 185 return maskFactory.apply(res); 186 } 187 } 188