"""Base hardware estimator class and registry."""
from __future__ import annotations
import importlib
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any
_ESTIMATOR_REGISTRY: dict[str, type["BaseHardwareEstimator"]] = {}
[docs]
def register_estimator(name: str):
"""Decorator to register a hardware estimator class by name."""
def decorator(cls: type["BaseHardwareEstimator"]) -> type["BaseHardwareEstimator"]:
_ESTIMATOR_REGISTRY[name] = cls
cls.name = name
return cls
return decorator
[docs]
def get_estimator(name: str) -> type["BaseHardwareEstimator"]:
"""Look up a hardware estimator by registry name or dotted import path."""
if name in _ESTIMATOR_REGISTRY:
return _ESTIMATOR_REGISTRY[name]
if "." in name:
module_path, cls_name = name.rsplit(".", 1)
mod = importlib.import_module(module_path)
cls = getattr(mod, cls_name)
if isinstance(cls, type) and issubclass(cls, BaseHardwareEstimator):
return cls
raise TypeError(f"{name} resolved to {cls!r}, not a BaseHardwareEstimator subclass.")
raise KeyError(
f"Unknown estimator {name!r}. Registered: {sorted(_ESTIMATOR_REGISTRY)}."
)
[docs]
@dataclass
class ResourceReport:
"""FPGA resource estimate for a single classifier."""
classifier_name: str
lut: int | None = None
ff: int | None = None
bram: int | None = None
dsp: int | None = None
latency_cycles: int | None = None
latency_ns: float | None = None
macs_per_inference: int | None = None
clock_period_ns: float | None = None
estimated: bool = True
note: str = ""
[docs]
class BaseHardwareEstimator(ABC):
"""Interface for hardware resource estimation.
Subclass and decorate with ``@register_estimator("name")``.
Example::
@register_estimator("my_estimator")
class MyEstimator(BaseHardwareEstimator):
def estimate(self, model, **kwargs):
...
return ResourceReport(classifier_name="my_clf", lut=100)
"""
name: str = "base"
[docs]
@abstractmethod
def estimate(self, model: Any, **kwargs: Any) -> ResourceReport:
"""Estimate hardware resources for a given model.
Args:
model: The trained model to estimate resources for.
**kwargs: Estimator-specific options.
Returns:
A ResourceReport with estimated FPGA resources.
"""
...