@@ -36,7 +36,6 @@ void report_largest(const CellResult& cell, std::size_t top_n,
3636 rec->label , rec->spaces , mb (rec->memory , bytes_per_elem),
3737 rec->uses , full_expr (*node), rec->flops .text ());
3838 }
39- out << " \n " ;
4039}
4140
4241void report_expensive (const CellResult& cell, std::size_t top_n,
@@ -59,7 +58,6 @@ void report_expensive(const CellResult& cell, std::size_t top_n,
5958 rec->spaces , rec->uses , full_expr (*node),
6059 rec->flops .text ());
6160 }
62- out << " \n " ;
6361}
6462
6563void report_shape_histogram (const CellResult& cell, double bytes_per_elem,
@@ -92,7 +90,6 @@ void report_shape_histogram(const CellResult& cell, double bytes_per_elem,
9290 for (const auto & [shape, g] : rows)
9391 out << std::format (" | {} | {:.4f} | {} | {} |\n " , shape,
9492 mb (g.mem , bytes_per_elem), g.count , g.uses );
95- out << " \n " ;
9693}
9794
9895} // namespace
@@ -109,37 +106,40 @@ void write_report(
109106 const std::vector<std::pair<std::string, CellResult>>& results,
110107 const SimResult& sim, std::ostream& out) {
111108 const double bytes_per_elem = cfg.real_field ? 8.0 : 16.0 ;
112- out << " # SeQuant cost analysis\n\n "
113- << std::format (" _SeQuant: {}_\n\n " , git_revision ())
114- << std::format (" Sizes in MB ({} bytes/element).\n\n " , bytes_per_elem);
109+ // Sections are separated by a leading blank line rather than a trailing one,
110+ // so the report ends with a single newline (matches the committed fixtures).
111+ out << " # SeQuant cost analysis\n " ;
112+ if (!cfg.out .omit_revision )
113+ out << std::format (" \n _SeQuant: {}_\n " , git_revision ());
114+ out << std::format (" \n Sizes in MB ({} bytes/element).\n " , bytes_per_elem);
115115 for (const auto & [name, cell] : results) {
116- out << std::format (" ## {}\n \n" , name);
116+ out << std::format (" \n ## {}\n " , name);
117117 out << std::format (
118- " Terms : {}; distinct intermediates: {}; reused: {}; largest: {:.4f} "
119- " MB; peak storage: {:.4f} MB.\n\n " ,
118+ " \n Terms : {}; distinct intermediates: {}; reused: {}; largest: {:.4f} "
119+ " MB; peak storage: {:.4f} MB.\n " ,
120120 cell.n_terms , cell.n_distinct , cell.n_reused ,
121121 mb (cell.largest_mem , bytes_per_elem),
122122 mb (cell.peak_storage , bytes_per_elem));
123123 // Op-count only; no concrete FLOP number.
124- out << std::format (" Total operations (symbolic): {}\n \n" ,
124+ out << std::format (" \n Total operations (symbolic): {}\n " ,
125125 cell.total_flops .text ());
126- out << " ### Largest intermediates\n\n " ;
126+ out << " \n ### Largest intermediates\n\n " ;
127127 report_largest (cell, cfg.out .top_n , bytes_per_elem, out);
128- out << " ### Most expensive contractions\n\n " ;
128+ out << " \n ### Most expensive contractions\n\n " ;
129129 report_expensive (cell, cfg.out .top_n , out);
130- out << " ### Shape census\n\n " ;
130+ out << " \n ### Shape census\n\n " ;
131131 report_shape_histogram (cell, bytes_per_elem, out);
132132 }
133133 if (cfg.cache .enabled ) {
134134 out << std::format (
135- " ## Cache (gated, volatile leaf = \" {}\" , min_repeats = {})\n\n " ,
135+ " \n ## Cache (gated, volatile leaf = \" {}\" , min_repeats = {})\n\n " ,
136136 cfg.optimize .volatile_leaf , cfg.cache .min_repeats );
137137 out << " | Metric | Value |\n |---|---|\n " ;
138138 out << std::format (" | Cached | {} |\n " , sim.n_cached );
139139 out << std::format (" | Persistent | {} |\n " , sim.n_persistent );
140140 out << std::format (" | Persistent footprint (MB) | {:.4f} |\n " ,
141141 mb (sim.persistent_footprint , bytes_per_elem));
142- out << std::format (" | Total cached footprint (MB) | {:.4f} |\n\n " ,
142+ out << std::format (" | Total cached footprint (MB) | {:.4f} |\n " ,
143143 mb (sim.cached_footprint , bytes_per_elem));
144144 }
145145}
0 commit comments