Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update pod_viewer display. #699

Merged
merged 1 commit into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions frontend/app/common/interfaces/data_table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -387,6 +399,7 @@ export declare interface PodViewerTopology {
hostYStride?: number;
hostZStride?: number;
numCoresPerChip?: number;
cores?: Chip[];
}

/** The base interface for a pod viewer summary. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
</div>
</div>
<div
*ngFor="let z_nodes of nodes; let z_axis=index;"
class="container"
[style.width]="containerWidth + 'px'"
[style.height]="containerHeight + 'px'">
<p>Z = {{z_axis}}</p>
<div
*ngFor="let label of labels"
class="label"
Expand All @@ -60,13 +62,13 @@
[style.left]="host.x + 'px'">
</div>
<div
*ngFor="let node of nodes"
*ngFor="let node of z_nodes.nodes"
class="node"
[id]="node.id"
[attr.rid]="node.rid"
[style.top]="node.y + 'px'"
[style.left]="node.x + 'px'"
(mouseenter)="showTooltip(node.id)"
(mouseenter)="showTooltip(node.id, $event)"
(mouseleave)="hideTooltip()">
</div>
<div
Expand All @@ -83,13 +85,13 @@
</g>
</svg>
</div>
<div
class="node-tooltip mat-elevation-z2"
[style.left]="tooltipX + 'px'"
[style.top]="tooltipY + 'px'"
[hidden]="!tooltipText">
</div>
<div
class="node-tooltip mat-elevation-z2"
[style.left]="tooltipX + 'px'"
[style.top]="tooltipY + 'px'"
[hidden]="!tooltipText">
<pre>{{tooltipText}}</pre>
</div>
</div>

<div class="color-table">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
}

.node-tooltip {
position: absolute;
position: fixed;
background-color: white;
padding: 10px;
border-radius: 8px;
Expand Down
161 changes: 130 additions & 31 deletions frontend/app/components/pod_viewer/topology_graph/topology_graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ interface ElementInfo {
y: number;
}

interface Nodes {
nodes: ElementInfo[];
}

interface ArrowElementInfo extends ElementInfo {
rotate?: number;
scale?: number;
Expand All @@ -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'
Expand Down Expand Up @@ -75,7 +77,9 @@ export class TopologyGraph implements OnChanges, OnDestroy {

hosts: ElementInfo[] = [];
labels: ElementInfo[] = [];
nodes: ElementInfo[] = [];
// Since we currently do not support 3d visualizations, We will unwrap the z
// axis and create a 2d plane for each z axis.
nodes: Nodes[] = [];
colorInfos: ColorInfo[] = [];
channels: number[] = [];
arrows: ArrowElementInfo[] = [];
Expand Down Expand Up @@ -128,6 +132,37 @@ export class TopologyGraph implements OnChanges, OnDestroy {
return NODE_COLORS[colorIndex];
}

/**
* Get the node coordinates to relatively position the node within the
* container. We create a new container for each z axis.
*/
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;
Expand Down Expand Up @@ -296,25 +331,60 @@ export class TopologyGraph implements OnChanges, OnDestroy {
}
}

private createElementId(chipId: number, node: number): string {
return 'node-' + chipId.toString() + '-' + node.toString();
}

private getChipId(id: string): number {
return Number(id.split('-')[1]);
}

private getNodeId(id: string): number {
return Number(id.split('-')[2]);
}

private updateNodes() {
this.nodes = [];

if (!this.topology || !this.podStatsPerCore) {
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 && this.topology.cores.length > 0) {
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 = this.createElementId(chipId, i);
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 = this.createElementId(chipId, nodeId);
if (this.coreIdToReplicaIdMap &&
this.coreIdToReplicaIdMap[coreId] !== undefined) {
nodeInfo.rid = this.coreIdToReplicaIdMap[coreId];
}
this.nodes[0].nodes.push(nodeInfo);
});
}
}

private updateSystemInfo() {
Expand Down Expand Up @@ -386,7 +456,7 @@ export class TopologyGraph implements OnChanges, OnDestroy {
Object.values(this.podStatsPerCore).forEach(podStatsRecord => {
const chipId = podStatsRecord.chipId || 0;
const nodeId = podStatsRecord.nodeId || 0;
const id = 'node-' + chipId.toString() + '-' + nodeId.toString();
const id = this.createElementId(chipId, nodeId);
const nodeEl = this.elRef.nativeElement.querySelector('#' + id);
if (nodeEl) {
let value = utils.getPodStatsRecordBreakdownProperty(
Expand All @@ -399,16 +469,45 @@ export class TopologyGraph implements OnChanges, OnDestroy {
});
}

showTooltip(id: string) {
showTooltip(id: string, event: MouseEvent) {
this.tooltipText = '';
this.tooltipX = event.x;
this.tooltipY = event.y;
let podStatsRecord: PodStatsRecord|null = null;
let coreId = '';

const globalId = this.getChipId(id);

const foundCore =
this.topology?.cores?.find(chip => globalId === chip.globalId);

if (foundCore) {
const nodeId = this.getNodeId(id);
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;
const nodeId = value.nodeId || 0;
return id === 'node-' + chipId.toString() + '-' + nodeId.toString();
return id === this.createElementId(chipId, nodeId);
});

if (!found || found.length !== 2) {
Expand All @@ -421,18 +520,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 +=
Expand All @@ -451,10 +554,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) {
Expand Down
Loading