"include/ck/utility/magic_division.hpp" did not exist on "970fa3e92ec4e67cfbfe1b0428e84870663ab8cd"
function.ts 11.2 KB
Newer Older
chicm-ms's avatar
chicm-ms committed
1
import * as JSON5 from 'json5';
Lijiao's avatar
Lijiao committed
2
import axios from 'axios';
Lijiaoa's avatar
Lijiaoa committed
3
import { IContextualMenuProps } from '@fluentui/react';
Lijiao's avatar
Lijiao committed
4
import { MANAGER_IP } from './const';
5
import { EXPERIMENT } from './datamodel';
Lijiaoa's avatar
Lijiaoa committed
6
import { MetricDataRecord, FinalType, TableObj, Tensorboard } from './interface';
Lijiao's avatar
Lijiao committed
7

8
9
10
function getPrefix(): string | undefined {
    const pathName = window.location.pathname;
    let newPathName = pathName;
11
12
13
14
15
16
17
    const pathArr: string[] = ['/oview', '/detail', '/experiment'];
    pathArr.forEach(item => {
        if (pathName.endsWith(item)) {
            newPathName = pathName.replace(item, '');
        }
    });
    return newPathName === '' || newPathName === '/' ? undefined : newPathName;
18
19
}

20
async function requestAxios(url: string): Promise<any> {
Lijiaoa's avatar
Lijiaoa committed
21
22
23
24
25
26
27
28
29
30
31
32
    const response = await axios.get(url);
    if (response.status === 200) {
        if (response.data.error !== undefined) {
            throw new Error(`API ${url} ${response.data.error}`);
        } else {
            return response.data as any;
        }
    } else {
        throw new Error(`API ${url} ${response.status} error`);
    }
}

Lijiao's avatar
Lijiao committed
33
const convertTime = (num: number): string => {
34
35
36
    if (num <= 0) {
        return '0';
    }
Lijiao's avatar
Lijiao committed
37
38
39
40
    if (num % 3600 === 0) {
        return num / 3600 + 'h';
    } else {
        const hour = Math.floor(num / 3600);
41
        const min = Math.floor((num / 60) % 60);
Lijiao's avatar
Lijiao committed
42
43
44
45
46
        return hour > 0 ? `${hour}h ${min}min` : `${min}min`;
    }
};

// trial's duration, accurate to seconds for example 10min 30s
47
48
49
50
51
52
const convertDuration = (seconds: number): string => {
    let str = '';

    const d = Math.floor(seconds / (24 * 3600));
    if (d > 0) {
        str += `${d}d `;
53
    }
54
55
56
57
58
    seconds -= d * 24 * 3600;

    const h = Math.floor(seconds / 3600);
    if (h > 0) {
        str += `${h}h `;
59
    }
60
61
62
63
64
    seconds -= h * 3600;

    const m = Math.floor(seconds / 60);
    if (m > 0) {
        str += `${m}m `;
65
    }
66
67
68
69
    seconds -= m * 60;

    if (seconds > 0) {
        str += `${Math.floor(seconds)}s`;
Lijiao's avatar
Lijiao committed
70
    }
71
    return str ? str : '0s';
Lijiao's avatar
Lijiao committed
72
73
};

74
75
76
77
78
79
80
81
82
83
84
85
// according the unit(d,h,m) to convert duration
function convertTimeAsUnit(unit: string, value: number): number {
    let divisor = 1;
    if (unit === 'h') {
        divisor = 3600;
    } else if (unit === 'm') {
        divisor = 60;
    } else {
        divisor = 24 * 3600;
    }
    return value / divisor;
}
86
function parseMetrics(metricData: string): any {
Lijiaoa's avatar
Lijiaoa committed
87
    if (metricData.includes('NaN') || metricData.includes('Infinity')) {
88
89
90
91
92
93
        return JSON5.parse(JSON5.parse(metricData));
    } else {
        return JSON.parse(JSON.parse(metricData));
    }
}

94
95
const isArrayType = (list: any): boolean | undefined => {
    return Array.isArray(list);
96
};
97

Lijiao's avatar
Lijiao committed
98
// get final result value
99
// draw Accuracy point graph
Lijiao's avatar
Lijiao committed
100
const getFinalResult = (final?: MetricDataRecord[]): number => {
Lijiao's avatar
Lijiao committed
101
102
103
    let acc;
    let showDefault = 0;
    if (final) {
104
        acc = parseMetrics(final[final.length - 1].data);
105
        if (typeof acc === 'object' && !isArrayType(acc)) {
Lijiao's avatar
Lijiao committed
106
107
108
            if (acc.default) {
                showDefault = acc.default;
            }
109
        } else if (typeof acc === 'number') {
Lijiao's avatar
Lijiao committed
110
            showDefault = acc;
111
112
        } else {
            showDefault = NaN;
Lijiao's avatar
Lijiao committed
113
114
115
116
117
118
        }
        return showDefault;
    } else {
        return 0;
    }
};
119

Lijiaoa's avatar
Lijiaoa committed
120
121
122
123
function isNaNorInfinity(val: number): boolean {
    return Object.is(val, NaN) || Object.is(val, Infinity);
}

