Skip to content

Commit

Permalink
Fixes as per latest code review
Browse files Browse the repository at this point in the history
  • Loading branch information
KabirSamsi committed Jul 12, 2024
1 parent 4efc05c commit 8db0b47
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion calyx-py/calyx/nwc_simple_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
max_cmds, len = int(sys.argv[1]), int(sys.argv[2])
keepgoing = "--keepgoing" in sys.argv
queue = queues.NWCSimple(len)
ans = queues.operate_queue(queue, max_cmds, commands, values, ranks, keepgoing=keepgoing, times=times)
ans = queues.operate_queue(queue, max_cmds, commands, values, ranks, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
2 changes: 1 addition & 1 deletion calyx-py/calyx/pcq_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
max_cmds, len = int(sys.argv[1]), int(sys.argv[2])
keepgoing = "--keepgoing" in sys.argv
pcq = queues.PCQ(len)
ans = queues.operate_queue(pcq, max_cmds, commands, values, ranks, keepgoing=keepgoing, times=times)
ans = queues.operate_queue(pcq, max_cmds, commands, values, ranks, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
2 changes: 1 addition & 1 deletion calyx-py/calyx/pieo_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
max_cmds, len = int(sys.argv[1]), int(sys.argv[2])
keepgoing = "--keepgoing" in sys.argv
pieo = queues.Pieo(len)
ans = queues.operate_queue(pieo, max_cmds, commands, values, ranks, keepgoing=keepgoing, times=times)
ans = queues.operate_queue(pieo, max_cmds, commands, values, ranks, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
11 changes: 9 additions & 2 deletions calyx-py/calyx/queue_data_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,14 @@ def dump_json(num_cmds, no_err: bool, queue_size: Optional[int]=None, nwc=False,
3 : pop by value
4 : peek by value
If the `no_err` flag is set and the policy of work-conserving,
If the `no_err` flag is set and the policy is work-conserving,
then items are chosen from 0 and 2 using a helper.
If the `always-true` flag is set to True for non-work-conserving policies,
If the `nwc` is set to False and the policy is set as work-conserving,
then the predicate is treated as though always true.
Otherwise, the user has the option to
- The `values` memory has `num_cmds` items:
random values between 0 and 400.
- The `ranks` memory has `num_cmds` items:
Expand All @@ -100,6 +102,11 @@ def dump_json(num_cmds, no_err: bool, queue_size: Optional[int]=None, nwc=False,
- The `ans_mem` memory has `num_cmds` items, all zeroes.
- Each memory has a `format` field, which is a format object for a bitvector.
"""

#For work-conserving policies, the predicate should be set as though always true
if not nwc:
always_true = True

commands = {
"commands": {
"data": (
Expand Down
27 changes: 19 additions & 8 deletions calyx-py/calyx/queues.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,29 +203,38 @@ def push(self, val, rank=0, time=0) -> None:
if len(self.data) >= self.max_len:
raise QueueError("Overflow")

# Left-shift the rank by 32 and add in the insertion count.
# With every push, we modify the insertion count as to reduce any possible duplicate ranks.

heapq.heappush(self.data, RankValue(((rank << 32) + self.insertion_count), (val, time)))
self.insertion_count += 1

def ripe(self, time) -> bool:
def is_ripe(self, time) -> bool:
return self.data[0].value[1] <= time

def query(self, time=0, val=None, remove=False) -> Optional[int]:
if len(self.data) == 0:
raise QueueError("Underflow")

#Cache popped values from heap while searching for the first eligible one
temp = []

while len(self.data) > 0:
if self.ripe(time) and (val is None or self.data[0].value[0] == val):
#Check for eligibility
if self.is_ripe(time) and (val is None or self.data[0].value[0] == val):

#If eligible, we pop the element and push all cached elements back into the heap
result = heapq.heappop(self.data) if remove else self.data[0]

for elem in temp:
heapq.heappush(self.data, elem)

return result.value[0]

#After each iteration, pop the current element so we can scan down the heap
temp.append(heapq.heappop(self.data))

#If no eligible elements are found, repopulate the data heap with cached elements
for elem in temp:
heapq.heappush(self.data, elem)
raise QueueError("Underflow")
Expand Down Expand Up @@ -292,7 +301,7 @@ def __init__(self, max_len: int):
self.data = []
self.insertion_count = 0

def ripe(self, element, time):
def is_ripe(self, element, time):
"""Check that an element is 'ripe' - i.e. its ready time has passed"""
return element["time"] <= time

Expand Down Expand Up @@ -357,7 +366,7 @@ def query(self, time=0, val=None, remove=False, return_rank=False) -> Optional[i
if val is None:
#Iterate until we find the first 'ripe' (time-ready) element
for x in range(len(self.data)):
if self.ripe(self.data[x], time):
if self.is_ripe(self.data[x], time):
if return_rank:
return self.data.pop(x) if remove else self.data[x]
return self.data.pop(x)["val"] if remove else self.data[x]["val"]
Expand All @@ -367,7 +376,7 @@ def query(self, time=0, val=None, remove=False, return_rank=False) -> Optional[i

#Otherwise, the first element that matches the queried value & is 'ripe'
for x in range(len(self.data)):
if self.data[x]["val"] == val and self.ripe(self.data[x], time):
if self.data[x]["val"] == val and self.is_ripe(self.data[x], time):
if return_rank:
return self.data.pop(x) if remove else self.data[x]
return self.data.pop(x)["val"] if remove else self.data[x]["val"]
Expand Down Expand Up @@ -725,9 +734,11 @@ def __len__(self) -> int:
return self.pifo_len


def operate_queue(queue, max_cmds, commands, values, ranks=None, keepgoing=None, times=None):
"""Given the four lists:
- One of commands, one of values, one of ranks, one of times:
def operate_queue(queue, max_cmds, commands, values, ranks=None, times=None, keepgoing=None):
"""Given the four lists
(One of commands, one of values, one of ranks, one of times):
- Note that `commands` and `values` are required,
while `ranks` and `times` are optional lists depending on the queue type.
- Feed these into our queue, and return the answer memory.
- Commands correspond to:
0 : pop (for non-work-conserving queues, pop by predicate)
Expand Down

0 comments on commit 8db0b47

Please sign in to comment.