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

Queues: Test Oracles for PIEOs and PCQs #2192

Merged
merged 67 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
9f73802
Initial Python PIEO implementation
KabirSamsi Jun 18, 2024
a9cfdaa
Full PIEO test oracle implementation, interface design for Calendar Q…
KabirSamsi Jun 20, 2024
e8f80ca
Cleanup of queue testing
KabirSamsi Jun 20, 2024
97ee3d7
Update calendar queue functionality
KabirSamsi Jun 20, 2024
ee50170
Merge branch 'main' into queues-extend
KabirSamsi Jun 20, 2024
c876469
Initial PCQ implementation
KabirSamsi Jun 20, 2024
769847e
Cleanup
KabirSamsi Jun 20, 2024
ecad28c
Queues: full test oracle for PIEOs, PCQs
KabirSamsi Jun 25, 2024
22badf6
Fixed PCQ and PIEO oracles
KabirSamsi Jun 25, 2024
1a98bad
Setup datagen for PIFO and PIEO
KabirSamsi Jun 25, 2024
31a3c5e
Fixed expect files
KabirSamsi Jun 25, 2024
121739a
Fixed infinite loop bug in PCQ rotation
KabirSamsi Jun 25, 2024
233a642
Fixed keepgoing flag
KabirSamsi Jun 26, 2024
7918ca7
Fixed original queue .expect files
KabirSamsi Jun 26, 2024
f9719b9
Fixed max_cmds setting for PIEOs, PCQs
KabirSamsi Jun 26, 2024
04d3e8d
Debugged and completed PIEO Test Oracle
KabirSamsi Jun 27, 2024
bf21a8f
Resolved old queue expect files
KabirSamsi Jun 27, 2024
59fdfaf
Reset build
KabirSamsi Jun 27, 2024
1df3de1
Fixed PCQ implementation
KabirSamsi Jun 28, 2024
42fb0c0
Further fixes to PCQ implementation – pushing and popping works well,…
KabirSamsi Jul 1, 2024
b00344e
Further corrections to PIEO and PCQ oracles
KabirSamsi Jul 1, 2024
d84082a
Some fixes
KabirSamsi Jul 1, 2024
870303a
Fifo reversal
KabirSamsi Jul 1, 2024
2764e0a
Fixed changes with old .expect files
KabirSamsi Jul 2, 2024
0f48f6d
Removed unnecessary .expect file, further documentation for bash script
KabirSamsi Jul 2, 2024
75707f4
Further fixes to PCQ oracle
KabirSamsi Jul 2, 2024
9b47ac6
Initiated FIFO rank order to break ties, full PCQ fix
KabirSamsi Jul 2, 2024
04a05e3
Merge branch 'main' into queues-extend
KabirSamsi Jul 3, 2024
4525ace
Resolved merge conflicts between main and queues-extend
KabirSamsi Jul 3, 2024
f4380ec
Resolved merge conflicts between main and queues-extend
KabirSamsi Jul 3, 2024
a2a647a
More merge fixes
KabirSamsi Jul 3, 2024
7b468b5
Documentation, refactoring, removal of unnecessary arguments
KabirSamsi Jul 3, 2024
f16cc3b
Implemented simpler general NWC queue oracle
KabirSamsi Jul 8, 2024
81373d5
Reverted to older queue implementation
KabirSamsi Jul 8, 2024
669eb03
More queues fixes
KabirSamsi Jul 9, 2024
376bb8b
More queues fixes
KabirSamsi Jul 9, 2024
5fd89fd
Introduced NWC general-purpose oracle, fixed binheap/RR expect files
KabirSamsi Jul 9, 2024
124d752
Removed files
KabirSamsi Jul 9, 2024
9e78419
Merge branch 'main' into queues-extend
KabirSamsi Jul 9, 2024
4d98402
Merged main into queues-extend
KabirSamsi Jul 9, 2024
3769a15
Removed obsolete pre-merge files
KabirSamsi Jul 9, 2024
8e2890b
File cleanup
KabirSamsi Jul 9, 2024
e51dbe3
Fixed NWC general-purpose oracle
KabirSamsi Jul 9, 2024
4f7afb0
Fixed file naming conventions
KabirSamsi Jul 9, 2024
5a11e3c
Merge branch 'main' into queues-extend
KabirSamsi Jul 10, 2024
cf92c1e
Reverted queues.py for test compiler checks
KabirSamsi Jul 10, 2024
d93d65c
More test compiler fixes
KabirSamsi Jul 10, 2024
d4e5ec5
More test compiler fixes
KabirSamsi Jul 10, 2024
159d80f
Fixing modifications
KabirSamsi Jul 10, 2024
3e0b921
Adding more back in
KabirSamsi Jul 10, 2024
e09885f
Temporarily removed all heap-related files
KabirSamsi Jul 10, 2024
49524f1
More file removal for testing
KabirSamsi Jul 10, 2024
363f518
Adding stable heap back in
KabirSamsi Jul 10, 2024
8a42af6
Testing veracity of round robin and strict queues
KabirSamsi Jul 10, 2024
adebc8a
Removing RR/Strict and adding back bhp pifos and pifo trees
KabirSamsi Jul 10, 2024
64d3338
Some stable binheap fixes
KabirSamsi Jul 10, 2024
c26fc3f
Re-adding strict and rr files
KabirSamsi Jul 10, 2024
bb704bd
Removed some strict queue files
KabirSamsi Jul 10, 2024
641736f
More file reversal fixes
KabirSamsi Jul 10, 2024
68e9298
Added back binheap files
KabirSamsi Jul 10, 2024
8dcc862
Update binheap.expect
KabirSamsi Jul 10, 2024
4efc05c
Update binheap.data
KabirSamsi Jul 10, 2024
8db0b47
Fixes as per latest code review
KabirSamsi Jul 12, 2024
ec33056
Typo fix
KabirSamsi Jul 12, 2024
76e5e02
Removed always-true flag
KabirSamsi Jul 15, 2024
9c78901
Reset commit
KabirSamsi Jul 15, 2024
9c7f547
Merge branch 'main' into queues-extend
KabirSamsi Jul 15, 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,6 @@ tools/profiler/tmp/
tools/profiler/logs

