From c5e26efdcf15879e379977d14fab9e050152f814 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Sun, 19 Jul 2020 23:44:28 +0800 Subject: [PATCH 01/12] add trial job detail link --- src/nni_manager/training_service/pai/paiConfig.ts | 4 +++- src/nni_manager/training_service/pai/paiJobInfoCollector.ts | 2 +- .../training_service/pai/paiK8S/paiK8STrainingService.ts | 4 +++- src/nni_manager/training_service/reusable/trialDispatcher.ts | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/nni_manager/training_service/pai/paiConfig.ts b/src/nni_manager/training_service/pai/paiConfig.ts index eceda619c7..fa38d007d7 100644 --- a/src/nni_manager/training_service/pai/paiConfig.ts +++ b/src/nni_manager/training_service/pai/paiConfig.ts @@ -45,9 +45,10 @@ export class PAITrialJobDetail implements TrialJobDetail { public form: TrialJobApplicationForm; public logPath: string; public isEarlyStopped?: boolean; + public paiJobDetailUrl?: string; constructor(id: string, status: TrialJobStatus, paiJobName: string, - submitTime: number, workingDirectory: string, form: TrialJobApplicationForm, logPath: string) { + submitTime: number, workingDirectory: string, form: TrialJobApplicationForm, logPath: string, paiJobDetailUrl?: string) { this.id = id; this.status = status; this.paiJobName = paiJobName; @@ -56,5 +57,6 @@ export class PAITrialJobDetail implements TrialJobDetail { this.form = form; this.tags = []; this.logPath = logPath; + this.paiJobDetailUrl = paiJobDetailUrl; } } diff --git a/src/nni_manager/training_service/pai/paiJobInfoCollector.ts b/src/nni_manager/training_service/pai/paiJobInfoCollector.ts index eb15765a4f..2590547849 100644 --- a/src/nni_manager/training_service/pai/paiJobInfoCollector.ts +++ b/src/nni_manager/training_service/pai/paiJobInfoCollector.ts @@ -84,7 +84,7 @@ export class PAIJobInfoCollector { if (response.body.jobStatus.appTrackingUrl) { paiTrialJob.url = response.body.jobStatus.appTrackingUrl; } else { - paiTrialJob.url = paiTrialJob.logPath; + paiTrialJob.url = paiTrialJob.paiJobDetailUrl; } } break; diff --git a/src/nni_manager/training_service/pai/paiK8S/paiK8STrainingService.ts b/src/nni_manager/training_service/pai/paiK8S/paiK8STrainingService.ts index e243387d39..f046fcda5c 100644 --- a/src/nni_manager/training_service/pai/paiK8S/paiK8STrainingService.ts +++ b/src/nni_manager/training_service/pai/paiK8S/paiK8STrainingService.ts @@ -123,6 +123,7 @@ class PAIK8STrainingService extends PAITrainingService { const trialWorkingFolder: string = path.join(this.expRootDir, 'trials', trialJobId); const paiJobName: string = `nni_exp_${this.experimentId}_trial_${trialJobId}`; const logPath: string = path.join(this.paiTrialConfig.nniManagerNFSMountPath, this.experimentId, trialJobId); + const paiJobDetailUrl: string = `${this.protocol}://${this.paiClusterConfig.host}/job-detail.html?username=${this.paiClusterConfig.userName}&jobName=${paiJobName}`; const trialJobDetail: PAITrialJobDetail = new PAITrialJobDetail( trialJobId, 'WAITING', @@ -130,7 +131,8 @@ class PAIK8STrainingService extends PAITrainingService { Date.now(), trialWorkingFolder, form, - logPath); + logPath, + paiJobDetailUrl); this.trialJobsMap.set(trialJobId, trialJobDetail); this.jobQueue.push(trialJobId); diff --git a/src/nni_manager/training_service/reusable/trialDispatcher.ts b/src/nni_manager/training_service/reusable/trialDispatcher.ts index 156909e129..ff324899c6 100644 --- a/src/nni_manager/training_service/reusable/trialDispatcher.ts +++ b/src/nni_manager/training_service/reusable/trialDispatcher.ts @@ -362,6 +362,7 @@ class TrialDispatcher implements TrainingService { liveTrialsCount++; continue; } + trial.url = environment.trackingUrl; const environmentStatus = environment.status; // any node exit, then make sure the whole trial stopped. From 60c888f7449caffc62827ef6f57368700bfe9688 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Mon, 27 Jul 2020 09:45:45 +0800 Subject: [PATCH 02/12] init --- tools/nni_cmd/nnictl.py | 26 ++++++++++++-------- tools/nni_cmd/nnictl_utils.py | 46 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/tools/nni_cmd/nnictl.py b/tools/nni_cmd/nnictl.py index 6a2991fe50..c6c65271db 100644 --- a/tools/nni_cmd/nnictl.py +++ b/tools/nni_cmd/nnictl.py @@ -11,7 +11,8 @@ from .nnictl_utils import stop_experiment, trial_ls, trial_kill, list_experiment, experiment_status,\ log_trial, experiment_clean, platform_clean, experiment_list, \ monitor_experiment, export_trials_data, trial_codegen, webui_url, \ - get_config, log_stdout, log_stderr, search_space_auto_gen, webui_nas + get_config, log_stdout, log_stderr, search_space_auto_gen, webui_nas, \ + save_experiment from .package_management import package_install, package_uninstall, package_show, package_list from .constants import DEFAULT_REST_PORT from .tensorboard_utils import start_tensorboard, stop_tensorboard @@ -129,15 +130,6 @@ def parse_args(): parser_experiment_clean.add_argument('id', nargs='?', help='the id of experiment') parser_experiment_clean.add_argument('--all', action='store_true', default=False, help='delete all of experiments') parser_experiment_clean.set_defaults(func=experiment_clean) - - #parse experiment command - parser_platform = subparsers.add_parser('platform', help='get platform information') - #add subparsers for parser_experiment - parser_platform_subparsers = parser_platform.add_subparsers() - parser_platform_clean = parser_platform_subparsers.add_parser('clean', help='clean up the platform data') - parser_platform_clean.add_argument('--config', '-c', required=True, dest='config', help='the path of yaml config file') - parser_platform_clean.set_defaults(func=platform_clean) - #import tuning data parser_import_data = parser_experiment_subparsers.add_parser('import', help='import additional data') parser_import_data.add_argument('id', nargs='?', help='the id of experiment') @@ -149,6 +141,20 @@ def parse_args(): parser_trial_export.add_argument('--type', '-t', choices=['json', 'csv'], required=True, dest='type', help='target file type') parser_trial_export.add_argument('--filename', '-f', required=True, dest='path', help='target file path') parser_trial_export.set_defaults(func=export_trials_data) + #save experiment data + parser_import_data = parser_experiment_subparsers.add_parser('save', help='save experiment data') + parser_import_data.add_argument('id', nargs='?', help='the id of experiment') + parser_import_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, default current working directory') + parser_import_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data of the experiment') + parser_import_data.set_defaults(func=save_experiment) + + #parse platform command + parser_platform = subparsers.add_parser('platform', help='get platform information') + #add subparsers for parser_platform + parser_platform_subparsers = parser_platform.add_subparsers() + parser_platform_clean = parser_platform_subparsers.add_parser('clean', help='clean up the platform data') + parser_platform_clean.add_argument('--config', '-c', required=True, dest='config', help='the path of yaml config file') + parser_platform_clean.set_defaults(func=platform_clean) #TODO:finish webui function #parse board command diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index bbbf54fcc6..96ebc9f6dd 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -5,7 +5,9 @@ import os import sys import json +import tempfile import time +import random import re import shutil import subprocess @@ -736,3 +738,47 @@ def search_space_auto_gen(args): print_warning('Expected search space file \'{}\' generated, but not found.'.format(file_path)) else: print_normal('Generate search space done: \'{}\'.'.format(file_path)) + +def save_experiment(args): + '''save experiment data to a zip file''' + experiment_config = Experiments() + experiment_dict = experiment_config.get_all_experiments() + if args.id is None: + print_error('please set experiment id.') + exit(1) + if args.id not in experiment_dict: + print_error('Cannot find experiment {0}.'.format(args.id)) + exit(1) + print_normal('SAVING...') + nni_config = Config(experiment_dict[args.id]['fileName']) + logDir = os.path.join(os.path.expanduser("~"), 'nni', 'experiments', args.id) + if nni_config.get_config('logDir'): + logDir = os.path.join(nni_config.get_config('logDir'), args.id) + temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', random.sample(string.ascii_letters + string.digits, 8)) + # copy logDir to temp folder + temp_experiment_dir = os.path.join(temp_root_dir, 'experiment') + os.makedirs(temp_experiment_dir, exist_ok = True) + shutil.copytree(logDir, temp_experiment_dir) + # copy nnictl metadata to temp folder + temp_nnictl_dir = os.path.join(temp_root_dir, 'nnictl') + os.makedirs(temp_nnictl_dir, exist_ok = True) + try: + with open(os.path.join(temp_nnictl_dir, '.experiment'), 'w') as file: + json.dump(experiment_dict[args.id], file) + except IOError as error: + print_error('Write file to %s failed!' % os.path.join(temp_nnictl_dir, '.experiment')) + exit(1) + nnictl_config_dir = os.path.join(NNICTL_HOME_DIR, experiment_dict[args.id]['fileName']) + shutil.copytree(nnictl_config_dir, temp_nnictl_dir) + # copy code Dir + if args.saveCodeDir: + temp_code_dir = os.path.join(temp_root_dir, 'code') + os.makedirs(temp_code_dir, exist_ok = True) + shutil.copytree(nni_config.get_config('trial')['codeDir'], temp_nnictl_dir) + zip_package_name = 'nni_experiment_%s.zip' % args.id + if args.path: + os.makedirs(args.path, exist_ok = True) + os.path.join(args.path, zip_package_name) + shutil.make_archive(zip_package_name, 'zip', temp_root_dir) + shutil.rmtree(temp_root_dir) + print_normal('Save to %s success!' % zip_package_name) From d68f73f4d256db618ef03cb61bbbc86700a528fa Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Thu, 30 Jul 2020 19:55:24 +0800 Subject: [PATCH 03/12] update command --- tools/nni_cmd/config_utils.py | 8 +- tools/nni_cmd/nnictl.py | 18 +++-- tools/nni_cmd/nnictl_utils.py | 136 ++++++++++++++++++++++++++++++---- 3 files changed, 139 insertions(+), 23 deletions(-) diff --git a/tools/nni_cmd/config_utils.py b/tools/nni_cmd/config_utils.py index 8cc1dc8ada..e6472ee3de 100644 --- a/tools/nni_cmd/config_utils.py +++ b/tools/nni_cmd/config_utils.py @@ -54,13 +54,13 @@ def __init__(self): self.experiment_file = os.path.join(NNICTL_HOME_DIR, '.experiment') self.experiments = self.read_file() - def add_experiment(self, expId, port, time, file_name, platform, experiment_name): + def add_experiment(self, expId, port, startTime, file_name, platform, experiment_name, endTime='N/A', status='INITIALIZED'): '''set {key:value} paris to self.experiment''' self.experiments[expId] = {} self.experiments[expId]['port'] = port - self.experiments[expId]['startTime'] = time - self.experiments[expId]['endTime'] = 'N/A' - self.experiments[expId]['status'] = 'INITIALIZED' + self.experiments[expId]['startTime'] = startTime + self.experiments[expId]['endTime'] = endTime + self.experiments[expId]['status'] = status self.experiments[expId]['fileName'] = file_name self.experiments[expId]['platform'] = platform self.experiments[expId]['experimentName'] = experiment_name diff --git a/tools/nni_cmd/nnictl.py b/tools/nni_cmd/nnictl.py index c6c65271db..fae79b3786 100644 --- a/tools/nni_cmd/nnictl.py +++ b/tools/nni_cmd/nnictl.py @@ -12,7 +12,7 @@ log_trial, experiment_clean, platform_clean, experiment_list, \ monitor_experiment, export_trials_data, trial_codegen, webui_url, \ get_config, log_stdout, log_stderr, search_space_auto_gen, webui_nas, \ - save_experiment + save_experiment, open_experiment from .package_management import package_install, package_uninstall, package_show, package_list from .constants import DEFAULT_REST_PORT from .tensorboard_utils import start_tensorboard, stop_tensorboard @@ -142,11 +142,17 @@ def parse_args(): parser_trial_export.add_argument('--filename', '-f', required=True, dest='path', help='target file path') parser_trial_export.set_defaults(func=export_trials_data) #save experiment data - parser_import_data = parser_experiment_subparsers.add_parser('save', help='save experiment data') - parser_import_data.add_argument('id', nargs='?', help='the id of experiment') - parser_import_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, default current working directory') - parser_import_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data of the experiment') - parser_import_data.set_defaults(func=save_experiment) + parser_save_data = parser_experiment_subparsers.add_parser('save', help='save experiment data') + parser_save_data.add_argument('id', nargs='?', help='the id of experiment') + parser_save_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, default current working directory') + parser_save_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data of the experiment') + parser_save_data.set_defaults(func=save_experiment) + #open experiment data + parser_open_data = parser_experiment_subparsers.add_parser('open', help='open experiment data') + parser_open_data.add_argument('--path', '-p', required=True, help='the path of nni package file') + parser_open_data.add_argument('--codeDir', '-c', required=True, help='the path of codeDir') + parser_open_data.add_argument('--logDir', '-l', required=False, help='the path of logDir') + parser_open_data.set_defaults(func=open_experiment) #parse platform command parser_platform = subparsers.add_parser('platform', help='get platform information') diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 96ebc9f6dd..4e705b2ab5 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -9,6 +9,7 @@ import time import random import re +import string import shutil import subprocess from datetime import datetime, timezone @@ -749,36 +750,145 @@ def save_experiment(args): if args.id not in experiment_dict: print_error('Cannot find experiment {0}.'.format(args.id)) exit(1) - print_normal('SAVING...') + print_normal('Saving...') nni_config = Config(experiment_dict[args.id]['fileName']) - logDir = os.path.join(os.path.expanduser("~"), 'nni', 'experiments', args.id) + logDir = os.path.join(os.path.expanduser("~"), 'nni-experiments', args.id) if nni_config.get_config('logDir'): logDir = os.path.join(nni_config.get_config('logDir'), args.id) - temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', random.sample(string.ascii_letters + string.digits, 8)) - # copy logDir to temp folder + temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', ''.join(random.sample(string.ascii_letters + string.digits, 8))) + + # Step1. Copy logDir to temp folder + if not os.path.exists(logDir): + print_error('logDir: %s does not exist!' % logDir) + exit(1) temp_experiment_dir = os.path.join(temp_root_dir, 'experiment') - os.makedirs(temp_experiment_dir, exist_ok = True) shutil.copytree(logDir, temp_experiment_dir) - # copy nnictl metadata to temp folder + + # Step2. Copy nnictl metadata to temp folder temp_nnictl_dir = os.path.join(temp_root_dir, 'nnictl') os.makedirs(temp_nnictl_dir, exist_ok = True) try: with open(os.path.join(temp_nnictl_dir, '.experiment'), 'w') as file: + experiment_dict[args.id]['id'] = args.id json.dump(experiment_dict[args.id], file) except IOError as error: print_error('Write file to %s failed!' % os.path.join(temp_nnictl_dir, '.experiment')) exit(1) nnictl_config_dir = os.path.join(NNICTL_HOME_DIR, experiment_dict[args.id]['fileName']) - shutil.copytree(nnictl_config_dir, temp_nnictl_dir) - # copy code Dir + shutil.copytree(nnictl_config_dir, os.path.join(temp_nnictl_dir, experiment_dict[args.id]['fileName'])) + + # Step3. Copy code dir if args.saveCodeDir: temp_code_dir = os.path.join(temp_root_dir, 'code') - os.makedirs(temp_code_dir, exist_ok = True) - shutil.copytree(nni_config.get_config('trial')['codeDir'], temp_nnictl_dir) - zip_package_name = 'nni_experiment_%s.zip' % args.id + shutil.copytree(nni_config.get_config('trial')['codeDir'], temp_code_dir) + + # Step4. Archive folder + zip_package_name = 'nni_experiment_%s' % args.id if args.path: os.makedirs(args.path, exist_ok = True) - os.path.join(args.path, zip_package_name) + zip_package_name = os.path.join(args.path, zip_package_name) shutil.make_archive(zip_package_name, 'zip', temp_root_dir) + print_normal('Save to %s.zip success!' % zip_package_name) + + # Step5. Cleanup temp data + shutil.rmtree(temp_root_dir) + +def open_experiment(args): + '''open experiment data''' + package_path = os.path.expanduser(args.path) + if not os.path.exists(args.path): + print_error('file path %s does not exist!' % args.path) + exit(1) + temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', ''.join(random.sample(string.ascii_letters + string.digits, 8))) + shutil.unpack_archive(package_path, temp_root_dir) + print_normal('Opening...') + # Step1. Validation + if not os.path.exists(args.codeDir): + print_error('Invalid: codeDir path does not exist!') + exit(1) + if args.logDir: + if not os.path.exists(args.logDir): + print_error('Invalid: logDir path does not exist!') + exit(1) + experiment_temp_dir = os.path.join(temp_root_dir, 'experiment') + if not os.path.exists(os.path.join(experiment_temp_dir, 'db')): + print_error('Invalid archive file: db file does not exist!') + shutil.rmtree(temp_root_dir) + exit(1) + nnictl_temp_dir = os.path.join(temp_root_dir, 'nnictl') + if not os.path.exists(os.path.join(nnictl_temp_dir, '.experiment')): + print_error('Invalid archive file: nnictl metadata file does not exist!') + shutil.rmtree(temp_root_dir) + exit(1) + try: + with open(os.path.join(nnictl_temp_dir, '.experiment'), 'r') as file: + experiment_metadata = json.load(file) + except ValueError as err: + print_error('Invalid nnictl metadata file: %s' % err) + shutil.rmtree(temp_root_dir) + exit(1) + experiment_config = Experiments() + experiment_dict = experiment_config.get_all_experiments() + experiment_id = experiment_metadata.get('id') + if experiment_id in experiment_dict: + print_error('Invalid: experiment id already exist!') + shutil.rmtree(temp_root_dir) + exit(1) + if not os.path.exists(os.path.join(nnictl_temp_dir, experiment_metadata.get('fileName'))): + print_error('Invalid: experiment metadata does not exist!') + shutil.rmtree(temp_root_dir) + exit(1) + + # Step2. Copy nnictl metadata + src_path = os.path.join(nnictl_temp_dir, experiment_metadata.get('fileName')) + dest_path = os.path.join(NNICTL_HOME_DIR, experiment_metadata.get('fileName')) + if os.path.exists(dest_path): + shutil.rmtree(dest_path) + shutil.copytree(src_path, dest_path) + + # Step3. Copy experiment data + nni_config = Config(experiment_metadata.get('fileName')) + if args.logDir: + logDir = args.logDir + nni_config.set_config('logDir', logDir) + else: + if nni_config.get_config('logDir'): + logDir = nni_config['logDir'] + else: + logDir = os.path.join(os.path.expanduser("~"), 'nni-experiments') + os.rename(os.path.join(temp_root_dir, 'experiment'), os.path.join(temp_root_dir, experiment_id)) + src_path = os.path.join(os.path.join(temp_root_dir, experiment_id)) + dest_path = os.path.join(os.path.join(logDir, experiment_id)) + if os.path.exists(dest_path): + shutil.rmtree(dest_path) + shutil.copytree(src_path, dest_path) + + # Step4. Copy code dir + nni_config.set_config('codeDir', args.codeDir) + archive_code_dir = os.path.join(temp_root_dir, 'code') + if os.path.exists(archive_code_dir): + file_list = os.listdir(archive_code_dir) + for file_name in file_list: + src_path = os.path.join(archive_code_dir, file_name) + target_path = os.path.join(args.codeDir, file_name) + if os.path.exists(target_path): + print_error('Copy %s failed, %s exist!' % (file_name, target_path)) + continue + if os.path.isdir(src_path): + shutil.copytree(src_path, target_path) + else: + shutil.copy(src_path, target_path) + + # Step5. Create experiment metadata + experiment_config.add_experiment(experiment_id, + experiment_metadata.get('port'), + experiment_metadata.get('startTime'), + experiment_metadata.get('fileName'), + experiment_metadata.get('platform'), + experiment_metadata.get('experimentName'), + experiment_metadata.get('endTime'), + experiment_metadata.get('status')) + print_normal('Open experiment %s succsss!' % experiment_id) + + # Step6. Cleanup temp data shutil.rmtree(temp_root_dir) - print_normal('Save to %s success!' % zip_package_name) From 806ce57720adecc3ac715a03a99abf7d9f0164de Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Fri, 31 Jul 2020 11:45:25 +0800 Subject: [PATCH 04/12] add doc --- docs/en_US/Tutorial/Nnictl.md | 59 +++++++++++++++++++++++++++++++++-- tools/nni_cmd/nnictl_utils.py | 20 +++++++----- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/docs/en_US/Tutorial/Nnictl.md b/docs/en_US/Tutorial/Nnictl.md index ed5c9761e1..6935addd17 100644 --- a/docs/en_US/Tutorial/Nnictl.md +++ b/docs/en_US/Tutorial/Nnictl.md @@ -444,9 +444,6 @@ Debug mode will disable version check function in Trialkeeper. |--all| False| |delete all of experiments| - - - * __nnictl experiment export__ * Description @@ -531,6 +528,62 @@ Debug mode will disable version check function in Trialkeeper. nnictl experiment import [experiment_id] -f experiment_data.json ``` +* __nnictl experiment save__ + * Description + + Save nni experiment metadata and code data. + + * Usage + + ```bash + nnictl experiment save [OPTIONS] + ``` + + * Options + + |Name, shorthand|Required|Default|Description| + |------|------|------ |------| + |id| True| |The id of the experiment you want to save| + |--path, -p| False| |the folder path to store nni experiment data, default current working directory| + |--saveCodeDir, -s| | |save codeDir data of the experiment, default False| + + * Examples + + > save an expeirment + + ```bash + nnictl experiment save [experiment_id] --saveCodeDir + ``` + +* __nnictl experiment open__ + * Description + + Open a nni experiment. + + * Usage + + ```bash + nnictl experiment open [OPTIONS] + ``` + + * Options + + |Name, shorthand|Required|Default|Description| + |------|------|------ |------| + |--path, -p| True| |the full file path of nni package| + |--codeDir, -c| True| |the path of codeDir| + |--logDir, -l| False| |the path of logDir| + + * Examples + + > open an expeirment + + ```bash + nnictl experiment open --path [path] --codeDir [codeDir] + ``` + + + ### Manage platform information diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 4e705b2ab5..62f9d90b59 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -500,7 +500,7 @@ def experiment_clean(args): home = str(Path.home()) local_dir = nni_config.get_config('experimentConfig').get('logDir') if not local_dir: - local_dir = os.path.join(home, 'nni', 'experiments', experiment_id) + local_dir = os.path.join(home, 'nni-experiments', experiment_id) local_clean(local_dir) experiment_config = Experiments() print_normal('removing metadata of experiment {0}'.format(experiment_id)) @@ -780,7 +780,7 @@ def save_experiment(args): # Step3. Copy code dir if args.saveCodeDir: temp_code_dir = os.path.join(temp_root_dir, 'code') - shutil.copytree(nni_config.get_config('trial')['codeDir'], temp_code_dir) + shutil.copytree(nni_config.get_config('experimentConfig')['trial']['codeDir'], temp_code_dir) # Step4. Archive folder zip_package_name = 'nni_experiment_%s' % args.id @@ -848,12 +848,13 @@ def open_experiment(args): # Step3. Copy experiment data nni_config = Config(experiment_metadata.get('fileName')) + nnictl_exp_config = nni_config.get_config('experimentConfig') if args.logDir: logDir = args.logDir - nni_config.set_config('logDir', logDir) + nnictl_exp_config['logDir'] = logDir else: - if nni_config.get_config('logDir'): - logDir = nni_config['logDir'] + if nnictl_exp_config.get('logDir'): + logDir = nnictl_exp_config['logDir'] else: logDir = os.path.join(os.path.expanduser("~"), 'nni-experiments') os.rename(os.path.join(temp_root_dir, 'experiment'), os.path.join(temp_root_dir, experiment_id)) @@ -864,13 +865,17 @@ def open_experiment(args): shutil.copytree(src_path, dest_path) # Step4. Copy code dir - nni_config.set_config('codeDir', args.codeDir) + codeDir = os.path.expanduser(args.codeDir) + if not os.path.isabs(codeDir): + codeDir = os.path.join(os. getcwd(), codeDir) + print_normal('Expand codeDir to %s' % codeDir) + nnictl_exp_config['trial']['codeDir'] = codeDir archive_code_dir = os.path.join(temp_root_dir, 'code') if os.path.exists(archive_code_dir): file_list = os.listdir(archive_code_dir) for file_name in file_list: src_path = os.path.join(archive_code_dir, file_name) - target_path = os.path.join(args.codeDir, file_name) + target_path = os.path.join(codeDir, file_name) if os.path.exists(target_path): print_error('Copy %s failed, %s exist!' % (file_name, target_path)) continue @@ -880,6 +885,7 @@ def open_experiment(args): shutil.copy(src_path, target_path) # Step5. Create experiment metadata + nni_config.set_config('experimentConfig', nnictl_exp_config) experiment_config.add_experiment(experiment_id, experiment_metadata.get('port'), experiment_metadata.get('startTime'), From 2f3fb7a13cf67b182df004de6f0106dcb51bd008 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Fri, 31 Jul 2020 14:25:02 +0800 Subject: [PATCH 05/12] fix pylint --- tools/nni_cmd/nnictl.py | 6 ++++-- tools/nni_cmd/nnictl_utils.py | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/tools/nni_cmd/nnictl.py b/tools/nni_cmd/nnictl.py index fae79b3786..12999e2647 100644 --- a/tools/nni_cmd/nnictl.py +++ b/tools/nni_cmd/nnictl.py @@ -144,8 +144,10 @@ def parse_args(): #save experiment data parser_save_data = parser_experiment_subparsers.add_parser('save', help='save experiment data') parser_save_data.add_argument('id', nargs='?', help='the id of experiment') - parser_save_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, default current working directory') - parser_save_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data of the experiment') + parser_save_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, \ + default current working directory') + parser_save_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data \ + of the experiment') parser_save_data.set_defaults(func=save_experiment) #open experiment data parser_open_data = parser_experiment_subparsers.add_parser('open', help='open experiment data') diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 62f9d90b59..85940ec8a4 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -771,7 +771,7 @@ def save_experiment(args): with open(os.path.join(temp_nnictl_dir, '.experiment'), 'w') as file: experiment_dict[args.id]['id'] = args.id json.dump(experiment_dict[args.id], file) - except IOError as error: + except IOError: print_error('Write file to %s failed!' % os.path.join(temp_nnictl_dir, '.experiment')) exit(1) nnictl_config_dir = os.path.join(NNICTL_HOME_DIR, experiment_dict[args.id]['fileName']) @@ -781,11 +781,11 @@ def save_experiment(args): if args.saveCodeDir: temp_code_dir = os.path.join(temp_root_dir, 'code') shutil.copytree(nni_config.get_config('experimentConfig')['trial']['codeDir'], temp_code_dir) - + # Step4. Archive folder zip_package_name = 'nni_experiment_%s' % args.id if args.path: - os.makedirs(args.path, exist_ok = True) + os.makedirs(args.path, exist_ok=True) zip_package_name = os.path.join(args.path, zip_package_name) shutil.make_archive(zip_package_name, 'zip', temp_root_dir) print_normal('Save to %s.zip success!' % zip_package_name) @@ -838,14 +838,14 @@ def open_experiment(args): print_error('Invalid: experiment metadata does not exist!') shutil.rmtree(temp_root_dir) exit(1) - + # Step2. Copy nnictl metadata src_path = os.path.join(nnictl_temp_dir, experiment_metadata.get('fileName')) dest_path = os.path.join(NNICTL_HOME_DIR, experiment_metadata.get('fileName')) if os.path.exists(dest_path): shutil.rmtree(dest_path) shutil.copytree(src_path, dest_path) - + # Step3. Copy experiment data nni_config = Config(experiment_metadata.get('fileName')) nnictl_exp_config = nni_config.get_config('experimentConfig') @@ -883,17 +883,17 @@ def open_experiment(args): shutil.copytree(src_path, target_path) else: shutil.copy(src_path, target_path) - + # Step5. Create experiment metadata nni_config.set_config('experimentConfig', nnictl_exp_config) experiment_config.add_experiment(experiment_id, - experiment_metadata.get('port'), - experiment_metadata.get('startTime'), - experiment_metadata.get('fileName'), - experiment_metadata.get('platform'), - experiment_metadata.get('experimentName'), - experiment_metadata.get('endTime'), - experiment_metadata.get('status')) + experiment_metadata.get('port'), + experiment_metadata.get('startTime'), + experiment_metadata.get('fileName'), + experiment_metadata.get('platform'), + experiment_metadata.get('experimentName'), + experiment_metadata.get('endTime'), + experiment_metadata.get('status')) print_normal('Open experiment %s succsss!' % experiment_id) # Step6. Cleanup temp data From dfdcf1fe4de71a0dba4739fe5b021c6f4bc9bc91 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Fri, 31 Jul 2020 17:27:37 +0800 Subject: [PATCH 06/12] fix pylint --- tools/nni_cmd/nnictl_utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 85940ec8a4..754a8bb7d5 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -500,7 +500,7 @@ def experiment_clean(args): home = str(Path.home()) local_dir = nni_config.get_config('experimentConfig').get('logDir') if not local_dir: - local_dir = os.path.join(home, 'nni-experiments', experiment_id) + local_dir = os.path.join(home, 'nni', 'experiments', experiment_id) local_clean(local_dir) experiment_config = Experiments() print_normal('removing metadata of experiment {0}'.format(experiment_id)) @@ -766,7 +766,7 @@ def save_experiment(args): # Step2. Copy nnictl metadata to temp folder temp_nnictl_dir = os.path.join(temp_root_dir, 'nnictl') - os.makedirs(temp_nnictl_dir, exist_ok = True) + os.makedirs(temp_nnictl_dir, exist_ok=True) try: with open(os.path.join(temp_nnictl_dir, '.experiment'), 'w') as file: experiment_dict[args.id]['id'] = args.id From 576bfe9f43c65c4f952f52097287727e7608dc62 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Wed, 5 Aug 2020 09:52:53 +0800 Subject: [PATCH 07/12] change args to nnictl experiment load --- docs/en_US/Tutorial/Nnictl.md | 10 +++++----- tools/nni_cmd/nnictl.py | 6 +++--- tools/nni_cmd/nnictl_utils.py | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/en_US/Tutorial/Nnictl.md b/docs/en_US/Tutorial/Nnictl.md index 6935addd17..a1b7503016 100644 --- a/docs/en_US/Tutorial/Nnictl.md +++ b/docs/en_US/Tutorial/Nnictl.md @@ -555,15 +555,15 @@ Debug mode will disable version check function in Trialkeeper. nnictl experiment save [experiment_id] --saveCodeDir ``` -* __nnictl experiment open__ +* __nnictl experiment load__ * Description - Open a nni experiment. + Load a nni experiment. * Usage ```bash - nnictl experiment open [OPTIONS] + nnictl experiment load [OPTIONS] ``` * Options @@ -576,10 +576,10 @@ Debug mode will disable version check function in Trialkeeper. * Examples - > open an expeirment + > load an expeirment ```bash - nnictl experiment open --path [path] --codeDir [codeDir] + nnictl experiment load --path [path] --codeDir [codeDir] ``` diff --git a/tools/nni_cmd/nnictl.py b/tools/nni_cmd/nnictl.py index 12999e2647..7aabc7b8f9 100644 --- a/tools/nni_cmd/nnictl.py +++ b/tools/nni_cmd/nnictl.py @@ -12,7 +12,7 @@ log_trial, experiment_clean, platform_clean, experiment_list, \ monitor_experiment, export_trials_data, trial_codegen, webui_url, \ get_config, log_stdout, log_stderr, search_space_auto_gen, webui_nas, \ - save_experiment, open_experiment + save_experiment, load_experiment from .package_management import package_install, package_uninstall, package_show, package_list from .constants import DEFAULT_REST_PORT from .tensorboard_utils import start_tensorboard, stop_tensorboard @@ -150,11 +150,11 @@ def parse_args(): of the experiment') parser_save_data.set_defaults(func=save_experiment) #open experiment data - parser_open_data = parser_experiment_subparsers.add_parser('open', help='open experiment data') + parser_open_data = parser_experiment_subparsers.add_parser('load', help='load experiment data') parser_open_data.add_argument('--path', '-p', required=True, help='the path of nni package file') parser_open_data.add_argument('--codeDir', '-c', required=True, help='the path of codeDir') parser_open_data.add_argument('--logDir', '-l', required=False, help='the path of logDir') - parser_open_data.set_defaults(func=open_experiment) + parser_open_data.set_defaults(func=load_experiment) #parse platform command parser_platform = subparsers.add_parser('platform', help='get platform information') diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 754a8bb7d5..0cdab86c54 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -793,8 +793,8 @@ def save_experiment(args): # Step5. Cleanup temp data shutil.rmtree(temp_root_dir) -def open_experiment(args): - '''open experiment data''' +def load_experiment(args): + '''load experiment data''' package_path = os.path.expanduser(args.path) if not os.path.exists(args.path): print_error('file path %s does not exist!' % args.path) From aa708ca61853c0ed5f0e0477e6bc2381ba9da06c Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Thu, 6 Aug 2020 11:52:29 +0800 Subject: [PATCH 08/12] fix pylint --- tools/nni_cmd/nnictl_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 0cdab86c54..4fb1a13275 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -781,7 +781,7 @@ def save_experiment(args): if args.saveCodeDir: temp_code_dir = os.path.join(temp_root_dir, 'code') shutil.copytree(nni_config.get_config('experimentConfig')['trial']['codeDir'], temp_code_dir) - + # Step4. Archive folder zip_package_name = 'nni_experiment_%s' % args.id if args.path: From 0080891b3fd5e18414095a6b8ab39388530b1aa8 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Tue, 11 Aug 2020 14:49:29 +0800 Subject: [PATCH 09/12] fix comments --- docs/en_US/Tutorial/Nnictl.md | 10 +++++----- tools/nni_cmd/common_utils.py | 13 +++++++++++++ tools/nni_cmd/constants.py | 2 ++ tools/nni_cmd/nnictl.py | 25 +++++++++++++------------ tools/nni_cmd/nnictl_utils.py | 20 ++++++++++---------- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/docs/en_US/Tutorial/Nnictl.md b/docs/en_US/Tutorial/Nnictl.md index a1b7503016..81caf6f047 100644 --- a/docs/en_US/Tutorial/Nnictl.md +++ b/docs/en_US/Tutorial/Nnictl.md @@ -545,7 +545,7 @@ Debug mode will disable version check function in Trialkeeper. |------|------|------ |------| |id| True| |The id of the experiment you want to save| |--path, -p| False| |the folder path to store nni experiment data, default current working directory| - |--saveCodeDir, -s| | |save codeDir data of the experiment, default False| + |--saveCodeDir, -s| False| |save codeDir data of the experiment, default False| * Examples @@ -558,7 +558,7 @@ Debug mode will disable version check function in Trialkeeper. * __nnictl experiment load__ * Description - Load a nni experiment. + Load an nni experiment. * Usage @@ -570,9 +570,9 @@ Debug mode will disable version check function in Trialkeeper. |Name, shorthand|Required|Default|Description| |------|------|------ |------| - |--path, -p| True| |the full file path of nni package| - |--codeDir, -c| True| |the path of codeDir| - |--logDir, -l| False| |the path of logDir| + |--path, -p| True| |the file path of nni package| + |--codeDir, -c| True| |the path of codeDir for loaded experiment, this path will also put the code in the loaded experiment package| + |--logDir, -l| False| |the path of logDir for loaded experiment| * Examples diff --git a/tools/nni_cmd/common_utils.py b/tools/nni_cmd/common_utils.py index 4166bf034c..c63a89faa5 100644 --- a/tools/nni_cmd/common_utils.py +++ b/tools/nni_cmd/common_utils.py @@ -4,7 +4,10 @@ import os import sys import json +import tempfile import socket +import string +import random import ruamel.yaml as yaml import psutil from colorama import Fore @@ -83,3 +86,13 @@ def check_tensorboard_version(): print_error('import tensorboard error!') exit(1) +def generate_temp_dir(): + '''generate a temp folder''' + def generate_folder_name(): + return os.path.join(tempfile.gettempdir(), 'nni', ''.join(random.sample(string.ascii_letters + string.digits, 8))) + temp_dir = generate_folder_name() + while os.path.exists(temp_dir): + temp_dir = generate_folder_name() + os.makedirs(temp_dir, exist_ok=True) + return temp_dir + diff --git a/tools/nni_cmd/constants.py b/tools/nni_cmd/constants.py index 5a37c3a1f1..0654473ed4 100644 --- a/tools/nni_cmd/constants.py +++ b/tools/nni_cmd/constants.py @@ -6,6 +6,8 @@ NNICTL_HOME_DIR = os.path.join(os.path.expanduser('~'), '.local', 'nnictl') +NNI_HOME_DIR = os.path.join(os.path.expanduser('~'), 'nni-experiments') + ERROR_INFO = 'ERROR: ' NORMAL_INFO = 'INFO: ' WARNING_INFO = 'WARNING: ' diff --git a/tools/nni_cmd/nnictl.py b/tools/nni_cmd/nnictl.py index 7aabc7b8f9..07afd85fab 100644 --- a/tools/nni_cmd/nnictl.py +++ b/tools/nni_cmd/nnictl.py @@ -141,20 +141,21 @@ def parse_args(): parser_trial_export.add_argument('--type', '-t', choices=['json', 'csv'], required=True, dest='type', help='target file type') parser_trial_export.add_argument('--filename', '-f', required=True, dest='path', help='target file path') parser_trial_export.set_defaults(func=export_trials_data) - #save experiment data - parser_save_data = parser_experiment_subparsers.add_parser('save', help='save experiment data') - parser_save_data.add_argument('id', nargs='?', help='the id of experiment') - parser_save_data.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, \ + #save an NNI experiment + parser_save_experiment = parser_experiment_subparsers.add_parser('save', help='save an experiment') + parser_save_experiment.add_argument('id', nargs='?', help='the id of experiment') + parser_save_experiment.add_argument('--path', '-p', required=False, help='the folder path to store nni experiment data, \ default current working directory') - parser_save_data.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data \ + parser_save_experiment.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data \ of the experiment') - parser_save_data.set_defaults(func=save_experiment) - #open experiment data - parser_open_data = parser_experiment_subparsers.add_parser('load', help='load experiment data') - parser_open_data.add_argument('--path', '-p', required=True, help='the path of nni package file') - parser_open_data.add_argument('--codeDir', '-c', required=True, help='the path of codeDir') - parser_open_data.add_argument('--logDir', '-l', required=False, help='the path of logDir') - parser_open_data.set_defaults(func=load_experiment) + parser_save_experiment.set_defaults(func=save_experiment) + #load an NNI experiment + parser_load_experiment = parser_experiment_subparsers.add_parser('load', help='load an experiment') + parser_load_experiment.add_argument('--path', '-p', required=True, help='the path of nni package file') + parser_load_experiment.add_argument('--codeDir', '-c', required=True, help='the path of codeDir for loaded experiment, \ + this path will also put the code in the loaded experiment package') + parser_load_experiment.add_argument('--logDir', '-l', required=False, help='the path of logDir for loaded experiment') + parser_load_experiment.set_defaults(func=load_experiment) #parse platform command parser_platform = subparsers.add_parser('platform', help='get platform information') diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 4fb1a13275..99b855e6fc 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -5,11 +5,8 @@ import os import sys import json -import tempfile import time -import random import re -import string import shutil import subprocess from datetime import datetime, timezone @@ -21,9 +18,9 @@ from .rest_utils import rest_get, rest_delete, check_rest_server_quick, check_response from .url_utils import trial_jobs_url, experiment_url, trial_job_id_url, export_data_url from .config_utils import Config, Experiments -from .constants import NNICTL_HOME_DIR, EXPERIMENT_INFORMATION_FORMAT, EXPERIMENT_DETAIL_FORMAT, \ +from .constants import NNICTL_HOME_DIR, NNI_HOME_DIR, EXPERIMENT_INFORMATION_FORMAT, EXPERIMENT_DETAIL_FORMAT, \ EXPERIMENT_MONITOR_INFO, TRIAL_MONITOR_HEAD, TRIAL_MONITOR_CONTENT, TRIAL_MONITOR_TAIL, REST_TIME_OUT -from .common_utils import print_normal, print_error, print_warning, detect_process, get_yml_content +from .common_utils import print_normal, print_error, print_warning, detect_process, get_yml_content, generate_temp_dir from .command_utils import check_output_command, kill_command from .ssh_utils import create_ssh_sftp_client, remove_remote_directory @@ -745,17 +742,20 @@ def save_experiment(args): experiment_config = Experiments() experiment_dict = experiment_config.get_all_experiments() if args.id is None: - print_error('please set experiment id.') + print_error('Please set experiment id.') exit(1) if args.id not in experiment_dict: print_error('Cannot find experiment {0}.'.format(args.id)) exit(1) + if experiment_dict[args.id].get('status') != 'STOPPED': + print_error('Can only save stopped experiment!') + exit(1) print_normal('Saving...') nni_config = Config(experiment_dict[args.id]['fileName']) - logDir = os.path.join(os.path.expanduser("~"), 'nni-experiments', args.id) + logDir = os.path.join(NNI_HOME_DIR, args.id) if nni_config.get_config('logDir'): logDir = os.path.join(nni_config.get_config('logDir'), args.id) - temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', ''.join(random.sample(string.ascii_letters + string.digits, 8))) + temp_root_dir = generate_temp_dir() # Step1. Copy logDir to temp folder if not os.path.exists(logDir): @@ -799,7 +799,7 @@ def load_experiment(args): if not os.path.exists(args.path): print_error('file path %s does not exist!' % args.path) exit(1) - temp_root_dir = os.path.join(tempfile.gettempdir(), 'nni', ''.join(random.sample(string.ascii_letters + string.digits, 8))) + temp_root_dir = generate_temp_dir() shutil.unpack_archive(package_path, temp_root_dir) print_normal('Opening...') # Step1. Validation @@ -867,7 +867,7 @@ def load_experiment(args): # Step4. Copy code dir codeDir = os.path.expanduser(args.codeDir) if not os.path.isabs(codeDir): - codeDir = os.path.join(os. getcwd(), codeDir) + codeDir = os.path.join(os.getcwd(), codeDir) print_normal('Expand codeDir to %s' % codeDir) nnictl_exp_config['trial']['codeDir'] = codeDir archive_code_dir = os.path.join(temp_root_dir, 'code') From 4ada4708d2d51e8ff93dd083a2d83bbadf7e6570 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Tue, 11 Aug 2020 16:36:57 +0800 Subject: [PATCH 10/12] fix comments --- tools/nni_cmd/common_utils.py | 2 +- tools/nni_cmd/nnictl_utils.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/nni_cmd/common_utils.py b/tools/nni_cmd/common_utils.py index c63a89faa5..52fcd04dad 100644 --- a/tools/nni_cmd/common_utils.py +++ b/tools/nni_cmd/common_utils.py @@ -93,6 +93,6 @@ def generate_folder_name(): temp_dir = generate_folder_name() while os.path.exists(temp_dir): temp_dir = generate_folder_name() - os.makedirs(temp_dir, exist_ok=True) + os.makedirs(temp_dir) return temp_dir diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 99b855e6fc..4d6ef5e86e 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -856,7 +856,7 @@ def load_experiment(args): if nnictl_exp_config.get('logDir'): logDir = nnictl_exp_config['logDir'] else: - logDir = os.path.join(os.path.expanduser("~"), 'nni-experiments') + logDir = NNI_HOME_DIR os.rename(os.path.join(temp_root_dir, 'experiment'), os.path.join(temp_root_dir, experiment_id)) src_path = os.path.join(os.path.join(temp_root_dir, experiment_id)) dest_path = os.path.join(os.path.join(logDir, experiment_id)) From 07ab6087d3b4fe0f623b617167ba4f824b3d4804 Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Tue, 11 Aug 2020 18:08:30 +0800 Subject: [PATCH 11/12] fix comments --- tools/nni_cmd/common_utils.py | 1 - tools/nni_cmd/nnictl_utils.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/nni_cmd/common_utils.py b/tools/nni_cmd/common_utils.py index 52fcd04dad..2edbf667df 100644 --- a/tools/nni_cmd/common_utils.py +++ b/tools/nni_cmd/common_utils.py @@ -95,4 +95,3 @@ def generate_folder_name(): temp_dir = generate_folder_name() os.makedirs(temp_dir) return temp_dir - diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index 4d6ef5e86e..f0ac16fc03 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -801,7 +801,7 @@ def load_experiment(args): exit(1) temp_root_dir = generate_temp_dir() shutil.unpack_archive(package_path, temp_root_dir) - print_normal('Opening...') + print_normal('Loading...') # Step1. Validation if not os.path.exists(args.codeDir): print_error('Invalid: codeDir path does not exist!') From e9d0ebc89f0d3f722fccc32bd3bc243df2b3122c Mon Sep 17 00:00:00 2001 From: Shinai Yang Date: Tue, 11 Aug 2020 18:30:57 +0800 Subject: [PATCH 12/12] fix comments --- tools/nni_cmd/nnictl_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/nni_cmd/nnictl_utils.py b/tools/nni_cmd/nnictl_utils.py index f0ac16fc03..b411cfda77 100644 --- a/tools/nni_cmd/nnictl_utils.py +++ b/tools/nni_cmd/nnictl_utils.py @@ -894,7 +894,7 @@ def load_experiment(args): experiment_metadata.get('experimentName'), experiment_metadata.get('endTime'), experiment_metadata.get('status')) - print_normal('Open experiment %s succsss!' % experiment_id) + print_normal('Load experiment %s succsss!' % experiment_id) # Step6. Cleanup temp data shutil.rmtree(temp_root_dir)