def __create_intercn_channel(self, src_id: str, name_generator: NameGenerator, cn: ConstructionNode, device: MINTDevice) -> None: src = self._construction_nodes[src_id] start_point = src.output_options[0] if start_point.component_name is None: # This means a single component was mapped here src_component_name = self._component_refs[src_id][0] else: src_component_name = name_generator.get_cn_name( src_id, start_point.component_name) end_point = cn.input_options[0] if end_point.component_name is None: # This means a single component was mapped here tar_component_name = self._component_refs[cn.id][0] else: tar_component_name = name_generator.get_cn_name( cn.id, end_point.component_name) print( "Generating the channel - Source: {0} {2}, Target: {1} {3}".format( src_component_name, tar_component_name, start_point.component_port, end_point.component_port)) # TODO - Change how we retrieve the technology type for the channel tech_string = "CHANNEL" # channel_name = name_generator.generate_name(tech_string) # TODO - Figure out how to hande a scenario where this isn't ture assert (len(end_point.component_port) == 1) if len(start_point.component_port) == 0: channel_name = name_generator.generate_name(tech_string) source = MINTTarget(src_component_name, None) sink = MINTTarget(tar_component_name, end_point.component_port[0]) device.addConnection(channel_name, tech_string, dict(), source, [sink], "0") else: for component_port in start_point.component_port: channel_name = name_generator.generate_name(tech_string) source = MINTTarget(src_component_name, component_port) sink = MINTTarget(tar_component_name, end_point.component_port[0]) # TODO - Figure out how to make this layer generate automatically device.addConnection(channel_name, tech_string, dict(), source, [sink], "0") # TODO - Once we are done creating a path, we need to delete the start and end point options # from their respective construction nodes. print("Updated the connectionoptions in {} - Removing {}".format( src, start_point)) src.output_options.remove(start_point) print("Updated the connectionoptions in {} - Removing {}".format( cn, end_point)) cn.input_options.remove(end_point)
def generate_constraints(mirror_driving_components: List[Component], mint_device: MINTDevice) -> None: """Generate the mirror constraints for the device Args: mirror_driving_components (List[Component]): components that are driving the mirror constraint device (MINTDevice): device to generate the constraint for """ for mirror_driving_component in mirror_driving_components: in_mirror_count = mirror_driving_component.params.get_param("in") out_mirror_count = mirror_driving_component.params.get_param("out") if in_mirror_count > 1: # Find groups for in_mirror_count mirror_groups = MirrorConstraint.find_mirror_groups( mirror_driving_component, mint_device.device, in_mirror_count) print("In Mirror Groups") print(mirror_groups) if len(mirror_groups) > 0: # If the number of mirror groups found is great than 0 generate the # mirror constraint mirror_constraint = MirrorConstraint( source_component=mirror_driving_component, mirror_count=len(mirror_groups), mirror_groups=mirror_groups, ) mint_device.add_constraint(mirror_constraint) if out_mirror_count > 1: # Find groups for out_mirror_count mirror_groups = MirrorConstraint.find_mirror_groups( mirror_driving_component, mint_device.device, out_mirror_count) print("Out Mirror Groups") print(mirror_groups) if len(mirror_groups) > 0: # If the number of mirror groups found is great than 0 generate the # mirror constraint mirror_constraint = MirrorConstraint( source_component=mirror_driving_component, mirror_count=len(mirror_groups), mirror_groups=mirror_groups, ) mint_device.add_constraint(mirror_constraint)
def assign_single_port_terminals(device: MINTDevice): #Loop through each of the connections for connection in device.connections: #Check if the source component has a single port source_component = device.getComponent(connection.source.component) if None == connection.source.port and len(source_component.ports) == 1: connection.source.port = source_component.ports[0].label for sink_target in connection.sinks: sink_component = device.getComponent(sink_target.component) if None == sink_target.port and len(sink_component.ports) == 1: sink_component.port = sink_component.ports[0].label
def convert_to_parchmint( input_file: Path, outpath: Path, skip_constraints: bool = True, generate_graph_view: bool = False, ): """ Convert a .mint file to a .parchmint.json file """ extension = input_file.suffix if extension == ".mint" or extension == ".uf": current_device = MINTDevice.from_mint_file(str(input_file), skip_constraints) # Save the device parchmint v1_2 to a file parchmint_text = current_device.to_parchmint() # Create new file in outpath with the same name as the current device outpath.mkdir(parents=True, exist_ok=True) with open(str(outpath.joinpath(input_file.stem + ".json")), "w") as f: print("Writing to file: {}".format(f.name)) json.dump(parchmint_text, f, indent=4) # Generate a graph view of the device if generate_graph_view: printgraph(current_device.device.graph, current_device.device.name) else: raise Exception("Unsupported file extension: {}".format(extension))
def serialize_netlist(device: MINTDevice) -> None: # Generate the MINT file from the pyparchmint device json_data = device.to_parchmint_v1() json_string = json.dumps(json_data) json_file = open(get_ouput_path(device.name + ".json"), "wt") json_file.write(json_string) json_file.close()
def get_default_netlist(self, cn_id: str, name_gen: NameGenerator) -> MINTDevice: """Returns the default netlist for the primitive Args: cn_id (str): ID of the construction node so that we can prefix the id's of all the components that are part of the default netlist name_gen (NameGenerator): A namegenerator instance that is used for the globally for synthesizing the design Returns: MINTDevice: Default netlist of whatever the primitive is """ if self.type is not PrimitiveType.NETLIST: raise Exception( "Cannot execute this method for this kind of a primitive") default_mint_file = parameters.LIB_DIR.joinpath( self._default_netlist).resolve() device = MINTDevice.from_mint_file(str(default_mint_file)) if device is None: raise Exception( "Unable to parse MINT file: {} for construction node {}". format(str(default_mint_file), cn_id)) name_gen.rename_netlist(cn_id, device) # Return the default netlist return device
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") mint_layer = ret.create_mint_layer("0", "0", 0, MINTLayerType.FLOW) for node in fig_subgraph_view.nodes: n = MINTNode("node_{}".format(node), mint_layer) 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.create_mint_connection(channel_name, "CHANNEL", params, source, sinks, "0") return ret
def test_mirror_test4(): mint_file = "tests/mint_files/mirror_test4.mint" mint_device = MINTDevice.from_mint_file(mint_file) # Convert it to Parchmint parchmint_device = mint_device.to_parchmint() # Write the Parchmint to a file with open(mint_file.replace(".mint", ".json"), "r") as data_file: text = data_file.read() device_json = json.loads(text) assert ordered(parchmint_device) == ordered(device_json)
def test_node_test2(): mint_file = "tests/mint_files/node_test2.mint" mint_device = MINTDevice.from_mint_file(mint_file) # Convert it to Parchmint parchmint_device = mint_device.to_parchmint() # Write the Parchmint to a file with open(mint_file.replace(".mint", ".json"), "r") as data_file: text = data_file.read() device_json = json.loads(text) assert parchmint_device == device_json
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 construct_components(self, name_generator: NameGenerator, device: MINTDevice) -> None: for cn in self.construction_nodes: if len(cn.mapping_options) > 1: # TODO - update for combinatorial design space exploration raise Exception( "Does not support Combinatorial design exploration") elif len(cn.mapping_options) == 1: mapping_option = cn.mapping_options[0] # TODO - Make sure we skip the mapping option if pass through is enabled if isinstance(mapping_option, NetworkMappingOption): if mapping_option.mapping_type is NetworkMappingOptionType.PASS_THROUGH: continue if mapping_option.primitive.type is PrimitiveType.COMPONENT: # Create a new component here based on the primitive technology # and the name generator # Then merge with the larger device # Save the copy of subgraph view of the netlist in the construction node component_to_add = mapping_option.primitive.get_default_component( name_generator) device.add_component(component_to_add) self._component_refs[cn.id] = [component_to_add.ID] # for connecting_option in cn # TODO - save the subgraph view reference elif mapping_option.primitive.type is PrimitiveType.NETLIST: netlist = mapping_option.primitive.get_default_netlist( cn.id, name_generator) self._component_refs[cn.id] = [ component.ID for component in netlist.components ] device.merge_netlist(netlist) # TODO - Save the subgraph view reference elif mapping_option.primitive.type is PrimitiveType.PROCEDURAL: netlist = mapping_option.primitive.get_default_netlist( cn.id, name_generator) self._component_refs[cn.id] = [ component.ID for component in netlist.components ] device.merge_netlist(netlist) else: raise Exception( "Does not work with any known option for primitive type" ) cn.load_connection_options() else: print("No mappings found to the current construction node {0}". format(cn))
class MINTCompiler(mintListener): """Primary ANTLR listener class for the compiler""" 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 exitNetlist(self, ctx: mintParser.NetlistContext): if self.current_device is None: raise Exception("Could not find the device") def enterHeader(self, ctx: mintParser.HeaderContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) if ctx.device_name is None: raise Exception("Could not find Device Name") self.current_device.device.name = ctx.device_name.text def exitLayerBlock(self, ctx: mintParser.LayerBlockContext): # Increement teh layer block self.current_block_id += 1 def enterFlowBlock(self, ctx: mintParser.FlowBlockContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) layer = self.current_device.create_mint_layer( str(self.current_layer_id), str(self.flow_layer_count), str(self.current_block_id), MINTLayerType.FLOW, ) self._current_layer = layer self.flow_layer_count += 1 self.current_layer_id += 1 def enterControlBlock(self, ctx: mintParser.ControlBlockContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) layer = self.current_device.create_mint_layer( str(self.current_layer_id), str(self.control_layer_count), str(self.current_block_id), MINTLayerType.CONTROL, ) self._current_layer = layer self.control_layer_count += 1 self.current_layer_id += 1 def enterIntegrationBlock(self, ctx: mintParser.IntegrationBlockContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) layer = self.current_device.create_mint_layer( str(self.current_layer_id), str(self.integration_layer_count), str(self.current_block_id), MINTLayerType.INTEGRATION, ) self._current_layer = layer self.integration_layer_count += 1 self.current_layer_id += 1 def enterEntity(self, ctx: mintParser.EntityContext): self.current_entity = ctx.getText() def enterParamsStat(self, ctx: mintParser.ParamsStatContext): self.current_params = {} def enterIntParam(self, ctx: mintParser.IntParamContext): value = ctx.value().getText() # type: ignore key = ctx.param_element().getText() # type: ignore self.current_params[key] = int(value) def enterBoolParam(self, ctx: mintParser.BoolParamContext): if ctx.boolvalue.getText() == "YES": value = True else: value = False key = ctx.param_element.getText() self.current_params[key] = value def enterLengthParam(self, ctx: mintParser.LengthParamContext): value = float(ctx.value().getText()) # type: ignore self.current_params["length"] = value def enterSpacingParam(self, ctx: mintParser.SpacingParamContext): value = float(ctx.value().getText()) # type: ignore self.current_params["spacing"] = value def enterWidthParam(self, ctx: mintParser.WidthParamContext): value = ctx.value().getText() # type: ignore if ctx.key is None: raise AssertionError key = ctx.key.text if key is None: raise Exception("Error in parsing the width parameter") if key == "w": key = "width" self.current_params[key] = int(value) def enterFlowStat(self, ctx: mintParser.FlowStatContext): self.current_entity = None self.current_params = {} def enterControlStat(self, ctx: mintParser.ControlStatContext): self.current_entity = None self.current_params = {} def exitPrimitiveStat(self, ctx: mintParser.PrimitiveStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) entity = self.current_entity if entity is None: raise Exception("Could not find the technology for the pimitive") # Loop for each of the components that need to be created with this param for ufname in ctx.ufnames().ufname(): # type: ignore if self._current_layer is None: raise Exception("Current layer is set to None") if not ( self._current_layer is not None and self._current_layer.ID is not None ): raise AssertionError self.current_device.create_mint_component( ufname.getText(), entity, self.current_params, [self._current_layer.ID], ) def exitBankDeclStat(self, ctx: mintParser.BankDeclStatContext): entity = self.current_entity if entity is None: raise Exception("Could not find the technology for the primitive") # Clean up the constraint specific params self._cleanup_bank_params() for ufname in ctx.ufnames().ufname(): # type: ignore component_name = ufname.getText() if self._current_layer is None: raise AssertionError self.current_device.create_mint_component( component_name, entity, self.current_params, [self._current_layer.ID], ) def exitBankGenStat(self, ctx: mintParser.BankGenStatContext): entity = self.current_entity if entity is None: raise Exception("Could not find the technology for the primitive") self._cleanup_bank_params() if ctx.dim is None: raise AssertionError dim = int(ctx.dim.text) name = ctx.ufname().getText() # type: ignore for i in range(1, dim + 1): component_name = name + "_" + str(i) if self._current_layer is None: raise Exception("Current Layer not Set") if not ( self._current_layer is not None and self._current_layer.ID is not None ): raise AssertionError self.current_device.create_mint_component( component_name, entity, self.current_params, [self._current_layer.ID] ) def exitGridDeclStat(self, ctx: mintParser.GridDeclStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) entity = self.current_entity if entity is None: raise Exception("Could not find the technology for the primitive") self._cleanup_grid_params() for ufname in ctx.ufnames().ufname(): # type: ignore component_name = ufname.getText() if self._current_layer is None: raise AssertionError self.current_device.create_mint_component( component_name, entity, self.current_params, [self._current_layer.ID], ) def exitChannelStat(self, ctx: mintParser.ChannelStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) entity = self.current_entity if entity is None: entity = "CHANNEL" connection_name = ctx.ufname().getText() # type: ignore source_target = ctx.uftarget()[0] # type: ignore source_id = source_target.ID().getText() if self.current_device.device.component_exists(source_id) is False: raise Exception( "Error ! - Could not find the component '{}' in device '{}'".format( source_id, self.current_device.device.name ) ) if source_target.INT(): source_port = source_target.INT().getText() else: source_port = None # source_uftarget = Target(component_id=source_id, port=source_port) source_uftarget = Target(component_id=source_id, port=source_port) sink_target = ctx.uftarget()[1] # type: ignore sink_id = sink_target.ID().getText() if self.current_device.device.component_exists(sink_id) is False: raise Exception( "Error ! - Could not find the component '{}' in device '{}'".format( sink_id, self.current_device.device.name ) ) if sink_target.INT(): sink_port = sink_target.INT().getText() else: sink_port = None sink_uftarget = Target(component_id=sink_id, port=sink_port) self._cleanup_channel_params() # Create a connection between the different components in the device if not (self._current_layer is not None and self._current_layer.ID is not None): raise AssertionError self.current_device.create_mint_connection( connection_name, entity, self.current_params, source_uftarget, [sink_uftarget], self._current_layer.ID, ) def exitNetStat(self, ctx: mintParser.NetStatContext): entity = self.current_entity if entity is None: entity = "NET" connection_name = ctx.ufname().getText() # type: ignore source_target = ctx.uftarget() source_id = source_target.ID().getText() # type: ignore if source_target.INT(): # type: ignore source_port = source_target.INT().getText() # type: ignore else: source_port = None source_uftarget = Target(component_id=source_id, port=source_port) sink_uftargets = [] for sink_target in ctx.uftargets().uftarget(): # type: ignore sink_id = sink_target.ID().getText() if sink_target.INT(): sink_port = sink_target.INT().getText() else: sink_port = None sink_uftargets.append(Target(component_id=sink_id, port=sink_port)) if not (self._current_layer is not None and self._current_layer.ID is not None): raise AssertionError self.current_device.create_mint_connection( connection_name, entity, self.current_params, source_uftarget, sink_uftargets, self._current_layer.ID, ) def exitSpanStat(self, ctx: mintParser.SpanStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) entity = self.current_entity if entity is None: raise Exception("Could not find the technology for the pimitive") # pipe in the in / out values to params for sizing if ctx.indim is not None: in_value = int(ctx.indim.text) self.current_params["in"] = in_value if ctx.outdim is not None: out_value = int(ctx.outdim.text) self.current_params["out"] = out_value # Loop for each of the components that need to be created with this param for ufname in ctx.ufnames().ufname(): # type: ignore if self._current_layer is None: raise AssertionError self.current_device.create_mint_component( ufname.getText(), entity, self.current_params, [self._current_layer.ID], ) def exitNodeStat(self, ctx: mintParser.NodeStatContext): entity = "NODE" if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) # Loop for each of the components that need to be created with this param if not (self._current_layer is not None and self._current_layer.ID is not None): raise AssertionError for ufname in ctx.ufnames().ufname(): # type: ignore self.current_device.create_mint_component( ufname.getText(), entity, self.current_params, [self._current_layer.ID], ) def exitValveStat(self, ctx: mintParser.ValveStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) entity = self.current_entity if entity is None: logging.error("Could not find entitry information for valve") raise Exception("Could not find entitry information for valve") valve_name = ctx.ufname()[0].getText() # type: ignore if not (self._current_layer is not None and self._current_layer.ID is not None): raise AssertionError valve_component = self.current_device.create_mint_component( valve_name, entity, self.current_params, [self._current_layer.ID], ) connection_name = ctx.ufname()[1].getText() # type: ignore valve_connection = self.current_device.device.get_connection(connection_name) if valve_connection is None: raise Exception( "Error: Could not find connection '{}' in device '{}'".format( connection_name, self.current_device.device.name ) ) self.current_device.device.map_valve(valve_component, valve_connection) def enterViaStat(self, ctx: mintParser.ViaStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) for ufname in ctx.ufnames().ufname(): self.current_device.add_via(ufname.getText(), []) def enterTerminalStat(self, ctx: mintParser.TerminalStatContext): if self.current_device is None: raise Exception( "Error Initializing the device. Could not find the current device" ) terminal_name = ctx.ufname().getText() pin_number = int(ctx.INT.getText()) if not (self._current_layer is not None and self._current_layer.ID is not None): raise AssertionError self.current_device.add_terminal( terminal_name, pin_number, self._current_layer.ID, ) def _cleanup_bank_params(self): if "spacing" in self.current_params: del self.current_params["spacing"] def _cleanup_grid_params(self): if "horizontalSpacing" in self.current_params: del self.current_params["horizontalSpacing"] if "verticalSpacing" in self.current_params: del self.current_params["verticalSpacing"] def _cleanup_channel_params(self): if "length" in self.current_params: del self.current_params["length"]
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
def main(): # parameters.PROGRAM_DIR = os.path.abspath(os.path.dirname(__file__)) parser = argparse.ArgumentParser() parser.add_argument('input', help="This is the file thats used as the input ") parser.add_argument('--outpath', type=str, default="out/", help="This is the output directory") parser.add_argument( '-c', '--convert', action='store_true', help='Sets the flag to only convert the design and nothing else') args = parser.parse_args() ascii_banner = pyfiglet.figlet_format("Fluigi") print(ascii_banner) print("output dir:", args.outpath) print("Running File: " + args.input) extension = Path(args.input).suffix if extension != '.mint' and extension != '.uf': print("Unrecognized file Extension") exit() abspath = Path(args.outpath).resolve() parameters.OUTPUT_DIR = abspath if os.path.isdir(abspath) is not True: print("Creating the output directory:") path = Path(parameters.OUTPUT_DIR) path.mkdir(parents=True) #Check if the device netlist is planar current_device = MINTDevice.from_mint_file(args.input) graph = current_device.G if nx.algorithms.check_planarity(graph) == False: print('Error - Non-planar graph seen') sys.exit(0) try: pull_defaults(current_device) pull_dimensions(current_device) except Exception as e: print('Error getting Primitive data: {}'.format(e)) layout = Layout() layout.importMINTwithoutConstraints(current_device) pull_defaults(current_device) pull_dimensions(current_device) pull_terminals(current_device) generateSpringLayout(layout) layout.applyLayout() tt = os.path.join(parameters.OUTPUT_DIR, '{}_no_par.json'.format(current_device.name)) with open(tt, 'w') as f: json.dump(current_device.to_parchmint_v1(), f) print(current_device.G.edges) utils.printgraph(current_device.G, current_device.name + '.dot') # We exit the process if only convert is set to true if args.convert: sys.exit(0) layout = Layout() layout.importMINTwithoutConstraints(current_device) #Do Terminal Assignment assign_single_port_terminals(current_device) # #Generate the Simulated Annealing Layout # generate_simulated_annealing_layout_v2(current_device) # generate_simulated_annealing_layout(layout) # generateSpectralLayout(layout) generateHOLALayout(layout) layout.applyLayout() layout.ensureLegalCoordinates() layout.print_layout() tt = os.path.join(parameters.OUTPUT_DIR, '{}_hola_par.json'.format(current_device.name)) with open(tt, 'w') as f: json.dump(current_device.to_parchmint_v1(), f) utils.printgraph(layout.G, current_device.name + '.layout.dot')
def generate_simulated_annealing_layout_v2(device: MINTDevice) -> Layout: jsonstring = json.dumps(device.to_parchmint_v1()) print(jsonstring) device = Fluigi.placeAndRouteDevice(jsonstring) print("PNR Executed"+ device.getName())
def __create_passthrough_channel( self, cn_start_id: str, cn_end_id: str, name_generator: NameGenerator, device: MINTDevice, ) -> None: cn_start = self._construction_nodes[cn_start_id] start_point = cn_start.output_options[0] cn_end = self._construction_nodes[cn_end_id] end_point = cn_end.input_options[0] if start_point.component_name is None: # This means a single component was mapped here src_component_name = self._component_refs[cn_start_id][0] else: src_component_name = name_generator.get_cn_name( cn_start_id, start_point.component_name) if end_point.component_name is None: # This means a single component was mapped here tar_component_name = self._component_refs[cn_end_id][0] else: tar_component_name = name_generator.get_cn_name( cn_end_id, end_point.component_name) # TODO - Change how we retrieve the technology type for the channel tech_string = "CHANNEL" # channel_name = name_generator.generate_name(tech_string) # TODO - Figure out how to hande a scenario where this isn't ture assert len(end_point.component_port) == 1 if len(start_point.component_port) == 0: channel_name = name_generator.generate_name(tech_string) source = MINTTarget(src_component_name, None) sink = MINTTarget(tar_component_name, end_point.component_port[0]) device.create_mint_connection(channel_name, tech_string, {"channelWidth": 400}, source, [sink], "0") else: for component_port in start_point.component_port: channel_name = name_generator.generate_name(tech_string) source = MINTTarget(src_component_name, component_port) sink = MINTTarget(tar_component_name, end_point.component_port[0]) # TODO - Figure out how to make this layer generate automatically device.create_mint_connection( channel_name, tech_string, {"channelWidth": 400}, source, [sink], "0", ) # TODO - Once we are done creating a path, we need to delete the start and end point options # from their respective construction nodes. print("Updated the connectionoptions in {} - Removing {}".format( cn_start, start_point)) cn_start.output_options.remove(start_point) print("Updated the connectionoptions in {} - Removing {}".format( cn_end, end_point)) cn_end.input_options.remove(end_point)
def enterNetlist(self, ctx: mintParser.NetlistContext): self.current_device = MINTDevice("DEFAULT_NAME")
def print_netlist(device: MINTDevice) -> None: # Generate the MINT file from the pyparchmint device minttext = device.to_MINT() mint_file = open(get_ouput_path(device.name + ".mint"), "wt") mint_file.write(minttext) mint_file.close()