124
// get final result value // acc obj
125
const getFinal = (final?: MetricDataRecord[]): FinalType | undefined => {
126
127
    let showDefault: FinalType;
    if (final) {
128
        showDefault = parseMetrics(final[final.length - 1].data);
129
        if (typeof showDefault === 'number') {
130
            if (!isNaNorInfinity(showDefault)) {
Lijiaoa's avatar
Lijiaoa committed
131
                return { default: showDefault };
132
            }
133
134
135
        } else if (isArrayType(showDefault)) {
            // not support final type
            return undefined;
136
            // eslint-disable-next-line no-prototype-builtins
137
138
        } else if (typeof showDefault === 'object' && showDefault.hasOwnProperty('default')) {
            return showDefault;
139
140
141
142
143
144
        }
    } else {
        return undefined;
    }
};

Lijiao's avatar
Lijiao committed
145
// detail page table intermediate button
Lijiao's avatar
Lijiao committed
146
const intermediateGraphOption = (intermediateArr: number[], id: string): any => {
Lijiao's avatar
Lijiao committed
147
148
149
150
151
152
153
154
155
156
157
    const sequence: number[] = [];
    const lengthInter = intermediateArr.length;
    for (let i = 1; i <= lengthInter; i++) {
        sequence.push(i);
    }
    return {
        title: {
            text: id,
            left: 'center',
            textStyle: {
                fontSize: 16,
158
                color: '#333'
Lijiao's avatar
Lijiao committed
159
160
161
162
163
164
            }
        },
        tooltip: {
            trigger: 'item'
        },
        xAxis: {
165
            // name: '#Intermediate result',
Lijiao's avatar
Lijiao committed
166
167
168
            data: sequence
        },
        yAxis: {
Lijiao's avatar
Lijiao committed
169
            name: 'Default metric',
Lijiao's avatar
Lijiao committed
170
            type: 'value',
Lijiaoa's avatar
Lijiaoa committed
171
172
            data: intermediateArr,
            scale: true
Lijiao's avatar
Lijiao committed
173
        },
174
175
176
177
178
179
180
        series: [
            {
                symbolSize: 6,
                type: 'scatter',
                data: intermediateArr
            }
        ]
Lijiao's avatar
Lijiao committed
181
182
183
184
    };
};

// kill job
Lijiao's avatar
Lijiao committed
185
const killJob = (key: number, id: string, status: string, updateList?: Function): void => {
Lijiao's avatar
Lijiao committed
186
187
188
189
190
191
192
193
    axios(`${MANAGER_IP}/trial-jobs/${id}`, {
        method: 'DELETE',
        headers: {
            'Content-Type': 'application/json;charset=utf-8'
        }
    })
        .then(res => {
            if (res.status === 200) {
194
195
                // TODO: use Message.txt to tooltip
                alert('Cancel the job successfully');
Lijiao's avatar
Lijiao committed
196
                // render the table
197
                if (updateList) {
198
                    updateList(); // FIXME
199
                }
Lijiao's avatar
Lijiao committed
200
            } else {
201
                alert('fail to cancel the job');
Lijiao's avatar
Lijiao committed
202
203
204
205
206
            }
        })
        .catch(error => {
            if (error.response.status === 500) {
                if (error.response.data.error) {
Lijiaoa's avatar
Lijiaoa committed
207
                    alert(error.response.data.error);
Lijiao's avatar
Lijiao committed
208
                } else {
Lijiaoa's avatar
Lijiaoa committed
209
                    alert('500 error, fail to cancel the job');
Lijiao's avatar
Lijiao committed
210
211
212
213
214
                }
            }
        });
};

215
const filterByStatus = (item: TableObj): boolean => {
216
217
218
    return item.status === 'SUCCEEDED';
};

219
// a waittiong trial may havn't start time
220
const filterDuration = (item: TableObj): boolean => {
221
222
223
    return item.status !== 'WAITING';
};

Lijiao's avatar
Lijiao committed
224
const downFile = (content: string, fileName: string): void => {
v-liguo's avatar
v-liguo committed
225
226
227
228
229
230
231
232
233
234
235
    const aTag = document.createElement('a');
    const isEdge = navigator.userAgent.indexOf('Edge') !== -1 ? true : false;
    const file = new Blob([content], { type: 'application/json' });
    aTag.download = fileName;
    aTag.href = URL.createObjectURL(file);
    aTag.click();
    if (!isEdge) {
        URL.revokeObjectURL(aTag.href);
    }
    if (navigator.userAgent.indexOf('Firefox') > -1) {
        const downTag = document.createElement('a');
236
        downTag.addEventListener('click', function () {
v-liguo's avatar
v-liguo committed
237
238
239
            downTag.download = fileName;
            downTag.href = URL.createObjectURL(file);
        });
chicm-ms's avatar
chicm-ms committed
240
        const eventMouse = document.createEvent('MouseEvents');
v-liguo's avatar
v-liguo committed
241
242
243
244
245
        eventMouse.initEvent('click', false, false);
        downTag.dispatchEvent(eventMouse);
    }
};

