@@ -87,6 +87,13 @@ public class Grid {
8787
8888 private static int diagnostic_level ;
8989
90+ /**
91+ * Get the index build time for a dataset
92+ */
93+ public static Double getIndexBuildTime (String datasetName ) {
94+ return indexBuildTimes .get (datasetName );
95+ }
96+
9097 static void runAll (DataSet ds ,
9198 List <Integer > mGrid ,
9299 List <Integer > efConstructionGrid ,
@@ -158,13 +165,21 @@ static void runOneGraph(List<? extends Set<FeatureId>> featureSets,
158165 DataSet ds ,
159166 Path testDirectory ) throws IOException
160167 {
168+ // Capture initial memory and disk state
169+ var diagnostics = new io .github .jbellis .jvector .example .benchmarks .diagnostics .BenchmarkDiagnostics (getDiagnosticLevel ());
170+ diagnostics .setMonitoredDirectory (testDirectory );
171+ diagnostics .capturePrePhaseSnapshot ("Graph Build" );
172+
161173 Map <Set <FeatureId >, ImmutableGraphIndex > indexes ;
162174 if (buildCompressor == null ) {
163175 indexes = buildInMemory (featureSets , M , efConstruction , neighborOverflow , addHierarchy , refineFinalGraph , ds , testDirectory );
164176 } else {
165177 indexes = buildOnDisk (featureSets , M , efConstruction , neighborOverflow , addHierarchy , refineFinalGraph , ds , testDirectory , buildCompressor );
166178 }
167179
180+ // Capture post-build memory and disk state
181+ diagnostics .capturePostPhaseSnapshot ("Graph Build" );
182+
168183 try {
169184 for (var cpSupplier : compressionGrid ) {
170185 indexes .forEach ((features , index ) -> {
@@ -188,7 +203,7 @@ static void runOneGraph(List<? extends Set<FeatureId>> featureSets,
188203 }
189204
190205 try (var cs = new ConfiguredSystem (ds , index , cv , featureSetForIndex )) {
191- testConfiguration (cs , topKGrid , usePruningGrid , M , efConstruction , neighborOverflow , addHierarchy , benchmarks );
206+ testConfiguration (cs , topKGrid , usePruningGrid , M , efConstruction , neighborOverflow , addHierarchy , benchmarks , testDirectory );
192207 } catch (Exception e ) {
193208 throw new RuntimeException (e );
194209 }
@@ -197,6 +212,11 @@ static void runOneGraph(List<? extends Set<FeatureId>> featureSets,
197212 for (var index : indexes .values ()) {
198213 index .close ();
199214 }
215+
216+ // Log final diagnostics summary
217+ if (diagnostic_level > 0 ) {
218+ diagnostics .logSummary ();
219+ }
200220 } finally {
201221 for (int n = 0 ; n < featureSets .size (); n ++) {
202222 Files .deleteIfExists (testDirectory .resolve ("graph" + n ));
@@ -432,13 +452,14 @@ private static void testConfiguration(ConfiguredSystem cs,
432452 int efConstruction ,
433453 float neighborOverflow ,
434454 boolean addHierarchy ,
435- Map <String , List <String >> benchmarkSpec ) {
455+ Map <String , List <String >> benchmarkSpec ,
456+ Path testDirectory ) {
436457 int queryRuns = 2 ;
437458 System .out .format ("Using %s:%n" , cs .index );
438459 // 1) Select benchmarks to run. Use .createDefault or .createEmpty (for other options)
439460
440461 var benchmarks = setupBenchmarks (benchmarkSpec );
441- QueryTester tester = new QueryTester (benchmarks );
462+ QueryTester tester = new QueryTester (benchmarks , testDirectory , cs . ds . name );
442463
443464 // 2) Setup benchmark table for printing
444465 for (var topK : topKGrid .keySet ()) {
@@ -563,11 +584,22 @@ public static List<BenchResult> runAllAndCollectResults(
563584 for (Function <DataSet , CompressorParameters > searchCompressor : compressionGrid ) {
564585 Path testDirectory = Files .createTempDirectory ("bench" );
565586 try {
587+ // Capture initial state
588+ var diagnostics = new io .github .jbellis .jvector .example .benchmarks .diagnostics .BenchmarkDiagnostics (getDiagnosticLevel ());
589+ diagnostics .setMonitoredDirectory (testDirectory );
590+ diagnostics .capturePrePhaseSnapshot ("Build" );
591+
566592 var compressor = getCompressor (buildCompressor , ds );
567593 var searchCompressorObj = getCompressor (searchCompressor , ds );
568594 CompressedVectors cvArg = (searchCompressorObj instanceof CompressedVectors ) ? (CompressedVectors ) searchCompressorObj : null ;
569595 var indexes = buildOnDisk (List .of (features ), m , ef , neighborOverflow , addHierarchy , false , ds , testDirectory , compressor );
570596 ImmutableGraphIndex index = indexes .get (features );
597+
598+ // Capture post-build state
599+ diagnostics .capturePostPhaseSnapshot ("Build" );
600+ var buildSnapshot = diagnostics .getLatestSystemSnapshot ();
601+ var buildDiskSnapshot = diagnostics .getLatestDiskSnapshot ();
602+
571603 try (ConfiguredSystem cs = new ConfiguredSystem (ds , index , cvArg , features )) {
572604 int queryRuns = 2 ;
573605 List <QueryBenchmark > benchmarks = List .of (
@@ -578,7 +610,7 @@ public static List<BenchResult> runAllAndCollectResults(
578610 CountBenchmark .createDefault (),
579611 AccuracyBenchmark .createDefault ()
580612 );
581- QueryTester tester = new QueryTester (benchmarks );
613+ QueryTester tester = new QueryTester (benchmarks , testDirectory , ds . name );
582614 for (int topK : topKGrid .keySet ()) {
583615 for (boolean usePruning : usePruningGrid ) {
584616 for (double overquery : topKGrid .get (topK )) {
@@ -596,11 +628,33 @@ public static List<BenchResult> runAllAndCollectResults(
596628 "overquery" , overquery ,
597629 "usePruning" , usePruning
598630 );
631+ // Collect all metrics including memory and disk usage
632+ Map <String , Object > allMetrics = new HashMap <>();
599633 for (Metric metric : metricsList ) {
600- Map <String , Object > metrics = java .util .Map .of (metric .getHeader (), metric .getValue ());
601- results .add (new BenchResult (ds .name , params , metrics ));
634+ allMetrics .put (metric .getHeader (), metric .getValue ());
635+ }
636+
637+ // Add build time if available
638+ if (indexBuildTimes .containsKey (ds .name )) {
639+ allMetrics .put ("Index Build Time" , indexBuildTimes .get (ds .name ));
640+ }
641+
642+ // Add memory metrics if available
643+ if (buildSnapshot != null ) {
644+ allMetrics .put ("Heap Memory Used (MB)" , buildSnapshot .memoryStats .heapUsed / 1024.0 / 1024.0 );
645+ allMetrics .put ("Heap Memory Max (MB)" , buildSnapshot .memoryStats .heapMax / 1024.0 / 1024.0 );
646+ allMetrics .put ("Off-Heap Direct (MB)" , buildSnapshot .memoryStats .directBufferMemory / 1024.0 / 1024.0 );
647+ allMetrics .put ("Off-Heap Mapped (MB)" , buildSnapshot .memoryStats .mappedBufferMemory / 1024.0 / 1024.0 );
648+ allMetrics .put ("Total Off-Heap (MB)" , buildSnapshot .memoryStats .getTotalOffHeapMemory () / 1024.0 / 1024.0 );
649+ }
650+
651+ // Add disk metrics if available
652+ if (buildDiskSnapshot != null ) {
653+ allMetrics .put ("Disk Usage (MB)" , buildDiskSnapshot .totalBytes / 1024.0 / 1024.0 );
654+ allMetrics .put ("File Count" , buildDiskSnapshot .fileCount );
602655 }
603- results .add (new BenchResult (ds .name , params , Map .of ("Index Build Time" , indexBuildTimes .get (ds .name ))));
656+
657+ results .add (new BenchResult (ds .name , params , allMetrics ));
604658 }
605659 }
606660 }
0 commit comments