File size: 3,818 Bytes
a924f72
b282e84
 
0a0138f
 
a924f72
5a4f1e9
0a0138f
066258d
5ff0236
0a0138f
b282e84
1410ba5
524b2aa
6128e62
1410ba5
 
524b2aa
d287b8c
b9daae4
0a0138f
1410ba5
6128e62
0a0138f
906c39f
 
 
1410ba5
 
906c39f
c20fa2e
1410ba5
0a0138f
 
1410ba5
0a0138f
1410ba5
0a0138f
f448904
0a0138f
 
b282e84
a924f72
 
 
 
 
 
 
 
cecfd3a
 
a924f72
 
 
 
 
 
 
 
 
6128e62
 
 
 
 
cecfd3a
 
6128e62
 
 
 
 
 
341020d
6128e62
 
 
 
3ddcf7d
 
 
e450cd0
3ddcf7d
6128e62
 
4911f37
6128e62
3ddcf7d
2953ef2
7754c8c
3ddcf7d
e450cd0
6128e62
3ddcf7d
6128e62
 
 
 
 
 
 
0a0138f
066258d
1410ba5
6794a6c
6128e62
b282e84
74cf7b8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a0138f
 
96af258
0a0138f
 
b282e84
0a0138f
6128e62
b282e84
 
5a4f1e9
b282e84
0a0138f
 
ee046f0
0a0138f
 
 
b282e84
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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(",")

    # Filter out blacklisted users
    df["users"] = df["users"].apply(
        lambda user_list: [u for u in user_list if u not in USER_BLACKLIST] or ["Free"]
    )

    # Construct a new DataFrame for the bar chart
    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):
    # Black indicates a free GPU
    if username == "Free":
        return "hsl(0, 0%, 0%)"

    # Deterministic hash → integer
    n = int.from_bytes(hashlib.sha1(username.encode()).digest(), "big")

    # Map to hue [0, 360). The 15 offset is to customize the color for a "specific user.""
    hue = (n + 15) % 360

    # Fixed saturation and lightness
    saturation = 50  # percent
    lightness = 80  # percent

    # Return as HSL CSS-style string
    return f"hsl({hue}, {saturation}%, {lightness}%)"


def get_bar_chart(df):
    # Create the bar chart
    fig = go.Figure()

    for _, row_series in df.iterrows():
        # Using the low-level interface because the high-level interface only allows contiguous
        # colored blocks in one bar
        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)

        # Reorganize DataFrame that will be displayed
        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)