示例#1
0
    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
示例#2
0
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)
示例#3
0
    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)))
示例#4
0
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)
示例#5
0
    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
示例#6
0
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)
示例#7
0
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)