Skip to content

Commit 7748a2d

Browse files
authored
Let nnictl support stopping by port (microsoft#1384)
* Support stopping by port * Doc for stopping by port
1 parent 9d47087 commit 7748a2d

5 files changed

Lines changed: 67 additions & 25 deletions

File tree

docs/en_US/Tutorial/Nnictl.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,16 @@ Debug mode will disable version check function in Trialkeeper.
114114
* Usage
115115

116116
```bash
117-
nnictl stop [id]
117+
nnictl stop [Options]
118118
```
119119

120+
* Options
121+
122+
|Name, shorthand|Required|Default|Description|
123+
|------|------|------ |------|
124+
|id| False| |The id of the experiment you want to stop|
125+
|--port, -p| False| |Rest port of the experiment you want to stop|
126+
120127
* Details & Examples
121128

122129
1. If there is no id specified, and there is an experiment running, stop the running experiment, or print error message.
@@ -131,15 +138,21 @@ Debug mode will disable version check function in Trialkeeper.
131138
nnictl stop [experiment_id]
132139
```
133140

134-
3. Users could use 'nnictl stop all' to stop all experiments.
141+
3. If there is a port specified, and an experiment is running on that port, the experiment will be stopped.
142+
143+
```bash
144+
nnictl stop --port 8080
145+
```
146+
147+
4. Users could use 'nnictl stop all' to stop all experiments.
135148

136149
```bash
137150
nnictl stop all
138151
```
139152

140-
4. If the id ends with *, nnictl will stop all experiments whose ids matchs the regular.
141-
5. If the id does not exist but match the prefix of an experiment id, nnictl will stop the matched experiment.
142-
6. If the id does not exist but match multiple prefix of the experiment ids, nnictl will give id information.
153+
5. If the id ends with *, nnictl will stop all experiments whose ids matchs the regular.
154+
6. If the id does not exist but match the prefix of an experiment id, nnictl will stop the matched experiment.
155+
7. If the id does not exist but match multiple prefix of the experiment ids, nnictl will give id information.
143156

144157
<a name="update"></a>
145158

@@ -704,4 +717,4 @@ Debug mode will disable version check function in Trialkeeper.
704717
```bash
705718
nnictl --version
706719
```
707-
720+

docs/zh_CN/Nnictl.md

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,18 @@ nnictl 支持的命令:
112112
使用此命令来停止正在运行的单个或多个 Experiment。
113113

114114
* 用法
115-
115+
116116
```bash
117-
nnictl stop [id]
117+
nnictl stop [OPTIONS]
118118
```
119119

120+
* 选项
121+
122+
| 参数及缩写 | 是否必需 | 默认值 | 说明 |
123+
| ----------- | ----- | --- | -------------------------------- |
124+
| id || | 要停止的 Experiment 标识 |
125+
| --port, -p || | 要停止的 Experiment 使用的 RESTful 服务端口 |
126+
120127
* 详细信息及样例
121128

122129
1. 如果没有指定 id,并且当前有运行的 Experiment,则会停止该 Experiment,否则会输出错误信息。
@@ -131,19 +138,24 @@ nnictl 支持的命令:
131138
```bash
132139
nnictl stop [experiment_id]
133140
```
134-
135-
136-
3. 可使用 'nnictl stop all' 来停止所有的 Experiment。
141+
142+
3. 如果指定了端口,并且有运行中的 Experiment 正在使用该端口,那么这个 Experiment 将会停止。
143+
144+
```bash
145+
nnictl stop --port 8080
146+
````
147+
148+
4. 可使用 'nnictl stop all' 来停止所有的 Experiment。
137149
138150
```bash
139151
nnictl stop all
140152
```
141153

142154

143-
4. 如果 id 以 * 结尾,nnictl 会停止所有匹配此通配符的 Experiment。
155+
5. 如果 id 以 * 结尾,nnictl 会停止所有匹配此通配符的 Experiment。
144156

145-
5. 如果 id 不存在,但匹配了某个Experiment 的 id 前缀,nnictl 会停止匹配的Experiment 。
146-
6. 如果 id 不存在,但匹配了多个 Experiment id 的前缀,nnictl 会输出这些 id 的信息。
157+
6. 如果 id 不存在,但匹配了某个Experiment 的 id 前缀,nnictl 会停止匹配的Experiment 。
158+
7. 如果 id 不存在,但匹配了多个 Experiment id 的前缀,nnictl 会输出这些 id 的信息。
147159

148160
<a name="update"></a>
149161

@@ -704,4 +716,4 @@ nnictl 支持的命令:
704716

705717
```bash
706718
nnictl --version
707-
```
719+
```

test/naive_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def stop_experiment_test():
8888
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8080'], check=True)
8989
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8888'], check=True)
9090
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8989'], check=True)
91+
subprocess.run(['nnictl', 'create', '--config', 'tuner_test/local.yml', '--port', '8990'], check=True)
9192

9293
# test cmd 'nnictl stop id`
9394
experiment_id = get_experiment_id(EXPERIMENT_URL)
@@ -96,6 +97,12 @@ def stop_experiment_test():
9697
snooze()
9798
assert not detect_port(8080), '`nnictl stop %s` failed to stop experiments' % experiment_id
9899

100+
# test cmd `nnictl stop --port`
101+
proc = subprocess.run(['nnictl', 'stop', '--port', '8990'])
102+
assert proc.returncode == 0, '`nnictl stop %s` failed with code %d' % (experiment_id, proc.returncode)
103+
snooze()
104+
assert not detect_port(8990), '`nnictl stop %s` failed to stop experiments' % experiment_id
105+
99106
# test cmd `nnictl stop all`
100107
proc = subprocess.run(['nnictl', 'stop', 'all'])
101108
assert proc.returncode == 0, '`nnictl stop all` failed with code %d' % proc.returncode

tools/nni_cmd/nnictl.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ def parse_args():
9090
#parse stop command
9191
parser_stop = subparsers.add_parser('stop', help='stop the experiment')
9292
parser_stop.add_argument('id', nargs='?', help='the id of experiment, use \'all\' to stop all running experiments')
93+
parser_stop.add_argument('--port', '-p', dest='port', help='the port of restful server')
9394
parser_stop.set_defaults(func=stop_experiment)
9495

9596
#parse trial command

tools/nni_cmd/nnictl_utils.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,14 @@ def check_experiment_id(args, update=True):
118118

119119
def parse_ids(args):
120120
'''Parse the arguments for nnictl stop
121-
1.If there is an id specified, return the corresponding id
122-
2.If there is no id specified, and there is an experiment running, return the id, or return Error
123-
3.If the id matches an experiment, nnictl will return the id.
124-
4.If the id ends with *, nnictl will match all ids matchs the regular
125-
5.If the id does not exist but match the prefix of an experiment id, nnictl will return the matched id
126-
6.If the id does not exist but match multiple prefix of the experiment ids, nnictl will give id information
121+
1.If port is provided and id is not specified, return the id who owns the port
122+
2.If both port and id are provided, return the id if it owns the port, otherwise fail
123+
3.If there is an id specified, return the corresponding id
124+
4.If there is no id specified, and there is an experiment running, return the id, or return Error
125+
5.If the id matches an experiment, nnictl will return the id.
126+
6.If the id ends with *, nnictl will match all ids matchs the regular
127+
7.If the id does not exist but match the prefix of an experiment id, nnictl will return the matched id
128+
8.If the id does not exist but match multiple prefix of the experiment ids, nnictl will give id information
127129
'''
128130
update_experiment()
129131
experiment_config = Experiments()
@@ -140,7 +142,14 @@ def parse_ids(args):
140142
elif isinstance(experiment_dict[key], list):
141143
# if the config file is old version, remove the configuration from file
142144
experiment_config.remove_experiment(key)
143-
if not args.id:
145+
if args.port is not None:
146+
for key in running_experiment_list:
147+
if str(experiment_dict[key]['port']) == args.port:
148+
result_list.append(key)
149+
if args.id and result_list and args.id != result_list[0]:
150+
print_error('Experiment id and resful server port not match')
151+
exit(1)
152+
elif not args.id:
144153
if len(running_experiment_list) > 1:
145154
print_error('There are multiple experiments, please set the experiment id...')
146155
experiment_information = ""
@@ -166,8 +175,8 @@ def parse_ids(args):
166175
if len(result_list) > 1:
167176
print_error(args.id + ' is ambiguous, please choose ' + ' '.join(result_list) )
168177
return None
169-
if not result_list and args.id and args.id != 'all':
170-
print_error('There are no experiments matched, please set correct experiment id...')
178+
if not result_list and ((args.id and args.id != 'all') or args.port):
179+
print_error('There are no experiments matched, please set correct experiment id or restful server port')
171180
elif not result_list:
172181
print_error('There is no experiment running...')
173182
return result_list
@@ -665,4 +674,4 @@ def export_trials_data(args):
665674
else:
666675
print_error('Export failed...')
667676
else:
668-
print_error('Restful server is not Running')
677+
print_error('Restful server is not Running')

0 commit comments

Comments
 (0)