diff --git a/b_asic/architecture.py b/b_asic/architecture.py index dc78118a135ca79273735357943a3f6daebd6e2b..c2943e6efd569828af7cc57d61b6cd054ba03399 100644 --- a/b_asic/architecture.py +++ b/b_asic/architecture.py @@ -764,19 +764,75 @@ of :class:`~b_asic.architecture.ProcessingElement` d_out[i][v] += 1 return [dict(d) for d in d_in], [dict(d) for d in d_out] - def resource_from_name(self, name: str): + def resource_from_name(self, name: str) -> Resource: + """ + Get :class:`Resource` based on name. + + Parameters + ---------- + name : str + Name of the resource. + + Returns + ------- + :class:`Resource` + + """ re = {p.entity_name: p for p in chain(self.memories, self.processing_elements)} return re[name] + def remove_resource( + self, + resource: Union[str, Resource], + ) -> None: + """ + Remove an empty :class:`Resource` from the architecture. + + Parameters + ---------- + resource : :class:`b_asic.architecture.Resource` or str + The resource or the resource name to remove. + """ + if isinstance(resource, str): + resource = self.resource_from_name(resource) + + if resource.collection: + raise ValueError("Resource must be empty") + + if resource in self.memories: + self.memories.remove(resource) + elif resource in self.processing_elements: + self.processing_elements.remove(resource) + else: + raise ValueError('Resource not in architecture') + + def assign_resources(self, heuristic: str = "left_edge") -> None: + """ + Convenience method to assign all resources in the architecture. + + Parameters + ---------- + heuristic : str, default: "left_edge" + The heurstic to use. + + See Also + -------- + Memory.assign + ProcessingElement.assign + + """ + for resource in chain(self.memories, self.processing_elements): + resource.assign(heuristic=heuristic) + def move_process( self, proc: Union[str, Process], re_from: Union[str, Resource], re_to: Union[str, Resource], assign: bool = False, - ): + ) -> None: """ - Move a :class:`b_asic.process.Process` from one resource to another. + Move a :class:`b_asic.process.Process` from one :class:`Resource` to another. Both the resource moved from and will become unassigned after a process has been moved, unless *assign* is set to True. diff --git a/examples/fivepointwinograddft.py b/examples/fivepointwinograddft.py index b1a0186dfb66e83d2b00d334919e12f8e4dfecab..f9afd0e6acf5f1a6feeb78449a231832c96e06ab 100644 --- a/examples/fivepointwinograddft.py +++ b/examples/fivepointwinograddft.py @@ -186,17 +186,18 @@ arch # Move memory variables to optimize architecture arch.move_process('addsub2.0', 'memory3', 'memory2') arch.move_process('bfly2.0', 'memory2', 'memory3') -memories[2].assign() -memories[3].assign() - arch.move_process('cmul2.0', 'memory1', 'memory0') arch.move_process('bfly3.0', 'memory0', 'memory1') arch.move_process('cmul3.0', 'memory4', 'memory0') -memories[0].assign() -memories[1].assign() -memories[4].assign() -for memory in memories: +arch.assign_resources() + +# %% +# Memory 4 is now empty, so remove it. + +arch.remove_resource('memory4') + +for memory in arch.memories: memory.show_content(title=f"Improved {memory.entity_name}") arch