def generate_flow_network(self, fig_subgraph_view) -> MINTDevice: # TODO - For now just assume that the networks basically are a bunch # of nodes with nets/channels connecting them ret = MINTDevice("flow_network_temp") for node in fig_subgraph_view.nodes: n = MINTNode("node_{}".format(node)) ret.add_component(n) self._store_fig_netlist_name(node, n.ID) i = 1 for node in fig_subgraph_view.nodes: # Create the channel between these nodes channel_name = "c_{}".format(i) i += 1 params = dict() params["channelWidth"] = 400 source = MINTTarget("node_{}".format(node)) sinks = [] # Add all the outgoing edges for edge in fig_subgraph_view.out_edges(node): tar = edge[1] if tar not in fig_subgraph_view.nodes: # We skip because this might be a weird edge that we were not supposed # to have in this network continue sinks.append(MINTTarget("node_{}".format(tar))) ret.addConnection(channel_name, "CHANNEL", params, source, sinks, '0') return ret
def __init__(self): super().__init__() self.current_device: MINTDevice = MINTDevice("DEFAULT_NAME") self.current_block_id = 0 self.current_layer_id = 0 self.flow_layer_count = 0 self.control_layer_count = 0 self.integration_layer_count = 0 self.current_entity: Optional[str] = None self.current_params: Dict = {} self._current_layer: Optional[Layer] = None
def enterNetlist(self, ctx: mintParser.NetlistContext): self.current_device = MINTDevice("DEFAULT_NAME")
def generate(module: Module, library: MappingLibrary) -> MINTDevice: construction_graph = ConstructionGraph() name_generator = NameGenerator() cur_device = MINTDevice(module.name) # Add a MINT Layer so that the device has something to work with cur_device.create_mint_layer("0", "0", 0, MINTLayerType.FLOW) # TODO - I need to change this DummyStrategy later on if library.name == "dropx": active_strategy = DropXStrategy(construction_graph, module.FIG) elif library.name == "mars": raise NotImplementedError() elif library.name == "hmlp": raise NotImplementedError() else: active_strategy = DummyStrategy(construction_graph, module.FIG) # First go through all the interactions in the design # IF interaction is mix/sieve/divide/dilute/meter look at the library # to get all the options available and set them up as options for the # construction graph to pick and choose from the options. # # FUTURE WORK # # Do the regex matching to find the mapping options # This means that we might need to have a forest of construction of graphs # as there would be alternatives for each type of mapping for interaction in module.FIG.get_interactions(): operator_candidates = library.get_operators( interaction_type=interaction.type) cn = ConstructionNode(interaction.id) # if isinstance(interaction, ValueNode): # continue for operator_candidate in operator_candidates: # TODO: This will change in the future when we can match subgraphs correctly if isinstance(interaction, (FluidNumberInteraction, FluidIntegerInteraction)): # Basically add the value node id into the subgraph view also node_ids = [ module.FIG.get_fignode(edge[0]).id for edge in module.FIG.in_edges(interaction.id) if isinstance(module.FIG.get_fignode(edge[0]), ValueNode) ] node_ids.append(interaction.id) sub_graph = module.FIG.subgraph(node_ids) else: sub_graph = module.FIG.subgraph(interaction.id) mapping_option = MappingOption(operator_candidate, sub_graph) cn.add_mapping_option(mapping_option) construction_graph.add_construction_node(cn) # Generate all ports necessary for the Explicitly declared IO # ------- # Generate the flow layer IO. These are typically declared explicitly # TODO - Figure out how we should generate the construction nodes for control networks for io_ref in module.io: if io_ref.type is IOType.CONTROL: continue for io in io_ref.vector_ref: cn = ConstructionNode(io.id) sub_graph = module.FIG.subgraph(io.id) mapping_candidate = library.get_default_IO() mapping_option = MappingOption(mapping_candidate, sub_graph) cn.add_mapping_option(mapping_option) construction_graph.add_construction_node(cn) # Map the storage and pump elements to their own individual construction graph nodes for fig_node_id in list(module.FIG.nodes): fig_node = module.FIG.get_fignode(fig_node_id) if isinstance(fig_node, Pump): cn = ConstructionNode(fig_node.id) sub_graph = module.FIG.subgraph(fig_node_id) mapping_candidates = library.get_pump_entries() for mapping_candidate in mapping_candidates: mapping_option = MappingOption(mapping_candidate, sub_graph) cn.add_mapping_option(mapping_option) elif isinstance(fig_node, Storage): cn = ConstructionNode(fig_node.id) sub_graph = module.FIG.subgraph(fig_node_id) mapping_candidates = library.get_storage_entries() for mapping_candidate in mapping_candidates: mapping_option = MappingOption(mapping_candidate, sub_graph) cn.add_mapping_option(mapping_option) # TODO - Validate if this is a legit way to do things mappings = module.get_explicit_mappings() override_network_mappings(mappings, library, module.FIG, construction_graph) # TODO - Go through the different flow-flow edge networks to generate construction nodes # specific to these networks, Conditions: # if its a 1-1 flow-flow connection, then create a construction node for the two flow nodes # if its a 1-n / n-1 / n-n construction nodes, then create a construction node capturing the whole network # TODO - Deal with coverage issues here since we need to figure out what are the flow networks, # that we want to match first and then ensure that they're no included on any list cn_nodes = get_flow_flow_candidates(module, active_strategy) for cn in cn_nodes: construction_graph.add_construction_node(cn) # Apply all the explicit mappings in the module to the nodes, overwriting # the options from the library to match against # TODO - Modify Explicit Mapping Data structure # Find all the explicit mappings and override them in the construction graph override_mappings(mappings, library, module.FIG, construction_graph) # Whittle Down the mapping options here to only include the requried single candidates # TODO - Check what library is being used and use the required library here active_strategy.reduce_mapping_options() # TODO - Consider what needs to get done for a combinatorial design space # ---------------- # Generate edges in the construction graph, these edges will guide the generation/ # reduction of path and pipelineing that needs to get done for mars devices construction_graph.generate_edges(module.FIG) # TODO - Extract all pass through networks eliminate_passthrough_nodes(construction_graph) # Now since all the mapping options are finalized Extract the netlist necessary construction_graph.construct_components(name_generator, cur_device) construction_graph.construct_connections(name_generator, cur_device) # Finally join all the netlist pieces attached to the construction nodes # and the input/output/load/carrier flows # TODO - MINIMIZE - carrier / load flows - this might require us to generate # multiple netlist options and pick the best construction_graph.generate_flow_cn_edges(module) construction_graph.generate_control_cn_edges(module) # Generate all the unaccounted carriers and waste output lines necessary # for this to function connect_orphan_IO() # Size the component netlist active_strategy.size_netlist(cur_device) return cur_device