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

Implement combinational groups and primitives #635

Merged
merged 52 commits into from
Sep 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
43f7f89
simplify parsing names with attributes attached
rachitnigam Aug 27, 2021
74d8c7f
initial implementation of comb groups
rachitnigam Aug 27, 2021
bbc3e54
top-down-cc requires cond ports to be @stable
rachitnigam Aug 28, 2021
1051233
remove-comb-groups updates control now
rachitnigam Aug 30, 2021
3473eaa
make `with` option in `if` and `while`
rachitnigam Aug 31, 2021
15c58b3
fix top down compilation and disable static-timing pass
rachitnigam Sep 1, 2021
e807d79
compiler workflow should not build interpreter
rachitnigam Sep 1, 2021
37693b2
fix some doc comments
rachitnigam Sep 2, 2021
3d68394
add comb primitive syntax
rachitnigam Sep 2, 2021
e316293
make combinational primitives with `comb`
rachitnigam Sep 2, 2021
12d39b2
Implement `Schedule::realize_schedule`
rachitnigam Sep 2, 2021
b165912
some cleanup and register top-down-st
rachitnigam Sep 2, 2021
89a6829
remove with_guard from calculate_states_recur
rachitnigam Sep 2, 2021
7bed491
fix bug in back edge generation of top-down-cc while FSM
rachitnigam Sep 3, 2021
86d8797
Fix bug in tdcc FSM generation, implement dead-group-removal pass, an…
rachitnigam Sep 4, 2021
ac961dc
add CombGroup to calyx-py and fix frontends to generate comb groups
rachitnigam Sep 4, 2021
e66c77e
remove generated calyx files for exp frontend
rachitnigam Sep 4, 2021
30f0255
flag-compare runs dead-group-removal before runnning the compiler
rachitnigam Sep 4, 2021
473d972
doc comment for dead-cell-removal
rachitnigam Sep 4, 2021
dfcd10d
extensive comments for tdcc
rachitnigam Sep 4, 2021
35f5eeb
disable broken passes and disable static-timing testing
rachitnigam Sep 4, 2021
1cf9914
disable compile-control tests
rachitnigam Sep 4, 2021
f358232
update some tests
rachitnigam Sep 4, 2021
1ad00a3
fix bug introduced in tdcc
rachitnigam Sep 4, 2021
5e283f5
mechanism to pass cli option to passes
rachitnigam Sep 4, 2021
cccdf95
tests for tdcc dump FSMs
rachitnigam Sep 4, 2021
b5dece0
fix more tests
rachitnigam Sep 4, 2021
18d3e80
update more tests
rachitnigam Sep 4, 2021
cffd5f6
update correctness tests
rachitnigam Sep 4, 2021
8a0fff1
systolic tests update
rachitnigam Sep 4, 2021
4d40a10
another tdcc FSM gen test
rachitnigam Sep 4, 2021
620dfa2
tdcc: handle branch at start
rachitnigam Sep 5, 2021
7e4a930
tdcc: visualize final state
rachitnigam Sep 5, 2021
68e8a47
dead-group-removal: tests
rachitnigam Sep 5, 2021
8b73c23
papercut: check if cond port is combinational
rachitnigam Sep 5, 2021
2522bdf
fix tcam implementation
rachitnigam Sep 5, 2021
ae2796c
fix mrxl
rachitnigam Sep 5, 2021
c06ac16
update test for live_range_analysis
rachitnigam Sep 5, 2021
da7bf50
emit comb groups in circt backend
rachitnigam Sep 5, 2021
2388ffd
update test
rachitnigam Sep 5, 2021
d28e6e5
build dahlia with getHeaders
rachitnigam Sep 5, 2021
4c4180a
fmt
rachitnigam Sep 5, 2021
7ce2b9b
update interpreter to work (maybe) with comb groups
EclecticGriffin Sep 5, 2021
9658309
fix while bug
EclecticGriffin Sep 5, 2021
a24f4ee
update tests and add timeout
EclecticGriffin Sep 5, 2021
28ebac2
make tdcc happy
EclecticGriffin Sep 5, 2021
63c2567
clean up warnings
EclecticGriffin Sep 5, 2021
8bd1430
clippy
EclecticGriffin Sep 5, 2021
4920b60
Merge branch 'master' into comb
rachitnigam Sep 6, 2021
67e1eae
reserved cells test is not longer relevant
rachitnigam Sep 6, 2021
b35ff13
Merge branch 'master' into comb
rachitnigam Sep 6, 2021
a532009
fmt
rachitnigam Sep 6, 2021
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
5 changes: 2 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,10 @@ jobs:
- name: Build Dahlia
if: steps.dahlia-cache.outputs.cache-hit != 'true'
run: |
cd ./dahlia && sbt assembly
cd ./dahlia && sbt "; getHeaders; assembly"
shell: bash

