rajvivan's picture
Upload sim.py
37c884b verified
Raw
History Blame Contribute Delete
3.12 kB
import numpy as np
NODE_TYPES = {"A": dict(cap=6.0, mem=4.0, p_idle=4.0, p_peak=15.0),
"B": dict(cap=24.0, mem=16.0, p_idle=12.0, p_peak=65.0)}
DT = 0.1
def make_nodes(n_nodes, rng):
nodes = []
for i in range(n_nodes):
t = "A" if rng.random() < 0.5 else "B"
base = NODE_TYPES[t]; jit = rng.uniform(0.85, 1.15)
nodes.append(dict(id=i, type=t, cap=base["cap"]*jit, mem=base["mem"],
p_idle=base["p_idle"], p_peak=base["p_peak"]))
return nodes
def node_arrays(nodes):
return (np.array([n["cap"] for n in nodes], dtype=float),
np.array([n["mem"] for n in nodes], dtype=float),
np.array([n["p_idle"] for n in nodes], dtype=float),
np.array([n["p_peak"] for n in nodes], dtype=float))
def make_tasks(n_tasks, rng):
if n_tasks == 0:
return (np.zeros(0), np.zeros(0), np.zeros(0), np.zeros(0, dtype=int))
cls = (rng.random(n_tasks) < 0.40).astype(int)
demand = np.where(cls == 1, rng.uniform(0.05, 0.30, n_tasks),
rng.uniform(0.40, 1.50, n_tasks))
mem = np.where(cls == 1, rng.uniform(0.05, 0.4, n_tasks),
rng.uniform(0.2, 1.2, n_tasks))
deadline = np.where(cls == 1, 0.050, 0.500)
return demand, mem, deadline, cls
def make_link_latency(n_nodes, rng):
return rng.uniform(0.002, 0.020, n_nodes)
def evaluate(assign, demand, mem, deadline, cls, backlog, cap, link_lat,
p_idle, p_peak, alpha=0.5, beta=0.3, gamma=0.2, dt=DT,
return_metrics=False, node_mem=None):
n_nodes = cap.shape[0]; m = assign.shape[0]
work = np.zeros(n_nodes); memload = np.zeros(n_nodes); lat = np.zeros(m)
order = np.lexsort((demand, -cls)); ahead = backlog.copy()
for idx in order:
n = assign[idx]
proc = demand[idx] / cap[n]; wait = ahead[n] / cap[n]
lat[idx] = link_lat[n] + wait + proc
ahead[n] += demand[idx]; work[n] += demand[idx]; memload[n] += mem[idx]
served = np.minimum(ahead, cap * dt)
util = np.clip(served / (cap * dt), 0.0, 1.0)
avg_lat = float(lat.mean()) if m > 0 else 0.0
energy = float(np.sum((p_idle + (p_peak - p_idle) * util) * dt))
sigma_u = float(np.std(util))
cap_over = np.maximum(work - cap * dt, 0.0).sum()
mem_over = np.maximum(memload - node_mem, 0.0).sum() if node_mem is not None else 0.0
penalty = 50.0 * cap_over + 50.0 * mem_over
lat_n = avg_lat / 0.1; en_n = energy / (n_nodes * 0.065 + 1e-9)
fit = alpha * lat_n + beta * en_n + gamma * sigma_u + penalty
if not return_metrics:
return fit
classA = cls == 1
a_met = float(np.mean(lat[classA] <= deadline[classA])) if classA.any() else 1.0
met_all = float(np.mean(lat <= deadline)) if m > 0 else 1.0
jain = float((util.sum() ** 2) / (n_nodes * np.sum(util ** 2) + 1e-12)) if util.sum() > 0 else 1.0
return dict(fitness=fit, avg_latency=avg_lat, energy=energy, sigma_u=sigma_u,
utilization=float(util.mean()), jain=jain,
classA_deadline_met=a_met, all_deadline_met=met_all, served=served, work=work)