Initial commit
This commit is contained in:
464
llamacpp_remote_test.ps1
Normal file
464
llamacpp_remote_test.ps1
Normal file
@@ -0,0 +1,464 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Model,
|
||||
[string]$BaseUrl = "http://192.168.1.2:8071",
|
||||
[string]$PromptPath = "prompt_crwv.txt",
|
||||
[int]$Runs = 3,
|
||||
[int]$MaxTokens = 2000,
|
||||
[int]$NumCtx = 131072,
|
||||
[int]$TopK = 1,
|
||||
[double]$TopP = 1.0,
|
||||
[int]$Seed = 42,
|
||||
[double]$RepeatPenalty = 1.05,
|
||||
[double]$Temperature = 0,
|
||||
[string]$JsonSchema = "",
|
||||
[int]$TimeoutSec = 1800,
|
||||
[string]$BatchId,
|
||||
[switch]$EnableGpuMonitor = $true,
|
||||
[string]$SshExe = "$env:SystemRoot\\System32\\OpenSSH\\ssh.exe",
|
||||
[string]$SshUser = "rushabh",
|
||||
[string]$SshHost = "192.168.1.2",
|
||||
[int]$SshPort = 55555,
|
||||
[int]$GpuMonitorIntervalSec = 1,
|
||||
[int]$GpuMonitorSeconds = 120
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
function Normalize-Strike([object]$value) {
|
||||
if ($null -eq $value) { return $null }
|
||||
if ($value -is [double] -or $value -is [float] -or $value -is [int] -or $value -is [long]) {
|
||||
return ([double]$value).ToString("0.################", [System.Globalization.CultureInfo]::InvariantCulture)
|
||||
}
|
||||
return ($value.ToString().Trim())
|
||||
}
|
||||
|
||||
function Get-AllowedLegs([string]$promptText) {
|
||||
$pattern = 'Options Chain\s*```\s*(\[[\s\S]*?\])\s*```'
|
||||
$match = [regex]::Match($promptText, $pattern, [System.Text.RegularExpressions.RegexOptions]::Singleline)
|
||||
if (-not $match.Success) {
|
||||
throw "Options Chain JSON block not found in prompt."
|
||||
}
|
||||
$chains = $match.Groups[1].Value | ConvertFrom-Json
|
||||
$allowedExpiry = @{}
|
||||
$allowedLegs = @{}
|
||||
foreach ($exp in $chains) {
|
||||
$expiry = [string]$exp.expiry
|
||||
if ([string]::IsNullOrWhiteSpace($expiry)) { continue }
|
||||
$allowedExpiry[$expiry] = $true
|
||||
foreach ($leg in $exp.liquidSet) {
|
||||
if ($null -eq $leg) { continue }
|
||||
if ($leg.liquid -ne $true) { continue }
|
||||
$side = [string]$leg.side
|
||||
$strikeNorm = Normalize-Strike $leg.strike
|
||||
if (-not [string]::IsNullOrWhiteSpace($side) -and $strikeNorm) {
|
||||
$key = "$expiry|$side|$strikeNorm"
|
||||
$allowedLegs[$key] = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
return @{ AllowedExpiry = $allowedExpiry; AllowedLegs = $allowedLegs }
|
||||
}
|
||||
|
||||
function Test-TradeSchema($obj, $allowedExpiry, $allowedLegs) {
|
||||
$errors = New-Object System.Collections.Generic.List[string]
|
||||
|
||||
$requiredTop = @("selectedExpiry", "expiryRationale", "strategyBias", "recommendedTrades", "whyOthersRejected", "confidenceScore")
|
||||
foreach ($key in $requiredTop) {
|
||||
if (-not ($obj.PSObject.Properties.Name -contains $key)) {
|
||||
$errors.Add("Missing top-level key: $key")
|
||||
}
|
||||
}
|
||||
|
||||
if ($obj.strategyBias -and ($obj.strategyBias -notin @("DIRECTIONAL","VOLATILITY","NEUTRAL","NO_TRADE"))) {
|
||||
$errors.Add("Invalid strategyBias: $($obj.strategyBias)")
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace([string]$obj.selectedExpiry)) {
|
||||
if (-not $allowedExpiry.ContainsKey([string]$obj.selectedExpiry)) {
|
||||
$errors.Add("selectedExpiry not in provided expiries: $($obj.selectedExpiry)")
|
||||
}
|
||||
} else {
|
||||
$errors.Add("selectedExpiry is missing or empty")
|
||||
}
|
||||
|
||||
if ($obj.confidenceScore -ne $null) {
|
||||
if (-not ($obj.confidenceScore -is [double] -or $obj.confidenceScore -is [int])) {
|
||||
$errors.Add("confidenceScore is not numeric")
|
||||
} elseif ($obj.confidenceScore -lt 0 -or $obj.confidenceScore -gt 100) {
|
||||
$errors.Add("confidenceScore out of range 0-100")
|
||||
}
|
||||
}
|
||||
|
||||
if ($obj.recommendedTrades -eq $null) {
|
||||
$errors.Add("recommendedTrades is null")
|
||||
} elseif (-not ($obj.recommendedTrades -is [System.Collections.IEnumerable])) {
|
||||
$errors.Add("recommendedTrades is not an array")
|
||||
}
|
||||
|
||||
if ($obj.strategyBias -eq "NO_TRADE") {
|
||||
if ($obj.recommendedTrades -and $obj.recommendedTrades.Count -gt 0) {
|
||||
$errors.Add("strategyBias is NO_TRADE but recommendedTrades is not empty")
|
||||
}
|
||||
} else {
|
||||
if (-not $obj.recommendedTrades -or $obj.recommendedTrades.Count -lt 1 -or $obj.recommendedTrades.Count -gt 3) {
|
||||
$errors.Add("recommendedTrades must contain 1-3 trades")
|
||||
}
|
||||
}
|
||||
|
||||
if ($obj.whyOthersRejected -ne $null -and -not ($obj.whyOthersRejected -is [System.Collections.IEnumerable])) {
|
||||
$errors.Add("whyOthersRejected is not an array")
|
||||
}
|
||||
|
||||
if ($obj.recommendedTrades) {
|
||||
foreach ($trade in $obj.recommendedTrades) {
|
||||
$tradeRequired = @("name","structure","legs","greekProfile","maxRisk","maxReward","thesisAlignment","invalidation")
|
||||
foreach ($tkey in $tradeRequired) {
|
||||
if (-not ($trade.PSObject.Properties.Name -contains $tkey)) {
|
||||
$errors.Add("Trade missing key: $tkey")
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace([string]$trade.name)) { $errors.Add("Trade name is empty") }
|
||||
if ([string]::IsNullOrWhiteSpace([string]$trade.structure)) { $errors.Add("Trade structure is empty") }
|
||||
if ([string]::IsNullOrWhiteSpace([string]$trade.thesisAlignment)) { $errors.Add("Trade thesisAlignment is empty") }
|
||||
if ([string]::IsNullOrWhiteSpace([string]$trade.invalidation)) { $errors.Add("Trade invalidation is empty") }
|
||||
if ($trade.maxRisk -eq $null -or [string]::IsNullOrWhiteSpace([string]$trade.maxRisk)) { $errors.Add("Trade maxRisk is empty") }
|
||||
if ($trade.maxReward -eq $null -or [string]::IsNullOrWhiteSpace([string]$trade.maxReward)) { $errors.Add("Trade maxReward is empty") }
|
||||
if ($trade.maxRisk -is [double] -or $trade.maxRisk -is [int]) {
|
||||
if ($trade.maxRisk -le 0) { $errors.Add("Trade maxRisk must be > 0") }
|
||||
}
|
||||
if ($trade.maxReward -is [double] -or $trade.maxReward -is [int]) {
|
||||
if ($trade.maxReward -le 0) { $errors.Add("Trade maxReward must be > 0") }
|
||||
}
|
||||
|
||||
if (-not $trade.legs -or -not ($trade.legs -is [System.Collections.IEnumerable])) {
|
||||
$errors.Add("Trade legs missing or not an array")
|
||||
continue
|
||||
}
|
||||
|
||||
$legs = @($trade.legs)
|
||||
|
||||
$hasBuy = $false
|
||||
$hasSell = $false
|
||||
foreach ($leg in $trade.legs) {
|
||||
$side = ([string]$leg.side).ToLowerInvariant()
|
||||
$action = ([string]$leg.action).ToLowerInvariant()
|
||||
$expiry = [string]$leg.expiry
|
||||
$strikeNorm = Normalize-Strike $leg.strike
|
||||
|
||||
if ($side -notin @("call","put")) { $errors.Add("Invalid leg side: $side") }
|
||||
if ($action -notin @("buy","sell")) { $errors.Add("Invalid leg action: $action") }
|
||||
if (-not $allowedExpiry.ContainsKey($expiry)) { $errors.Add("Leg expiry not allowed: $expiry") }
|
||||
if (-not $strikeNorm) { $errors.Add("Leg strike missing") } else {
|
||||
$key = "$expiry|$side|$strikeNorm"
|
||||
if (-not $allowedLegs.ContainsKey($key)) {
|
||||
$errors.Add("Leg not in liquid set: $key")
|
||||
}
|
||||
}
|
||||
|
||||
if ($action -eq "buy") { $hasBuy = $true }
|
||||
if ($action -eq "sell") { $hasSell = $true }
|
||||
}
|
||||
|
||||
if ($obj.selectedExpiry -and $legs) {
|
||||
foreach ($leg in $legs) {
|
||||
if ([string]$leg.expiry -ne [string]$obj.selectedExpiry) {
|
||||
$errors.Add("Leg expiry does not match selectedExpiry: $($leg.expiry)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasSell -and -not $hasBuy) {
|
||||
$errors.Add("Naked short detected: trade has sell leg(s) with no buy leg")
|
||||
}
|
||||
|
||||
if ($trade.greekProfile) {
|
||||
$gp = $trade.greekProfile
|
||||
$gpRequired = @("deltaBias","gammaExposure","thetaExposure","vegaExposure")
|
||||
foreach ($gkey in $gpRequired) {
|
||||
if (-not ($gp.PSObject.Properties.Name -contains $gkey)) {
|
||||
$errors.Add("Missing greekProfile.$gkey")
|
||||
}
|
||||
}
|
||||
if ($gp.deltaBias -and ($gp.deltaBias -notin @("POS","NEG","NEUTRAL"))) { $errors.Add("Invalid deltaBias") }
|
||||
if ($gp.gammaExposure -and ($gp.gammaExposure -notin @("HIGH","MED","LOW"))) { $errors.Add("Invalid gammaExposure") }
|
||||
if ($gp.thetaExposure -and ($gp.thetaExposure -notin @("POS","NEG","LOW"))) { $errors.Add("Invalid thetaExposure") }
|
||||
if ($gp.vegaExposure -and ($gp.vegaExposure -notin @("HIGH","MED","LOW"))) { $errors.Add("Invalid vegaExposure") }
|
||||
|
||||
if (-not $hasSell -and $gp.thetaExposure -eq "POS") {
|
||||
$errors.Add("ThetaExposure POS on all-long legs")
|
||||
}
|
||||
} else {
|
||||
$errors.Add("Missing greekProfile")
|
||||
}
|
||||
|
||||
$structure = ([string]$trade.structure).ToLowerInvariant()
|
||||
$tradeName = ([string]$trade.name).ToLowerInvariant()
|
||||
$isStraddle = $structure -match "straddle" -or $tradeName -match "straddle"
|
||||
$isStrangle = $structure -match "strangle" -or $tradeName -match "strangle"
|
||||
$isCallDebit = ($structure -match "call") -and ($structure -match "debit") -and ($structure -match "spread")
|
||||
$isPutDebit = ($structure -match "put") -and ($structure -match "debit") -and ($structure -match "spread")
|
||||
|
||||
if ($isStraddle -or $isStrangle) {
|
||||
if ($legs.Count -ne 2) { $errors.Add("Straddle/Strangle must have exactly 2 legs") }
|
||||
$callLegs = $legs | Where-Object { $_.side -eq "call" }
|
||||
$putLegs = $legs | Where-Object { $_.side -eq "put" }
|
||||
if ($callLegs.Count -ne 1 -or $putLegs.Count -ne 1) { $errors.Add("Straddle/Strangle must have 1 call and 1 put") }
|
||||
if ($callLegs.Count -eq 1 -and $putLegs.Count -eq 1) {
|
||||
$callStrike = Normalize-Strike $callLegs[0].strike
|
||||
$putStrike = Normalize-Strike $putLegs[0].strike
|
||||
if ($isStraddle -and $callStrike -ne $putStrike) { $errors.Add("Straddle strikes must match") }
|
||||
if ($isStrangle) {
|
||||
try {
|
||||
if ([double]$callStrike -le [double]$putStrike) { $errors.Add("Strangle call strike must be above put strike") }
|
||||
} catch {
|
||||
$errors.Add("Strangle strike comparison failed")
|
||||
}
|
||||
}
|
||||
if ($callLegs[0].action -ne "buy" -or $putLegs[0].action -ne "buy") {
|
||||
$errors.Add("Straddle/Strangle must be long (buy) legs")
|
||||
}
|
||||
}
|
||||
if ($trade.greekProfile -and $trade.greekProfile.deltaBias -and $trade.greekProfile.deltaBias -ne "NEUTRAL") {
|
||||
$errors.Add("DeltaBias must be NEUTRAL for straddle/strangle")
|
||||
}
|
||||
}
|
||||
|
||||
if ($isCallDebit) {
|
||||
$callLegs = $legs | Where-Object { $_.side -eq "call" }
|
||||
if ($callLegs.Count -ne 2) { $errors.Add("Call debit spread must have 2 call legs") }
|
||||
$buy = $callLegs | Where-Object { $_.action -eq "buy" }
|
||||
$sell = $callLegs | Where-Object { $_.action -eq "sell" }
|
||||
if ($buy.Count -ne 1 -or $sell.Count -ne 1) { $errors.Add("Call debit spread must have 1 buy and 1 sell") }
|
||||
if ($buy.Count -eq 1 -and $sell.Count -eq 1) {
|
||||
try {
|
||||
if ([double](Normalize-Strike $buy[0].strike) -ge [double](Normalize-Strike $sell[0].strike)) {
|
||||
$errors.Add("Call debit spread buy strike must be below sell strike")
|
||||
}
|
||||
} catch {
|
||||
$errors.Add("Call debit spread strike comparison failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($isPutDebit) {
|
||||
$putLegs = $legs | Where-Object { $_.side -eq "put" }
|
||||
if ($putLegs.Count -ne 2) { $errors.Add("Put debit spread must have 2 put legs") }
|
||||
$buy = $putLegs | Where-Object { $_.action -eq "buy" }
|
||||
$sell = $putLegs | Where-Object { $_.action -eq "sell" }
|
||||
if ($buy.Count -ne 1 -or $sell.Count -ne 1) { $errors.Add("Put debit spread must have 1 buy and 1 sell") }
|
||||
if ($buy.Count -eq 1 -and $sell.Count -eq 1) {
|
||||
try {
|
||||
if ([double](Normalize-Strike $buy[0].strike) -le [double](Normalize-Strike $sell[0].strike)) {
|
||||
$errors.Add("Put debit spread buy strike must be above sell strike")
|
||||
}
|
||||
} catch {
|
||||
$errors.Add("Put debit spread strike comparison failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors
|
||||
}
|
||||
|
||||
function Parse-GpuLog {
|
||||
param([string]$Path)
|
||||
$summary = [ordered]@{ gpu0Used = $false; gpu1Used = $false; samples = 0; error = $null }
|
||||
if (-not (Test-Path $Path)) {
|
||||
$summary.error = "gpu log missing"
|
||||
return $summary
|
||||
}
|
||||
$lines = Get-Content -Path $Path
|
||||
$currentIndex = -1
|
||||
$gpuIndex = -1
|
||||
$inUtilBlock = $false
|
||||
foreach ($line in $lines) {
|
||||
if ($line -match '^Timestamp') {
|
||||
$gpuIndex = -1
|
||||
$currentIndex = -1
|
||||
$inUtilBlock = $false
|
||||
continue
|
||||
}
|
||||
if ($line -match '^GPU\\s+[0-9A-Fa-f:.]+$') {
|
||||
$gpuIndex += 1
|
||||
$currentIndex = $gpuIndex
|
||||
$inUtilBlock = $false
|
||||
continue
|
||||
}
|
||||
if ($line -match '^\\s*Utilization\\s*$') {
|
||||
$inUtilBlock = $true
|
||||
continue
|
||||
}
|
||||
if ($inUtilBlock -and $line -match '^\\s*GPU\\s*:\\s*([0-9]+)\\s*%') {
|
||||
$util = [int]$Matches[1]
|
||||
if ($currentIndex -eq 0 -and $util -gt 0) { $summary.gpu0Used = $true }
|
||||
if ($currentIndex -eq 1 -and $util -gt 0) { $summary.gpu1Used = $true }
|
||||
$summary.samples += 1
|
||||
}
|
||||
}
|
||||
return $summary
|
||||
}
|
||||
|
||||
$prompt = [string](Get-Content -Raw -Path $PromptPath)
|
||||
$allowed = Get-AllowedLegs -promptText $prompt
|
||||
$allowedExpiry = $allowed.AllowedExpiry
|
||||
$allowedLegs = $allowed.AllowedLegs
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($BatchId)) {
|
||||
$BatchId = (Get-Date).ToString("yyyyMMdd_HHmmss")
|
||||
}
|
||||
|
||||
$outBase = Join-Path -Path (Get-Location) -ChildPath "llamacpp_runs_remote"
|
||||
if (-not (Test-Path $outBase)) { New-Item -ItemType Directory -Path $outBase | Out-Null }
|
||||
|
||||
$safeModel = $Model -replace '[\\/:*?"<>|]', '_'
|
||||
$batchDir = Join-Path -Path $outBase -ChildPath ("batch_{0}" -f $BatchId)
|
||||
if (-not (Test-Path $batchDir)) { New-Item -ItemType Directory -Path $batchDir | Out-Null }
|
||||
|
||||
$outDir = Join-Path -Path $batchDir -ChildPath $safeModel
|
||||
if (-not (Test-Path $outDir)) { New-Item -ItemType Directory -Path $outDir | Out-Null }
|
||||
|
||||
$summary = [ordered]@{
|
||||
model = $Model
|
||||
baseUrl = $BaseUrl
|
||||
batchId = $BatchId
|
||||
params = [ordered]@{
|
||||
temperature = $Temperature
|
||||
top_k = $TopK
|
||||
top_p = $TopP
|
||||
seed = $Seed
|
||||
repeat_penalty = $RepeatPenalty
|
||||
max_tokens = $MaxTokens
|
||||
num_ctx = $NumCtx
|
||||
}
|
||||
gpuMonitor = [ordered]@{
|
||||
enabled = [bool]$EnableGpuMonitor
|
||||
sshHost = $SshHost
|
||||
sshPort = $SshPort
|
||||
intervalSec = $GpuMonitorIntervalSec
|
||||
durationSec = $GpuMonitorSeconds
|
||||
}
|
||||
modelMeta = $null
|
||||
runs = @()
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrWhiteSpace($JsonSchema)) {
|
||||
try {
|
||||
$schemaObject = $JsonSchema | ConvertFrom-Json
|
||||
} catch {
|
||||
throw "JsonSchema is not valid JSON: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$modelsResponse = Invoke-RestMethod -Uri "$BaseUrl/v1/models" -TimeoutSec 30
|
||||
$meta = $modelsResponse.data | Where-Object { $_.id -eq $Model } | Select-Object -First 1
|
||||
if ($meta) { $summary.modelMeta = $meta.meta }
|
||||
} catch {
|
||||
$summary.modelMeta = @{ error = $_.Exception.Message }
|
||||
}
|
||||
|
||||
for ($i = 1; $i -le $Runs; $i++) {
|
||||
Write-Host "Running $Model (run $i/$Runs)"
|
||||
|
||||
$runResult = [ordered]@{ run = $i; ok = $false; errors = @() }
|
||||
$gpuJob = $null
|
||||
$gpuLogPath = $null
|
||||
|
||||
if ($EnableGpuMonitor) {
|
||||
$samples = [math]::Max(5, [int]([math]::Ceiling($GpuMonitorSeconds / [double]$GpuMonitorIntervalSec)))
|
||||
$gpuLogPath = Join-Path $outDir ("gpu_run{0}.csv" -f $i)
|
||||
$sshTarget = "{0}@{1}" -f $SshUser, $SshHost
|
||||
$gpuJob = Start-Job -ScriptBlock {
|
||||
param($sshExe, $target, $port, $samples, $interval, $logPath)
|
||||
for ($s = 1; $s -le $samples; $s++) {
|
||||
Add-Content -Path $logPath -Value ("=== SAMPLE {0} {1}" -f $s, (Get-Date).ToString('s'))
|
||||
try {
|
||||
$out = & $sshExe -p $port $target "nvidia-smi -q -d UTILIZATION"
|
||||
Add-Content -Path $logPath -Value $out
|
||||
} catch {
|
||||
Add-Content -Path $logPath -Value ("GPU monitor error: $($_.Exception.Message)")
|
||||
}
|
||||
Start-Sleep -Seconds $interval
|
||||
}
|
||||
} -ArgumentList $SshExe, $sshTarget, $SshPort, $samples, $GpuMonitorIntervalSec, $gpuLogPath
|
||||
Start-Sleep -Seconds 1
|
||||
}
|
||||
|
||||
$body = @{
|
||||
model = $Model
|
||||
messages = @(@{ role = "user"; content = $prompt })
|
||||
temperature = $Temperature
|
||||
top_k = $TopK
|
||||
top_p = $TopP
|
||||
seed = $Seed
|
||||
repeat_penalty = $RepeatPenalty
|
||||
max_tokens = $MaxTokens
|
||||
}
|
||||
|
||||
if ($schemaObject) {
|
||||
$body.response_format = @{
|
||||
type = "json_schema"
|
||||
json_schema = @{
|
||||
name = "trade_schema"
|
||||
schema = $schemaObject
|
||||
strict = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$body = $body | ConvertTo-Json -Depth 12
|
||||
|
||||
try {
|
||||
$resp = Invoke-RestMethod -Uri "$BaseUrl/v1/chat/completions" -Method Post -Body $body -ContentType "application/json" -TimeoutSec $TimeoutSec
|
||||
} catch {
|
||||
$runResult.errors = @("API error: $($_.Exception.Message)")
|
||||
$summary.runs += $runResult
|
||||
if ($gpuJob) { Stop-Job -Job $gpuJob | Out-Null }
|
||||
continue
|
||||
} finally {
|
||||
if ($gpuJob) {
|
||||
Wait-Job -Job $gpuJob -Timeout 5 | Out-Null
|
||||
if ($gpuJob.State -eq "Running") { Stop-Job -Job $gpuJob | Out-Null }
|
||||
Remove-Job -Job $gpuJob | Out-Null
|
||||
}
|
||||
}
|
||||
|
||||
$raw = [string]$resp.choices[0].message.content
|
||||
|
||||
$jsonPath = Join-Path $outDir ("run{0}.json" -f $i)
|
||||
Set-Content -Path $jsonPath -Value $raw -Encoding ASCII
|
||||
|
||||
try {
|
||||
$parsed = $raw | ConvertFrom-Json
|
||||
$errors = Test-TradeSchema -obj $parsed -allowedExpiry $allowedExpiry -allowedLegs $allowedLegs
|
||||
if ($errors.Count -eq 0) {
|
||||
$runResult.ok = $true
|
||||
} else {
|
||||
$runResult.errors = $errors
|
||||
}
|
||||
} catch {
|
||||
$runResult.errors = @("Invalid JSON: $($_.Exception.Message)")
|
||||
}
|
||||
|
||||
if ($gpuLogPath) {
|
||||
$runResult.gpuLog = $gpuLogPath
|
||||
$runResult.gpuUsage = Parse-GpuLog -Path $gpuLogPath
|
||||
}
|
||||
if ($resp.timings) {
|
||||
$runResult.timings = $resp.timings
|
||||
}
|
||||
if ($resp.usage) {
|
||||
$runResult.usage = $resp.usage
|
||||
}
|
||||
|
||||
$summary.runs += $runResult
|
||||
}
|
||||
|
||||
$summaryPath = Join-Path $outDir "summary.json"
|
||||
$summary | ConvertTo-Json -Depth 6 | Set-Content -Path $summaryPath -Encoding ASCII
|
||||
|
||||
$summary | ConvertTo-Json -Depth 6
|
||||
Reference in New Issue
Block a user