Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -227,12 +227,114 @@ def plot_disks(alert_threshold_pct=99.0):
|
|
| 227 |
return fig, df
|
| 228 |
|
| 229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
|
| 231 |
##### PLOT ALL #####
|
| 232 |
def plot_figs():
|
| 233 |
-
fig_gpus, df_gpus =
|
| 234 |
-
|
| 235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
|
| 237 |
demo = gr.Interface(
|
| 238 |
fn=plot_figs,
|
|
@@ -242,8 +344,10 @@ demo = gr.Interface(
|
|
| 242 |
outputs = [
|
| 243 |
gr.Plot(label="GPU Status", elem_classes="plotcss"),
|
| 244 |
gr.Plot(label="Disk Status", elem_classes="plotcss"),
|
|
|
|
| 245 |
gr.Dataframe(label="GPU Status Details"),
|
| 246 |
gr.Dataframe(label="Disk Status Details"),
|
|
|
|
| 247 |
],
|
| 248 |
live=True,
|
| 249 |
flagging_options=[],
|
|
@@ -252,4 +356,4 @@ demo = gr.Interface(
|
|
| 252 |
)
|
| 253 |
|
| 254 |
if __name__ == "__main__":
|
| 255 |
-
demo.launch(debug=False)
|
|
|
|
| 227 |
return fig, df
|
| 228 |
|
| 229 |
|
| 230 |
+
def plot_users_disks(topk_to_show=5):
|
| 231 |
+
df = datasets.load_dataset(
|
| 232 |
+
"pluslab/PLUS_Lab_GPUs_Data",
|
| 233 |
+
data_files="users_disks.csv",
|
| 234 |
+
download_mode="force_redownload",
|
| 235 |
+
)["train"].to_pandas()
|
| 236 |
+
|
| 237 |
+
df["server_path"] = df["server"] + "/" + df["path"]
|
| 238 |
+
df["server_path"] = df["server_path"].apply(
|
| 239 |
+
lambda x: x.replace(".cs.ucla.edu", "")
|
| 240 |
+
)
|
| 241 |
+
df = df[df["path"] != "home"]
|
| 242 |
+
|
| 243 |
+
# Ensure numeric
|
| 244 |
+
df["size_GB"] = pd.to_numeric(df["size_GB"], errors="coerce").fillna(0)
|
| 245 |
+
|
| 246 |
+
# Preserve original appearance order
|
| 247 |
+
original_order = df["server_path"].drop_duplicates()
|
| 248 |
+
|
| 249 |
+
heatmap_df = df.pivot_table(
|
| 250 |
+
index="server_path",
|
| 251 |
+
columns="username",
|
| 252 |
+
values="size_GB",
|
| 253 |
+
aggfunc="sum",
|
| 254 |
+
fill_value=0,
|
| 255 |
+
)
|
| 256 |
+
|
| 257 |
+
# Reindex to preserve original order first
|
| 258 |
+
heatmap_df = heatmap_df.reindex(original_order)
|
| 259 |
+
|
| 260 |
+
# ----------- Custom ordering logic -----------
|
| 261 |
+
local1_rows = [p for p in heatmap_df.index if "/local1" in p]
|
| 262 |
+
home_rows = [p for p in heatmap_df.index if "/home" in p]
|
| 263 |
+
other_rows = [
|
| 264 |
+
p for p in heatmap_df.index
|
| 265 |
+
if p not in local1_rows and p not in home_rows
|
| 266 |
+
]
|
| 267 |
+
|
| 268 |
+
new_order = home_rows + local1_rows + other_rows
|
| 269 |
+
heatmap_df = heatmap_df.reindex(new_order)
|
| 270 |
+
# ---------------------------------------------
|
| 271 |
+
|
| 272 |
+
# --- Top-K users per server_path (row), then union across rows ---
|
| 273 |
+
# Don't include any special rows (e.g., Total) if they exist yet
|
| 274 |
+
base_df = heatmap_df.copy()
|
| 275 |
+
|
| 276 |
+
# For each row, get top-K usernames by usage (ignore zeros)
|
| 277 |
+
top_users_per_row = base_df.apply(
|
| 278 |
+
lambda row: row[row > 0].nlargest(topk_to_show).index,
|
| 279 |
+
axis=1
|
| 280 |
+
)
|
| 281 |
+
|
| 282 |
+
# Union of all selected users across rows
|
| 283 |
+
selected_users = pd.Index(sorted(set().union(*top_users_per_row.tolist())))
|
| 284 |
+
|
| 285 |
+
# Keep only those users (columns) that exist
|
| 286 |
+
heatmap_df = heatmap_df.loc[:, heatmap_df.columns.intersection(selected_users)]
|
| 287 |
+
# ---------------------------------------------------------------
|
| 288 |
+
|
| 289 |
+
# Add Total row LAST
|
| 290 |
+
heatmap_df.loc["Total"] = heatmap_df.sum(axis=0)
|
| 291 |
+
|
| 292 |
+
# Sort users by total usage (descending)
|
| 293 |
+
heatmap_df = heatmap_df[
|
| 294 |
+
heatmap_df.loc["Total"].sort_values(ascending=False).index
|
| 295 |
+
]
|
| 296 |
+
|
| 297 |
+
# -------- Reverse row order (keep Total last) --------
|
| 298 |
+
non_total_rows = [r for r in heatmap_df.index if r != "Total"]
|
| 299 |
+
reversed_rows = ["Total"] + list(reversed(non_total_rows))
|
| 300 |
+
heatmap_df = heatmap_df.reindex(reversed_rows)
|
| 301 |
+
# -----------------------------------------------------
|
| 302 |
+
|
| 303 |
+
# Text labels inside cells
|
| 304 |
+
text_values = heatmap_df.round(1).astype(str)
|
| 305 |
+
|
| 306 |
+
fig = go.Figure(
|
| 307 |
+
data=go.Heatmap(
|
| 308 |
+
z=heatmap_df.values,
|
| 309 |
+
x=heatmap_df.columns.tolist(),
|
| 310 |
+
y=heatmap_df.index.tolist(),
|
| 311 |
+
text=text_values.values,
|
| 312 |
+
texttemplate="%{text}",
|
| 313 |
+
textfont={"size": 12},
|
| 314 |
+
hovertemplate="path=%{y}<br>user=%{x}<br>size_GB=%{z:.2f}<extra></extra>",
|
| 315 |
+
colorscale="YlOrRd",
|
| 316 |
+
)
|
| 317 |
+
)
|
| 318 |
+
|
| 319 |
+
fig.update_layout(
|
| 320 |
+
title="Users Disk Usage Heatmap (GB)",
|
| 321 |
+
xaxis_title="username",
|
| 322 |
+
yaxis_title="server_path",
|
| 323 |
+
)
|
| 324 |
+
|
| 325 |
+
return fig, df
|
| 326 |
+
|
| 327 |
|
| 328 |
##### PLOT ALL #####
|
| 329 |
def plot_figs():
|
| 330 |
+
fig_gpus, fig_disks, fig_users_disks, df_gpus, df_disks, df_users_disks = None, None, None, None, None, None
|
| 331 |
+
try:
|
| 332 |
+
fig_gpus, df_gpus = plot_gpus()
|
| 333 |
+
fig_disks, df_disks = plot_disks()
|
| 334 |
+
fig_users_disks, df_users_disks = plot_users_disks()
|
| 335 |
+
except Exception as e:
|
| 336 |
+
print(e)
|
| 337 |
+
return fig_gpus, fig_disks, fig_users_disks, df_gpus, df_disks, df_users_disks
|
| 338 |
|
| 339 |
demo = gr.Interface(
|
| 340 |
fn=plot_figs,
|
|
|
|
| 344 |
outputs = [
|
| 345 |
gr.Plot(label="GPU Status", elem_classes="plotcss"),
|
| 346 |
gr.Plot(label="Disk Status", elem_classes="plotcss"),
|
| 347 |
+
gr.Plot(label="Users Disk Status", elem_classes="plotcss"),
|
| 348 |
gr.Dataframe(label="GPU Status Details"),
|
| 349 |
gr.Dataframe(label="Disk Status Details"),
|
| 350 |
+
gr.Dataframe(label="Users Disk Status Details"),
|
| 351 |
],
|
| 352 |
live=True,
|
| 353 |
flagging_options=[],
|
|
|
|
| 356 |
)
|
| 357 |
|
| 358 |
if __name__ == "__main__":
|
| 359 |
+
demo.launch(debug=False)
|