< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java

Print this page
rev 54658 : refactored mask and shuffle creation methods, moved classes to top-level
rev 54659 : changed VectorSpecies to interface and moved stuff to AbstractSpecies
rev 54660 : Javadoc changes


  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 
  30 import java.util.Objects;
  31 
  32 /**
  33  * A {@code VectorMask} represents an ordered immutable sequence of {@code boolean}
  34  * values.  A VectorMask can be used with a mask accepting vector operation to
  35  * control the selection and operation of lane elements of input vectors.
  36  * <p>
  37  * The number of values in the sequence is referred to as the VectorMask
  38  * {@link #length() length}. The length also corresponds to the number of
  39  * VectorMask lanes.  The lane element at lane index {@code N} (from {@code 0},
  40  * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
  41  * value in the sequence.
  42  * A VectorMask and Vector of the same element type and shape have the same number
  43  * of lanes.
  44  * <p>
  45  * A lane is said to be <em>set</em> if the lane element is {@code true},
  46  * otherwise a lane is said to be <em>unset</em> if the lane element is
  47  * {@code false}.
  48  * <p>
  49  * VectorMask declares a limited set of unary, binary and reductive mask
  50  * operations.
  51  * <ul>
  52  * <li>
  53  * A mask unary operation (1-ary) operates on one input mask to produce a
  54  * result mask.
  55  * For each lane of the input mask the
  56  * lane element is operated on using the specified scalar unary operation and
  57  * the boolean result is placed into the mask result at the same lane.
  58  * The following pseudocode expresses the behaviour of this operation category:
  59  *
  60  * <pre>{@code
  61  * VectorMask<E> a = ...;
  62  * boolean[] ar = new boolean[a.length()];
  63  * for (int i = 0; i < a.length(); i++) {
  64  *     ar[i] = boolean_unary_op(a.isSet(i));
  65  * }
  66  * VectorMask<E> r = VectorMask.fromArray(ar, 0);
  67  * }</pre>
  68  *
  69  * <li>
  70  * A mask binary operation (2-ary) operates on two input
  71  * masks to produce a result mask.
  72  * For each lane of the two input masks,
  73  * a and b say, the corresponding lane elements from a and b are operated on
  74  * using the specified scalar binary operation and the boolean result is placed
  75  * into the mask result at the same lane.
  76  * The following pseudocode expresses the behaviour of this operation category:
  77  *
  78  * <pre>{@code
  79  * VectorMask<E> a = ...;
  80  * VectorMask<E> b = ...;
  81  * boolean[] ar = new boolean[a.length()];
  82  * for (int i = 0; i < a.length(); i++) {
  83  *     ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
  84  * }
  85  * VectorMask<E> r = VectorMask.fromArray(ar, 0);















  86  * }</pre>
  87  *
  88  * </ul>
  89  * @param <E> the boxed element type of this mask
  90  */
  91 public abstract class VectorMask<E> {
  92     VectorMask() {}
  93 
  94     /**
  95      * Returns the species of this mask.
  96      *
  97      * @return the species of this mask
  98      */
  99     public abstract VectorSpecies<E> species();
 100 
 101     /**
 102      * Returns the number of mask lanes (the length).
 103      *
 104      * @return the number of mask lanes
 105      */


 115      *
 116      * @param species mask species
 117      * @param bits the given {@code boolean} values
 118      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 119      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 120      */
 121     @ForceInline
 122     public static <E> VectorMask<E> fromValues(VectorSpecies<E> species, boolean... bits) {
 123         return fromArray(species, bits, 0);
 124     }
 125 
 126     /**
 127      * Loads a mask from a {@code boolean} array starting at an offset.
 128      * <p>
 129      * For each mask lane, where {@code N} is the mask lane index,
 130      * if the array element at index {@code ix + N} is {@code true} then the
 131      * mask lane at index {@code N} is set, otherwise it is unset.
 132      *
 133      * @param species mask species
 134      * @param bits the {@code boolean} array
 135      * @param ix the offset into the array
 136      * @return the mask loaded from a {@code boolean} array
 137      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 138      * {@code ix > bits.length - species.length()}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static <E> VectorMask<E> fromArray(VectorSpecies<E> species, boolean[] bits, int ix) {
 143         Objects.requireNonNull(bits);
 144         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 145         return VectorIntrinsics.load((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
 146                 bits, (long) ix + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 147                 bits, ix, species,
 148                 (boolean[] c, int idx, VectorSpecies<E> s) -> ((AbstractSpecies<E>)s).opm(n -> c[idx + n]));
 149     }
 150 
 151     /**
 152      * Returns a mask where all lanes are set.
 153      *
 154      * @param species mask species
 155      * @return a mask where all lanes are set
 156      */
 157     @ForceInline
 158     @SuppressWarnings("unchecked")
 159     public static <E> VectorMask<E> maskAllTrue(VectorSpecies<E> species) {
 160         return VectorIntrinsics.broadcastCoerced((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
 161                 -1,  species,
 162                 ((z, s) -> AbstractMask.trueMask(s)));
 163     }
 164 
 165     /**
 166      * Returns a mask where all lanes are unset.
 167      *


 216      * this mask into an allocated array and returns that array as
 217      * follows:
 218      * <pre>{@code
 219      * boolean[] a = new boolean[this.length()];
 220      * this.intoArray(a, 0);
 221      * return a;
 222      * }</pre>
 223      *
 224      * @return an array containing the the lane elements of this vector
 225      */
 226     public abstract boolean[] toArray();
 227 
 228     /**
 229      * Stores this mask into a {@code boolean} array starting at offset.
 230      * <p>
 231      * For each mask lane, where {@code N} is the mask lane index,
 232      * the lane element at index {@code N} is stored into the array at index
 233      * {@code i + N}.
 234      *
 235      * @param a the array
 236      * @param i the offset into the array
 237      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 238      * {@code i > a.length - this.length()}
 239      */
 240     public abstract void intoArray(boolean[] a, int i);
 241 
 242     /**
 243      * Returns {@code true} if any of the mask lanes are set.
 244      *
 245      * @return {@code true} if any of the mask lanes are set, otherwise
 246      * {@code false}.
 247      */
 248     public abstract boolean anyTrue();
 249 
 250     /**
 251      * Returns {@code true} if all of the mask lanes are set.
 252      *
 253      * @return {@code true} if all of the mask lanes are set, otherwise
 254      * {@code false}.
 255      */
 256     public abstract boolean allTrue();
 257 
 258     /**
 259      * Returns the number of mask lanes that are set.
 260      *
 261      * @return the number of mask lanes that are set.
 262      */
 263     public abstract int trueCount();
 264 
 265     /**
 266      * Logically ands this mask with an input mask.
 267      * <p>
 268      * This is a mask binary operation where the logical and operation
 269      * ({@code &&} is applied to lane elements.
 270      *
 271      * @param o the input mask
 272      * @return the result of logically and'ing this mask with an input mask
 273      */
 274     public abstract VectorMask<E> and(VectorMask<E> o);
 275 
 276     /**
 277      * Logically ors this mask with an input mask.
 278      * <p>
 279      * This is a mask binary operation where the logical or operation
 280      * ({@code ||} is applied to lane elements.
 281      *
 282      * @param o the input mask
 283      * @return the result of logically or'ing this mask with an input mask
 284      */
 285     public abstract VectorMask<E> or(VectorMask<E> o);
 286 
 287     /**
 288      * Logically negates this mask.
 289      * <p>
 290      * This is a mask unary operation where the logical not operation
 291      * ({@code !} is applied to lane elements.
 292      *
 293      * @return the result of logically negating this mask.
 294      */
 295     public abstract VectorMask<E> not();
 296 
 297     /**
 298      * Returns a vector representation of this mask.
 299      * <p>
 300      * For each mask lane, where {@code N} is the mask lane index,
 301      * if the mask lane is set then an element value whose most significant
 302      * bit is set is placed into the resulting vector at lane index
 303      * {@code N}, otherwise the default element value is placed into the
 304      * resulting vector at lane index {@code N}.
 305      *
 306      * @return a vector representation of this mask.
 307      */
 308     public abstract Vector<E> toVector();
 309 
 310     /**
 311      * Tests if the lane at index {@code i} is set
 312      * @param i the lane index
 313      *
 314      * @return true if the lane at index {@code i} is set, otherwise false
 315      */
 316     public abstract boolean getElement(int i);
 317 
 318     /**
 319      * Tests if the lane at index {@code i} is set
 320      * @param i the lane index
 321      * @return true if the lane at index {@code i} is set, otherwise false
 322      * @see #getElement
 323      */
 324     public boolean isSet(int i) {
 325         return getElement(i);
 326     }
 327 }


  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 
  30 import java.util.Objects;
  31 
  32 /**
  33  * A {@code VectorMask} represents an ordered immutable sequence of {@code boolean}
  34  * values.  Some vector operations accept masks to
  35  * control the selection and operation of lane elements of input vectors.
  36  * <p>
  37  * The number of values in the sequence is referred to as the VectorMask
  38  * {@link #length() length}. The length also corresponds to the number of
  39  * VectorMask lanes.  The lane element at lane index {@code N} (from {@code 0},
  40  * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
  41  * value in the sequence.
  42  * A VectorMask and Vector of the same element type and shape have the same number
  43  * of lanes.
  44  * <p>
  45  * A lane is said to be <em>set</em> if the lane element is {@code true},
  46  * otherwise a lane is said to be <em>unset</em> if the lane element is
  47  * {@code false}.
  48  * <p>
  49  * VectorMask declares a limited set of unary, binary and reduction operations.

  50  * <ul>
  51  * <li>
  52  * A lane-wise unary operation operates on one input mask and produces a
  53  * result mask.
  54  * For each lane of the input mask the
  55  * lane element is operated on using the specified scalar unary operation and
  56  * the boolean result is placed into the mask result at the same lane.
  57  * The following pseudocode expresses the behavior of this operation category:
  58  *
  59  * <pre>{@code
  60  * VectorMask<E> a = ...;
  61  * boolean[] ar = new boolean[a.length()];
  62  * for (int i = 0; i < a.length(); i++) {
  63  *     ar[i] = scalar_unary_op(a.isSet(i));
  64  * }
  65  * VectorMask<E> r = VectorMask.fromArray(a.species(), ar, 0);
  66  * }</pre>
  67  *
  68  * <li>
  69  * A lane-wise binary operation operates on two input
  70  * masks to produce a result mask.
  71  * For each lane of the two input masks a and b,
  72  * the corresponding lane elements from a and b are operated on
  73  * using the specified scalar binary operation and the boolean result is placed
  74  * into the mask result at the same lane.
  75  * The following pseudocode expresses the behavior of this operation category:
  76  *
  77  * <pre>{@code
  78  * VectorMask<E> a = ...;
  79  * VectorMask<E> b = ...;
  80  * boolean[] ar = new boolean[a.length()];
  81  * for (int i = 0; i < a.length(); i++) {
  82  *     ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
  83  * }
  84  * VectorMask<E> r = VectorMask.fromArray(a.species(), ar, 0);
  85  * }</pre>
  86  *
  87  * <li>
  88  * A cross-lane reduction operation accepts an input mask and produces a scalar result.
  89  * For each lane of the input mask the lane element is operated on, together with a scalar accumulation value,
  90  * using the specified scalar binary operation.  The scalar result is the final value of the accumulator. The
  91  * following pseudocode expresses the behaviour of this operation category:
  92  *
  93  * <pre>{@code
  94  * Mask<E> a = ...;
  95  * int acc = zero_for_scalar_binary_op;  // 0, or 1 for &
  96  * for (int i = 0; i < a.length(); i++) {
  97  *      acc = scalar_binary_op(acc, a.isSet(i) ? 1 : 0);  // & | +
  98  * }
  99  * return acc;  // maybe boolean (acc != 0)
 100  * }</pre>
 101  *
 102  * </ul>
 103  * @param <E> the boxed element type of this mask
 104  */
 105 public abstract class VectorMask<E> {
 106     VectorMask() {}
 107 
 108     /**
 109      * Returns the species of this mask.
 110      *
 111      * @return the species of this mask
 112      */
 113     public abstract VectorSpecies<E> species();
 114 
 115     /**
 116      * Returns the number of mask lanes (the length).
 117      *
 118      * @return the number of mask lanes
 119      */


 129      *
 130      * @param species mask species
 131      * @param bits the given {@code boolean} values
 132      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 133      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 134      */
 135     @ForceInline
 136     public static <E> VectorMask<E> fromValues(VectorSpecies<E> species, boolean... bits) {
 137         return fromArray(species, bits, 0);
 138     }
 139 
 140     /**
 141      * Loads a mask from a {@code boolean} array starting at an offset.
 142      * <p>
 143      * For each mask lane, where {@code N} is the mask lane index,
 144      * if the array element at index {@code ix + N} is {@code true} then the
 145      * mask lane at index {@code N} is set, otherwise it is unset.
 146      *
 147      * @param species mask species
 148      * @param bits the {@code boolean} array
 149      * @param offset the offset into the array
 150      * @return the mask loaded from a {@code boolean} array
 151      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
 152      * {@code offset > bits.length - species.length()}
 153      */
 154     @ForceInline
 155     @SuppressWarnings("unchecked")
 156     public static <E> VectorMask<E> fromArray(VectorSpecies<E> species, boolean[] bits, int offset) {
 157         Objects.requireNonNull(bits);
 158         offset = VectorIntrinsics.checkIndex(offset, bits.length, species.length());
 159         return VectorIntrinsics.load((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
 160                 bits, (long) offset + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 161                 bits, offset, species,
 162                 (boolean[] c, int idx, VectorSpecies<E> s) -> ((AbstractSpecies<E>)s).opm(n -> c[idx + n]));
 163     }
 164 
 165     /**
 166      * Returns a mask where all lanes are set.
 167      *
 168      * @param species mask species
 169      * @return a mask where all lanes are set
 170      */
 171     @ForceInline
 172     @SuppressWarnings("unchecked")
 173     public static <E> VectorMask<E> maskAllTrue(VectorSpecies<E> species) {
 174         return VectorIntrinsics.broadcastCoerced((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
 175                 -1,  species,
 176                 ((z, s) -> AbstractMask.trueMask(s)));
 177     }
 178 
 179     /**
 180      * Returns a mask where all lanes are unset.
 181      *


 230      * this mask into an allocated array and returns that array as
 231      * follows:
 232      * <pre>{@code
 233      * boolean[] a = new boolean[this.length()];
 234      * this.intoArray(a, 0);
 235      * return a;
 236      * }</pre>
 237      *
 238      * @return an array containing the the lane elements of this vector
 239      */
 240     public abstract boolean[] toArray();
 241 
 242     /**
 243      * Stores this mask into a {@code boolean} array starting at offset.
 244      * <p>
 245      * For each mask lane, where {@code N} is the mask lane index,
 246      * the lane element at index {@code N} is stored into the array at index
 247      * {@code i + N}.
 248      *
 249      * @param a the array
 250      * @param offset the offset into the array
 251      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
 252      * {@code offset > a.length - this.length()}
 253      */
 254     public abstract void intoArray(boolean[] a, int offset);
 255 
 256     /**
 257      * Returns {@code true} if any of the mask lanes are set.
 258      *
 259      * @return {@code true} if any of the mask lanes are set, otherwise
 260      * {@code false}.
 261      */
 262     public abstract boolean anyTrue();
 263 
 264     /**
 265      * Returns {@code true} if all of the mask lanes are set.
 266      *
 267      * @return {@code true} if all of the mask lanes are set, otherwise
 268      * {@code false}.
 269      */
 270     public abstract boolean allTrue();
 271 
 272     /**
 273      * Returns the number of mask lanes that are set.
 274      *
 275      * @return the number of mask lanes that are set.
 276      */
 277     public abstract int trueCount();
 278 
 279     /**
 280      * Logically ands this mask with an input mask.
 281      * <p>
 282      * This is a lane-wise binary operation which applies the logical and operation
 283      * ({@code &&}) to each lane.
 284      *
 285      * @param o the input mask
 286      * @return the result of logically and'ing this mask with an input mask
 287      */
 288     public abstract VectorMask<E> and(VectorMask<E> o);
 289 
 290     /**
 291      * Logically ors this mask with an input mask.
 292      * <p>
 293      * This is a lane-wise binary operation which applies the logical or operation
 294      * ({@code ||}) to each lane.
 295      *
 296      * @param o the input mask
 297      * @return the result of logically or'ing this mask with an input mask
 298      */
 299     public abstract VectorMask<E> or(VectorMask<E> o);
 300 
 301     /**
 302      * Logically negates this mask.
 303      * <p>
 304      * This is a lane-wise unary operation which applies the logical not operation
 305      * ({@code !}) to each lane.
 306      *
 307      * @return the result of logically negating this mask.
 308      */
 309     public abstract VectorMask<E> not();
 310 
 311     /**
 312      * Returns a vector representation of this mask.
 313      * <p>
 314      * For each mask lane, where {@code N} is the mask lane index,
 315      * if the mask lane is set then an element value whose most significant
 316      * bit is set is placed into the resulting vector at lane index
 317      * {@code N}, otherwise the default element value is placed into the
 318      * resulting vector at lane index {@code N}.
 319      *
 320      * @return a vector representation of this mask.
 321      */
 322     public abstract Vector<E> toVector();
 323 
 324     /**
 325      * Tests if the lane at index {@code i} is set
 326      * @param i the lane index
 327      *
 328      * @return true if the lane at index {@code i} is set, otherwise false
 329      */
 330     public abstract boolean lane(int i);
 331 
 332     /**
 333      * Tests if the lane at index {@code i} is set
 334      * @param i the lane index
 335      * @return true if the lane at index {@code i} is set, otherwise false
 336      * @see #lane
 337      */
 338     public boolean isSet(int i) {
 339         return lane(i);
 340     }
 341 }
< prev index next >