def test(self, trace: Trace, save_dir: str, plot_flag: bool = False) -> Tuple[float, float]: """Test a network trace and return rewards. The 1st return value is the reward in Monitor Interval(MI) level and the length of MI is 1 srtt. The 2nd return value is the reward in packet level. It is computed by using throughput, average rtt, and loss rate in each 500ms bin of the packet log. The 2nd value will be 0 if record_pkt_log flag is False. Args: trace: network trace. save_dir: where a MI level log will be saved if save_dir is a valid path. A packet level log will be saved if record_pkt_log flag is True and save_dir is a valid path. """ links = [Link(trace), Link(trace)] senders = [BBRSender(0, 0, self.seed)] net = Network(senders, links, self.record_pkt_log) rewards = [] start_rtt = trace.get_delay(0) * 2 / 1000 run_dur = start_rtt if save_dir: os.makedirs(save_dir, exist_ok=True) f_sim_log = open( os.path.join(save_dir, '{}_simulation_log.csv'.format(self.cc_name)), 'w', 1) writer = csv.writer(f_sim_log, lineterminator='\n') writer.writerow([ 'timestamp', "send_rate", 'recv_rate', 'latency', 'loss', 'reward', "action", "bytes_sent", "bytes_acked", "bytes_lost", "send_start_time", "send_end_time", 'recv_start_time', 'recv_end_time', 'latency_increase', "packet_size", 'bandwidth', "queue_delay", 'packet_in_queue', 'queue_size', 'cwnd', 'ssthresh', "rto", "packets_in_flight" ]) else: f_sim_log = None writer = None while True: net.run(run_dur) mi = senders[0].get_run_data() throughput = mi.get("recv rate") # bits/sec send_rate = mi.get("send rate") # bits/sec latency = mi.get("avg latency") avg_queue_delay = mi.get("avg queue delay") loss = mi.get("loss ratio") reward = pcc_aurora_reward( throughput / BITS_PER_BYTE / BYTES_PER_PACKET, latency, loss, trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET) rewards.append(reward) try: ssthresh = senders[0].ssthresh except: ssthresh = 0 action = 0 if save_dir and writer: writer.writerow([ net.get_cur_time(), send_rate, throughput, latency, loss, reward, action, mi.bytes_sent, mi.bytes_acked, mi.bytes_lost, mi.send_start, mi.send_end, mi.recv_start, mi.recv_end, mi.get('latency increase'), mi.packet_size, links[0].get_bandwidth(net.get_cur_time()) * BYTES_PER_PACKET * BITS_PER_BYTE, avg_queue_delay, links[0].pkt_in_queue, links[0].queue_size, senders[0].cwnd, ssthresh, senders[0].rto, senders[0].bytes_in_flight / BYTES_PER_PACKET ]) if senders[0].srtt: run_dur = senders[0].srtt should_stop = trace.is_finished(net.get_cur_time()) if should_stop: break if f_sim_log: f_sim_log.close() avg_sending_rate = senders[0].avg_sending_rate tput = senders[0].avg_throughput avg_lat = senders[0].avg_latency loss = senders[0].pkt_loss_rate pkt_level_reward = pcc_aurora_reward(tput, avg_lat, loss, avg_bw=trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET) pkt_level_original_reward = pcc_aurora_reward(tput, avg_lat, loss) if save_dir: with open( os.path.join(save_dir, "{}_summary.csv".format(self.cc_name)), 'w') as f: summary_writer = csv.writer(f, lineterminator='\n') summary_writer.writerow([ 'trace_average_bandwidth', 'trace_average_latency', 'average_sending_rate', 'average_throughput', 'average_latency', 'loss_rate', 'mi_level_reward', 'pkt_level_reward' ]) summary_writer.writerow([ trace.avg_bw, trace.avg_delay, avg_sending_rate * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, tput * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, avg_lat, loss, np.mean(rewards), pkt_level_reward ]) if self.record_pkt_log and save_dir: with open( os.path.join(save_dir, "{}_packet_log.csv".format(self.cc_name)), 'w', 1) as f: pkt_logger = csv.writer(f, lineterminator='\n') pkt_logger.writerow([ 'timestamp', 'packet_event_id', 'event_type', 'bytes', 'cur_latency', 'queue_delay', 'packet_in_queue', 'sending_rate', 'bandwidth' ]) pkt_logger.writerows(net.pkt_log) # with open(os.path.join(save_dir, "{}_log.csv".format(self.cc_name)), 'w', 1) as f: # writer = csv.writer(f, lineterminator='\n') # writer.writerow( # ['timestamp', 'pacing_gain', "pacing_rate", 'cwnd_gain', # 'cwnd', 'target_cwnd', 'prior_cwnd', "btlbw", "rtprop", # "full_bw", 'state', "packets_in_flight", # "in_fast_recovery_mode", 'rs_delivery_rate', 'round_start', # 'round_count', 'rto', 'exit_fast_recovery_ts', # 'pkt_in_queue']) # writer.writerows(senders[0].bbr_log) if plot_flag and save_dir: plot_mi_level_time_series( trace, os.path.join(save_dir, '{}_simulation_log.csv'.format(self.cc_name)), save_dir, self.cc_name) plot(trace, *senders[0].bin_tput, *senders[0].bin_sending_rate, tput * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, avg_sending_rate * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, *senders[0].latencies, avg_lat * 1000, loss, pkt_level_original_reward, pkt_level_reward, save_dir, self.cc_name) return np.mean(rewards), pkt_level_reward
def _test(self, trace: Trace, save_dir: str, plot_flag: bool = False, saliency: bool = False): reward_list = [] loss_list = [] tput_list = [] delay_list = [] send_rate_list = [] ts_list = [] action_list = [] mi_list = [] obs_list = [] if save_dir: os.makedirs(save_dir, exist_ok=True) f_sim_log = open(os.path.join(save_dir, 'aurora_simulation_log.csv'), 'w', 1) writer = csv.writer(f_sim_log, lineterminator='\n') writer.writerow(['timestamp', "target_send_rate", "send_rate", 'recv_rate', 'latency', 'loss', 'reward', "action", "bytes_sent", "bytes_acked", "bytes_lost", "MI", "send_start_time", "send_end_time", 'recv_start_time', 'recv_end_time', 'latency_increase', "packet_size", 'min_lat', 'sent_latency_inflation', 'latency_ratio', 'send_ratio', 'bandwidth', "queue_delay", 'packet_in_queue', 'queue_size', "recv_ratio", "srtt"]) else: f_sim_log = None writer = None env = gym.make( 'PccNs-v0', traces=[trace], delta_scale=self.delta_scale, record_pkt_log=self.record_pkt_log) env.seed(self.seed) obs = env.reset() grads = [] # gradients for saliency map while True: if isinstance(self.model, LoadedModel): obs = obs.reshape(1, -1) action = self.model.act(obs) action = action['act'][0] else: if env.net.senders[0].got_data: if saliency: action, _states, grad = self.model.predict( obs, deterministic=True, saliency=saliency) grads.append(grad) else: action, _states = self.model.predict( obs, deterministic=True) else: action = np.array([0]) # get the new MI and stats collected in the MI # sender_mi = env.senders[0].get_run_data() sender_mi = env.senders[0].history.back() #get_run_data() max_recv_rate = env.senders[0].max_tput throughput = sender_mi.get("recv rate") # bits/sec send_rate = sender_mi.get("send rate") # bits/sec latency = sender_mi.get("avg latency") loss = sender_mi.get("loss ratio") avg_queue_delay = sender_mi.get('avg queue delay') sent_latency_inflation = sender_mi.get('sent latency inflation') latency_ratio = sender_mi.get('latency ratio') send_ratio = sender_mi.get('send ratio') recv_ratio = sender_mi.get('recv ratio') reward = pcc_aurora_reward( throughput / BITS_PER_BYTE / BYTES_PER_PACKET, latency, loss, trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET, trace.avg_delay * 2/ 1e3) if save_dir and writer: writer.writerow([ env.net.get_cur_time(), round(env.senders[0].rate * BYTES_PER_PACKET * BITS_PER_BYTE, 0), round(send_rate, 0), round(throughput, 0), latency, loss, reward, action.item(), sender_mi.bytes_sent, sender_mi.bytes_acked, sender_mi.bytes_lost, sender_mi.send_end - sender_mi.send_start, sender_mi.send_start, sender_mi.send_end, sender_mi.recv_start, sender_mi.recv_end, sender_mi.get('latency increase'), sender_mi.packet_size, sender_mi.get('conn min latency'), sent_latency_inflation, latency_ratio, send_ratio, env.links[0].get_bandwidth( env.net.get_cur_time()) * BYTES_PER_PACKET * BITS_PER_BYTE, avg_queue_delay, env.links[0].pkt_in_queue, env.links[0].queue_size, recv_ratio, env.senders[0].estRTT]) reward_list.append(reward) loss_list.append(loss) delay_list.append(latency * 1000) tput_list.append(throughput / 1e6) send_rate_list.append(send_rate / 1e6) ts_list.append(env.net.get_cur_time()) action_list.append(action.item()) mi_list.append(sender_mi.send_end - sender_mi.send_start) obs_list.append(obs.tolist()) obs, rewards, dones, info = env.step(action) if dones: break if f_sim_log: f_sim_log.close() if self.record_pkt_log and save_dir: with open(os.path.join(save_dir, "aurora_packet_log.csv"), 'w', 1) as f: pkt_logger = csv.writer(f, lineterminator='\n') pkt_logger.writerow(['timestamp', 'packet_event_id', 'event_type', 'bytes', 'cur_latency', 'queue_delay', 'packet_in_queue', 'sending_rate', 'bandwidth']) pkt_logger.writerows(env.net.pkt_log) assert env.senders[0].last_ack_ts is not None and env.senders[0].first_ack_ts is not None assert env.senders[0].last_sent_ts is not None and env.senders[0].first_sent_ts is not None avg_sending_rate = env.senders[0].tot_sent / (env.senders[0].last_sent_ts - env.senders[0].first_sent_ts) tput = env.senders[0].tot_acked / (env.senders[0].last_ack_ts - env.senders[0].first_ack_ts) avg_lat = env.senders[0].cur_avg_latency loss = 1 - env.senders[0].tot_acked / env.senders[0].tot_sent pkt_level_reward = pcc_aurora_reward(tput, avg_lat,loss, avg_bw=trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET) pkt_level_original_reward = pcc_aurora_reward(tput, avg_lat, loss) if self.record_pkt_log and plot_flag: pkt_log = PacketLog.from_log(env.net.pkt_log) plot_pkt_log(trace, pkt_log, save_dir, "aurora") if plot_flag and save_dir: plot_simulation_log(trace, os.path.join(save_dir, 'aurora_simulation_log.csv'), save_dir, self.cc_name) bin_tput_ts, bin_tput = env.senders[0].bin_tput bin_sending_rate_ts, bin_sending_rate = env.senders[0].bin_sending_rate lat_ts, lat = env.senders[0].latencies plot(trace, bin_tput_ts, bin_tput, bin_sending_rate_ts, bin_sending_rate, tput * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, avg_sending_rate * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, lat_ts, lat, avg_lat * 1000, loss, pkt_level_original_reward, pkt_level_reward, save_dir, self.cc_name) if save_dir: with open(os.path.join(save_dir, "{}_summary.csv".format(self.cc_name)), 'w', 1) as f: summary_writer = csv.writer(f, lineterminator='\n') summary_writer.writerow([ 'trace_average_bandwidth', 'trace_average_latency', 'average_sending_rate', 'average_throughput', 'average_latency', 'loss_rate', 'mi_level_reward', 'pkt_level_reward']) summary_writer.writerow( [trace.avg_bw, trace.avg_delay, avg_sending_rate * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, tput * BYTES_PER_PACKET * BITS_PER_BYTE / 1e6, avg_lat, loss, np.mean(reward_list), pkt_level_reward]) if saliency: with open(os.path.join(save_dir, "saliency.npy"), 'wb') as f: np.save(f, np.concatenate(grads)) return ts_list, reward_list, loss_list, tput_list, delay_list, send_rate_list, action_list, obs_list, mi_list, pkt_level_reward