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'])