Skip to content

Commit ae58fd7

Browse files
committed
Report the resolved compression-fusion decision in CLI JSON
FZGM CLI JSON reports now include the resolved fusion policy, legal-domain count, installed implementation and stage coverage, and an explicit fallback reason, so corpus results can prove whether Auto actually specialized a pipeline.
1 parent 147472b commit ae58fd7

3 files changed

Lines changed: 60 additions & 3 deletions

File tree

‎src/utils/cli/cli.cpp‎

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,15 @@ static std::string strategy_str(MemoryStrategy s) {
782782
return s == MemoryStrategy::MINIMAL ? "MINIMAL" : "PREALLOCATE";
783783
}
784784

785+
static const char* fusion_policy_str(FusionPolicy p) {
786+
switch (p) {
787+
case FusionPolicy::Off: return "off";
788+
case FusionPolicy::Auto: return "auto";
789+
case FusionPolicy::Force: return "force";
790+
}
791+
return "off";
792+
}
793+
785794
static const char* operation_str(CliOperation op) {
786795
switch (op) {
787796
case CliOperation::Compress: return "compress";
@@ -827,6 +836,16 @@ static void fill_from_pipeline(fz::cli::ReportData& d, const Pipeline& p) {
827836
// key order would make otherwise-identical reports diff.
828837
std::sort(d.run_notes.begin(), d.run_notes.end(),
829838
[](const auto& a2, const auto& b2) { return a2.first < b2.first; });
839+
840+
const FusionInfo& fusion = p.getFusionInfo();
841+
d.has_fusion = true;
842+
d.fusion_policy = fusion_policy_str(fusion.policy);
843+
d.fusion_legal_group_count = fusion.legal_group_count;
844+
d.fusion_fallback_reason = fusion.fallback_reason;
845+
d.fusion_installed_groups.clear();
846+
for (const auto& group : fusion.installed_groups) {
847+
d.fusion_installed_groups.push_back({group.implementation, group.stages});
848+
}
830849
}
831850

832851
// Append per-stage device timings from a perf result into the report.
@@ -1366,4 +1385,4 @@ int fzgmod_cli_main(int argc, char** argv) {
13661385
print_root_usage(argc > 0 ? argv[0] : "fzgmod-cli");
13671386
return 1;
13681387
}
1369-
}
1388+
}

‎src/utils/cli/report_json.cpp‎

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ void write_report_json(const std::string& path, const ReportData& d) {
201201
<< "\", \"device_ms\": " << num(s.device_ms) << " }";
202202
}
203203
o << (d.stages.empty() ? "]" : "\n ]");
204-
if (d.graph_requested || !d.stage_versions.empty() || !d.run_notes.empty()) o << ",";
204+
if (d.graph_requested || !d.stage_versions.empty() || !d.run_notes.empty() || d.has_fusion) o << ",";
205205
o << "\n";
206206

207207
// stage_versions: source fingerprint of each stage that ran. Omitted entirely
@@ -216,7 +216,7 @@ void write_report_json(const std::string& path, const ReportData& d) {
216216
first = false;
217217
}
218218
o << "\n }";
219-
if (d.graph_requested || !d.run_notes.empty()) o << ",";
219+
if (d.graph_requested || !d.run_notes.empty() || d.has_fusion) o << ",";
220220
o << "\n";
221221
}
222222

@@ -236,6 +236,32 @@ void write_report_json(const std::string& path, const ReportData& d) {
236236
first = false;
237237
}
238238
o << "\n }";
239+
if (d.graph_requested || d.has_fusion) o << ",";
240+
o << "\n";
241+
}
242+
243+
if (d.has_fusion) {
244+
size_t installed_stage_count = 0;
245+
for (const auto& group : d.fusion_installed_groups)
246+
installed_stage_count += group.stages.size();
247+
o << " \"fusion\": {\n";
248+
o << " \"policy\": \"" << esc(d.fusion_policy) << "\",\n";
249+
o << " \"legal_group_count\": " << d.fusion_legal_group_count << ",\n";
250+
o << " \"installed_group_count\": " << d.fusion_installed_groups.size() << ",\n";
251+
o << " \"installed_stage_count\": " << installed_stage_count << ",\n";
252+
o << " \"fallback_reason\": " << str_or_null(d.fusion_fallback_reason) << ",\n";
253+
o << " \"groups\": [";
254+
for (size_t i = 0; i < d.fusion_installed_groups.size(); ++i) {
255+
const auto& group = d.fusion_installed_groups[i];
256+
o << (i ? "," : "") << "\n { \"implementation\": \""
257+
<< esc(group.implementation) << "\", \"stages\": [";
258+
for (size_t j = 0; j < group.stages.size(); ++j) {
259+
o << (j ? ", " : "") << "\"" << esc(group.stages[j]) << "\"";
260+
}
261+
o << "] }";
262+
}
263+
o << (d.fusion_installed_groups.empty() ? "]\n" : "\n ]\n");
264+
o << " }";
239265
if (d.graph_requested) o << ",";
240266
o << "\n";
241267
}

‎src/utils/cli/report_json.h‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ struct PhaseTimingJson {
4444
std::vector<double> host_wall_ms; ///< per-rep host wall time (ms)
4545
};
4646

47+
struct FusionGroupJson {
48+
std::string implementation;
49+
std::vector<std::string> stages;
50+
};
51+
4752
/// Everything the JSON needs, in plain types decoupled from CLI internals.
4853
struct ReportData {
4954
// ── tool ──
@@ -101,6 +106,13 @@ struct ReportData {
101106
/// case costs no bytes and an absent key reads as "no notes".
102107
std::vector<std::pair<std::string, std::vector<std::string>>> run_notes;
103108

109+
// ── finalize-time compression fusion decision ──
110+
bool has_fusion = false;
111+
std::string fusion_policy;
112+
size_t fusion_legal_group_count = 0;
113+
std::vector<FusionGroupJson> fusion_installed_groups;
114+
std::string fusion_fallback_reason;
115+
104116
// ── graph mode (benchmark only; omitted entirely when graph_requested is false) ──
105117
bool graph_requested = false;
106118
bool graph_active = false;

0 commit comments

Comments
 (0)