def on_message_from_bottom(self, eventobj: Event): self.recvcnt = self.recvcnt + 1 self.sentcnt = eventobj.eventcontent.payload print(f"{self.recvcnt / self.sentcnt}") # print(nx.adjacency_matrix(Topology().G).todense()) # print("Progress {:2.2}".format(self.recvcnt/self.sentcnt), end="\r") Topology().shortest_path_to_all(self.componentinstancenumber)
def main(): n = int(sys.argv[1]) print(f"Creating a tree with size {n}") G = nx.random_tree(n) update = threading.Event() draw_delay = threading.Event() plt.ion() fig = plt.figure(num=0) topology = Topology() topology.construct_from_graph(G, FireWireNode, P2PFIFOPerfectChannel) topology.start() FireWireNode.callback = update FireWireNode.draw_delay = draw_delay while True: update.wait() node_colours = list() G = Topology().G pos = nx.spectral_layout(G, center=(0, 0)) for nodeID in Topology().nodes: node = Topology().nodes[nodeID] if node.is_leader: node_colours.append(LEADER_NODE_COLOUR) elif node.in_root_contention: node_colours.append(CONTENDING_NODE_COLOUR) elif node.is_terminated: node_colours.append(PASSIVE_NODE_COLOUR) elif not node.is_terminated: node_colours.append(ACTIVE_NODE_COLOUR) nx.draw( G, pos, node_color=node_colours, edge_color=EDGE_COLOUR, with_labels=True, font_weight="bold", ) fig.canvas.draw() fig.canvas.flush_events() fig.clear() update.clear() draw_delay.set() sleep(1.0 / FPS)
def on_init(self, eventobj: Event): sleep(1) self.neighbours = set(Topology().get_neighbors( self.componentinstancenumber)) print( f"the neighbours of {self.componentinstancenumber} is {self.neighbours}" ) self.send_parent_req()
def drawGraph(overwrite=False): global drawnGraphNodeColors, drawnGraphNodeClockValues G = Topology().G pos = nx.circular_layout(G, center=(0, 0)) nodeColors = [] clockValues = [] for nodeID in Topology().nodes: node = Topology().nodes[nodeID] G.nodes[nodeID]['clock'] = node.clock clockValues.append(node.clock) if node.isPrivileged: nodeColors.append(PRIVILEGED_NODE_COLOR) elif node.havePendingRequest: nodeColors.append(WAITING_NODE_COLOR) else: nodeColors.append(NODE_COLOR) if overwrite or nodeColors != drawnGraphNodeColors or clockValues != drawnGraphNodeClockValues: drawnGraphNodeColors = list(nodeColors) drawnGraphNodeClockValues = list(clockValues) clockLabelsPos = {} for key in pos: x, y = pos[key] r = math.sqrt(x**2 + y**2) theta = atan2(y, x) + radians(75) d = 0.1 clockLabelsPos[key] = (x + d * cos(theta), y + d * sin(theta)) nodeClockLabels = nx.get_node_attributes(G, 'clock') nx.draw(G, pos, node_color=nodeColors, edge_color=EDGE_COLOR, with_labels=True, font_weight='bold') nx.draw_networkx_labels(G, clockLabelsPos, nodeClockLabels) plt.draw() plt.show()
def send_reply(self, nodeID): self.sentReplyCount += 1 nextHop = Topology().get_next_hop(self.componentinstancenumber, nodeID) interfaceID = f"{self.componentinstancenumber}-{nextHop}" header = RicartAgrawalaMessageHeader(RicartAgrawalaMessageTypes.REPLY, self.componentinstancenumber, nodeID, nextHop, interfaceID) payload = GenericMessagePayload(self.componentinstancenumber) message = GenericMessage(header, payload) self.send_down(Event(self, EventTypes.MFRT, message))
def main(): topo = Topology() topo.construct_single_node(Node, 0) topo.start() while True: pass
def requestCommand(args): allNodes = ARGUMENT.ALL.value in args if allNodes: args.remove(ARGUMENT.ALL.value) if len(args) == 0: for nodeID in Topology().nodes: Topology().nodes[nodeID].send_request() else: helpCommand(COMMAND.REQUEST) else: nodes = list() for arg in args: try: nodeID = int(arg) node = Topology().nodes[nodeID] nodes.append(node) except KeyError: print(f"Node {nodeID} does not exist in the topology.") except ValueError: print(f"\'{arg}\' is not integer.") if nodes: for node in nodes: node.send_request() else: helpCommand(COMMAND.REQUEST)
def on_message_from_top(self, eventobj: Event): # Encapsulate the SDU in network layer PDU applmsg = eventobj.eventcontent destination = applmsg.header.messageto nexthop = Topology().get_next_hop(self.componentinstancenumber, destination) if nexthop != float('inf'): print(f"{self.componentinstancenumber} will SEND a message to {destination} over {nexthop}") hdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination, nexthop) payload = eventobj.eventcontent msg = GenericMessage(hdr, payload) self.send_down(Event(self, EventTypes.MFRT, msg)) else: print(f"NO PATH: {self.componentinstancenumber} will NOTSEND a message to {destination} over {nexthop}")
def send_request(self): self.sentRequestCount += 1 self.havePendingRequest = True self.pendingRequestClock = self.clock for nodeID in self.otherNodeIDs: nextHop = Topology().get_next_hop(self.componentinstancenumber, nodeID) interfaceID = f"{self.componentinstancenumber}-{nextHop}" header = RicartAgrawalaMessageHeader( RicartAgrawalaMessageTypes.REQUEST, self.componentinstancenumber, nodeID, nextHop, interfaceID) payload = RicartAgrawalaMessagePayload( self.pendingRequestClock, self.componentinstancenumber) message = GenericMessage(header, payload) self.send_down(Event(self, EventTypes.MFRT, message))
def main(): # G = nx.Graph() # G.add_nodes_from([1, 2]) # G.add_edges_from([(1, 2)]) # nx.draw(G, with_labels=True, font_weight='bold') # plt.draw() G = nx.random_geometric_graph(19, 0.5) topo = Topology() topo.construct_from_graph(G, AdHocNode, P2PFIFOFairLossChannel) for ch in topo.channels: topo.channels[ch].setPacketLossProbability(random.random()) topo.channels[ch].setAverageNumberOfDuplicates(0) ComponentRegistry().print_components() topo.start() topo.plot() plt.show() # while (True): pass print(topo.nodecolors)
def main(): G = completeBinomialGraph(20, 0.00000001, seed=5) topology = Topology() topology.construct_from_graph(G, RicartAgrawalaNode, P2PFIFOPerfectChannel) topology.start() graphDaemon = threading.Thread(target=graphDrawingDaemon, daemon=True) graphDaemon.start() while True: userInput = input("User Command: \n") processUserCommand(userInput)
def main(): topo = Topology() topo.construct_sender_receiver(Sender, Receiver, P2PFIFOFairLossChannel) nx.draw(topo.G, with_labels=True, font_weight='bold') plt.draw() topo.channels["0-1"].setPacketLossProbability(0.1) topo.channels["0-1"].setAverageNumberOfDuplicates(0) # topo.computeForwardingTable() topo.start() plt.show()
def main(): G = nx.random_geometric_graph(9, 0.5, seed=5) nx.draw(G, with_labels=True, font_weight='bold') plt.draw() topo = Topology() topo.construct_from_graph(G, AdHocNode, P2PFIFOPerfectChannel) topo.start() time.sleep(1) random.seed(10) random_node: AdHocNode = topo.get_random_node() random_node.traverse_service.start_traverse() plt.show() while (True): pass
def on_message_from_bottom(self, eventobj: Event): msg = eventobj.eventcontent hdr = msg.header payload = msg.payload if hdr.messageto == self.componentinstancenumber or hdr.messageto == MessageDestinationIdentifiers.NETWORKLAYERBROADCAST: # Add if broadcast.... self.send_up(Event(self, EventTypes.MFRB, payload)) print(f"I received a message to {hdr.messageto} and I am {self.componentinstancenumber}") else: destination = hdr.messageto nexthop = Topology().get_next_hop(self.componentinstancenumber, destination) if nexthop != float('inf'): newhdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination, nexthop) newpayload = eventobj.eventcontent.payload msg = GenericMessage(newhdr, newpayload) self.send_down(Event(self, EventTypes.MFRT, msg)) print(f"{self.componentinstancenumber} will FORWARD a message to {destination} over {nexthop}") else: print(f"NO PATH {self.componentinstancenumber} will NOT FORWARD a message to {destination} over {nexthop}")
def main(): # G = nx.Graph() # G.add_nodes_from([1, 2]) # G.add_edges_from([(1, 2)]) # nx.draw(G, with_labels=True, font_weight='bold') # plt.draw() G = nx.random_geometric_graph(19, 0.5) nx.draw(G, with_labels=True, font_weight='bold') plt.draw() topo = Topology() topo.construct_from_graph(G, AdHocNode, P2PFIFOPerfectChannel) topo.start() plt.show() # while (True): pass
def on_message_from_bottom(self, eventobj: Event): message = eventobj.eventcontent header = message.header messageType = header.messagetype messageTo = header.messageto if messageTo == self.componentinstancenumber: if messageType == RicartAgrawalaMessageTypes.REQUEST: eventobj.event = RicartAgrawalaEventTypes.REQUEST self.send_self(eventobj) elif messageType == RicartAgrawalaMessageTypes.REPLY: eventobj.event = RicartAgrawalaEventTypes.REPLY self.send_self(eventobj) else: nextHop = Topology().get_next_hop(self.componentinstancenumber, messageTo) interfaceID = f"{self.componentinstancenumber}-{nextHop}" if nextHop != inf and nextHop != self.componentinstancenumber: self.forwardedMessageCount += 1 header.nexthop = nextHop header.interfaceid = interfaceID self.send_down(Event(self, EventTypes.MFRT, message))
def on_init(self, eventobj: Event): self.otherNodeIDs = set(Topology().nodes.keys()) self.otherNodeIDs.remove(self.componentinstancenumber)
def getCommand(args): isTime = ARGUMENT.TIME.value in args isAll = ARGUMENT.ALL.value in args isMean = ARGUMENT.MEAN.value in args isTotal = ARGUMENT.TOTAL.value in args isRequest = ARGUMENT.REQUEST.value in args isReply = ARGUMENT.REPLY.value in args isPrivilege = ARGUMENT.PRIVILEGE.value in args isForwarded = ARGUMENT.FORWARDED.value in args areAnyOtherArgumentsSet = isRequest or isReply or isPrivilege or isForwarded if isTime: args.remove(ARGUMENT.TIME.value) if isAll: args.remove(ARGUMENT.ALL.value) if isMean: args.remove(ARGUMENT.MEAN.value) if isTotal: args.remove(ARGUMENT.TOTAL.value) if isRequest: args.remove(ARGUMENT.REQUEST.value) if isReply: args.remove(ARGUMENT.REPLY.value) if isPrivilege: args.remove(ARGUMENT.PRIVILEGE.value) if isForwarded: args.remove(ARGUMENT.FORWARDED.value) if isTime and not isAll and not (isMean or isTotal): if len(args) == 0 and not areAnyOtherArgumentsSet: print( f"Sleep amount in critical section is {RicartAgrawalaNode.privilegeSleepAmount} seconds." ) else: helpCommand(COMMAND.GET) elif isAll and not isTime and not (isMean or isTotal): if not areAnyOtherArgumentsSet: isRequest = isReply = isPrivilege = isForwarded = True if len(args) == 0: for nodeID in Topology().nodes: node = Topology().nodes[nodeID] print( getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) else: helpCommand(COMMAND.GET) elif (isMean or isTotal) and not isTime and not isAll: if not areAnyOtherArgumentsSet: isRequest = isReply = isPrivilege = isForwarded = True if len(args) == 0: N = len(Topology().nodes) node = RicartAgrawalaNode("node", -1) for nodeID in Topology().nodes: node.privilegeCount += Topology().nodes[nodeID].privilegeCount node.sentRequestCount += Topology( ).nodes[nodeID].sentRequestCount node.sentReplyCount += Topology().nodes[nodeID].sentReplyCount node.receivedRequestCount += Topology( ).nodes[nodeID].receivedRequestCount node.receivedReplyCount += Topology( ).nodes[nodeID].receivedReplyCount node.forwardedMessageCount += Topology( ).nodes[nodeID].forwardedMessageCount if isTotal: node.componentinstancenumber = f"Total of {N} Nodes" print( getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) if isMean: node.componentinstancenumber = f"Mean of {N} Nodes" node.privilegeCount /= N node.sentRequestCount /= N node.sentReplyCount /= N node.receivedRequestCount /= N node.receivedReplyCount /= N node.forwardedMessageCount /= N print( getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) else: helpCommand(COMMAND.GET) else: if areAnyOtherArgumentsSet and not isTime and not isAll and not isMean: if len(args) == 1: try: nodeID = int(args[0]) node = Topology().nodes[nodeID] print( getNodeInformation(node, isRequest, isReply, isPrivilege, isForwarded)) except KeyError: print(f"Node {nodeID} does not exist in the topology.") except ValueError: print(f"\'{args[0]}\' is not integer.") else: helpCommand(COMMAND.GET) else: helpCommand(COMMAND.GET)
def update_topology(self): Topology().nodecolors[self.componentinstancenumber] = 'r' Topology().plot()
def run_dijkstra_scholten_simulation(args): ts = dt.now().timestamp() if args.network_type == "erg": N = ERG(args.node_count, args.node_connectivity) total_nodes = args.node_count elif args.network_type == "grid": N = Grid(args.node_count_on_edge) total_nodes = args.node_count_on_edge**2 elif args.network_type == "star": N = Star(args.slave_count, master_is_root=args.master_is_root) total_nodes = args.slave_count + 1 if args.save_tick_plots: tick_plots_save_path = f"{args.tick_plots_save_dir}/DS_{args.network_type}_{total_nodes}_{ts}/" os.mkdir(tick_plots_save_path) print(f"++ Tick plots will be saved to: {tick_plots_save_path}") if args.run_until_termination: args.simulation_ticks = 10**10 assert args.hard_stop_max_tick < args.simulation_ticks assert args.hard_stop_min_tick > 0 hard_stop_on_tick = None if args.hard_stop_nodes: hard_stop_on_tick = [ random.randint(args.hard_stop_min_tick, args.hard_stop_max_tick) for _ in range(total_nodes) ] node_active_ticks_initial = [ random.randint(args.node_min_activeness_after_receive, args.node_max_activeness_after_receive) if random.random() <= args.node_initial_activeness_prob else 0 for _ in range(total_nodes) ] alive_nodes = list(range(total_nodes)) topo_context = { "network": N, "ms_per_tick": args.ms_per_tick, "simulation_ticks": args.simulation_ticks, "initial_liveness": node_active_ticks_initial, "communication_on_active_prob": args.node_activeness_communication_prob, "min_activeness_after_receive": args.node_min_activeness_after_receive, "max_activeness_after_receive": args.node_max_activeness_after_receive, "node_package_process_per_tick": args.node_package_process_per_tick, "passiveness_death_thresh": args.passiveness_death_thresh, "hard_stop_on_tick": hard_stop_on_tick, "alive_nodes": alive_nodes, "only_root_alive_initially": args.only_root_alive_initially } print(topo_context) topo = Topology() topo.construct_from_graph(N.G, DijkstraScholtenAdHocNode, P2PFIFOPerfectChannel, context=topo_context) topo.start() stats = { "df": pd.DataFrame( data={ "dead_nodes": [], "active_nodes": [], "packets_in_transmit": [], "queued_packets": [], "control_packets_sent": [], "control_basic_instant_ratio": [], "control_total_cumulative_ratio": [], }), "terminated_on_tick": None, "announced_on_tick": None } graphs = [] fig, axes = plt.subplots(2, 3) fig.set_figwidth(25) fig.set_figheight(10) # fig.tight_layout() input("\n>>> Proceed ?") term_wait_ctr = 0 reason = None try: for t in range(1, args.simulation_ticks + 1): print(f"[S] Tick: {t}") packages_sent = 0 packages_waiting_on_queue = 0 num_nodes_active = 0 num_dead_nodes = 0 break_this_tick = False control_packets_sent = 0 T = nx.Graph() node_color = [] for index, node in topo.nodes.items(): new_state, pkg_sent_to_friend, cps = node.simulation_tick() if N.root == index: node_color.append("red") elif new_state == DSAHCNodeSimulationStatus.ACTIVE: node_color.append("green") elif new_state == DSAHCNodeSimulationStatus.PASSIVE: node_color.append("mediumslateblue") elif new_state == DSAHCNodeSimulationStatus.OUT_OF_TREE: node_color.append("gray") if index not in T.nodes(): T.add_node(index) if node.parent_node is not None: if node.parent_node not in T.nodes(): T.add_node(node.parent_node) T.add_edge(index, node.parent_node) if index == N.root and new_state is None: reason = f"root terminated ({t})" break_this_tick = True if new_state == DSAHCNodeSimulationStatus.ACTIVE: num_nodes_active += 1 elif new_state == DSAHCNodeSimulationStatus.OUT_OF_TREE: num_dead_nodes += 1 if pkg_sent_to_friend is not None: packages_sent += 1 control_packets_sent += cps packages_waiting_on_queue += node.waiting_packages_on_queue print( f" (ACTIVE: {num_nodes_active}, PKGS-WAIT: {packages_waiting_on_queue}, PKGS-SENT: {packages_sent})" ) if (packages_waiting_on_queue == 0 and num_nodes_active == 0 and packages_sent == 0): if stats["terminated_on_tick"] is None: stats["terminated_on_tick"] = t print("!!! TERMINATED !!!") term_wait_ctr += 1 if args.wait_ticks_after_termination > 0 and term_wait_ctr > args.wait_ticks_after_termination: print("!!! FORCE TERMINATED !!!") reason = f"forced ({args.wait_ticks_after_termination})" break_this_tick = True if args.exit_on_termination: break_this_tick = True total_pkgs_sent_cum = (stats["df"]["control_packets_sent"].sum() + control_packets_sent + stats["df"]["packets_in_transmit"].sum() + packages_sent) stats["df"].loc[t - 1] = [ num_dead_nodes, num_nodes_active, packages_sent, packages_waiting_on_queue, control_packets_sent, (control_packets_sent / packages_sent) if packages_sent > 0 else 0, # TODO: Fix later, find a better soln,,, (((stats["df"]["control_packets_sent"].sum() + control_packets_sent) / total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100 ] graphs.append({ "edges": T.edges(), "nodes": T.nodes(), }) if not args.no_realtime_plot or args.save_tick_plots: axes[0][0].cla() axes[0][1].cla() axes[0][2].cla() axes[1][0].cla() axes[1][1].cla() axes[1][2].cla() axes[0][0].set_title("Active/Dead Nodes") axes[0][0].set_xlabel( f"Simulation Ticks ({args.ms_per_tick}ms/tick)") axes[0][0].set_ylabel(f"Node Count") axes[0][1].set_title("Packets in Transmit") axes[0][1].set_xlabel( f"Simulation Ticks ({args.ms_per_tick}ms/tick)") axes[0][1].set_ylabel(f"Packet Count") axes[1][0].set_title("Control Packet Ratio") axes[1][0].set_xlabel(f"CPR ({args.ms_per_tick}ms/tick)") axes[1][0].set_ylabel(f"CPR (control packets/total packets)") axes[1][1].set_title("Instant Control Packet Ratio") axes[1][1].set_xlabel( f"Simulation Ticks ({args.ms_per_tick}ms/tick)") axes[1][1].set_ylabel(f"CPR (control packets/total packets)") sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange", legend='brief', label="Active nodes") sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue", legend='brief', label="Dead nodes") sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple", legend='brief', label="Basic packets") sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green", legend='brief', label="Control packets") sns.lineplot( data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue") sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red") nx.draw(T, ax=axes[0][2], with_labels=True, node_color=node_color) if args.network_type == "grid": pos = { i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes) } nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos) else: nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color) plt.pause(0.0005) if args.save_tick_plots: plt.savefig(tick_plots_save_path + f"{str(t).zfill(3)}.png", dpi=160) if break_this_tick: break time.sleep(args.ms_per_tick / 1000) except KeyboardInterrupt: pass axes[0][0].cla() axes[0][1].cla() axes[0][2].cla() axes[1][0].cla() axes[1][1].cla() axes[1][2].cla() sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange") sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue") sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple") sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green") sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue") sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red") nx.draw(T, ax=axes[0][2], with_labels=True, node_color=node_color) if args.network_type == "grid": pos = { i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes) } nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos) else: nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color) plt.savefig(f"simdump/DS_stats_{args.network_type}_{total_nodes}_{ts}.png", dpi=200) with open(f"simdump/DS_run_{args.network_type}_{total_nodes}_{ts}.pkl", "wb") as fp: pickle.dump( { "args": args, "context": topo_context, "stats": stats, "graphs": graphs }, fp) if not args.no_realtime_plot: plt.show() print( f"\n{reason} [{t - stats['terminated_on_tick'] if stats['terminated_on_tick'] is not None else None}]" ) if args.generate_gif: make_gif(f"{tick_plots_save_path}/*.png", tick_plots_save_path, "animation.gif", t * 20)
def main(): n = int(sys.argv[1]) print(f"Creating a ring with size {n}") G = nx.cycle_graph(n) plt.ion() fig = plt.figure(num=0) topology = Topology() topology.construct_from_graph(G, ItaiRodehNode, P2PFIFOPerfectChannel) topology.start() ItaiRodehNode.ring_size = n update = threading.Event() draw_delay = threading.Event() ItaiRodehNode.callback = update ItaiRodehNode.draw_delay = draw_delay while True: update.wait() assumed_ids = list() node_colours = list() G = Topology().G pos = nx.circular_layout(G, center=(0, 0)) for nodeID in Topology().nodes: node = Topology().nodes[nodeID] G.nodes[nodeID]["id_p"] = node.id_p assumed_ids.append(node.id_p) if node.state == State.active: node_colours.append(ACTIVE_NODE_COLOUR) elif node.state == State.passive: node_colours.append(PASSIVE_NODE_COLOUR) elif node.state == State.leader: node_colours.append(LEADER_NODE_COLOUR) node_id_label_pos = {} for key in pos: x, y = pos[key] theta = atan2(y, x) + radians(75) d = 0.1 node_id_label_pos[key] = (x + d * cos(theta), y + d * sin(theta)) node_id_labels = nx.get_node_attributes(G, "id_p") nx.draw( G, pos, node_color=node_colours, edge_color=EDGE_COLOUR, with_labels=False, font_weight="bold", ) nx.draw_networkx_labels(G, node_id_label_pos, node_id_labels) fig.text(0.2, 0.2, f"Round: {ItaiRodehNode.global_round}") fig.canvas.draw() fig.canvas.flush_events() fig.clear() update.clear() draw_delay.set() sleep(1.0 / FPS)
def prepare_neighbor_map(self): neighbor_list = Topology().get_neighbors(self.componentinstancenumber) return [DfsNeighbor(n, False) for n in neighbor_list]
def run_shavit_francez_simulation(args): if args.network_type == "erg": N = ERG(args.node_count, args.node_connectivity) total_nodes = args.node_count elif args.network_type == "grid": N = Grid(args.node_count_on_edge) total_nodes = args.node_count_on_edge ** 2 elif args.network_type == "star": N = Star(args.slave_count, master_is_root=args.master_is_root) total_nodes = args.slave_count + 1 if args.run_until_termination: args.simulation_ticks = 10**10 assert args.hard_stop_max_tick < args.simulation_ticks assert args.hard_stop_min_tick > 0 hard_stop_on_tick = None if args.hard_stop_nodes: hard_stop_on_tick = [random.randint(args.hard_stop_min_tick, args.hard_stop_max_tick) for _ in range(total_nodes)] node_active_ticks_initial = [random.randint(args.node_min_activeness_after_receive, args.node_max_activeness_after_receive) if random.random() <= args.node_initial_activeness_prob else 0 for _ in range(total_nodes)] alive_nodes = list(range(total_nodes)) topo_context = { "network": N, "ms_per_tick": args.ms_per_tick, "simulation_ticks": args.simulation_ticks, "initial_liveness": node_active_ticks_initial, "communication_on_active_prob": args.node_activeness_communication_prob, "min_activeness_after_receive": args.node_min_activeness_after_receive, "max_activeness_after_receive": args.node_max_activeness_after_receive, "node_package_process_per_tick": args.node_package_process_per_tick, "passiveness_death_thresh": args.passiveness_death_thresh, "hard_stop_on_tick": hard_stop_on_tick, "alive_nodes": alive_nodes, "only_root_alive_initially": args.only_root_alive_initially } print(topo_context) # N.plot() # plt.show() topo = Topology() topo.construct_from_graph(N.G, ShavitFrancezAdHocNode, P2PFIFOPerfectChannel, context=topo_context) topo.start() stats = { "df": pd.DataFrame(data={ "dead_nodes": [], "active_nodes": [], "packets_in_transmit": [], "queued_packets": [], "control_packets_sent": [], "control_basic_instant_ratio": [], "control_total_cumulative_ratio": [], "wave_packets_sent": [], "wave_basic_instant_ratio": [], "wave_total_cumulative_ratio": [], "wave_control_cumulative_ratio": [] }), "terminated_on_tick": None, "announced_on_tick": None } fig, axes = plt.subplots(2, 3) fig.set_figwidth(25) fig.set_figheight(10) # fig.tight_layout() input("\n>>> Proceed ?") term_wait_ctr = 0 reason = None wave_finisher = None try: for t in range(1, args.simulation_ticks + 1): print(f"[S] Tick: {t}") packages_sent = 0 packages_waiting_on_queue = 0 num_nodes_active = 0 num_dead_nodes = 0 break_this_tick = False control_packets_sent = 0 wave_packets_sent = 0 node_color = [] for index, node in topo.nodes.items(): new_state, pkg_sent_to_friend, cps, wps = node.simulation_tick() if N.root == index and new_state != SFAHCNodeSimulationStatus.OUT_OF_TREE: node_color.append("red") elif N.root == index and new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE: node_color.append("orange") elif new_state == SFAHCNodeSimulationStatus.ACTIVE: node_color.append("green") elif new_state == SFAHCNodeSimulationStatus.PASSIVE: node_color.append("mediumslateblue") elif new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE: node_color.append("gray") else: # is None... # It's the wave finisher!!! node_color.append("yellow") wave_finisher = index if new_state is None: reason = f"wave terminated ({t}) ({wave_finisher})" break_this_tick = True if new_state == SFAHCNodeSimulationStatus.ACTIVE: num_nodes_active += 1 elif new_state == SFAHCNodeSimulationStatus.OUT_OF_TREE: num_dead_nodes += 1 if pkg_sent_to_friend is not None: packages_sent += 1 control_packets_sent += cps wave_packets_sent += wps packages_waiting_on_queue += node.waiting_packages_on_queue print(f" (ACTIVE: {num_nodes_active}, PKGS-WAIT: {packages_waiting_on_queue}, PKGS-SENT: {packages_sent})") if (packages_waiting_on_queue == 0 and num_nodes_active == 0 and packages_sent == 0): if stats["terminated_on_tick"] is None: stats["terminated_on_tick"] = t print("!!! TERMINATED !!!") term_wait_ctr += 1 if args.wait_ticks_after_termination > 0 and term_wait_ctr > args.wait_ticks_after_termination: print("!!! FORCE TERMINATED !!!") reason = f"forced ({args.wait_ticks_after_termination})" break_this_tick = True if args.exit_on_termination: break_this_tick = True control_pkgs_sent_cum = stats["df"]["control_packets_sent"].sum() + control_packets_sent total_pkgs_sent_cum = (stats["df"]["control_packets_sent"].sum() + control_packets_sent + stats["df"]["packets_in_transmit"].sum() + packages_sent + stats["df"]["wave_packets_sent"].sum() + wave_packets_sent) stats["df"].loc[t-1] = [ num_dead_nodes, num_nodes_active, packages_sent, packages_waiting_on_queue, control_packets_sent, (control_packets_sent / packages_sent) if packages_sent > 0 else 0, # TODO: Fix later, find a better soln,,, (((stats["df"]["control_packets_sent"].sum() + control_packets_sent) / total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100, wave_packets_sent, (wave_packets_sent / packages_sent) if packages_sent > 0 else 0, # TODO: Fix later, find a better soln,,, (((stats["df"]["wave_packets_sent"].sum() + wave_packets_sent) / total_pkgs_sent_cum) if total_pkgs_sent_cum > 0 else 0) * 100, (((stats["df"]["wave_packets_sent"].sum() + wave_packets_sent) / control_pkgs_sent_cum) if control_pkgs_sent_cum > 0 else 0) * 100, ] # axes.scatter(x=t, y=num_nodes_active) if not args.no_realtime_plot: axes[0][0].cla() axes[0][1].cla() axes[0][2].cla() axes[1][0].cla() axes[1][1].cla() axes[1][2].cla() sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange") sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue") sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple") sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green") sns.lineplot(data=stats["df"]["wave_packets_sent"], ax=axes[0][1], color="blue") sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue") sns.lineplot(data=stats["df"]["wave_total_cumulative_ratio"], ax=axes[1][0], color="yellow") sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red") sns.lineplot(data=stats["df"]["wave_basic_instant_ratio"], ax=axes[1][1], color="orange") sns.lineplot(data=stats["df"]["wave_control_cumulative_ratio"], ax=axes[0][2], color="mediumslateblue") if args.network_type == "grid": pos = {i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes)} nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos) else: nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color) plt.pause(0.0005) if break_this_tick: break time.sleep(args.ms_per_tick / 1000) except KeyboardInterrupt: pass ts = dt.now().timestamp() if args.no_realtime_plot: axes[0][0].cla() axes[0][1].cla() axes[0][2].cla() axes[1][0].cla() axes[1][1].cla() axes[1][2].cla() sns.lineplot(data=stats["df"]["active_nodes"], ax=axes[0][0], color="orange") sns.lineplot(data=stats["df"]["dead_nodes"], ax=axes[0][0], color="blue") sns.lineplot(data=stats["df"]["packets_in_transmit"], ax=axes[0][1], color="purple") sns.lineplot(data=stats["df"]["control_packets_sent"], ax=axes[0][1], color="green") sns.lineplot(data=stats["df"]["wave_packets_sent"], ax=axes[0][1], color="blue") sns.lineplot(data=stats["df"]["control_total_cumulative_ratio"], ax=axes[1][0], color="mediumslateblue") sns.lineplot(data=stats["df"]["wave_total_cumulative_ratio"], ax=axes[1][0], color="yellow") sns.lineplot(data=stats["df"]["control_basic_instant_ratio"], ax=axes[1][1], color="red") sns.lineplot(data=stats["df"]["wave_basic_instant_ratio"], ax=axes[1][1], color="orange") sns.lineplot(data=stats["df"]["wave_control_cumulative_ratio"], ax=axes[0][2], color="mediumslateblue") if args.network_type == "grid": pos = {i: (i // args.node_count_on_edge, i % args.node_count_on_edge) for i in range(total_nodes)} nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color, pos=pos) else: nx.draw(N.G, ax=axes[1][2], with_labels=True, node_color=node_color) plt.pause(0.0005) plt.savefig(f"simdump/SF_stats_{args.network_type}_{total_nodes}_{ts}.png", dpi=200) with open(f"simdump/SF_run_{args.network_type}_{total_nodes}_{ts}.pkl", "wb") as fp: pickle.dump({ "args": args, "context": topo_context, "stats": stats }, fp) if not args.no_realtime_plot: plt.show() print(f"\n{reason} [{t - stats['terminated_on_tick'] if stats['terminated_on_tick'] is not None else None}]")
def prepare_neighbor_map(self): neighbor_list = Topology().get_neighbors(self.componentinstancenumber) # return [{"neighbor": n, "invoked": False} for n in neighbor_list] return [TarryNeighbor(n, False) for n in neighbor_list]