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

Sparse array updates #84

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion metamapper/instruction_selection/dag_rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def visit_Select(self, node):
#What this is doing is pointing the matched inputs of the dag to the body of the tile.
#Then replacing the body of the tile to this node
#TODO verify and call with the matched dag
rr_name = node.children()[0].iname
rr_name = str(self.rr.name).replace(".", "_")
replace_dag_copy = Clone().clone(self.rr.replace(None), iname_prefix=f"{rr_name}_{node.iname}_")
ReplaceInputs(matched_inputs).run(replace_dag_copy)
return replace_dag_copy.output.children()[0]
Expand Down
36 changes: 35 additions & 1 deletion metamapper/irs/coreir/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def gen_CoreIRNodes(width):
CoreIRNodes = Nodes("CoreIR")
peak_ir = gen_peak_CoreIR(width)
c = CoreIRContext()
cgralib = True
try:
c.load_library("cgralib")
except:
cgralib = False

basic = ("mul", "add", "const", "and_", "or_", "neg")
other = ("ashr", "eq", "neq", "lshr", "mux", "sub", "slt", "sle", "sgt", "sge", "ult", "ule", "ugt", "uge", "shl")
Expand Down Expand Up @@ -45,7 +50,6 @@ def gen_CoreIRNodes(width):
assert name_ == name
assert name in CoreIRNodes.coreir_modules
assert CoreIRNodes.name_from_coreir(cmod) == name

name = f"float_DW.fp_add"
peak_fc = peak_ir.instructions[name]
cmod = None
Expand Down Expand Up @@ -139,9 +143,39 @@ def gen_CoreIRNodes(width):
cmod = None
name_ = load_from_peak(CoreIRNodes, peak_fc, cmod=cmod, name="commonlib.mult_middle", modparams=())

if cgralib:
name = f"cgralib.Mem"
peak_fc = peak_ir.instructions[name]
cmod = c.get_namespace('cgralib').generators['Mem'](ctrl_width=16, has_chain_en=False, has_external_addrgen=False, has_flush=True, has_read_valid=False, has_reset=False, has_stencil_valid=True, has_valid=False, is_rom=True, num_inputs=2, num_outputs=2, use_prebuilt_mem=True, width=16)
name_ = load_from_peak(CoreIRNodes, peak_fc, cmod=cmod, stateful=True, name="cgralib.Mem", modparams=())

name = f"cgralib.Pond"
peak_fc = peak_ir.instructions[name]
cmod = c.get_namespace('cgralib').generators['Pond'](num_inputs=2, num_outputs=2, width=16)
name_ = load_from_peak(CoreIRNodes, peak_fc, cmod=cmod, stateful=True, name="cgralib.Pond", modparams=())


CoreIRNodes.custom_nodes = ["coreir.neq", "commonlib.mult_middle", "float.max", "float.min", "float.div", "float_DW.fp_mul", "float_DW.fp_add", "float.sub", "fp_getmant", "fp_addiexp", "fp_subexp", "fp_cnvexp2f", "fp_getfint", "fp_getffrac", "fp_cnvint2f", "fp_gt", "fp_lt", "float.exp", "float.mux"]

class Mem_amber(DagNode):
def __init__(self, clk_en, data_in_0, data_in_1, wen_in_0, wen_in_1, *, iname):
super().__init__(clk_en, data_in_0, data_in_1, wen_in_0, wen_in_1, iname=iname)
self.modparams=()
@property
def attributes(self):
return ("iname")

#Hack to get correct port name
#def select(self, field, original=None):
# self._selects.add("data_out_0")
# return Select(self, field="rdata",type=BitVector[16])

nodes = CoreIRNodes
static_attributes = {}
node_name = "cgralib.Mem_amber"
num_children = 3
type = Product.from_fields("Output",{"data_out_0":BitVector[16], "data_out_1":BitVector[16], "stencil_valid":BitVector[1]})

class FPRom(DagNode):
def __init__(self, raddr, ren, *, init, iname):
super().__init__(raddr, ren, init=init, iname=iname)
Expand Down
24 changes: 24 additions & 0 deletions metamapper/irs/coreir/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@ def gen_peak_CoreIR(width):
DATAWIDTH = 16
CoreIR = gen_custom_ops_peak_CoreIR(DATAWIDTH)

