File size: 18,636 Bytes
b84549f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
import argparse
import logging
import os
import pkg_resources
from colorama import init
from .common_utils import print_error
from .launcher import create_experiment, resume_experiment, view_experiment
from .updater import update_searchspace, update_concurrency, update_duration, update_trialnum, import_data
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, \
save_experiment, load_experiment
from .algo_management import algo_reg, algo_unreg, algo_show, algo_list
from .constants import DEFAULT_REST_PORT
from .import ts_management
init(autoreset=True)
if os.environ.get('COVERAGE_PROCESS_START'):
import coverage
coverage.process_startup()
def nni_info(*args):
if args[0].version:
try:
print(pkg_resources.get_distribution('nni').version)
except pkg_resources.ResolutionError:
print_error('Get version failed, please use `pip3 list | grep nni` to check nni version!')
else:
print('please run "nnictl {positional argument} --help" to see nnictl guidance')
def parse_args():
logging.getLogger().setLevel(logging.ERROR)
'''Definite the arguments users need to follow and input'''
parser = argparse.ArgumentParser(prog='nnictl', description='use nnictl command to control nni experiments')
parser.add_argument('--version', '-v', action='store_true')
parser.set_defaults(func=nni_info)
# create subparsers for args with sub values
subparsers = parser.add_subparsers()
# parse the command of auto generating search space
parser_start = subparsers.add_parser('ss_gen', help='automatically generate search space file from trial code')
parser_start.add_argument('--trial_command', '-t', required=True, dest='trial_command', help='the command for running trial code')
parser_start.add_argument('--trial_dir', '-d', default='./', dest='trial_dir', help='the directory for running the command')
parser_start.add_argument('--file', '-f', default='nni_auto_gen_search_space.json', dest='file', help='the path of search space file')
parser_start.set_defaults(func=search_space_auto_gen)
# parse start command
parser_start = subparsers.add_parser('create', help='create a new experiment')
parser_start.add_argument('--config', '-c', required=True, dest='config', help='the path of yaml config file')
parser_start.add_argument('--port', '-p', default=DEFAULT_REST_PORT, dest='port', type=int, help='the port of restful server')
parser_start.add_argument('--debug', '-d', action='store_true', help=' set debug mode')
parser_start.add_argument('--url_prefix', '-u', dest='url_prefix', help=' set prefix url')
parser_start.add_argument('--foreground', '-f', action='store_true', help=' set foreground mode, print log content to terminal')
parser_start.set_defaults(func=create_experiment)
# parse resume command
parser_resume = subparsers.add_parser('resume', help='resume a new experiment')
parser_resume.add_argument('id', nargs='?', help='The id of the experiment you want to resume')
parser_resume.add_argument('--port', '-p', default=DEFAULT_REST_PORT, dest='port', type=int, help='the port of restful server')
parser_resume.add_argument('--debug', '-d', action='store_true', help=' set debug mode')
parser_resume.add_argument('--foreground', '-f', action='store_true', help=' set foreground mode, print log content to terminal')
parser_resume.set_defaults(func=resume_experiment)
# parse view command
parser_view = subparsers.add_parser('view', help='view a stopped experiment')
parser_view.add_argument('id', nargs='?', help='The id of the experiment you want to view')
parser_view.add_argument('--port', '-p', default=DEFAULT_REST_PORT, dest='port', type=int, help='the port of restful server')
parser_view.set_defaults(func=view_experiment)
# parse update command
parser_updater = subparsers.add_parser('update', help='update the experiment')
#add subparsers for parser_updater
parser_updater_subparsers = parser_updater.add_subparsers()
parser_updater_searchspace = parser_updater_subparsers.add_parser('searchspace', help='update searchspace')
parser_updater_searchspace.add_argument('id', nargs='?', help='the id of experiment')
parser_updater_searchspace.add_argument('--filename', '-f', required=True)
parser_updater_searchspace.set_defaults(func=update_searchspace)
parser_updater_concurrency = parser_updater_subparsers.add_parser('concurrency', help='update concurrency')
parser_updater_concurrency.add_argument('id', nargs='?', help='the id of experiment')
parser_updater_concurrency.add_argument('--value', '-v', required=True)
parser_updater_concurrency.set_defaults(func=update_concurrency)
parser_updater_duration = parser_updater_subparsers.add_parser('duration', help='update duration')
parser_updater_duration.add_argument('id', nargs='?', help='the id of experiment')
parser_updater_duration.add_argument('--value', '-v', required=True, help='the unit of time should in {\'s\', \'m\', \'h\', \'d\'}')
parser_updater_duration.set_defaults(func=update_duration)
parser_updater_trialnum = parser_updater_subparsers.add_parser('trialnum', help='update maxtrialnum')
parser_updater_trialnum.add_argument('id', nargs='?', help='the id of experiment')
parser_updater_trialnum.add_argument('--value', '-v', required=True)
parser_updater_trialnum.set_defaults(func=update_trialnum)
#parse stop command
parser_stop = subparsers.add_parser('stop', help='stop the experiment')
parser_stop.add_argument('id', nargs='?', help='the id of experiment, use \'all\' to stop all running experiments')
parser_stop.add_argument('--port', '-p', dest='port', type=int, help='the port of restful server')
parser_stop.add_argument('--all', '-a', action='store_true', help='stop all of experiments')
parser_stop.set_defaults(func=stop_experiment)
#parse trial command
parser_trial = subparsers.add_parser('trial', help='get trial information')
#add subparsers for parser_trial
parser_trial_subparsers = parser_trial.add_subparsers()
parser_trial_ls = parser_trial_subparsers.add_parser('ls', help='list trial jobs')
parser_trial_ls.add_argument('id', nargs='?', help='the id of experiment')
parser_trial_ls.add_argument('--head', type=int, help='list the highest experiments on the default metric')
parser_trial_ls.add_argument('--tail', type=int, help='list the lowest experiments on the default metric')
parser_trial_ls.set_defaults(func=trial_ls)
parser_trial_kill = parser_trial_subparsers.add_parser('kill', help='kill trial jobs')
parser_trial_kill.add_argument('id', nargs='?', help='the id of experiment')
parser_trial_kill.add_argument('--trial_id', '-T', required=True, dest='trial_id', help='the id of trial to be killed')
parser_trial_kill.set_defaults(func=trial_kill)
parser_trial_codegen = parser_trial_subparsers.add_parser('codegen', help='generate trial code for a specific trial')
parser_trial_codegen.add_argument('id', nargs='?', help='the id of experiment')
parser_trial_codegen.add_argument('--trial_id', '-T', required=True, dest='trial_id', help='the id of trial to do code generation')
parser_trial_codegen.set_defaults(func=trial_codegen)
#parse experiment command
parser_experiment = subparsers.add_parser('experiment', help='get experiment information')
#add subparsers for parser_experiment
parser_experiment_subparsers = parser_experiment.add_subparsers()
parser_experiment_show = parser_experiment_subparsers.add_parser('show', help='show the information of experiment')
parser_experiment_show.add_argument('id', nargs='?', help='the id of experiment')
parser_experiment_show.set_defaults(func=list_experiment)
parser_experiment_status = parser_experiment_subparsers.add_parser('status', help='show the status of experiment')
parser_experiment_status.add_argument('id', nargs='?', help='the id of experiment')
parser_experiment_status.set_defaults(func=experiment_status)
parser_experiment_list = parser_experiment_subparsers.add_parser('list', help='list all of running experiment ids')
parser_experiment_list.add_argument('--all', action='store_true', default=False, help='list all of experiments')
parser_experiment_list.set_defaults(func=experiment_list)
parser_experiment_clean = parser_experiment_subparsers.add_parser('delete', help='clean up the experiment data')
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)
#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')
parser_import_data.add_argument('--filename', '-f', required=True)
parser_import_data.set_defaults(func=import_data)
#export trial data
parser_trial_export = parser_experiment_subparsers.add_parser('export', help='export trial job results to csv or json')
parser_trial_export.add_argument('id', nargs='?', help='the id of experiment')
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.add_argument('--intermediate', '-i', action='store_true',
default=False, help='are intermediate results included')
parser_trial_export.set_defaults(func=export_trials_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_experiment.add_argument('--saveCodeDir', '-s', action='store_true', default=False, help='save codeDir data \
of the 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.add_argument('--searchSpacePath', '-s', required=False, help='the path of search space file for \
loaded experiment, this path contains file name. Default in $codeDir/search_space.json')
parser_load_experiment.set_defaults(func=load_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
parser_webui = subparsers.add_parser('webui', help='get web ui information')
#add subparsers for parser_board
parser_webui_subparsers = parser_webui.add_subparsers()
parser_webui_url = parser_webui_subparsers.add_parser('url', help='show the url of web ui')
parser_webui_url.add_argument('id', nargs='?', help='the id of experiment')
parser_webui_url.set_defaults(func=webui_url)
parser_webui_nas = parser_webui_subparsers.add_parser('nas', help='show nas ui')
parser_webui_nas.add_argument('--port', default=6060, type=int, help='port of nas ui')
parser_webui_nas.add_argument('--logdir', default='.', type=str, help='the logdir where nas ui will read data')
parser_webui_nas.set_defaults(func=webui_nas)
#parse config command
parser_config = subparsers.add_parser('config', help='get config information')
parser_config_subparsers = parser_config.add_subparsers()
parser_config_show = parser_config_subparsers.add_parser('show', help='show the information of config')
parser_config_show.add_argument('id', nargs='?', help='the id of experiment')
parser_config_show.set_defaults(func=get_config)
#parse log command
parser_log = subparsers.add_parser('log', help='get log information')
# add subparsers for parser_log
parser_log_subparsers = parser_log.add_subparsers()
parser_log_stdout = parser_log_subparsers.add_parser('stdout', help='get stdout information')
parser_log_stdout.add_argument('id', nargs='?', help='the id of experiment')
parser_log_stdout.add_argument('--tail', '-T', dest='tail', type=int, help='get tail -100 content of stdout')
parser_log_stdout.add_argument('--head', '-H', dest='head', type=int, help='get head -100 content of stdout')
parser_log_stdout.add_argument('--path', action='store_true', default=False, help='get the path of stdout file')
parser_log_stdout.set_defaults(func=log_stdout)
parser_log_stderr = parser_log_subparsers.add_parser('stderr', help='get stderr information')
parser_log_stderr.add_argument('id', nargs='?', help='the id of experiment')
parser_log_stderr.add_argument('--tail', '-T', dest='tail', type=int, help='get tail -100 content of stderr')
parser_log_stderr.add_argument('--head', '-H', dest='head', type=int, help='get head -100 content of stderr')
parser_log_stderr.add_argument('--path', action='store_true', default=False, help='get the path of stderr file')
parser_log_stderr.set_defaults(func=log_stderr)
parser_log_trial = parser_log_subparsers.add_parser('trial', help='get trial log path')
parser_log_trial.add_argument('id', nargs='?', help='the id of experiment')
parser_log_trial.add_argument('--trial_id', '-T', dest='trial_id', help='find trial log path by id')
parser_log_trial.set_defaults(func=log_trial)
#parse algo command
parser_algo = subparsers.add_parser('algo', help='control nni builtin tuner, assessor and advisor algorithms')
# add subparsers for parser_algo
parser_algo_subparsers = parser_algo.add_subparsers()
parser_algo_reg = parser_algo_subparsers.add_parser(
'register',
aliases=('reg',),
help='''register algorithms as nni builtin algorithm, for example:
nnictl reg --meta_path <path_to_meta_file>
where <path_to_meta_file> is the path to a meta data in yml format,
reference the nni document and examples/tuners/customized_tuner example
for the format of the yml file.'''
)
parser_algo_reg.add_argument('--meta_path', '-m', dest='meta_path', help='path to the meta file', required=True)
parser_algo_reg.set_defaults(func=algo_reg)
parser_algo_unreg = parser_algo_subparsers.add_parser('unregister', aliases=('unreg',), help='unregister algorithm')
parser_algo_unreg.add_argument('name', nargs=1, help='builtin name of the algorithm')
parser_algo_unreg.set_defaults(func=algo_unreg)
parser_algo_show = parser_algo_subparsers.add_parser('show', help='show the information of algorithm')
parser_algo_show.add_argument('name', nargs=1, help='builtin name of the algorithm')
parser_algo_show.set_defaults(func=algo_show)
parser_algo_list = parser_algo_subparsers.add_parser('list', help='list registered algorithms')
parser_algo_list.set_defaults(func=algo_list)
#parse trainingservice command
parser_ts = subparsers.add_parser('trainingservice', help='control training service')
# add subparsers for parser_ts
parser_ts_subparsers = parser_ts.add_subparsers()
parser_ts_reg = parser_ts_subparsers.add_parser('register', help='register training service')
parser_ts_reg.add_argument('--package', dest='package', help='package name', required=True)
parser_ts_reg.set_defaults(func=ts_management.register)
parser_ts_unreg = parser_ts_subparsers.add_parser('unregister', help='unregister training service')
parser_ts_unreg.add_argument('--package', dest='package', help='package name', required=True)
parser_ts_unreg.set_defaults(func=ts_management.unregister)
parser_ts_list = parser_ts_subparsers.add_parser('list', help='list custom training services')
parser_ts_list.set_defaults(func=ts_management.list_services)
# To show message that nnictl package command is replaced by nnictl algo, to be remove in the future release.
def show_messsage_for_nnictl_package(args):
print_error('nnictl package command is replaced by nnictl algo, please run nnictl algo -h to show the usage')
parser_package_subparsers = subparsers.add_parser('package', help='this argument is replaced by algo', prefix_chars='\n')
parser_package_subparsers.add_argument('args', nargs=argparse.REMAINDER)
parser_package_subparsers.set_defaults(func=show_messsage_for_nnictl_package)
#parse top command
parser_top = subparsers.add_parser('top', help='monitor the experiment')
parser_top.add_argument('--time', '-t', dest='time', type=int, default=3, help='the time interval to update the experiment status, ' \
'the unit is second')
parser_top.set_defaults(func=monitor_experiment)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
parse_args()
|