Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Allow NaN in metrics data #1958

Merged
merged 39 commits into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3a45961
Merge pull request #31 from microsoft/master
chicm-ms Aug 6, 2019
633db43
Merge pull request #32 from microsoft/master
chicm-ms Sep 9, 2019
3e926f1
Merge pull request #33 from microsoft/master
chicm-ms Oct 8, 2019
f173789
Merge pull request #34 from microsoft/master
chicm-ms Oct 9, 2019
508850a
Merge pull request #35 from microsoft/master
chicm-ms Oct 9, 2019
5a0e9c9
Merge pull request #36 from microsoft/master
chicm-ms Oct 10, 2019
e7df061
Merge pull request #37 from microsoft/master
chicm-ms Oct 23, 2019
2175cef
Merge pull request #38 from microsoft/master
chicm-ms Oct 29, 2019
2ccbfbb
Merge pull request #39 from microsoft/master
chicm-ms Oct 30, 2019
b29cb0b
Merge pull request #40 from microsoft/master
chicm-ms Oct 30, 2019
4a3ba83
Merge pull request #41 from microsoft/master
chicm-ms Nov 4, 2019
c8a1148
Merge pull request #42 from microsoft/master
chicm-ms Nov 4, 2019
73c6101
Merge pull request #43 from microsoft/master
chicm-ms Nov 5, 2019
6a518a9
Merge pull request #44 from microsoft/master
chicm-ms Nov 11, 2019
a0d587f
Merge pull request #45 from microsoft/master
chicm-ms Nov 12, 2019
e905bfe
Merge pull request #46 from microsoft/master
chicm-ms Nov 14, 2019
4b266f3
Merge pull request #47 from microsoft/master
chicm-ms Nov 15, 2019
237ff4b
Merge pull request #48 from microsoft/master
chicm-ms Nov 21, 2019
682be01
Merge pull request #49 from microsoft/master
chicm-ms Nov 25, 2019
133af82
Merge pull request #50 from microsoft/master
chicm-ms Nov 25, 2019
71a8a25
Merge pull request #51 from microsoft/master
chicm-ms Nov 26, 2019
d2a73bc
Merge pull request #52 from microsoft/master
chicm-ms Nov 26, 2019
198cf5e
Merge pull request #53 from microsoft/master
chicm-ms Dec 5, 2019
cdbfaf9
Merge pull request #54 from microsoft/master
chicm-ms Dec 6, 2019
7e9b29e
Merge pull request #55 from microsoft/master
chicm-ms Dec 10, 2019
d00c46d
Merge pull request #56 from microsoft/master
chicm-ms Dec 10, 2019
de7d1fa
Merge pull request #57 from microsoft/master
chicm-ms Dec 11, 2019
1835ab0
Merge pull request #58 from microsoft/master
chicm-ms Dec 12, 2019
24fead6
Merge pull request #59 from microsoft/master
chicm-ms Dec 20, 2019
0b7321e
Merge pull request #60 from microsoft/master
chicm-ms Dec 23, 2019
60058d4
Merge pull request #61 from microsoft/master
chicm-ms Dec 23, 2019
b111a55
Merge pull request #62 from microsoft/master
chicm-ms Dec 24, 2019
611c337
Merge pull request #63 from microsoft/master
chicm-ms Dec 30, 2019
4a1f14a
Merge pull request #64 from microsoft/master
chicm-ms Jan 10, 2020
7a9e604
Merge pull request #65 from microsoft/master
chicm-ms Jan 14, 2020
683242f
Allow NaN in metrics data
chicm-ms Jan 14, 2020
6f9678f
updates
chicm-ms Jan 14, 2020
d84d65b
updates
chicm-ms Jan 14, 2020
d64e2f4
updates
chicm-ms Jan 15, 2020
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
5 changes: 3 additions & 2 deletions src/nni_manager/core/nniDataStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'use strict';

import * as assert from 'assert';
import * as JSON5 from 'json5';
import { Deferred } from 'ts-deferred';

