Skip to content

Commit 2c55a96

Browse files
authored
Merge pull request #16 from rameel/ci-simd-testing
Fix a logic error in ARM64 SIMD range comparison and enhance CI workflow to test SIMD optimizations
2 parents 9a01c06 + 5fa31a3 commit 2c55a96

6 files changed

Lines changed: 86 additions & 15 deletions

File tree

.github/workflows/test.yml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ on:
66

77
jobs:
88
build-and-test:
9-
name: "Test projects"
10-
runs-on: ubuntu-latest
9+
name: build-and-test-${{ matrix.os }}
10+
runs-on: ${{ matrix.os }}
11+
strategy:
12+
matrix:
13+
os: [ubuntu-latest, ubuntu-24.04-arm]
14+
1115
steps:
1216
- name: Install .NET
1317
uses: actions/setup-dotnet@v4
@@ -21,8 +25,34 @@ jobs:
2125
- name: Checkout
2226
uses: actions/checkout@v4
2327

24-
- name: Test Projects (Debug)
25-
run: dotnet test -c Debug
28+
- name: Build (Debug)
29+
run: dotnet build -c Debug
30+
31+
- name: Build (Release)
32+
run: dotnet build -c Release
33+
34+
- name: Test (Debug)
35+
run: dotnet test -c Debug --no-build
36+
37+
- name: Test (Release)
38+
run: dotnet test -c Release --no-build
39+
40+
- name: Test (Debug, AVX2=0)
41+
env:
42+
DOTNET_EnableAVX2: "0"
43+
run: dotnet test -c Debug --no-build
44+
45+
- name: Test (Release, AVX2=0)
46+
env:
47+
DOTNET_EnableAVX2: "0"
48+
run: dotnet test -c Release --no-build
49+
50+
- name: Test (Debug, HWIntrinsic=0)
51+
env:
52+
DOTNET_EnableHWIntrinsic: "0"
53+
run: dotnet test -c Debug --no-build
2654

27-
- name: Test Projects (Release)
28-
run: dotnet test -c Release
55+
- name: Test (Release, HWIntrinsic=0)
56+
env:
57+
DOTNET_EnableHWIntrinsic: "0"
58+
run: dotnet test -c Release --no-build

src/Ramstack.Parsing/Parser.Set.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,13 @@ private static bool ContainsCore(char ch, ushort[] ranges)
624624
}
625625
else
626626
{
627-
var v = AdvSimd.CompareLessThanOrEqual(
628-
AdvSimd.Subtract(c, x),
629-
y);
627+
// var v = AdvSimd.CompareEqual(
628+
// AdvSimd.Min(AdvSimd.Max(c, x), y),
629+
// c);
630+
631+
var v = AdvSimd.And(
632+
AdvSimd.CompareGreaterThanOrEqual(c, x),
633+
AdvSimd.CompareLessThanOrEqual(c, y));
630634

631635
if (!v.Equals(Vector128<ushort>.Zero))
632636
return true;

tests/Ramstack.Parsing.Tests/ParsersTests.Repeat_Opt.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ public void Repeat_ContainsSearcher()
211211
var parser = Set(set.ToString()).Many();
212212
var p = parser.Text();
213213

214-
Assert.That(parser.GetType().ToString(), Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+ContainsSearcher]"));
214+
Assert.That(parser.GetType().ToString(),
215+
Avx2.IsSupported
216+
? Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+ContainsSearcher]")
217+
: Is.EqualTo("Ramstack.Parsing.Parser+RepeatCharClassParser`1[Ramstack.Parsing.Parser+BinaryRangeSearcher]"));
215218

216219
var s = chars.ToString();
217220
var r = string.Join("", s.Reverse());

tests/Ramstack.Parsing.Tests/ParsersTests.Set_Opt.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ public void Set_MultipleRanges_ContainsSearch()
122122

123123
var parser = Set(sb.ToString());
124124

125-
Assert.That(parser.GetType().ToString(), Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+ContainsSearcher]"));
125+
Assert.That(parser.GetType().ToString(),
126+
Avx2.IsSupported
127+
? Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+ContainsSearcher]")
128+
: Is.EqualTo("Ramstack.Parsing.Parser+RangeParser`2[System.Char,Ramstack.Parsing.Parser+BinaryRangeSearcher]"));
126129
IncludeTest(parser, c => c < 128*5 && c % 5 == 0);
127130
}
128131

@@ -195,20 +198,20 @@ public void Set_MultipleRanges_BinarySearch()
195198
IncludeTest(parser, c => c < 10240 && c % 2 == 0);
196199
}
197200

198-
private static void IncludeTest(Parser<char> parser, Func<char, bool> isIncluded)
201+
private static void IncludeTest(Parser<char> parser, Func<char, bool> included)
199202
{
200203
for (var c = 0; c <= 65535; c++)
201204
{
202205
var s = new string((char)c, 1);
203206

204207
if (parser.TryParse(s, out var v))
205208
{
206-
Assert.That(isIncluded((char)c), Is.True);
207-
Assert.That(v, Is.EqualTo((char)c));
209+
Assert.That(included((char)c), Is.True, $"Code: 0x{c:x4}");
210+
Assert.That(v, Is.EqualTo((char)c), $"Code: 0x{c:x4}");
208211
}
209212
else
210213
{
211-
Assert.That(isIncluded((char)c), Is.False);
214+
Assert.That(included((char)c), Is.False, $"Code: 0x{c:x4}");
212215
}
213216
}
214217
}

tests/Ramstack.Parsing.Tests/Scenarios/JsonTests.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ public class JsonTests
1010
[Test]
1111
public void JsonParseTest()
1212
{
13+
#if NET7_0_OR_GREATER
1314
var s1 = JsonSerializer.Serialize(JsonParser.Parser.Parse(Json).Value);
1415
var s2 = JsonSerializer.Serialize(JsonSerializer.Deserialize<object>(Json));
1516
Assert.That(s1, Is.EqualTo(s2));
17+
#endif
1618
}
1719

1820
private const string Json =
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Runtime.InteropServices;
2+
using System.Runtime.Intrinsics.Arm;
3+
using System.Runtime.Intrinsics.X86;
4+
5+
namespace Ramstack.Parsing;
6+
7+
[TestFixture]
8+
public class SimdConfigurationTests
9+
{
10+
[Test]
11+
public void VerifySimdConfiguration()
12+
{
13+
if (Environment.GetEnvironmentVariable("DOTNET_EnableHWIntrinsic") == "0")
14+
{
15+
Assert.That(Sse2.IsSupported, Is.False);
16+
Assert.That(Sse41.IsSupported, Is.False);
17+
Assert.That(Avx2.IsSupported, Is.False);
18+
Assert.That(AdvSimd.Arm64.IsSupported, Is.False);
19+
Assert.That(AdvSimd.IsSupported, Is.False);
20+
}
21+
22+
if (RuntimeInformation.ProcessArchitecture == Architecture.X64 && Environment.GetEnvironmentVariable("DOTNET_EnableAVX2") == "0")
23+
{
24+
Assert.That(Sse2.IsSupported, Is.True);
25+
Assert.That(Sse41.IsSupported, Is.True);
26+
Assert.That(Avx2.IsSupported, Is.False);
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)