// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using System; using System.Collections.Generic; using System.Linq; using System.Numerics; #if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics.X86; #endif using Xunit; using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests { public class FeatureTestRunnerTests { public static TheoryData Intrinsics => new TheoryData { { HwIntrinsics.DisableAES | HwIntrinsics.AllowAll, new string[] { "EnableAES", "AllowAll" } }, { HwIntrinsics.DisableSIMD | HwIntrinsics.DisableHWIntrinsic, new string[] { "FeatureSIMD", "EnableHWIntrinsic" } }, { HwIntrinsics.DisableSSE42 | HwIntrinsics.DisableAVX, new string[] { "EnableSSE42", "EnableAVX" } } }; [Theory] [MemberData(nameof(Intrinsics))] public void ToFeatureCollectionReturnsExpectedResult(HwIntrinsics expectedItrinsics, string[] expectedValues) { Dictionary 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 actualValues = features.Select(x => x.Value); Assert.Equal(expectedValues, actualValues); } [Fact] public void AllowsAllHwIntrinsicFeatures() { FeatureTestRunner.RunWithHwIntrinsicsFeature( () => Assert.True(Vector.IsHardwareAccelerated, nameof(Vector.IsHardwareAccelerated)), HwIntrinsics.AllowAll); } #if SUPPORTS_RUNTIME_INTRINSICS [Fact] public void CanLimitHwIntrinsicFeatures() { FeatureTestRunner.RunWithHwIntrinsicsFeature( () => Assert.False(Sse.IsSupported, nameof(Sse.IsSupported)), HwIntrinsics.DisableSSE); } #endif // [Fact] // public void CanLimitHwIntrinsicFeaturesWithIntrinsicsParam() // { // static void AssertHwIntrinsicsFeatureDisabled(string intrinsic) // { // Assert.NotNull(intrinsic); // switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) // { // case HwIntrinsics.DisableSIMD: // Assert.False(Vector.IsHardwareAccelerated); // break; //#if SUPPORTS_RUNTIME_INTRINSICS // case HwIntrinsics.DisableHWIntrinsic: // Assert.False(Vector.IsHardwareAccelerated); // break; // case HwIntrinsics.DisableSSE: // Assert.False(Sse.IsSupported); // break; // case HwIntrinsics.DisableSSE2: // Assert.False(Sse2.IsSupported); // break; // case HwIntrinsics.DisableAES: // Assert.False(Aes.IsSupported); // break; // case HwIntrinsics.DisablePCLMULQDQ: // Assert.False(Pclmulqdq.IsSupported); // break; // case HwIntrinsics.DisableSSE3: // Assert.False(Sse3.IsSupported); // break; // case HwIntrinsics.DisableSSSE3: // Assert.False(Ssse3.IsSupported); // break; // case HwIntrinsics.DisableSSE41: // Assert.False(Sse41.IsSupported); // break; // case HwIntrinsics.DisableSSE42: // Assert.False(Sse42.IsSupported); // break; // case HwIntrinsics.DisablePOPCNT: // Assert.False(Popcnt.IsSupported); // break; // case HwIntrinsics.DisableAVX: // Assert.False(Avx.IsSupported); // break; // case HwIntrinsics.DisableFMA: // Assert.False(Fma.IsSupported); // break; // case HwIntrinsics.DisableAVX2: // Assert.False(Avx2.IsSupported); // break; // case HwIntrinsics.DisableBMI1: // Assert.False(Bmi1.IsSupported); // break; // case HwIntrinsics.DisableBMI2: // Assert.False(Bmi2.IsSupported); // break; // case HwIntrinsics.DisableLZCNT: // Assert.False(Lzcnt.IsSupported); // break; //#endif // } // } // foreach (HwIntrinsics intrinsic in (HwIntrinsics[])Enum.GetValues(typeof(HwIntrinsics))) // { // FeatureTestRunner.RunWithHwIntrinsicsFeature(AssertHwIntrinsicsFeatureDisabled, intrinsic); // } // } // [Fact] // public void CanLimitHwIntrinsicFeaturesWithSerializableParam() // { // static void AssertHwIntrinsicsFeatureDisabled(string serializable) // { // Assert.NotNull(serializable); // Assert.NotNull(FeatureTestRunner.Deserialize(serializable)); //#if SUPPORTS_RUNTIME_INTRINSICS // Assert.False(Sse.IsSupported); //#endif // } // foreach (HwIntrinsics intrinsic in (HwIntrinsics[])Enum.GetValues(typeof(HwIntrinsics))) // { // FeatureTestRunner.RunWithHwIntrinsicsFeature( // AssertHwIntrinsicsFeatureDisabled, // HwIntrinsics.DisableSSE, // new FakeSerializable()); // } // } // [Fact] // public void CanLimitHwIntrinsicFeaturesWithSerializableAndIntrinsicsParams() // { // static void AssertHwIntrinsicsFeatureDisabled(string serializable, string intrinsic) // { // Assert.NotNull(serializable); // Assert.NotNull(FeatureTestRunner.Deserialize(serializable)); // switch ((HwIntrinsics)Enum.Parse(typeof(HwIntrinsics), intrinsic)) // { // case HwIntrinsics.DisableSIMD: // Assert.False(Vector.IsHardwareAccelerated, nameof(Vector.IsHardwareAccelerated)); // break; //#if SUPPORTS_RUNTIME_INTRINSICS // case HwIntrinsics.DisableHWIntrinsic: // Assert.False(Vector.IsHardwareAccelerated, nameof(Vector.IsHardwareAccelerated)); // break; // case HwIntrinsics.DisableSSE: // Assert.False(Sse.IsSupported); // break; // case HwIntrinsics.DisableSSE2: // Assert.False(Sse2.IsSupported); // break; // case HwIntrinsics.DisableAES: // Assert.False(Aes.IsSupported); // break; // case HwIntrinsics.DisablePCLMULQDQ: // Assert.False(Pclmulqdq.IsSupported); // break; // case HwIntrinsics.DisableSSE3: // Assert.False(Sse3.IsSupported); // break; // case HwIntrinsics.DisableSSSE3: // Assert.False(Ssse3.IsSupported); // break; // case HwIntrinsics.DisableSSE41: // Assert.False(Sse41.IsSupported); // break; // case HwIntrinsics.DisableSSE42: // Assert.False(Sse42.IsSupported); // break; // case HwIntrinsics.DisablePOPCNT: // Assert.False(Popcnt.IsSupported); // break; // case HwIntrinsics.DisableAVX: // Assert.False(Avx.IsSupported); // break; // case HwIntrinsics.DisableFMA: // Assert.False(Fma.IsSupported); // break; // case HwIntrinsics.DisableAVX2: // Assert.False(Avx2.IsSupported); // break; // case HwIntrinsics.DisableBMI1: // Assert.False(Bmi1.IsSupported); // break; // case HwIntrinsics.DisableBMI2: // Assert.False(Bmi2.IsSupported); // break; // case HwIntrinsics.DisableLZCNT: // Assert.False(Lzcnt.IsSupported); // break; //#endif // } // } // foreach (HwIntrinsics intrinsic in (HwIntrinsics[])Enum.GetValues(typeof(HwIntrinsics))) // { // FeatureTestRunner.RunWithHwIntrinsicsFeature(AssertHwIntrinsicsFeatureDisabled, intrinsic, new FakeSerializable()); // } // } public class FakeSerializable : IXunitSerializable { public void Deserialize(IXunitSerializationInfo info) { } public void Serialize(IXunitSerializationInfo info) { } } } }