Skip to content

[API Proposa]: Provide vector functions covering common "mask" checks #98055

@tannergooding

Description

@tannergooding

Summary

When working with vectors, it is frequent that you will do some sequence of operations and ultimately do a comparison which produces a mask. For the fixed-width vectors, you can then use var mask = vector.ExtractMostSignificantBits() to get a scalar bitmask that allows you to do many common operations such as determining if any matches existed (mask != 0), getting the total number of matches (BitOperations.PopCount(mask)), or getting the index of the first/last match (BitOperations.LeadingZeroCount(mask) or BitOperations.TrailingZeroCount(mask)).

However, getting this bit mask is not efficient on all platforms (Arm64 doesn't have an instruction similar to pmovmskb)_ nor can it be used with variable width vector types (Vector<T>, which will impact SVE on Arm64). As such, it is proposed that we expose some helpers for these "core" operations that abstract the logic, thus allowing more efficient handling in those scenarios.

API Proposal

namespace System.Numerics
{
    public partial class Vector
    {
        public static bool AnyMatches<T>(Vector<T> value);

        public static int GetMatchCount<T>(Vector<T> value);

        public static int IndexOfFirstMatch<T>(Vector<T> value);
        public static int IndexOfLastMatch<T>(Vector<T> value);
    }
}

namespace System.Runtime.Intrinsics
{
    public partial class Vector64
    {
        public static bool AnyMatches<T>(Vector64<T> value);

        public static int GetMatchCount<T>(Vector64<T> value);

        public static int IndexOfFirstMatch<T>(Vector64<T> value);
        public static int IndexOfLastMatch<T>(Vector64<T> value);
    }

    public partial class Vector128
    {
        public static bool AnyMatches<T>(Vector128<T> value);

        public static int GetMatchCount<T>(Vector128<T> value);

        public static int IndexOfFirstMatch<T>(Vector128<T> value);
        public static int IndexOfLastMatch<T>(Vector128<T> value);
    }

    public partial class Vector256
    {
        public static bool AnyMatches<T>(Vector256<T> value);

        public static int GetMatchCount<T>(Vector256<T> value);

        public static int IndexOfFirstMatch<T>(Vector256<T> value);
        public static int IndexOfLastMatch<T>(Vector256<T> value);
    }

    public partial class Vector512
    {
        public static bool AnyMatches<T>(Vector512<T> value);

        public static int GetMatchCount<T>(Vector512<T> value);

        public static int IndexOfFirstMatch<T>(Vector512<T> value);
        public static int IndexOfLastMatch<T>(Vector512<T> value);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions