Skip to content

Commit 89ea0bf

Browse files
authored
render flag help next to values for config command (#574)
* render flag help next to values for config command Signed-off-by: Harper, Jason M <[email protected]> * render flag help next to values for config command Signed-off-by: Harper, Jason M <[email protected]> --------- Signed-off-by: Harper, Jason M <[email protected]>
1 parent 6d0bb86 commit 89ea0bf

File tree

7 files changed

+90
-31
lines changed

7 files changed

+90
-31
lines changed

cmd/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ func printConfig(myTargets []target.Target, localTempDir string) (err error) {
280280
}
281281
// create the report for this single table
282282
var reportBytes []byte
283-
if reportBytes, err = report.Create("txt", tableValues, targetScriptOutputs.ScriptOutputs, targetScriptOutputs.TargetName); err != nil {
283+
if reportBytes, err = report.Create("txt", tableValues, targetScriptOutputs.TargetName); err != nil {
284284
err = fmt.Errorf("failed to create report: %v", err)
285285
return
286286
}

cmd/config/flag_groups.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ const (
4040
const (
4141
flagCoreCountName = "cores"
4242
flagLLCSizeName = "llc"
43-
flagAllCoreMaxFrequencyName = "core-max"
4443
flagTDPName = "tdp"
44+
flagAllCoreMaxFrequencyName = "core-max"
4545
flagEPBName = "epb"
4646
flagEPPName = "epp"
4747
flagGovernorName = "gov"
@@ -93,13 +93,13 @@ func initializeFlags(cmd *cobra.Command) {
9393
func(cmd *cobra.Command) bool { value, _ := cmd.Flags().GetInt(flagCoreCountName); return value > 0 }),
9494
newFloat64Flag(cmd, flagLLCSizeName, 0, setLlcSize, "LLC size in MB", "greater than 0",
9595
func(cmd *cobra.Command) bool { value, _ := cmd.Flags().GetFloat64(flagLLCSizeName); return value > 0 }),
96+
newIntFlag(cmd, flagTDPName, 0, setTDP, "maximum power per processor in Watts", "greater than 0",
97+
func(cmd *cobra.Command) bool { value, _ := cmd.Flags().GetInt(flagTDPName); return value > 0 }),
9698
newFloat64Flag(cmd, flagAllCoreMaxFrequencyName, 0, setCoreFrequency, "all-core max frequency in GHz", "greater than 0.1",
9799
func(cmd *cobra.Command) bool {
98100
value, _ := cmd.Flags().GetFloat64(flagAllCoreMaxFrequencyName)
99101
return value > 0.1
100102
}),
101-
newIntFlag(cmd, flagTDPName, 0, setTDP, "maximum power per processor in Watts", "greater than 0",
102-
func(cmd *cobra.Command) bool { value, _ := cmd.Flags().GetInt(flagTDPName); return value > 0 }),
103103
newIntFlag(cmd, flagEPBName, 0, setEPB, "energy perf bias from best performance (0) to most power savings (15)", "0-15",
104104
func(cmd *cobra.Command) bool {
105105
value, _ := cmd.Flags().GetInt(flagEPBName)

internal/common/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ func (rc *ReportingCommand) createReports(appContext AppContext, orderedTargetSc
407407
})
408408
// create the report(s)
409409
for _, format := range formats {
410-
reportBytes, err := report.Create(format, allTableValues, targetScriptOutputs.ScriptOutputs, targetScriptOutputs.TargetName)
410+
reportBytes, err := report.Create(format, allTableValues, targetScriptOutputs.TargetName)
411411
if err != nil {
412412
err = fmt.Errorf("failed to create report: %w", err)
413413
return nil, err

internal/report/render_text.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,44 @@ func DefaultTextTableRendererFunc(tableValues TableValues) string {
9797
}
9898
return sb.String()
9999
}
100+
101+
// configurationTableTextRenderer renders the configuration table for text reports.
102+
// It's similar to the default text table renderer, but uses the Description field
103+
// to show the command line argument for each config item.
104+
// Example output:
105+
// Configuration
106+
// =============
107+
// Cores per Socket: 86 --cores <N>
108+
// L3 Cache: 336M --llc <MB>
109+
// Package Power / TDP: 350W --tdp <Watts>
110+
// All-Core Max Frequency: 3.2GHz --core-max <GHz>
111+
func configurationTableTextRenderer(tableValues TableValues) string {
112+
var sb strings.Builder
113+
114+
// Find the longest field name and value for formatting
115+
maxFieldNameLen := 0
116+
maxValueLen := 0
117+
for _, field := range tableValues.Fields {
118+
if len(field.Name) > maxFieldNameLen {
119+
maxFieldNameLen = len(field.Name)
120+
}
121+
if len(field.Values) > 0 && len(field.Values[0]) > maxValueLen {
122+
maxValueLen = len(field.Values[0])
123+
}
124+
}
125+
126+
// Print each field with name, value, and description (command-line arg)
127+
for _, field := range tableValues.Fields {
128+
var value string
129+
if len(field.Values) > 0 {
130+
value = field.Values[0]
131+
}
132+
// Format: "Field Name: Value Description"
133+
sb.WriteString(fmt.Sprintf("%-*s %-*s %s\n",
134+
maxFieldNameLen+1, field.Name+":",
135+
maxValueLen, value,
136+
field.Description))
137+
}
138+
139+
return sb.String()
140+
}

internal/report/report.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ package report
77
import (
88
"fmt"
99
"strings"
10-
11-
"perfspect/internal/script"
1210
)
1311

1412
const (
@@ -32,13 +30,12 @@ var FormatOptions = []string{FormatHtml, FormatXlsx, FormatJson, FormatTxt}
3230
// Parameters:
3331
// - format: The desired format of the report (txt, json, html, xlsx, raw).
3432
// - tableValues: The values for each field in each table.
35-
// - scriptOutputs: The outputs of any scripts used in the report.
3633
// - targetName: The name of the target for which the report is being generated.
3734
//
3835
// Returns:
3936
// - out: The generated report as a byte slice.
4037
// - err: An error, if any occurred during report generation.
41-
func Create(format string, allTableValues []TableValues, scriptOutputs map[string]script.ScriptOutput, targetName string) (out []byte, err error) {
38+
func Create(format string, allTableValues []TableValues, targetName string) (out []byte, err error) {
4239
// make sure that all fields have the same number of values
4340
for _, tableValue := range allTableValues {
4441
numRows := -1

internal/report/table_defs.go

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,8 @@ var tableDefinitions = map[string]TableDefinition{
599599
script.CstatesScriptName,
600600
script.C1DemotionScriptName,
601601
},
602-
FieldsFunc: configurationTableValues},
602+
TextTableRendererFunc: configurationTableTextRenderer,
603+
FieldsFunc: configurationTableValues},
603604
//
604605
// benchmarking tables
605606
//
@@ -2176,34 +2177,36 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []Field {
21762177
slog.Error("failed to get uarch from script outputs")
21772178
return []Field{}
21782179
}
2179-
2180+
// This table is only shown in text mode on stdout for the config command. The config
2181+
// command implements its own print logic and uses the Description field to show the command line
2182+
// argument for each config item.
21802183
fields := []Field{
2181-
{Name: "Cores per Socket", Values: []string{valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Core\(s\) per socket:\s*(.+)$`)}},
2182-
{Name: "L3 Cache", Values: []string{l3InstanceFromOutput(outputs)}},
2183-
{Name: "Package Power / TDP", Values: []string{tdpFromOutput(outputs)}},
2184-
{Name: "All-Core Max Frequency", Values: []string{allCoreMaxFrequencyFromOutput(outputs)}},
2184+
{Name: "Cores per Socket", Description: "--cores <N>", Values: []string{valFromRegexSubmatch(outputs[script.LscpuScriptName].Stdout, `^Core\(s\) per socket:\s*(.+)$`)}},
2185+
{Name: "L3 Cache", Description: "--llc <MB>", Values: []string{l3InstanceFromOutput(outputs)}},
2186+
{Name: "Package Power / TDP", Description: "--tdp <Watts>", Values: []string{tdpFromOutput(outputs)}},
2187+
{Name: "All-Core Max Frequency", Description: "--core-max <GHz>", Values: []string{allCoreMaxFrequencyFromOutput(outputs)}},
21852188
}
21862189
if strings.Contains(uarch, "SRF") || strings.Contains(uarch, "GNR") || strings.Contains(uarch, "CWF") {
21872190
fields = append(fields, []Field{
2188-
{Name: "Uncore Min Frequency (Compute)", Values: []string{uncoreMinMaxDieFrequencyFromOutput(false, true, outputs)}},
2189-
{Name: "Uncore Min Frequency (I/O)", Values: []string{uncoreMinMaxDieFrequencyFromOutput(false, false, outputs)}},
2190-
{Name: "Uncore Max Frequency (Compute)", Values: []string{uncoreMinMaxDieFrequencyFromOutput(true, true, outputs)}},
2191-
{Name: "Uncore Max Frequency (I/O)", Values: []string{uncoreMinMaxDieFrequencyFromOutput(true, false, outputs)}},
2191+
{Name: "Uncore Max Frequency (Compute)", Description: "--uncore-max-compute <GHz>", Values: []string{uncoreMinMaxDieFrequencyFromOutput(true, true, outputs)}},
2192+
{Name: "Uncore Min Frequency (Compute)", Description: "--uncore-min-compute <GHz>", Values: []string{uncoreMinMaxDieFrequencyFromOutput(false, true, outputs)}},
2193+
{Name: "Uncore Max Frequency (I/O)", Description: "--uncore-max-io <GHz>", Values: []string{uncoreMinMaxDieFrequencyFromOutput(true, false, outputs)}},
2194+
{Name: "Uncore Min Frequency (I/O)", Description: "--uncore-min-io <GHz>", Values: []string{uncoreMinMaxDieFrequencyFromOutput(false, false, outputs)}},
21922195
}...)
21932196
} else {
21942197
fields = append(fields, []Field{
2195-
{Name: "Uncore Max Frequency (GHz)", Values: []string{uncoreMaxFrequencyFromOutput(outputs)}},
2196-
{Name: "Uncore Min Frequency (GHz)", Values: []string{uncoreMinFrequencyFromOutput(outputs)}},
2198+
{Name: "Uncore Max Frequency", Description: "--uncore-max <GHz>", Values: []string{uncoreMaxFrequencyFromOutput(outputs)}},
2199+
{Name: "Uncore Min Frequency", Description: "--uncore-min <GHz>", Values: []string{uncoreMinFrequencyFromOutput(outputs)}},
21972200
}...)
21982201
}
21992202
fields = append(fields, []Field{
2200-
{Name: "Energy Performance Bias", Values: []string{epbFromOutput(outputs)}},
2201-
{Name: "Energy Performance Preference", Values: []string{eppFromOutput(outputs)}},
2202-
{Name: "Scaling Governor", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}},
2203+
{Name: "Energy Performance Bias", Description: "--epb <0-15>", Values: []string{epbFromOutput(outputs)}},
2204+
{Name: "Energy Performance Preference", Description: "--epp <0-255>", Values: []string{eppFromOutput(outputs)}},
2205+
{Name: "Scaling Governor", Description: "--gov <performance|powersave>", Values: []string{strings.TrimSpace(outputs[script.ScalingGovernorScriptName].Stdout)}},
22032206
}...)
22042207
// add ELC (for SRF, CWF and GNR only)
22052208
if strings.Contains(uarch, "SRF") || strings.Contains(uarch, "GNR") || strings.Contains(uarch, "CWF") {
2206-
fields = append(fields, Field{Name: "Efficiency Latency Control", Values: []string{elcSummaryFromOutput(outputs)}})
2209+
fields = append(fields, Field{Name: "Efficiency Latency Control", Description: "--elc <default|latency-optimized>", Values: []string{elcSummaryFromOutput(outputs)}})
22072210
}
22082211
// add prefetchers
22092212
for _, pf := range prefetcherDefinitions {
@@ -2232,18 +2235,23 @@ func configurationTableValues(outputs map[string]script.ScriptOutput) []Field {
22322235
} else {
22332236
enabledDisabled = "Disabled"
22342237
}
2235-
fields = append(fields, Field{Name: pf.ShortName + " prefetcher", Values: []string{enabledDisabled}})
2238+
fields = append(fields,
2239+
Field{
2240+
Name: pf.ShortName + " prefetcher",
2241+
Description: "--" + "pref-" + strings.ReplaceAll(strings.ToLower(pf.ShortName), " ", "") + " <enable|disable>",
2242+
Values: []string{enabledDisabled}},
2243+
)
22362244
}
22372245
}
2238-
// add C-states
2239-
cstates := cstatesSummaryFromOutput(outputs)
2240-
if cstates != "" {
2241-
fields = append(fields, Field{Name: "C-states", Values: []string{cstates}})
2246+
// add C6
2247+
c6 := c6FromOutput(outputs)
2248+
if c6 != "" {
2249+
fields = append(fields, Field{Name: "C6", Description: "--c6 <enable|disable>", Values: []string{c6}})
22422250
}
22432251
// add C1 Demotion
22442252
c1Demotion := strings.TrimSpace(outputs[script.C1DemotionScriptName].Stdout)
22452253
if c1Demotion != "" {
2246-
fields = append(fields, Field{Name: "C1 Demotion", Values: []string{c1Demotion}})
2254+
fields = append(fields, Field{Name: "C1 Demotion", Description: "--c1-demotion <enable|disable>", Values: []string{c1Demotion}})
22472255
}
22482256
return fields
22492257
}

internal/report/table_helpers.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,19 @@ type cstateInfo struct {
10881088
Status string
10891089
}
10901090

1091+
func c6FromOutput(outputs map[string]script.ScriptOutput) string {
1092+
cstatesInfo := cstatesFromOutput(outputs)
1093+
if cstatesInfo == nil {
1094+
return ""
1095+
}
1096+
for _, cstateInfo := range cstatesInfo {
1097+
if cstateInfo.Name == "C6" {
1098+
return cstateInfo.Status
1099+
}
1100+
}
1101+
return ""
1102+
}
1103+
10911104
func cstatesFromOutput(outputs map[string]script.ScriptOutput) []cstateInfo {
10921105
var cstatesInfo []cstateInfo
10931106
output := outputs[script.CstatesScriptName].Stdout

0 commit comments

Comments
 (0)