def characterize(args, adcs, seed): with misc.push_random_state(): np.random.seed(seed) seeds = [np.random.randint(0, 4294967296) for _ in range(3)] assert not args.relative_snr_ref, "TODO implement relative" assert not args.relative_snr_thres, "TODO implement relative" min_snr_ref_v = args.min_snr_ref_v min_snr_thres_v = args.min_snr_thres_v fsr = adcs[0].stages[0].meta.fsr n_bits = int(np.sum([np.floor(stage.meta.n_bits) for stage in adcs[0].stages])) n_bits += int(gen.infer_thres_bits(adcs[0].tail)[0]) lsb = gen.compute_lsb(n_bits, *fsr) if min_snr_ref_v is None: min_snr_ref_v = lsb/2 if min_snr_thres_v is None: min_snr_thres_v = lsb/2 snr_ref_inv = np.linspace(0, min_snr_ref_v, args.samples_snr_ref) snr_thres_inv = np.linspace(0, min_snr_thres_v, args.samples_snr_thres) snr_ref = np.power((fsr[1] - fsr[0]), 2)/np.power(snr_ref_inv, 2) snr_thres = np.power((fsr[1] - fsr[0]), 2)/np.power(snr_thres_inv, 2) snr_ref[0] = 0 snr_thres[0] = 0 real_thres_s = data.at_least_ndarray(args.real_thres_s) shape = (np.size(real_thres_s), np.size(adcs),) adcs_sweep = np.tile(np.array(adcs, dtype=object), shape[:-1] + (1,)) # Sweep thres with misc.push_random_state(): np.random.seed(seed) for idx in cartesian(*tuple(range(s) for s in shape)): r_thres_s = real_thres_s[idx[0]] adcs_sweep[idx] = copy.deepcopy(adcs_sweep[idx]) for stage in adcs_sweep[idx].stages: r_thres_s_local = r_thres_s * stage.meta.lsb stage._thres = np.random.normal(stage.thres, r_thres_s_local) adcs_sweep[idx]._tail = np.random.normal(adcs_sweep[idx].tail, r_thres_s) uncertain = characterize_uncertanty(args, adcs_sweep, seed, real_thres_s) ref = characterize_noise(args, adcs_sweep, seed, snr_ref, real_thres_s, ref=True) thres = characterize_noise(args, adcs_sweep, seed, snr_thres, real_thres_s, ref=False) return uncertain, ref, thres
def _compute_u_center(self, thres): assert len(np.shape(thres)) == 2, "Need multiple thres instances." codes = self.codes fsr = self._start.meta.fsr half_bit = gen.infer_thres_bits(thres[0, ...])[1] lsb_ext = np.array([[gen.infer_thres_lsb(thres[ii, ...], fsr)] for ii in range(np.size(thres, 0))]) half_factor = 3 / 2 if half_bit else 1 extremes = ( thres[:, :1, ...] - half_factor * (lsb_ext / 2), thres[:, -1:, ...] + half_factor * (lsb_ext / 2), ) lsb = np.diff(thres, axis=1) mid = thres[:, :-1, ...] + lsb / 2 center_map = np.concatenate(( extremes[0], mid, extremes[1], ), axis=1) lsb = np.concatenate(( lsb_ext * half_factor, lsb, lsb_ext * half_factor, ), axis=1) def evaluate(arr): return np.transpose(arr[:, codes], ( 1, 0, 2, )) return evaluate(center_map), evaluate(lsb)
def save_stages(tb, path_context, location, dest): shape = tb.conf_shape + tb.shape array = len(shape) > 0 stages = np.full(shape, None) stages_ideal = np.full(shape, None) for idx in tb.iter_idx(): conf_idx, stage_idx = idx idx = conf_idx + stage_idx real = tb.stages[stage_idx] stages[idx] = real ideal = real.meta.generate_ideal() tail_bits, tail_half = gen.infer_thres_bits(real.thres) thres_ideal = gen.compute_thres(tail_bits, *real.meta.fsr, half_bit=tail_half) ideal._thres = thres_ideal stages_ideal[idx] = ideal NestedStages = data.nested_lists_of(gen.StageParameters) dims = len(shape) stages = NestedStages(stages.tolist() if array else stages[tuple()], dims) stages_ideal = NestedStages( stages_ideal.tolist() if array else stages_ideal[tuple()], dims) stages_location = data.DataLocation(path_context, location, dest + ".stages", "json") print(" saving {}...".format(stages_location.computed_path)) data.save(stages if array else stages[tuple()], stages_location) ideal_location = data.DataLocation(path_context, location, dest + ".stages.ideal", "json") print(" saving {}...".format(ideal_location.computed_path)) data.save(stages_ideal if array else stages_ideal[tuple()], ideal_location)
def system(self, x, scalar=False, use_bands=None, sum_conf=None, limit_samples=None, lsb_scale=1): if scalar: x = [x] cm, eff, caps, refs, thres, ins = self._map_internal(x) ext_codes = self._codes[:, np.newaxis, ...] if not hasattr(self, "_cache"): self._cache = {} base_shape = np.shape(x)[:-1] if base_shape not in self._cache: print("Generating cache for {}".format(base_shape)) self._cache[base_shape] = self.recreate_cache( eff, caps, refs, thres, ins, cm, self._configuration_sequence, ext_codes) use_bands = default(use_bands, self.use_bands) sum_conf = default(sum_conf, self.sum_conf) ext_codes = self._codes[:, np.newaxis, ...] u = self.recreate(eff, caps, refs, thres, ins, cm, self._configuration_sequence, self._cache[base_shape], limit_samples=limit_samples) meta = self._configuration_sequence.meta # Ignore last u since it is not converted to code u = np.diff(u[:-1, :, ...], axis=-1) if meta.differential else u[:-1, :, ..., -1] samples = np.size(u, 0) u_center, lsb = self._compute_u_center(thres) thres_bits, thres_half = gen.infer_thres_bits(thres[0, ...]) ideal_lsb = gen.compute_lsb(thres_bits, *self._start.meta.fsr, thres_half) lsb = lsb + ideal_lsb * (lsb_scale - 1) if use_bands else np.zeros(( samples, 1, 1, )) result = np.maximum( np.abs(u - u_center[:samples, ...]) - lsb[:samples, ...] / 2, 0) if DEBUG: # FIXME import matplotlib.pyplot as plots try: print(np.shape(result)) sum_axis = tuple(range(len(np.shape(result)) - 1)) cut = (np.sum(result, axis=sum_axis) > 0).tolist().index(True) print("Found cut {}".format(cut)) except: cut = 10 print("Not found cut") x_thres = np.stack(( np.zeros_like(thres[0, :]), np.full_like(thres[0, :], samples), ), axis=0) y_thres = np.stack((thres[0, :], ) * 2, axis=0) plots.plot(x_thres, y_thres, c='orange', linestyle='-.') plots.plot(u[:, 0, cut, ...], 'r') internal, _ = self.configuration_sequence.configuration_sets[ 0].generate_in(self.configuration_sequence. configuration_sets[0].ds_samples) internal = np.sum(internal, axis=( -2, -1, )) plots.plot(0.25 * (internal[:, cut, ...] - 1.5), 'cyan') #plots.plot(internal[:samples, cut, ...], 'k') adj_codes = (0.5 / (np.max(self._codes))) * (self._codes - np.max(self._codes) / 2) plots.plot(adj_codes[:samples, cut, ...], 'k') plots.plot(u_center[:samples, 0, cut, ...], 'b') plots.plot(u_center[:samples, 0, cut, ...] + lsb[:samples, 0, cut, ...] / 2, 'g', linestyle='--') plots.plot(u_center[:samples, 0, cut, ...] - lsb[:samples, 0, cut, ...] / 2, 'g', linestyle='--') plots.show() if scalar: result = result[:, 0, ...] else: result = np.transpose(result, ( 1, 0, ) + tuple(range(2, len(np.shape(result))))) sum_axis = ( -2, -1, ) if sum_conf else (-2, ) result = np.sum(result, axis=sum_axis) if PRINT_ERROR: print("System error: {}".format(np.sum(np.power(result, 2)))) return result
def run(args): assert len(args.bits) == len(args.seed) directory = args.location mkdir(misc.Namespace(directory=directory, mode="750")) path_context = data.PathContext.relative() names = [ "paper_set_{}{}".format(ii, "_DRY" if DRY_RUN else "") for ii in range(len(args.bits)) ] if not JUST_PLOT: for ii, bits, seed, name in zip(count(), args.bits, args.seed, names): print("SET {}/{}".format(ii + 1, len(args.bits))) adcs = gen_adc(bits, seed, args, args.n_adcs) uncertain, ref, thres = characterize(args, adcs, seed) if 0 in TESTS: uncertain = prepickle_data(uncertain, path_context, directory, "{}.{}".format(name, "uncertain")) else: uncertain = None if 1 in TESTS: ref = prepickle_data(ref, path_context, directory, "{}.{}".format(name, "ref")) else: ref = None if 2 in TESTS: thres = prepickle_data(thres, path_context, directory, "{}.{}".format(name, "thres")) else: thres = None with open(name, 'wb') as f: pickle.dump(( uncertain, ref, thres, ), f, protocol=pickle.HIGHEST_PROTOCOL) for name in names: with open(name, 'rb') as f: dat = pickle.load(f) uncertain, ref, thres = dat uncertain = postpickle_data(uncertain, path_context) ref = postpickle_data(ref, path_context) thres = postpickle_data(thres, path_context) dat = ( uncertain, ref, thres, ) real_thres_s = data.at_least_ndarray(args.real_thres_s) sample_adc = dat[TESTS[0]][0][0, 0, 0] fsr = sample_adc.stages[0].meta.fsr n_bits = int( np.sum([ np.floor(stage.meta.n_bits) for stage in sample_adc.stages ])) n_bits += int(gen.infer_thres_bits(sample_adc.tail)[0]) lsb = gen.compute_lsb(n_bits, *fsr) min_snr_ref_v = args.min_snr_ref_v min_snr_thres_v = args.min_snr_thres_v if min_snr_ref_v is None: min_snr_ref_v = lsb / 2 if min_snr_thres_v is None: min_snr_thres_v = lsb / 2 snr_ref_inv = np.linspace(0, min_snr_ref_v, args.samples_snr_ref) snr_thres_inv = np.linspace(0, min_snr_thres_v, args.samples_snr_thres) u_args = ( "{}.uncertain".format(name), uncertain, ( "Real threshold voltage standard deviation (LSB)", "Modeled std (LSB)", ), ) u_kwargs = {"x_axes": real_thres_s, "y_axes": real_thres_s} t_args = ( "{}.thres".format(name), thres, ( "Real threshold voltage standard deviation (LSB)", "Thres. noise (SNR)", ), ) t_kwargs = { "x_axes": real_thres_s, "y_axes": snr_thres_inv, "noise": True } r_args = ( "{}.ref".format(name), ref, ( "Real threshold voltage standard deviation (LSB)", "Ref. noise (SNR)", ), ) r_kwargs = { "x_axes": real_thres_s, "y_axes": snr_ref_inv, "noise": True } if TOGETHER: f = plots.figure(figsize=( 10, 4, ) if FULL_SIZE else ( 5 * 1.5, 2 * 1.5, )) ax = f.add_subplot(111) h0 = [] h1 = [] h2 = [] brightness = 1 if 0 in TESTS: f, ax, h0 = plot2d(*u_args, **u_kwargs, ax=ax, color=(brightness, 0, 0), first_black=True, index=0, legend_handlers=h0, hide_constants=False) h0 = reversed(h0) if 2 in TESTS: f, ax, h2 = plot2d(*t_args, **t_kwargs, ax=ax, color=(0, 0, brightness), first_black=None, index=2, legend_handlers=h2) h2 = reversed(h2) if 1 in TESTS: f, ax, h1 = plot2d(*r_args, **r_kwargs, ax=ax, color=(0, brightness, 0), first_black=None, index=1, legend_handlers=h1) h1 = reversed(h1) h = [] for hh in (h0, h1, h2): h.extend(hh) proportion = 0.65 box = ax.get_position() ax.set_position( [box.x0, box.y0, box.width * proportion, box.height]) ax.set_facecolor((0.85, ) * 3) legend_handlers = h paths, names = tuple(zip(*legend_handlers)) f.legend(paths, names, loc='center left', bbox_to_anchor=(proportion, 0.5)) prev = mpl.rcParams['hatch.linewidth'] mpl.rcParams['hatch.linewidth'] = 5.0 f.savefig("{}.png".format(name), dpi=300) plots.show() mpl.rcParams['hatch.linewidth'] = prev else: if 0 in TESTS: plot2d(*u_args, **u_kwargs, color=(0.8, 0, 1), hide_constants=False) if 1 in TESTS: plot2d(*r_args, **r_kwargs, color=(0.8, 0, 1), hide_constants=False) if 2 in TESTS: plot2d(*t_args, **t_kwargs, color=(0.8, 0, 1), hide_constants=False) print("DONE")