Unverified Commit 1bd17a02 authored by Yuge Zhang's avatar Yuge Zhang Committed by GitHub
Browse files

[Retiarii] Visualization (#3878)

parent 4b38e64f
...@@ -503,6 +503,13 @@ ...@@ -503,6 +503,13 @@
"@types/minimatch" "*" "@types/minimatch" "*"
"@types/node" "*" "@types/node" "*"
"@types/http-proxy@^1.17.7":
version "1.17.7"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.7.tgz#30ea85cc2c868368352a37f0d0d3581e24834c6f"
integrity sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==
dependencies:
"@types/node" "*"
"@types/js-base64@^3.3.1": "@types/js-base64@^3.3.1":
version "3.3.1" version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/js-base64/-/js-base64-3.3.1.tgz#36c2d6dc126277ea28a4d0599d0cafbf547b51e6" resolved "https://registry.yarnpkg.com/@types/js-base64/-/js-base64-3.3.1.tgz#36c2d6dc126277ea28a4d0599d0cafbf547b51e6"
...@@ -2071,6 +2078,11 @@ etag@~1.8.1: ...@@ -2071,6 +2078,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
execa@^0.7.0: execa@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
...@@ -2273,6 +2285,11 @@ flatted@^3.1.0: ...@@ -2273,6 +2285,11 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
follow-redirects@^1.0.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
for-in@^0.1.3: for-in@^0.1.3:
version "0.1.8" version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
...@@ -2715,6 +2732,15 @@ http-proxy-agent@^4.0.1: ...@@ -2715,6 +2732,15 @@ http-proxy-agent@^4.0.1:
agent-base "6" agent-base "6"
debug "4" debug "4"
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
dependencies:
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
http-signature@~1.2.0: http-signature@~1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
...@@ -5010,6 +5036,11 @@ require-main-filename@^2.0.0: ...@@ -5010,6 +5036,11 @@ require-main-filename@^2.0.0:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
resolve-from@^4.0.0: resolve-from@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
......
...@@ -56,8 +56,13 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> { ...@@ -56,8 +56,13 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
} }
}; };
openTrialLog = (type: string): void => { openTrialLog = (filename: string): void => {
window.open(`${MANAGER_IP}/trial-log/${this.props.trialId}/${type}`); window.open(`${MANAGER_IP}/trial-file/${this.props.trialId}/${filename}`);
};
openModelOnnx = (): void => {
// TODO: netron might need prefix.
window.open(`/netron/index.html?url=${MANAGER_IP}/trial-file/${this.props.trialId}/model.onnx`);
}; };
render(): React.ReactNode { render(): React.ReactNode {
...@@ -113,16 +118,16 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> { ...@@ -113,16 +118,16 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
<div id='trialog'> <div id='trialog'>
<div className='copy' style={{ marginTop: 15 }}> <div className='copy' style={{ marginTop: 15 }}>
<PrimaryButton <PrimaryButton
onClick={this.openTrialLog.bind(this, 'TRIAL_LOG')} onClick={this.openTrialLog.bind(this, 'trial.log')}
text='View trial log' text='View trial log'
/> />
<PrimaryButton <PrimaryButton
onClick={this.openTrialLog.bind(this, 'TRIAL_ERROR')} onClick={this.openTrialLog.bind(this, 'stderr')}
text='View trial error' text='View trial error'
styles={{ root: { marginLeft: 15 } }} styles={{ root: { marginLeft: 15 } }}
/> />
<PrimaryButton <PrimaryButton
onClick={this.openTrialLog.bind(this, 'TRIAL_STDOUT')} onClick={this.openTrialLog.bind(this, 'stdout')}
text='View trial stdout' text='View trial stdout'
styles={{ root: { marginLeft: 15 } }} styles={{ root: { marginLeft: 15 } }}
/> />
...@@ -132,6 +137,18 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> { ...@@ -132,6 +137,18 @@ class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
) )
} }
</PivotItem> </PivotItem>
{EXPERIMENT.metadata.tag.includes('retiarii') ? (
<PivotItem headerText='Visualization' key='3' itemIcon='FlowChart'>
<div id='visualization'>
<div id='visualizationText'>Visualize models with 3rd-party tools.</div>
<PrimaryButton
onClick={this.openModelOnnx.bind(this)}
text='Netron'
styles={{ root: { marginLeft: 15 } }}
/>
</div>
</PivotItem>
) : null}
</Pivot> </Pivot>
</Stack> </Stack>
</Stack> </Stack>
......
...@@ -165,6 +165,21 @@ interface ExperimentProfile { ...@@ -165,6 +165,21 @@ interface ExperimentProfile {
revision: number; revision: number;
} }
interface ExperimentMetadata {
id: string;
port: number;
startTime: number | string;
endTime: number | string;
status: string;
platform: string;
experimentName: string;
tag: any[];
pid: number;
webuiUrl: any[];
logDir: string;
prefixUrl: string | null;
}
interface NNIManagerStatus { interface NNIManagerStatus {
status: string; status: string;
errors: string[]; errors: string[];
...@@ -230,6 +245,7 @@ export { ...@@ -230,6 +245,7 @@ export {
MetricDataRecord, MetricDataRecord,
TrialJobInfo, TrialJobInfo,
ExperimentProfile, ExperimentProfile,
ExperimentMetadata,
NNIManagerStatus, NNIManagerStatus,
EventMap, EventMap,
SingleAxis, SingleAxis,
......
import { MANAGER_IP } from '../const'; import { MANAGER_IP } from '../const';
import { ExperimentConfig, toSeconds } from '../experimentConfig'; import { ExperimentConfig, toSeconds } from '../experimentConfig';
import { ExperimentProfile, NNIManagerStatus } from '../interface'; import { ExperimentProfile, ExperimentMetadata, NNIManagerStatus } from '../interface';
import { requestAxios } from '../function'; import { requestAxios } from '../function';
import { SearchSpace } from './searchspace'; import { SearchSpace } from './searchspace';
...@@ -32,8 +32,24 @@ const emptyProfile: ExperimentProfile = { ...@@ -32,8 +32,24 @@ const emptyProfile: ExperimentProfile = {
revision: 0 revision: 0
}; };
const emptyMetadata: ExperimentMetadata = {
id: '',
port: 0,
startTime: '',
endTime: '',
status: '',
platform: '',
experimentName: '',
tag: [],
pid: 0,
webuiUrl: [],
logDir: '',
prefixUrl: null
};
class Experiment { class Experiment {
private profileField?: ExperimentProfile; private profileField?: ExperimentProfile;
private metadataField?: ExperimentMetadata = undefined;
private statusField?: NNIManagerStatus = undefined; private statusField?: NNIManagerStatus = undefined;
private isNestedExperiment: boolean = false; private isNestedExperiment: boolean = false;
private isexperimentError: boolean = false; private isexperimentError: boolean = false;
...@@ -82,10 +98,14 @@ class Experiment { ...@@ -82,10 +98,14 @@ class Experiment {
public async update(): Promise<boolean> { public async update(): Promise<boolean> {
let updated = false; let updated = false;
await requestAxios(`${MANAGER_IP}/experiment`) await Promise.all([requestAxios(`${MANAGER_IP}/experiment`), requestAxios(`${MANAGER_IP}/experiment-metadata`)])
.then(data => { .then(([profile, metadata]) => {
updated = updated || !compareProfiles(this.profileField, data); updated ||= !compareProfiles(this.profileField, profile);
this.profileField = data; this.profileField = profile;
if (JSON.stringify(this.metadataField) !== JSON.stringify(metadata)) {
this.metadataField = metadata;
}
}) })
.catch(error => { .catch(error => {
this.isexperimentError = true; this.isexperimentError = true;
...@@ -111,6 +131,10 @@ class Experiment { ...@@ -111,6 +131,10 @@ class Experiment {
return this.profileField === undefined ? emptyProfile : this.profileField; return this.profileField === undefined ? emptyProfile : this.profileField;
} }
get metadata(): ExperimentMetadata {
return this.metadataField === undefined ? emptyMetadata : this.metadataField;
}
get config(): ExperimentConfig { get config(): ExperimentConfig {
return this.profile.params; return this.profile.params;
} }
......
...@@ -55,3 +55,8 @@ $bgColor: #f2f2f2; ...@@ -55,3 +55,8 @@ $bgColor: #f2f2f2;
} }
} }
} }
#visualizationText {
margin: 5px 0 10px 15px;
font-size: 14px;
}
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