VectorMask.firstTrue()/lastTrue()
Paul Sandoz
paul.sandoz at oracle.com
Wed Apr 14 22:06:55 UTC 2021
Hi Remi,
That will not work because reduction with MIN will return 0 if the mask contains a false value.
You need to do something like this:
static int firstTrue(VectorMask<Integer> mask) {
var iota = IntVector.broadcast(mask.vectorSpecies(), 0).addIndex(1);
return IntVector.broadcast(mask.vectorSpecies(), mask.length()).blend(iota, mask).reduceLanes(VectorOperators.MIN);
}
static int lastTrue(VectorMask<Integer> mask) {
var iota = IntVector.broadcast(mask.vectorSpecies(), 0).addIndex(1);
return IntVector.broadcast(mask.vectorSpecies(), -1).blend(iota, mask).reduceLanes(VectorOperators.MAX);
}
I would like to add intrinsic operations for counting leading and trailing zeros (in addition to popcount), then use those operations for implementing first/lastTrue.
firstTrue == count-leading-zeros
lastTrue == length - count-trailing-zeros - 1
The above should help answer your question about the return value. But it does make me wonder if the result for "not found" is non-obvious and we should at least clarify in the Javadoc. The method names likely do not help in this regard.
Paul.
> On Apr 14, 2021, at 5:35 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>
> There is a way to implement firstTrue and lastTrue using only vector operations.
>
> The idea is to use to mask iota with the mask and then do a reduceLanes with MIN or MAX.
> By example to for firstTrue() that returns -1 if the mask is empty,
> first create iotaPlusOne, blend with zero, then reduceLanes with MIN, then substract 1
>
> VectorMask mask = ...
> var iotaPlusOne = ByteVector.broadcast(SPECIES, 1).addIndex(1);
> ByteVector.zero(SPECIES).blend(iotaPlusOne, mask).reduceLanes(VectorOperators.MIN) - 1;
>
> BTW, i wonder why firstTrue return the mask length instead of -1.
>
> regards,
> Rémi
More information about the panama-dev
mailing list