bag3_testbenches.design.optimize.base

This module defines an optimization-based design flow inspired by Eric Chang’s VLSI 2018 talk.

Module Contents

Classes

SweepParams

A data structure containing sweep information for a multi-dimensional parametric sweep.

OptDesigner

A design script class that attempts to find a globally optimal design via a characterization database.

Functions

_soft_cast_si_to_float(→ float)

exception bag3_testbenches.design.optimize.base.OptimizationError[source]

Bases: Exception

A custom exception class for optimization design script errors

class bag3_testbenches.design.optimize.base.SweepParams(params: Dict[str, Union[Dict[str, Union[str, float]], List[Union[str, float]], numpy.ndarray]], force_linear: bool = False)[source]

A data structure containing sweep information for a multi-dimensional parametric sweep. This class defines some utility methods to be used by OptDesigner.

Parameters:
  • params (Dict[str, Union[Dict[str, Union[str, float]], List[Union[str, float]], np.ndarray]]) – The sweep parameters dictionary, mapping variable names to their sweep points: If the value is a dictionary, the value is parsed as keyworded arguments to numpy.linspace Otherwise, the value is directly assumed to be an array of sweep points. Sweep points can be provided as str (where SI string to float conversion will be applied)

  • force_linear (bool) – True if sweep values should be linear. If not linear, and exception is raised. Defaults to False. Since most multi-variable interpolation functions require sweep points to be on a regular grid, this allows for linearity conditions to be verified.

property is_linear: Dict[str, bool][source]

Returns a dictionary mapping sweep variables to whether their sweep points are linear

property first_params: Dict[str, Any][source]
property is_regular_grid: bool[source]

Returns whether the entire sweep space is on a regular grid (i.e., linear along each dimension)

property swp_var_list: bag.util.immutable.ImmutableList[str][source]

Returns a list of sweep variable names

property swp_shape: List[int][source]

Returns the sweep shape (number of points along each dimension)

property swp_params: Dict[str, numpy.ndarray][source]

Returns a dictionary mapping sweep variable names to the list of points

__contains__(item: str) bool[source]
get_swp_values(var: str) numpy.ndarray[source]

Returns a list of valid sweep variable values.

Parameter

varstr

the sweep variable name.

returns:

val_list – the sweep values of the given variable.

rtype:

np.ndarray

swp_combo_iter() Iterable[Tuple[float, Ellipsis]][source]

Returns an iterator of parameter combinations we sweep over.

Returns:

combo_iter – an iterator of tuples of parameter values that we sweep over.

Return type:

Iterable[Tuple[float, …]]

swp_combo_iter_as_dict() Iterable[Dict[str, float]][source]

Returns an iterator of parameter combinations we sweep over as a dictionary.

Returns:

combo_iter – an iterator of dictionary mapping variable names to values that we sweep over.

Return type:

Iterable[Dict[str, float]]

class bag3_testbenches.design.optimize.base.OptDesigner(root_dir: pathlib.Path, sim_db: bag.simulation.cache.SimulationDB, dsn_specs: Mapping[str, Any])[source]

Bases: bag.simulation.design.DesignerBase, abc.ABC

A design script class that attempts to find a globally optimal design via a characterization database.

The general design methodology is as follows: 1. Over a user-defined design space (multi-dimensional sweep of design variables), an array of designs are generated

and simulated simultaneously. Each design’s measurement results are stored in an HDF5 file, and the measurement results from all designs are combined and stored in a single HDF5 file to represent a characterization database.

  1. The measured results are then modeled as continuous multivariable functions by interpolating between adjacent design points.

  2. These models are passed into the optimization engine, which converges to a final design based on user-defined target specs.

Parameters:

dsn_specs (Mapping[str, Any]) –

The design script specifications. The following entries should be specified:

gen_specsUnion[Mapping[str, Any], Path, str]

The base/default generator parameters. For each set of design parameters, new generator parameters will be computed by overriding only the design variables. If a Path or str is specified, the argument will be treated as a path to a specs YAML file.

dsn_swp_paramsDict[str, Union[Dict[str, Union[str, float]], List[Union[str, float]], np.ndarray]]