246
247
248
249
250
// function formatTimestamp(timestamp?: number, placeholder?: string = 'N/A'): string {
function formatTimestamp(timestamp?: number, placeholder?: string): string {
    if (placeholder === undefined) {
        placeholder = 'N/A';
    }
251
252
253
    return timestamp ? new Date(timestamp).toLocaleString('en-US') : placeholder;
}

254
255
256
257
258
259
260
261
function expformatTimestamp(timestamp: number | string): string {
    if (typeof timestamp === 'number') {
        return new Date(timestamp).toLocaleString('en-US');
    } else {
        return 'N/A';
    }
}

262
function metricAccuracy(metric: MetricDataRecord): number {
chicm-ms's avatar
chicm-ms committed
263
    const data = parseMetrics(metric.data);
264
265
266
267
268
269
    // return typeof data === 'number' ? data : NaN;
    if (typeof data === 'number') {
        return data;
    } else {
        return data.default;
    }
270
271
272
273
}

function formatAccuracy(accuracy: number): string {
    // TODO: how to format NaN?
274
    return accuracy.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
275
276
}

Lijiaoa's avatar
Lijiaoa committed
277
278
279
280
281
282
283
284
function formatComplexTypeValue(value: any): string | number {
    if (['number', 'string'].includes(typeof value)) {
        return value;
    } else {
        return value.toString();
    }
}

285
286
287
288
function isManagerExperimentPage(): boolean {
    return location.pathname.indexOf('experiment') === -1 ? false : true;
}

289
290
291
292
293
294
295
function caclMonacoEditorHeight(height): number {
    // [Search space 56px] + [marginBottom 18px] +
    // button[height: 32px, marginTop: 45px, marginBottom: 7px]
    // panel own padding-bottom: 20px;
    return height - 178;
}

296
297
function copyAndSort<T>(items: T[], columnKey: string, isSortedDescending?: boolean): any {
    const key = columnKey as keyof T;
298
    return items.slice(0).sort(function (a: T, b: T): any {
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
        if (
            a[key] === undefined ||
            Object.is(a[key], NaN) ||
            Object.is(a[key], Infinity) ||
            Object.is(a[key], -Infinity) ||
            typeof a[key] === 'object'
        ) {
            return 1;
        }
        if (
            b[key] === undefined ||
            Object.is(b[key], NaN) ||
            Object.is(b[key], Infinity) ||
            Object.is(b[key], -Infinity) ||
            typeof b[key] === 'object'
        ) {
            return -1;
        }
        return (isSortedDescending ? a[key] < b[key] : a[key] > b[key]) ? 1 : -1;
    });
}
Lijiaoa's avatar
Lijiaoa committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358

function disableTensorboard(selectedRowIds: string[], queryTensorboardList: Tensorboard[]): boolean {
    let flag = true;

    if (selectedRowIds.length !== 0) {
        flag = false;
    }

    if (selectedRowIds.length === 0 && queryTensorboardList.length !== 0) {
        flag = false;
    }

    return flag;
}

function getTensorboardMenu(queryTensorboardList: Tensorboard[], stopFunc, seeDetailFunc): IContextualMenuProps {
    const result: Array<object> = [];
    if (queryTensorboardList.length !== 0) {
        result.push({
            key: 'delete',
            text: 'Stop all tensorBoard',
            className: 'clearAll',
            onClick: stopFunc
        });
        queryTensorboardList.forEach(item => {
            result.push({
                key: item.id,
                text: `${item.id}`,
                className: `CommandBarButton-${item.status}`,
                onClick: (): void => seeDetailFunc(item)
            });
        });
    }
    const tensorboardMenu: IContextualMenuProps = {
        items: result.reverse() as any
    };

    return tensorboardMenu;
}
359
360
361
362
363
364
365
366
367
368
369
370
371

// search space type map list: now get type from search space
const parametersType = (): Map<string, string> => {
    const parametersTypeMap = new Map();
    const trialParameterlist = Object.keys(EXPERIMENT.searchSpace);

    trialParameterlist.forEach(item => {
        parametersTypeMap.set(item, typeof EXPERIMENT.searchSpace[item]._value[0]);
    });

    return parametersTypeMap;
};

372
export {
373
    getPrefix,
374
375
    convertTime,
    convertDuration,
376
    convertTimeAsUnit,
377
378
379
380
381
382
383
384
385
    getFinalResult,
    getFinal,
    downFile,
    intermediateGraphOption,
    killJob,
    filterByStatus,
    filterDuration,
    formatAccuracy,
    formatTimestamp,
386
    expformatTimestamp,
387
388
389
390
391
    metricAccuracy,
    parseMetrics,
    isArrayType,
    requestAxios,
    isNaNorInfinity,
392
    formatComplexTypeValue,
393
    isManagerExperimentPage,
394
    caclMonacoEditorHeight,
Lijiaoa's avatar
Lijiaoa committed
395
396
    copyAndSort,
    disableTensorboard,
397
398
    getTensorboardMenu,
    parametersType
399
};