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 box type for this species
  48      *
  49      * @return the box type
  50      */
  51     abstract Class<?> boxType();
  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     // Factory
  99 
 100     /**
 101      * Finds a species for an element type and shape.
 102      *
 103      * @param c the element type
 104      * @param s the shape
 105      * @param <E> the boxed element type
 106      * @return a species for an element type and shape
 107      * @throws IllegalArgumentException if no such species exists for the
 108      * element type and/or shape
 109      */
 110     @SuppressWarnings("unchecked")
 111     public static <E> VectorSpecies<E> of(Class<E> c, VectorShape s) {
 112         if (c == float.class) {
 113             return (VectorSpecies<E>) FloatVector.species(s);
 114         }
 115         else if (c == double.class) {
 116             return (VectorSpecies<E>) DoubleVector.species(s);
 117         }
 118         else if (c == byte.class) {
 119             return (VectorSpecies<E>) ByteVector.species(s);
 120         }
 121         else if (c == short.class) {
 122             return (VectorSpecies<E>) ShortVector.species(s);
 123         }
 124         else if (c == int.class) {
 125             return (VectorSpecies<E>) IntVector.species(s);
 126         }
 127         else if (c == long.class) {
 128             return (VectorSpecies<E>) LongVector.species(s);
 129         }
 130         else {
 131             throw new IllegalArgumentException("Bad vector element type: " + c.getName());
 132         }
 133     }
 134 
 135     /**
 136      * Finds a preferred species for an element type.
 137      * <p>
 138      * A preferred species is a species chosen by the platform that has a
 139      * shape of maximal bit size.  A preferred species for different element
 140      * types will have the same shape, and therefore vectors created from
 141      * such species will be shape compatible.
 142      *
 143      * @param c the element type
 144      * @param <E> the boxed element type
 145      * @return a preferred species for an element type
 146      * @throws IllegalArgumentException if no such species exists for the
 147      * element type
 148      */
 149     public static <E> VectorSpecies<E> ofPreferred(Class<E> c) {
 150         Unsafe u = Unsafe.getUnsafe();
 151 
 152         int vectorLength = u.getMaxVectorSize(c);
 153         int vectorBitSize = Vector.bitSizeForVectorLength(c, vectorLength);
 154         VectorShape s = VectorShape.forBitSize(vectorBitSize);
 155         return VectorSpecies.of(c, s);
 156     }
 157 }
 158