Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Round Robin oracle and eDSL #2177

Merged
merged 45 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
fd0d864
add init, push, and pop
Jun 20, 2024
c84e23e
making progress
Jun 21, 2024
102acdc
working progress
Jun 24, 2024
3b42a87
update implementation
Jun 25, 2024
27f6b97
implement RR Queue
Jun 25, 2024
8b97a38
Merge branch 'main' of https://github.com/calyxir/calyx into generali…
Jun 25, 2024
08267f7
tweaked the dump
Jun 25, 2024
8d28373
remove runt stanza, will add back later
Jun 25, 2024
82477a8
Docstring stuff
Jun 25, 2024
3b6cd51
re-upload expect files w/o pretty-printing
Jun 25, 2024
36e2f31
tweak in expect files
Jun 25, 2024
2cd1acf
debug rr_queue.py and add test cases
Jun 26, 2024
6facd8b
move rr_queue files to their own directory
Jun 26, 2024
3e14e77
Merge branch 'main' of https://github.com/calyxir/calyx into generali…
Jun 27, 2024
72172af
tidying up
Jun 27, 2024
b24fffb
delete commented out code
Jun 27, 2024
b722dc5
Whitespace
anshumanmohan Jun 28, 2024
02cd600
Autoformat
anshumanmohan Jun 28, 2024
16caa16
Fix gen_queue script, regen data and expect. Passes runt tests
anshumanmohan Jun 28, 2024
7a98cbd
Bugfix
anshumanmohan Jun 28, 2024
8234be6
Autoformat
anshumanmohan Jun 28, 2024
ad75e07
Tidy eDSL code
anshumanmohan Jun 28, 2024
88ac68f
larger test
Jun 28, 2024
887bd53
add more tests for debugging
Jul 1, 2024
8633672
bug fixes and factoring out code
Jul 1, 2024
871bc93
increase testing
Jul 2, 2024
43a33ae
tweaks
Jul 2, 2024
5a22944
Comments, whitespace, and bring back keepgoing
anshumanmohan Jul 2, 2024
2f4a70e
Some more commentary
anshumanmohan Jul 2, 2024
75f6860
Add failsafe case
anshumanmohan Jul 2, 2024
5ce714f
Factor out more code
anshumanmohan Jul 2, 2024
66e4fc6
Use factored out code bigtime
anshumanmohan Jul 2, 2024
c6c8db0
Bring back numcmds
anshumanmohan Jul 2, 2024
81f002e
A little Python fanciness
anshumanmohan Jul 2, 2024
b9cab55
Turn on well-formedness
anshumanmohan Jul 2, 2024
77c06ec
Rip out stats component
anshumanmohan Jul 2, 2024
c3fbe7e
No need for edge-case logic!
anshumanmohan Jul 2, 2024
7d6c855
Comment
anshumanmohan Jul 2, 2024
a7fcc8e
Simplify peek logic
anshumanmohan Jul 2, 2024
da475f0
TIdy
anshumanmohan Jul 2, 2024
4094f34
Simplify pop logic
anshumanmohan Jul 2, 2024
ab98b8e
Simplify logic using case
anshumanmohan Jul 2, 2024
3b68cc4
Comment
anshumanmohan Jul 2, 2024
a412f04
Merge branch 'main' into generalize_pifo_oracle
anshumanmohan Jul 2, 2024
345ef20
delete strict subdirectory
Jul 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions calyx-py/calyx/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,14 @@ def le_store_in_reg(
cell = self.le(width, cellname, signed)
return self.op_store_in_reg(cell, left, right, cell.name, 1, ans_reg)

def ge_store_in_reg(
self, left, right, ans_reg=None, cellname=None, width=None, signed=False
):
"""Inserts wiring into `self` to perform `reg := left <= right`."""
csziklai marked this conversation as resolved.
Show resolved Hide resolved
width = width or self.try_infer_width(width, left, right)
cell = self.ge(width, cellname, signed)
return self.op_store_in_reg(cell, left, right, cell.name, 1, ans_reg)

def mult_store_in_reg(
self, left, right, ans_reg=None, cellname=None, width=None, signed=False
):
Expand Down
103 changes: 103 additions & 0 deletions calyx-py/calyx/queues.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,109 @@ def __len__(self) -> int:
return self.len


@dataclass
class RRQueue:
"""
This is a version of a PIFO generalized to n flows, with a round robin policy
that is work conserving. Just as with the PIFO, if a flow falls silent, the
remaining flows will take their turns. That flow effectively skips its turn.

Supports the operations `push`, `pop`, and `peek`.
It takes in a list `boundaries` that must be of length `n`, the user can
divide the flows however they like.
csziklai marked this conversation as resolved.
Show resolved Hide resolved

- Push works analagously to that of the PIFO, except it checks the `boundaries`
list to determine which flow to push to.
- Pop first tries to pop from `hot`, given the length is not 0. If this fails,
csziklai marked this conversation as resolved.
Show resolved Hide resolved
it continues to check all flows after. It then increments hot at the end and
decreases the length.
- Peek works the same as `pop`, except `hot` remains unchanged.
csziklai marked this conversation as resolved.
Show resolved Hide resolved
"""

def __init__(self, n, boundaries, max_len: int):
self.data = []
self.hot = 0
self.n_flows = n
self.pifo_len = 0
self.boundaries = boundaries
for i in range(n):
queue = Fifo(max_len)
self.data.append(queue)

self.max_len = max_len
assert (
self.pifo_len <= self.max_len
) # We can't be initialized with a PIFO that is too long.


def push(self, val: int):
"""Pushes `val` to the PIFO."""
if self.pifo_len == self.max_len:
raise QueueError("Cannot push to full PIFO.")
for b in range(len(self.boundaries)):
csziklai marked this conversation as resolved.
Show resolved Hide resolved
if val <= self.boundaries[b]:
self.data[b].push(val)
self.pifo_len += 1
break


def increment_hot(self):
csziklai marked this conversation as resolved.
Show resolved Hide resolved
"""Increments hot, taking into account wrap around."""
if self.hot == (self.n_flows - 1): # handle wrap around when updating hot
self.hot = 0
else:
self.hot = self.hot + 1


def pop(self) -> Optional[int]:
"""Pops the PIFO. Updates `hot`."""
if self.pifo_len == 0:
raise QueueError("Cannot pop from empty PIFO.")

original_hot = self.hot

while True:
try:
val = self.data[self.hot].pop()
if val is not None:
self.increment_hot()
self.pifo_len -= 1
return val
else:
self.increment_hot()
if self.hot == original_hot:
csziklai marked this conversation as resolved.
Show resolved Hide resolved
return None
except QueueError:
self.increment_hot()
if self.hot == original_hot:
csziklai marked this conversation as resolved.
Show resolved Hide resolved
return None


def peek(self) -> Optional[int]:
"""Peeks into the PIFO. Does not affect what `hot` is."""
if self.pifo_len == 0:
raise QueueError("Cannot peek into empty PIFO.")

original_hot = self.hot
while True:
try:
val = self.data[self.hot].peek()
if val is not None:
self.hot = original_hot
return val
else:
self.increment_hot()
if self.hot == original_hot:
return None
except QueueError:
self.increment_hot()
if self.hot == original_hot:
return None
csziklai marked this conversation as resolved.
Show resolved Hide resolved


def __len__(self) -> int:
return self.pifo_len

def operate_queue(queue, max_cmds, commands, values, ranks=None, keepgoing=False):
"""Given the two lists, one of commands and one of values.
Feed these into our queue, and return the answer memory.
Expand Down
18 changes: 18 additions & 0 deletions calyx-py/calyx/rrqueue_oracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# For usage, see gen_queue_data_expect.sh
import sys
import calyx.queues as queues
from calyx import queue_util

if __name__ == "__main__":
max_cmds, len = int(sys.argv[1]), int(sys.argv[2])
keepgoing = "--keepgoing" in sys.argv
commands, values, _ = queue_util.parse_json()

# Our Round Robin Queue (formerly known as generalized pifo) is simple: it
# just orchestrates n FIFOs, in this case 3. It takes in a list of
# boundaries of length n (in this case 3).
pifo = queues.RRQueue(3, [133, 266, 400], len)

ans = queues.operate_queue(pifo, max_cmds, commands, values, keepgoing=keepgoing)

queue_util.dump_json(ans, commands, values)
89 changes: 89 additions & 0 deletions calyx-py/test/correctness/queues/rr_queues/rr_queue.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{
"commands": {
"data": [
2,
2,
2,
1,
0,
0,
1,
0,
2,
2,
0,
0,
1,
2,
1,
2,
2,
2,
0,
1
],
"format": {
"is_signed": false,
"numeric_type": "bitnum",
"width": 2
}
},
"values": {
"data": [
52,
293,
127,
6,
374,
110,
208,
143,
93,
392,
199,
81,
390,
36,
71,
316,
316,
227,
64,
67
],
"format": {
"is_signed": false,
"numeric_type": "bitnum",
"width": 32
}
},
"ans_mem": {
"data": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"format": {
"is_signed": false,
"numeric_type": "bitnum",
"width": 32
}
}
}
68 changes: 68 additions & 0 deletions calyx-py/test/correctness/queues/rr_queues/rr_queue.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"ans_mem": [
52,
52,
293,
127,
127,
392,
93,
36,
316,
36,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"commands": [
2,
2,
2,
1,
0,
0,
1,
0,
2,
2,
0,
0,
1,
2,
1,
2,
2,
2,
0,
1
],
"values": [
52,
293,
127,
6,
374,
110,
208,
143,
93,
392,
199,
81,
390,
36,
71,
316,
316,
227,
64,
67
]
}
Loading
Loading