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

pull code #92

Merged
merged 3 commits into from
Jun 22, 2020
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
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