param( [Parameter(Mandatory = $true)] [string]$ResultDirectory, [Parameter(Mandatory = $true)] [string]$RunId, [Parameter(Mandatory = $true)] [string]$Scale, [Parameter(Mandatory = $true)] [string]$Profiles ) $ErrorActionPreference = 'Stop' $result = [IO.Path]::GetFullPath((Join-Path (Get-Location) $ResultDirectory)) New-Item -ItemType Directory -Force -Path $result | Out-Null $cpu = (Get-ItemProperty 'HKLM:\HARDWARE\DESCRIPTION\System\CentralProcessor\0').ProcessorNameString $windows = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' $compilerFile = Get-ChildItem 'out\build\msvc-baseline\CMakeFiles' -Recurse ` -Filter 'CMakeCXXCompiler.cmake' -File | Select-Object -First 1 $compilerText = if ($compilerFile) { Get-Content -Raw $compilerFile.FullName } else { '' } $compilerVersion = if ($compilerText -match 'CMAKE_CXX_COMPILER_VERSION "([^"]+)"') { $Matches[1] } else { 'unknown' } $cache = Get-Content -Raw 'out\build\msvc-baseline\CMakeCache.txt' $cmakePath = if ($cache -match '(?m)^CMAKE_COMMAND:INTERNAL=(.+)$') { $Matches[1].Trim() } else { '' } $cmakeVersion = if ($cmakePath -and (Test-Path -LiteralPath $cmakePath)) { (& $cmakePath --version | Select-Object -First 1) } else { 'unknown' } $gitHead = try { (git rev-parse --verify HEAD 2>$null) } catch { '' } $gitDirty = try { @((git status --porcelain 2>$null)).Count } catch { -1 } $projectRoot = (Get-Location).Path $sourceManifestName = 'source-manifest.sha256' $binaryManifestName = 'binary-manifest.sha256' $metadata = [ordered]@{ run_id = $RunId timestamp = (Get-Date).ToString('o') scale = $Scale profiles = @($Profiles -split ' ' | Where-Object { $_ }) cpu = $cpu.Trim() logical_processors = [Environment]::ProcessorCount windows = "$($windows.ProductName) $($windows.DisplayVersion) build $($windows.CurrentBuildNumber)" power_plan = ((powercfg /getactivescheme) -join ' ').Trim() compiler = "MSVC $compilerVersion x64" cmake = $cmakeVersion release_runtime = '/MT static' ipo_lto = 'off' scalar_flags = '/O2 /d2Qvec- /Qvec-report:1 /Oi-, no /arch:AVX*' baseline_flags = '/O2, no /Qvec disable, no /arch:AVX*' avx2_flags = '/O2 /arch:AVX2' git_head = $gitHead git_dirty_entries = $gitDirty source_manifest = $sourceManifestName binary_manifest = $binaryManifestName } $metadata | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $result 'environment.json') -Encoding utf8 $metadata.GetEnumerator() | ForEach-Object { $value = if ($_.Value -is [array]) { $_.Value -join ',' } else { $_.Value } "$($_.Key)=$value" } | Set-Content -LiteralPath (Join-Path $result 'environment.txt') -Encoding utf8 # A manifest makes an uncommitted experimental run identifiable even before the # repository has its first HEAD. Results/out are intentionally excluded from # the source set; generated executables receive their own manifest. $sourceRoots = @( '.gitignore', 'CMakeLists.txt', 'CMakePresets.json', 'README.md', 'build.bat', 'benchmark.bat', 'include', 'src', 'tests', 'tools', 'docs' ) $sourceFiles = @() foreach ($entry in $sourceRoots) { if (Test-Path -LiteralPath $entry -PathType Leaf) { $sourceFiles += Get-Item -LiteralPath $entry } elseif (Test-Path -LiteralPath $entry -PathType Container) { $sourceFiles += Get-ChildItem -LiteralPath $entry -Recurse -File } } $sourceLines = @($sourceFiles | Sort-Object FullName -Unique | ForEach-Object { $relative = $_.FullName.Substring($projectRoot.Length).TrimStart('\') -replace '\\', '/' $hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() "$hash $relative" }) $sourceLines | Set-Content -LiteralPath (Join-Path $result $sourceManifestName) -Encoding ascii $binaryFiles = @() foreach ($profile in @($Profiles -split ' ' | Where-Object { $_ })) { $profileDirectory = Join-Path $projectRoot "out\bin\$profile\Release" if (Test-Path -LiteralPath $profileDirectory) { $binaryFiles += Get-ChildItem -LiteralPath $profileDirectory -File } } $binaryLines = @($binaryFiles | Sort-Object FullName -Unique | ForEach-Object { $relative = $_.FullName.Substring($projectRoot.Length).TrimStart('\') -replace '\\', '/' $hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() "$hash $relative" }) $binaryLines | Set-Content -LiteralPath (Join-Path $result $binaryManifestName) -Encoding ascii Write-Host "Wrote benchmark environment metadata to $result"