Major namespace migration from SPMD to HPC across all code, templates, and projects. Introduced Misaki.HighPerformance.HPC.Generator with Roslyn-based source generators for SIMD code (e.g., AVX2), including attribute and method generators. Renamed MultipleAdd to MultiplyAdd in all lanes and updated usages. Added AVX2 utility methods via codegen. Updated tests, benchmarks, and project references to use the new framework. Improved SIMD memory utilities and modernized project files. Removed legacy SPMD project from the solution.
115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using Misaki.HighPerformance.HPC;
|
|
using System.Numerics;
|
|
using System.Runtime.Intrinsics.X86;
|
|
|
|
namespace Misaki.HighPerformance.Test.UnitTest.Jobs;
|
|
|
|
public static class CompressStoreTest
|
|
{
|
|
public static void Run()
|
|
{
|
|
Console.WriteLine("--- Testing CompressStore (Double) ---");
|
|
|
|
// Test 1: Simple Pattern (True, False, True, False...)
|
|
TestPattern_Double(
|
|
input: new double[] { 1, 2, 3, 4, 5, 6, 7, 8 },
|
|
// Mask: Keep only even numbers (values > 0)
|
|
// We simulate a mask by comparing against 0 or -1
|
|
keepPattern: new bool[] { true, false, true, false, true, false, true, false }
|
|
);
|
|
|
|
// Test 2: All True
|
|
TestPattern_Double(
|
|
input: new double[] { 10, 20, 30, 40, 50, 60, 70, 80 },
|
|
keepPattern: new bool[] { true, true, true, true, true, true, true, true }
|
|
);
|
|
|
|
// Test 3: All False
|
|
TestPattern_Double(
|
|
input: new double[] { 10, 20, 30, 40, 50, 60, 70, 80 },
|
|
keepPattern: new bool[] { false, false, false, false, false, false, false, false }
|
|
);
|
|
|
|
// Test 4: Sparse (First and Last only)
|
|
TestPattern_Double(
|
|
input: new double[] { 1, 2, 3, 4, 5, 6, 7, 8 },
|
|
keepPattern: new bool[] { true, false, false, false, false, false, false, true }
|
|
);
|
|
}
|
|
|
|
private static unsafe void TestPattern_Double(double[] input, bool[] keepPattern)
|
|
{
|
|
// 1. Setup Input Vector
|
|
// Handle case where Vector<TLane> is smaller than 8 (e.g. 2 or 4)
|
|
var vecSize = Vector<double>.Count;
|
|
var safeInput = new double[vecSize];
|
|
var safeMaskVal = new double[vecSize];
|
|
|
|
// Expected Output Calculation
|
|
var expected = new double[vecSize];
|
|
var expectedCount = 0;
|
|
|
|
for (var i = 0; i < vecSize; i++)
|
|
{
|
|
safeInput[i] = input[i];
|
|
// If we want to keep it, make mask "GreaterThan" true
|
|
// We'll compare X > 0.
|
|
// If keep=true, val=1. If keep=false, val=-1.
|
|
safeMaskVal[i] = keepPattern[i] ? 1 : -1;
|
|
|
|
if (keepPattern[i])
|
|
{
|
|
expected[expectedCount++] = input[i];
|
|
}
|
|
}
|
|
|
|
// 2. Create WideLanes
|
|
var vInput = WideLane<double>.Load(ref safeInput.AsSpan().GetPinnableReference());
|
|
|
|
// Create Mask: greater than 0
|
|
var vMaskVal = WideLane<double>.Load(ref safeMaskVal.AsSpan().GetPinnableReference());
|
|
var vZero = WideLane<double>.Create(0);
|
|
var vMask = WideLane<double>.GreaterThan(vMaskVal, vZero);
|
|
|
|
// 3. Run CompressStore
|
|
var outputBuffer = new double[vecSize];
|
|
var actualCount = 0;
|
|
|
|
fixed (double* ptr = outputBuffer)
|
|
{
|
|
actualCount = vInput.CompressStore(ptr, vMask);
|
|
}
|
|
|
|
// 4. Verify
|
|
var pass = actualCount == expectedCount;
|
|
for (var i = 0; i < expectedCount; i++)
|
|
{
|
|
if (outputBuffer[i] != expected[i])
|
|
pass = false;
|
|
}
|
|
|
|
// 5. Report
|
|
var hardware = (vecSize == 4) ? "AVX2 (256-bit)" : (vecSize == 2) ? "SSE/NEON (128-bit)" : "Scalar";
|
|
Console.Write($"[{hardware}] Pattern: ");
|
|
for (var i = 0; i < vecSize; i++)
|
|
Console.Write(keepPattern[i] ? "1" : "0");
|
|
|
|
if (pass)
|
|
{
|
|
Console.WriteLine($" -> PASS (Count: {actualCount})");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($" -> FAIL!");
|
|
Console.WriteLine($" Expected Count: {expectedCount}, Actual: {actualCount}");
|
|
Console.Write(" Expected Data: ");
|
|
foreach (var d in expected)
|
|
Console.Write($"{d} ");
|
|
Console.WriteLine();
|
|
Console.Write(" Actual Data: ");
|
|
foreach (var d in outputBuffer)
|
|
Console.Write($"{d} ");
|
|
Console.WriteLine();
|
|
}
|
|
}
|
|
} |