TL-System/ns.py

Bug For SP scheduler

JinJinGuang opened this issue · 1 comments

Describe the bug
Hello, I analyze the sp.py, and find a mismatch for different formats of priority, which may result in some bugs.

The input priorities is a list or a dict, with the following comment:

This can be either a list or a dictionary. If it is a list, it uses the flow_id
as its index to look for the flow's corresponding priority. If it is a dictionary,
it contains (flow_id -> priority) pairs for each possible flow_id.

But self.prio_queue_count has a different map:

if isinstance(priorities, list):
    self.prio_queue_count = [0 for __ in range(len(priorities))] # flow_id -> count
elif isinstance(priorities, dict):
    self.prio_queue_count = {prio: 0 for prio in priorities.values()} # priority -> count
else:
    raise ValueError(
        'Priorities must be either a list or a dictionary.')

Specifically, if priorities is a list, self.prio_queue_count will map flow_id to count. Otherwise, self.prio_queue_count will map the priority of the flow_id to count.

To Reproduce
You can run the following code and see a bug:

import numpy as np
import simpy
from ns.packet.dist_generator import DistPacketGenerator
from ns.packet.sink import PacketSink
from ns.scheduler.sp import SPServer

np.random.seed(42)

def arrival_1():
    """ Packets arrive with a constant interval of 1.5 seconds. """
    return 1.5


def arrival_2():
    """ Packets arrive with a constant interval of 2.0 seconds. """
    return 2.0

def packet_size():
    return int(np.random.exponential(100))

DEBUG = True

env = simpy.Environment()
sp = SPServer(env, 100, [1,100], debug=DEBUG) # line[1]
# sp = SPServer(env, 100, {0:10, 1:1}, debug=DEBUG) # line[2]
# sp = SPServer(env, 100, {0:1, 1:10}, debug=DEBUG) # line[3]
ps = PacketSink(env, rec_flow_ids=False, debug=DEBUG)

pg1 = DistPacketGenerator(env, "flow_1", arrival_1, packet_size, flow_id=0)
pg2 = DistPacketGenerator(env, "flow_2", arrival_2, packet_size, flow_id=1)

pg1.out = sp
pg2.out = sp
sp.out = ps

env.run(until=20)

The error:

Time 1.5, flow_id 0, packet_id 1
Sent out packet 1 of priority 1
Traceback (most recent call last):
  File "D:\anaconda3\lib\site-packages\ns\packet\dist_generator.py", line 80, in run
    self.out.put(packet)
  File "D:\anaconda3\lib\site-packages\ns\scheduler\sp.py", line 179, in put
    self.prio_queue_count[prio] += 1
IndexError: list index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "e:\Study\2021-summer\ns.py\examples\sp.py", line 36, in <module>
    env.run(until=20)
  File "D:\anaconda3\lib\site-packages\simpy\core.py", line 254, in run
    self.step()
  File "D:\anaconda3\lib\site-packages\simpy\core.py", line 206, in step
    raise exc
IndexError: list index out of range

Confusion
Moreover, I also want to know whether a larger number will result in a higher priority or a lower priority. Because, for the above test code, line[2] and line[3] act as the same: flow_0 has a high priority in both codes, regardless of the priority value.

In the latest release (0.2.0) that should have fixed this issue, higher priority values imply higher priorities (which is the intuition).