Unverified Commit 7978c25a authored by Lijiaoa's avatar Lijiaoa Committed by GitHub
Browse files

[webui] Improve trial parameter for retiarii experiment (#4314)

parent 971e5055
import * as React from 'react';
import * as copy from 'copy-to-clipboard';
import { Stack, PrimaryButton, Pivot, PivotItem } from '@fluentui/react';
import { Stack, PrimaryButton, Pivot, PivotItem, DefaultButton } from '@fluentui/react';
import { Trial } from '../../static/model/trial';
import { MANAGER_IP } from '../../static/const';
import { MANAGER_IP, RETIARIIPARAMETERS } from '../../static/const';
import { EXPERIMENT, TRIALS } from '../../static/datamodel';
import { reformatRetiariiParameter } from '../../static/function';
import JSONTree from 'react-json-tree';
import PaiTrialLog from '../public-child/PaiTrialLog';
import TrialLog from '../public-child/TrialLog';
import MessageInfo from '../modals/MessageInfo';
import PanelMonacoEditor from '../public-child/PanelMonacoEditor';
import '../../static/style/overview/overview.scss';
import '../../static/style/copyParameter.scss';
import '../../static/style/openRow.scss';
......@@ -20,6 +22,7 @@ interface OpenRowState {
typeInfo: string;
info: string;
isHidenInfo: boolean;
showRetiaParamPanel: boolean;
}
class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
......@@ -28,7 +31,8 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
this.state = {
typeInfo: '',
info: '',
isHidenInfo: true
isHidenInfo: true,
showRetiaParamPanel: false
};
}
......@@ -36,6 +40,14 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
this.setState(() => ({ isHidenInfo: true }));
};
hideRetiaParam = (): void => {
this.setState(() => ({ showRetiaParamPanel: false }));
};
isshowRetiaParamPanel = (): void => {
this.setState(() => ({ showRetiaParamPanel: true }));
};
/**
* info: message content
* typeInfo: message type: success | error...
......@@ -48,7 +60,7 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
copyParams = (trial: Trial): void => {
// get copy parameters
const params = JSON.stringify(trial.description.parameters, null, 4);
const params = JSON.stringify(reformatRetiariiParameter(trial.description.parameters as any), null, 4);
if (copy.default(params)) {
this.getCopyStatus('Success copy parameters to clipboard in form of python dict !', 'success');
} else {
......@@ -66,10 +78,12 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
};
render(): React.ReactNode {
const { isHidenInfo, typeInfo, info } = this.state;
const { isHidenInfo, typeInfo, info, showRetiaParamPanel } = this.state;
const trialId = this.props.trialId;
const trial = TRIALS.getTrial(trialId);
const logPathRow = trial.info.logPath || "This trial's log path is not available.";
const originParameters = trial.description.parameters;
const hasVisualHyperParams = RETIARIIPARAMETERS in originParameters;
return (
<Stack className='openRow'>
<Stack className='openRowContent'>
......@@ -82,7 +96,7 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
hideRoot={true}
shouldExpandNode={(): boolean => true} // default expandNode
getItemString={(): null => null} // remove the {} items
data={trial.description.parameters}
data={reformatRetiariiParameter(originParameters as any)}
/>
</Stack>
<Stack horizontal className='copy'>
......@@ -91,8 +105,21 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
text='Copy as json'
styles={{ root: { width: 128, marginRight: 10 } }}
/>
{hasVisualHyperParams && (
<DefaultButton
onClick={this.isshowRetiaParamPanel}
text='Original parameters'
/>
)}
{/* copy success | failed message info */}
{!isHidenInfo && <MessageInfo typeInfo={typeInfo} info={info} />}
{showRetiaParamPanel && (
<PanelMonacoEditor
hideConfigPanel={this.hideRetiaParam}
panelName='Retiarii parameters'
panelContent={JSON.stringify(originParameters, null, 2)}
/>
)}
</Stack>
</Stack>
) : (
......
import * as React from 'react';
import { Stack, Panel, PrimaryButton } from '@fluentui/react';
import MonacoEditor from 'react-monaco-editor';
import { caclMonacoEditorHeight } from '../../static/function';
import '../../static/style/logDrawer.scss';
interface LogDrawerProps {
hideConfigPanel: () => void;
panelName: string;
panelContent: string;
}
interface LogDrawerState {
panelInnerHeight: number;
}
/**
* search space
* config
* retiarii parameter
* panel
*/
class PanelMonacoEditor extends React.Component<LogDrawerProps, LogDrawerState> {
constructor(props: LogDrawerProps) {
super(props);
this.state = {
panelInnerHeight: window.innerHeight
};
}
// use arrow function for change window size met error: this.setState is not a function
setLogDrawerHeight = (): void => {
this.setState(() => ({ panelInnerHeight: window.innerHeight, innerWidth: window.innerWidth }));
};
async componentDidMount(): Promise<void> {
window.addEventListener('resize', this.setLogDrawerHeight);
}
componentWillUnmount(): void {
window.removeEventListener('resize', this.setLogDrawerHeight);
}
render(): React.ReactNode {
const { hideConfigPanel, panelName, panelContent } = this.props;
const { panelInnerHeight } = this.state;
const monacoEditorHeight = caclMonacoEditorHeight(panelInnerHeight);
return (
<Stack>
<Panel
isOpen={true}
hasCloseButton={false}
isFooterAtBottom={true}
isLightDismiss={true}
onLightDismissClick={hideConfigPanel}
>
<div className='panel'>
<div>
<div className='panelName'>{panelName}</div>
<MonacoEditor
height={monacoEditorHeight}
language='json'
theme='vs-light'
value={panelContent}
options={{
minimap: { enabled: false },
readOnly: true,
automaticLayout: true,
wordWrap: 'on'
}}
/>
</div>
<PrimaryButton text='Close' className='configClose' onClick={hideConfigPanel} />
</div>
</Panel>
</Stack>
);
}
}
export default PanelMonacoEditor;
......@@ -4,6 +4,7 @@ import ReactEcharts from 'echarts-for-react';
import { EXPERIMENT, TRIALS } from '../../static/datamodel';
import { Trial } from '../../static/model/trial';
import { TooltipForAccuracy, EventMap } from '../../static/interface';
import { reformatRetiariiParameter } from '../../static/function';
import 'echarts/lib/chart/scatter';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
......@@ -82,7 +83,11 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
<div>Trial No.: ${data.data[0]}</div>
<div>Trial ID: ${data.data[2]}</div>
<div>Default metric: ${data.data[1]}</div>
<div>Parameters: <pre>${JSON.stringify(data.data[3], null, 4)}</pre></div>
<div>Parameters: <pre>${JSON.stringify(
reformatRetiariiParameter(data.data[3]),
null,
4
)}</pre></div>
</div>
`
},
......
import * as React from 'react';
import { Stack, PrimaryButton, Toggle, IStackTokens } from '@fluentui/react';
import { TooltipForIntermediate, TableObj, Intermedia, EventMap } from '../../static/interface';
import { reformatRetiariiParameter } from '../../static/function';
import ReactEcharts from 'echarts-for-react';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/title';
......@@ -100,7 +101,11 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
<div>Trial No.: ${trialNum}</div>
<div>Trial ID: ${trialId}</div>
<div>Intermediate: ${data.data}</div>
<div>Parameters: <pre>${JSON.stringify(parameters, null, 4)}</pre>
<div>Parameters: <pre>${JSON.stringify(
reformatRetiariiParameter(parameters),
null,
4
)}</pre>
</div>
</div>
`;
......
......@@ -64,6 +64,7 @@ const SUPPORTED_SEARCH_SPACE_TYPE = [
const TOOLTIP_BACKGROUND_COLOR = '#484848';
const MAX_TRIAL_NUMBERS = 'Max trial No.';
const RETIARIIPARAMETERS = 'mutation_summary';
export {
MANAGER_IP,
......@@ -81,5 +82,6 @@ export {
CONCURRENCYTOOLTIP,
SUPPORTED_SEARCH_SPACE_TYPE,
TOOLTIP_BACKGROUND_COLOR,
MAX_TRIAL_NUMBERS
MAX_TRIAL_NUMBERS,
RETIARIIPARAMETERS
};
import * as JSON5 from 'json5';
import axios from 'axios';
import { IContextualMenuProps } from '@fluentui/react';
import { MANAGER_IP } from './const';
import { MANAGER_IP, RETIARIIPARAMETERS } from './const';
import { EXPERIMENT } from './datamodel';
import { MetricDataRecord, FinalType, TableObj, Tensorboard } from './interface';
......@@ -375,6 +375,11 @@ const parametersType = (): Map<string, string> => {
return parametersTypeMap;
};
// retiarii experiment parameters is in field `mutation_summary`
const reformatRetiariiParameter = (parameters: any): {} => {
return RETIARIIPARAMETERS in parameters ? parameters[RETIARIIPARAMETERS] : parameters;
};
export {
getPrefix,
convertTime,
......@@ -401,5 +406,6 @@ export {
copyAndSort,
disableTensorboard,
getTensorboardMenu,
parametersType
parametersType,
reformatRetiariiParameter
};
......@@ -228,10 +228,6 @@ interface SearchItems {
isChoice: boolean; // for parameters: type = choice and status also as choice type
}
interface RetiariiParameter {
mutation_summary: object; // retiarii experiment's parameter
}
export {
TableObj,
TableRecord,
......@@ -257,6 +253,5 @@ export {
SortInfo,
AllExperimentList,
Tensorboard,
SearchItems,
RetiariiParameter
SearchItems
};
......@@ -7,8 +7,7 @@ import {
Parameters,
FinalType,
MultipleAxes,
SingleAxis,
RetiariiParameter
SingleAxis
} from '../interface';
import {
getFinal,
......@@ -17,7 +16,8 @@ import {
parseMetrics,
isArrayType,
isNaNorInfinity,
formatComplexTypeValue
formatComplexTypeValue,
reformatRetiariiParameter
} from '../function';
/**
......@@ -32,8 +32,7 @@ function inferTrialParameters(
space: MultipleAxes,
prefix: string = ''
): [Map<SingleAxis, any>, Map<string, any>] {
const latestedParamObj =
'mutation_summary' in paramObj ? (paramObj as RetiariiParameter).mutation_summary : paramObj;
const latestedParamObj: object = reformatRetiariiParameter(paramObj);
const parameters = new Map<SingleAxis, any>();
const unexpectedEntries = new Map<string, any>();
for (const [k, v] of Object.entries(latestedParamObj)) {
......
......@@ -54,6 +54,11 @@ $bgColor: #f2f2f2;
outline: none;
}
}
.ms-MessageBar {
width: 70%;
margin-left: 15px;
}
}
#visualizationText {
......
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