Spaces:
Runtime error
Runtime error
import streamlit as st | |
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
from PIL import Image | |
import copy | |
import time | |
import requests | |
from time import strftime, localtime | |
sample_data = { | |
"gpus" : { | |
"Alice" : 16, | |
"Tom" : 16, | |
"γ γ΄γ γ " : 16, | |
}, | |
"total" : { | |
"total" : 28, | |
"used" : 12 | |
}, | |
"chain" : [ | |
{ | |
'index': 1, | |
'timestamp': 1701025843.5186985, | |
'transactions': [], | |
'previous_hash': '1' | |
}, | |
{ | |
'index': 2, | |
'timestamp': 1701037845.518921, | |
'transactions': [ | |
{'id': 'Alice', 'kind': 'add', 'data': '16'}, | |
{'id': 'bob', 'kind': 'add', 'data': '16'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': 'Hello?'}, | |
{'id': 'Alice', 'kind': 'add', 'data': '16'}, | |
{'id': 'bob', 'kind': 'inference', 'data': '16'} | |
], | |
'previous_hash':'5199cc3018287cf3f5fffbb0d1ae3f949256774a2347401818bdc93d29c379e8' | |
}, | |
{ | |
'index': 3, | |
'timestamp': 1701147846.535392, | |
'transactions': [ | |
{'id': 'Alice', 'kind': 'add', 'data': '16'}, | |
{'id': 'TOM', 'kind': 'add', 'data': '8'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': 'Hello?'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': '16'}, | |
{'id': 'bob', 'kind': 'inference', 'data': '0'} | |
], | |
'previous_hash':'5199cc3018287cf3f5fffbb0d1ae3f949256774a2347401818bdc93d29c379e8' | |
}, | |
{ | |
'index': 4, | |
'timestamp': 1701157947.545325, | |
'transactions': [ | |
{'id': 'Alice', 'kind': 'inference', 'data': '16'}, | |
{'id': 'bob', 'kind': 'inference', 'data': '16'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': 'Hello?'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': '16'}, | |
{'id': 'Nee', 'kind': 'add', 'data': '16'} | |
], | |
'previous_hash':'5199cc3018287cf3f5fffbb0d1ae3f949256774a2347401818bdc93d29c379e8' | |
}, | |
{ | |
'index': 5, | |
'timestamp': 1701057969.582371, | |
'transactions': [ | |
{'id': 'Alice', 'kind': 'add', 'data': '16'}, | |
{'id': 'bob', 'kind': 'inference', 'data': '16'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': 'Hello?'}, | |
{'id': 'Alice', 'kind': 'inference', 'data': '16'}, | |
{'id': 'bob', 'kind': 'inference', 'data': '16'} | |
], | |
'previous_hash':'5199cc3018287cf3f5fffbb0d1ae3f949256774a2347401818bdc93d29c379e8' | |
}, | |
] | |
} | |
response = requests.post("https://ldhldh-api-for-unity.hf.space/run/predict_7", json={ | |
"data": [ | |
]}).json() | |
#sample_data = eval(response["data"][0]) | |
print(sample_data) | |
user_num = len(sample_data['gpus']) | |
total_gpu = sample_data['total']['total'] | |
used_gpu = min(sample_data['total']['used'],total_gpu*0.87) | |
timestamp_list = [] | |
name_list = [] | |
timestamp_gpu_data = [] | |
timestamp_inference_data = [0, 0] | |
timestamp_list_date = [] | |
for block in sample_data['chain']: | |
timestamp_list.append(block['timestamp'] ) | |
for t in block['transactions']: | |
if t['kind'] == "add": | |
if not t['id'] in name_list: | |
name_list.append(t['id']) | |
timestamp_gpu_data = [[0 for _ in range(len(name_list))]] | |
timestamp_list_date = [1701115843.5186985, sample_data['chain'][0]['timestamp']] | |
for block in sample_data['chain']: | |
temp = timestamp_gpu_data[int(block['index']) - 1] | |
if strftime('%Y-%m-%d', localtime( timestamp_list_date[-1] )) != strftime('%Y-%m-%d', localtime( block['timestamp'] )): | |
timestamp_list_date.append(block['timestamp']) | |
timestamp_inference_data.append(0) | |
for t in block['transactions']: | |
if t['kind'] == "add": | |
temp[name_list.index(t['id'])] += int(t['data']) | |
elif t['kind'] == "out": | |
temp[name_list.index(t['id'])] = 0 | |
else: | |
timestamp_inference_data[-1] += 1 | |
timestamp_gpu_data.append(copy.deepcopy(temp)) | |
timestamp_gpu_data = timestamp_gpu_data[0:-1] | |
col1, col2, col3 = st.columns(3) | |
col1.metric("Total GPU", f"{total_gpu} GB", f"{user_num} users are sharing now") | |
if total_gpu != 0: | |
col2.metric("Used", f"{used_gpu} GB") | |
col3.metric("Percent", f"{round(100 * used_gpu/total_gpu, 2)} %",) | |
else: | |
col2.metric("Used", f"0 GB") | |
col3.metric("Percent", f"- %",) | |
chart_data = pd.DataFrame(timestamp_gpu_data, columns = name_list, index = timestamp_list) | |
last_timestamp = strftime('%Y-%m-%d %I:%M:%S %p', localtime( sample_data['chain'][-1]['timestamp'] )) | |
st.title('Gpu pool timeline') | |
st.area_chart(chart_data) | |
st.caption(f'last updated in timestamp {last_timestamp}.') | |
class BubbleChart: | |
def __init__(self, data, bubble_spacing=0, n_bins=5): | |
unity_ids = list(data.keys()) | |
share_values = list(data.values()) | |
area = np.asarray(share_values) | |
r = np.sqrt(area / np.pi) | |
self.bubble_spacing = bubble_spacing | |
self.bubbles = np.ones((len(area), 4)) | |
self.bubbles[:, 2] = r | |
self.bubbles[:, 3] = area | |
self.maxstep = 2 * self.bubbles[:, 2].max() + self.bubble_spacing | |
self.step_dist = self.maxstep / 2 | |
length = np.ceil(np.sqrt(len(self.bubbles))) | |
grid = np.arange(length) * self.maxstep | |
gx, gy = np.meshgrid(grid, grid) | |
self.bubbles[:, 0] = gx.flatten()[:len(self.bubbles)] | |
self.bubbles[:, 1] = gy.flatten()[:len(self.bubbles)] | |
min_size = np.min(area) | |
max_size = np.max(area) | |
if min_size == max_size: | |
min_size = max_size//2 | |
self.colors = self.quantize_colors(area, min_size, max_size, n_bins) | |
self.com = self.center_of_mass() | |
def quantize_colors(self, sizes, min_size, max_size, n_bins): | |
size_range = max_size - min_size | |
bin_size = size_range / n_bins | |
quantized_colors = [] | |
for size in sizes: | |
bin_index = min(int((size - min_size) / bin_size), n_bins - 1) | |
quantized_colors.append(self.get_color_from_bin(bin_index, n_bins)) | |
print(f"Size: {size}, Bin Index: {bin_index}, Color: {self.get_color_from_bin(bin_index, n_bins)}") | |
return quantized_colors | |
def get_color_from_bin(self, bin_index, n_bins): | |
# colors = ['#9a9fad', '#848dad', '#7080b5', '#5269b3', '#3654b5'] | |
colors = ['#42c5ac', '#61d87d', '#a8eb86', '#d3f59a', '#f8ffaf'] | |
return colors[bin_index] | |
def center_of_mass(self): | |
return np.average( | |
self.bubbles[:, :2], axis=0, weights=self.bubbles[:, 3] | |
) | |
def center_distance(self, bubble, bubbles): | |
return np.hypot(bubble[0] - bubbles[:, 0], | |
bubble[1] - bubbles[:, 1]) | |
def outline_distance(self, bubble, bubbles): | |
center_distance = self.center_distance(bubble, bubbles) | |
return center_distance - bubble[2] - \ | |
bubbles[:, 2] - self.bubble_spacing | |
def check_collisions(self, bubble, bubbles): | |
distance = self.outline_distance(bubble, bubbles) | |
return len(distance[distance < 0]) | |
def collides_with(self, bubble, bubbles): | |
distance = self.outline_distance(bubble, bubbles) | |
idx_min = np.argmin(distance) | |
return idx_min if type(idx_min) == np.ndarray else [idx_min] | |
def collapse(self, n_iterations=50): | |
for _i in range(n_iterations): | |
moves = 0 | |
for i in range(len(self.bubbles)): | |
rest_bub = np.delete(self.bubbles, i, 0) | |
dir_vec = self.com - self.bubbles[i, :2] | |
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec)) | |
new_point = self.bubbles[i, :2] + dir_vec * self.step_dist | |
new_bubble = np.append(new_point, self.bubbles[i, 2:4]) | |
if not self.check_collisions(new_bubble, rest_bub): | |
self.bubbles[i, :] = new_bubble | |
self.com = self.center_of_mass() | |
moves += 1 | |
else: | |
for colliding in self.collides_with(new_bubble, rest_bub): | |
dir_vec = rest_bub[colliding, :2] - self.bubbles[i, :2] | |
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec)) | |
orth = np.array([dir_vec[1], -dir_vec[0]]) | |
new_point1 = (self.bubbles[i, :2] + orth * | |
self.step_dist) | |
new_point2 = (self.bubbles[i, :2] - orth * | |
self.step_dist) | |
dist1 = self.center_distance( | |
self.com, np.array([new_point1])) | |
dist2 = self.center_distance( | |
self.com, np.array([new_point2])) | |
new_point = new_point1 if dist1 < dist2 else new_point2 | |
new_bubble = np.append(new_point, self.bubbles[i, 2:4]) | |
if not self.check_collisions(new_bubble, rest_bub): | |
self.bubbles[i, :] = new_bubble | |
self.com = self.center_of_mass() | |
if moves / len(self.bubbles) < 0.1: | |
self.step_dist = self.step_dist / 2 | |
def plot(self, ax, labels, alpha, edge_alpha = 1): | |
for i in range(len(self.bubbles)): | |
circ = plt.Circle( | |
self.bubbles[i, :2], self.bubbles[i, 2], | |
color=self.colors[i], alpha= alpha) | |
ax.add_patch(circ) | |
ax.text(*self.bubbles[i, :2], labels[i], | |
horizontalalignment='center', verticalalignment='center') | |
class GenerateChart: | |
def __init__(self, data, bubble_spacing=0, n_bins=5): | |
unity_ids = list(data.keys()) | |
share_values = list(data.values()) | |
simulation = BubbleChart(data, bubble_spacing=bubble_spacing, n_bins=n_bins) | |
simulation.collapse() | |
fig, ax = plt.subplots(subplot_kw=dict(aspect="equal")) | |
alpha_value = 1 | |
simulation.plot(ax, unity_ids, alpha=alpha_value) | |
ax.axis("off") | |
ax.relim() | |
ax.autoscale_view() | |
ax.set_title('p2p share', color = "white") | |
fig = plt.gcf() | |
img = fig2img(fig) | |
st.title('Current GPU contributors') | |
st.image(img, caption='Bubble chart of gpu pool of each Users') | |
def fig2img(fig): | |
"""Convert a Matplotlib figure to a PIL Image and return it""" | |
import io | |
buf = io.BytesIO() | |
fig.savefig(buf) | |
buf.seek(0) | |
img = Image.open(buf) | |
return img | |
if len(sample_data['gpus'])> 1: | |
chart_generator = GenerateChart(sample_data.get("gpus", {}), bubble_spacing=0.1, n_bins=5) | |
#st.title('Inference call') | |
#timestamp_list_date_str = [] | |
#for d in timestamp_list_date: | |
# timestamp_list_date_str.append(strftime('%Y-%m-%d', localtime( d ))) | |
#call_data = pd.DataFrame(timestamp_inference_data, columns = ["inference call"], index = timestamp_list_date_str) | |
#st.bar_chart(call_data) | |
st.title('Previous Blocks') | |
st.json(sample_data['chain']) | |