The mapping of design sweep parameters (e.g., device sizing). Each combination is used to generate a unique DUT. Refer to the SweepParams constructor for more info. Defaults to {}.

sim_cfg_swp_paramsDict[str, Union[Dict[str, Union[str, float]], List[Union[str, float]], np.ndarray]]

The mapping of simulation configuration sweep parameters (e.g., biasing). Refer to the SweepParams constructor for more info. Defaults to {}.

sim_load_swp_paramsDict[str, Union[Dict[str, Union[str, float]], List[Union[str, float]], np.ndarray]]

The mapping of simulation load sweep parameters (e.g., capacitive loading). Refer to the SweepParams constructor for more info. Defaults to {}.

dsn_fixed_paramsDict[str, Any]

The mapping of design parameters to fixed (i.e., non-swept) values. This is useful for quickly changing certain design parameters by bypassing an update to gen_specs. Defaults to {}.

property is_lay: bool[source]

Return whether the specified DUT generator is a layout generator (True) or schematic generator (False)

property dut_class: Union[Type[bag.design.module.Module], Type[bag.layout.template.TemplateBase]][source]

Return the DUT generator class

property dsn_swp_vars: bag.util.immutable.ImmutableList[str][source]

Return the list of design sweep variable names

property sim_cfg_swp_vars: bag.util.immutable.ImmutableList[str][source]

Return the list of simulation configuration sweep variable names

property sim_load_swp_vars: bag.util.immutable.ImmutableList[str][source]

Return the list of simulation loading sweep variable names

property env_list: List[str][source]

Return the list of corners

property dsn_basename: str[source]

Return the design basename

property swp_order: List[str][source]

Returns an ordered list of all sweep variables.

property swp_params: Dict[str, numpy.ndarray][source]

Returns a dictionary mapping of sweep variable names to values.

property swp_shape: tuple[source]

Returns the number of sweep points along each dimension.

property sim_swp_order: List[str][source]

Returns an ordered list of simulation sweep variables.

property sim_swp_params: Dict[str, numpy.ndarray][source]

Returns a dictionary mapping of simulation sweep variable names to values.

classmethod _parse_params(params: Union[Mapping[str, Any], str, pathlib.Path]) bag.util.immutable.Param[source]

Returns the parsed parameter file if a Pathlike argument is specified, otherwise passthrough is performed.

Parameters:

params (Union[Mapping[str, Any], str, Path]) – The parameters to parse. If a string or a Path, then it is assumed to be the path to a yaml file and its contents are returned.

Returns:

new_params – the parsed parameters cast to an immutable dictionary.

Return type:

Param

commit()[source]

Commit changes to specs dictionary. Perform necessary initialization.

get_dut_class_info(gen_specs: bag.util.immutable.Param) Tuple[Union[Type[bag.design.module.Module], Type[bag.layout.template.TemplateBase]], bool][source]

Returns information about the DUT generator class.

Parameters:

gen_specs (Param) – The generator specs.

Returns:

  • dut_class (Union[Type[Module], Type[TemplateBase]]) – The DUT generator class.

  • is_lay (bool) – True if the DUT generator is a layout generator, False if schematic generator.

static get_out_dir(sim_db: bag.simulation.cache.SimulationDB, sim_dir: Union[pathlib.Path, str]) pathlib.Path[source]

Returns the root output directory for permanent data storage.

Parameters:
  • sim_db (SimulationDB) – The simulation database.

  • sim_dir (Union[Path, str]) – The simulation directory.

Returns:

out_dir – The output directory.

Return type:

Path

get_data_dir(dsn_name: str, meas_type: str = '') pathlib.Path[source]

Returns the data directory path for the given measurement.

get_meas_dir(dsn_name: str, meas_type: str = '') pathlib.Path[source]

Returns the measurement directory path for the given measurement.

abstract get_dut_sch_class() Type[bag.design.module.Module][source]

Returns the default schematic generator class.

abstract get_dut_lay_class() Type[bag.layout.template.TemplateBase][source]

Returns the default layout generator class.