temp/

# for running a venv
.venv
4 changes: 2 additions & 2 deletions calyx-py/calyx/binheap_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
if __name__ == "__main__":
max_cmds, len = int(sys.argv[1]), int(sys.argv[2])
keepgoing = "--keepgoing" in sys.argv
commands, values, ranks = queue_util.parse_json()
commands, values, ranks, _ = queue_util.parse_json(True)
binheap = queues.Binheap(len)
ans = queues.operate_queue(binheap, max_cmds, commands, values, ranks=ranks, keepgoing=keepgoing)
queue_util.dump_json(ans, commands, values, ranks=ranks)
queue_util.dump_json(commands, values, ans, ranks=ranks)
4 changes: 2 additions & 2 deletions calyx-py/calyx/fifo_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
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()
commands, values, _, _ = queue_util.parse_json()
fifo = queues.Fifo(len)
ans = queues.operate_queue(fifo, max_cmds, commands, values, keepgoing=keepgoing)
queue_util.dump_json(ans, commands, values)
queue_util.dump_json(commands, values, ans)
19 changes: 14 additions & 5 deletions calyx-py/calyx/gen_queue_data_expect.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ for queue_kind in fifo pifo pifo_tree; do
[[ "$queue_kind" != "pifo_tree" ]] && cp ../test/correctness/queues/$queue_kind.expect ../test/correctness/queues/binheap/$queue_kind.expect
done

# Here, we test the queues for non-work-conserving algorithms,
# which are the following:
# - pieo_oracle.py
# - pcq_oracle.py

for queue_kind in pieo pcq nwc_simple; do
python3 queue_data_gen.py $num_cmds --nwc-en > ../test/correctness/queues/$queue_kind.data
cat ../test/correctness/queues/$queue_kind.data | python3 ${queue_kind}_oracle.py $num_cmds $queue_size --keepgoing > ../test/correctness/queues/$queue_kind.expect
done

# For the Binary Heap, we drop piezo mode and enable ranks for data gen and
# use binheap_oracle to generate the expected output
Expand All @@ -31,15 +40,15 @@ cat ../test/correctness/queues/binheap/stable_binheap.data | python3 binheap_ora
# generate the expected output for queues with 2..7 flows. This generates 6 data expect file pairs.

for n in {2..7}; do
python3 queue_data_gen.py $num_cmds > ../test/correctness/queues/rr_queues/rr_queue_${n}flows.data
cat ../test/correctness/queues/rr_queues/rr_queue_${n}flows.data | python3 rrqueue_oracle.py $num_cmds $queue_size $n --keepgoing > ../test/correctness/queues/rr_queues/rr_queue_${n}flows.expect
python3 queue_data_gen.py $num_cmds > ../test/correctness/queues/strict_and_rr_queues/rr_queues/rr_queue_${n}flows.data
cat ../test/correctness/queues/strict_and_rr_queues/rr_queues/rr_queue_${n}flows.data | python3 rr_queue_oracle.py $num_cmds $queue_size $n --keepgoing > ../test/correctness/queues/strict_and_rr_queues/rr_queues/rr_queue_${n}flows.expect
done

