def _JsonDictToArgs(cls, path_context, data_location, dct, memo=None): _, args, kwargs = super()._JsonDictToArgs(path_context, data_location, dct, memo=memo) StagesType = data.nested_lists_of(gen.StageParameters) ConfType = data.nested_lists_of(gen.ConfigurationSequence) args.append(StagesType.Load(path_context, dct["stages"], memo=memo)) ins = data.NumpyData.Load(path_context, dct["ins"], memo=memo) try: shape = dct["ins_shape"] ins = np.reshape(ins, shape) except KeyError: pass args.append(ins) args.append( ConfType.Load(path_context, dct["configuration_sequence"], memo=memo)) kwargs["shape"] = None if dct["shape"] is None else tuple(dct["shape"]) return cls, args, kwargs
def run(args): path_context = data.PathContext.relative() stages_location = [ data.DataLocation(path_context, args.location, source, "json") for source in getattr(args, "stages-sources") ] NestedStages = data.nested_lists_of(gen.StageParameters) all_stages = [] for stage_loc in stages_location: print(" loading {}...".format(stage_loc.computed_path)) stage = data.load(NestedStages, stage_loc) all_stages.append(stage) assert len(all_stages) > 0 shape = np.shape(all_stages[0].data) assert all(shape == np.shape(stages.data) for stages in all_stages[1:]) adcs = np.full(shape, None) for idx in all_stages[0].iter_idx(): stages = tuple(stages[idx] for stages in all_stages) thresholds = [stage.thres for stage in stages] meta0 = stages[0].meta thresholds = [ gen.compute_thres( meta0.n_bits, *meta0.fsr, half_bit=meta0.half_bit) ] + thresholds thresholds, tail = thresholds[:-1], thresholds[-1] assert all(stage.meta.n_codes == np.size(thres) + 1 for stage, thres in zip(stages, thresholds)) stages = [ gen.StageParameters(s.meta, s.eff, s.caps, s.refs, thres, s.common_mode) for s, thres in zip(stages, thresholds) ] adcs[idx] = gen.PipeParameters(stages, tail) adcs = data.nested_lists_of(gen.PipeParameters)(adcs.tolist(), len(np.shape(adcs))) adcs_location = data.DataLocation(path_context, args.location, args.dest, "json") print(" saving {}...".format(adcs_location.computed_path)) data.save(adcs, adcs_location)
def as_scalars(self): result = np.zeros(self.conf_shape + self.shape, dtype=object) for idx_conf, idx_stage in self.iter_idx(): ins = self.ins[idx_stage + (Ellipsis, )] stage = self.stages[idx_stage] conf = self.configuration_sequence[idx_conf] result[idx_conf + idx_stage] = StageTestbench.Scalar( stage, ins, conf) ResultType = data.nested_lists_of(StageTestbench) return ResultType(result.tolist(), dims=len(np.shape(result)))
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 __init__(self, stages, ins, configuration_sequence, shape=None, data_location=None): super().__init__(data_location) NestedStages = data.nested_lists_of(gen.StageParameters) NestedSequences = data.nested_lists_of(gen.ConfigurationSequence) if not isinstance(configuration_sequence, NestedSequences): conf_shape = np.shape(configuration_sequence) configuration_sequence = NestedSequences(configuration_sequence, len(conf_shape)) conf_shape = np.shape(configuration_sequence.data) if not isinstance(stages, NestedStages): shape = default(shape, np.shape(stages)) dims = len(shape) cur = stages root_arr = stages # Check a valid 0,0,0... for dd in range(dims): assert isinstance(cur, ( tuple, list, )) cur = cur[0] # Check elements for idx in cartesian(*tuple(range(ss) for ss in shape)): assert isinstance(misc.getitem(stages, idx), gen.StageParameters) # Check regularity def rec_check(lst, shape): valid = (not isinstance(lst, list) and len(shape) == 0) or len(lst) == shape[0] if len(shape) > 1: sub_shape = shape[1:] valid = valid and all( [rec_check(llst, sub_shape) for llst in lst]) return valid assert rec_check(stages, shape) else: stages_shape = np.shape(stages.data) shape = default(shape, stages_shape) assert shape == stages_shape dims = len(shape) root_arr = stages.data ref_element = misc.getitem(root_arr, (0, ) * dims) ins = data.at_least_ndarray(ins) if len(np.shape(ins)) == 1: ins = ins[..., np.newaxis] # Broadcast ins if len(np.shape(ins)) == 2: ins = ins[(np.newaxis, ) * dims + (Ellipsis, )] ins = np.tile(ins, shape + ( 1, 1, )) assert len(np.shape(ins)) == dims + 2 if np.size(ins, -1) != ref_element.meta.n_diff: cm = ref_element.meta.common_mode ins = np.concatenate(( cm - ins, cm + ins, ), axis=1) # All meta the same for idx in cartesian(*tuple(range(ss) for ss in shape)): c_element = misc.getitem(root_arr, idx) assert c_element.meta == ref_element.meta self._stages = NestedStages.EnsureIsInstance(stages) self._shape = shape self._ins = ins self._configuration_sequence = configuration_sequence
def run(args): seed = None if args.seed is None else int(args.seed) path_context = data.PathContext.relative() testbench_location = data.DataLocation(path_context, args.location, args.source, "json") cache = bool(args.cache) array = bool(args.array) serial = bool(args.serial) print(" loading {}...".format(testbench_location.computed_path)) testbench = data.load(sims.StageTestbench, testbench_location) simulator = sims.Simulator(seed, args.ref_snr, args.thres_snr, args.test_snr) testbenches = testbench.as_scalars() if serial else testbench iter_shape = testbench.conf_shape + testbench.shape if serial else tuple() codes = np.full(iter_shape, None, dtype=object) us = np.full(iter_shape, None, dtype=object) iter_idx = tuple(cartesian(*tuple( range(ss) for ss in iter_shape))) if serial else (tuple(), ) for ii, idx in enumerate(iter_idx): bench = testbenches[idx] if serial else testbenches if cache: print(" building cache...") for conf_idx in bench.iter_conf_idx(): bench.configuration_sequence[conf_idx].build_cache() print(" simulating...") code, u = bench.simulate(simulator, raise_=bool(getattr(args, "raise"))) indexes = list(bench.iter_idx()) fsr = [bench.stages[idx_stage].meta.fsr for _, idx_stage in indexes] out_of_range = [] for ff, fsr_idx in zip(fsr, indexes): idx_conf, idx_stage = fsr_idx iidx = idx_conf + idx_stage outs = np.logical_or(u[iidx + (Ellipsis, )] > ff[1], u[iidx + (Ellipsis, )] < ff[0]) if outs.any(): out_of_range.append((np.sum(outs), np.size(outs), ff)) for outs in out_of_range: sum_, size_, fsr = outs warnings.warn( "{}/{} samples are out of range (fsr: {}, {})".format( sum_, size_, *fsr)) codes[idx] = code us[idx] = u c_name = "{}.c".format(args.dest) u_name = "{}.u".format(args.dest) if array: ext = "json" NestedNum = data.nested_lists_of(data.NumpyData) data_code = np.full(iter_shape, None) data_u = np.full(iter_shape, None) for idx in testbench.iter_idx(): idx = idx[0] + idx[1] data_code[idx] = data.at_least_numpydata(codes[idx]) data_u[idx] = data.at_least_numpydata(us[idx]) codes = NestedNum(data_code.tolist(), dims=len(np.shape(data_code))) us = NestedNum(data_u.tolist(), dims=len(np.shape(data_u))) codes.set_children_data_location( data.DataLocation(path_context, args.location, c_name, "npy")) us.set_children_data_location( data.DataLocation(path_context, args.location, u_name, "npy")) else: codes = np.array(codes.tolist()) us = np.array(us.tolist()) samples_index = len(iter_shape) if samples_index > 0: transpose_indexes = ( (samples_index, ) + tuple(range(samples_index)) + tuple(range(samples_index + 1, len(np.shape(codes))))) codes = np.transpose(codes) us = np.transpose(us) ext = "npy" code_location = data.DataLocation(path_context, args.location, c_name, ext) u_location = data.DataLocation(path_context, args.location, u_name, ext) print(" saving {}...".format(code_location.computed_path)) data.save(codes, code_location) if bool(args.store_u): print(" saving {}...".format(u_location.computed_path)) data.save(us, u_location)
def run(args): path_context = data.PathContext.relative() adcs_location = data.DataLocation(path_context, args.location, args.adcs, "json") estimations_location = (adcs_location if args.estimation is None else data.DataLocation(path_context, args.location, args.estimation, "json")) NestedAdcs = data.nested_lists_of(gen.PipeParameters) print(" loading {}...".format(adcs_location.computed_path)) adcs = data.load(NestedAdcs, adcs_location) print(" loading {}...".format(estimations_location.computed_path)) estimations = data.load(NestedAdcs, estimations_location) extras = [] for extra in args.extra: extra_location = data.DataLocation(path_context, args.location, extra, "json") print(" loading {}...".format(extra_location.computed_path)) extras.append(data.load(NestedAdcs, extra_location)) def snr(real_adc, est_adc): magnitude = an.snr(real_adc, est_adc, sampling_factor=args.sampling_factor) return an.snr_to_enob(magnitude) shape = np.shape(adcs.data) assert shape == np.shape(estimations.data) for extra in extras: assert shape == np.shape(extra.data) real_snr = np.empty(shape) ideal_snr = np.empty(shape) est_snr = np.empty(shape) extras_snr = [np.empty(shape) for _ in range(len(extras))] iter_idx = (tuple(), ) if len(shape) == 0 else cartesian(*tuple( range(ss) for ss in shape)) for idx in iter_idx: real = adcs[idx] est = estimations[idx] real_snr[idx] = snr(real, real) ideal_snr[idx] = snr(real, real.as_ideal()) est_snr[idx] = snr(real, est) for ii, extra in enumerate(extras): extras_snr[ii][idx] = snr(real, extra[idx]) keep_axis = None if args.keep_axis is None else int(args.keep_axis) if keep_axis is not None: axes = list(range(len(shape))) axes.pop(keep_axis) axes = tuple(axes) def reduce_(arr): return ( np.mean(arr, axis=axes), np.std(arr, axis=axes), ) else: def reduce_(arr): return ( arr, None, ) real_snr = reduce_(real_snr) ideal_snr = reduce_(ideal_snr) est_snr = reduce_(est_snr) extras_snr = [reduce_(e_snr) for e_snr in extras_snr] x_param = args.x_param if x_param is None: canvas = enob_compare(args, real_snr, ideal_snr, est_snr, extras_snr) else: assert keep_axis is not None samples = shape[keep_axis] if x_param == 'eff': def element(idx): return (0, ) * keep_axis + ( idx, ) + (0, ) * (len(shape) - 1 - keep_axis) samples_idx = tuple(element(ii) for ii in range(samples)) x_axis = [adcs[idx].stages[0].eff.item() for idx in samples_idx] x_label = "Charge transfer efficiency" else: assert args.testbench is not None, "Testbench required for x-param" testbench_loc = data.DataLocation(path_context, args.location, args.testbench, "json") testbench = data.load(sims.StageTestbench, testbench_loc) conf_shape = testbench.conf_shape def element(idx): return (0, ) * keep_axis + ( idx, ) + (0, ) * (len(conf_shape) - 1 - keep_axis) samples_idx = tuple(element(ii) for ii in range(samples)) def conf_seq(idx): return testbench.configuration_sequence[idx] if x_param == 'samples': x_axis = [conf_seq(idx).samples for idx in samples_idx] x_label = "Samples" if x_param == 'switches': x_axis = [ len(conf_seq(idx).configuration_sets) for idx in samples_idx ] x_label = "Switching" canvas = enob_improvement(args, real_snr, ideal_snr, est_snr, extras_snr, x_axis, x_label) dest_location = data.DataLocation(path_context, args.location, args.dest, "json") print(" saving {}...".format(dest_location.computed_path)) data.save(canvas, dest_location)