nvidia-smi 보다 더 자세한 정보를 알려주는 nvidia-htop + python script 확장자 없이 사용하기

2020. 3. 5. 20:50분석 Python/구현 및 자료

https://github.com/peci1/nvidia-htop

 

peci1/nvidia-htop

A tool for enriching the output of nvidia-smi. Contribute to peci1/nvidia-htop development by creating an account on GitHub.

github.com

nvidia-smi vs nvidia-htop

 


블로깅할 소스를 제공해준 JMS형에게 감사를 표합니다.


기존에 nvidia-smi가 왼쪽의 그림인데, 아쉽게도 cpu할당량과 memory 할당량 또는 유저 정보를 알 수가 없다. 
이러한 점을 개선한 것이 nvidia-htop이다. 중간 코드에 ps가 안먹는 것 같다고 하여 그걸 top을 이용하는 방식으로 수정을 했는데, 그럴 필요가 없어진 거라고 들었다. 아쉬우니 일단 공유

ps를 활용한 코드

## nvidia-htop.py
# Query the PIDs using ps
ps_format = "pid,user,%cpu,%mem,etime,command"
processes = subprocess.run(["ps", "-o", ps_format, "-p", ",".join(pid)], stdout=subprocess.PIPE)

# Parse ps output
for line in processes.stdout.decode().split("\n"):
    if line.strip().startswith("PID") or len(line) == 0:
        continue
    parts = re.split(r'\s+', line.strip(), 5)
    idx = pid.index(parts[0])
    user[idx] = parts[1]
    cpu[idx] = parts[2]
    mem[idx] = parts[3]
    time[idx] = parts[4] if not "-" in parts[4] else parts[4].split("-")[0] + " days"
    command[idx] = parts[5][0:100]

top을 활용한 코드

## nvidia-htop.py
def replaceRight(original, old, new, count_right):
    repeat=0
    text = original
    
    count_find = original.count(old)
    if count_right > count_find : # 바꿀 횟수가 문자열에 포함된 old보다 많다면
        repeat = count_find # 문자열에 포함된 old의 모든 개수(count_find)만큼 교체한다
    else :
        repeat = count_right # 아니라면 입력받은 개수(count)만큼 교체한다

    for _ in range(repeat):
        find_index = text.rfind(old) # 오른쪽부터 index를 찾기위해 rfind 사용
        text = text[:find_index] + new + text[find_index+1:]
    
    return text
    
commands = f'top  -b -n 2 -d 0.2 -p {",".join(pid)}'
cpuinfos = os.popen(commands).readlines()
#print(cpuinfos[-len(np.unique(pid)):])
for cpuinfo in cpuinfos[-len(np.unique(pid)):] :
    value = [i for i in cpuinfo.split(" ") if i != "" ]
    idx = pid.index(value[0])
    user[idx] = value[1]
    cpu[idx] = value[8]
    mem[idx] = value[9]
    time[idx] = value[10] if not "-" in value[10] else value[10].split("-")[0] + " days"
    command[idx] = replaceRight(value[11] , "\n","",1)

그래서 딱 여기까지만 하고 python script를 다음과 같이 실행시키면

python3 ./nvidia-htop.py

작동을 하게 된다. 하지만 이렇게 했을 때 문제점은

  1. 확장자(.py)도 적어줘야 함
  2. python3라고 적어줘야 함
  3. 해당 폴더 외에서는 작동하지 않음

아래의 글을 참고하여 문제점들을 해결하였다.

  1. 실행 권한을 부여
  2. 셔뱅을 추가
  3. bin에 넣기

1. 실행 권한 부여하기

chmod +x nvidia-htop.py

2. 셔뱅 추가

3. bin에 넣기

이제 이것을 할 때 /usr/local/bin이나 /usr/bin에 넣으면 바로 끝나게 되지만, 같은 명령어가 존재해 충돌의 위험성이 있고, 관리의 어려움이 있어서 새로운 bin 폴더를 만들어서 해결한다고 함.

필자는 그래서 해당 디렉토리에 바로 bin을 만들고 추가함.

mkdir ./bin
cp nvidia-htop ./bin
export PATH=$PATH":/home/~~~~/bin"

## /home/~~~/은 해당 폴더 경로를 적어주면 됨

이렇게만 하면 해당 세션에만 유효하므로, 터미널을 재시작하거나 로그인할 때마다 해줘야 한다고 한다.
그래서 이것을 방지하게 위해 적절한 위치에 추가시켜주면 된다고 하는데.
여기서 zsh를 사용한다면 ~/.zshrc 
bash를 사용하면다면, ~/. bashrc에 넣어주면 된다.

## zsh 사용하면 아래
echo 'export PATH=$PATH":/home/~~~/bin"' >> ~/.zshrc
## bash 사용하면 아래
echo 'export PATH=$PATH":/home/~~~/bin"' >> ~/.bashrc

아래 블로그에서는 딱 여기까지만 진행하였다.
필자도 여기까지만 하면 될 줄 알고 시도했지만, 다른 터미널에서는 먼가 안 되는 것 같았다. 
그래서 알고보니 파일의 내용이 반영되기 위해서는 명령어가 한 단계 더 있었다.

https://javafactory.tistory.com/640

 

그래서 다음과 같은 명령어를 추가적으로 실행하였다.

source ~/.bashrc

## or

source ~/.zshrc

 

필자는 .bashrc 에 넣어놓았다.
그리고 실행하니 잘 실행된 것을 확인했다!

nvidia-htop
watch -n 0.5 nvidia-htop

굳!!

 

 

https://winterj.me/python-make-command/

 

python script.py에서 벗어나기

engineering blog

winterj.me

 

728x90