# For Strict queues, we use strict_queue_oracle.py to generate the expected output
# for queues with 2..6 flows, each with a different strict ordering. This generates 5
# expect file pairs.

for n in {2..6}; do
python3 queue_data_gen.py $num_cmds > ../test/correctness/queues/strict_queues/strict_${n}flows.data
cat ../test/correctness/queues/strict_queues/strict_${n}flows.data | python3 strict_queue_oracle.py $num_cmds $queue_size $n --keepgoing > ../test/correctness/queues/strict_queues/strict_${n}flows.expect
done
python3 queue_data_gen.py $num_cmds > ../test/correctness/queues/strict_and_rr_queues/strict_queues/strict_${n}flows.data
cat ../test/correctness/queues/strict_and_rr_queues/strict_queues/strict_${n}flows.data | python3 strict_queue_oracle.py $num_cmds $queue_size $n --keepgoing > ../test/correctness/queues/strict_and_rr_queues/strict_queues/strict_${n}flows.expect
done
11 changes: 11 additions & 0 deletions calyx-py/calyx/nwc_simple_oracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys
import calyx.queues as queues
from calyx import queue_util

if __name__ == "__main__":
commands, values, ranks, times = queue_util.parse_json(True, True)
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, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
11 changes: 11 additions & 0 deletions calyx-py/calyx/pcq_oracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys
import calyx.queues as queues
from calyx import queue_util

if __name__ == "__main__":
commands, values, ranks, times = queue_util.parse_json(True, True)
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, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
11 changes: 11 additions & 0 deletions calyx-py/calyx/pieo_oracle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys
import calyx.queues as queues
from calyx import queue_util

if __name__ == "__main__":
commands, values, ranks, times = queue_util.parse_json(True, True)
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, times=times, keepgoing=keepgoing)
queue_util.dump_json(commands, values, ans, ranks, times)
4 changes: 2 additions & 2 deletions calyx-py/calyx/pifo_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
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()
commands, values, _, _ = queue_util.parse_json()

# Our PIFO is simple: it just orchestrates two FIFOs. The boundary is 200.
pifo = queues.Pifo(queues.Fifo(len), queues.Fifo(len), 200, len)

ans = queues.operate_queue(pifo, max_cmds, commands, values, keepgoing=keepgoing)
queue_util.dump_json(ans, commands, values)
queue_util.dump_json(commands, values, ans)
4 changes: 2 additions & 2 deletions calyx-py/calyx/pifo_tree_oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
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()
commands, values, _, _ = queue_util.parse_json()

# Our PIFO is a little complicated: it is a tree of queues.
# The root has two children, which are PIFOs.
Expand All @@ -28,4 +28,4 @@
)

ans = queues.operate_queue(pifo, max_cmds, commands, values, keepgoing=keepgoing)
queue_util.dump_json(ans, commands, values)
queue_util.dump_json(commands, values, ans)
62 changes: 52 additions & 10 deletions calyx-py/calyx/queue_data_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def no_err_cmds_list(queue_size, num_cmds):
- No underflows.
- `num_cmds`/2 pushes and `num_cmds`/2 pops.
A combination of the above means that no packet is left unpopped.
This is specifically catered for work-conserving algorithms,
and not for non-work-conserving algorithms.
"""
running_count = 0 # The current size of the queue.
push_goal = int(num_cmds / 2) # How many pushes we want overall.
Expand Down Expand Up @@ -63,29 +65,58 @@ def no_err_cmds_list(queue_size, num_cmds):
return commands


def dump_json(num_cmds, use_rank: bool, no_err: bool, queue_size: Optional[int] = None):
def dump_json(num_cmds, no_err: bool, queue_size: Optional[int]=None, nwc=False, use_ranks=False):
"""Prints a JSON representation of the data to stdout.
The data itself is populated randomly, following certain rules:
- It has three "memories": `commands`, `values`, and `ans_mem`.
- The `commands` memory has `num_cmds` items, which are 0, 1, or 2.
0: pop, 1: peek, 2: push
If the `no_err` flag is set, then items are chosen from 0 and 2 using a helper.
- Optional memories `ranks` and `times` are included for queues primed for non-work-conserving algorithms.
- The `commands` memory has `num_cmds` items, which range from 0-2 for work-conserving policies,
and from 0-4 for non-work-conserving. They are as follows:

