Skip to content

Commit

Permalink
Began binary-heap based PIEO implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
KabirSamsi committed Jul 15, 2024
1 parent b662308 commit 8782c74
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 12 deletions.
162 changes: 162 additions & 0 deletions calyx-py/test/correctness/queues/binheap/binheap_pieo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# pylint: disable=import-error
import sys
import binheap
import calyx.builder as cb
import calyx.queue_call as qc

def insert_pieo(prog, name, val_queue, time_queue, rank_queue, queue_len, stats=None, static=False):
pieo = prog.component(name)

queue_size_factor = 4

# Declare the two sub-queues as cells of this component.
val_queue = pieo.cell("val_queue", val_queue)
time_queue = pieo.cell("time_queue", time_queue)
rank_queue = pieo.cell("rank_queue", rank_queue)

ans_mem = pieo.seq_mem_d1("out", 32, queue_len, queue_size_factor, is_external=True)

ans = pieo.reg(32)
err = pieo.reg(1)

ans_index = pieo.reg(32)

def push(value, rank, time=0):
"""Push an element into the heap (timewise) """
#Parallelly push value, time and rank into their respective heaps
return cb.par(
cb.invoke(
val_queue,
in_value=cb.const(32, value),
in_rank=cb.const(64, rank),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
),
cb.invoke(
time_queue,
in_value=cb.const(32, time),
in_rank=cb.const(64, rank),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
),
cb.invoke(
rank_queue,
in_value=cb.const(32, time),
in_rank=cb.const(64, rank),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
)
)

def peek_by_value(value, time):
#Scan every element of the heap until the correct one is found
queue_index = pieo.reg(32)

#Stores accessed times from popping queue
time_ans = pieo.reg(32)
val_ans = pieo.reg(32)
rank_ans = pieo.reg(32)


cached_vals = pieo.seq_mem_d1("cached_vals", 32, queue_len, 32)
cached_times = pieo.seq_mem_d1("cached_times", 32, queue_len, 32)
cached_ranks = pieo.seq_mem_d1("cached_ranks", 32, queue_len, 32)

#Equality checkers
value_eq = pieo.eq_use(value, time_ans)
time_leq = pieo.le_use(val_ans, time)
overflow_check = pieo.lt_use(queue_index, queue_len)

