feat(benchmark): build jobs from DXF manifests and run solves in parallel
Benchmark jobs could only come from .nest files. A JSON manifest now lists DXF files with quantities (plus sheet sizes, spacing, edge spacing, quadrant and per-part allowRotation), imported through CadImporter. DXF paths resolve relative to the manifest; sheet sizes are required from the manifest or --sheet-sizes and are read in the DXFs' own units. Folder scans pick up *.nest and *.manifest.json, and invalid manifests fail loudly. BenchmarkRunner now runs (job x engine) solves concurrently, capped by --parallel N (CLI default 3; --parallel 1 is sequential). Results are written by index so report order is unchanged. Concurrent solves compete for cores, so Time(ms) is only clean at --parallel 1; the run prints a note when N > 1. Also fixes --output for manifest jobs, which tried to read the manifest as a .nest to copy metadata from. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,7 +38,7 @@ static class BenchmarkConsole
|
||||
if (jobs.Count == 0)
|
||||
{
|
||||
Console.Error.WriteLine(
|
||||
"No benchmark jobs found (no .nest files with any drawing quantity > 0)."
|
||||
"No benchmark jobs found (no .nest files with any drawing quantity > 0, or *.manifest.json files)."
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
@@ -83,12 +83,23 @@ static class BenchmarkConsole
|
||||
|
||||
Console.WriteLine($"Engines: {string.Join(", ", engines.Select(e => e.Name))}");
|
||||
|
||||
var solves = jobs.Count * engines.Count;
|
||||
|
||||
if (options.Parallel > 1 && solves > 1)
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"Running up to {options.Parallel} solves at a time; Time(ms) is measured under that "
|
||||
+ "concurrent load. Use --parallel 1 for strictly isolated timings."
|
||||
);
|
||||
}
|
||||
|
||||
var results = BenchmarkRunner.Run(
|
||||
jobs,
|
||||
engines,
|
||||
options.SalvageRate,
|
||||
options.MinimumSalvageDimension,
|
||||
options.OutputDirectory
|
||||
options.OutputDirectory,
|
||||
options.Parallel
|
||||
);
|
||||
|
||||
Report.PrintDetailed(results);
|
||||
@@ -149,6 +160,15 @@ static class BenchmarkConsole
|
||||
o.OutputDirectory = args[++i];
|
||||
break;
|
||||
|
||||
case "--parallel" when i + 1 < args.Length:
|
||||
if (int.TryParse(args[++i], out var parallel) && parallel >= 1)
|
||||
o.Parallel = parallel;
|
||||
else
|
||||
Console.Error.WriteLine(
|
||||
$"Warning: --parallel needs a whole number >= 1, using {o.Parallel}"
|
||||
);
|
||||
break;
|
||||
|
||||
case "--help":
|
||||
PrintUsage();
|
||||
return null;
|
||||
@@ -215,7 +235,25 @@ static class BenchmarkConsole
|
||||
);
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine("Usage:");
|
||||
Console.Error.WriteLine(" OpenNest.Benchmark <file.nest | folder> [options]");
|
||||
Console.Error.WriteLine(
|
||||
" OpenNest.Benchmark <file.nest | manifest.json | folder> [options]"
|
||||
);
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine(
|
||||
"A manifest.json builds a job straight from DXF files (paths relative to the manifest):"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
" { \"sheetSizes\": [\"48x96\"], \"spacing\": 0.25, \"edgeSpacing\": 0.25, \"quadrant\": 1,"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
" \"parts\": [ { \"dxf\": \"a.dxf\", \"quantity\": 12 }, { \"dxf\": \"b.dxf\", \"quantity\": 4, \"allowRotation\": false } ] }"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
"Sheet sizes must use the same units as the DXFs. A folder is scanned for *.nest and"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
"*.manifest.json files. --sheet-sizes and --spacing override the manifest."
|
||||
);
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine("Options:");
|
||||
Console.Error.WriteLine(
|
||||
@@ -242,6 +280,12 @@ static class BenchmarkConsole
|
||||
Console.Error.WriteLine(
|
||||
" --output <directory> Save valid layouts as .nest plus detailed JSON reports"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
" --parallel <n> Solves to run at once (default 3; 1 = strictly sequential,"
|
||||
);
|
||||
Console.Error.WriteLine(
|
||||
" which gives the cleanest per-engine timings)"
|
||||
);
|
||||
Console.Error.WriteLine(" --help Show this message");
|
||||
}
|
||||
|
||||
@@ -255,5 +299,6 @@ static class BenchmarkConsole
|
||||
public string OutputDirectory;
|
||||
public double SalvageRate;
|
||||
public double MinimumSalvageDimension;
|
||||
public int Parallel = 3;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user