diff --git a/frontend/app/common/interfaces/data_table.ts b/frontend/app/common/interfaces/data_table.ts index 44a4dd51f..598d8f62e 100644 --- a/frontend/app/common/interfaces/data_table.ts +++ b/frontend/app/common/interfaces/data_table.ts @@ -378,6 +378,18 @@ declare interface PodStatsSequence { podStatsMap?: PodStatsMap[]; } +/** Chip details. */ +export declare interface Chip { + globalId?: number; + hostX?: number; + hostY?: number; + hostZ?: number; + indexOnHost?: number; + x?: number; + y?: number; + z?: number; +} + /** The base interface for information to draw topology graph. */ export declare interface PodViewerTopology { xDimension?: number; @@ -387,6 +399,7 @@ export declare interface PodViewerTopology { hostYStride?: number; hostZStride?: number; numCoresPerChip?: number; + cores?: Chip[]; } /** The base interface for a pod viewer summary. */ diff --git a/frontend/app/components/pod_viewer/topology_graph/topology_graph.ng.html b/frontend/app/components/pod_viewer/topology_graph/topology_graph.ng.html index 09bf07e47..9f724c55f 100644 --- a/frontend/app/components/pod_viewer/topology_graph/topology_graph.ng.html +++ b/frontend/app/components/pod_viewer/topology_graph/topology_graph.ng.html @@ -43,9 +43,11 @@
+

Z = {{z_axis}}

-
-
{{tooltipText}}
-
+
+
+
{{tooltipText}}
diff --git a/frontend/app/components/pod_viewer/topology_graph/topology_graph.scss b/frontend/app/components/pod_viewer/topology_graph/topology_graph.scss index 2b6a8c737..f0a230704 100644 --- a/frontend/app/components/pod_viewer/topology_graph/topology_graph.scss +++ b/frontend/app/components/pod_viewer/topology_graph/topology_graph.scss @@ -109,7 +109,7 @@ } .node-tooltip { - position: absolute; + position: fixed; background-color: white; padding: 10px; border-radius: 8px; diff --git a/frontend/app/components/pod_viewer/topology_graph/topology_graph.ts b/frontend/app/components/pod_viewer/topology_graph/topology_graph.ts index bca5f7833..d4fcaf8db 100644 --- a/frontend/app/components/pod_viewer/topology_graph/topology_graph.ts +++ b/frontend/app/components/pod_viewer/topology_graph/topology_graph.ts @@ -19,6 +19,10 @@ interface ElementInfo { y: number; } +interface Nodes { + nodes: ElementInfo[]; +} + interface ArrowElementInfo extends ElementInfo { rotate?: number; scale?: number; @@ -34,8 +38,6 @@ const LABEL_PADDING = 5; const LABEL_WIDTH = 20; const NODE_HEIGHT = 30; const NODE_WIDTH = 15; -const TOOLTIP_OFFSET_X = 20; -const TOOLTIP_OFFSET_Y = 35; const NODE_COLORS = [ '#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58' @@ -75,7 +77,7 @@ export class TopologyGraph implements OnChanges, OnDestroy { hosts: ElementInfo[] = []; labels: ElementInfo[] = []; - nodes: ElementInfo[] = []; + nodes: Nodes[] = []; colorInfos: ColorInfo[] = []; channels: number[] = []; arrows: ArrowElementInfo[] = []; @@ -128,6 +130,33 @@ export class TopologyGraph implements OnChanges, OnDestroy { return NODE_COLORS[colorIndex]; } + private getNodePositionFromCoordinates( + xCoordinate: number, yCoordinate: number, nodeId: number): ElementInfo { + const hostWidthWithPadding = HOST_PADDING + BORDER_WIDTH + this.hostWidth + + BORDER_WIDTH + HOST_PADDING; + const hostHeightWithPadding = HOST_PADDING + BORDER_WIDTH + + this.hostHeight + BORDER_WIDTH + HOST_PADDING; + const chipWidthWithPadding = CHIP_PADDING + + (BORDER_WIDTH + NODE_WIDTH) * this.nodesPerChip + BORDER_WIDTH + + CHIP_PADDING; + const chipHeightWithPadding = + CHIP_PADDING + BORDER_WIDTH + NODE_HEIGHT + BORDER_WIDTH + CHIP_PADDING; + let x = CONTAINER_MARGIN + LABEL_PADDING + LABEL_WIDTH + LABEL_PADDING; + let y = CONTAINER_MARGIN + LABEL_PADDING + LABEL_HEIGHT + LABEL_PADDING; + + x += hostWidthWithPadding * Math.floor(xCoordinate / this.hostXStride); + x += HOST_PADDING + BORDER_WIDTH + HOST_MARGIN; + x += chipWidthWithPadding * (xCoordinate % this.hostXStride); + x += CHIP_PADDING + (BORDER_WIDTH + NODE_WIDTH) * nodeId; + + y += hostHeightWithPadding * Math.floor(yCoordinate / this.hostYStride); + y += HOST_PADDING + BORDER_WIDTH + HOST_MARGIN; + y += chipHeightWithPadding * (yCoordinate % this.hostYStride); + y += CHIP_PADDING; + + return {x, y}; + } + private getNodePosition(chipId: number, nodeId: number): ElementInfo { const hostWidthWithPadding = HOST_PADDING + BORDER_WIDTH + this.hostWidth + BORDER_WIDTH + HOST_PADDING; @@ -303,18 +332,41 @@ export class TopologyGraph implements OnChanges, OnDestroy { return; } - Object.keys(this.podStatsPerCore).forEach(coreId => { - const podStatsRecord = this.podStatsPerCore![coreId]; - const chipId = podStatsRecord.chipId || 0; - const nodeId = podStatsRecord.nodeId || 0; - const nodeInfo = this.getNodePosition(chipId, nodeId); - nodeInfo.id = 'node-' + chipId.toString() + '-' + nodeId.toString(); - if (this.coreIdToReplicaIdMap && - this.coreIdToReplicaIdMap[coreId] !== undefined) { - nodeInfo.rid = this.coreIdToReplicaIdMap[coreId]; - } - this.nodes.push(nodeInfo); - }); + if (this.topology.cores) { + const numCoresPerChip = this.topology.numCoresPerChip || 1; + this.topology.cores.forEach(chip => { + for (let i = 0; i < numCoresPerChip; i++) { + const chipId = chip.globalId || 0; + const chipx = chip.x || 0; + const chipy = chip.y || 0; + const chipz = chip.z || 0; + const nodeInfo = this.getNodePositionFromCoordinates(chipx, chipy, i); + nodeInfo.id = 'node-' + chipId.toString() + '-' + i.toString(); + if (this.coreIdToReplicaIdMap && + this.coreIdToReplicaIdMap[chipId] !== undefined) { + nodeInfo.rid = this.coreIdToReplicaIdMap[chipId]; + } + if (this.nodes[chipz] === undefined) { + this.nodes[chipz] = {nodes: []}; + } + this.nodes[chipz].nodes.push(nodeInfo); + } + }); + } else { + this.nodes[0] = {nodes: []}; + Object.keys(this.podStatsPerCore).forEach(coreId => { + const podStatsRecord = this.podStatsPerCore![coreId]; + const chipId = podStatsRecord.chipId || 0; + const nodeId = podStatsRecord.nodeId || 0; + const nodeInfo = this.getNodePosition(chipId, nodeId); + nodeInfo.id = 'node-' + chipId.toString() + '-' + nodeId.toString(); + if (this.coreIdToReplicaIdMap && + this.coreIdToReplicaIdMap[coreId] !== undefined) { + nodeInfo.rid = this.coreIdToReplicaIdMap[coreId]; + } + this.nodes[0].nodes.push(nodeInfo); + }); + } } private updateSystemInfo() { @@ -399,11 +451,40 @@ export class TopologyGraph implements OnChanges, OnDestroy { }); } - showTooltip(id: string) { + showTooltip(id: string, event: MouseEvent) { this.tooltipText = ''; + this.tooltipX = event.screenX; + this.tooltipY = event.screenY; let podStatsRecord: PodStatsRecord|null = null; let coreId = ''; + const globalId = id.split('-')[1] || 0; + + const foundCore = this.topology?.cores?.find( + chip => globalId === chip.globalId?.toString()); + + if (foundCore) { + const nodeId = id.split('-')[2] || 0; + this.tooltipText += 'pos: ('; + this.tooltipText += foundCore.x; + this.tooltipText += ','; + this.tooltipText += foundCore.y; + this.tooltipText += ','; + this.tooltipText += foundCore.z; + this.tooltipText += ')\n'; + this.tooltipText += 'chip id: '; + this.tooltipText += foundCore.globalId; + this.tooltipText += '\n'; + this.tooltipText += 'node id: ' + nodeId.toString() + '\n'; + this.tooltipText += 'host: ('; + this.tooltipText += foundCore.hostX; + this.tooltipText += ','; + this.tooltipText += foundCore.hostY; + this.tooltipText += ','; + this.tooltipText += foundCore.hostZ; + this.tooltipText += ')\n'; + } + const found = Object.entries(this.podStatsPerCore || {}).find(([, value]) => { const chipId = value.chipId || 0; @@ -421,18 +502,22 @@ export class TopologyGraph implements OnChanges, OnDestroy { return; } + const chipId = podStatsRecord.chipId || 0; const nodeId = podStatsRecord.nodeId || 0; - this.tooltipText += 'pos: ('; - this.tooltipText += - (chipId % (this.hostColumns * this.hostXStride)).toString(); - this.tooltipText += ','; - this.tooltipText += - Math.floor(chipId / (this.hostColumns * this.hostXStride)).toString(); - this.tooltipText += ')\n'; + if (!foundCore) { + this.tooltipText += 'pos: ('; + this.tooltipText += + (chipId % (this.hostColumns * this.hostXStride)).toString(); + this.tooltipText += ','; + this.tooltipText += + Math.floor(chipId / (this.hostColumns * this.hostXStride)).toString(); + this.tooltipText += ')\n'; + this.tooltipText += 'chip id: ' + chipId.toString() + '\n'; + this.tooltipText += 'node id: ' + nodeId.toString() + '\n'; + } this.tooltipText += 'host: ' + (podStatsRecord.hostName || '') + '\n'; - this.tooltipText += 'chip id: ' + chipId.toString() + '\n'; - this.tooltipText += 'node id: ' + nodeId.toString() + '\n'; + if (this.coreIdToReplicaIdMap && this.coreIdToReplicaIdMap[coreId] !== undefined) { this.tooltipText += @@ -451,10 +536,6 @@ export class TopologyGraph implements OnChanges, OnDestroy { '0.00'; this.tooltipText += '% of a step.'; } - - const nodeInfo = this.getNodePosition(chipId, nodeId); - this.tooltipX = nodeInfo.x + TOOLTIP_OFFSET_X; - this.tooltipY = nodeInfo.y + TOOLTIP_OFFSET_Y; } updateChannelId(id: number) {