Source code for aihwkit.simulator.parameters.io

# -*- coding: utf-8 -*-

# (C) Copyright 2020, 2021, 2022, 2023, 2024 IBM. All Rights Reserved.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# pylint: disable=too-many-instance-attributes

"""Forward / backward / update related parameters for resistive processing units."""

from dataclasses import dataclass
from typing import ClassVar, Type, Optional, Union, List

from .helpers import _PrintableMixin
from .enums import BoundManagementType, NoiseManagementType, WeightNoiseType, AnalogMVType


[docs]@dataclass class IOParameters(_PrintableMixin): """Parameter that define the analog-matvec (forward / backward) and peripheral digital input-output behavior. Here one can enable analog-digital conversion, dynamic input scaling, and define the properties of the analog-matvec computations, such as noise and non-idealities (e.g. IR-drop). """ bindings_class: ClassVar[Optional[Union[str, Type]]] = "AnalogTileInputOutputParameter" bindings_module: ClassVar[str] = "devices" is_perfect: bool = False """Short-cut to compute a perfect forward pass. If ``True``, it assumes an ideal forward pass (e.g. no bound, ADC etc...). Will disregard all other settings in this case. """ mv_type: AnalogMVType = AnalogMVType.ONE_PASS """Selects the type of analog mat-vec computation. See :class:`AnalogMVType` for details. """ inp_bound: float = 1.0 """Input bound and ranges for the digital-to-analog converter (DAC).""" inp_noise: float = 0.0 r"""Std deviation of Gaussian input noise (:math:`\sigma_\text{inp}`). i.e. noisiness of the analog input (at the stage after DAC and before the multiplication). """ inp_res: float = 1 / (2**7 - 2) r"""Number of discretization steps for DAC (:math:`\le0` means infinite steps) or resolution (1/steps).""" inp_sto_round: bool = False """Whether to enable stochastic rounding of DAC.""" inp_asymmetry: float = 0.0 """Input asymmetry :math:`a_\text{input}`. Input of the negative input pass is scaled by :math:`(1 - a_\text{input})`. Note: This setting has only effect in case of and :class:`AnalogMVType` that uses separate passes for positive and negative inputs. """ out_bound: float = 12.0 """Output bound and ranges for analog-to-digital converter (ADC).""" out_noise: float = 0.06 r"""Output noise strength at each output of a tile. This sets the std-deviation of the Gaussian output noise (:math:`\sigma_\text{out}`) at each output, i.e. noisiness of device summation at the output. """ out_noise_std: float = 0.0 r"""Systematic output-to-output variation of the output noise strength. In fraction of the ``out_noise`` parameter, that is 0.3 would mean a 30\% variation of the output noise std deviation given by ``out_noise``. Note: This variation is drawn at instantiation and kept fixed thereafter. It can be adjusted, however, with ``analog_tile.set_forward/backward_parameter({'out_noise_values': x})`` for each analog tiles (if implemented). Caution: This is *not* simply the output noise std.-dev, but the systematic variation of the noise strength across outputs. Use ``out_noise`` to set the former. """ out_res: float = 1 / (2**9 - 2) """Number of discretization steps for ADC or resolution. Number of discretization steps for ADC (:math:`<=0` means infinite steps) or resolution (1/steps). """ out_sto_round: bool = False """Whether to enable stochastic rounding of ADC.""" out_scale: float = 1.0 """Additional fixed scalar factor.""" out_asymmetry: float = 0.0 """Output asymmetry :math:`a_\text{output}`. Output of the negative input pass is scaled by :math:`(1 - a_\text{output})`. Note: This setting has only effect in case of and :class:`AnalogMVType` that uses separate passes for positive and negative inputs. """ bound_management: BoundManagementType = BoundManagementType.ITERATIVE """Type of bound management, see :class:`BoundManagementType`. Caution: Bound management is **only** available for the forward pass. It will be ignored when used for the backward pass. """ noise_management: NoiseManagementType = NoiseManagementType.ABS_MAX """Type of noise management, see :class:`NoiseManagementType`.""" w_noise: float = 0.0 r"""Scale of output referred weight noise (:math:`\sigma_w`) for a given ``w_noise_type``.""" w_noise_type: WeightNoiseType = WeightNoiseType.NONE """Type as specified in :class:`OutputWeightNoiseType`. Note: This noise us applied each time anew as it is referred to the output. It will not change the conductance values of the weight matrix. For the latter one can apply :meth:`diffuse_weights`. """ ir_drop: float = 0.0 """Scale of IR drop along the inputs (rows of the weight matrix). The IR-drop is calculated assuming that the first input is farthest away from the output channel. The expected drop is approximating the steady-state voltage distributions and depends on the input current. """ ir_drop_g_ratio: float = 1.0 / 0.35 / 5e-6 """Physical ratio of wire conductance from one cell to the next to physical max conductance of a device. Default is compute with 5mS maximal conductance set state and 0.35 Ohm wire resistance. """ out_nonlinearity: float = 0.0 """S-shaped non-linearity applied to the analog output. Output non-linearity applies an S-shaped non-linearity to the analog output (before the ADC), i.e. :math:`\frac{y_i}{1 + n_i*|y_i|}` where :math:`n_i` is drawn at the instantiation time by:: out_nonlinearity / out_bound * (1 + out_nonlinearity_std * rand) """ out_nonlinearity_std: float = 0.0 """ Output-to-output non linearity variation. """ slope_calibration: float = 0.0 """Models a calibration process of the output non-linearity (and r-series). This is the relative value in the output range where the slope of the non-linearity should have slope 1. E.g. 0.5 would be at half-out range. """ v_offset_std: float = 0.0 """Voltage offset variation. The output is multiplied by a systematic factor set for each output line at time of instantiation, e.g. :math:`(1 - v_i)` for the coding device and :math:`(1 + v_i)` for the reference device (assuming differential reads). """ v_offset_w_min: float = -1.0 """ Voltage offset for an implicit reference unit. """ r_series: float = 0.0 """Series resistance in fraction of the total output current.""" w_read_asymmetry_dtod: float = 0.0 """Device polarity read dependence. The negative inputs perceive a slightly different weight (e.g. pcm polarity dependence). Each device has a different factor, and the spread of this device-to-device variability can be set with ``w_read_asymmetry_dtod``. A weight (given negative input) will be then scaled by :math:`1 - f_{ij}` where :math:`f_{ij}` is drawn from a Gaussian distribution (with zero mean and standard deviation ``w_read_asymmetry_dtod``). """ max_bm_factor: int = 1000 """Maximal bound management factor. If this factor is reached then the iterative process is stopped. """ max_bm_res: float = 0.25 """Limit the maximal number of iterations of the bound management. Another way to limit the maximal number of iterations of the bound management. The max effective resolution number of the inputs, e.g. use :math:`1/4` for 2 bits. """ bm_test_negative_bound: bool = True nm_thres: float = 0.0 r"""Constant noise management value for ``type`` ``Constant``. In other cases, this is a upper threshold :math:`\theta` above which the noise management factor is saturated. E.g. for `AbsMax`: .. math:: :nowrap: \begin{equation*} \alpha=\begin{cases}\max_i|x_i|, & \text{if} \max_i|x_i|<\theta \\ \theta, & \text{otherwise}\end{cases} \end{equation*} Caution: If ``nm_thres`` is set (and type is not ``Constant``), the noise management will clip some large input values, in favor of having a better SNR for smaller input values. """
[docs]@dataclass class IOParametersIRDropT(IOParameters): """Parameter that define the analog-matvec (forward / backward) and peripheral digital input-output behavior. Here one can enable analog-digital conversion, dynamic input scaling, and define the properties of the analog-matvec computations, such as noise and non-idealities (e.g. IR-drop). """ bindings_ignore: ClassVar[List] = [ "ir_drop_rs", "ir_drop_segments", "ir_drop_time_step_resolution_scale", "ir_drop_v_read", "split_mode_bit_shift", ] ir_drop: float = 1.0 """Scales the physical wire resistance. To turn off the ir_drop, set `ir_drop=0.0`. Note: IR-drop is only enabled during testing. It is automatically turned off during HWA training. """ ir_drop_rs: float = 0.15 """Physical wire resistance [Ohms] from one unit cell to the next unit cell. """ ir_drop_segments: int = 8 """Number of segments into which to break column simulation when appromixating IR-drop. Ideal calculation uses max_input_size meaning that the number of segments will be equivalent to the number of unit cells. This is more computationally expensive, however. Approximating IR-drop using eight segments is usually suffiecient and an appropriate trade-off between speed and IR-drop accuracy. """ ir_drop_time_step_resolution_scale: float = 1.0 """Time slice resolution to be used when calculating the transient current responses for IR-drop. Default PWM/DAC uses 8-bits (with one sign bit), so 128 time slices is adequate. These time slices are automatically determined, during conventional mode operation and adjusted (reduced) during split PWM and bit-wise PWM operation. The inp_res parameter to determine the appropriate number of IR-drop time slices as inp_res determines the max number of discrete time steps used for describing input activations. Reducing ir_drop_time_resolution_scale to 0.5, for instance, will reduce the number of time slices computed (and reduce accuracy), but increase the speed of IR drop calculations. Values above 1.0 will increase resolution beyond the PWM/DAC change rate and therefore offer no benefit (just increased memory usage and increased computational time). Bit slicing mode will ignore this parameter as it will lead to faulty IR drop calculations if the resolution is below the minimum resolution of the PWM/DAC. """ ir_drop_v_read: float = 0.4005 """ADC read voltage used in calculating IR-drop current in conjunction with Thevenin equivalent circuit approximation of MAC tile. """ split_mode_bit_shift = 3 """Number of bits in in LSB (remainder) that is fed to MVM tile in first phase of split mode PWM/DAC operation. Split mode PWM/DAC operation increases throughput / energy efficiency of MVM tile hardware while potentially sacrificing some analog MVM accuracy."""