"src/targets/gpu/vscode:/vscode.git/clone" did not exist on "3e70d01b1effd8086d9ccffad51d3fa04cdea31c"
OpenRow.tsx 8.97 KB
Newer Older
Lijiao's avatar
Lijiao committed
1
import * as React from 'react';
2
import * as copy from 'copy-to-clipboard';
3
import { Stack, PrimaryButton, Pivot, PivotItem, DefaultButton } from '@fluentui/react';
4
import JSONTree from 'react-json-tree';
5
6
7
8
9
10
11
12
13
14
15
import { Trial } from '@model/trial';
import { MANAGER_IP, RETIARIIPARAMETERS } from '@static/const';
import { EXPERIMENT, TRIALS } from '@static/datamodel';
import { reformatRetiariiParameter } from '@static/function';
import PaiTrialLog from './PaiTrialLog';
import TrialLog from './TrialLog';
import MessageInfo from './MessageInfo';
import PanelMonacoEditor from './PanelMonacoEditor';
import '@style/experiment/overview/overview.scss';
import '@style/copyParameter.scss';
import '@style/openRow.scss';
Lijiao's avatar
Lijiao committed
16

liuzhe-lz's avatar
liuzhe-lz committed
17
18
19
20
21
/**
 *  netron URL must be synchronized with ts/nni_manager/rest_server/index.ts`.
 *  Remember to update it if the value is changed or this file is moved.
 **/

Lijiao's avatar
Lijiao committed
22
interface OpenRowProps {
23
    trialId: string;
Lijiao's avatar
Lijiao committed
24
25
}

Lijiao's avatar
Lijiao committed
26
interface OpenRowState {
27
28
29
    typeInfo: string;
    info: string;
    isHidenInfo: boolean;
30
    showRetiaParamPanel: boolean;
Lijiao's avatar
Lijiao committed
31
32
33
}

class OpenRow extends React.Component<OpenRowProps, OpenRowState> {
Lijiao's avatar
Lijiao committed
34
35
    constructor(props: OpenRowProps) {
        super(props);
Lijiao's avatar
Lijiao committed
36
        this.state = {
37
38
            typeInfo: '',
            info: '',
39
40
            isHidenInfo: true,
            showRetiaParamPanel: false
Lijiao's avatar
Lijiao committed
41
        };
42
43
    }

44
45
    hideMessageInfo = (): void => {
        this.setState(() => ({ isHidenInfo: true }));
46
    };
Lijiao's avatar
Lijiao committed
47

48
49
50
51
52
53
54
55
    hideRetiaParam = (): void => {
        this.setState(() => ({ showRetiaParamPanel: false }));
    };