FOR WORK-CONSERVING POLICIES
0 : pop
1 : peek
2 : push

FOR NON-WORK-CONSERVING POLICIES
0 : pop by predicate
1 : peek by predicate
2 : push
3 : pop by value
4 : peek by value

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 `nwc` flag is set to False (marking the policy as work-conserving),
then the predicate is treated as though always true.

- The `values` memory has `num_cmds` items:
random values between 0 and 400.
- The `ranks` memory has `num_cmds` items:
random values between 0 and 400.
- The `times` memory has `num_cmds` items:
random values between 0 and 50.
- The `ans_mem` memory has `num_cmds` items, all zeroes.
- Each memory has a `format` field, which is a format object for a bitvector.
"""

commands = {
"commands": {
"data": (
# The `commands` memory has `num_cmds` items, which are all 0, 1, or 2
# The `commands` memory has `num_cmds` items, which are all 0, 1, or 2 (or 3 and 4, for nwc policies)
no_err_cmds_list(queue_size, num_cmds)
if no_err
KabirSamsi marked this conversation as resolved.
Show resolved Hide resolved
# If the `no_err` flag is set, then we use the special helper
# that ensures no overflow or overflow will occur.
if no_err
else [random.randint(0, 2) for _ in range(num_cmds)]
else (
[random.randint(0, 4) for _ in range(num_cmds)]
if nwc
else
[random.randint(0, 2) for _ in range(num_cmds)]
)
),
"format": format_gen(2),
"format": format_gen(3 if nwc else 2),
}
}
values = {
Expand All @@ -104,6 +135,14 @@ def dump_json(num_cmds, use_rank: bool, no_err: bool, queue_size: Optional[int]
"format": format_gen(32),
}
}
times = {
"times": {
"data": [0 if not nwc else random.randint(0, 50) for _ in range(num_cmds)],
# The `times` memory has `num_cmds` items, which are all
# random values between 0 and 50.
"format": format_gen(32),
}
}
ans_mem = {
"ans_mem": {
"data": [0] * num_cmds,
Expand All @@ -112,7 +151,9 @@ def dump_json(num_cmds, use_rank: bool, no_err: bool, queue_size: Optional[int]
}
}

if use_rank:
if nwc:
print(json.dumps(commands | values | ranks | times | ans_mem, indent=2))
elif use_ranks:
print(json.dumps(commands | values | ranks | ans_mem, indent=2))
else:
print(json.dumps(commands | values | ans_mem, indent=2))
Expand All @@ -123,8 +164,9 @@ def dump_json(num_cmds, use_rank: bool, no_err: bool, queue_size: Optional[int]
# This says whether we should use the special no_err helper.
random.seed(5)
num_cmds = int(sys.argv[1])
nwc = "--nwc-en" in sys.argv
no_err = "--no-err" in sys.argv
use_rank = "--use-rank" in sys.argv
if no_err:
queue_size = int(sys.argv[3])
dump_json(num_cmds, use_rank, no_err, queue_size if no_err else None)
dump_json(num_cmds, no_err, queue_size if no_err else None, nwc, use_rank)
44 changes: 23 additions & 21 deletions calyx-py/calyx/queue_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys


def parse_json():
def parse_json(parse_ranks=False, parse_times=False):
"""Effectively the opposite of `data_gen`:
Given a JSON file formatted for Calyx purposes, parses it into two lists:
- The `commands` list.
Expand All @@ -12,28 +12,30 @@ def parse_json():
data = json.load(sys.stdin)
commands = data["commands"]["data"]
values = data["values"]["data"]
ranks = None
try:

if parse_ranks:
ranks = data["ranks"]["data"]
except KeyError:
pass
return commands, values, ranks
if parse_times:
times = data["times"]["data"]

#Return tuple of data
return commands, values, (ranks if parse_ranks else None), (times if parse_times else None)


def dump_json(ans_mem, commands, values, ranks=None):
def dump_json(commands, values, ans_mem, ranks=None, times=None):
"""Prints a JSON representation of the data to stdout."""
payload = {}
if ranks == None:
payload = {
"ans_mem": ans_mem,
"commands": commands,
"values": values
}
else:
payload = {
"ans_mem": ans_mem,
"commands": commands,
"ranks": ranks,
"values": values
}

payload = {
"ans_mem": ans_mem,
"commands": commands
}

if ranks:
payload["ranks"] = ranks

payload["values"] = values

if times:
payload["times"] = times

print(json.dumps(payload, indent=2))
Loading
Loading