import * as component from '../common/component';
Expand Down Expand Up @@ -131,7 +132,7 @@ class NNIDataStore implements DataStore {
}

public async storeMetricData(trialJobId: string, data: string): Promise<void> {
const metrics: MetricData = JSON.parse(data);
const metrics: MetricData = JSON5.parse(data);
// REQUEST_PARAMETER is used to request new parameters for multiphase trial job,
// it is not metrics, so it is skipped here.
if (metrics.type === 'REQUEST_PARAMETER') {
Expand All @@ -140,7 +141,7 @@ class NNIDataStore implements DataStore {
}
assert(trialJobId === metrics.trial_job_id);
try {
await this.db.storeMetricData(trialJobId, JSON.stringify({
await this.db.storeMetricData(trialJobId, JSON5.stringify({
trialJobId: metrics.trial_job_id,
parameterId: metrics.parameter_id,
type: metrics.type,
Expand Down
7 changes: 4 additions & 3 deletions src/nni_manager/core/sqlDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import * as assert from 'assert';
import * as fs from 'fs';
import * as JSON5 from 'json5';
import * as path from 'path';
import * as sqlite3 from 'sqlite3';
import { Deferred } from 'ts-deferred';
Expand Down Expand Up @@ -202,10 +203,10 @@ class SqlDB implements Database {

public storeMetricData(trialJobId: string, data: string): Promise<void> {
const sql: string = 'insert into MetricData values (?,?,?,?,?,?)';
const json: MetricDataRecord = JSON.parse(data);
const args: any[] = [Date.now(), json.trialJobId, json.parameterId, json.type, json.sequence, JSON.stringify(json.data)];
const json: MetricDataRecord = JSON5.parse(data);
const args: any[] = [Date.now(), json.trialJobId, json.parameterId, json.type, json.sequence, JSON5.stringify(json.data)];

this.log.trace(`storeMetricData: SQL: ${sql}, args: ${JSON.stringify(args)}`);
this.log.trace(`storeMetricData: SQL: ${sql}, args: ${JSON5.stringify(args)}`);
const deferred: Deferred<void> = new Deferred<void>();
this.db.run(sql, args, (err: Error | null) => { this.resolve(deferred, err); });

Expand Down
2 changes: 2 additions & 0 deletions src/nni_manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"express": "^4.16.3",
"express-joi-validator": "^2.0.0",
"js-base64": "^2.4.9",
"json5": "^2.1.1",
"kubernetes-client": "^6.5.0",
"rx": "^4.1.0",
"sqlite3": "^4.0.2",
Expand All @@ -34,6 +35,7 @@
"@types/express": "^4.16.0",
"@types/glob": "^7.1.1",
"@types/js-base64": "^2.3.1",
"@types/json5": "^0.0.30",
"@types/mocha": "^5.2.5",
"@types/node": "10.12.18",
"@types/request": "^2.47.1",
Expand Down
16 changes: 13 additions & 3 deletions src/nni_manager/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@
version "7.0.3"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"

"@types/json5@^0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818"

"@types/mime@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b"
Expand Down Expand Up @@ -1840,9 +1844,9 @@ growl@1.10.5:
version "1.10.5"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"

handlebars@^4.0.11, handlebars@^4.3.0:
version "4.5.3"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482"
handlebars@^4.0.11, handlebars@^4.5.3:
version "4.7.2"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.2.tgz#01127b3840156a0927058779482031afe0e730d7"
dependencies:
neo-async "^2.6.0"
optimist "^0.6.1"
Expand Down Expand Up @@ -2371,6 +2375,12 @@ json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"

json5@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6"
dependencies:
minimist "^1.2.0"

jsonparse@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
Expand Down
4 changes: 2 additions & 2 deletions src/sdk/pynni/nni/msg_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .assessor import AssessResult
from .common import multi_thread_enabled, multi_phase_enabled
from .env_vars import dispatcher_env_vars
from .utils import MetricType
from .utils import MetricType, to_json

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -62,7 +62,7 @@ def _pack_parameter(parameter_id, params, customized=False, trial_job_id=None, p
ret['parameter_index'] = parameter_index
else:
ret['parameter_index'] = 0
return json_tricks.dumps(ret)
return to_json(ret)


class MsgDispatcher(MsgDispatcherBase):
Expand Down
4 changes: 2 additions & 2 deletions src/sdk/pynni/nni/platform/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
import json
import time
import subprocess
import json_tricks

from ..common import init_logger
from ..env_vars import trial_env_vars
from ..utils import to_json

_sysdir = trial_env_vars.NNI_SYS_DIR
if not os.path.exists(os.path.join(_sysdir, '.nni')):
Expand All @@ -30,7 +30,7 @@
_param_index = 0

def request_next_parameter():
metric = json_tricks.dumps({
metric = to_json({
'trial_job_id': trial_env_vars.NNI_TRIAL_JOB_ID,
'type': 'REQUEST_PARAMETER',
'sequence': 0,
Expand Down
8 changes: 3 additions & 5 deletions src/sdk/pynni/nni/trial.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

import json_tricks

from .utils import to_json
from .env_vars import trial_env_vars
from . import platform

Expand Down Expand Up @@ -110,7 +109,7 @@ def report_intermediate_result(metric):
global _intermediate_seq
assert _params or trial_env_vars.NNI_PLATFORM is None, \
'nni.get_next_parameter() needs to be called before report_intermediate_result'
metric = json_tricks.dumps({
metric = to_json({
'parameter_id': _params['parameter_id'] if _params else None,
'trial_job_id': trial_env_vars.NNI_TRIAL_JOB_ID,
'type': 'PERIODICAL',
Expand All @@ -120,7 +119,6 @@ def report_intermediate_result(metric):
_intermediate_seq += 1
platform.send_metric(metric)


def report_final_result(metric):
"""
Reports final result to NNI.
Expand All @@ -132,7 +130,7 @@ def report_final_result(metric):
"""
assert _params or trial_env_vars.NNI_PLATFORM is None, \
'nni.get_next_parameter() needs to be called before report_final_result'
metric = json_tricks.dumps({
metric = to_json({
'parameter_id': _params['parameter_id'] if _params else None,
'trial_job_id': trial_env_vars.NNI_TRIAL_JOB_ID,
'type': 'FINAL',
Expand Down
8 changes: 4 additions & 4 deletions src/sdk/pynni/nni/utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

"""
utils.py
"""

import os
import functools
from enum import Enum, unique
import json_tricks

from .common import init_logger
from .env_vars import dispatcher_env_vars

to_json = functools.partial(json_tricks.dumps, allow_nan=True)

@unique
class OptimizeMode(Enum):
"""Optimize Mode class
Expand Down
2 changes: 2 additions & 0 deletions src/webui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"fork-ts-checker-webpack-plugin": "^1.5.0",
"fs-extra": "^8.1.0",
"html-webpack-plugin": "^4.0.0-beta.8",
"json5": "^2.1.1",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.8.0",
Expand Down Expand Up @@ -55,6 +56,7 @@
"eslint": "npx eslint ./ --ext .tsx,.ts"
},
"devDependencies": {
"@types/json5": "^0.0.30",
"@types/node": "^10.14.14",
"@types/react": "16.4.17",
"@types/react-dom": "^16.0.7",
Expand Down
10 changes: 5 additions & 5 deletions src/webui/src/components/trial-detail/TableList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ColumnProps } from 'antd/lib/table';
const Option = Select.Option;
const CheckboxGroup = Checkbox.Group;
import { MANAGER_IP, trialJobStatus, COLUMN_INDEX, COLUMNPro } from '../../static/const';
import { convertDuration, formatTimestamp, intermediateGraphOption, killJob } from '../../static/function';
import { convertDuration, formatTimestamp, intermediateGraphOption, killJob, parseMetrics } from '../../static/function';
import { EXPERIMENT, TRIALS } from '../../static/datamodel';
import { TableRecord } from '../../static/interface';
import OpenRow from '../public-child/OpenRow';
Expand Down Expand Up @@ -178,11 +178,11 @@ class TableList extends React.Component<TableListProps, TableListState> {
// get intermediate result dict keys array
let otherkeys: Array<string> = ['default'];
if (res.data.length !== 0) {
otherkeys = Object.keys(JSON.parse(res.data[0].data));
otherkeys = Object.keys(parseMetrics(res.data[0].data));
}
// intermediateArr just store default val
Object.keys(res.data).map(item => {
const temp = JSON.parse(res.data[item].data);
const temp = parseMetrics(res.data[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp.default);
} else {
Expand Down Expand Up @@ -210,7 +210,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
// just watch default key-val
if (isShowDefault === true) {
Object.keys(intermediateData).map(item => {
const temp = JSON.parse(intermediateData[item].data);
const temp = parseMetrics(intermediateData[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp[value]);
} else {
Expand All @@ -219,7 +219,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
});
} else {
Object.keys(intermediateData).map(item => {
const temp = JSON.parse(intermediateData[item].data);
const temp = parseMetrics(intermediateData[item].data);
if (typeof temp === 'object') {
intermediateArr.push(temp[value]);
}
Expand Down
13 changes: 11 additions & 2 deletions src/webui/src/static/function.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as JSON5 from 'json5';
import axios from 'axios';
import { message } from 'antd';
import { MANAGER_IP } from './const';
Expand Down Expand Up @@ -173,8 +174,16 @@ function formatTimestamp(timestamp?: number, placeholder?: string = 'N/A'): stri
return timestamp ? new Date(timestamp).toLocaleString('en-US') : placeholder;
}

function parseMetrics(metricData: string): any {
if (metricData.includes('NaN')) {
return JSON5.parse(metricData)
} else {
return JSON.parse(metricData)
}
}

function metricAccuracy(metric: MetricDataRecord): number {
const data = JSON.parse(metric.data);
const data = parseMetrics(metric.data);
return typeof data === 'number' ? data : NaN;
}

Expand All @@ -186,5 +195,5 @@ function formatAccuracy(accuracy: number): string {
export {
convertTime, convertDuration, getFinalResult, getFinal, downFile,
intermediateGraphOption, killJob, filterByStatus, filterDuration,
formatAccuracy, formatTimestamp, metricAccuracy
formatAccuracy, formatTimestamp, metricAccuracy, parseMetrics
};
10 changes: 5 additions & 5 deletions src/webui/src/static/model/trial.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MetricDataRecord, TrialJobInfo, TableObj, TableRecord, Parameters, FinalType } from '../interface';
import { getFinal, formatAccuracy, metricAccuracy } from '../function';
import { getFinal, formatAccuracy, metricAccuracy, parseMetrics } from '../function';

class Trial implements TableObj {
private metricsInitialized: boolean = false;
Expand Down Expand Up @@ -56,7 +56,7 @@ class Trial implements TableObj {
// TODO: support intermeidate result is dict
const temp = this.intermediates[this.intermediates.length - 1];
if (temp !== undefined) {
return JSON.parse(temp.data);
return parseMetrics(temp.data);
} else {
return undefined;
}
Expand Down Expand Up @@ -138,10 +138,10 @@ class Trial implements TableObj {

const mediate: number[] = [ ];
for (const items of this.intermediateMetrics) {
if (typeof JSON.parse(items.data) === 'object') {
mediate.push(JSON.parse(items.data).default);
if (typeof parseMetrics(items.data) === 'object') {
mediate.push(parseMetrics(items.data).default);
} else {
mediate.push(JSON.parse(items.data));
mediate.push(parseMetrics(items.data));
}
}
ret.intermediate = mediate;
Expand Down
10 changes: 10 additions & 0 deletions src/webui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"

"@types/json5@^0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.30.tgz#44cb52f32a809734ca562e685c6473b5754a7818"

"@types/minimatch@*":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
Expand Down Expand Up @@ -3988,6 +3992,12 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"

json5@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6"
dependencies:
minimist "^1.2.0"

jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
Expand Down