Пример #1
0
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
Пример #2
0
    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)
Пример #3
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)
Пример #4
0
    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
Пример #5
0
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")