Skip to content

Commit 57ffc04

Browse files
committed
3.1.1 Release
- Bug fixes to AnalogCore and Keras network conversion - New Array circuit simulation interface for improved and more flexible parasitics simulation - Improvement to torch gradient calculation and AnalogLayer interface changes to support new approach
1 parent f1585c0 commit 57ffc04

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1226
-1787
lines changed

applications/dnn/calibration.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import numpy.typing as npt
1717
import numpy as np
1818
from scipy.optimize import minimize
19-
from simulator.parameters.core_parameters import CoreStyle
19+
from simulator.parameters.core_parameters import CoreStyle, BitSlicedCoreStyle
2020
from simulator.backend import ComputeBackend
2121
xp = ComputeBackend()
2222

@@ -30,6 +30,9 @@ def calibrate_input_limits(
3030
input values. This function is intended for use with ResNet CNNs where
3131
all but the first layer is precded by a ReLU, so inputs are strictly positive.
3232
33+
Note that this method may not work well for the first layer which has a different
34+
value distribution from the other layers!
35+
3336
Args:
3437
all_xbar_inputs: list of arrays, each array contains profiled input
3538
values for a layer

applications/dnn/dnn_inference_params.py

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ def dnn_inference_params(**kwargs):
3535

3636
Rp_row = kwargs.get("Rp_row",0)
3737
Rp_col = kwargs.get("Rp_col",0)
38+
Rp_row_terminal = kwargs.get("Rp_row_terminal",0)
39+
Rp_col_terminal = kwargs.get("Rp_col_terminal",0)
3840
NrowsMax = kwargs.get("NrowsMax",None)
3941
NcolsMax = kwargs.get("NcolsMax",None)
4042
weight_bits = kwargs.get("weight_bits",0)
@@ -47,13 +49,14 @@ def dnn_inference_params(**kwargs):
4749
adc_type = kwargs.get("adc_type","generic")
4850
positiveInputsOnly = kwargs.get("positiveInputsOnly",False)
4951
interleaved_posneg = kwargs.get("interleaved_posneg",False)
52+
current_from_input = kwargs.get("current_from_input",True)
53+
selected_rows = kwargs.get("selected_rows","top")
5054
subtract_current_in_xbar = kwargs.get("subtract_current_in_xbar",True)
5155
Rmin = kwargs.get("Rmin", 1000)
5256
Rmax = kwargs.get("Rmax", 10000)
5357
Vread = kwargs.get("Vread",0.1)
5458
infinite_on_off_ratio = kwargs.get("infinite_on_off_ratio", True)
55-
gate_input = kwargs.get("gate_input",True)
56-
59+
5760
Nslices = kwargs.get("Nslices",1)
5861
digital_offset = kwargs.get("digital_offset",True)
5962
adc_range_option = kwargs.get("adc_range_option","CALIBRATED")
@@ -64,19 +67,16 @@ def dnn_inference_params(**kwargs):
6467
y_par = kwargs.get("y_par",1)
6568
useGPU = kwargs.get("useGPU",False)
6669
gpu_id = kwargs.get("gpu_id",0)
67-
disable_fast_balanced = kwargs.get("disable_fast_balanced",False)
6870

6971
profile_xbar_inputs = kwargs.get("profile_xbar_inputs",False)
7072
profile_adc_inputs = kwargs.get("profile_adc_inputs",False)
71-
profile_adc_reluAware = kwargs.get("profile_adc_reluAware",False)
7273
ntest = kwargs.get("ntest",1)
7374

7475
balanced_style = kwargs.get("balanced_style","ONE_SIDED")
7576
input_bitslicing = kwargs.get("input_bitslicing",False)
7677
input_slice_size = kwargs.get("input_slice_size",1)
7778
adc_per_ibit = kwargs.get("adc_per_ibit",False)
78-
disable_parasitics_slices = kwargs.get("disable_parasitics_slices",None)
79-
79+
8080
################ create parameter objects with all core settings
8181
params = CrossSimParameters()
8282

@@ -85,27 +85,9 @@ def dnn_inference_params(**kwargs):
8585
if useGPU:
8686
params.simulation.gpu_id = gpu_id
8787

88-
# Enable conv matmul?
89-
# These cases cannot be realistically modeled with matmul
90-
noCM_cond1 = (Rp_col > 0)
91-
noCM_cond2 = (Rp_row > 0 and not gate_input)
92-
noCM_cond3 = (noise_model == "generic" and alpha_noise > 0)
93-
noCM_cond4 = (noise_model != "none" and noise_model != "generic")
94-
if not ideal and any([noCM_cond1, noCM_cond2, noCM_cond3, noCM_cond4]):
95-
params.simulation.disable_fast_matmul = True
96-
else:
97-
params.simulation.disable_fast_matmul = False
98-
x_par, y_par = 1, 1
99-
100-
if profile_adc_inputs:
101-
x_par, y_par = 1, 1
102-
103-
# Multiple convolutional MVMs in parallel? (only used if disable_fast_matmul = True)
104-
params.simulation.convolution.x_par = int(x_par) # Number of sliding window steps to do in parallel (x)
105-
params.simulation.convolution.y_par = int(y_par) # Number of sliding window steps to do in parallel (y)
106-
107-
if core_style == "BALANCED":
108-
params.simulation.disable_fast_balanced = disable_fast_balanced
88+
# Parameters for SW packing mode (only used if simulation.disable_fast_matmul = True)
89+
params.simulation.convolution.x_par = int(x_par)
90+
params.simulation.convolution.y_par = int(y_par)
10991

11092
if ideal:
11193
return params
@@ -170,20 +152,21 @@ def dnn_inference_params(**kwargs):
170152

171153
############### Parasitic resistance
172154

173-
if Rp_col > 0 or Rp_row > 0:
155+
if Rp_col > 0 or Rp_row > 0 or Rp_col_terminal > 0 and Rp_row_terminal > 0:
174156
# Bit line parasitic resistance
175157
params.xbar.array.parasitics.enable = True
176-
params.xbar.array.parasitics.Rp_col = Rp_col/Rmin
177-
params.xbar.array.parasitics.Rp_row = Rp_row/Rmin
178-
params.xbar.array.parasitics.gate_input = gate_input
179-
180-
if gate_input and Rp_col == 0:
181-
params.xbar.array.parasitics.enable = False
158+
params.xbar.array.parasitics.Rp_col = Rp_col
159+
params.xbar.array.parasitics.Rp_row = Rp_row
160+
params.xbar.array.parasitics.Rp_col_terminal = Rp_col_terminal
161+
params.xbar.array.parasitics.Rp_row_terminal = Rp_row_terminal
162+
params.xbar.array.parasitics.current_from_input = current_from_input
163+
params.xbar.array.parasitics.selected_rows = selected_rows
182164

183165
# Numeric params related to parasitic resistance simulation
184166
params.simulation.Niters_max_parasitics = 100
185167
params.simulation.Verr_th_mvm = 2e-4
186168
params.simulation.relaxation_gamma = 0.9 # under-relaxation
169+
params.simulation.Verr_matmul_criterion = "max_mean" # max over array, max over MVMs
187170

188171
############### Weight bit slicing
189172

@@ -202,10 +185,6 @@ def dnn_inference_params(**kwargs):
202185
else:
203186
cell_bits = int(np.ceil(weight_bits/Nslices))
204187
params.core.bit_sliced.num_slices = Nslices
205-
if disable_parasitics_slices is not None:
206-
params.xbar.array.parasitics.disable_slices = disable_parasitics_slices
207-
else:
208-
params.xbar.array.parasitics.disable_slices = [False]*Nslices
209188

210189
# Weights
211190
params.core.weight_bits = int(weight_bits)
@@ -220,7 +199,7 @@ def dnn_inference_params(**kwargs):
220199
###################### Analytics
221200

222201
params.simulation.analytics.profile_xbar_inputs = profile_xbar_inputs
223-
params.simulation.analytics.profile_adc_inputs = (profile_adc_inputs and not profile_adc_reluAware)
202+
params.simulation.analytics.profile_adc_inputs = profile_adc_inputs
224203
params.simulation.analytics.ntest = ntest
225204

226205
###################### DAC settings

applications/dnn/inference/interface/inference_net.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ def set_params(**kwargs):
105105
params.simulation.convolution.x_par = int(x_par) # Number of sliding window steps to do in parallel (x)
106106
params.simulation.convolution.y_par = int(y_par) # Number of sliding window steps to do in parallel (y)
107107

108-
if export_conductances:
109-
params.simulation.disable_fast_balanced = True
110-
111108
if export_conductances:
112109
params.simulation.disable_fast_balanced = True
113110

applications/dnn/inference/readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ More details on this process can be found in Section 9.4 of the manual.
4949

5050
The optimized ADC limits are only valid for a specific combination of neural network and hardware settings. The ``adc_limits`` directory contains calibrated ADC limits for a number of neural networks that are part of the ``cross-sim-models`` submodule, but does not account for every possible simulation configuration with these models. The most extensive set of ADC limits we have generated are for the ResNet50-v1.5 network (part of the MLPerf Inference benchmark). These can be found inside the ``adc_limits/imagenet`` and ``adc_limits/imagenet_bitslicing`` folders. See ``interface/dnn_setup.py`` to see the simulation settings that are matched to these different calibrated ADC limits.
5151

52-
[1] T. P. Xiao, B. Feinberg, C. H. Bennett, V. Prabhakar, P. Saxena, V. Agrawal, S. Agarwal, and M. J. Marinella, "On the accuracy of analog neural network inference accelerators," _IEEE Circuits and Systems Magazine_, 22(4), pp. 26-48, 2022.
52+
[1] T. P. Xiao, B. Feinberg, C. H. Bennett, V. Prabhakar, P. Saxena, V. Agrawal, S. Agarwal, and M. J. Marinella, "On the accuracy of analog neural network inference accelerators," _IEEE Circuits and Systems Magazine_, 22(4), pp. 26-48, 2022.

applications/dnn/keras/cifar10_resnet/calibrate_adcs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
# n = 3 : ResNet-20 (272K weights)
3232
# n = 5 : ResNet-32 (467K weights)
3333
# n = 9 : ResNet-56 (856K weights)
34-
n = 9
34+
n = 3
3535

3636
useGPU = True # use GPU?
37-
N = 1000 # number of images
37+
N = 500 # number of images
3838
batch_size = 32
3939
Nruns = 1
4040
print_progress = True
@@ -84,7 +84,7 @@
8484
'Rp_col' : 0, # ohms
8585
'interleaved_posneg' : False,
8686
'subtract_current_in_xbar' : True,
87-
'gate_input' : False,
87+
'current_from_input' : True,
8888
## Input quantization
8989
'input_bits' : 8,
9090
'input_bitslicing' : False,

applications/dnn/keras/cifar10_resnet/calibrate_inputs.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@
3131
# n = 3 : ResNet-20 (272K weights)
3232
# n = 5 : ResNet-32 (467K weights)
3333
# n = 9 : ResNet-56 (856K weights)
34-
n = 9
34+
n = 3
3535

3636
useGPU = True # use GPU?
37-
N = 1000 # number of images
37+
N = 500 # number of images
3838
batch_size = 32
3939
Nruns = 1
4040
print_progress = True
@@ -84,7 +84,7 @@
8484
'Rp_col' : 0, # ohms
8585
'interleaved_posneg' : False,
8686
'subtract_current_in_xbar' : True,
87-
'gate_input' : False,
87+
'current_from_input' : True,
8888
## Input quantization
8989
'input_bits' : 0,
9090
'input_bitslicing' : False,
@@ -149,5 +149,8 @@
149149
print("Optimizing input limits")
150150
calibrated_ranges = calibrate_input_limits(profiled_inputs, Nbits=8)
151151

152+
# Manually calibrate first layer's limits based on value range of CIFAR-10 images
153+
calibrated_ranges[0,:] = np.array([-2.64, 2.64])
154+
152155
np.save("./calibrated_config/input_limits_ResNet{:d}.npy".format(depth),
153156
calibrated_ranges)

applications/dnn/keras/cifar10_resnet/inference_cifar10_resnet.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
'Rp_col' : 0, # ohms
7878
'interleaved_posneg' : False,
7979
'subtract_current_in_xbar' : True,
80-
'gate_input' : False,
80+
'current_from_input' : True,
8181
## Input quantization
8282
'input_bits' : 8,
8383
'input_bitslicing' : False,
@@ -97,19 +97,12 @@
9797
### Load ADC limits
9898
adc_ranges = find_adc_range(base_params_args, n_layers, depth)
9999

100-
### Load (x_par, y_par) values
101-
xy_pars = np.load("./calibrated_config/resnet{:d}_xy.npy".format(depth))
102-
if base_params_args['Rp_row'] > 0 or base_params_args['Rp_col'] > 0:
103-
xy_pars = np.load("./calibrated_config/resnet{:d}_xy_parasitics.npy".format(depth))
104-
105100
### Set the parameters
106101
for k in range(n_layers):
107102
params_args_k = base_params_args.copy()
108103
params_args_k['positiveInputsOnly'] = (False if k == 0 else True)
109104
params_args_k['input_range'] = input_ranges[k]
110105
params_args_k['adc_range'] = adc_ranges[k]
111-
params_args_k['x_par'] = xy_pars[k,0]
112-
params_args_k['y_par'] = xy_pars[k,1]
113106
params_list[k] = dnn_inference_params(**params_args_k)
114107

115108
# Convert Keras layers to analog layers

0 commit comments

Comments
 (0)