From 826f36477254a8672018090866a7441b52c15fc2 Mon Sep 17 00:00:00 2001 From: Thomas Gruber Date: Fri, 13 May 2022 14:28:07 +0200 Subject: [PATCH] CC topology module update (#76) * Rename CPU to hardware thread, write some comments * Do renaming in other parts * Remove CpuList and SocketList function from metricCollector. Available in ccTopology --- collectors/likwidMetric.go | 2 +- collectors/metricCollector.go | 56 --------- internal/ccTopology/ccTopology.go | 108 ++++++++++++------ .../metricAggregatorFunctions.go | 12 +- 4 files changed, 82 insertions(+), 96 deletions(-) diff --git a/collectors/likwidMetric.go b/collectors/likwidMetric.go index ae44392..c036415 100644 --- a/collectors/likwidMetric.go +++ b/collectors/likwidMetric.go @@ -205,7 +205,7 @@ func (m *LikwidCollector) Init(config json.RawMessage) error { m.meta = map[string]string{"group": "PerfCounter"} cclog.ComponentDebug(m.name, "Get cpulist and init maps and lists") - cpulist := topo.CpuList() + cpulist := topo.HwthreadList() m.cpulist = make([]C.int, len(cpulist)) m.cpu2tid = make(map[int]int) for i, c := range cpulist { diff --git a/collectors/metricCollector.go b/collectors/metricCollector.go index 13f8f2a..4d52571 100644 --- a/collectors/metricCollector.go +++ b/collectors/metricCollector.go @@ -3,10 +3,6 @@ package collectors import ( "encoding/json" "fmt" - "io/ioutil" - "log" - "strconv" - "strings" "time" lp "github.com/ClusterCockpit/cc-metric-collector/internal/ccMetric" @@ -72,58 +68,6 @@ func stringArrayContains(array []string, str string) (int, bool) { return -1, false } -// SocketList returns the list of physical sockets as read from /proc/cpuinfo -func SocketList() []int { - buffer, err := ioutil.ReadFile("/proc/cpuinfo") - if err != nil { - log.Print(err) - return nil - } - ll := strings.Split(string(buffer), "\n") - var packs []int - for _, line := range ll { - if strings.HasPrefix(line, "physical id") { - lv := strings.Fields(line) - id, err := strconv.ParseInt(lv[3], 10, 32) - if err != nil { - log.Print(err) - return packs - } - _, found := intArrayContains(packs, int(id)) - if !found { - packs = append(packs, int(id)) - } - } - } - return packs -} - -// CpuList returns the list of physical CPUs (in contrast to logical CPUs) as read from /proc/cpuinfo -func CpuList() []int { - buffer, err := ioutil.ReadFile("/proc/cpuinfo") - if err != nil { - log.Print(err) - return nil - } - ll := strings.Split(string(buffer), "\n") - var cpulist []int - for _, line := range ll { - if strings.HasPrefix(line, "processor") { - lv := strings.Fields(line) - id, err := strconv.ParseInt(lv[2], 10, 32) - if err != nil { - log.Print(err) - return cpulist - } - _, found := intArrayContains(cpulist, int(id)) - if !found { - cpulist = append(cpulist, int(id)) - } - } - } - return cpulist -} - // RemoveFromStringList removes the string r from the array of strings s // If r is not contained in the array an error is returned func RemoveFromStringList(s []string, r string) ([]string, error) { diff --git a/internal/ccTopology/ccTopology.go b/internal/ccTopology/ccTopology.go index f68c3f4..0ed8883 100644 --- a/internal/ccTopology/ccTopology.go +++ b/internal/ccTopology/ccTopology.go @@ -29,6 +29,7 @@ func intArrayContains(array []int, str int) (int, bool) { return -1, false } +// Used internally for sysfs file reads func fileToInt(path string) int { buffer, err := ioutil.ReadFile(path) if err != nil { @@ -47,6 +48,7 @@ func fileToInt(path string) int { return int(id) } +// Get list of CPU socket IDs func SocketList() []int { buffer, err := ioutil.ReadFile(string(PROCFS_CPUINFO)) if err != nil { @@ -54,7 +56,7 @@ func SocketList() []int { return nil } ll := strings.Split(string(buffer), "\n") - var packs []int + packs := make([]int, 0) for _, line := range ll { if strings.HasPrefix(line, "physical id") { lv := strings.Fields(line) @@ -72,7 +74,8 @@ func SocketList() []int { return packs } -func CpuList() []int { +// Get list of hardware thread IDs in the order of listing in /proc/cpuinfo +func HwthreadList() []int { buffer, err := ioutil.ReadFile(string(PROCFS_CPUINFO)) if err != nil { log.Print(err) @@ -97,6 +100,13 @@ func CpuList() []int { return cpulist } +// Get list of hardware thread IDs in the order of listing in /proc/cpuinfo +// Deprecated! Use HwthreadList() +func CpuList() []int { + return HwthreadList() +} + +// Get list of CPU core IDs in the order of listing in /proc/cpuinfo func CoreList() []int { buffer, err := ioutil.ReadFile(string(PROCFS_CPUINFO)) if err != nil { @@ -122,6 +132,7 @@ func CoreList() []int { return corelist } +// Get list of NUMA node IDs func NumaNodeList() []int { numaList := make([]int, 0) globPath := filepath.Join(string(SYSFS_NUMABASE), "node*") @@ -156,8 +167,9 @@ func NumaNodeList() []int { return numaList } +// Get list of CPU die IDs func DieList() []int { - cpulist := CpuList() + cpulist := HwthreadList() dielist := make([]int, 0) for _, c := range cpulist { diepath := filepath.Join(string(SYSFS_CPUBASE), fmt.Sprintf("cpu%d", c), "topology/die_id") @@ -175,7 +187,27 @@ func DieList() []int { return SocketList() } -type CpuEntry struct { +// Get list of specified type using the naming format inside ClusterCockpit +func GetTypeList(topology_type string) []int { + switch topology_type { + case "node": + return []int{0} + case "socket": + return SocketList() + case "die": + return DieList() + case "memoryDomain": + return NumaNodeList() + case "core": + return CoreList() + case "hwthread": + return HwthreadList() + } + return []int{} +} + +// Structure holding all information about a hardware thread +type HwthreadEntry struct { Cpuid int SMT int Core int @@ -184,25 +216,25 @@ type CpuEntry struct { Die int } -func CpuData() []CpuEntry { +func CpuData() []HwthreadEntry { - fileToInt := func(path string) int { - buffer, err := ioutil.ReadFile(path) - if err != nil { - log.Print(err) - //cclogger.ComponentError("ccTopology", "Reading", path, ":", err.Error()) - return -1 - } - sbuffer := strings.Replace(string(buffer), "\n", "", -1) - var id int64 - //_, err = fmt.Scanf("%d", sbuffer, &id) - id, err = strconv.ParseInt(sbuffer, 10, 32) - if err != nil { - cclogger.ComponentError("ccTopology", "Parsing", path, ":", sbuffer, err.Error()) - return -1 - } - return int(id) - } + // fileToInt := func(path string) int { + // buffer, err := ioutil.ReadFile(path) + // if err != nil { + // log.Print(err) + // //cclogger.ComponentError("ccTopology", "Reading", path, ":", err.Error()) + // return -1 + // } + // sbuffer := strings.Replace(string(buffer), "\n", "", -1) + // var id int64 + // //_, err = fmt.Scanf("%d", sbuffer, &id) + // id, err = strconv.ParseInt(sbuffer, 10, 32) + // if err != nil { + // cclogger.ComponentError("ccTopology", "Parsing", path, ":", sbuffer, err.Error()) + // return -1 + // } + // return int(id) + // } getCore := func(basepath string) int { return fileToInt(fmt.Sprintf("%s/core_id", basepath)) } @@ -260,9 +292,9 @@ func CpuData() []CpuEntry { return 0 } - clist := make([]CpuEntry, 0) - for _, c := range CpuList() { - clist = append(clist, CpuEntry{Cpuid: c}) + clist := make([]HwthreadEntry, 0) + for _, c := range HwthreadList() { + clist = append(clist, HwthreadEntry{Cpuid: c}) } for i, centry := range clist { centry.Socket = -1 @@ -298,6 +330,7 @@ func CpuData() []CpuEntry { return clist } +// Structure holding basic information about a CPU type CpuInformation struct { NumHWthreads int SMTWidth int @@ -307,6 +340,7 @@ type CpuInformation struct { NumNumaDomains int } +// Get basic information about the CPU func CpuInfo() CpuInformation { var c CpuInformation @@ -342,7 +376,8 @@ func CpuInfo() CpuInformation { return c } -func GetCpuSocket(cpuid int) int { +// Get the CPU socket ID for a given hardware thread ID +func GetHwthreadSocket(cpuid int) int { cdata := CpuData() for _, d := range cdata { if d.Cpuid == cpuid { @@ -352,7 +387,8 @@ func GetCpuSocket(cpuid int) int { return -1 } -func GetCpuNumaDomain(cpuid int) int { +// Get the NUMA node ID for a given hardware thread ID +func GetHwthreadNumaDomain(cpuid int) int { cdata := CpuData() for _, d := range cdata { if d.Cpuid == cpuid { @@ -362,7 +398,8 @@ func GetCpuNumaDomain(cpuid int) int { return -1 } -func GetCpuDie(cpuid int) int { +// Get the CPU die ID for a given hardware thread ID +func GetHwthreadDie(cpuid int) int { cdata := CpuData() for _, d := range cdata { if d.Cpuid == cpuid { @@ -372,7 +409,8 @@ func GetCpuDie(cpuid int) int { return -1 } -func GetCpuCore(cpuid int) int { +// Get the CPU core ID for a given hardware thread ID +func GetHwthreadCore(cpuid int) int { cdata := CpuData() for _, d := range cdata { if d.Cpuid == cpuid { @@ -382,7 +420,8 @@ func GetCpuCore(cpuid int) int { return -1 } -func GetSocketCpus(socket int) []int { +// Get the all hardware thread ID associated with a CPU socket +func GetSocketHwthreads(socket int) []int { all := CpuData() cpulist := make([]int, 0) for _, d := range all { @@ -393,7 +432,8 @@ func GetSocketCpus(socket int) []int { return cpulist } -func GetNumaDomainCpus(domain int) []int { +// Get the all hardware thread ID associated with a NUMA node +func GetNumaDomainHwthreads(domain int) []int { all := CpuData() cpulist := make([]int, 0) for _, d := range all { @@ -404,7 +444,8 @@ func GetNumaDomainCpus(domain int) []int { return cpulist } -func GetDieCpus(die int) []int { +// Get the all hardware thread ID associated with a CPU die +func GetDieHwthreads(die int) []int { all := CpuData() cpulist := make([]int, 0) for _, d := range all { @@ -415,7 +456,8 @@ func GetDieCpus(die int) []int { return cpulist } -func GetCoreCpus(core int) []int { +// Get the all hardware thread ID associated with a CPU core +func GetCoreHwthreads(core int) []int { all := CpuData() cpulist := make([]int, 0) for _, d := range all { diff --git a/internal/metricAggregator/metricAggregatorFunctions.go b/internal/metricAggregator/metricAggregatorFunctions.go index 0228047..945dc6d 100644 --- a/internal/metricAggregator/metricAggregatorFunctions.go +++ b/internal/metricAggregator/metricAggregatorFunctions.go @@ -246,7 +246,7 @@ func matchfunc(args ...interface{}) (interface{}, error) { func getCpuCoreFunc(args ...interface{}) (interface{}, error) { switch cpuid := args[0].(type) { case int: - return topo.GetCpuCore(cpuid), nil + return topo.GetHwthreadCore(cpuid), nil } return -1, errors.New("function 'getCpuCore' accepts only an 'int' cpuid") } @@ -255,7 +255,7 @@ func getCpuCoreFunc(args ...interface{}) (interface{}, error) { func getCpuSocketFunc(args ...interface{}) (interface{}, error) { switch cpuid := args[0].(type) { case int: - return topo.GetCpuSocket(cpuid), nil + return topo.GetHwthreadSocket(cpuid), nil } return -1, errors.New("function 'getCpuCore' accepts only an 'int' cpuid") } @@ -264,7 +264,7 @@ func getCpuSocketFunc(args ...interface{}) (interface{}, error) { func getCpuNumaDomainFunc(args ...interface{}) (interface{}, error) { switch cpuid := args[0].(type) { case int: - return topo.GetCpuNumaDomain(cpuid), nil + return topo.GetHwthreadNumaDomain(cpuid), nil } return -1, errors.New("function 'getCpuNuma' accepts only an 'int' cpuid") } @@ -273,7 +273,7 @@ func getCpuNumaDomainFunc(args ...interface{}) (interface{}, error) { func getCpuDieFunc(args ...interface{}) (interface{}, error) { switch cpuid := args[0].(type) { case int: - return topo.GetCpuDie(cpuid), nil + return topo.GetHwthreadDie(cpuid), nil } return -1, errors.New("function 'getCpuDie' accepts only an 'int' cpuid") } @@ -336,7 +336,7 @@ func getCpuListOfDieFunc(args ...interface{}) (interface{}, error) { // wrapper function to get a list of all cpuids of the node func getCpuListOfNode(args ...interface{}) (interface{}, error) { - return topo.CpuList(), nil + return topo.HwthreadList(), nil } // helper function to get the cpuid list for a CCMetric type tag set (type and type-id) @@ -348,7 +348,7 @@ func getCpuListOfType(args ...interface{}) (interface{}, error) { case string: switch typ { case "node": - return topo.CpuList(), nil + return topo.HwthreadList(), nil case "socket": return getCpuListOfSocketFunc(args[1]) case "numadomain":