4

Can anyone explain preferably with an example what/when/how System.Numerics.Vector.ConditionalSelect can be used?

I cannot understand much from the docs.

MaYaN
  • 6,683
  • 12
  • 57
  • 109

1 Answers1

1

The condition parameter is actually Vector<int> when using 4 byte overloads of the ConditionalSelect such as the ones with Vector<int> or Vector<float> arguments. condition is Vector<long> when using 8 byte versions, etc.

To expand on @Hans' comment in your question, condition means something like: double c = cond == -1 ? a : b;. That is, when cond == -1, it selects the left values. When cond == 0, it selects the right values.

When cond is something else, I saw some results I don't particularly understand yet and didn't actually research.

class Program
{
    static void Main(string[] args)
    {
        //Length depends on your Vector<int>.Count. In my computer it is 4
        Vector<int> vector1 = new Vector<int>(4); //vector1 == {<4, 4, 4, 4>}
        Vector<int> vector2 = new Vector<int>(5); //vector2 == {<5, 5, 5, 5>}
        Vector<int> mask = Vector.GreaterThan(vector1, vector2); //mask == {<0, 0, 0, 0>}
        Vector<int> selected = Vector.ConditionalSelect(mask, vector1, vector2); //selected == {<5, 5, 5, 5>}

        vector1 = new Vector<int>(4); //vector1 == {<4, 4, 4, 4>}
        vector2 = new Vector<int>(3); //vector2 == {<3, 3, 3, 3>}
        mask = Vector.GreaterThan(vector1, vector2); //mask == {<-1, -1, -1, -1>}
        selected = Vector.ConditionalSelect(mask, vector1, vector2); //selected == {<4, 4, 4, 4>}

        mask = new Vector<int>(123); //mask == {<123, 123, 123, 123>}
        selected = Vector.ConditionalSelect(mask, vector1, vector2); //selected == {<0, 0, 0, 0>}

        mask = new Vector<int>(4);
        selected = Vector.ConditionalSelect(mask, vector1, vector2); //selected == {<7, 7, 7, 7>}
    }
}
johnildergleidisson
  • 2,087
  • 3
  • 30
  • 50
  • 1
    Related: [How to use if condition in intrinsics](https://stackoverflow.com/q/38006616) has some other comments and examples on how to branchlessly handle per-element conditions with SIMD. Sometimes you can use a simple AND instead of `ConditionalSelect`, if making some elements of the input or output all-zero works. (zero is the identity value for integer add/sub/xor/or, and for FP add/sub.) Another example with C++ intrinsics: caseflip ASCII letters only: [How to access a char array and change lower case letters to upper case, and vice versa](https://stackoverflow.com/a/35936844) – Peter Cordes Aug 14 '18 at 13:34