Skip to content

Commit

Permalink
CPUID alternative solution, major changes are as follows: (#1029)
Browse files Browse the repository at this point in the history
1. Move original Intel specific script and output file to `data/intel_cpu` directory.
2. Move legacy power model csv files to `data/legacy` directory.
3. Obsolete `normalized_cpu_arch.csv`, introduce `cpus.yaml` to involve more data mapping.
4. Change `cpuid -1 |grep uarch` output parsing logic to align with cpuid source logic.
5. Introduce `github.com/klauspost/cpuid/v2` library to replace the raw `lscpu` command call.
6. Add new function(getCPUMircoarchitecture) to fetch uarch from `cpus.yaml`.
7. For CPU models not matched in `cpus.yaml`, read `/sys/devices/cpu/pmu_name` as uarch.
8. Align with latest Linux kernel for Intel CPU family models.
9. Update README document and Dockerfile accordingly.
10. Update kepler validator side code accordingly.

Signed-off-by: Jie Ren <[email protected]>
  • Loading branch information
jiere authored Nov 23, 2023
1 parent 5f67a16 commit e2d7a5c
Show file tree
Hide file tree
Showing 37 changed files with 3,561 additions and 1,540 deletions.
4 changes: 2 additions & 2 deletions build/Dockerfile.bcc.kepler
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ FROM quay.io/sustainable_computing_io/kepler_base:ubi-9-bcc-0.26
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/_output/bin/kepler /usr/bin/kepler

RUN mkdir -p /var/lib/kepler/data
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/normalized_cpu_arch.csv /var/lib/kepler/data/normalized_cpu_arch.csv
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/cpus.yaml /var/lib/kepler/data/cpus.yaml

# copy model weight
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/model_weight/acpi_AbsPowerModel.json /var/lib/kepler/data/acpi_AbsPowerModel.json
Expand All @@ -40,4 +40,4 @@ RUN mkdir -p /usr/share/kepler/kernel_sources

COPY --from=quay.io/sustainable_computing_io/kepler_kernel_source_images:ubi9 /usr/src/kernels /usr/share/kepler/kernel_sources

ENTRYPOINT ["/usr/bin/kepler"]
ENTRYPOINT ["/usr/bin/kepler"]
3 changes: 0 additions & 3 deletions build/Dockerfile.kepler-validator
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,3 @@ FROM quay.io/sustainable_computing_io/kepler_base:ubi-9-libbpf-1.2.0
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/_output/bin/validator /usr/bin/validator

RUN chmod +x /usr/bin/validator

RUN mkdir -p /var/lib/kepler/data
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/normalized_cpu_arch.csv /var/lib/kepler/data/normalized_cpu_arch.csv
2 changes: 1 addition & 1 deletion build/Dockerfile.libbpf.kepler
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler

RUN mkdir -p /var/lib/kepler/data
RUN mkdir -p /var/lib/kepler/bpfassets
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/normalized_cpu_arch.csv /var/lib/kepler/data/normalized_cpu_arch.csv
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/data/cpus.yaml /var/lib/kepler/data/cpus.yaml
COPY --from=builder /opt/app-root/src/github.com/sustainable-computing-io/kepler/bpfassets/libbpf/bpf.o /var/lib/kepler/bpfassets

# copy model weight
Expand Down
60 changes: 25 additions & 35 deletions cmd/validator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"encoding/csv"
"flag"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
Expand All @@ -30,16 +29,14 @@ import (
"time"

"github.com/jaypipes/ghw"
"github.com/jszwec/csvutil"
"github.com/sustainable-computing-io/kepler/pkg/power/components"
"github.com/sustainable-computing-io/kepler/pkg/power/components/source"
"github.com/sustainable-computing-io/kepler/pkg/power/platform"
)

const (
uJTomJ = 1000
resultDirPath = "/output"
CPUModelDataPath = "/var/lib/kepler/data/normalized_cpu_arch.csv"
uJTomJ = 1000
resultDirPath = "/output"
)

var (
Expand Down Expand Up @@ -145,43 +142,36 @@ func getX86Architecture() (string, error) {
}
res, _ := grep.Output()

// format the CPUArchitecture result
uarch := strings.Split(string(res), "=")
if len(uarch) != 2 {
// format the CPUArchitecture result, the raw "uarch synth" string is like this:
// (uarch synth) = <vendor> <uarch> {<family>}, <phys>
// example 1: "(uarch synth) = Intel Sapphire Rapids {Golden Cove}, Intel 7"
// example 2: "(uarch synth) = AMD Zen 2, 7nm", here the <family> info is missing.
uarchSection := strings.Split(string(res), "=")
if len(uarchSection) != 2 {
return "", fmt.Errorf("cpuid grep output is unexpected")
}

if err2 := output.Wait(); err2 != nil {
return "", err2
}

myCPUModel := strings.Split(uarch[1], "{")[0]
file, er := os.Open(CPUModelDataPath)
if er != nil {
return "", er
// get the string contains only vendor/uarch/family info
// example 1: "Intel Sapphire Rapids {Golden Cove}"
// example 2: "AMD Zen 2"
vendorUarchFamily := strings.Split(strings.TrimSpace(uarchSection[1]), ",")[0]

// remove the family info if necessary
var vendorUarch string
if strings.Contains(vendorUarchFamily, "{") {
vendorUarch = strings.TrimSpace(strings.Split(vendorUarchFamily, "{")[0])
} else {
vendorUarch = vendorUarchFamily
}
reader := csv.NewReader(file)

dec, e := csvutil.NewDecoder(reader)
if e != nil {
return "", e
}
// get the uarch finally, e.g. "Sapphire Rapids", "Zen 2".
start := strings.Index(vendorUarch, " ") + 1
uarch := vendorUarch[start:]

var de error
for {
type CPUModelData struct {
Architecture string `csv:"Architecture"`
}
var p CPUModelData
if de = dec.Decode(&p); de == io.EOF {
break
}
if strings.Contains(myCPUModel, p.Architecture) {
return p.Architecture, nil
}
if err = output.Wait(); err != nil {
fmt.Printf("cpuid command is not properly completed: %s", err)
}

return "unknown", fmt.Errorf("no CPU power model found for architecture %s", myCPUModel)
return uarch, err
}

func isFileExists(path string) bool {
Expand Down
14 changes: 13 additions & 1 deletion data/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,14 @@
# CPU Model
[cpu_model.csv](./cpu_model.csv) relates CPU model family found in `/proc/cpuinfo` to its architecture.
[cpus.yaml](./cpus.yaml) lists CPU information includes: `Core`, `Uarch`, `Family`, `Model` and `Stepping`.

`Core` refers to the CPU core name.

`Family`, `Model` and `Stepping` are information included in /proc/cpuinfo, could be fetched by Golang libraries such as "github.com/klauspost/cpuid/v2".

`Uarch` refers to the CPU microarchitecture.

Help needed for any vendors' CPU Models data missing in this file when you test Kepler on your platform.

Please feel free to raise issue in Kepler for your case.

[power_model.csv](./legacy/power_model.csv) and [power_data.csv](./legacy/power_data.csv) are legacy data files for Kepler CPU power model.
Loading

0 comments on commit e2d7a5c

Please sign in to comment.