| import hashlib |
| from datetime import datetime |
|
|
| import gradio as gr |
| import pandas as pd |
| import plotly.graph_objects as go |
| from datasets import load_dataset |
|
|
| DATASET_REPO_PATH = "uclanecl/NECL_GPUs" |
| USER_BLACKLIST = ["gdm", "necl", "ncel"] |
|
|
|
|
| def get_plot_df(df): |
| df = df.fillna({"fan_speed": "N/A"}) |
|
|
| df["users"] = df["users"].str.split(",") |
|
|
| |
| df["users"] = df["users"].apply( |
| lambda user_list: [u for u in user_list if u not in USER_BLACKLIST] or ["Free"] |
| ) |
|
|
| |
| new_df = [] |
| for _, row_series in df.iterrows(): |
| users_list = row_series["users"] |
| gpu_users_num = len(row_series["users"]) |
|
|
| for username in users_list: |
| new_row = row_series.copy() |
| new_row = new_row.drop(labels="users") |
|
|
| new_row["count"] = 1 / gpu_users_num |
| new_row["username"] = username |
|
|
| new_df.append(new_row) |
|
|
| df = pd.DataFrame(new_df) |
|
|
| return df |
|
|
|
|
| def username_to_hsl(username): |
| |
| if username == "Free": |
| return "hsl(0, 0%, 0%)" |
|
|
| |
| n = int.from_bytes(hashlib.sha1(username.encode()).digest(), "big") |
|
|
| |
| hue = (n + 15) % 360 |
|
|
| |
| saturation = 50 |
| lightness = 80 |
|
|
| |
| return f"hsl({hue}, {saturation}%, {lightness}%)" |
|
|
|
|
| def get_bar_chart(df): |
| |
| fig = go.Figure() |
|
|
| for _, row_series in df.iterrows(): |
| |
| |
| fig.add_bar( |
| x=[row_series["count"]], |
| y=[row_series["server"]], |
| orientation="h", |
| marker_color=username_to_hsl(row_series["username"]), |
| text=f"{row_series['index']}<br>{row_series['username']}", |
| textposition="inside", |
| insidetextanchor="middle", |
| hoverinfo="none", |
| ) |
|
|
| last_update_time = max(df["query_time"]) |
| last_update_time = datetime.fromisoformat(last_update_time).strftime("%Y-%m-%d %H:%M:%S") |
|
|
| max_index = df["index"].max() |
|
|
| fig.update_layout( |
| barmode="stack", |
| title=f"Last Modified {last_update_time}", |
| showlegend=False, |
| modebar_remove=["lasso2d", "select2d"], |
| height=500, |
| plot_bgcolor="#E4E4E6", |
| xaxis_fixedrange=True, |
| xaxis_range=[0, max_index + 1], |
| xaxis_showticklabels=False, |
| yaxis_fixedrange=True, |
| yaxis_categoryorder="category descending", |
| ) |
|
|
| return fig |
|
|
|
|
| def get_interface_elements(): |
| try: |
| df = load_dataset(DATASET_REPO_PATH)["train"].to_pandas() |
| df = get_plot_df(df) |
|
|
| plot = get_bar_chart(df) |
|
|
| |
| display_df_columns = [ |
| "server", |
| "index", |
| "username", |
| "device", |
| "memory", |
| "memory_usage", |
| "utilization", |
| "temperature", |
| "fan_speed", |
| "query_time", |
| ] |
| display_df = df[display_df_columns] |
|
|
| return plot, display_df |
|
|
| except Exception as e: |
| print(f"Global error in plot: {e}") |
| return None, pd.DataFrame() |
|
|
|
|
| demo = gr.Interface( |
| fn=get_interface_elements, |
| inputs=[], |
| outputs=[ |
| gr.Plot(label="GPU Status", elem_classes="gpu_status_plot"), |
| gr.Dataframe(label="GPU Status Details"), |
| ], |
| live=True, |
| css=".gpu_status_plot {max-width: 800px;}", |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch(debug=False) |
|
|