@@ -29,6 +29,9 @@ const (
2929 memoryKey = "memory"
3030 cpuKey = "cpu"
3131 gpuKey = "nvidia.com/gpu"
32+ neuronKey = "aws.amazon.com/neuron"
33+ neuroncoreKey = "aws.amazon.com/neuroncore"
34+ neuronDeviceKey = "aws.amazon.com/neurondevice"
3235 splitRegexStr = "\\ .|-"
3336 kubeProxy = "kube-proxy"
3437)
@@ -247,6 +250,7 @@ func (p *PodStore) Decorate(ctx context.Context, metric CIMetric, kubernetesBlob
247250 p .decorateCPU (metric , & entry .pod )
248251 p .decorateMem (metric , & entry .pod )
249252 p .decorateGPU (metric , & entry .pod )
253+ p .decorateNeuron (metric , & entry .pod )
250254 p .addStatus (metric , & entry .pod )
251255 addContainerCount (metric , & entry .pod )
252256 addContainerID (& entry .pod , metric , kubernetesBlob , p .logger )
@@ -298,6 +302,8 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
298302 var memRequest uint64
299303 var gpuRequest uint64
300304 var gpuUsageTotal uint64
305+ var neuroncoreRequest uint64
306+ var neuroncoreUsageTotal uint64
301307
302308 for i := range podList {
303309 pod := podList [i ]
@@ -312,6 +318,12 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
312318 cpuRequest += tmpCPUReq
313319 tmpMemReq , _ := getResourceSettingForPod (& pod , p .nodeInfo .getMemCapacity (), memoryKey , getRequestForContainer )
314320 memRequest += tmpMemReq
321+ if coresLimit , coresReq , hasNeuron := p .getNeuronCoresFromPod (& pod ); hasNeuron {
322+ neuroncoreRequest += coresReq
323+ if pod .Status .Phase == corev1 .PodRunning {
324+ neuroncoreUsageTotal += coresLimit
325+ }
326+ }
315327 if tmpGpuLimit , ok := getResourceSettingForPod (& pod , 0 , gpuKey , getLimitForContainer ); ok {
316328 tmpGpuReq , _ := getResourceSettingForPod (& pod , 0 , gpuKey , getRequestForContainer )
317329 gpuRequest += tmpGpuReq
@@ -337,12 +349,14 @@ func (p *PodStore) refreshInternal(now time.Time, podList []corev1.Pod) {
337349 }
338350
339351 p .nodeInfo .setNodeStats (nodeStats {
340- podCnt : podCount ,
341- containerCnt : containerCount ,
342- memReq : memRequest ,
343- cpuReq : cpuRequest ,
344- gpuReq : gpuRequest ,
345- gpuUsageTotal : gpuUsageTotal ,
352+ podCnt : podCount ,
353+ containerCnt : containerCount ,
354+ memReq : memRequest ,
355+ cpuReq : cpuRequest ,
356+ gpuReq : gpuRequest ,
357+ gpuUsageTotal : gpuUsageTotal ,
358+ neuroncoreReq : neuroncoreRequest ,
359+ neuroncoreUsageTotal : neuroncoreUsageTotal ,
346360 })
347361}
348362
@@ -408,6 +422,17 @@ func (p *PodStore) decorateNode(metric CIMetric) {
408422 metric .AddField (ci .MetricName (ci .TypeNode , ci .GpuUsageTotal ), nodeStats .gpuUsageTotal )
409423 metric .AddField (ci .MetricName (ci .TypeNode , ci .GpuReservedCapacity ), float64 (nodeStats .gpuReq )/ float64 (nodeStatusCapacityGPUs )* 100 )
410424 }
425+
426+ if nodeStatusCapacityNeuroncore , ok := p .nodeInfo .getNodeStatusCapacityNeuronCores (); ok && nodeStatusCapacityNeuroncore != 0 {
427+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreRequest ), nodeStats .neuroncoreReq )
428+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreLimit ), nodeStatusCapacityNeuroncore )
429+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreUsageTotal ), nodeStats .neuroncoreUsageTotal )
430+
431+ reservedCapacity := float64 (nodeStats .neuroncoreReq ) / float64 (nodeStatusCapacityNeuroncore ) * 100
432+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreReservedCapacity ), reservedCapacity )
433+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreUnreservedCapacity ), 100.0 - reservedCapacity )
434+ metric .AddField (ci .MetricName (ci .TypeNode , ci .NeuroncoreAvailableCapacity ), nodeStatusCapacityNeuroncore - nodeStats .neuroncoreReq )
435+ }
411436 }
412437 }
413438}
@@ -431,6 +456,56 @@ func (p *PodStore) decorateGPU(metric CIMetric, pod *corev1.Pod) {
431456 }
432457}
433458
459+ func (p * PodStore ) getCoresPerNeuronDevice () (int , bool ) {
460+ return p .nodeInfo .getNeuronCoresPerDevice ()
461+ }
462+
463+ func (p * PodStore ) getNeuronCoresFromPod (pod * corev1.Pod ) (limitCores , requestCores uint64 , hasNeuron bool ) {
464+ if coreLimit , ok := getResourceSettingForPod (pod , 0 , neuroncoreKey , getLimitForContainer ); ok {
465+ coreRequest , _ := getResourceSettingForPod (pod , 0 , neuroncoreKey , getRequestForContainer )
466+ return coreLimit , coreRequest , true
467+ }
468+
469+ coresPerDevice , hasRatio := p .getCoresPerNeuronDevice ()
470+ if ! hasRatio {
471+ p .logger .Debug ("Cannot determine neuron cores per device ratio, skipping device-based neuron metrics" )
472+ return 0 , 0 , false
473+ }
474+
475+ deviceKeys := []corev1.ResourceName {neuronKey , neuronDeviceKey }
476+ for _ , deviceKey := range deviceKeys {
477+ if deviceLimit , ok := getResourceSettingForPod (pod , 0 , deviceKey , getLimitForContainer ); ok {
478+ deviceRequest , _ := getResourceSettingForPod (pod , 0 , deviceKey , getRequestForContainer )
479+ return deviceLimit * uint64 (coresPerDevice ), deviceRequest * uint64 (coresPerDevice ), true
480+ }
481+ }
482+
483+ return 0 , 0 , false
484+ }
485+
486+ func (p * PodStore ) decorateNeuron (metric CIMetric , pod * corev1.Pod ) {
487+ if p .includeEnhancedMetrics && p .enableAcceleratedComputeMetrics && metric .GetTag (ci .MetricType ) == ci .TypePod &&
488+ pod .Status .Phase != corev1 .PodSucceeded && pod .Status .Phase != corev1 .PodFailed {
489+ coresLimit , coresRequest , hasNeuron := p .getNeuronCoresFromPod (pod )
490+
491+ if hasNeuron {
492+ metric .AddField (ci .MetricName (ci .TypePod , ci .NeuroncoreRequest ), coresRequest )
493+ metric .AddField (ci .MetricName (ci .TypePod , ci .NeuroncoreLimit ), coresLimit )
494+
495+ var podNeuroncoreUsageTotal uint64
496+ if pod .Status .Phase == corev1 .PodRunning {
497+ podNeuroncoreUsageTotal = coresLimit
498+ }
499+ metric .AddField (ci .MetricName (ci .TypePod , ci .NeuroncoreUsageTotal ), podNeuroncoreUsageTotal )
500+
501+ if nodeCapacityCores , ok := p .nodeInfo .getNodeStatusCapacityNeuronCores (); ok && nodeCapacityCores != 0 {
502+ reservedCapacity := float64 (coresLimit ) / float64 (nodeCapacityCores ) * 100
503+ metric .AddField (ci .MetricName (ci .TypePod , ci .NeuroncoreReservedCapacity ), reservedCapacity )
504+ }
505+ }
506+ }
507+ }
508+
434509func (p * PodStore ) decorateCPU (metric CIMetric , pod * corev1.Pod ) {
435510 if metric .GetTag (ci .MetricType ) == ci .TypePod {
436511 // add cpu limit and request for pod cpu
0 commit comments