@@ -30,10 +30,12 @@ use std::{
3030 borrow:: Cow ,
3131 cell:: RefCell ,
3232 fmt:: Write as _,
33+ fs:: OpenOptions ,
3334 io:: { self , Write } ,
3435 mem:: { replace, size_of, take} ,
3536 num:: { NonZeroU8 , NonZeroUsize } ,
3637 ops:: { Add , Neg } ,
38+ path:: Path ,
3739 rc:: Rc ,
3840 sync:: { Arc , Mutex } ,
3941 thread,
@@ -43,6 +45,9 @@ use std::{
4345#[ global_allocator]
4446static ALLOC : MiMalloc = MiMalloc ;
4547
48+ // If you change this, also adjust `scripts/ci.bash`:
49+ const LDBC_RESULT_CSV : & str = "ldbc_results.csv" ;
50+
4651enum OutputData {
4752 None ,
4853 Bfs ( DistanceSet < i8 > ) ,
@@ -238,6 +243,30 @@ fn main() {
238243 let kevps = evps / 1000.0 ;
239244 println ! ( "achieved {kevps:.02} kEVPS ({evps:.02} EVPS)" ) ;
240245
246+ if config. output_csv {
247+ let results_file_already_exists = Path :: new ( LDBC_RESULT_CSV ) . is_file ( ) ;
248+ // If the file exists, we append another row, this is different
249+ // from other benchmarks that can run everything with a single
250+ // invocation:
251+ let file = OpenOptions :: new ( )
252+ . write ( true )
253+ . append ( results_file_already_exists)
254+ . create ( !results_file_already_exists)
255+ . open ( LDBC_RESULT_CSV )
256+ . expect ( "failed to open results csv file for writing" ) ;
257+ let mut csv_writer = csv:: Writer :: from_writer ( file) ;
258+
259+ if !results_file_already_exists {
260+ // Write a header row if the file is newly created
261+ csv_writer
262+ . write_record ( & [ "name" , "algorithm" , "dataset" , "threads" , "elapsed" , "elements" , "evps" ] )
263+ . expect ( "failed to write csv header" ) ;
264+ }
265+ csv_writer
266+ . write_record ( & [ "ldbc" , args. algorithm ( ) , config. dataset . name , threads. get ( ) . to_string ( ) . as_str ( ) , elapsed. as_secs_f64 ( ) . to_string ( ) . as_str ( ) , elements. to_string ( ) . as_str ( ) , evps. to_string ( ) . as_str ( ) ] )
267+ . expect ( "failed to write csv record" ) ;
268+ }
269+
241270 let output = replace ( & mut * output. borrow_mut ( ) , OutputData :: None ) ;
242271 match output {
243272 OutputData :: None => println ! ( "no output was produced" ) ,
@@ -428,6 +457,14 @@ impl Args {
428457 | Self :: ListDatasets { config } => config,
429458 }
430459 }
460+
461+ fn algorithm ( & self ) -> & str {
462+ match Self :: parse ( ) {
463+ Self :: Bfs { .. } => "bfs" ,
464+ Self :: Pagerank { .. } => "pagerank" ,
465+ _ => unreachable ! ( ) ,
466+ }
467+ }
431468}
432469
433470#[ derive( Debug , Clone , Copy , Parser ) ]
@@ -449,6 +486,10 @@ struct Config {
449486 #[ clap( long, default_value = "5" ) ]
450487 iters : NonZeroU8 ,
451488
489+ /// Store results in a csv file in addition to printing on the command-line.
490+ #[ clap( long = "csv" , env = "DBSP_RESULTS_AS_CSV" ) ]
491+ output_csv : bool ,
492+
452493 // When running with `cargo bench` the binary gets the `--bench` flag, so we
453494 // have to parse and ignore it so clap doesn't get angry
454495 #[ doc( hidden) ]
0 commit comments