return [
cb.seq(
cb.while_with ((value_eq & time_leq & overflow_check),
cb.seq([
cb.par(
[cb.invoke(
q,
in_value=0,
in_rank=0,
in_cmd=0, #Pop from queue
ref_ans=ans,
ref_err=err,
)]
for (q, ans) in ((val_queue, val_ans), (time_queue, time_ans), (rank_queue, rank_ans))
),
pieo.mem_store_d1(cached_vals, queue_index, val_ans, "cache_vals"),
pieo.mem_store_d1(cached_times, queue_index, time_ans, "cache_times"),
pieo.mem_store_d1(cached_ranks, queue_index, rank_ans, "cache_ranks"),
pieo.incr(queue_index)
])
),
cb.if_with((value_eq & time_leq),
cb.seq([
pieo.mem_store_d1(ans_mem, ans_index, val_ans, ""),
cb.incr(ans_index),

cb.
cb.par(
cb.invoke(
val_queue,
in_value=cb.const(32, v),
in_rank=cb.const(64, r),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
),
cb.invoke(
time_queue,
in_value=cb.const(32, v),
in_rank=cb.const(64, r),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
),
cb.invoke(
rank_queue,
in_value=cb.const(32, r),
in_rank=cb.const(64, r),
in_cmd=cb.const(2, 2),
ref_ans=ans,
ref_err=err,
)
)
for (v, t, r) in
)
)
)
# comp.mem_store_d1(out, index - 1, ans.out, f"store_ans_{index}"),
]

def pop_and_store():
queue_index = pieo.reg(32)

return [
cb.invoke(
val_queue,
in_value=cb.const(32, 50),
in_rank=cb.const(64, 50),
in_cmd=cb.const(2, 0),
ref_ans=ans,
ref_err=err,
),
pieo.mem_store_d1(ans_mem, index - 1, ans.out, f"store_ans_{index}"),
]

def build():
"""Top-level function to build the program."""
num_cmds = int(sys.argv[1])
keepgoing = "--keepgoing" in sys.argv
prog = cb.Builder()
val_queue = binheap.insert_binheap(prog, "val_queue", 4, 32, 32)
time_queue = binheap.insert_binheap(prog, "time_queue", 4, 32, 32)
rank_queue = binheap.insert_binheap(prog, "rank_queue", 4, 32, 32)
pieo = insert_pieo(prog, "pieo", val_queue, time_queue, rank_queue, 16)
qc.insert_main(prog, pieo, num_cmds, keepgoing=keepgoing)
return prog.program


if __name__ == "__main__":
build().emit()
32 changes: 20 additions & 12 deletions calyx-py/test/correctness/queues/pieo.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,18 @@ def insert_shift_backward(prog, name, length, idx):
def query_time(prog, name, length, current_time):
"""Component for finding the lowest-rank element matching a time predicate"""
comp = prog.component(name)
idx = comp.reg(32)
inc = comp.incr(idx)
ready_time = comp.reg(32)

mem = comp.seq_mem_d2("queue", *length, 3, is_ref=True)
idx = comp.reg(32, is_ref=True)

#Register loads in the readiness time at each level
ready_time = comp.reg(32)
inc = comp.incr(idx)

found = comp.reg(1, is_ref=True)

load_time = comp.mem_load_d2(mem, idx, 1, ready_time, "load_time")

time_leq = comp.le_use(ready_time.out, current_time.out)
idx_leq = comp.lt_use(idx.out, length)

Expand Down Expand Up @@ -246,10 +249,6 @@ def insert_pieo(prog, max_cmds, queue_size):
incr_cmd_idx = pieo.add_store_in_reg(cmd_idx.out, 1, cmd_idx, "incr_cmd_idx")
cmd_in_range = pieo.lt_use(cmd_idx.out, max_cmds)

ans_index = pieo.reg(32, "ans_index")
insert_pos = pieo.reg(32)
result = pieo.reg(32)

#Data trackers (reading from external memory)
cmd, value, time, rank = (
pieo.reg(3, "cmd"),
Expand All @@ -272,11 +271,18 @@ def insert_pieo(prog, max_cmds, queue_size):
for i in range(3)
]

#Write memory
write = pieo.mem_store_d1(ans_mem, ans_index.out, result, "store_result")
#Reference registers
ans_index = pieo.reg(32, "ans_index")
insert_pos = pieo.reg(32)
remove_pos = pieo.reg(32)
result = pieo.reg(32)

#Invoke cells
find_push_loc = insert_find_push_loc(prog, "find_push_loc", queue_dim, rank)
push_loc = insert_push_loc(prog, "insert_push_loc", queue_dim, (value, time, rank), insert_pos)
push_loc = insert_push_loc(prog, "push_loc", queue_dim, (value, time, rank), insert_pos)
shift_backward = insert_shift_backward(prog, "shift_backward", )

write = pieo.mem_store_d1(ans_mem, ans_index.out, result, "store_result")

#Check the type of command
cmd_eqs = [pieo.eq_use(cmd.out, i) for i in range(5)]
Expand All @@ -286,7 +292,9 @@ def insert_pieo(prog, max_cmds, queue_size):
load_cmd,
cb.par (
cb.if_with(cmd_eqs[0] & not_minned,
print("Peek by time")
cb.seq(

)
),

cb.if_with(cmd_eqs[1] & not_minned,
Expand Down Expand Up @@ -319,7 +327,7 @@ def build():
num_cmds = 20000
keepgoing = "--keepgoing" in sys.argv
prog = cb.Builder()
pieo = insert_pieo(prog, "pieo", 16)
pieo = insert_pieo(prog, 20000, 16)
qc.insert_main(prog, pieo, num_cmds, keepgoing=keepgoing)
return prog.program

Expand Down

0 comments on commit 8782c74

Please sign in to comment.