Source code for synth.ChakrabortyAutomatedSynthesis
import time
from datetime import datetime
from typing import Any, Dict
from utils import config
from core.decision_diagrams.BDD import BDD
from synth.SynthesisMethod import SynthesisMethod
from core.expressions.BooleanExpression import LITERAL
from core.hardware.Crossbar import MemristorCrossbar
[docs]
class ChakrabortyAutomatedSynthesis(SynthesisMethod):
def __init__(self, bdd: BDD):
"""
This synthesis method is based on the work by D. Chakraborty et al. [1].
[1] Chakraborty, D., & Jha, S. K. (2017, March).
Automated synthesis of compact crossbars for sneak-path based in-memory computing.
In Design, Automation & Test in Europe Conference & Exhibition (DATE), 2017 (pp. 770-775). IEEE.
"""
super(ChakrabortyAutomatedSynthesis, self).__init__(bdd)
[docs]
def map(self) -> MemristorCrossbar:
print("Chakraborty's mapping method started")
print(datetime.now())
self.start_time = time.time()
rows = len(self.dd.dag.nodes)
columns = len(self.dd.dag.edges)
crossbar = MemristorCrossbar(rows, columns)
# We assign each node to a layer with the terminal node to the bottom-most nanowire
# and the root node to the top-most nanowire
r = 0
input_variables = set()
input_nodes = dict()
root_nodes = dict()
node_layers = dict()
for (current_node, node_data) in self.dd.dag.nodes(data=True):
input_variables.add(node_data["variable"])
if node_data["root"]:
output_variables = node_data["output_variables"]
for output_variable in output_variables:
root_nodes[output_variable] = (0, r)
if node_data["terminal"]:
input_variable = node_data["variable"]
input_nodes[input_variable] = (0, r)
node_layers[current_node] = r
r += 1
c = 0
for (current_node, node_data) in self.dd.dag.nodes(data=True):
out_edges = self.dd.dag.edges(current_node, data=True)
variable = node_data['variable']
positive_child_node = None
negative_child_node = None
for (_, child_node, edge_data) in out_edges:
literal = edge_data.get("literal")
if literal.positive:
positive_child_node = child_node
else:
negative_child_node = child_node
if positive_child_node is not None:
r_current_node = node_layers[current_node]
r_child_node = node_layers[positive_child_node]
crossbar.set_memristor(r_current_node, c, LITERAL(variable, True))
crossbar.set_memristor(r_child_node, c, LITERAL("True", True))
c += 1
if negative_child_node is not None:
r_current_node = node_layers[current_node]
r_child_node = node_layers[negative_child_node]
crossbar.set_memristor(r_current_node, c, LITERAL(variable, False))
crossbar.set_memristor(r_child_node, c, LITERAL("True", True))
c += 1
crossbar.input_variables = list(input_variables)
for (input_function, (layer, nanowire)) in input_nodes.items():
crossbar.set_input_nanowire(input_function, nanowire, layer=layer)
for (output_function, (layer, nanowire)) in root_nodes.items():
crossbar.set_output_nanowire(output_function, nanowire, layer=layer)
self.end_time = time.time()
self.component = crossbar
config.log.add_json(self.get_log())
print("Chakraborty's mapping method stopped")
return crossbar
[docs]
def get_log(self) -> Dict[str, Any]:
return {
"synthesis_method": self.__class__.__name__,
"nodes": len(self.dd.dag.nodes),
"edges": len(self.dd.dag.edges),
"rows": self.component.get_rows(),
"columns": self.component.get_columns(),
"synthesis_time": self.end_time - self.start_time
}