Beispiel #1
0
 def get_reward(self, trace_file: str, trace=None) -> float:
     if trace_file and trace_file.endswith('.json'):
         trace = Trace.load_from_file(trace_file)
     elif trace_file and trace_file.endswith('.log'):
         trace = Trace.load_from_pantheon_file(trace_file, 0, 50, 500)
     loss = self.get_loss_rate()
     if trace is None:
         # original reward
         return pcc_aurora_reward(
             self.get_avg_throughput() * 1e6 / BITS_PER_BYTE /
             BYTES_PER_PACKET,
             self.get_avg_latency() / 1e3, loss)
     # normalized reward
     return pcc_aurora_reward(
         self.get_avg_throughput() * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET,
         self.get_avg_latency() / 1e3, loss,
         trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET,
         trace.min_delay * 2 / 1e3)
Beispiel #2
0
 def reward(self, avg_bw=None):
     if avg_bw is None:
         avg_bw = np.mean([
             val for ts, val in zip(self.datalink.link_capacity_timestamps,
                                    self.datalink.link_capacity)
             if ts >= min(self.datalink.throughput_timestamps[0],
                          self.datalink.sending_rate_timestamps[0])
         ])
     reward = pcc_aurora_reward(
         self.datalink.avg_throughput / avg_bw,  # * 1e6 / 8 / 1500,
         (np.mean(self.datalink.one_way_delay) +
          np.mean(self.acklink.one_way_delay)) / 1000,
         self.datalink.loss_rate)
     return reward
Beispiel #3
0
    def on_mi_finish(self) -> Tuple[float, float]:
        self.record_run()

        sender_mi = self.history.back()  # get_run_data()
        throughput = sender_mi.get("recv rate")  # bits/sec
        latency = sender_mi.get("avg latency")  # second
        loss = sender_mi.get("loss ratio")
        reward = pcc_aurora_reward(
            throughput / BITS_PER_BYTE / BYTES_PER_PACKET, latency, loss,
            self.trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET,
            self.trace.avg_delay * 2 / 1e3)

        if latency > 0.0:
            mi_duration = MI_RTT_PROPORTION * \
                sender_mi.get("avg latency") + np.mean(self.net.extra_delays)
        else:
            mi_duration = 0
        return reward, mi_duration
Beispiel #4
0
    def on_mi_finish(self) -> Tuple[float, float]:
        self.record_run()

        sender_mi = self.history.back()  # get_run_data()
        throughput = sender_mi.get("recv rate")  # bits/sec
        latency = sender_mi.get("avg latency")  # second
        loss = sender_mi.get("loss ratio")
        reward = pcc_aurora_reward(
            throughput / BITS_PER_BYTE / BYTES_PER_PACKET, latency, loss,
            self.trace.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET,
            self.trace.avg_delay * 2 / 1e3)

        if latency > 0.0:
            self.mi_duration = MI_RTT_PROPORTION * \
                sender_mi.get("avg latency") # + np.mean(extra_delays)
        self.btlbw_filter.update(throughput, self.round_count)
        min_lat = sender_mi.get("conn min latency")
        btlbw = self.btlbw_filter.get_btlbw()
        self.cwnd = max(2 * round(btlbw * self.min_latency / BITS_PER_BYTE / BYTES_PER_PACKET), MIN_CWND * 2)
        return reward, self.mi_duration