@family_closure
def mem_fc(family: AbstractFamily):
Data = family.BitVector[width]
Bit = family.Bit
class mem(Peak):
@name_outputs(data_out_0=Data, data_out_1=Data, stencil_valid=Bit)
def __call__(self, rst_n: Bit, clk_en: Bit, data_in_0: Data, chain_data_in_0: Data, data_in_1: Data, chain_data_in_1: Data, wen_in_0: Bit, ren_in_0: Bit, addr_in_0: Data, flush: Bit) -> (Data, Data, Bit):
return Data(0), Data(0), Bit(0)
return mem

CoreIR.add_instruction("cgralib.Mem", mem_fc)

@family_closure
def pond_fc(family: AbstractFamily):
Data = family.BitVector[width]
Bit = family.Bit
class pond(Peak):
@name_outputs(data_out_pond_0=Data, data_out_pond_1=Data, valid_out_pond=Bit)
def __call__(self, rst_n: Bit, clk_en: Bit, data_in_pond_0: Data, data_in_pond_1: Data, flush: Bit) -> (Data, Data, Bit):
return Data(0), Data(0), Bit(0)
return pond

CoreIR.add_instruction("cgralib.Pond", pond_fc)

@family_closure
def rom_fc(family: AbstractFamily):
Data = family.BitVector[width]
Expand Down
10 changes: 10 additions & 0 deletions metamapper/rewrite_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def discover(self, from_name, to_name, path_constraints={}, rr_name=None, solver


def sort_rules(self):
self.rules.sort(key=lambda x: x.name)
rule_nodes = []
for rule in self.rules:
dag = rule.tile
Expand All @@ -187,3 +188,12 @@ def sort_rules(self):

keydict = dict(zip(self.rules, rule_nodes))
self.rules.sort(key=keydict.get, reverse=True)

mul_add_rules = []
for idx,rule in enumerate(self.rules):
if "mac" in rule.name or "muladd" in rule.name:
mul_add_rules.append(idx)

for idx in mul_add_rules:
self.rules.insert(0, self.rules.pop(idx))

80 changes: 54 additions & 26 deletions scripts/map_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from metamapper.common_passes import print_dag, gen_dag_img, Constant2CoreIRConstant
from peak.mapper import read_serialized_bindings


class _ArchCycles:
def get(self, node):
kind = node.kind()[0]
Expand All @@ -25,8 +26,12 @@ def get(self, node):
return pe_cycles
return 0


lassen_location = os.path.join(Path(__file__).parent.parent.parent.resolve(), "lassen")
lassen_header = os.path.join(Path(__file__).parent.parent.resolve(), "libs/lassen_header.json")
lassen_header = os.path.join(
Path(__file__).parent.parent.resolve(), "libs/lassen_header.json"
)


def gen_rrules(pipelined=False):

Expand All @@ -39,16 +44,30 @@ def gen_rrules(pipelined=False):
ops = []

if pipelined:
rrule_files = glob.glob(f'{lassen_location}/lassen/rewrite_rules/*_pipelined.json')
rrule_files = glob.glob(
f"{lassen_location}/lassen/rewrite_rules/*_pipelined.json"
)
else:
rrule_files = glob.glob(f'{lassen_location}/lassen/rewrite_rules/*.json')
rrule_files = [rrule_file for rrule_file in rrule_files if "pipelined" not in rrule_file]

custom_rule_names = {"mult_middle": "commonlib.mult_middle", "fp_exp": "float.exp", "fp_div": "float.div", "fp_mux": "float.mux", "fp_mul":"float_DW.fp_mul", "fp_add":"float_DW.fp_add", "fp_sub":"float.sub"}
rrule_files = glob.glob(f"{lassen_location}/lassen/rewrite_rules/*.json")
rrule_files = [
rrule_file for rrule_file in rrule_files if "pipelined" not in rrule_file
]

custom_rule_names = {
"mult_middle": "commonlib.mult_middle",
"fp_exp": "float.exp",
"fp_div": "float.div",
"fp_mux": "float.mux",
"fp_mul": "float_DW.fp_mul",
"fp_add": "float_DW.fp_add",
"fp_sub": "float.sub",
}

for idx, rrule in enumerate(rrule_files):
rule_name = Path(rrule).stem
if ("fp" in rule_name and "pipelined" in rule_name) or rule_name.split("_pipelined")[0] in custom_rule_names:
if ("fp" in rule_name and "pipelined" in rule_name) or rule_name.split(
"_pipelined"
)[0] in custom_rule_names:
rule_name = rule_name.split("_pipelined")[0]
if rule_name in custom_rule_names:
ops.append(custom_rule_names[rule_name])
Expand All @@ -69,6 +88,7 @@ def gen_rrules(pipelined=False):

return rrules, ops


pe_reg_instrs = {}
pe_reg_instrs["const"] = 0
pe_reg_instrs["bypass"] = 2
Expand All @@ -80,39 +100,40 @@ def gen_rrules(pipelined=False):
pe_port_to_reg["data2"] = "regc"

pe_reg_info = {}
pe_reg_info['instrs'] = pe_reg_instrs
pe_reg_info['port_to_reg'] = pe_port_to_reg
pe_reg_info["instrs"] = pe_reg_instrs
pe_reg_info["port_to_reg"] = pe_port_to_reg

file_name = str(sys.argv[1])
if len(sys.argv) > 2:
pe_cycles = int(sys.argv[2])
if "PIPELINED" in os.environ and os.environ["PIPELINED"].isnumeric():
pe_cycles = int(os.environ["PIPELINED"])
else:
pe_cycles = 0
pe_cycles = 1

rrules, ops = gen_rrules(pipelined = pe_cycles != 0)
rrules, ops = gen_rrules(pipelined=pe_cycles != 0)
verilog = False
app = os.path.basename(file_name).split(".json")[0]
output_dir = os.path.dirname(file_name)

c = CoreIRContext(reset=True)
cutil.load_libs(["commonlib", "float_DW"])
CoreIRNodes = gen_CoreIRNodes(16)
cutil.load_from_json(file_name) #libraries=["lakelib"])
cutil.load_from_json(file_name) # libraries=["lakelib"])
kernels = dict(c.global_namespace.modules)

arch_fc = lassen_fc
ArchNodes = Nodes("Arch")

putil.load_and_link_peak(
ArchNodes,
lassen_header,
{"global.PE": arch_fc}
)
putil.load_and_link_peak(ArchNodes, lassen_header, {"global.PE": arch_fc})

mr = "memory.fprom2"
ArchNodes.add(mr, CoreIRNodes.peak_nodes[mr], CoreIRNodes.coreir_modules[mr], CoreIRNodes.dag_nodes[mr])
ArchNodes.add(
mr,
CoreIRNodes.peak_nodes[mr],
CoreIRNodes.coreir_modules[mr],
CoreIRNodes.dag_nodes[mr],
)

mapper = Mapper(CoreIRNodes, ArchNodes, lazy=False, ops = ops, rrules=rrules)
mapper = Mapper(CoreIRNodes, ArchNodes, lazy=False, ops=ops, rrules=rrules)

c.run_passes(["rungenerators", "deletedeadinstances"])
mods = []
Expand All @@ -122,16 +143,23 @@ def gen_rrules(pipelined=False):
dag = cutil.coreir_to_dag(CoreIRNodes, kmod, archnodes=ArchNodes)
Constant2CoreIRConstant(CoreIRNodes).run(dag)

mapped_dag = mapper.do_mapping(dag, kname=kname, node_cycles=_ArchCycles(), convert_unbound=False, prove_mapping=False, pe_reg_info=pe_reg_info)
mod = cutil.dag_to_coreir(ArchNodes, mapped_dag, f"{kname}_mapped", convert_unbounds=verilog)
mapped_dag = mapper.do_mapping(
dag,
kname=kname,
node_cycles=_ArchCycles(),
convert_unbound=False,
prove_mapping=False,
pe_reg_info=pe_reg_info,
)
mod = cutil.dag_to_coreir(
ArchNodes, mapped_dag, f"{kname}_mapped", convert_unbounds=verilog
)
mods.append(mod)

print(f"Total num PEs used: {mapper.num_pes}")
output_file = f"{output_dir}/{app}_mapped.json"
print(f"saving to {output_file}")
c.serialize_definitions(output_file, mods)

with open(f'{output_dir}/{app}_kernel_latencies.json', 'w') as outfile:
with open(f"{output_dir}/{app}_kernel_latencies.json", "w") as outfile:
json.dump(mapper.kernel_cycles, outfile)


59 changes: 38 additions & 21 deletions scripts/map_dse.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from peak_gen.arch import read_arch
from peak_gen.peak_wrapper import wrapped_peak_class


class _ArchCycles:
def get(self, node):
kind = node.kind()[0]
Expand All @@ -28,9 +29,15 @@ def get(self, node):
return pe_cycles
return 0

pe_location = os.path.join(Path(__file__).parent.parent.parent.resolve(), "DSEGraphAnalysis/outputs")

pe_location = os.path.join(
Path(__file__).parent.parent.parent.resolve(), "DSEGraphAnalysis/outputs"
)
pe_header = os.path.join(Path(__file__).parent.parent.resolve(), "libs/pe_header.json")
metamapper_location = os.path.join(Path(__file__).parent.parent.resolve(), "examples/peak_gen")
metamapper_location = os.path.join(
Path(__file__).parent.parent.resolve(), "examples/peak_gen"
)


def gen_rrules():

Expand All @@ -42,37 +49,43 @@ def gen_rrules():
mapping_funcs = []
rrules = []

num_rrules = len(glob.glob(f'{pe_location}/rewrite_rules/*.json'))
num_rrules = len(glob.glob(f"{pe_location}/rewrite_rules/*.json"))

if not os.path.exists(f'{metamapper_location}'):
os.makedirs(f'{metamapper_location}')
if not os.path.exists(f"{metamapper_location}"):
os.makedirs(f"{metamapper_location}")

for ind in range(num_rrules):

with open(f"{pe_location}/peak_eqs/peak_eq_" + str(ind) + ".py", "r") as file:
with open(f"{metamapper_location}/peak_eq_" + str(ind) + ".py", "w") as outfile:
with open(
f"{metamapper_location}/peak_eq_" + str(ind) + ".py", "w"
) as outfile:
for line in file:
outfile.write(line.replace('mapping_function', 'mapping_function_'+str(ind)))
outfile.write(
line.replace("mapping_function", "mapping_function_" + str(ind))
)
peak_eq = importlib.import_module("examples.peak_gen.peak_eq_" + str(ind))

ir_fc = getattr(peak_eq, "mapping_function_" + str(ind) + "_fc")
mapping_funcs.append(ir_fc)

with open(f"{pe_location}/rewrite_rules/rewrite_rule_" + str(ind) + ".json", "r") as json_file:
with open(
f"{pe_location}/rewrite_rules/rewrite_rule_" + str(ind) + ".json", "r"
) as json_file:
rewrite_rule_in = json.load(json_file)

rewrite_rule = read_serialized_bindings(rewrite_rule_in, ir_fc, PE_fc)
counter_example = rewrite_rule.verify()


rrules.append(rewrite_rule)
return PE_fc, rrules


file_name = str(sys.argv[1])
if len(sys.argv) > 2:
pe_cycles = int(sys.argv[2])
if "PIPELINED" in os.environ and os.environ["PIPELINED"].isnumeric():
pe_cycles = int(os.environ["PIPELINED"])
else:
pe_cycles = 0
pe_cycles = 1

arch_fc, rrules = gen_rrules()
verilog = False
Expand All @@ -83,15 +96,11 @@ def gen_rrules():
c = CoreIRContext(reset=True)
cutil.load_libs(["commonlib", "float_DW"])
CoreIRNodes = gen_CoreIRNodes(16)
cutil.load_from_json(file_name) #libraries=["lakelib"])
cutil.load_from_json(file_name) # libraries=["lakelib"])
kernels = dict(c.global_namespace.modules)

ArchNodes = Nodes("Arch")
putil.load_and_link_peak(
ArchNodes,
pe_header,
{"global.PE": arch_fc}
)
putil.load_and_link_peak(ArchNodes, pe_header, {"global.PE": arch_fc})

mapper = Mapper(CoreIRNodes, ArchNodes, lazy=True, rrules=rrules)

Expand All @@ -103,8 +112,16 @@ def gen_rrules():
dag = cutil.coreir_to_dag(CoreIRNodes, kmod, archnodes=ArchNodes)
Constant2CoreIRConstant(CoreIRNodes).run(dag)

mapped_dag = mapper.do_mapping(dag, kname=kname, node_cycles=_ArchCycles(), convert_unbound=False, prove_mapping=False)
mod = cutil.dag_to_coreir(ArchNodes, mapped_dag, f"{kname}_mapped", convert_unbounds=verilog)
mapped_dag = mapper.do_mapping(
dag,
kname=kname,
node_cycles=_ArchCycles(),
convert_unbound=False,
prove_mapping=False,
)
mod = cutil.dag_to_coreir(
ArchNodes, mapped_dag, f"{kname}_mapped", convert_unbounds=verilog
)
mods.append(mod)

print(f"Num PEs used: {mapper.num_pes}")
Expand All @@ -113,5 +130,5 @@ def gen_rrules():
c.serialize_definitions(output_file, mods)


with open(f'{output_dir}/{app}_kernel_latencies.json', 'w') as outfile:
with open(f"{output_dir}/{app}_kernel_latencies.json", "w") as outfile:
json.dump(mapper.kernel_cycles, outfile)
Loading