- name: Cache Futil dependencies
- name: Cache Calyx dependencies
uses: actions/cache@v2
with:
path: |
Expand Down Expand Up @@ -228,7 +228,6 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --all

- name: Test
run: |
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ __pycache__
!.vscode/settings.json
!.vscode/launch.json
!.vscode/tasks.json

./tests/correctness/exp/*.futil
103 changes: 68 additions & 35 deletions calyx-py/calyx/gen_exp.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from calyx.py_ast import *
from calyx.py_ast import (
Connect, CompVar, Cell, Group, ConstantPort, CompPort, Stdlib,
Component, ThisPort, And, HolePort, Atom, Not, PortDef, SeqComp,
Enable, While, ParComp, Structure, CompInst, Invoke, Program, Control,
If, Import, CombGroup
)
from calyx.utils import float_to_fixed_point
from math import factorial, log2
from typing import List
from fud.stages.verilator import numeric_types


def generate_fp_pow_component(width: int, int_width: int, is_signed: bool) -> Component:
def generate_fp_pow_component(
width: int, int_width: int, is_signed: bool) -> Component:
"""Generates a fixed point `pow` component, which
computes the value x**y, where y must be an integer.
"""
Expand Down Expand Up @@ -87,12 +93,12 @@ def generate_fp_pow_component(width: int, int_width: int, is_signed: bool) -> Co
),
],
),
Group(
CombGroup(
id=CompVar("cond"),
connections=[
Connect(CompPort(count, "out"), CompPort(lt, "left")),
Connect(ThisPort(CompVar("integer_exp")), CompPort(lt, "right")),
Connect(ConstantPort(1, 1), HolePort(CompVar("cond"), "done")),
Connect(ThisPort(CompVar("integer_exp")),
CompPort(lt, "right")),
],
),
Connect(CompPort(CompVar("pow"), "out"), ThisPort(CompVar("out"))),
Expand All @@ -117,6 +123,7 @@ def generate_fp_pow_component(width: int, int_width: int, is_signed: bool) -> Co
),
)


def generate_cells(
degree: int, width: int, int_width: int, is_signed: bool
) -> List[Cell]:
Expand All @@ -137,7 +144,10 @@ def generate_cells(
)

pow_registers = [
Cell(CompVar(f"p{i}"), stdlib.register(width)) for i in range(2, degree + 1)
Cell(
CompVar(f"p{i}"),
stdlib.register(width)
) for i in range(2, degree + 1)
]
product_registers = [
Cell(CompVar(f"product{i}"), stdlib.register(width))
Expand Down Expand Up @@ -167,20 +177,26 @@ def generate_cells(
]
# One extra `fp_pow` instance to compute e^{int_value}.
pows = [
Cell(CompVar(f"pow{i}"), CompInst("fp_pow", [])) for i in range(1, degree + 1)
Cell(
CompVar(f"pow{i}"), CompInst("fp_pow", [])
) for i in range(1, degree + 1)
]
reciprocal_factorials = []
for i in range(2, degree + 1):
fixed_point_value = float_to_fixed_point(1.0 / factorial(i), frac_width)
fixed_point_value = float_to_fixed_point(
1.0 / factorial(i), frac_width)
value = numeric_types.FixedPoint(
str(fixed_point_value), width, int_width, is_signed=is_signed
).unsigned_integer()
reciprocal_factorials.append(
Cell(CompVar(f"reciprocal_factorial{i}"), stdlib.constant(width, value))
Cell(CompVar(f"reciprocal_factorial{i}"), stdlib.constant(
width, value))
)
# Constant values for the exponent to the fixed point `pow` function.
constants = [
Cell(CompVar(f"c{i}"), stdlib.constant(width, i)) for i in range(2, degree + 1)
Cell(
CompVar(f"c{i}"), stdlib.constant(width, i)
) for i in range(2, degree + 1)
] + [
Cell(
CompVar("one"),
Expand Down Expand Up @@ -218,7 +234,7 @@ def generate_cells(
)
pipes.append(
Cell(
CompVar(f"div_pipe"),
CompVar("div_pipe"),
stdlib.fixed_point_op(
"div_pipe", width, int_width, frac_width, signed=is_signed
),
Expand Down Expand Up @@ -277,7 +293,8 @@ def divide_and_conquer_sums(degree: int) -> List[Structure]:
reg_rhs = CompVar(f"{register_name}{rhs}")
sum = CompVar(f"sum{i + 1}")

# In the first round and first group, we add the 1st degree, the value `x` itself.
# In the first round and first group, we add the 1st degree, the
# value `x` itself.
lhs = (
CompPort(CompVar("frac_x"), "out")
if round == 1 and i == 0
Expand All @@ -296,7 +313,7 @@ def divide_and_conquer_sums(degree: int) -> List[Structure]:

# Sums the 0th degree value, 1, and the final
# sum of the divide-and-conquer.
group_name = CompVar(f"add_degree_zero")
group_name = CompVar("add_degree_zero")
adder = CompVar("add1")
reg = CompVar("sum1")
groups.append(
Expand Down Expand Up @@ -329,7 +346,8 @@ def generate_groups(
connections=[
Connect(ConstantPort(1, 1), CompPort(input, "write_en")),
Connect(ThisPort(CompVar("x")), CompPort(input, "in")),
Connect(CompPort(input, "done"), HolePort(CompVar("init"), "done")),
Connect(CompPort(input, "done"),
HolePort(CompVar("init"), "done")),
],
static_delay=1,
)
Expand All @@ -349,13 +367,16 @@ def generate_groups(
CompPort(mult_pipe, "go"),
Not(Atom(CompPort(mult_pipe, "done"))),
),
Connect(CompPort(mult_pipe, "done"), CompPort(input, "write_en")),
Connect(CompPort(mult_pipe, "done"),
CompPort(input, "write_en")),
Connect(CompPort(mult_pipe, "out"), CompPort(input, "in")),
Connect(CompPort(input, "done"), HolePort(CompVar("negate"), "done")),
Connect(CompPort(input, "done"), HolePort(
CompVar("negate"), "done")),
],
)

# Initialization: split up the value `x` into its integer and fractional values.
# Initialization: split up the value `x` into its integer and fractional
# values.
split_bits = Group(
id=CompVar("split_bits"),
connections=[
Expand Down Expand Up @@ -440,7 +461,8 @@ def multiply_by_reciprocal_factorial(i: int) -> Group:
CompPort(mult_pipe, "go"),
Not(Atom(CompPort(mult_pipe, "done"))),
),
Connect(CompPort(mult_pipe, "done"), CompPort(product, "write_en")),
Connect(CompPort(mult_pipe, "done"),
CompPort(product, "write_en")),
Connect(CompPort(mult_pipe, "out"), CompPort(product, "in")),
Connect(CompPort(product, "done"), HolePort(group_name, "done")),
]
Expand Down Expand Up @@ -469,9 +491,11 @@ def final_multiply(register_id: CompVar) -> List[Group]:
CompPort(mult_pipe, "go"),
Not(Atom(CompPort(mult_pipe, "done"))),
),
Connect(CompPort(mult_pipe, "done"), CompPort(reg, "write_en")),
Connect(CompPort(mult_pipe, "done"),
CompPort(reg, "write_en")),
Connect(CompPort(mult_pipe, "out"), CompPort(reg, "in")),
Connect(CompPort(reg, "done"), HolePort(group_name, "done")),
Connect(CompPort(reg, "done"),
HolePort(group_name, "done")),
],
)
]
Expand All @@ -483,28 +507,32 @@ def final_multiply(register_id: CompVar) -> List[Group]:
reciprocal = Group(
id=CompVar("reciprocal"),
connections=[
Connect(CompPort(CompVar("one"), "out"), CompPort(div_pipe, "left")),
Connect(CompPort(CompVar("one"), "out"),
CompPort(div_pipe, "left")),
Connect(CompPort(input, "out"), CompPort(div_pipe, "right")),
Connect(
ConstantPort(1, 1),
CompPort(div_pipe, "go"),
Not(Atom(CompPort(div_pipe, "done"))),
),
Connect(CompPort(div_pipe, "done"), CompPort(input, "write_en")),
Connect(CompPort(div_pipe, "out_quotient"), CompPort(input, "in")),
Connect(CompPort(div_pipe, "done"),
CompPort(input, "write_en")),
Connect(CompPort(div_pipe, "out_quotient"),
CompPort(input, "in")),
Connect(
CompPort(input, "done"), HolePort(CompVar("reciprocal"), "done")
CompPort(input, "done"), HolePort(
CompVar("reciprocal"), "done")
),
],
)
is_negative = Group(
is_negative = CombGroup(
id=CompVar("is_negative"),
connections=[
Connect(ThisPort(CompVar("x")), CompPort(CompVar("lt"), "left")),
Connect(ConstantPort(width, 0), CompPort(CompVar("lt"), "right")),
Connect(ConstantPort(1, 1), HolePort(CompVar("is_negative"), "done")),
],
static_delay=0,
Connect(ThisPort(CompVar("x")),
CompPort(CompVar("lt"), "left")),
Connect(ConstantPort(width, 0),
CompPort(CompVar("lt"), "right")),
]
)

# Connect final value to the `out` signal of the component.
Expand Down Expand Up @@ -547,18 +575,21 @@ def generate_control(degree: int, is_signed: bool) -> Control:
]
)
]
consume_pow = [ParComp([Enable(f"consume_pow{i}") for i in range(2, degree + 1)])]
consume_pow = [
ParComp([Enable(f"consume_pow{i}") for i in range(2, degree + 1)])]
mult_by_reciprocal = [
ParComp(
[Enable(f"mult_by_reciprocal_factorial{i}") for i in range(2, degree + 1)]
[Enable(f"mult_by_reciprocal_factorial{i}")
for i in range(2, degree + 1)]
)
]

divide_and_conquer = []
Enable_count = degree >> 1
for r in range(1, int(log2(degree) + 1)):
divide_and_conquer.append(
ParComp([Enable(f"sum_round{r}_{i}") for i in range(1, Enable_count + 1)])
ParComp([Enable(f"sum_round{r}_{i}")
for i in range(1, Enable_count + 1)])
)
Enable_count >>= 1

Expand Down Expand Up @@ -631,7 +662,8 @@ def generate_exp_taylor_series_approximation(


if __name__ == "__main__":
import argparse, json
import argparse
import json

parser = argparse.ArgumentParser(
description="`exp` using a Taylor Series approximation"
Expand Down Expand Up @@ -677,7 +709,8 @@ def generate_exp_taylor_series_approximation(
outputs=[],
structs=[
Cell(CompVar("t"), Stdlib().register(width)),
Cell(CompVar("x"), Stdlib().mem_d1(width, 1, 1), is_external=True),
Cell(CompVar("x"), Stdlib().mem_d1(
width, 1, 1), is_external=True),
Cell(
CompVar("ret"),
Stdlib().mem_d1(width, 1, 1),
Expand Down
16 changes: 14 additions & 2 deletions calyx-py/calyx/py_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Connect(Structure):
def doc(self) -> str:
source = (
self.src.doc()
if self.guard == None
if self.guard is None
else f"{self.guard.doc()} ? {self.src.doc()}"
)
return f"{self.dest.doc()} = {source};"
Expand All @@ -180,14 +180,26 @@ class Group(Structure):

def doc(self) -> str:
static_delay_attr = (
"" if self.static_delay == None else f'<"static"={self.static_delay}>'
"" if self.static_delay is None else f'<"static"={self.static_delay}>'
)
return block(
f"group {self.id.doc()}{static_delay_attr}",
[c.doc() for c in self.connections],
)


@dataclass
class CombGroup(Structure):
id: CompVar
connections: list[Connect]

def doc(self) -> str:
return block(
f"comb group {self.id.doc()}",
[c.doc() for c in self.connections],
)


@dataclass
class CompInst(Emittable):
id: str
Expand Down
27 changes: 19 additions & 8 deletions calyx/src/analysis/control_ports.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::{collections::HashMap, rc::Rc};

use itertools::Itertools;

use crate::ir::{self, RRC};

/// Contains a mapping from name of groups to the ports read by the control
/// program.
/// The vector of ports is guaranteed to only contain unique ports.
pub struct ControlPorts {
used_ports: HashMap<ir::Id, Vec<RRC<ir::Port>>>,
}
Expand Down Expand Up @@ -36,21 +39,25 @@ fn construct(
fbranch,
..
}) => {
used_ports
.entry(cond.borrow().name().clone())
.or_default()
.push(Rc::clone(port));
if let Some(c) = cond {
used_ports
.entry(c.borrow().name().clone())
.or_default()
.push(Rc::clone(port));
}

construct(tbranch, used_ports);
construct(fbranch, used_ports);
}
ir::Control::While(ir::While {
cond, port, body, ..
}) => {
used_ports
.entry(cond.borrow().name().clone())
.or_default()
.push(Rc::clone(port));
if let Some(c) = cond {
used_ports
.entry(c.borrow().name().clone())
.or_default()
.push(Rc::clone(port));
}
construct(body, used_ports);
}
ir::Control::Seq(ir::Seq { stmts, .. })
Expand All @@ -64,6 +71,10 @@ impl From<&ir::Control> for ControlPorts {
fn from(con: &ir::Control) -> Self {
let mut used_ports = HashMap::default();
construct(con, &mut used_ports);
// Deduplicate all vectors
used_ports.values_mut().for_each(|v| {
*v = v.drain(..).unique_by(|p| p.borrow().canonical()).collect()
});
ControlPorts { used_ports }
}
}
Loading