### Example: Patching and Applying Non-Idealities to a PyTorch Model Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/nonideality/Retention.html Demonstrates patching a PyTorch MLP model with memristive properties and then applying non-idealities, specifically retention, using specified models and parameters. The model is tuned before and after applying non-idealities. ```python if __name__ == "__main__": class MLP(torch.nn.Module): def __init__(self, n_inputs): super(MLP, self).__init__() self.layer = torch.nn.Linear(n_inputs, 10) self.activation = torch.nn.ReLU() def forward(self, x): x = self.layer(x) x = self.activation(x) return x model = MLP(n_inputs=100) reference_memristor = memtorch.bh.memristor.VTEAM m_model = patch_model( model, memristor_model=reference_memristor, memristor_model_params={}, module_parameters_to_patch=[torch.nn.Linear], mapping_routine=naive_map, transistor=True, programming_routine=None, scheme=memtorch.bh.Scheme.DoubleColumn, tile_shape=(8, 8), max_input_voltage=0.3, ADC_resolution=int(8), ADC_overflow_rate=0.0, quant_method="linear", ) m_model.tune_() p_model = memtorch.bh.nonideality.apply_nonidealities( m_model, non_idealities=[memtorch.bh.nonideality.NonIdeality.Retention], time=1e4, retention_model=memtorch.bh.nonideality.endurance_retention_models.model_conductance_drift, retention_model_kwargs={\"initial_time\": 0.0, \"drift_coefficient\": 0.1}, ) m_model.tune_() ``` -------------------------------- ### Define Crossbar with Stochastic Parameters Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.html Example of defining a crossbar with stochastic parameters for 'r_on' and 'r_off'. This is useful for modeling memristor behavior with inherent variability. ```python import torch import memtorch crossbar = memtorch.bh.crossbar.Crossbar(memtorch.bh.memristor.VTEAM, {"r_on": memtorch.bh.StochasticParameter(min=1e3, max=1e2), "r_off": 1e4}, shape=(100, 100), tile_shape=(64, 64)) ``` -------------------------------- ### Memristor Get Resistance Method Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Memristor.html Calculates and returns the current resistance of the memristive device based on its conductance. ```python def get_resistance(self): """ Method to determine the resistance of a memristive device. Returns ------- float The devices resistance (ohms). """ return 1 / self.g ``` -------------------------------- ### Initialize and Use Crossbar Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.html Demonstrates initializing a Crossbar object with a specific memristor model and parameters, writing a conductance matrix, setting a device's conductance, and updating the crossbar. This is useful for setting up and manipulating memristor crossbar simulations. ```python import torch import memtorch crossbar = memtorch.bh.crossbar.Crossbar(memtorch.bh.memristor.VTEAM, {"r_on": 1e2, "r_off": 1e4}, shape=(100, 100), tile_shape=(64, 64)) crossbar.write_conductance_matrix(torch.zeros(100, 100).uniform_(1e-2, 1e-4), transistor=True) crossbar.devices[0][0][0].set_conductance(1e-4) crossbar.update(from_devices=True, parallelize=True) ``` -------------------------------- ### Stanford_PKU Memristor Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Stanford_PKU.html Initializes the Stanford_PKU memristor model with various physical and electrical parameters. It sets up the memristor's resistance range, initial gap, and model-specific constants. The gap bounds are validated to ensure they are physically meaningful. ```python import math import numpy as np import torch import memtorch from memtorch.utils import clip, convert_range from .Memristor import Memristor as Memristor class Stanford_PKU(Memristor): """Stanford PKU memristor model (https://nano.stanford.edu/stanford-rram-model). Parameters ---------- time_series_resolution : float Time series resolution (s). r_off : float Off (maximum) resistance of the device (ohms). r_on : float On (minimum) resistance of the device (ohms). gap_init : float Initial gap distance (m). g_0 : float g_0 model parameter. V_0 : float V_0 model parameter. I_0 : float I_0 model parameter. read_voltage : float Read voltage (V) to determine the device's conductance. T_init : float Initial room tempurature. R_th : float Thermal resistance. gamma_init : float gamma_init model parameter. beta : float beta model parameter. t_ox : float Oxide thickness (m). F_min : float Minimum field requirement to enhance gap formation. vel_0 : float vel_0 model parameter. E_a : float Activation energy. a_0 : float Atom spacing. delta_g_init : float Initial delta_g value. model_switch : int Switch to select standard model (0) or dynamic model (1). T_crit : float Threshold temperature (K) for random variations. T_smth : float Activation energy for vacancy generation. """ def __init__( self, time_series_resolution=1e-4, r_off=218586, r_on=542, gap_init=2e-10, g_0=0.25e-9, V_0=0.25, I_0=1000e-6, read_voltage=0.1, T_init=298, R_th=2.1e3, gamma_init=16, beta=0.8, t_ox=12e-9, F_min=1.4e9, vel_0=10, E_a=0.6, a_0=0.25e-9, delta_g_init=0.02, model_switch=0, T_crit=450, T_smth=500, **kwargs ): args = memtorch.bh.unpack_parameters(locals()) super(Stanford_PKU, self).__init__( args.r_off, args.r_on, args.time_series_resolution, 0, 0 ) self.gap_init = args.gap_init self.g_0 = args.g_0 self.V_0 = args.V_0 self.I_0 = args.I_0 self.read_voltage = args.read_voltage self.T_init = args.T_init self.R_th = args.R_th self.gamma_init = args.gamma_init self.beta = args.beta self.t_ox = args.t_ox self.F_min = args.F_min self.vel_0 = args.vel_0 self.E_a = args.E_a self.a_0 = args.a_0 self.delta_g_init = args.delta_g_init self.model_switch = args.model_switch self.T_crit = args.T_crit self.T_smth = args.T_smth gap_min = self.g_0 * np.log( self.I_0 * np.sinh(self.read_voltage / self.V_0) / (self.read_voltage / self.r_on) ) gap_max = self.g_0 * np.log( self.I_0 * np.sinh(self.read_voltage / self.V_0) / (self.read_voltage / self.r_off) ) assert ( gap_min > 0 and gap_max > 0 and gap_max > gap_min ), "Invalid gap length bounds (min: %f, max: %f) encountered." % ( gap_min, gap_max, ) self.gap_min = gap_min self.gap_max = gap_max self.gap = max(min(gap_init, gap_max), gap_min) self.g = self.current(self.read_voltage) / self.read_voltage ``` -------------------------------- ### VTEAM Memristor Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/VTEAM.html Initializes the VTEAM memristor model with various parameters. It unpacks parameters and sets up initial state variables and constants based on provided or default values. ```python import math import numpy as np import torch import memtorch from memtorch.utils import clip, convert_range from .Memristor import Memristor as Memristor class VTEAM(Memristor): """VTEAM memristor model (https://asic2.group/tools/memristor-models/). Parameters ---------- time_series_resolution : float Time series resolution (s). r_off : float Off (maximum) resistance of the device (ohms). r_on : float On (minimum) resistance of the device (ohms). d : float Device length (m). k_on : float k_on model parameter. k_off: float k_off model parameter. alpha_on : float alpha_on model parameter. alpha_off : float alpha_off model parameter. v_on : float Positive write threshold voltage (V). v_off : float Negative write threshold voltage (V). x_on : float x_on model parameter. x_off : float x_off model parameter. """ def __init__( self, time_series_resolution=1e-10, r_off=1000, r_on=50, d=3e-9, k_on=-10, k_off=5e-4, alpha_on=3, alpha_off=1, v_on=-0.2, v_off=0.02, x_on=0, x_off=3e-9, **kwargs ): args = memtorch.bh.unpack_parameters(locals()) super(VTEAM, self).__init__( args.r_off, args.r_on, args.time_series_resolution, args.v_off, args.v_on ) self.d = args.d self.k_on = args.k_on self.k_off = args.k_off self.alpha_on = args.alpha_on self.alpha_off = args.alpha_off self.v_on = args.v_on self.v_off = args.v_off self.x_on = args.x_on self.x_off = args.x_off self.g = 1 / self.r_on self.x = self.x_on self.lamda = np.log(self.r_off / self.r_on) ``` -------------------------------- ### Stanford_PKU Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Stanford_PKU.html Initializes the Stanford_PKU memristor model with various physical and electrical parameters. It sets up the memristor's resistance, gap, and other model-specific constants based on the provided arguments. ```APIDOC ## Stanford_PKU Class ### Description Represents the Stanford PKU memristor model, a physical model for memristive devices. ### Parameters - **time_series_resolution** (float) - Optional - Time series resolution (s). Defaults to 1e-4. - **r_off** (float) - Optional - Off (maximum) resistance of the device (ohms). Defaults to 218586. - **r_on** (float) - Optional - On (minimum) resistance of the device (ohms). Defaults to 542. - **gap_init** (float) - Optional - Initial gap distance (m). Defaults to 2e-10. - **g_0** (float) - Optional - g_0 model parameter. Defaults to 0.25e-9. - **V_0** (float) - Optional - V_0 model parameter. Defaults to 0.25. - **I_0** (float) - Optional - I_0 model parameter. Defaults to 1000e-6. - **read_voltage** (float) - Optional - Read voltage (V) to determine the device's conductance. Defaults to 0.1. - **T_init** (float) - Optional - Initial room temperature. Defaults to 298. - **R_th** (float) - Optional - Thermal resistance. Defaults to 2.1e3. - **gamma_init** (float) - Optional - gamma_init model parameter. Defaults to 16. - **beta** (float) - Optional - beta model parameter. Defaults to 0.8. - **t_ox** (float) - Optional - Oxide thickness (m). Defaults to 12e-9. - **F_min** (float) - Optional - Minimum field requirement to enhance gap formation. Defaults to 1.4e9. - **vel_0** (float) - Optional - vel_0 model parameter. Defaults to 10. - **E_a** (float) - Optional - Activation energy. Defaults to 0.6. - **a_0** (float) - Optional - Atom spacing. Defaults to 0.25e-9. - **delta_g_init** (float) - Optional - Initial delta_g value. Defaults to 0.02. - **model_switch** (int) - Optional - Switch to select standard model (0) or dynamic model (1). Defaults to 0. - **T_crit** (float) - Optional - Threshold temperature (K) for significant random variations. Defaults to 450. - **T_smth** (float) - Optional - Activation energy for vacancy generation. Defaults to 500. ### Method `__init__` ``` -------------------------------- ### Patch Model with Naive Mapping Source: https://memtorch.readthedocs.io/en/latest/memtorch.map.html Demonstrates patching a torch.nn.Module instance to use naive mapping for parameter to conductance conversion. ```python import copy from memtorch.mn.Module import patch_model from memtorch.map.Parameter import naive_map import Net model = Net() patched_model = patch_model(copy.deepcopy(model), memtorch.bh.memristor.VTEAM, {}, module_parameters_to_patch=[torch.nn.Linear], mapping_routine=naive_map) ``` -------------------------------- ### Convert Linear Layer with Naive Scaling Source: https://memtorch.readthedocs.io/en/latest/memtorch.map.html Demonstrates how to convert a torch.nn.Linear layer to a memristive layer using naive scaling for input encoding. ```python from memtorch.map.Input import naive_scale m = memtorch.mn.Linear(torch.nn.Linear(10, 10), memtorch.bh.memristor.VTEAM, {}, tile_shape=(64, 64), scaling_routine=naive_scale) ``` -------------------------------- ### Initialize LinearIonDrift Model Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/LinearIonDrift.html Initializes the LinearIonDrift model with specified physical and electrical parameters. It unpacks arguments and sets up initial conductance and state variables. ```python import math import numpy as np import torch import memtorch from memtorch.utils import clip, convert_range from .Memristor import Memristor as Memristor class LinearIonDrift(Memristor): """Linear Ion behvaioural drift model. Parameters ---------- time_series_resolution : float Time series resolution (s). u_v : float Dopant drift mobility of the device material. d : float Device length (m). r_on : float On (minimum) resistance of the device (ohms). r_off : float Off (maximum) resistance of the device (ohms). pos_write_threshold: float Positive write threshold voltage (V). neg_write_threshold : float Negative write threshold voltage (V). p : int Joglekar window p constant. """ def __init__( self, time_series_resolution=1e-4, u_v=1e-14, d=10e-9, r_on=100, r_off=16e3, pos_write_threshold=0.55, neg_write_threshold=-0.55, p=1, **kwargs ): args = memtorch.bh.unpack_parameters(locals()) super(LinearIonDrift, self).__init__( args.r_off, args.r_on, args.time_series_resolution, args.pos_write_threshold, args.neg_write_threshold, ) self.u_v = args.u_v self.d = args.d self.r_i = args.r_on self.p = args.p self.g = 1 / self.r_i self.x = convert_range(self.r_i, self.r_on, self.r_off, 0, 1) ``` -------------------------------- ### VTEAM Class Initialization Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.memristor.html Initializes the VTEAM memristor model with various parameters that define its behavior. These parameters control characteristics like resistance, device dimensions, and switching thresholds. ```APIDOC ## VTEAM ### Description Initializes the VTEAM memristor model. ### Parameters * **time_series_resolution** (float) - Time series resolution (s). * **r_off** (float) - Off (maximum) resistance of the device (ohms). * **r_on** (float) - On (minimum) resistance of the device (ohms). * **d** (float) - Device length (m). * **k_on** (float) - k_on model parameter. * **k_off** (float) - k_off model parameter. * **alpha_on** (float) - alpha_on model parameter. * **alpha_off** (float) - alpha_off model parameter. * **v_on** (float) - Positive write threshold voltage (V). * **v_off** (float) - Negative write threshold voltage (V). * **x_on** (float) - x_on model parameter. * **x_off** (float) - x_off model parameter. ``` -------------------------------- ### Patch Model with Naive Scaling Source: https://memtorch.readthedocs.io/en/latest/memtorch.map.html Shows how to patch a torch.nn.Module instance to use naive scaling for input encoding during memristive conversion. ```python import copy from memtorch.mn.Module import patch_model from memtorch.map.Input import naive_scale import Net model = Net() patched_model = patch_model(copy.deepcopy(model), memtorch.bh.memristor.VTEAM, {}, module_parameters_to_patch=[torch.nn.Linear], scaling_routine=naive_scale) ``` -------------------------------- ### Crossbar Initialization Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.html Initializes and constructs memristive crossbars with specified configurations, including weights, memristor models, transistor usage, mapping and programming routines, and tiling schemes. ```APIDOC ## init_crossbar ### Description Method to initialise and construct memristive crossbars. ### Method Signature `memtorch.bh.crossbar.Crossbar.init_crossbar(_weights_, _memristor_model_, _memristor_model_params_, _transistor_, _mapping_routine_, _programming_routine_, _programming_routine_params={}, _p_l=None_, _scheme=_, _tile_shape=(128, 128)_, _use_bindings=True_, _cuda_malloc_heap_size=50_, _random_crossbar_init=False_) ### Parameters #### Positional Arguments * **_weights_** (torch.Tensor) – Weights to map. * **_memristor_model_** (memtorch.bh.memristor.Memristor.Memristor) – Memristor model. * **_memristor_model_params_** (**kwargs) – **kwargs to instantiate the memristor model with. * **_transistor_** (bool) – Used to determine if a 1T1R (True) or 1R arrangement (False) is simulated. * **_mapping_routine_** (function) – Mapping routine to use. * **_programming_routine_** (function) – Programming routine to use. * **_programming_routine_params_** (**kwargs) – Programming routine keyword arguments. * **_p_l_** (float) – If not None, the proportion of weights to retain. * **_scheme_** (memtorch.bh.Scheme) – Scheme enum. * **_tile_shape_** (int, int) – Tile shape to use to store weights. If None, modular tiles are not used. * **_use_bindings_** (bool) – Used to determine if C++/CUDA bindings are used (True) or not (False). * **_cuda_malloc_heap_size_** (int) – CUDA malloc heap size. * **_random_crossbar_init_** (boolean) – Determines if the crossbar is to be initialized at random values in between Ron and Roff ### Returns The constructed crossbars and forward() function. ### Return Type tuple ``` -------------------------------- ### Convert Linear Layer with Naive Mapping Source: https://memtorch.readthedocs.io/en/latest/memtorch.map.html Illustrates converting a torch.nn.Linear layer to a memristive layer using naive mapping for parameter to conductance conversion. ```python from memtorch.map.Parameter import naive_map m = memtorch.mn.Linear(torch.nn.Linear(10, 10), memtorch.bh.memristor.VTEAM, {}, tile_shape=(64, 64), mapping_routine=naive_map) ``` -------------------------------- ### Naive Map Parameters to Conductances Source: https://memtorch.readthedocs.io/en/latest/memtorch.map.html Maps network parameters to memristive device conductances using two crossbars for positive and negative weights. Optionally retains a proportion of weights. ```python memtorch.map.Parameter.naive_map(weight, r_on, r_off, scheme, p_l=None) ``` -------------------------------- ### Crossbar Class Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Crossbar.html Initializes a Crossbar object, setting up memristor models, device, and conductance matrix based on provided parameters. Supports modular tiles and random initialization. ```python def __init__( self, memristor_model, memristor_model_params, shape, tile_shape=None, use_bindings=True, cuda_malloc_heap_size=50, random_crossbar_init=False, ): self.memristor_model_params = memristor_model_params self.time_series_resolution = memristor_model_params.get( "time_series_resolution" ) self.device = torch.device("cpu" if "cpu" in memtorch.__version__ else "cuda") self.tile_shape = tile_shape self.use_bindings = use_bindings self.cuda_malloc_heap_size = cuda_malloc_heap_size if hasattr(memristor_model_params, "r_off"): self.r_off_mean = memristor_model_params["r_off"] if callable(self.r_off_mean): self.r_off_mean = self.r_off_mean() else: self.r_off_mean = memristor_model().r_off if hasattr(memristor_model_params, "r_on"): self.r_on_mean = memristor_model_params["r_on"] if callable(self.r_on_mean): self.r_on_mean = self.r_on_mean() else: self.r_on_mean = memristor_model().r_on if len(shape) == 4: # memtorch.mn.Conv2d and memtorch.mn.Conv3d self.rows = shape[1] * shape[2] * shape[3] self.columns = shape[0] elif len(shape) == 3: # memtorch.mn.Conv1d self.rows = shape[1] * shape[2] self.columns = shape[0] elif len(shape) == 2: # memtorch.mn.Linear self.columns, self.rows = shape else: raise Exception("Unsupported crossbar shape.") self.rows = int(self.rows) self.columns = int(self.columns) if tile_shape is not None: self.tiles_map = None tiles_num = math.ceil(self.rows / tile_shape[0]) * math.ceil( self.columns / tile_shape[1] ) self.devices = np.empty( (tiles_num, tile_shape[0], tile_shape[1]), dtype=object ) self.devices.flat = [ memristor_model(**memristor_model_params) for _ in self.devices.flat ] if random_crossbar_init: self.conductance_matrix = torch.FloatTensor( np.random.uniform( 1 / self.r_off_mean, 1 / self.r_on_mean, size=(tiles_num, tile_shape[0], tile_shape[1]), ) ).to(self.device) else: self.conductance_matrix = torch.zeros( (tiles_num, tile_shape[0], tile_shape[1]) ) else: self.devices = np.empty((self.rows, self.columns), dtype=object) self.devices.flat = [ memristor_model(**memristor_model_params) for _ in self.devices.flat ] if random_crossbar_init: self.conductance_matrix = torch.FloatTensor( np.random.uniform( 1 / self.r_off_mean, 1 / self.r_on_mean, size=(self.rows, self.columns), ) ).to(self.device) else: self.conductance_matrix = torch.zeros((self.rows, self.columns)).to( self.device ) self.g_np = np.vectorize(lambda x: x.g) self.update(from_devices=False) self.max_abs_conductance = torch.abs(self.conductance_matrix).flatten() ``` -------------------------------- ### Tile Matrix Multiplication (Bindings) Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Performs tiled matrix multiplication using optimized bindings. Supports quantization with specified methods and parameters. ```python if use_bindings: if quant_method is None: return memtorch_bindings.tile_matmul( mat_a_tiles, mat_a_tiles_map, mat_a_shape, mat_b_tiles, mat_b_tiles_map, mat_b_shape, cuda_malloc_heap_size, ) else: assert ( quant_method in memtorch.bh.Quantize.quant_methods ), "quant_method is invalid." return memtorch_bindings.tile_matmul( mat_a_tiles, mat_a_tiles_map, mat_a_shape, mat_b_tiles, mat_b_tiles_map, mat_b_shape, ADC_resolution, ADC_overflow_rate, memtorch.bh.Quantize.quant_methods.index(quant_method), cuda_malloc_heap_size, ) ``` -------------------------------- ### Initialize Crossbar Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.html Use this method to initialize and construct memristive crossbars. It requires specifying the weights, memristor model, transistor configuration, mapping and programming routines, and optional parameters like retention proportion, scheme, and tile shape. ```python memtorch.bh.crossbar.Crossbar.init_crossbar(weights, memristor_model, memristor_model_params, transistor, mapping_routine, programming_routine, programming_routine_params={}, p_l=None, scheme=Scheme.DoubleColumn, tile_shape=(128, 128), use_bindings=True, cuda_malloc_heap_size=50, random_crossbar_init=False) ``` -------------------------------- ### Tile Class Initialization Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.html Initializes a Tile object to create modular crossbar tiles. These tiles are used to represent 2D matrices. ```APIDOC ## class memtorch.bh.crossbar.Tile.Tile ### Description Class used to create modular crossbar tiles to represent 2D matrices. ### Parameters * **tile_shape** (_int_, _int_) - Tile shape to use to store weights. * **patch_num** (_int_) - Patch number. ``` -------------------------------- ### Generate Tiles with Bindings Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Generates a set of modular tiles from a tensor using memtorch bindings. This is the preferred method for performance. ```python def gen_tiles(tensor, tile_shape, input=False, use_bindings=True): """Method to generate a set of modular tiles representative of a tensor. Parameters ---------- tensor : torch.Tensor Tensor to represent using modular crossbar tiles. tile_shape : int, int Tile shape to use to store weights. input : bool Used to determine if a tensor is an input (True). Returns ------- torch.Tensor, torch.Tensor Tiles and tile_map. """ if use_bindings: tiles, tiles_map = memtorch_bindings.gen_tiles(tensor, tile_shape, input) return tiles, tiles_map ``` -------------------------------- ### Crossbar Initialization Parameters Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Crossbar.html Defines the parameters required to initialize a memristive crossbar, including weights, memristor models, and programming routines. ```python def init_crossbar( weights, memristor_model, memristor_model_params, transistor, mapping_routine, programming_routine, programming_routine_params={}, p_l=None, scheme=Scheme.DoubleColumn, tile_shape=(128, 128), use_bindings=True, cuda_malloc_heap_size=50, random_crossbar_init=False, ): """Method to initialise and construct memristive crossbars. Parameters ---------- weights : torch.Tensor Weights to map. memristor_model : memtorch.bh.memristor.Memristor.Memristor Memristor model. memristor_model_params: **kwargs **kwargs to instantiate the memristor model with. transistor : bool Used to determine if a 1T1R (True) or 1R arrangement (False) is simulated. mapping_routine : function Mapping routine to use. programming_routine : function Programming routine to use. programming_routine_params : **kwargs Programming routine keyword arguments. p_l: float If not None, the proportion of weights to retain. scheme : memtorch.bh.Scheme Scheme enum. tile_shape : int, int Tile shape to use to store weights. If None, modular tiles are not used. use_bindings : bool Used to determine if C++/CUDA bindings are used (True) or not (False). random_crossbar_init: boolean Determines if the crossbar is to be initialized at random values in between Ron and Roff ``` -------------------------------- ### Data_Driven Class Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Data_Driven.html Initializes the Data_Driven memristor model with various parameters controlling its behavior. These parameters define the device's resistance characteristics and switching properties. ```python import math import numpy as np import memtorch from memtorch.utils import clip from .Memristor import Memristor as Memristor class Data_Driven(Memristor): """A Data-Driven Verilog-A ReRAM Model (https://eprints.soton.ac.uk/411693/). Parameters ---------- time_series_resolution : float Time series resolution (s). r_off : float Off (maximum) resistance of the device (ohms). r_on : float On (minimum) resistance of the device (ohms). A_p : float A_p model parameter. A_n : float A_n model parameter. t_p : float t_p model parameter. t_n : float t_n model parameter. k_p : float k_p model parameter. k_n : float k_n model parameter. r_p : float r_p voltage-dependent resistive boundary function coefficients. r_n : float r_n voltage-dependent resistive boundary function coefficients. eta : int Switching direction to stimulus polarity. a_p : float a_p model parameter. a_n : float a_n model parameter. b_p : float b_p model parameter. b_n : float b_n model parameter. """ def __init__( self, time_series_resolution=1e-8, r_off=17e3, r_on=1280, A_p=743.47, A_n=-68012.28374, t_p=6.51, t_n=0.31645, k_p=5.11e-4, k_n=1.17e-3, r_p=[16719, 0], r_n=[29304.82557, 23692.77225], eta=1, a_p=0.24, a_n=0.24, b_p=3, b_n=3, **kwargs ): args = memtorch.bh.unpack_parameters(locals()) super(Data_Driven, self).__init__( args.r_off, args.r_on, args.time_series_resolution, 0, 0 ) self.A_p = args.A_p self.A_n = args.A_n self.t_p = args.t_p self.t_n = args.t_n self.k_p = args.k_p self.k_n = args.k_n self.r_p = args.r_p self.r_n = args.r_n self.eta = args.eta self.a_p = args.a_p self.a_n = args.a_n self.b_p = args.b_p self.b_n = args.b_n self.g = 1 / self.r_on ``` -------------------------------- ### Data_Driven Class Initialization Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.memristor.html Initializes the Data_Driven memristor model with various parameters defining its behavior. ```APIDOC ## Data_Driven ### Description A Data-Driven Verilog-A ReRAM Model. ### Parameters * **time_series_resolution** (float) - Time series resolution (s). * **r_off** (float) - Off (maximum) resistance of the device (ohms). * **r_on** (float) - On (minimum) resistance of the device (ohms). * **A_p** (float) - A_p model parameter. * **A_n** (float) - A_n model parameter. * **t_p** (float) - t_p model parameter. * **t_n** (float) - t_n model parameter. * **k_p** (float) - k_p model parameter. * **k_n** (float) - k_n model parameter. * **r_p** (float) - r_p voltage-dependent resistive boundary function coefficients. * **r_n** (float) - r_n voltage-dependent resistive boundary function coefficients. * **eta** (int) - Switching direction to stimulus polarity. * **a_p** (float) - a_p model parameter. * **a_n** (float) - a_n model parameter. * **b_p** (float) - b_p model parameter. * **b_n** (float) - b_n model parameter. ``` -------------------------------- ### Tiled Inference with Transistor Model (CPU) Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Performs tiled inference using the CPU binding when a transistor model is enabled. Requires specific input and crossbar configurations. ```python return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), tiles_map, crossbar_shape, m.ADC_resolution, m.ADC_overflow_rate, memtorch.bh.Quantize.quant_methods.index(quant_method), ) ``` -------------------------------- ### Tile Matrix Multiplication (No Bindings) Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Performs tile matrix multiplication without using bindings, suitable for scenarios where direct Python implementation is preferred or bindings are unavailable. Requires generated tiles and map. ```python return tile_matmul( input_tiles, input_tiles_map, input.shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), tiles_map, crossbar_shape, m.source_resistance, m.line_resistance, m.ADC_resolution, m.ADC_overflow_rate, m.quant_method, m.transistor, use_bindings=False, ) ``` -------------------------------- ### Tiled Inference without Transistor Model (CPU) Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Performs tiled inference using the CPU binding when no transistor model is used. Requires source and line resistance parameters. ```python return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), tiles_map, crossbar_shape, m.source_resistance, m.line_resistance, m.ADC_resolution, m.ADC_overflow_rate, memtorch.bh.Quantize.quant_methods.index(quant_method), ) ``` -------------------------------- ### simulate Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.memristor.html Simulates the VTEAM memristor's response to a given voltage signal and determines its equivalent conductance over time. ```APIDOC ## simulate ### Description Method to determine the equivalent conductance of a memristive device when a given voltage signal is applied. ### Parameters * **voltage_signal** (torch.Tensor) - A discrete voltage signal with resolution time_series_resolution. * **return_current** (bool) - If True, returns the current instead of conductance. ### Returns * **torch.Tensor** - A tensor containing the equivalent device conductance (or current) for each simulated timestep. ``` -------------------------------- ### Memristor Simulate Method Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Memristor.html Abstract method to simulate the memristive device's conductance over time given a voltage signal. Must be implemented by subclasses. ```python @abstractmethod def simulate(self, voltage_signal): """Method to determine the equivalent conductance of a memristive device when a given voltage signal is applied. Parameters ---------- voltage_signal : torch.Tensor A discrete voltage signal with resolution time_series_resolution. Returns ------- torch.Tensor A tensor containing the equivalent device conductance for each simulated timestep. """ return ``` -------------------------------- ### Constructing Crossbars for DoubleColumn Scheme Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Crossbar.html Initializes and configures crossbar arrays for the DoubleColumn scheme, handling both 5D (Conv3d) and other weight shapes. It maps positive and negative conductance matrices to respective crossbars. ```python assert scheme in Scheme, "scheme must be a Scheme Enum." weights_ = weights.data.detach().clone() crossbars = [] reference_memristor_model_params = {**memristor_model_params, **{"reference": True}} reference_memristor_model = memristor_model(**reference_memristor_model_params) if scheme == Scheme.DoubleColumn: if len(weights.shape) == 5: # memtorch.mn.Conv3d channel_idx = 0 for channel in range(weights.shape[1]): channel_weights = weights.detach().clone()[:, channel, :, :, :] crossbars.append( memtorch.bh.crossbar.Crossbar( memristor_model, memristor_model_params, channel_weights.shape, tile_shape, use_bindings=use_bindings, cuda_malloc_heap_size=cuda_malloc_heap_size, random_crossbar_init=random_crossbar_init, ) ) crossbars.append( memtorch.bh.crossbar.Crossbar( memristor_model, memristor_model_params, channel_weights.shape, tile_shape, use_bindings=use_bindings, cuda_malloc_heap_size=cuda_malloc_heap_size, random_crossbar_init=random_crossbar_init, ) ) pos_conductance_matrix, neg_conductance_matrix = mapping_routine( channel_weights, reference_memristor_model.r_on, reference_memristor_model.r_off, scheme=scheme, p_l=p_l, ) crossbars[channel_idx].write_conductance_matrix( pos_conductance_matrix, transistor=transistor, programming_routine=programming_routine, programming_routine_params=programming_routine_params, ) crossbars[channel_idx + 1].write_conductance_matrix( neg_conductance_matrix, transistor=transistor, programming_routine=programming_routine, programming_routine_params=programming_routine_params, ) channel_idx += 2 else: crossbars.append( memtorch.bh.crossbar.Crossbar( memristor_model, memristor_model_params, weights.shape, tile_shape, use_bindings=use_bindings, random_crossbar_init=random_crossbar_init, ) ) crossbars.append( memtorch.bh.crossbar.Crossbar( memristor_model, memristor_model_params, weights.shape, tile_shape, use_bindings=use_bindings, random_crossbar_init=random_crossbar_init, ) ) pos_conductance_matrix, neg_conductance_matrix = mapping_routine( weights_, reference_memristor_model.r_on, reference_memristor_model.r_off, scheme=scheme, p_l=p_l, ) crossbars[0].write_conductance_matrix( pos_conductance_matrix, transistor=transistor, programming_routine=programming_routine, programming_routine_params=programming_routine_params, ) crossbars[1].write_conductance_matrix( neg_conductance_matrix, transistor=transistor, programming_routine=programming_routine, programming_routine_params=programming_routine_params, ) def out(crossbars, operation, idx=(0, 1), **kwargs): assert ( len(idx) == 2 ), "idx must contain indicies of the positive and negative crossbars" return operation(crossbars[idx[0]], **kwargs) - operation( crossbars[idx[1]], **kwargs ) ``` -------------------------------- ### Tile Class Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Initializes a Tile object, which can store weights as a 2D tensor. It supports either a fixed tile shape or a shape determined by patch number and tile dimensions. ```python class Tile: """Class used to create modular crossbar tiles to represent 2D matrices. Parameters ---------- tile_shape : int, int Tile shape to use to store weights. patch_num : int Patch number. """ def __init__(self, tile_shape, patch_num=None): self.tile_shape = tile_shape self.patch_num = patch_num if patch_num is None: self.array = torch.zeros(tile_shape) else: self.array = torch.zeros((patch_num, tile_shape[0])) ``` -------------------------------- ### simulate Method Source: https://memtorch.readthedocs.io/en/latest/memtorch.bh.memristor.html Determines the equivalent conductance of a memristive device when a given voltage signal is applied. ```APIDOC ## simulate ### Description Method to determine the equivalent conductance of a memristive device when a given voltage signal is applied. ### Parameters * **voltage_signal** (torch.Tensor) - A discrete voltage signal with resolution time_series_resolution. ### Returns A tensor containing the equivalent device conductance for each simulated timestep. ### Return type torch.Tensor ``` -------------------------------- ### Memristor Abstract Base Class Initialization Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/memristor/Memristor.html Initializes a Memristor object with device parameters. This is the base class for all memristor models. ```python class Memristor(ABC): """ Parameters ---------- r_off : float Off (maximum) resistance of the device (ohms). r_on : float On (minimum) resistance of the device (ohms). time_series_resolution : float Time series resolution (s). pos_write_threshold : float Positive write threshold voltage (V). neg_write_threshold : float Negative write threshold voltage (V). """ def __init__( self, r_off, r_on, time_series_resolution, pos_write_threshold=0, neg_write_threshold=0, ): self.r_off = r_off self.r_on = r_on self.time_series_resolution = time_series_resolution self.pos_write_threshold = pos_write_threshold self.neg_write_threshold = neg_write_threshold self.g = None self.finite_states = None ``` -------------------------------- ### Tiled Inference (Bindings - CPU) Source: https://memtorch.readthedocs.io/en/latest/_modules/memtorch/bh/crossbar/Tile.html Performs tiled inference using bindings on CPU. Requires input tensor, layer parameters, and crossbar configurations. ```python if m.use_bindings: quant_method = m.quant_method if quant_method is None: if transistor: if "cpu" in memtorch.__version__: return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), m.crossbars[0].tiles_map, (m.crossbars[0].rows, m.crossbars[0].columns), ) else: return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), m.crossbars[0].tiles_map, (m.crossbars[0].rows, m.crossbars[0].columns), cuda_malloc_heap_size=m.cuda_malloc_heap_size, ) else: if "cpu" in memtorch.__version__: return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), m.crossbars[0].tiles_map, (m.crossbars[0].rows, m.crossbars[0].columns), m.source_resistance, m.line_resistance, ) else: return memtorch_bindings.tiled_inference( input, input.shape, m.tile_shape, m.crossbar_operation( m.crossbars, lambda crossbar: crossbar.conductance_matrix ), ```