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  * Interface supporting 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 interface VectorSpecies<E> {
  38     /**
  39      * Returns the primitive element type of vectors produced by this
  40      * species.
  41      *
  42      * @return the primitive element type
  43      */
  44     public abstract Class<E> elementType();
  45 
  46     /**
  47      * Returns the vector type corresponding to this species
  48      *
  49      * @return the vector type corresponding to this species
  50      */
  51     abstract Class<?> vectorType();
  52 
  53     /**
  54      * Returns the vector mask type for this species
  55      *
  56      * @return the box type
  57      */
  58     abstract Class<?> maskType();
  59 
  60     /**
  61      * Returns the element size, in bits, of vectors produced by this
  62      * species.
  63      *
  64      * @return the element size, in bits
  65      */
  66     public abstract int elementSize();
  67 
  68     /**
  69      * Returns the shape of masks, shuffles, and vectors produced by this
  70      * species.
  71      *
  72      * @return the primitive element type
  73      */
  74     public abstract VectorShape shape();
  75 
  76     /**
  77      * Returns the shape of the corresponding index species
  78      * @return the shape
  79      */
  80     @ForceInline
  81     public abstract VectorShape indexShape();
  82 
  83     /**
  84      * Returns the mask, shuffe, or vector lanes produced by this species.
  85      *
  86      * @return the the number of lanes
  87      */
  88     default public int length() { return shape().length(this); }
  89 
  90     /**
  91      * Returns the total vector size, in bits, of vectors produced by this
  92      * species.
  93      *
  94      * @return the total vector size, in bits
  95      */
  96     default public int bitSize() { return shape().bitSize(); }
  97 
  98     /**
  99      * Helper function to calculate the loop terminating condition when iterating over an array of given length.
 100      * Returns the result of {@code (length & ~(this.length() - 1))}
 101      *
 102      * @return the result of {@code (length & ~(this.length() - 1))}
 103      */
 104     default public int loopBound(int length) {
 105         return length & ~(this.length() - 1);
 106     }
 107 
 108     // Factory
 109 
 110     /**
 111      * Finds a species for an element type and shape.
 112      *
 113      * @param c the element type
 114      * @param s the shape
 115      * @param <E> the boxed element type
 116      * @return a species for an element type and shape
 117      * @throws IllegalArgumentException if no such species exists for the
 118      * element type and/or shape
 119      */
 120     @SuppressWarnings("unchecked")
 121     public static <E> VectorSpecies<E> of(Class<E> c, VectorShape s) {
 122         if (c == float.class) {
 123             return (VectorSpecies<E>) FloatVector.species(s);
 124         }
 125         else if (c == double.class) {
 126             return (VectorSpecies<E>) DoubleVector.species(s);
 127         }
 128         else if (c == byte.class) {
 129             return (VectorSpecies<E>) ByteVector.species(s);
 130         }
 131         else if (c == short.class) {
 132             return (VectorSpecies<E>) ShortVector.species(s);
 133         }
 134         else if (c == int.class) {
 135             return (VectorSpecies<E>) IntVector.species(s);
 136         }
 137         else if (c == long.class) {
 138             return (VectorSpecies<E>) LongVector.species(s);
 139         }
 140         else {
 141             throw new IllegalArgumentException("Bad vector element type: " + c.getName());
 142         }
 143     }
 144 
 145     /**
 146      * Finds a preferred species for an element type.
 147      * <p>
 148      * A preferred species is a species chosen by the platform that has a
 149      * shape of maximal bit size.  A preferred species for different element
 150      * types will have the same shape, and therefore vectors created from
 151      * such species will be shape compatible.
 152      *
 153      * @param c the element type
 154      * @param <E> the boxed element type
 155      * @return a preferred species for an element type
 156      * @throws IllegalArgumentException if no such species exists for the
 157      * element type
 158      */
 159     public static <E> VectorSpecies<E> ofPreferred(Class<E> c) {
 160         Unsafe u = Unsafe.getUnsafe();
 161 
 162         int vectorLength = u.getMaxVectorSize(c);
 163         int vectorBitSize = Vector.bitSizeForVectorLength(c, vectorLength);
 164         VectorShape s = VectorShape.forBitSize(vectorBitSize);
 165         return VectorSpecies.of(c, s);
 166     }
 167 }
 168