Beispiel #5
0
    def run_for_dur(self, dur, action=None):
        if self.senders[0].lat_diff != 0:
            self.senders[0].start_stage = False
        start_time = self.cur_time
        end_time = min(self.cur_time + dur,
                       self.env.current_trace.timestamps[-1])
        # debug_print('MI from {} to {}, dur {}'.format(
        #     self.cur_time, end_time, dur))
        for sender in self.senders:
            sender.reset_obs()
        # set_obs_start = False
        extra_delays = []  # time used to put packet onto the network
        while True:
            event_time, sender, event_type, next_hop, cur_latency, dropped, \
                event_id, rto, event_queue_delay = self.q[0]
            # if not sender.got_data and event_time >= end_time and event_type == EVENT_TYPE_ACK and next_hop == len(sender.path):
            #     end_time = event_time
            #     self.cur_time = end_time
            #     self.env.run_dur = end_time - start_time
            #     break
            if sender.got_data and event_time >= end_time and event_type == EVENT_TYPE_SEND:
                end_time = event_time
                self.cur_time = end_time
                break
            event_time, sender, event_type, next_hop, cur_latency, dropped, \
                event_id, rto, event_queue_delay = heapq.heappop(self.q)
            self.cur_time = event_time
            new_event_time = event_time
            new_event_type = event_type
            new_next_hop = next_hop
            new_latency = cur_latency
            new_dropped = dropped
            new_event_queue_delay = event_queue_delay
            push_new_event = False
            # debug_print("Got %d event %s, to link %d, latency %f at time %f, "
            #             "next_hop %d, dropped %s, event_q length %f, "
            #             "sender rate %f, duration: %f, queue_size: %f, "
            #             "rto: %f, cwnd: %f, ssthresh: %f, sender rto %f, "
            #             "pkt in flight %d, wait time %d" % (
            #                 event_id, event_type, next_hop, cur_latency,
            #                 event_time, next_hop, dropped, len(self.q),
            #                 sender.rate, dur, self.links[0].queue_size,
            #                 rto, sender.cwnd, sender.ssthresh, sender.rto,
            #                 int(sender.bytes_in_flight/BYTES_PER_PACKET),
            #                 sender.pkt_loss_wait_time))
            if event_type == EVENT_TYPE_ACK:
                if next_hop == len(sender.path):
                    # if cur_latency > 1.0:
                    #     sender.timeout(cur_latency)
                    # sender.on_packet_lost(cur_latency)
                    if rto >= 0 and cur_latency > rto and sender.pkt_loss_wait_time <= 0:
                        sender.timeout()
                        dropped = True
                        new_dropped = True
                    elif dropped:
                        sender.on_packet_lost(cur_latency)
                        if self.env.record_pkt_log:
                            self.pkt_log.append([
                                self.cur_time, event_id, 'lost',
                                BYTES_PER_PACKET, cur_latency,
                                event_queue_delay, self.links[0].pkt_in_queue,
                                sender.rate * BYTES_PER_PACKET * BITS_PER_BYTE,
                                self.links[0].get_bandwidth(self.cur_time) *
                                BYTES_PER_PACKET * BITS_PER_BYTE
                            ])
                    else:
                        sender.on_packet_acked(cur_latency)
                        # debug_print('Ack packet at {}'.format(self.cur_time))
                        # log packet acked
                        if self.env.record_pkt_log:
                            self.pkt_log.append([
                                self.cur_time, event_id, 'acked',
                                BYTES_PER_PACKET, cur_latency,
                                event_queue_delay, self.links[0].pkt_in_queue,
                                sender.rate * BYTES_PER_PACKET * BITS_PER_BYTE,
                                self.links[0].get_bandwidth(self.cur_time) *
                                BYTES_PER_PACKET * BITS_PER_BYTE
                            ])
                else:
                    # comment out to save disk usage
                    # if self.env.record_pkt_log:
                    #     self.pkt_log.append(
                    #         [self.cur_time, event_id, 'arrived',
                    #          BYTES_PER_PACKET, cur_latency, event_queue_delay,
                    #          self.links[0].pkt_in_queue,
                    #          sender.rate * BYTES_PER_PACKET * BITS_PER_BYTE,
                    #          self.links[0].get_bandwidth(self.cur_time) * BYTES_PER_PACKET * BITS_PER_BYTE])
                    new_next_hop = next_hop + 1
                    # new_event_queue_delay += sender.path[next_hop].get_cur_queue_delay(
                    #     self.cur_time)
                    link_latency = sender.path[
                        next_hop].get_cur_propagation_latency(self.cur_time)
                    # link_latency *= self.env.current_trace.get_delay_noise_replay(self.cur_time)
                    # if USE_LATENCY_NOISE:
                    # link_latency *= random.uniform(1.0, MAX_LATENCY_NOISE)
                    new_latency += link_latency
                    new_event_time += link_latency
                    push_new_event = True
            elif event_type == EVENT_TYPE_SEND:
                if next_hop == 0:
                    if sender.can_send_packet():
                        sender.on_packet_sent()
                        # print('Send packet at {}'.format(self.cur_time))
                        if not self.env.train_flag and self.env.record_pkt_log:
                            self.pkt_log.append([
                                self.cur_time, event_id, 'sent',
                                BYTES_PER_PACKET, cur_latency,
                                event_queue_delay, self.links[0].pkt_in_queue,
                                sender.rate * BYTES_PER_PACKET * BITS_PER_BYTE,
                                self.links[0].get_bandwidth(self.cur_time) *
                                BYTES_PER_PACKET * BITS_PER_BYTE
                            ])
                        push_new_event = True
                    heapq.heappush(self.q,
                                   (self.cur_time + (1.0 / sender.rate),
                                    sender, EVENT_TYPE_SEND, 0, 0.0, False,
                                    self.event_count, sender.rto, 0))
                    self.event_count += 1

                else:
                    push_new_event = True

                if next_hop == sender.dest:
                    new_event_type = EVENT_TYPE_ACK
                new_next_hop = next_hop + 1

                prop_delay, new_event_queue_delay = sender.path[
                    next_hop].get_cur_latency(self.cur_time)
                link_latency = prop_delay + new_event_queue_delay
                # if USE_LATENCY_NOISE:
                # link_latency *= random.uniform(1.0, MAX_LATENCY_NOISE)
                # link_latency += self.env.current_trace.get_delay_noise(
                #     self.cur_time, self.links[0].get_bandwidth(self.cur_time)) / 1000
                # link_latency += max(0, np.random.normal(0, 1) / 1000)
                # link_latency += max(0, np.random.uniform(0, 5) / 1000)
                rand = random.uniform(0, 1)
                if rand > 0.9:
                    noise = random.uniform(
                        0, sender.path[next_hop].trace.delay_noise) / 1000
                else:
                    noise = 0
                new_latency += noise
                new_event_time += noise
                # link_latency *= self.env.current_trace.get_delay_noise_replay(self.cur_time)
                new_latency += link_latency
                new_event_time += link_latency
                new_dropped = not sender.path[next_hop].packet_enters_link(
                    self.cur_time)
                extra_delays.append(1 /
                                    self.links[0].get_bandwidth(self.cur_time))
                # new_latency += 1 / self.links[0].get_bandwidth(self.cur_time)
                # new_event_time += 1 / self.links[0].get_bandwidth(self.cur_time)
                if not new_dropped:
                    sender.queue_delay_samples.append(new_event_queue_delay)

            if push_new_event:
                heapq.heappush(self.q, (new_event_time, sender, new_event_type,
                                        new_next_hop, new_latency, new_dropped,
                                        event_id, rto, new_event_queue_delay))
        for sender in self.senders:
            sender.record_run()

        sender_mi = self.senders[0].history.back()  #get_run_data()
        throughput = sender_mi.get("recv rate")  # bits/sec
        latency = sender_mi.get("avg latency")  # second
        loss = sender_mi.get("loss ratio")
        # debug_print("thpt %f, delay %f, loss %f, bytes sent %f, bytes acked %f" % (
        #     throughput/1e6, latency, loss, sender_mi.bytes_sent, sender_mi.bytes_acked))
        avg_bw_in_mi = self.env.current_trace.get_avail_bits2send(
            start_time, end_time) / (
                end_time - start_time) / BITS_PER_BYTE / BYTES_PER_PACKET
        # avg_bw_in_mi = np.mean(self.env.current_trace.bandwidths) * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET
        reward = pcc_aurora_reward(
            throughput / BITS_PER_BYTE / BYTES_PER_PACKET, latency, loss,
            avg_bw_in_mi,
            np.mean(self.env.current_trace.delays) * 2 / 1e3)

        # self.env.run_dur = MI_RTT_PROPORTION * self.senders[0].estRTT # + np.mean(extra_delays)
        if latency > 0.0:
            self.env.run_dur = MI_RTT_PROPORTION * \
                sender_mi.get("avg latency") + np.mean(np.array(extra_delays))
        # elif self.env.run_dur != 0.01:
        # assert self.env.run_dur >= 0.03
        # self.env.run_dur = max(MI_RTT_PROPORTION * sender_mi.get("avg latency"), 5 * (1 / self.senders[0].rate))

        # self.senders[0].avg_latency = sender_mi.get("avg latency")  # second
        # self.senders[0].recv_rate = round(sender_mi.get("recv rate"), 3)  # bits/sec
        # self.senders[0].send_rate = round(sender_mi.get("send rate"), 3)  # bits/sec
        # self.senders[0].lat_diff = sender_mi.rtt_samples[-1] - sender_mi.rtt_samples[0]
        # self.senders[0].latest_rtt = sender_mi.rtt_samples[-1]
        # self.recv_rate_cache.append(self.senders[0].recv_rate)
        # if len(self.recv_rate_cache) > 6:
        #     self.recv_rate_cache = self.recv_rate_cache[1:]
        # self.senders[0].max_tput = max(self.recv_rate_cache)
        #
        # if self.senders[0].lat_diff == 0 and self.senders[0].start_stage:  # no latency change
        #     pass
        #     # self.senders[0].max_tput = max(self.senders[0].recv_rate, self.senders[0].max_tput)
        # elif self.senders[0].lat_diff == 0 and not self.senders[0].start_stage:  # no latency change
        #     pass
        #     # self.senders[0].max_tput = max(self.senders[0].recv_rate, self.senders[0].max_tput)
        # elif self.senders[0].lat_diff > 0:  # latency increase
        #     self.senders[0].start_stage = False
        #     # self.senders[0].max_tput = self.senders[0].recv_rate # , self.max_tput)
        # else:  # latency decrease
        #     self.senders[0].start_stage = False
        #     # self.senders[0].max_tput = max(self.senders[0].recv_rate, self.senders[0].max_tput)
        return reward  # * REWARD_SCALE
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
def plot(trace: Union[Trace, None], log_file: str, save_dir: str, cc: str):
    df = pd.read_csv(log_file)
    assert isinstance(df, pd.DataFrame)
    fig, axes = plt.subplots(6, 1, figsize=(12, 10))
    axes[0].set_title(cc)
    axes[0].plot(df['timestamp'],
                 df['recv_rate'] / 1e6,
                 'o-',
                 ms=2,
                 label='throughput, avg {:.3f}mbps'.format(
                     df['recv_rate'].mean() / 1e6))
    axes[0].plot(df['timestamp'],
                 df['send_rate'] / 1e6,
                 'o-',
                 ms=2,
                 label='send rate, avg {:.3f}mbps'.format(
                     df['send_rate'].mean() / 1e6))

    if trace:
        avg_bw = trace.avg_bw
        min_rtt = trace.min_delay * 2 / 1e3
        axes[0].plot(trace.timestamps,
                     trace.bandwidths,
                     'o-',
                     ms=2,
                     drawstyle='steps-post',
                     label='bw, avg {:.3f}mbps'.format(avg_bw))
    else:
        axes[0].plot(df['timestamp'],
                     df['bandwidth'] / 1e6,
                     label='bw, avg {:.3f}mbps'.format(df['bandwidth'].mean() /
                                                       1e6))
        avg_bw = df['bandwidth'].mean() / 1e6
        min_rtt = None
    axes[0].set_xlabel("Time(s)")
    axes[0].set_ylabel("mbps")
    axes[0].legend(loc='right')
    axes[0].set_ylim(0, )
    axes[0].set_xlim(0, )

    axes[1].plot(df['timestamp'],
                 df['latency'] * 1000,
                 label='RTT avg {:.3f}ms'.format(df['latency'].mean() * 1000))
    axes[1].set_xlabel("Time(s)")
    axes[1].set_ylabel("Latency(ms)")
    axes[1].legend(loc='right')
    axes[1].set_xlim(0, )
    axes[1].set_ylim(0, )

    axes[2].plot(df['timestamp'],
                 df['loss'],
                 label='loss avg {:.3f}'.format(df['loss'].mean()))
    axes[2].set_xlabel("Time(s)")
    axes[2].set_ylabel("loss")
    axes[2].legend()
    axes[2].set_xlim(0, )
    axes[2].set_ylim(0, 1)

    avg_reward_mi = pcc_aurora_reward(
        df['recv_rate'].mean() / BITS_PER_BYTE / BYTES_PER_PACKET,
        df['latency'].mean(), df['loss'].mean(),
        avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET, min_rtt)

    axes[3].plot(df['timestamp'],
                 df['reward'],
                 label='rewards avg {:.3f}'.format(avg_reward_mi))
    axes[3].set_xlabel("Time(s)")
    axes[3].set_ylabel("Reward")
    axes[3].legend()
    axes[3].set_xlim(0, )
    # axes[3].set_ylim(, )

    axes[4].plot(df['timestamp'],
                 df['action'] * 1.0,
                 label='delta avg {:.3f}'.format(df['action'].mean()))
    axes[4].set_xlabel("Time(s)")
    axes[4].set_ylabel("delta")
    axes[4].legend()
    axes[4].set_xlim(0, )

    axes[5].plot(df['timestamp'],
                 df['packet_in_queue'] / df['queue_size'],
                 label='Queue Occupancy')
    axes[5].set_xlabel("Time(s)")
    axes[5].set_ylabel("Queue occupancy")
    axes[5].legend()
    axes[5].set_xlim(0, )
    axes[5].set_ylim(0, 1)

    # axes[5].plot(df['timestamp'], df['cwnd'], label='cwnd')
    # axes[5].plot(df['timestamp'], df['ssthresh'], label='ssthresh')
    # axes[5].set_xlabel("Time(s)")
    # axes[5].set_ylabel("# packets")
    # axes[5].set_ylim(0, df['cwnd'].max())
    # axes[5].legend()
    # axes[5].set_xlim(0, )
    plt.tight_layout()
    if save_dir is not None:
        fig.savefig(os.path.join(save_dir, "{}_time_series.jpg".format(cc)))
    plt.close()
Beispiel #9
0
 def optimal_reward(self):
     return pcc_aurora_reward(
         self.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET,
         self.avg_delay * 2 / 1000, self.loss_rate,
         self.avg_bw * 1e6 / BITS_PER_BYTE / BYTES_PER_PACKET)