Skip to content

Commit

Permalink
Merge pull request #92 from microsoft/master
Browse files Browse the repository at this point in the history
pull code
  • Loading branch information
chicm-ms authored Jun 22, 2020
2 parents 32bedcc + a17632b commit 6155aa4
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 66 deletions.
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ jobs:
echo "##vso[task.setvariable variable=PATH]${HOME}/Library/Python/3.7/bin:${PATH}"
displayName: 'Install python tools'
- script: |
echo "network-timeout 600000" >> ${HOME}/.yarnrc
source install.sh
displayName: 'Install nni toolkit via source code'
- script: |
Expand Down
1 change: 1 addition & 0 deletions deployment/pypi/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
'PythonWebHDFS',
'hyperopt==0.1.2',
'json_tricks',
'netifaces',
'numpy',
'scipy',
'coverage',
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def read(fname):
'astor',
'hyperopt==0.1.2',
'json_tricks',
'netifaces',
'numpy',
'psutil',
'ruamel.yaml',
Expand Down
2 changes: 1 addition & 1 deletion src/webui/src/components/Modals/Compare.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import IntermediateVal from '../public-child/IntermediateVal';
import { TRIALS } from '../../static/datamodel';
import { contentStyles, iconButtonStyles } from '../Buttons/ModalTheme';
import '../../static/style/compare.scss';
import { TableRecord, Intermedia, TooltipForIntermediate } from '../../static/interface'; // eslint-disable-line no-unused-vars
import { TableRecord, Intermedia, TooltipForIntermediate } from '../../static/interface';

