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 }
|