classmethod get_dut_gen_specs(is_lay: bool, base_gen_specs: bag.util.immutable.Param, dsn_params: Mapping[str, Any]) Union[bag.util.immutable.Param, Dict[str, Any]][source]

Returns the updated generator specs with some design variables.

Parameters:
  • is_lay (bool) – True if DUT is layout, False if schematic.

  • base_gen_specs (Param) – The base/default generator specs.

  • dsn_params (Mapping[str, Any]) – The design variables.

Returns:

gen_specs – The updated generator specs.

Return type:

Union[Param, Dict[str, Any]]

classmethod get_em_dut_gen_specs(base_gen_specs: bag.util.immutable.Param, gen_params: Mapping[str, Any]) Union[bag.util.immutable.Param, Dict[str, Any]][source]

Returns the updated generator specs with some design variables.

Parameters:
  • base_gen_specs (Param) – The base/default generator specs.

  • gen_params (Mapping[str, Any]) – The design variables.

Returns:

gen_specs – The updated generator specs.

Return type:

Union[Param, Dict[str, Any]]

process_meas_results(res: Dict[str, Any], params: Dict[str, Any]) Dict[str, Any][source]

Processes and returns measurement results. If any particular post-processing needs to be done, this method should be overriden by subclasses.

Parameters:
  • res (Dict[str, Any]) – Measurement results.

  • params (Dict[str, Any]) – Design parameters.

Returns:

new_res – The updated measurement results.

Return type:

Dict[str, Any]

abstract async verify_design(dut: bag.simulation.cache.DesignInstance, dsn_params: Dict[str, Any], sim_swp_params: Dict[str, numpy.ndarray]) Dict[str, Any][source]

Simulates and verifies design. This method is to be implemented by subclasses.

Parameters:
  • dut (DesignInstance) – The DUT.

  • dsn_params (Dict[str, Any]) – Design parameters.

  • sim_swp_params (Dict[str, np.ndarray]) – Simulation sweep parameters.

Returns:

res – The measurement results.

Return type:

Dict[str, Any]

get_design_name(combo: Mapping[str, Any]) str[source]

Constructs the design name based on the specified combination of design parameters.

get_results_fname(params: Dict[str, Any]) pathlib.Path[source]

Returns the path to the design’s measured results.

Parameters:

params (Dict[str, Any]) – The design parameters.

Returns:

fpath – The measurement results path for the specified design parameters.

Return type:

Path

load_results(params: Dict[str, Any]) Dict[str, Any][source]

Loads and returns previously saved measurement results.

Parameters:

params (Dict[str, Any]) – The design parameters.

Returns:

res – The saved measurement results.

Return type:

Dict[str, Any]

save_results(res: Dict[str, Any], params: Dict[str, Any])[source]

Saves the measurement results.

Parameters:
  • res (Dict[str, Any]) – The measurement results.

  • params (Dict[str, Any]) – The design parameters.

check_results_exists(params: Dict[str, Any]) bool[source]

Checks if previous measurement results exist.

Parameters:

params (Dict[str, Any]) – The design parameters.

Returns:

exists – True if previous results exist, False if not.

Return type:

bool

async characterize_designs()[source]

Generates and characterizes all designs.

async characterize_single_design(dsn_params: Dict[str, Any]) Dict[str, Any][source]

Generates and characterizes a single design.

Parameters:

dsn_params (Dict[str, Any]) – The design parameters.

Returns:

res – The measurement results.

Return type:

Dict[str, Any]

async pre_setup(dsn_params: Dict[str, Any]) Dict[str, Any][source]

Processes and returns design parameters. If any particular pre-processing needs to be done, this method should be overridden by subclasses.

Parameters:

dsn_params (Dict[str, Any]) – Design parameters.

Returns:

new_params – The updated design parameters.

Return type:

Dict[str, Any]

check_run_meas(res_fpath: pathlib.Path, var_list: Optional[List[str]] = None) bool[source]

Checks to see if a design should be re-simulated.

Parameters:
  • res_fpath (Path) – File path to (previous) measurement results.

  • var_list (Optional[List[str]]) – The list of measurement variables to check. Defaults to None.

