diff --git a/internal/metricdata/cc-metric-store.go b/internal/metricdata/cc-metric-store.go index 5db7583..f3ee55f 100644 --- a/internal/metricdata/cc-metric-store.go +++ b/internal/metricdata/cc-metric-store.go @@ -440,6 +440,23 @@ func (ccms *CCMetricStore) buildQueries( continue } + // Core -> Socket + if nativeScope == schema.MetricScopeCore && scope == schema.MetricScopeSocket { + sockets, _ := topology.GetSocketsFromCores(hwthreads) + for _, socket := range sockets { + queries = append(queries, ApiQuery{ + Metric: remoteName, + Hostname: host.Hostname, + Aggregate: true, + Type: &coreString, + TypeIds: intToStringSlice(topology.Socket[socket]), + Resolution: resolution, + }) + assignedScope = append(assignedScope, scope) + } + continue + } + // Core -> Node if nativeScope == schema.MetricScopeCore && scope == schema.MetricScopeNode { cores, _ := topology.GetCoresFromHWThreads(hwthreads) @@ -1038,6 +1055,23 @@ func (ccms *CCMetricStore) buildNodeQueries( continue } + // Core -> Socket + if nativeScope == schema.MetricScopeCore && scope == schema.MetricScopeSocket { + sockets, _ := topology.GetSocketsFromCores(topology.Node) + for _, socket := range sockets { + queries = append(queries, ApiQuery{ + Metric: remoteName, + Hostname: hostname, + Aggregate: true, + Type: &coreString, + TypeIds: intToStringSlice(topology.Socket[socket]), + Resolution: resolution, + }) + assignedScope = append(assignedScope, scope) + } + continue + } + // Core -> Node if nativeScope == schema.MetricScopeCore && scope == schema.MetricScopeNode { cores, _ := topology.GetCoresFromHWThreads(topology.Node) diff --git a/pkg/schema/cluster.go b/pkg/schema/cluster.go index 07e4647..322f308 100644 --- a/pkg/schema/cluster.go +++ b/pkg/schema/cluster.go @@ -122,6 +122,38 @@ func (topo *Topology) GetSocketsFromHWThreads( return sockets, exclusive } +// Return a list of socket IDs given a list of core IDs. Even if just one +// core is in that socket, add it to the list. If no cores other than +// those in the argument list are assigned to one of the sockets in the first +// return value, return true as the second value. TODO: Optimize this, there +// must be a more efficient way/algorithm. +func (topo *Topology) GetSocketsFromCores ( + cores []int, +) (sockets []int, exclusive bool) { + socketsMap := map[int]int{} + for _, core := range cores { + for _, hwthreadInCore := range topo.Core[core] { + for socket, hwthreadsInSocket := range topo.Socket { + for _, hwthreadInSocket := range hwthreadsInSocket { + if hwthreadInCore == hwthreadInSocket { + socketsMap[socket] += 1 + } + } + } + } + } + + exclusive = true + hwthreadsPerSocket := len(topo.Node) / len(topo.Socket) + sockets = make([]int, 0, len(socketsMap)) + for socket, count := range socketsMap { + sockets = append(sockets, socket) + exclusive = exclusive && count == hwthreadsPerSocket + } + + return sockets, exclusive +} + // Return a list of core IDs given a list of hwthread IDs. Even if just one // hwthread is in that core, add it to the list. If no hwthreads other than // those in the argument list are assigned to one of the cores in the first