diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js index 1f772defcd2..99b4fdd242e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-ui/src/main/webapp/app/components/nodes-heatmap.js @@ -30,6 +30,7 @@ export default BaseChartComponent.extend({ memoryLabel: "Memory", cpuLabel: "VCores", containersLabel: "Containers", + gpuLabel: "GPUs", totalContainers: 0, bindTP: function(element, cell) { @@ -95,15 +96,17 @@ export default BaseChartComponent.extend({ return false; }, - // data: - // [{label=label1, value=value1}, ...] - // ... - renderCells: function (model, title) { - var selectedOption = d3.select("select").property("value"); + getData: function(model) { var data = []; model.forEach(function (o) { data.push(o); }); + return data; + }, + + renderCells: function (model, title) { + var selectedOption = d3.select("select").property("value"); + var data = this.getData(model); this.chart.g.remove(); this.chart.g = this.chart.svg.append("g"); @@ -260,6 +263,9 @@ export default BaseChartComponent.extend({ didInsertElement: function () { var self = this; var optionsData = [this.memoryLabel, this.cpuLabel, this.containersLabel]; + if (this.areGPUsSupported(this.get("model"))) { + optionsData.push(this.gpuLabel); + } d3.select("#heatmap-select") .on('change', function() { self.renderCells(self.get("model"), self.get("title"), self.get("textWidth")); @@ -280,21 +286,59 @@ export default BaseChartComponent.extend({ } }, + /** + * Gets the number of GPUs from a resource object. + * Returns -1 if no GPU resource found. + */ + getGPUs: function(resource) { + if (!resource) { + return -1; + } + let resourceInfos = resource.resourceInformations.resourceInformation; + for (var i = 0; i < resourceInfos.length; i++) { + let resourceInfo = resourceInfos[i]; + if (resourceInfo.name === "yarn.io/gpu") { + return resourceInfo.value; + } + } + return -1; + }, + + areGPUsSupported: function(model) { + let data = this.getData(model); + if (data.length < 1) { + // No nodes in the cluster + return false; + } + let node = data[0]; + let gpus = this.getGPUs(node.get("availableResource")); + return gpus > -1; + }, + calcUsage: function(data) { var selectedOption = d3.select('select').property("value"); if (selectedOption === this.memoryLabel) { - return data.get("usedMemoryMB") / - (data.get("usedMemoryMB") + data.get("availMemoryMB")); + let totalMemory = data.get("usedMemoryMB") + data.get("availMemoryMB"); + if (totalMemory === 0) { return 0; } + return data.get("usedMemoryMB") / totalMemory; } else if (selectedOption === this.cpuLabel) { - return data.get("usedVirtualCores") / - (data.get("usedVirtualCores") + data.get("availableVirtualCores")); + let totalVCores = data.get("usedVirtualCores") + + data.get("availableVirtualCores"); + if (totalVCores === 0) { return 0; } + return data.get("usedVirtualCores") / totalVCores; } else if (selectedOption === this.containersLabel) { var totalContainers = this.totalContainers; if (totalContainers === 0) { return 0; } return data.get("numContainers") / totalContainers; } + else if (selectedOption === this.gpuLabel) { + let usedGpus = Math.max(0, this.getGPUs(data.get("usedResource"))); + let availableGpus = Math.max(0, this.getGPUs(data.get("availableResource"))); + if (usedGpus + availableGpus === 0) { return 0; } + return usedGpus / (usedGpus + availableGpus); + } }, getToolTipText: function(data) { @@ -310,6 +354,11 @@ export default BaseChartComponent.extend({ else if (selectedOption === this.containersLabel) { return "

Containers: " + Math.round(data.get("numContainers")) + " Containers

" + "

Total Containers: " + this.totalContainers + " Containers

"; + } else if (selectedOption === this.gpuLabel) { + let usedGpus = Math.round(Math.max(0, this.getGPUs(data.get("usedResource")))); + let availableGpus = Math.round(Math.max(0, this.getGPUs(data.get("availableResource")))); + return "

Used GPUs: " + usedGpus + "

" + + "

Available GPUs: " + availableGpus + "

"; } } });