From f05e685f20c4dd32c874d2f0368081d505c75a65 Mon Sep 17 00:00:00 2001 From: SparkSnail Date: Mon, 1 Apr 2019 09:57:39 +0800 Subject: [PATCH 1/4] Refactor local gpu scheduler (#943) --- src/nni_manager/package.json | 1 - .../training_service/common/gpuData.ts | 8 + .../training_service/local/gpuScheduler.ts | 343 ++---------------- .../local/localTrainingServiceForGPU.ts | 4 +- .../remote_machine/remoteMachineData.ts | 8 - .../remoteMachineTrainingService.ts | 6 +- .../types/node-nvidia-smi/index.d.ts | 23 -- 7 files changed, 50 insertions(+), 343 deletions(-) delete mode 100644 src/nni_manager/types/node-nvidia-smi/index.d.ts diff --git a/src/nni_manager/package.json b/src/nni_manager/package.json index 4d5c864d89..6876579c02 100644 --- a/src/nni_manager/package.json +++ b/src/nni_manager/package.json @@ -18,7 +18,6 @@ "express-joi-validator": "^2.0.0", "js-base64": "^2.4.9", "kubernetes-client": "^6.5.0", - "node-nvidia-smi": "^1.0.0", "rx": "^4.1.0", "sqlite3": "^4.0.2", "ssh2": "^0.6.1", diff --git a/src/nni_manager/training_service/common/gpuData.ts b/src/nni_manager/training_service/common/gpuData.ts index 5a99821f13..eb2d5a3ad7 100644 --- a/src/nni_manager/training_service/common/gpuData.ts +++ b/src/nni_manager/training_service/common/gpuData.ts @@ -58,3 +58,11 @@ export class GPUSummary { this.gpuInfos = gpuInfos; } } + +export const GPU_INFO_COLLECTOR_FORMAT: string = +` +#!/bin/bash +export METRIC_OUTPUT_DIR={0} +echo $$ >{1} +python3 -m nni_gpu_tool.gpu_metrics_collector +` diff --git a/src/nni_manager/training_service/local/gpuScheduler.ts b/src/nni_manager/training_service/local/gpuScheduler.ts index f89fc5b514..2c790b019c 100644 --- a/src/nni_manager/training_service/local/gpuScheduler.ts +++ b/src/nni_manager/training_service/local/gpuScheduler.ts @@ -19,268 +19,16 @@ 'use strict'; -import * as assert from 'assert'; -import * as nodeNvidiaSmi from 'node-nvidia-smi'; import { delay } from '../../common/utils'; import { GPUInfo, GPUSummary } from '../common/gpuData'; import { getLogger, Logger } from '../../common/log'; - -/* Example of nvidia-smi result -{ - "nvidia_smi_log": { - "timestamp": "Fri Jul 13 15:17:27 2018", - "driver_version": "396.26", - "attached_gpus": "8", - "gpu": [ - ..., - { - ... - "minor_number": "5", - "utilization": { - "gpu_util": "100 %", - "memory_util": "27 %", - "encoder_util": "0 %", - "decoder_util": "0 %" - }, - ... - "processes": { - "process_info": { - "pid": "39943", - "type": "C", - "process_name": "python", - "used_memory": "16229 MiB" - } - }, - ... - }, - { - "$": { - "id": "00000000:8E:00.0" - }, - "product_name": "Tesla P100-PCIE-16GB", - "product_brand": "Tesla", - "display_mode": "Enabled", - "display_active": "Disabled", - "persistence_mode": "Disabled", - "accounting_mode": "Disabled", - "accounting_mode_buffer_size": "4000", - "driver_model": { - "current_dm": "N/A", - "pending_dm": "N/A" - }, - "serial": "0321017108732", - "uuid": "GPU-df3e8a0a-ce99-350c-b196-c3775eb32309", - "minor_number": "6", - "vbios_version": "86.00.40.00.01", - "multigpu_board": "No", - "board_id": "0x8e00", - "gpu_part_number": "900-2H400-0300-031", - "inforom_version": { - "img_version": "H400.0201.00.08", - "oem_object": "1.1", - "ecc_object": "4.1", - "pwr_object": "N/A" - }, - "gpu_operation_mode": { - "current_gom": "N/A", - "pending_gom": "N/A" - }, - "gpu_virtualization_mode": { - "virtualization_mode": "None" - }, - "ibmnpu": { - "relaxed_ordering_mode": "N/A" - }, - "pci": { - "pci_bus": "8E", - "pci_device": "00", - "pci_domain": "0000", - "pci_device_id": "15F810DE", - "pci_bus_id": "00000000:8E:00.0", - "pci_sub_system_id": "118F10DE", - "pci_gpu_link_info": { - "pcie_gen": { - "max_link_gen": "3", - "current_link_gen": "3" - }, - "link_widths": { - "max_link_width": "16x", - "current_link_width": "16x" - } - }, - "pci_bridge_chip": { - "bridge_chip_type": "N/A", - "bridge_chip_fw": "N/A" - }, - "replay_counter": "0", - "tx_util": "0 KB/s", - "rx_util": "0 KB/s" - }, - "fan_speed": "N/A", - "performance_state": "P0", - "clocks_throttle_reasons": { - "clocks_throttle_reason_gpu_idle": "Not Active", - "clocks_throttle_reason_applications_clocks_setting": "Not Active", - "clocks_throttle_reason_sw_power_cap": "Not Active", - "clocks_throttle_reason_hw_slowdown": "Not Active", - "clocks_throttle_reason_hw_thermal_slowdown": "Not Active", - "clocks_throttle_reason_hw_power_brake_slowdown": "Not Active", - "clocks_throttle_reason_sync_boost": "Not Active", - "clocks_throttle_reason_sw_thermal_slowdown": "Not Active" - }, - "fb_memory_usage": { - "total": "16280 MiB", - "used": "16239 MiB", - "free": "41 MiB" - }, - "bar1_memory_usage": { - "total": "16384 MiB", - "used": "2 MiB", - "free": "16382 MiB" - }, - "compute_mode": "Default", - "utilization": { - "gpu_util": "0 %", - "memory_util": "0 %", - "encoder_util": "0 %", - "decoder_util": "0 %" - }, - "encoder_stats": { - "session_count": "0", - "average_fps": "0", - "average_latency": "0" - }, - "ecc_mode": { - "current_ecc": "Enabled", - "pending_ecc": "Enabled" - }, - "ecc_errors": { - "volatile": { - "single_bit": { - "device_memory": "0", - "register_file": "0", - "l1_cache": "N/A", - "l2_cache": "0", - "texture_memory": "0", - "texture_shm": "0", - "cbu": "N/A", - "total": "0" - }, - "double_bit": { - "device_memory": "0", - "register_file": "0", - "l1_cache": "N/A", - "l2_cache": "0", - "texture_memory": "0", - "texture_shm": "0", - "cbu": "N/A", - "total": "0" - } - }, - "aggregate": { - "single_bit": { - "device_memory": "0", - "register_file": "0", - "l1_cache": "N/A", - "l2_cache": "0", - "texture_memory": "0", - "texture_shm": "0", - "cbu": "N/A", - "total": "0" - }, - "double_bit": { - "device_memory": "0", - "register_file": "0", - "l1_cache": "N/A", - "l2_cache": "0", - "texture_memory": "0", - "texture_shm": "0", - "cbu": "N/A", - "total": "0" - } - } - }, - "retired_pages": { - "multiple_single_bit_retirement": { - "retired_count": "0", - "retired_page_addresses": "\n\t\t\t\t" - }, - "double_bit_retirement": { - "retired_count": "0", - "retired_page_addresses": "\n\t\t\t\t" - }, - "pending_retirement": "No" - }, - "temperature": { - "gpu_temp": "33 C", - "gpu_temp_max_threshold": "85 C", - "gpu_temp_slow_threshold": "82 C", - "gpu_temp_max_gpu_threshold": "N/A", - "memory_temp": "N/A", - "gpu_temp_max_mem_threshold": "N/A" - }, - "power_readings": { - "power_state": "P0", - "power_management": "Supported", - "power_draw": "37.29 W", - "power_limit": "250.00 W", - "default_power_limit": "250.00 W", - "enforced_power_limit": "250.00 W", - "min_power_limit": "125.00 W", - "max_power_limit": "250.00 W" - }, - "clocks": { - "graphics_clock": "1328 MHz", - "sm_clock": "1328 MHz", - "mem_clock": "715 MHz", - "video_clock": "1189 MHz" - }, - "applications_clocks": { - "graphics_clock": "1189 MHz", - "mem_clock": "715 MHz" - }, - "default_applications_clocks": { - "graphics_clock": "1189 MHz", - "mem_clock": "715 MHz" - }, - "max_clocks": { - "graphics_clock": "1328 MHz", - "sm_clock": "1328 MHz", - "mem_clock": "715 MHz", - "video_clock": "1328 MHz" - }, - "max_customer_boost_clocks": { - "graphics_clock": "1328 MHz" - }, - "clock_policy": { - "auto_boost": "N/A", - "auto_boost_default": "N/A" - }, - "supported_clocks": { - "supported_mem_clock": { - "value": "715 MHz", - "supported_graphics_clock": [ - "1328 MHz", - "1316 MHz", - "1303 MHz", - ... - ] - } - }, - "processes": { - "process_info": { - "pid": "40788", - "type": "C", - "process_name": "python", - "used_memory": "16229 MiB" - } - }, - "accounted_processes": "\n\t\t" - }, - ... - ] - } -}*/ +import * as cp from 'child_process'; +import * as cpp from 'child-process-promise'; +import * as path from 'path'; +import * as os from 'os'; +import * as fs from 'fs'; +import { String } from 'typescript-string-operations'; +import { GPU_INFO_COLLECTOR_FORMAT } from '../common/gpuData' /** * GPUScheduler @@ -290,29 +38,43 @@ class GPUScheduler { private gpuSummary!: GPUSummary; private stopping: boolean; private log: Logger; - private nvdmNotFoundRegex: RegExp; + private gpuMetricCollectorScriptFolder: string; constructor() { this.stopping = false; this.log = getLogger(); - this.nvdmNotFoundRegex = /nvidia-smi: not found/gi; + this.gpuMetricCollectorScriptFolder = `${os.tmpdir()}/nni/script`; } public async run(): Promise { + await this.runGpuMetricsCollectorScript(); while (!this.stopping) { try { - this.gpuSummary = await this.readGPUSummary(); + await this.updateGPUSummary(); } catch (error) { this.log.error('Read GPU summary failed with error: ', error); - // If nvidia-smi command is not found, break the gpu summary reading loop to avoid unnecessary periodically checking - if(this.nvdmNotFoundRegex.test(error)) { - break; - } } await delay(5000); } } + /** + * Generate gpu metric collector shell script in local machine, + * used to run in remote machine, and will be deleted after uploaded from local. + */ + private async runGpuMetricsCollectorScript(): Promise { + await cpp.exec(`mkdir -p ${this.gpuMetricCollectorScriptFolder}`); + //generate gpu_metrics_collector.sh + let gpuMetricsCollectorScriptPath: string = path.join(this.gpuMetricCollectorScriptFolder, 'gpu_metrics_collector.sh'); + const gpuMetricsCollectorScriptContent: string = String.Format( + GPU_INFO_COLLECTOR_FORMAT, + this.gpuMetricCollectorScriptFolder, + path.join(this.gpuMetricCollectorScriptFolder, 'pid'), + ); + await fs.promises.writeFile(gpuMetricsCollectorScriptPath, gpuMetricsCollectorScriptContent, { encoding: 'utf8' }); + cp.exec(`bash ${gpuMetricsCollectorScriptPath}`); + } + public getAvailableGPUIndices(): number[] { if (this.gpuSummary !== undefined) { return this.gpuSummary.gpuInfos.filter((info: GPUInfo) => info.activeProcessNum === 0).map((info: GPUInfo) => info.index); @@ -321,51 +83,20 @@ class GPUScheduler { return []; } - public stop(): void { + public async stop() { this.stopping = true; + const pid: string = await fs.promises.readFile(path.join(this.gpuMetricCollectorScriptFolder, 'pid'), 'utf8'); + await cpp.exec(`pkill -P ${pid}`); + await cpp.exec(`rm -rf ${this.gpuMetricCollectorScriptFolder}`); } - - private generateEmbededGPUSummary(data: nodeNvidiaSmi.GPUInfo) : GPUInfo[] { - let gpuInfos : GPUInfo[] = []; - const gpuNumber : number = parseInt(data.nvidia_smi_log.attached_gpus, 10); - - assert(gpuNumber > 0); - if(gpuNumber == 1) { - const embededGPUSummary = data.nvidia_smi_log.gpu; - gpuInfos.push(this.convertGPUSummaryToInfo(embededGPUSummary)); + private async updateGPUSummary() { + const cmdresult = await cpp.exec(`tail -n 1 ${path.join(this.gpuMetricCollectorScriptFolder, 'gpu_metrics')}`); + if(cmdresult && cmdresult.stdout) { + this.gpuSummary = JSON.parse(cmdresult.stdout); } else { - const embededGPUSummaryArray = data.nvidia_smi_log.gpu; - gpuInfos = embededGPUSummaryArray.map(embededGPUSummary => this.convertGPUSummaryToInfo(embededGPUSummary)); + this.log.error('Could not get gpu metrics information!'); } - - return gpuInfos; - } - - private convertGPUSummaryToInfo(embededGPUSummary : nodeNvidiaSmi.EmbededGPUSummary) : GPUInfo { - return new GPUInfo( - typeof embededGPUSummary.process === 'object' ? 1 : 0, - parseFloat(embededGPUSummary.utilization.memory_util), - parseFloat(embededGPUSummary.utilization.gpu_util), - parseInt(embededGPUSummary.minor_number, 10)); - } - - private readGPUSummary(): Promise { - return new Promise((resolve: Function, reject: Function): void => { - nodeNvidiaSmi((error: Error, data: nodeNvidiaSmi.GPUInfo) => { - if (error) { - reject(error); - } else { - const gpuNumber : number = parseInt(data.nvidia_smi_log.attached_gpus, 10); - const gpuSummary: GPUSummary = new GPUSummary( - gpuNumber, - Date().toString(), - this.generateEmbededGPUSummary(data) - ); - resolve(gpuSummary); - } - }); - }); } } diff --git a/src/nni_manager/training_service/local/localTrainingServiceForGPU.ts b/src/nni_manager/training_service/local/localTrainingServiceForGPU.ts index 9a7fd4e00f..60f3dc2068 100644 --- a/src/nni_manager/training_service/local/localTrainingServiceForGPU.ts +++ b/src/nni_manager/training_service/local/localTrainingServiceForGPU.ts @@ -69,9 +69,9 @@ class LocalTrainingServiceForGPU extends LocalTrainingService { } } - public cleanUp(): Promise { + public async cleanUp(): Promise { if (this.gpuScheduler !== undefined) { - this.gpuScheduler.stop(); + await this.gpuScheduler.stop(); } return super.cleanUp(); diff --git a/src/nni_manager/training_service/remote_machine/remoteMachineData.ts b/src/nni_manager/training_service/remote_machine/remoteMachineData.ts index 58179ab7c0..2bc0df1e01 100644 --- a/src/nni_manager/training_service/remote_machine/remoteMachineData.ts +++ b/src/nni_manager/training_service/remote_machine/remoteMachineData.ts @@ -259,11 +259,3 @@ cd {0} echo $$ >{1} eval {2} >stdout 2>stderr echo $? \`date +%s%3N\` >{3}`; - -export const GPU_COLLECTOR_FORMAT: string = -` -#!/bin/bash -export METRIC_OUTPUT_DIR={0} -echo $$ >{1} -python3 -m nni_gpu_tool.gpu_metrics_collector -` diff --git a/src/nni_manager/training_service/remote_machine/remoteMachineTrainingService.ts b/src/nni_manager/training_service/remote_machine/remoteMachineTrainingService.ts index 97751adf8e..0656b50be0 100644 --- a/src/nni_manager/training_service/remote_machine/remoteMachineTrainingService.ts +++ b/src/nni_manager/training_service/remote_machine/remoteMachineTrainingService.ts @@ -44,9 +44,9 @@ import { GPUScheduler } from './gpuScheduler'; import { HOST_JOB_SHELL_FORMAT, RemoteCommandResult, RemoteMachineMeta, RemoteMachineScheduleInfo, RemoteMachineScheduleResult, SSHClient, SSHClientManager, - RemoteMachineTrialJobDetail, ScheduleResultType, REMOTEMACHINE_TRIAL_COMMAND_FORMAT, - GPU_COLLECTOR_FORMAT + RemoteMachineTrialJobDetail, ScheduleResultType, REMOTEMACHINE_TRIAL_COMMAND_FORMAT } from './remoteMachineData'; +import { GPU_INFO_COLLECTOR_FORMAT } from '../common/gpuData'; import { SSHClientUtility } from './sshClientUtility'; import { validateCodeDir } from '../common/util'; import { RemoteMachineJobRestServer } from './remoteMachineJobRestServer'; @@ -452,7 +452,7 @@ class RemoteMachineTrainingService implements TrainingService { let gpuMetricsCollectorScriptPath: string = path.join(gpuMetricCollectorScriptFolder, userName, 'gpu_metrics_collector.sh'); const remoteGPUScriptsDir: string = this.getRemoteScriptsPath(userName); // This directory is used to store gpu_metrics and pid created by script const gpuMetricsCollectorScriptContent: string = String.Format( - GPU_COLLECTOR_FORMAT, + GPU_INFO_COLLECTOR_FORMAT, remoteGPUScriptsDir, path.join(remoteGPUScriptsDir, 'pid'), ); diff --git a/src/nni_manager/types/node-nvidia-smi/index.d.ts b/src/nni_manager/types/node-nvidia-smi/index.d.ts deleted file mode 100644 index 4f035833b1..0000000000 --- a/src/nni_manager/types/node-nvidia-smi/index.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -declare module 'node-nvidia-smi' { - function smi(callback: (error: Error, data: smi.GPUInfo) => void): void; - - namespace smi { - interface EmbededGPUSummary { - minor_number: string; - utilization: { - gpu_util: string; - memory_util: string; - }; - process: string | object; - } - - interface GPUInfo { - nvidia_smi_log: { - attached_gpus: string; - gpu: EmbededGPUSummary[] | EmbededGPUSummary; - }; - } - } - - export = smi; -} \ No newline at end of file From 0e196f9bcbfe74815d6249e99ba317b091904d49 Mon Sep 17 00:00:00 2001 From: Shufan Huang Date: Mon, 1 Apr 2019 11:32:06 +0800 Subject: [PATCH 2/4] [fix bug]Control the maximum epoch number is less than or equal to R (#945) * Fix bug: incorrect number of trial jobs in hyperband --- docs/en_US/PAIMode.md | 2 +- src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/en_US/PAIMode.md b/docs/en_US/PAIMode.md index 52cb31e82d..07cf53e25f 100644 --- a/docs/en_US/PAIMode.md +++ b/docs/en_US/PAIMode.md @@ -55,7 +55,7 @@ Compared with LocalMode and [RemoteMachineMode](RemoteMachineMode.md), trial con * Optional key. It specifies the HDFS data direcotry for trial to download data. The format should be something like hdfs://{your HDFS host}:9000/{your data directory} * outputDir * Optional key. It specifies the HDFS output directory for trial. Once the trial is completed (either succeed or fail), trial's stdout, stderr will be copied to this directory by NNI sdk automatically. The format should be something like hdfs://{your HDFS host}:9000/{your output directory} -* virturlCluster +* virtualCluster * Optional key. Set the virtualCluster of OpenPAI. If omitted, the job will run on default virtual cluster. * shmMB * Optional key. Set the shmMB configuration of OpenPAI, it set the shared memory for one task in the task role. diff --git a/src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py b/src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py index 7ab1a68167..542372f873 100644 --- a/src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py +++ b/src/sdk/pynni/nni/hyperband_advisor/hyperband_advisor.py @@ -143,7 +143,7 @@ def __init__(self, s, s_max, eta, R, optimize_mode): self.s_max = s_max self.eta = eta self.n = math.ceil((s_max + 1) * (eta**s) / (s + 1) - _epsilon) # pylint: disable=invalid-name - self.r = math.ceil(R / eta**s - _epsilon) # pylint: disable=invalid-name + self.r = R / eta**s # pylint: disable=invalid-name self.i = 0 self.hyper_configs = [] # [ {id: params}, {}, ... ] self.configs_perf = [] # [ {id: [seq, acc]}, {}, ... ] @@ -158,7 +158,7 @@ def is_completed(self): def get_n_r(self): """return the values of n and r for the next round""" - return math.floor(self.n / self.eta**self.i + _epsilon), self.r * self.eta**self.i + return math.floor(self.n / self.eta**self.i + _epsilon), math.floor(self.r * self.eta**self.i + _epsilon) def increase_i(self): """i means the ith round. Increase i by 1""" From 151013aa5ba7d38ca25bfc434ef30578fe7b09d8 Mon Sep 17 00:00:00 2001 From: Lijiao <35484733+lvybriage@users.noreply.github.com> Date: Mon, 1 Apr 2019 17:52:10 +0800 Subject: [PATCH 3/4] Fix issue #927: show experiment profile in the Overview page (#932) --- src/webui/src/components/Overview.tsx | 9 ++-- .../src/components/overview/TrialProfile.tsx | 44 ++++++++++++------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/webui/src/components/Overview.tsx b/src/webui/src/components/Overview.tsx index 14121c0123..a65842e836 100644 --- a/src/webui/src/components/Overview.tsx +++ b/src/webui/src/components/Overview.tsx @@ -20,6 +20,7 @@ require('../static/style/overviewTitle.scss'); interface OverviewState { tableData: Array; + experimentAPI: object; searchSpace: object; status: string; errorStr: string; @@ -47,6 +48,7 @@ class Overview extends React.Component<{}, OverviewState> { super(props); this.state = { searchSpace: {}, + experimentAPI: {}, status: '', errorStr: '', trialProfile: { @@ -143,6 +145,7 @@ class Overview extends React.Component<{}, OverviewState> { }); if (this._isMounted) { this.setState({ + experimentAPI: res.data, trialProfile: trialPro[0], searchSpace: searchSpace, isLogCollection: expLogCollection @@ -390,7 +393,7 @@ class Overview extends React.Component<{}, OverviewState> { const { trialProfile, searchSpace, tableData, accuracyData, accNodata, status, errorStr, trialNumber, bestAccuracy, - titleMaxbgcolor, titleMinbgcolor, isLogCollection + titleMaxbgcolor, titleMinbgcolor, isLogCollection, experimentAPI } = this.state; return ( @@ -425,9 +428,7 @@ class Overview extends React.Component<{}, OverviewState> { {/* the scroll bar all the trial profile in the searchSpace div*/}
- +
diff --git a/src/webui/src/components/overview/TrialProfile.tsx b/src/webui/src/components/overview/TrialProfile.tsx index 7276c445f5..592fa6a185 100644 --- a/src/webui/src/components/overview/TrialProfile.tsx +++ b/src/webui/src/components/overview/TrialProfile.tsx @@ -1,10 +1,9 @@ import * as React from 'react'; -import { Experiment } from '../../static/interface'; import MonacoEditor from 'react-monaco-editor'; import { MONACO } from '../../static/const'; interface TrialInfoProps { - tiralProInfo: Experiment; + experiment: object; } class TrialInfo extends React.Component { @@ -13,19 +12,32 @@ class TrialInfo extends React.Component { super(props); } - render() { - const { tiralProInfo } = this.props; - const showProInfo = []; - showProInfo.push({ - revision: tiralProInfo.revision, - authorName: tiralProInfo.author, - trialConcurrency: tiralProInfo.runConcurren, - tuner: tiralProInfo.tuner, - assessor: tiralProInfo.assessor ? tiralProInfo.assessor : undefined, - logCollection: tiralProInfo.logCollection ? tiralProInfo.logCollection : undefined, - advisor: tiralProInfo.advisor ? tiralProInfo.advisor : undefined, - clusterMetaData: tiralProInfo.clusterMetaData ? tiralProInfo.clusterMetaData : undefined + componentWillReceiveProps(nextProps: TrialInfoProps) { + const experiments = nextProps.experiment; + Object.keys(experiments).map(key => { + switch (key) { + case 'id': + case 'logDir': + case 'startTime': + case 'endTime': + experiments[key] = undefined; + break; + case 'params': + const params = experiments[key]; + Object.keys(params).map(item => { + if (item === 'experimentName' || item === 'searchSpace' + || item === 'trainingServicePlatform') { + params[item] = undefined; + } + }); + break; + default: + } }); + } + + render() { + const { experiment } = this.props; return (
{ height="380" language="json" theme="vs-light" - value={JSON.stringify(showProInfo[0], null, 2)} + value={JSON.stringify(experiment, null, 2)} options={MONACO} />
@@ -41,4 +53,4 @@ class TrialInfo extends React.Component { } } -export default TrialInfo; \ No newline at end of file +export default TrialInfo; From c49c24c483f42bb45ffa67e2955f730bbc99ad02 Mon Sep 17 00:00:00 2001 From: QuanluZhang Date: Mon, 1 Apr 2019 17:56:35 +0800 Subject: [PATCH 4/4] fix bug in smac search space convert (#940) * fix bug in smac search space convert * update docstring --- src/sdk/pynni/nni/smac_tuner/smac_tuner.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/sdk/pynni/nni/smac_tuner/smac_tuner.py b/src/sdk/pynni/nni/smac_tuner/smac_tuner.py index 2eb76d97bc..2a17becdeb 100644 --- a/src/sdk/pynni/nni/smac_tuner/smac_tuner.py +++ b/src/sdk/pynni/nni/smac_tuner/smac_tuner.py @@ -192,17 +192,20 @@ def convert_loguniform_categorical(self, challenger_dict): Returns ------- dict - challenger dict + dict which stores copy of challengers """ + converted_dict = {} for key, value in challenger_dict.items(): # convert to loguniform if key in self.loguniform_key: - challenger_dict[key] = np.exp(challenger_dict[key]) + converted_dict[key] = np.exp(challenger_dict[key]) # convert categorical back to original value - if key in self.categorical_dict: + elif key in self.categorical_dict: idx = challenger_dict[key] - challenger_dict[key] = self.categorical_dict[key][idx] - return challenger_dict + converted_dict[key] = self.categorical_dict[key][idx] + else: + converted_dict[key] = value + return converted_dict def generate_parameters(self, parameter_id): """generate one instance of hyperparameters @@ -220,13 +223,11 @@ def generate_parameters(self, parameter_id): if self.first_one: init_challenger = self.smbo_solver.nni_smac_start() self.total_data[parameter_id] = init_challenger - json_tricks.dumps(init_challenger.get_dictionary()) return self.convert_loguniform_categorical(init_challenger.get_dictionary()) else: challengers = self.smbo_solver.nni_smac_request_challengers() for challenger in challengers: self.total_data[parameter_id] = challenger - json_tricks.dumps(challenger.get_dictionary()) return self.convert_loguniform_categorical(challenger.get_dictionary()) def generate_multiple_parameters(self, parameter_id_list): @@ -247,7 +248,6 @@ def generate_multiple_parameters(self, parameter_id_list): for one_id in parameter_id_list: init_challenger = self.smbo_solver.nni_smac_start() self.total_data[one_id] = init_challenger - json_tricks.dumps(init_challenger.get_dictionary()) params.append(self.convert_loguniform_categorical(init_challenger.get_dictionary())) else: challengers = self.smbo_solver.nni_smac_request_challengers() @@ -257,7 +257,6 @@ def generate_multiple_parameters(self, parameter_id_list): if cnt >= len(parameter_id_list): break self.total_data[parameter_id_list[cnt]] = challenger - json_tricks.dumps(challenger.get_dictionary()) params.append(self.convert_loguniform_categorical(challenger.get_dictionary())) cnt += 1 return params