diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb762c3..e86448d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,8 +6,12 @@ on: jobs: build-and-test: - name: "Test projects" - runs-on: ubuntu-latest + name: build-and-test-${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, ubuntu-24.04-arm] + steps: - name: Install .NET uses: actions/setup-dotnet@v4 @@ -21,8 +25,34 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Test Projects (Debug) - run: dotnet test -c Debug + - name: Build (Debug) + run: dotnet build -c Debug + + - name: Build (Release) + run: dotnet build -c Release + + - name: Test (Debug) + run: dotnet test -c Debug --no-build + + - name: Test (Release) + run: dotnet test -c Release --no-build + + - name: Test (Debug, AVX2=0) + env: + DOTNET_EnableAVX2: "0" + run: dotnet test -c Debug --no-build + + - name: Test (Release, AVX2=0) + env: + DOTNET_EnableAVX2: "0" + run: dotnet test -c Release --no-build + + - name: Test (Debug, HWIntrinsic=0) + env: + DOTNET_EnableHWIntrinsic: "0" + run: dotnet test -c Debug --no-build - - name: Test Projects (Release) - run: dotnet test -c Release + - name: Test (Release, HWIntrinsic=0) + env: + DOTNET_EnableHWIntrinsic: "0" + run: dotnet test -c Release --no-build diff --git a/src/Ramstack.Parsing/Parser.Set.cs b/src/Ramstack.Parsing/Parser.Set.cs index 326c6b2..3a6fab2 100644 --- a/src/Ramstack.Parsing/Parser.Set.cs +++ b/src/Ramstack.Parsing/Parser.Set.cs @@ -624,9 +624,13 @@ private static bool ContainsCore(char ch, ushort[] ranges) } else { - var v = AdvSimd.CompareLessThanOrEqual( - AdvSimd.Subtract(c, x), - y); + // var v = AdvSimd.CompareEqual( + // AdvSimd.Min(AdvSimd.Max(c, x), y), + // c); + + var v = AdvSimd.And( + AdvSimd.CompareGreaterThanOrEqual(c, x), + AdvSimd.CompareLessThanOrEqual(c, y)); if (!v.Equals(Vector128.Zero)) return true; diff --git a/tests/Ramstack.Parsing.Tests/ParsersTests.Repeat_Opt.cs b/tests/Ramstack.Parsing.Tests/ParsersTests.Repeat_Opt.cs index 8fe69f3..cfc9c6b 100644 --- a/tests/Ramstack.Parsing.Tests/ParsersTests.Repeat_Opt.cs +++ b/tests/Ramstack.Parsing.Tests/ParsersTests.Repeat_Opt.cs @@ -211,7 +211,10 @@ public void Repeat_ContainsSearcher() var parser = Set(set.ToString()).Many(); var p = parser.Text(); - Assert.That(parser.GetType().ToString(), Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+ContainsSearcher]")); + Assert.That(parser.GetType().ToString(), + Avx2.IsSupported + ? Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+ContainsSearcher]") + : Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+BinaryRangeSearcher]")); var s = chars.ToString(); var r = string.Join("", s.Reverse()); diff --git a/tests/Ramstack.Parsing.Tests/ParsersTests.Set_Opt.cs b/tests/Ramstack.Parsing.Tests/ParsersTests.Set_Opt.cs index b3ba62b..c1207a2 100644 --- a/tests/Ramstack.Parsing.Tests/ParsersTests.Set_Opt.cs +++ b/tests/Ramstack.Parsing.Tests/ParsersTests.Set_Opt.cs @@ -122,7 +122,10 @@ public void Set_MultipleRanges_ContainsSearch() var parser = Set(sb.ToString()); - Assert.That(parser.GetType().ToString(), Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+ContainsSearcher]")); + Assert.That(parser.GetType().ToString(), + Avx2.IsSupported + ? Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+ContainsSearcher]") + : Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+BinaryRangeSearcher]")); IncludeTest(parser, c => c < 128*5 && c % 5 == 0); } @@ -195,7 +198,7 @@ public void Set_MultipleRanges_BinarySearch() IncludeTest(parser, c => c < 10240 && c % 2 == 0); } - private static void IncludeTest(Parser parser, Func isIncluded) + private static void IncludeTest(Parser parser, Func included) { for (var c = 0; c <= 65535; c++) { @@ -203,12 +206,12 @@ private static void IncludeTest(Parser parser, Func isIncluded if (parser.TryParse(s, out var v)) { - Assert.That(isIncluded((char)c), Is.True); - Assert.That(v, Is.EqualTo((char)c)); + Assert.That(included((char)c), Is.True, $"Code: 0x{c:x4}"); + Assert.That(v, Is.EqualTo((char)c), $"Code: 0x{c:x4}"); } else { - Assert.That(isIncluded((char)c), Is.False); + Assert.That(included((char)c), Is.False, $"Code: 0x{c:x4}"); } } } diff --git a/tests/Ramstack.Parsing.Tests/Scenarios/JsonTests.cs b/tests/Ramstack.Parsing.Tests/Scenarios/JsonTests.cs index 32c761c..8d4cb26 100644 --- a/tests/Ramstack.Parsing.Tests/Scenarios/JsonTests.cs +++ b/tests/Ramstack.Parsing.Tests/Scenarios/JsonTests.cs @@ -10,9 +10,11 @@ public class JsonTests [Test] public void JsonParseTest() { + #if NET7_0_OR_GREATER var s1 = JsonSerializer.Serialize(JsonParser.Parser.Parse(Json).Value); var s2 = JsonSerializer.Serialize(JsonSerializer.Deserialize(Json)); Assert.That(s1, Is.EqualTo(s2)); + #endif } private const string Json = diff --git a/tests/Ramstack.Parsing.Tests/SimdConfigurationTests.cs b/tests/Ramstack.Parsing.Tests/SimdConfigurationTests.cs new file mode 100644 index 0000000..5306034 --- /dev/null +++ b/tests/Ramstack.Parsing.Tests/SimdConfigurationTests.cs @@ -0,0 +1,29 @@ +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.Arm; +using System.Runtime.Intrinsics.X86; + +namespace Ramstack.Parsing; + +[TestFixture] +public class SimdConfigurationTests +{ + [Test] + public void VerifySimdConfiguration() + { + if (Environment.GetEnvironmentVariable("DOTNET_EnableHWIntrinsic") == "0") + { + Assert.That(Sse2.IsSupported, Is.False); + Assert.That(Sse41.IsSupported, Is.False); + Assert.That(Avx2.IsSupported, Is.False); + Assert.That(AdvSimd.Arm64.IsSupported, Is.False); + Assert.That(AdvSimd.IsSupported, Is.False); + } + + if (RuntimeInformation.ProcessArchitecture == Architecture.X64 && Environment.GetEnvironmentVariable("DOTNET_EnableAVX2") == "0") + { + Assert.That(Sse2.IsSupported, Is.True); + Assert.That(Sse41.IsSupported, Is.True); + Assert.That(Avx2.IsSupported, Is.False); + } + } +}