"...tutorials/git@developer.sourcefind.cn:OpenDAS/nni.git" did not exist on "fbee0df1205ec0f9557c24398526510b92da306f"
Unverified Commit 67ea3304 authored by Yuge Zhang's avatar Yuge Zhang Committed by GitHub
Browse files

Fix bugs in NAS UI (deferred from previous releases) (#2552)

* Fix NASUI bugs

* Add pipeline for NASUI

* update log

* Move graph utils test to test folder
parent 885a2580
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"start": "react-scripts start", "start": "react-scripts start",
"build": "react-scripts build", "build": "react-scripts build",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"test": "react-scripts test",
"backend": "node server.js" "backend": "node server.js"
}, },
"eslintConfig": { "eslintConfig": {
......
...@@ -29,6 +29,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; ...@@ -29,6 +29,7 @@ import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import List from '@material-ui/core/List'; import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem'; import ListItem from '@material-ui/core/ListItem';
import Backdrop from '@material-ui/core/Backdrop'; import Backdrop from '@material-ui/core/Backdrop';
import Tooltip from '@material-ui/core/Tooltip';
import Chart from './Chart'; import Chart from './Chart';
import { Graph } from './graphUtils'; import { Graph } from './graphUtils';
...@@ -272,15 +273,21 @@ class App extends React.Component<AppProps, AppState> { ...@@ -272,15 +273,21 @@ class App extends React.Component<AppProps, AppState> {
<Typography variant='h6' className={classes.title}> <Typography variant='h6' className={classes.title}>
NNI NAS Board NNI NAS Board
</Typography> </Typography>
<IconButton color='inherit' onClick={handleLayoutStateChanged(true)}> <Tooltip title="Re-layout graph">
<ShuffleIcon /> <IconButton color='inherit' onClick={handleLayoutStateChanged(true)}>
</IconButton> <ShuffleIcon />
<IconButton color='inherit' onClick={this.refresh}> </IconButton>
<RefreshIcon /> </Tooltip>
</IconButton> <Tooltip title="Refresh">
<IconButton color='inherit' onClick={handleSettingsDialogToggle(true)}> <IconButton color='inherit' onClick={this.refresh}>
<SettingsIcon /> <RefreshIcon />
</IconButton> </IconButton>
</Tooltip>
<Tooltip title="Settings">
<IconButton color='inherit' onClick={handleSettingsDialogToggle(true)}>
<SettingsIcon />
</IconButton>
</Tooltip>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
<AppBar position='fixed' color='default' className={classes.bottomAppBar}> <AppBar position='fixed' color='default' className={classes.bottomAppBar}>
......
...@@ -91,6 +91,7 @@ export default class Chart extends React.Component<ChartProps> { ...@@ -91,6 +91,7 @@ export default class Chart extends React.Component<ChartProps> {
expandSet: Set<string> = new Set<string>(); expandSet: Set<string> = new Set<string>();
elemWeight: Map<string, number> = new Map<string, number>(); elemWeight: Map<string, number> = new Map<string, number>();
graphEl: any[] = []; graphEl: any[] = [];
private firstUpdate = true;
componentDidMount() { componentDidMount() {
this.cyInstance = cytoscape({ this.cyInstance = cytoscape({
...@@ -149,7 +150,8 @@ export default class Chart extends React.Component<ChartProps> { ...@@ -149,7 +150,8 @@ export default class Chart extends React.Component<ChartProps> {
} }
} else { } else {
// re-calculate collapse // re-calculate collapse
this.renderGraph(true); this.renderGraph(true, this.firstUpdate);
this.firstUpdate = false;
} }
} }
...@@ -245,7 +247,7 @@ export default class Chart extends React.Component<ChartProps> { ...@@ -245,7 +247,7 @@ export default class Chart extends React.Component<ChartProps> {
setTimeout(_render, 100); setTimeout(_render, 100);
} }
private renderGraph(graphChanged: boolean) { private renderGraph(graphChanged: boolean, fit: boolean = false) {
const { graph } = this.props; const { graph } = this.props;
if (graph === undefined) if (graph === undefined)
return; return;
...@@ -269,7 +271,9 @@ export default class Chart extends React.Component<ChartProps> { ...@@ -269,7 +271,9 @@ export default class Chart extends React.Component<ChartProps> {
this.cyInstance!.json({ this.cyInstance!.json({
elements: graphEl elements: graphEl
}); });
layout.fit = false; if (!fit) {
layout.fit = false;
}
eles.layout(layout).run(); eles.layout(layout).run();
} }
} else { } else {
......
import { Graph } from '../graphUtils';
import * as fs from 'fs';
describe('Graph utils test', () => {
it('Graph constructor darts', () => {
const graph = new Graph(JSON.parse(fs.readFileSync('assets/darts/graph.json').toString()), true);
const activation = JSON.parse(fs.readFileSync('assets/darts/log').toString().split('\n')[0]);
expect(graph.nodes.length).toEqual(1842);
expect(graph.edges.length).toEqual(927);
const weights = graph.weightFromMutables(activation);
expect(weights.get('["CNN/ModuleList[cells]/Cell[1]/ModuleList[mutable_ops]/Node[0]/InputChoice[input_switch]/input.228",' +
'"CNN/ModuleList[cells]/Cell[1]/ModuleList[mutable_ops]/Node[1]/ModuleList[ops]/' +
'LayerChoice[2]/PoolBN[maxpool]/MaxPool2d[pool]/input.229"]')).toBeCloseTo(0.125, 3);
});
it('Graph constructor naive', () => {
const graph = new Graph(JSON.parse(fs.readFileSync('assets/naive/graph.json').toString()), true);
expect(graph.nodes.length).toEqual(51);
expect(graph.edges.length).toEqual(37);
expect(graph.mutableEdges.get('LayerChoice1')![0].length).toEqual(5);
expect(graph.mutableEdges.get('LayerChoice1')![1].length).toEqual(5);
expect(graph.mutableEdges.get('LayerChoice2')![0].length).toEqual(5);
expect(graph.mutableEdges.get('LayerChoice2')![1].length).toEqual(5);
expect(graph.mutableEdges.get('InputChoice3')![0].length).toEqual(4);
});
});
...@@ -47,6 +47,10 @@ export class NodeTs { ...@@ -47,6 +47,10 @@ export class NodeTs {
isParent(): boolean { isParent(): boolean {
return this.children.length > 0; return this.children.length > 0;
} }
toString(): string {
return `Node(id=${this.id})`;
}
}; };
export class Edge { export class Edge {
...@@ -59,6 +63,10 @@ export class Edge { ...@@ -59,6 +63,10 @@ export class Edge {
this.target = target; this.target = target;
this.id = JSON.stringify([this.source.id, this.target.id]); this.id = JSON.stringify([this.source.id, this.target.id]);
} }
toString(): string {
return `Edge(${this.source} -> ${this.target})`;
}
}; };
interface NodeSummary { interface NodeSummary {
...@@ -76,12 +84,12 @@ export class Graph { ...@@ -76,12 +84,12 @@ export class Graph {
nodes: NodeTs[]; nodes: NodeTs[];
edges: Edge[]; edges: Edge[];
defaultExpandSet: Set<string>; defaultExpandSet: Set<string>;
mutableEdges: Map<string, Edge[][]>;
private id2idx: Map<string, number>; private id2idx: Map<string, number>;
private edgeId2idx: Map<string, number>; private edgeId2idx: Map<string, number>;
private forwardGraph: Map<string, string[]>; private forwardGraph: Map<string, string[]>;
private backwardGraph: Map<string, string[]>; private backwardGraph: Map<string, string[]>;
private node2edge: Map<string, Edge[]>; private node2edge: Map<string, Edge[]>;
private mutableEdges: Map<string, Edge[][]>;
private build() { private build() {
this.id2idx.clear(); this.id2idx.clear();
...@@ -359,17 +367,25 @@ export class Graph { ...@@ -359,17 +367,25 @@ export class Graph {
weightFromMutables(mutable: any): Map<string, number> { weightFromMutables(mutable: any): Map<string, number> {
const elemWeight = new Map<string, number>(); const elemWeight = new Map<string, number>();
Object.entries(mutable).forEach(entry => { Object.entries(mutable).forEach(entry => {
const elemWeightPartial = new Map<string, number>();
const key = entry[0]; const key = entry[0];
const weights = entry[1] as number[]; const weights = entry[1] as number[];
this.mutableEdges.get(key)!.forEach((edges: any, i: number) => { this.mutableEdges.get(key)!.forEach((edges: any, i: number) => {
edges.forEach((edge: any) => { edges.forEach((edge: any) => {
if (elemWeight.has(edge.id)) { if (elemWeightPartial.has(edge.id)) {
elemWeight.set(edge.id, elemWeight.get(edge.id)! + weights[i]); elemWeightPartial.set(edge.id, elemWeightPartial.get(edge.id)! + weights[i]);
} else { } else {
elemWeight.set(edge.id, weights[i]); elemWeightPartial.set(edge.id, weights[i]);
} }
}) })
}); });
elemWeightPartial.forEach((v, k) => {
if (elemWeight.has(k)) {
elemWeight.set(k, Math.min(elemWeight.get(k)!, v));
} else {
elemWeight.set(k, v);
}
});
}); });
this.nodes.forEach(node => { this.nodes.forEach(node => {
const edges = this.connectedEdges(node.id); const edges = this.connectedEdges(node.id);
......
...@@ -26,6 +26,12 @@ echo "" ...@@ -26,6 +26,12 @@ echo ""
echo "===========================Testing: nni_manager===========================" echo "===========================Testing: nni_manager==========================="
npm run test npm run test
# -------------For NASUI unittest-------------
cd ${CWD}/../src/nasui
echo ""
echo "===========================Testing: nasui==========================="
CI=true npm test
## ------Run nnictl unit test------ ## ------Run nnictl unit test------
echo "" echo ""
echo "===========================Testing: nnictl===========================" echo "===========================Testing: nnictl==========================="
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment