CiMLoop HWComponents

The HWComponents (Hardware Components) package, part of the CiMLoop project, provides an interface for the estimation of area, energy, latency, and leak power of hardware components in hardware architectures. Key features in HWComponents include:

  • A simple Python API for writing area, energy, latency, and leak power models. New models can be written in minutes.

  • Automatic scaling of parameters to different configurations, including scaling to different technology nodes.

  • Pythonic interfaces for finding components, picking the best components for a given request, and more.

  • Automatic gathering of components from available Python packages. This includes support for different models in virtual environments.

Installation

Clone the repository and install with pip. This repository also contains provided models as submodules.

# Install the main package
pip install hwcomponents

# Install model packages
pip install hwcomponents-cacti
pip install hwcomponents-neurosim
pip install hwcomponents-adc
pip install hwcomponents-library

 # List available models
 hwc --list # or hwcomponents --list

hwcomponents API

Code

Tutorials

See the tutorials directory for examples of how to use the package and to create models. Additional documentation and tutorials are available on this site:

Example Usage

The following example shows a ternary MAC component written in HWComponents. It uses scaling to scale the width and technology node of the MAC.

Full examples of how to use the package are available in the notebooks directory.

from hwcomponents import ComponentModel, action, ActionCost
from hwcomponents.scaling import (
    tech_node_area,
    tech_node_energy,
    tech_node_leak,
    tech_node_latency,
    tech_node_throughput,
)


class TernaryMAC(ComponentModel):
    """

    A ternary MAC unit, which multiplies two ternary values and accumulates the result.

    Parameters
    ----------
    accum_n_bits : int
        The width of the accumulator in bits.
    tech_node : int
        The technology node in meters.

    Attributes
    ----------
    accum_n_bits : int
        The width of the accumulator in bits.
    tech_node : int
        The technology node in meters.
    """

    component_name: str | list[str] = "TernaryMAC"
    """ Name of the component. Must be a string or list/tuple of strings. """

    priority = 0.3
    """
    Priority determines which model is used when multiple models are available for a
    given component. Higher priority models are used first. Must be a number between 0
    and 1.
    """

    def __init__(self, accum_n_bits: int, tech_node: int):
        # Provide an area and leakage power for the component. All units are in
        # standard units without any prefixes (Joules, Watts, meters, etc.).
        super().__init__(area=5e-12 * accum_n_bits, leak_power=1e-3 * accum_n_bits)

        # Scale tech_node to the target from the 40nm reference.
        self.tech_node = self.scale(
            "tech_node",
            tech_node,
            40e-9,
            area_scale_function=tech_node_area,
            energy_scale_function=tech_node_energy,
            latency_scale_function=tech_node_latency,
            throughput_scale_function=tech_node_throughput,
            leak_power_scale_function=tech_node_leak,
        )
        self.accum_n_bits = accum_n_bits

        assert (
            4 <= accum_n_bits <= 8
        ), f"Accumulation number of bits {accum_n_bits} outside supported range [4, 8]"

    # The action decorator makes this function visible as an action. Return an
    # ActionCost; throughput defaults to 1/latency if not given.
    @action
    def mac(self, clock_gated: bool = False):
        """
        Returns the cost of one ternary MAC operation.

        Parameters
        ----------
        clock_gated : bool
            Whether the MAC is clock gated during this operation.

        Returns
        -------
        ActionCost
            The cost of this action.
        """
        self.logger.info(f"TernaryMAC Model is estimating energy for mac_random.")
        if clock_gated:
            return ActionCost(energy=0.0, throughput=float("inf"), latency=0.0)
        return ActionCost(
            energy=0.002e-12 * (self.accum_n_bits + 0.25),
            throughput=float("inf"),
            latency=0.0,
        )


mac = TernaryMAC(accum_n_bits=8, tech_node=16e-9)  # Scale the TernaryMAC to 16nm
cost = mac.mac()
print(
    f"TernaryMAC energy is {cost.energy:.2e}J (throughput {cost.throughput:.2e} actions/s). "
    f"Area is {mac.area:.2e}m^2. Leak power is {mac.leak_power:.2e}W"
)

Contributing

Contributions are welcome! Please issue a pull request on GitHub with any changes.

Citing HWComponents

If you use this package in your work, please cite the CiMLoop project:

@software{hwcomponents,
author={Andrulis, Tanner and Gilbert, Michael},
title={HWComponents},
url={https://github.com/Accelergy-Project/hwcomponents},
license={MIT},
}

@INPROCEEDINGS{cimloop,
author={Andrulis, Tanner and Emer, Joel S. and Sze, Vivienne},
booktitle={2024 IEEE International Symposium on Performance Analysis of Systems and Software (ISPASS)},
title={CiMLoop: A Flexible, Accurate, and Fast Compute-In-Memory Modeling Tool},
year={2024},
volume={},
number={},
pages={10-23},
keywords={Performance evaluation;Accuracy;Computational modeling;Computer architecture;Artificial neural networks;In-memory computing;Data models;Compute-In-Memory;Processing-In-Memory;Analog;Deep Neural Networks;Systems;Hardware;Modeling;Open-Source},
doi={10.1109/ISPASS61541.2024.00012}
}