Returns:

run_meas – True to run measurement, False if not.

Return type:

bool

classmethod get_meas_var_list() List[str][source]

Return the expected measurement variables. Used for caching.

classmethod reorder_data_swp(data: Dict[str, Any], swp_order: List[str])[source]

Reorders the simulation data to have the same order of sweep variables.

make_models(db_path: Optional[pathlib.Path] = None) Tuple[Dict[str, List[bag.math.dfun.DiffFunction]], List[str]][source]

Computes models of the characterized database by interpolating simulation data.

Parameters:

db_path (Optional[Path]) – File path to the database. By default, set to db.hdf5 in the output directory.

Returns:

  • fn_table (Dict[str, List[DiffFunction]]) – A dictionary mapping measured values to a list of functions (1 per corner).

  • swp_names (List[str]) – The ordered list of sweep variables found in the database.

optimize(opt_var: str, fn_table: Dict[str, List[bag.math.dfun.DiffFunction]], swp_order: List[str], maximize: bool = False, var_constraints: Optional[Dict[str, Union[float, Tuple[Optional[float], Optional[float]]]]] = None, spec_constraints: Optional[Dict[str, Union[float, Tuple[Optional[float], Optional[float]]]]] = None, reduce_fn: Callable = np.mean, custom_constraints_fn: Optional[Callable] = None, rng: Optional[numpy.random.Generator] = None, rng_seed: Optional[int] = None, num_success: int = 64, max_ratio_fail: float = 0.75, plot_conv: bool = False) Tuple[Dict[str, List[Union[float, numpy.ndarray]]], float, Dict[str, numpy.ndarray]][source]

Runs the optimization engine.

The function to optimize and constraints are computed and passed into scipy.optimize.minimize. This solver will find a locally optimal design. To increase the chances of hitting the global optimal design, the solver is re-run multiple times with randomly generated initial conditions and the best design of all optimization results is chosen.

Parameters:
  • opt_var (str) – The measurement variable to optimize.

  • fn_table (Dict[str, List[DiffFunction]]) – A mapping of measurement variables to function models.

  • swp_order (List[str]) – The ordered list of sweep variables.

  • maximize (bool) – True if opt_var should be maximized, False if minimized.

  • var_constraints (Optional[Dict[str, Union[float, Tuple[Optional[float], Optional[float]]]]]) – A mapping of sweep variables to constraints. If a (single) float is passed in, the variable is constrained to exactly that value. If a tuple of 2 optional floats is passed in, the variable is constrained to (lower bound, upper bound).

  • spec_constraints (Optional[Dict[str, Union[float, Tuple[Optional[float], Optional[float]]]]]) – A mapping of spec/measurement variables to constraints. If a (single) float is passed in, the variable is constrained to exactly that value. If a tuple of 2 optional floats is passed in, the variable is constrained to (lower bound, upper bound).

  • reduce_fn (Callable) – The reduction function to apply to derive the optimization function. Database interpolation models are vector functions by nature (by corner). Since the optimizer aims to minimize a scalar, the vector must be reduced to a scalar.

  • custom_constraints_fn (Optional[Callable]) – A function that can be called to generate additional optimization constraints as a function of fn_table.

  • rng (Optional[np.random.Generator]) – The random number generator to use. Defaults to numpy.random.default_rng.

  • rng_seed (Optional[int]) – The random number generator seed to use. Only used if the default RNG is used.

  • num_success (int) – The number of successful optimization runs.

  • max_ratio_fail (float) – Maximum ratio of optimization runs that can fail.

  • plot_conv (bool) – True to plot the convergence trend.

Returns:

  • opt_x_fmt (Dict[str, List[Union[float, np.ndarray]]]) – The dictionary mapping design parameters to optimal values.

  • opt_y (float) – The optimized spec value.

  • spec_vals (Dict[str, np.ndarray]) – The dictionary mapping spec/measured variables to their values at the optimal design point.

bag3_testbenches.design.optimize.base._soft_cast_si_to_float(si: Union[float, str]) float[source]