GPU监控(三)对提取出的数据进行绘图

一、需求背景和目标

本文章记录需求实现第三部分:对提取出的数据进行绘图,更加直观的感受GPU使用变化情况

二、代码实现

在第二部分的基础上进行补充

import sys
import os
import argparse
import datetime as dt
from datetime import datetime

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
from matplotlib import rcParams

# 获取地址
proj_path = r'/home/gpu_usage_monitor'
sys.path.append(proj_path)

# 筛选log文件
def filter_logs(start_time,end_time):
    # 对传入的字符串转换为时间格式
    start_time = datetime.strptime(start_time,"%Y-%m-%d")
    end_time = datetime.strptime(end_time,"%Y-%m-%d")

    filtered_log = []
    log_floder = os.path.join(proj_path,'usage_log')
    #遍历访问usage_log文件夹,log文件均记录在该文件夹中
    for filename in os.listdir(log_floder):
        # 提取log文件命名中的日期,便于和传入的参数比较
        file_date_str = filename.split("_")[2].split(".")[0] #log文件命名为gpu_usage_yyyy_mm_dd.log
        file_datetime = datetime.strptime(file_date_str,"%Y-%m-%d")
        
        # 筛选符合用户输入的时间区间的log文件
        if start_time.date() <= file_datetime.date() <= end_time.date():
            with open(os.path.join(log_floder,filename),'r') as file:
                lines = file.readlines()
      
                # 若传入的参数格式为yyyy-mm-dd,用这个
                for i in lines[1:]:
                    filtered_log.append(i.strip())

               '''# 若传入的参数格式为yyyy-mm-dd H:M:S,用这个
               for i in lines[1:]:
                   columns = i.strip().split(',')
                   use_datetime = datetime.strptime(f"20{columns[0]} {columns[1]}","%Y-%m-%d %H:%M:%S")
                   if start_time <= use_datetime <= end_time:
                   filtered_log.append(i.strip())
               '''
   return filtered_log

def gpu_usage(start_time,end_time):
    # 获取log文件内容
    filtered_log = filter_logs(start_time,end_time)

    # 转化为DataFrame
    gpu_use_log = pd.DataFrame(columns=['use_datetime','gpu_index','gpu_uuid','gpu_name','gpu_util','mem_use_snap_mib','mem_mib_max'])
    for log in filtered_log:
        gpu_log = log.split(',')
        gpu_log_datetime = datetime.strptime(f"20{columns[0]} {columns[1]}","%Y-%m-%d %H:%M:%S"
        row = [gpu_log_datetime] + gpu_log[2:5] + [int(x) for x in gpu_log [5:]]
        gpu_use_log.loc[len(gpu_use_log)] = row
    
    # 多显卡系统,根据datetime分组,gpu_util取最大值,mem_mib_max、mem_use_snap_mib取sum值
    gpu_use_log_all = gpu_use_log.groupby('use_datetime').agg({'gpu_util':'max','mem_mib_max':'sum','mem_use_snap_mib':'sum'}).reset_index()
    
    plt.figure(figsize(20,8))
    # 绘制显存使用量折线图
    plt.plot(gpu_use_log_all["use_datetime"],gpu_use_log_all["mem_use_snap_mib"],label='显存使用情况')
    # 绘制GPU使用率散点图(util不为0则记录)
    gpu_util = gpu_use_log_all.loc[gpu_use_log_all["gpu_util"]!=0]
    plt.scatter(gpu_util["use_datetime"],gpu_util["mem_use_snap_mib"],label='GPU使用情况',color='red')
    
    # 设置中文字体
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.xlabel("时间")
    plt.ylabel("显存实时使用量")
    plt.title(f'{start_time}{end_time}GPU/显存实时使用量折线图')
    
    # 取消科学计数法
    ax = plt.gca()
    ax.ticklabel_format(style='plain',axis='y')
        
    # 调整横轴显示,显示20个标签(以时间为单位进行划分)
    date_format = "%Y-%m-%d %H:%M:%S"
    plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter(date_format))
    plt.gca().xaxis.set_major_locator(plt.matplotlib.dates.AutoDateLocator(maxticks=20))
    plt.gca().autofmt_xdate()
    
    # 设置y轴坐标最大值
    plt.ylim(0,gpu_use_log_all["mem_mib_max"].max())
    
    # 标注图中折线的最大值
    y_max = np.argmax(gpu_use_log_all["mem_use_snap_mib"]) # 最大值的索引
    show_max = gpu_use_log_all["mem_use_snap_mib"][y_max] #最大值
    plt.plot(gpu_use_log_all["use_datetime"][y_max],show_max,'o',c='blue',lable=f'显存最大值:{show_max }mib')
    plt.annotate(text=(f'(时间:{str(gpu_use_log_all["use_datetime"][y_max])} 显存使用最大值:{show_max }mib({gpu_use_log_all["mem_mib_max"].max()}mib))'),xy=(gpu_use_log_all["use_datetime"][y_max],show_max)),xytext=(gpu_use_log_all["use_datetime"][y_max],show_max))
    
    plt.legend()
    plt.tight_layout()
    plt.xyticks(rotation=20)

    # 输出折线图
    jpg_path = f'gpu_use_{start_time}_{end_time}'
    output_file_path = os.path.join(proj_path,'pic',jpg_path)
    plt.savefig(output_file_path )
    plt.show()

if __name__ =="__main__":
    today = dt.date.today()
    parser = argparse.ArgumentParser(description="filter logs by time range")
    # 如果不传参,默认参数为2023-08-18到当天
    parser.addargument("start_time",type=str,default='2023-08-18',required=False,help="start_time in the format 'yyyy-mm-dd'")
    parser.addargument("end_time",type=str,default=today,required=False,help="end_time in the format 'yyyy-mm-dd'")
    args = parser.parser_args()

    gpu_usage(args.start_time,args.end_time)

三、实现效果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值