    isshowRetiaParamPanel = (): void => {
        this.setState(() => ({ showRetiaParamPanel: true }));
    };

56
57
58
    /**
     * info: message content
     * typeInfo: message type: success | error...
59
     * continuousTime: show time, 2000ms
60
61
62
63
     */
    getCopyStatus = (info: string, typeInfo: string): void => {
        this.setState(() => ({ info, typeInfo, isHidenInfo: false }));
        setTimeout(this.hideMessageInfo, 2000);
64
    };
Lijiao's avatar
Lijiao committed
65

66
67
    copyParams = (trial: Trial): void => {
        // get copy parameters
68
        const params = JSON.stringify(reformatRetiariiParameter(trial.description.parameters as any), null, 4);
69
70
        if (copy.default(params)) {
            this.getCopyStatus('Success copy parameters to clipboard in form of python dict !', 'success');
71
        } else {
72
            this.getCopyStatus('Failed !', 'error');
73
        }
74
    };
75

Yuge Zhang's avatar
Yuge Zhang committed
76
77
78
79
80
81
82
    openTrialLog = (filename: string): void => {
        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`);
83
    };
84

Lijiao's avatar
Lijiao committed
85
    render(): React.ReactNode {
86
        const { isHidenInfo, typeInfo, info, showRetiaParamPanel } = this.state;
87
88
        const trialId = this.props.trialId;
        const trial = TRIALS.getTrial(trialId);
89
        const logPathRow = trial.info.logPath || "This trial's log path is not available.";
90
91
        const originParameters = trial.description.parameters;
        const hasVisualHyperParams = RETIARIIPARAMETERS in originParameters;
Lijiao's avatar
Lijiao committed
92
        return (
93
94
            <Stack className='openRow'>
                <Stack className='openRowContent'>
95
                    <Pivot>
96
97
98
99
100
101
102
103
                        <PivotItem headerText='Parameters' key='1' itemIcon='TestParameter'>
                            {trial.info.hyperParameters !== undefined ? (
                                <Stack id='description'>
                                    <Stack className='bgHyper'>
                                        <JSONTree
                                            hideRoot={true}
                                            shouldExpandNode={(): boolean => true} // default expandNode
                                            getItemString={(): null => null} // remove the {} items
104
                                            data={reformatRetiariiParameter(originParameters as any)}
105
                                        />
106
                                    </Stack>
107
108
109
110
111
112
                                    <Stack horizontal className='copy'>
                                        <PrimaryButton
                                            onClick={this.copyParams.bind(this, trial)}
                                            text='Copy as json'
                                            styles={{ root: { width: 128, marginRight: 10 } }}
                                        />
113
114
115
116
117
118
                                        {hasVisualHyperParams && (
                                            <DefaultButton
                                                onClick={this.isshowRetiaParamPanel}
                                                text='Original parameters'
                                            />
                                        )}
119
120
                                        {/* copy success | failed message info */}
                                        {!isHidenInfo && <MessageInfo typeInfo={typeInfo} info={info} />}
121
122
123
124
125
126
127
                                        {showRetiaParamPanel && (
                                            <PanelMonacoEditor
                                                hideConfigPanel={this.hideRetiaParam}
                                                panelName='Retiarii parameters'
                                                panelContent={JSON.stringify(originParameters, null, 2)}
                                            />
                                        )}
128
                                    </Stack>
129
130
131
132
133
134
135
                                </Stack>
                            ) : (
                                <Stack className='logpath'>
                                    <span className='logName'>Error: </span>
                                    <span className='error'>{`This trial's parameters are not available.'`}</span>
                                </Stack>
                            )}
136
                        </PivotItem>
137
                        <PivotItem headerText='Log' key='2' itemIcon='M365InvoicingLogo'>
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
                            {
                                // FIXME: this should not be handled in web UI side
                                EXPERIMENT.trainingServicePlatform !== 'local' ? (
                                    <PaiTrialLog
                                        logStr={logPathRow}
                                        id={trialId}
                                        logCollection={EXPERIMENT.logCollectionEnabled}
                                    />
                                ) : (
                                    <div>
                                        <TrialLog logStr={logPathRow} id={trialId} />
                                        {/* view each trial log in drawer*/}
                                        <div id='trialog'>
                                            <div className='copy' style={{ marginTop: 15 }}>
                                                <PrimaryButton
Yuge Zhang's avatar
Yuge Zhang committed
153
                                                    onClick={this.openTrialLog.bind(this, 'trial.log')}
154
155
156
                                                    text='View trial log'
                                                />
                                                <PrimaryButton
Yuge Zhang's avatar
Yuge Zhang committed
157
                                                    onClick={this.openTrialLog.bind(this, 'stderr')}
158
159
160
161
                                                    text='View trial error'
                                                    styles={{ root: { marginLeft: 15 } }}
                                                />
                                                <PrimaryButton
Yuge Zhang's avatar
Yuge Zhang committed
162
                                                    onClick={this.openTrialLog.bind(this, 'stdout')}
163
164
165
166
                                                    text='View trial stdout'
                                                    styles={{ root: { marginLeft: 15 } }}
                                                />
                                            </div>
167
168
                                        </div>
                                    </div>
169
170
                                )
                            }
171
                        </PivotItem>
Yuge Zhang's avatar
Yuge Zhang committed
172
173
174
175
176
177
178
179
180
181
182
183
                        {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}
184
                    </Pivot>
185
                </Stack>
186
            </Stack>
Lijiao's avatar
Lijiao committed
187
188
189
190
        );
    }
}

191
export default OpenRow;