73 lines
3.7 KiB
PowerShell
73 lines
3.7 KiB
PowerShell
[CmdletBinding()]
|
|
param(
|
|
[string]$BuildDirectory = (Join-Path $PSScriptRoot '..\build-msvc'),
|
|
[double]$Tolerance = 0.01,
|
|
[switch]$ShowAllDifferences
|
|
)
|
|
|
|
$cppRunner = Join-Path $BuildDirectory 'fluidsim_parity_trace.exe'
|
|
$csProject = Join-Path $PSScriptRoot 'CSharpParityTrace.csproj'
|
|
if (-not (Test-Path -LiteralPath $cppRunner)) { throw "C++ trace runner not found: $cppRunner" }
|
|
|
|
$cppText = & $cppRunner
|
|
if ($LASTEXITCODE -ne 0) { throw "C++ trace runner failed with exit code $LASTEXITCODE." }
|
|
$csText = & dotnet run --project $csProject --configuration Release --no-launch-profile --verbosity quiet
|
|
if ($LASTEXITCODE -ne 0) { throw "C# reference trace failed with exit code $LASTEXITCODE." }
|
|
|
|
$cppRows = @($cppText | Where-Object { $_ -match '^(step,|\d+,)' } | ConvertFrom-Csv)
|
|
$csRows = @($csText | Where-Object { $_ -match '^(step,|\d+,)' } | ConvertFrom-Csv)
|
|
if ($cppRows.Count -ne $csRows.Count) { throw "Checkpoint count differs: C++=$($cppRows.Count), C#=$($csRows.Count)." }
|
|
|
|
$columns = @('rpm', 'angle', 'cylinder1_pa', 'cylinder2_pa', 'intake_pa', 'exhaust_pa', 'speed_kmh',
|
|
'valve1_in', 'valve2_in', 'intake_flow', 'exhaust_flow', 'pipe0_left_pa', 'pipe0_right_pa',
|
|
'pipe1_left_pa', 'pipe1_right_pa', 'pipe2_left_pa', 'pipe2_right_pa',
|
|
'pipe3_left_pa', 'pipe3_right_pa', 'pipe4_left_pa', 'pipe4_right_pa',
|
|
'throttle_port_flow', 'runner1_port_flow', 'runner2_port_flow',
|
|
'cyl1_intake_flow', 'cyl2_intake_flow', 'cyl1_exhaust_flow', 'cyl2_exhaust_flow',
|
|
'pipe0_right_rho', 'pipe0_right_u', 'pipe1_left_rho', 'pipe1_left_u', 'pipe1_right_rho', 'pipe1_right_u',
|
|
'pipe2_left_rho', 'pipe2_left_u', 'pipe2_right_rho', 'pipe2_right_u',
|
|
'intake_rho', 'intake_temperature', 'pipe0_left_rho', 'pipe0_left_u')
|
|
$largestDifference = 0.0
|
|
$largestField = ''
|
|
$largestStep = 0
|
|
$differences = [System.Collections.Generic.List[object]]::new()
|
|
for ($rowIndex = 0; $rowIndex -lt $cppRows.Count; ++$rowIndex) {
|
|
if ($cppRows[$rowIndex].step -ne $csRows[$rowIndex].step) { throw 'Checkpoint steps differ.' }
|
|
foreach ($column in $columns) {
|
|
$cppValue = [double]::Parse($cppRows[$rowIndex].$column, [Globalization.CultureInfo]::InvariantCulture)
|
|
$csValue = [double]::Parse($csRows[$rowIndex].$column, [Globalization.CultureInfo]::InvariantCulture)
|
|
$difference = [Math]::Abs($cppValue - $csValue)
|
|
$scale = [Math]::Max(1.0, [Math]::Abs($csValue))
|
|
$relativeDifference = $difference / $scale
|
|
if ($relativeDifference -gt $largestDifference) {
|
|
$largestDifference = $relativeDifference
|
|
$largestField = $column
|
|
$largestStep = [int]$cppRows[$rowIndex].step
|
|
}
|
|
if ($relativeDifference -gt 0.0) {
|
|
$differences.Add([pscustomobject]@{
|
|
Step = [int]$cppRows[$rowIndex].step
|
|
Field = $column
|
|
CSharp = $csValue
|
|
Cpp = $cppValue
|
|
RelativeDifference = $relativeDifference
|
|
})
|
|
}
|
|
if ($ShowAllDifferences) {
|
|
"step={0} {1}: C#={2:G9}, C++={3:G9}, rel={4:G6}" -f `
|
|
$cppRows[$rowIndex].step, $column, $csValue, $cppValue, $relativeDifference
|
|
}
|
|
}
|
|
}
|
|
|
|
"Compared {0} checkpoints across {1} fields; tolerance {2:G6}." -f $cppRows.Count, $columns.Count, $Tolerance
|
|
"Largest relative difference: {0:G6} in {1} at step {2}." -f $largestDifference, $largestField, $largestStep
|
|
if ($largestDifference -gt $Tolerance) {
|
|
'Largest remaining differences:'
|
|
$differences | Sort-Object RelativeDifference -Descending | Select-Object -First 10 | ForEach-Object {
|
|
" step={0} {1}: C#={2:G9}, C++={3:G9}, rel={4:G6}" -f `
|
|
$_.Step, $_.Field, $_.CSharp, $_.Cpp, $_.RelativeDifference
|
|
}
|
|
}
|
|
if ($largestDifference -gt $Tolerance) { exit 1 }
|