// the modal of trial compare
interface CompareProps {
Expand Down
2 changes: 1 addition & 1 deletion src/webui/src/components/trial-detail/Duration.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react';
import ReactEcharts from 'echarts-for-react';
import { TableObj, EventMap } from '../../static/interface'; // eslint-disable-line no-unused-vars
import { TableObj, EventMap } from '../../static/interface';
import { filterDuration, convertDuration } from '../../static/function';
import 'echarts/lib/chart/bar';
import 'echarts/lib/component/tooltip';
Expand Down
168 changes: 105 additions & 63 deletions src/webui/src/components/trial-detail/Para.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import * as React from 'react';
import ReactEcharts from 'echarts-for-react';
import { filterByStatus } from '../../static/function';
import { EXPERIMENT } from '../../static/datamodel';
import { Stack, PrimaryButton, Dropdown, IDropdownOption, } from 'office-ui-fabric-react'; // eslint-disable-line no-unused-vars
import { ParaObj, Dimobj, TableObj } from '../../static/interface'; // eslint-disable-line no-unused-vars
import { Stack, PrimaryButton, Dropdown, IDropdownOption } from 'office-ui-fabric-react';
import { ParaObj, Dimobj, TableObj } from '../../static/interface';
import 'echarts/lib/chart/parallel';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
Expand All @@ -28,6 +28,8 @@ interface ParaState {
// office-fabric-ui
selectedItem?: { key: string | number | undefined }; // percent Selector
swapyAxis?: string[]; // yAxis Selector
paraYdataNested: number[][];
isNested: false;
}

interface ParaProps {
Expand Down Expand Up @@ -68,7 +70,9 @@ class Para extends React.Component<ParaProps, ParaState> {
succeedRenderCount: 10000000,
clickCounts: 1,
isLoadConfirm: false,
swapyAxis: []
swapyAxis: [],
paraYdataNested: [],
isNested: false
};
}

Expand All @@ -79,23 +83,29 @@ class Para extends React.Component<ParaProps, ParaState> {
lengthofTrials: number
): void => {
// get data for every lines. if dim is choice type, number -> toString()
const paraYdata: number[][] = [];
Object.keys(eachTrialParams).map(item => {
const temp: number[] = [];
for (let i = 0; i < dimName.length; i++) {
if ('type' in parallelAxis[i]) {
temp.push(eachTrialParams[item][dimName[i]].toString());
} else {
// default metric
temp.push(eachTrialParams[item][dimName[i]]);
let paraYdata: number[][] = [];
const { isNested } = this.state;
if (isNested === false) {
for (const item of eachTrialParams) {
const temp: number[] = [];
for (let i = 0; i < dimName.length; i++) {
if ('type' in parallelAxis[i]) {
temp.push(item[dimName[i]].toString());
} else {
// default metric
temp.push(item[dimName[i]]);
}
}
paraYdata.push(temp);
}
paraYdata.push(temp);
});
} else {
paraYdata = this.state.paraYdataNested;
}
// add acc
Object.keys(paraYdata).map(item => {
paraYdata[item].push(accPara[item]);
});

// according acc to sort ydata // sort to find top percent dataset
if (paraYdata.length !== 0) {
const len = paraYdata[0].length - 1;
Expand Down Expand Up @@ -133,7 +143,7 @@ class Para extends React.Component<ParaProps, ParaState> {
const lenOfDataSource: number = dataSource.length;
const accPara: number[] = [];
// specific value array
const eachTrialParams: string[] = [];
const eachTrialParams: Array<any> = [];
// experiment interface search space obj
const searchRange = searchSpace !== undefined ? JSON.parse(searchSpace) : '';
// nest search space
Expand All @@ -144,13 +154,15 @@ class Para extends React.Component<ParaProps, ParaState> {
return;
}
});
const dimName = Object.keys(searchRange);
this.setState({ dimName: dimName });

let dimName: string[] = [];
const parallelAxis: Array<Dimobj> = [];
// search space range and specific value [only number]
let i = 0;
const yAxisOrderList = new Map();
this.setState({ isNested: isNested });
if (isNested === false) {
dimName = Object.keys(searchRange);
this.setState({ dimName: dimName });
for (i; i < dimName.length; i++) {
const data: string[] = [];
const searchKey = searchRange[dimName[i]];
Expand Down Expand Up @@ -223,37 +235,25 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
} else {
for (i; i < dimName.length; i++) {
const searchKey = searchRange[dimName[i]];
const data: string[] = [];
let j = 0;
switch (searchKey._type) {
case 'choice':
for (j; j < searchKey._value.length; j++) {
const item = searchKey._value[j];
Object.keys(item).map(key => {
if (key !== '_name' && key !== '_type') {
Object.keys(item[key]).map(index => {
if (index !== '_type') {
const realChoice = item[key][index];
Object.keys(realChoice).map(m => {
data.push(`${item._name}_${realChoice[m]}`);
});
}
});
}
});
for (const parallelAxisName in searchRange) {
const data: any[] = [];
dimName.push(parallelAxisName);

for (const choiceItem in searchRange[parallelAxisName]) {
if (choiceItem === '_value') {
for (const item in searchRange[parallelAxisName][choiceItem]) {
data.push(searchRange[parallelAxisName][choiceItem][item]._name);
}
data.push('null');
yAxisOrderList.set(parallelAxisName, JSON.parse(JSON.stringify(data)));
parallelAxis.push({
dim: i,
name: dimName[i],
type: 'category',
data: data,
name: parallelAxisName,
type: 'category',
boundaryGap: true,
axisLine: {
lineStyle: {
type: 'dotted', // axis type,solid dashed dotted
type: 'dotted', // axis type,soliddasheddotted
width: 1
}
},
Expand All @@ -266,16 +266,44 @@ class Para extends React.Component<ParaProps, ParaState> {
show: true,
interval: 0,
// rotate: 30
},
});
break;
default:
parallelAxis.push({
dim: i,
name: dimName[i]
}
});
i++;
for (const item in searchRange[parallelAxisName][choiceItem]) {
for (const key in searchRange[parallelAxisName][choiceItem][item]) {
if (key !== '_name') {
dimName.push(key);
parallelAxis.push({
dim: i,
data: searchRange[parallelAxisName][choiceItem][item][key]._value.concat('null'),
name: `${searchRange[parallelAxisName][choiceItem][item]._name}_${key}`,
type: 'category',
boundaryGap: true,
axisLine: {
lineStyle: {
type: 'dotted', // axis type,solid,dashed,dotted
width: 1
}
},
axisTick: {
show: true,
interval: 0,
alignWithLabel: true,
},
axisLabel: {
show: true,
interval: 0,
// rotate: 30
}
});
i++;
}
}
}
}
}
}
this.setState({ dimName: dimName });
}
parallelAxis.push({
dim: i,
Expand All @@ -291,6 +319,7 @@ class Para extends React.Component<ParaProps, ParaState> {
tooltip: {
trigger: 'item'
},

parallel: {
parallelAxisDefault: {
tooltip: {
Expand Down Expand Up @@ -332,7 +361,7 @@ class Para extends React.Component<ParaProps, ParaState> {
} else {
Object.keys(dataSource).map(item => {
const trial = dataSource[item];
eachTrialParams.push(trial.description.parameters || '');
eachTrialParams.push(trial.description.parameters);
// may be a succeed trial hasn't final result
// all detail page may be break down if havn't if
if (trial.acc !== undefined) {
Expand All @@ -341,22 +370,35 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
});
// nested search space, deal data
// nested search space, fill all yAxis data
if (isNested !== false) {
eachTrialParams.forEach(element => {
Object.keys(element).forEach(key => {
const item = element[key];
if (typeof item === 'object') {
Object.keys(item).forEach(index => {
if (index !== '_name') {
element[key] = `${item._name}_${item[index]}`;
const renderDataSource: Array<any> = [];
for (const i in eachTrialParams) {
const eachTrialData: Array<any> = [];
for (const m in eachTrialParams[i]) {
const eachTrialParamsObj = eachTrialParams[i][m];
for (const n in yAxisOrderList.get(m)) {
if (yAxisOrderList.get(m)[n] === eachTrialParamsObj._name) {
for (const index in eachTrialParamsObj) {
if (index !== '_name') {
eachTrialData.push(eachTrialParamsObj[index].toString());
}
if (eachTrialParamsObj[index] === 'Empty') {
eachTrialData.push('Empty');
}
}
} else {
if (yAxisOrderList.get(m)[n] === 'Empty') {
eachTrialData.push(eachTrialParamsObj._name.toString());
} else {
element[key] = 'null';
eachTrialData.push('null');
}
});
}
}
});
});
}
renderDataSource.push(eachTrialData);
}
this.setState({ paraYdataNested: renderDataSource });
}
// if not return final result
const maxVal = accPara.length === 0 ? 1 : Math.max(...accPara);
Expand Down Expand Up @@ -592,7 +634,7 @@ class Para extends React.Component<ParaProps, ParaState> {
}

componentDidUpdate(prevProps: ParaProps): void {
if(this.props.dataSource !== prevProps.dataSource) {
if (this.props.dataSource !== prevProps.dataSource) {
const { dataSource, expSearchSpace, whichGraph } = this.props;
if (whichGraph === 'Hyper-parameter') {
this.hyperParaPic(dataSource, expSearchSpace);
Expand Down
10 changes: 10 additions & 0 deletions tools/nni_cmd/launcher_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import os
import json
import netifaces
from schema import SchemaError
from schema import Schema
from .config_schema import LOCAL_CONFIG_SCHEMA, REMOTE_CONFIG_SCHEMA, PAI_CONFIG_SCHEMA, PAI_YARN_CONFIG_SCHEMA, \
Expand Down Expand Up @@ -297,10 +298,19 @@ def validate_pai_trial_conifg(experiment_config):
print_warning(warning_information.format('outputDir'))
validate_pai_config_path(experiment_config)

def validate_eth0_device(experiment_config):
'''validate whether the machine has eth0 device'''
if experiment_config.get('trainingServicePlatform') not in ['local'] \
and not experiment_config.get('nniManagerIp') \
and 'eth0' not in netifaces.interfaces():
print_error('This machine does not contain eth0 network device, please set nniManagerIp in config file!')
exit(1)

def validate_all_content(experiment_config, config_path):
'''Validate whether experiment_config is valid'''
parse_path(experiment_config, config_path)
validate_common_content(experiment_config)
validate_eth0_device(experiment_config)
validate_pai_trial_conifg(experiment_config)
experiment_config['maxExecDuration'] = parse_time(experiment_config['maxExecDuration'])
if experiment_config.get('advisor'):
Expand Down
3 changes: 2 additions & 1 deletion tools/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
'astor',
'schema',
'PythonWebHDFS',
'colorama'
'colorama',
'netifaces'
],

author = 'Microsoft NNI Team',
Expand Down

0 comments on commit 6155aa4

Please sign in to comment.