/// <summary> /// Runs the given test <paramref name="action"/> within an environment /// where the given <paramref name="intrinsics"/> features. /// </summary> /// <param name="action"> /// The test action to run. /// The parameter passed will be a string representing the currently testing <see cref="HwIntrinsics"/>.</param> /// <param name="intrinsics">The intrinsics features.</param> public static void RunWithHwIntrinsicsFeature( Action <string> action, HwIntrinsics intrinsics) { if (!RemoteExecutor.IsSupported) { return; } foreach (KeyValuePair <HwIntrinsics, string> intrinsic in intrinsics.ToFeatureKeyValueCollection()) { var processStartInfo = new ProcessStartInfo(); if (intrinsic.Key != HwIntrinsics.AllowAll) { processStartInfo.Environment[$"COMPlus_{intrinsic.Value}"] = "0"; RemoteExecutor.Invoke( action, intrinsic.Key.ToString(), new RemoteInvokeOptions { StartInfo = processStartInfo }) .Dispose(); } else { // Since we are running using the default architecture there is no // point creating the overhead of running the action in a separate process. action(intrinsic.Key.ToString()); } } }
public static void Shuffle4( ReadOnlySpan <float> source, Span <float> dest, byte control) { VerifyShuffle4SpanInput(source, dest); #if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, control); #endif // Deal with the remainder: if (source.Length > 0) { Shuffle4Remainder(source, dest, control); } }
public static void Shuffle4 <TShuffle>( ReadOnlySpan <byte> source, Span <byte> dest, TShuffle shuffle) where TShuffle : struct, IShuffle4 { VerifyShuffle4SpanInput(source, dest); #if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle4Reduce(ref source, ref dest, shuffle.Control); #endif // Deal with the remainder: if (source.Length > 0) { shuffle.RunFallbackShuffle(source, dest); } }
public static void Shuffle3 <TShuffle>( ReadOnlySpan <byte> source, Span <byte> dest, TShuffle shuffle) where TShuffle : struct, IShuffle3 { // Source length should be smaller than dest length, and divisible by 3. VerifyShuffle3SpanInput(source, dest); #if SUPPORTS_RUNTIME_INTRINSICS HwIntrinsics.Shuffle3Reduce(ref source, ref dest, shuffle.Control); #endif // Deal with the remainder: if (source.Length > 0) { shuffle.RunFallbackShuffle(source, dest); } }
public void ToFeatureCollectionReturnsExpectedResult(HwIntrinsics expectedItrinsics, string[] expectedValues) { Dictionary <HwIntrinsics, string> features = expectedItrinsics.ToFeatureKeyValueCollection(); HwIntrinsics[] keys = features.Keys.ToArray(); HwIntrinsics actualIntrinsics = keys[0]; for (int i = 1; i < keys.Length; i++) { actualIntrinsics |= keys[i]; } Assert.Equal(expectedItrinsics, actualIntrinsics); IEnumerable <string> actualValues = features.Select(x => x.Value); Assert.Equal(expectedValues, actualValues); }
internal static void PackFromRgbPlanes( Configuration configuration, ReadOnlySpan <byte> redChannel, ReadOnlySpan <byte> greenChannel, ReadOnlySpan <byte> blueChannel, Span <Rgba32> destination) { DebugGuard.IsTrue(greenChannel.Length == redChannel.Length, nameof(greenChannel), "Channels must be of same size!"); DebugGuard.IsTrue(blueChannel.Length == redChannel.Length, nameof(blueChannel), "Channels must be of same size!"); DebugGuard.IsTrue(destination.Length > redChannel.Length, nameof(destination), "'destination' span should not be shorter than the source channels!"); #if SUPPORTS_RUNTIME_INTRINSICS if (Avx2.IsSupported) { HwIntrinsics.PackFromRgbPlanesAvx2Reduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } else #endif { PackFromRgbPlanesScalarBatchedReduce(ref redChannel, ref greenChannel, ref blueChannel, ref destination); } PackFromRgbPlanesRemainder(redChannel, greenChannel, blueChannel, destination); }
internal static Dictionary <HwIntrinsics, string> ToFeatureKeyValueCollection(this HwIntrinsics intrinsics) { // Loop through and translate the given values into COMPlus equivaluents var features = new Dictionary <HwIntrinsics, string>(); foreach (string intrinsic in intrinsics.ToString("G").Split(SplitChars, StringSplitOptions.RemoveEmptyEntries)) { var key = (HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic); switch (intrinsic) { case nameof(HwIntrinsics.DisableSIMD): features.Add(key, "FeatureSIMD"); break; case nameof(HwIntrinsics.AllowAll): // Not a COMPlus value. We filter in calling method. features.Add(key, nameof(HwIntrinsics.AllowAll)); break; default: features.Add(key, intrinsic.Replace("Disable", "Enable")); break; } } return(features); }