addftool 0.1.2__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- addftool/addf_portal.py +23 -0
- addftool/process/__init__.py +87 -0
- addftool/process/utils.py +70 -0
- {addftool-0.1.2.dist-info → addftool-0.1.3.dist-info}/METADATA +2 -1
- addftool-0.1.3.dist-info/RECORD +12 -0
- {addftool-0.1.2.dist-info → addftool-0.1.3.dist-info}/entry_points.txt +1 -0
- addftool-0.1.2.dist-info/RECORD +0 -9
- {addftool-0.1.2.dist-info → addftool-0.1.3.dist-info}/WHEEL +0 -0
- {addftool-0.1.2.dist-info → addftool-0.1.3.dist-info}/top_level.txt +0 -0
addftool/addf_portal.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from addftool.process import add_killer_args, killer_main
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def get_args():
|
|
6
|
+
parser = argparse.ArgumentParser(description="Addf's tool")
|
|
7
|
+
|
|
8
|
+
subparsers = parser.add_subparsers(dest='command', help='Sub-command help')
|
|
9
|
+
add_killer_args(subparsers)
|
|
10
|
+
|
|
11
|
+
return parser.parse_args()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main():
|
|
15
|
+
args = get_args()
|
|
16
|
+
if args.command == "kill":
|
|
17
|
+
killer_main(args)
|
|
18
|
+
else:
|
|
19
|
+
print("Unknown command: ", args.command)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
main()
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import psutil
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from .utils import get_processes, get_process_using_rocm, get_process_using_cuda
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def add_killer_args(subparsers):
|
|
8
|
+
process_killer_parser = subparsers.add_parser('kill', help='process kill')
|
|
9
|
+
|
|
10
|
+
process_killer_parser.add_argument("--prefix", help="prefix of command", default=None)
|
|
11
|
+
process_killer_parser.add_argument("--contains", help="contains of command", default=None)
|
|
12
|
+
process_killer_parser.add_argument("--timeout", help="timeout of command", default=5, type=int)
|
|
13
|
+
process_killer_parser.add_argument("--try_count", help="try count of command", default=3, type=int)
|
|
14
|
+
|
|
15
|
+
process_killer_parser.add_argument("--rocm", help="kill process using rocm", action='store_true', default=False)
|
|
16
|
+
process_killer_parser.add_argument("--cuda", help="kill process using cuda", action='store_true', default=False)
|
|
17
|
+
|
|
18
|
+
process_killer_parser.add_argument("-v", "--view", help="view process", action='store_true', default=False)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def kill_process(processes, timeout=5, try_count=3):
|
|
22
|
+
for process in processes:
|
|
23
|
+
try:
|
|
24
|
+
proc = psutil.Process(process['pid'])
|
|
25
|
+
print(f"Killing process {proc.pid} - {proc.cmdline()}")
|
|
26
|
+
proc.terminate()
|
|
27
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
28
|
+
print(f"Process {process['pid']} not found or access denied")
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
time.sleep(timeout)
|
|
32
|
+
for _ in range(try_count):
|
|
33
|
+
all_terminated = True
|
|
34
|
+
for process in processes:
|
|
35
|
+
try:
|
|
36
|
+
proc = psutil.Process(process['pid'])
|
|
37
|
+
print("Process still running: ", proc.pid)
|
|
38
|
+
proc.kill()
|
|
39
|
+
all_terminated = False
|
|
40
|
+
except (psutil.NoSuchProcess):
|
|
41
|
+
continue
|
|
42
|
+
except (psutil.AccessDenied):
|
|
43
|
+
print(f"Process {process['pid']} access denied")
|
|
44
|
+
continue
|
|
45
|
+
except (psutil.ZombieProcess):
|
|
46
|
+
print(f"Process {process['pid']} is a zombie process")
|
|
47
|
+
continue
|
|
48
|
+
except Exception as e:
|
|
49
|
+
print(f"Error killing process {process['pid']}: {e}")
|
|
50
|
+
continue
|
|
51
|
+
if all_terminated:
|
|
52
|
+
print("All processes terminated")
|
|
53
|
+
break
|
|
54
|
+
|
|
55
|
+
if not all_terminated:
|
|
56
|
+
print("Some processes are still running. Please check manually.")
|
|
57
|
+
exit(1)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def find_and_kill_process(prefix=None, contains=None, use_rocm=False, use_cuda=False, timeout=5, try_count=3, only_view=False):
|
|
61
|
+
do_not_do_anything = prefix is None and contains is None
|
|
62
|
+
if use_rocm:
|
|
63
|
+
processes = get_process_using_rocm()
|
|
64
|
+
elif use_cuda:
|
|
65
|
+
processes = get_process_using_cuda()
|
|
66
|
+
elif do_not_do_anything and not only_view:
|
|
67
|
+
print("Use top or htop to find the process you want to kill")
|
|
68
|
+
return
|
|
69
|
+
else:
|
|
70
|
+
processes = get_processes(command_prefix=prefix, prefix_contains=contains)
|
|
71
|
+
|
|
72
|
+
if only_view:
|
|
73
|
+
print(f"Found {len(processes)} processes")
|
|
74
|
+
for process in processes:
|
|
75
|
+
print(f"PID: {process['pid']}, Command: {' '.join(process['command'])}")
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
if len(processes) > 0:
|
|
79
|
+
print(f"Found {len(processes)} processes to kill")
|
|
80
|
+
kill_process(processes, timeout, try_count)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def killer_main(args):
|
|
84
|
+
find_and_kill_process(
|
|
85
|
+
args.prefix, args.contains, use_rocm=args.rocm, use_cuda=args.cuda,
|
|
86
|
+
timeout=args.timeout, try_count=args.try_count, only_view=args.view,
|
|
87
|
+
)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import psutil
|
|
2
|
+
import subprocess
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def get_processes(command_prefix=None, prefix_contains=None, pids=None):
|
|
6
|
+
"""获取进程的PID和命令"""
|
|
7
|
+
|
|
8
|
+
processes = []
|
|
9
|
+
for proc in psutil.process_iter(['pid', 'cmdline']):
|
|
10
|
+
try:
|
|
11
|
+
pid = proc.info['pid']
|
|
12
|
+
cmdline = proc.info['cmdline']
|
|
13
|
+
if cmdline is None or len(cmdline) == 0:
|
|
14
|
+
continue
|
|
15
|
+
if pids is not None and pid not in pids:
|
|
16
|
+
continue
|
|
17
|
+
if command_prefix and not cmdline[0] == command_prefix:
|
|
18
|
+
continue
|
|
19
|
+
if prefix_contains and prefix_contains not in cmdline[0]:
|
|
20
|
+
continue
|
|
21
|
+
if len(cmdline) > 1 and cmdline[1].endswith('addf'):
|
|
22
|
+
continue
|
|
23
|
+
processes.append({'pid': pid, 'command': cmdline})
|
|
24
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
return processes
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_process_using_rocm():
|
|
31
|
+
result = subprocess.run(['rocm-smi', '--showpidgpus'], capture_output=True, text=True)
|
|
32
|
+
if result.returncode != 0:
|
|
33
|
+
return False
|
|
34
|
+
|
|
35
|
+
gpu_pids = []
|
|
36
|
+
output_lines = result.stdout.strip().split('\n')
|
|
37
|
+
for line in output_lines:
|
|
38
|
+
if "PID" in line and ":" in line:
|
|
39
|
+
# Extract PID from lines like "GPU[0-7]: PID: 12345"
|
|
40
|
+
try:
|
|
41
|
+
pid_part = line.split("PID:")[1].strip()
|
|
42
|
+
pid = int(pid_part.split()[0])
|
|
43
|
+
gpu_pids.append(pid)
|
|
44
|
+
except (IndexError, ValueError):
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
# Remove duplicates
|
|
48
|
+
gpu_pids = list(set(gpu_pids))
|
|
49
|
+
return get_processes(pids=gpu_pids)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_process_using_cuda():
|
|
53
|
+
result = subprocess.run(['nvidia-smi', '--query-compute-apps=pid', '--format=csv,noheader'], capture_output=True, text=True)
|
|
54
|
+
if result.returncode != 0:
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
gpu_pids = []
|
|
58
|
+
output_lines = result.stdout.strip().split('\n')
|
|
59
|
+
for line in output_lines:
|
|
60
|
+
try:
|
|
61
|
+
pid = int(line.strip())
|
|
62
|
+
gpu_pids.append(pid)
|
|
63
|
+
except ValueError:
|
|
64
|
+
continue
|
|
65
|
+
|
|
66
|
+
# Remove duplicates
|
|
67
|
+
gpu_pids = list(set(gpu_pids))
|
|
68
|
+
|
|
69
|
+
# get process id and cmdline
|
|
70
|
+
return get_processes(pids=gpu_pids)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
addftool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
addftool/addf_portal.py,sha256=U52TdNcwWOEvv_C5r-guWYxn3ntzwYI2eBzJIE7IdcY,493
|
|
3
|
+
addftool/blob.py,sha256=NZOItDyFUIdV1tfhJZJJBEzGy296CE5NCictTzP4OPc,8282
|
|
4
|
+
addftool/tool.py,sha256=EuKQ2t2InN7yB-_oYLcdsA7vRqzRGTunwIxplUSqEG0,2054
|
|
5
|
+
addftool/util.py,sha256=Q3A68vJDxgfeNiEFmk54HuMuworVndocXpSbVpvGMfc,362
|
|
6
|
+
addftool/process/__init__.py,sha256=EFJ90RcF04M4imGm5NLgb9rmpwxBslZUL_4LKA52uv8,3487
|
|
7
|
+
addftool/process/utils.py,sha256=kS1bYYiWymB1_SObqQLfGiVbZdCJqd57SO6DrwN5H1s,2246
|
|
8
|
+
addftool-0.1.3.dist-info/METADATA,sha256=YwSmBYP8v9T_PnVr-3WM-V2KkCcPg17IwMKllfp-pc0,148
|
|
9
|
+
addftool-0.1.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
10
|
+
addftool-0.1.3.dist-info/entry_points.txt,sha256=9lkmuWMInwUAtev8w8poNkNd7iML9Bjd5CBCFVxg2b8,111
|
|
11
|
+
addftool-0.1.3.dist-info/top_level.txt,sha256=jqj56-plrBbyzY0tIxB6wPzjAA8kte4hUlajyyQygN4,9
|
|
12
|
+
addftool-0.1.3.dist-info/RECORD,,
|
addftool-0.1.2.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
addftool/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
addftool/blob.py,sha256=NZOItDyFUIdV1tfhJZJJBEzGy296CE5NCictTzP4OPc,8282
|
|
3
|
-
addftool/tool.py,sha256=EuKQ2t2InN7yB-_oYLcdsA7vRqzRGTunwIxplUSqEG0,2054
|
|
4
|
-
addftool/util.py,sha256=Q3A68vJDxgfeNiEFmk54HuMuworVndocXpSbVpvGMfc,362
|
|
5
|
-
addftool-0.1.2.dist-info/METADATA,sha256=gmakYu_DywA1K1z3yEoLN0h43nBUFbtNy0JmKcEbTgw,126
|
|
6
|
-
addftool-0.1.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
7
|
-
addftool-0.1.2.dist-info/entry_points.txt,sha256=h5TlQy4AQw-J55HqI7FRkIVRUfw-x3pStFWCoYtoCTM,78
|
|
8
|
-
addftool-0.1.2.dist-info/top_level.txt,sha256=jqj56-plrBbyzY0tIxB6wPzjAA8kte4hUlajyyQygN4,9
|
|
9
|
-
addftool-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|