Source code for synth.CrossbarMapping3D
import math
from networkx import Graph
from utils import config
from core.expressions.BooleanExpression import LITERAL
from core.hardware.Crossbar import MemristorCrossbar
[docs]
class CrossbarMapping3D:
def __init__(self, graph: Graph, layers: int = 1):
self.graph = graph
self.layers = layers
self.vertical = [[] for _ in range(math.ceil((layers+1)/2))]
self.horizontal = [[] for _ in range(math.floor((layers+1)/2))]
self.crossbar = None
[docs]
def map(self, labeling) -> MemristorCrossbar:
input_variables = set()
input_nodes = dict()
root_nodes = dict()
rows = max(1, labeling[0])
columns = max(1, labeling[1])
node_assignment = labeling[2]
edge_assignment = labeling[3]
q = [[] for layer in range(self.layers + 1)]
for (node, layers) in node_assignment.items():
for layer in layers:
q[layer].append(node)
crossbar = MemristorCrossbar(rows, columns, layers=self.layers)
for ((v0, v1), (l0, l1)) in edge_assignment.items():
if l0 % 2 == 0:
l = min(l0, l1)
r = q[l0].index(v0)
c = q[l1].index(v1)
else:
l = min(l0, l1)
c = q[l0].index(v0)
r = q[l1].index(v1)
edge_data = self.graph.get_edge_data(v0, v1)
literal = edge_data["literal"]
crossbar.set_memristor(r, c, literal, layer=l)
# For each node v in layers (l, l+1), we introduce a True value.
for (node, layers) in node_assignment.items():
if self.graph.nodes[node]["variable"] != '1' and self.graph.nodes[node]["variable"] != '0':
input_variables.add(self.graph.nodes[node]["variable"])
if config.io_constraints:
if self.graph.nodes[node]["terminal"]:
input_variable = self.graph.nodes[node]["variable"]
input_nodes[input_variable] = (0, q[0].index(node))
if self.graph.nodes[node]["root"]:
output_variables = self.graph.nodes[node]["output_variables"]
for output_variable in output_variables:
if config.output_layer is not None:
root_nodes[output_variable] = (config.output_layer, q[config.output_layer].index(node))
else:
if self.layers % 2 == 0:
root_nodes[output_variable] = (self.layers, q[self.layers].index(node))
else:
root_nodes[output_variable] = (self.layers - 1, q[self.layers - 1].index(node))
sorted(layers)
for i in range(len(layers) - 1):
l = layers[i]
if l % 2 == 0:
r = q[l].index(node)
c = q[l+1].index(node)
else:
c = q[l].index(node)
r = q[l+1].index(node)
crossbar.set_memristor(r, c, LITERAL("True", True), layer=l)
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.crossbar = crossbar
return self.crossbar