Skip to content
Snippets Groups Projects
process.py 5.86 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    """B-ASIC classes representing resource usage."""
    
    Mikael Henriksson's avatar
    Mikael Henriksson committed
    from typing import Dict, Optional, Tuple
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from b_asic.operation import Operation
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from b_asic.port import InputPort, OutputPort
    
    
    class Process:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        Object for use in resource allocation.
    
        Has a start time and an execution time. Subclasses will in many cases
        contain additional information for resource assignment.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
        Parameters
        ==========
        start_time : int
            Start time of process.
        execution_time : int
            Execution time (lifetime) of process.
    
        name : str, optional
            The name of the process. If not provided, generate a name.
    
        def __init__(
            self, start_time: int, execution_time: int, name: Optional[str] = None
        ):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            self._start_time = start_time
            self._execution_time = execution_time
    
            if name is None:
    
                self._name = f"Proc. {Process._name_cnt}"
                Process._name_cnt += 1
    
            else:
                self._name = name
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
        def __lt__(self, other):
            return self._start_time < other.start_time or (
    
                self._start_time == other.start_time
                and self.execution_time > other.execution_time
            )
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
        @property
    
        def start_time(self) -> int:
            """Return the start time."""
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return self._start_time
    
        @property
    
        def execution_time(self) -> int:
            """Return the execution time."""
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return self._execution_time
    
    
        @property
        def name(self) -> str:
            return self._name
    
        def __str__(self) -> str:
            return self._name
    
    
        def __repr__(self) -> str:
    
            return f"Process({self.start_time}, {self.execution_time}, {self.name!r})"
    
        # Static counter for default names
        _name_cnt = 0
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
    class OperatorProcess(Process):
    
        """
        Object that corresponds to usage of an operator.
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        Parameters
        ==========
        start_time : int
            Start time of process.
    
        operation : :class:`~b_asic.operation.Operation`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            Operation that the process corresponds to.
    
        name : str, optional
            The name of the process.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """
    
        def __init__(
            self,
            start_time: int,
            operation: Operation,
            name: Optional[str] = None,
        ):
    
            execution_time = operation.execution_time
            if execution_time is None:
                raise ValueError(
    
                    f"Operation {operation!r} does not have an execution time specified!"
    
            super().__init__(
                start_time,
                execution_time,
    
                name=name or operation.name or operation.graph_id,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            self._operation = operation
    
    
    class MemoryVariable(Process):
    
        """
        Object that corresponds to a memory variable.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
        Parameters
        ==========
    
        write_time : int
            Time when the memory variable is written.
    
        write_port : :class:`~b_asic.port.OutputPort`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            The OutputPort that the memory variable originates from.
    
        reads : dict
    
            Dictionary with :class:`~b_asic.port.InputPort` that reads the memory variable
            as key and for how long after the *write_time* it will read.
    
        name : str, optional
            The name of the process.
    
        """
    
        def __init__(
            self,
            write_time: int,
            write_port: OutputPort,
            reads: Dict[InputPort, int],
    
            name: Optional[str] = None,
    
        ):
            self._read_ports = tuple(reads.keys())
            self._life_times = tuple(reads.values())
    
            self._write_port = write_port
            super().__init__(
    
                start_time=write_time,
                execution_time=max(self._life_times),
                name=name,
    
        @property
        def reads(self) -> Dict[InputPort, int]:
            return self._reads
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        @property
    
        def life_times(self) -> Tuple[int, ...]:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return self._life_times
    
        @property
    
        def read_ports(self) -> Tuple[InputPort, ...]:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            return self._read_ports
    
    
        @property
        def write_port(self) -> OutputPort:
            return self._write_port
    
    
        def __repr__(self) -> str:
            reads = {k: v for k, v in zip(self._read_ports, self._life_times)}
            return (
                f"MemoryVariable({self.start_time}, {self.write_port},"
                f" {reads!r}, {self.name!r})"
            )
    
    
    
    class PlainMemoryVariable(Process):
        """
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        Object that corresponds to a memory variable which only use numbers for ports.
    
        This can be useful when only a plain memory variable is wanted with
    
        no connection to a schedule.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
        Parameters
        ==========
        write_time : int
            The time the memory variable is written.
        write_port : int
            Identifier for the source of the memory variable.
        reads : {int: int, ...}
            Dictionary where the key is the destination identifier and the value
    
            is the time after *write_time* that the memory variable is read, i.e., the
            lifetime of the variable.
    
        name : str, optional
            The name of the process.
    
        """
    
        def __init__(
            self,
            write_time: int,
            write_port: int,
            reads: Dict[int, int],
    
    Mikael Henriksson's avatar
    Mikael Henriksson committed
            name: Optional[str] = None,
    
        ):
            self._read_ports = tuple(reads.keys())
            self._life_times = tuple(reads.values())
            self._write_port = write_port
    
            super().__init__(
    
                start_time=write_time,
                execution_time=max(self._life_times),
                name=name,
    
        @property
        def reads(self) -> Dict[int, int]:
            return self._reads
    
    
        def life_times(self) -> Tuple[int, ...]:
    
            return self._life_times
    
        @property
    
        def read_ports(self) -> Tuple[int, ...]:
    
            return self._read_ports
    
        @property
        def write_port(self) -> int:
            return self._write_port
    
    
        def __repr__(self) -> str:
            reads = {k: v for k, v in zip(self._read_ports, self._life_times)}
            return (
                f"PlainMemoryVariable({self.start_time}, {self.write_port},"
                f" {reads!r}, {self.name!r})"
            )