Commit 2d7d7293 authored by Mario's avatar Mario
Browse files

dut_lib.load and save and sim_con.run_and_read(validate)

parent dfb1abc5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

### Added
    - to_feather and from_feather method overwrites to DMT.DataFrame
    - DutLib save version 1.1: Added back proper load on from different path
    - optional validate Flag for sim_con.read_and_run()

### Fixed
    - hidden bug in naming.get_specifier_from_string when a specifier is repeated in a non-convertable string
+32 −20
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ try:
except ImportError:
    pass

SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=0)
SEMVER_DUTLIB_CURRENT = VersionInfo(major=1, minor=1)


class __Filter(object):
@@ -542,6 +542,7 @@ class DutLib(object):
            "wafer": self.wafer,
            "date_tapeout": self.date_tapeout,
            "date_received": self.date_received,
            "save_dir": str(self._save_dir),
            "__DutLib__": str(
                SEMVER_DUTLIB_CURRENT
            ),  # make versions, so we can introduce compatibility here!}
@@ -579,7 +580,12 @@ class DutLib(object):
        if (lib_directory / "dut_lib.json").exists():
            with (lib_directory / "dut_lib.json").open("r", encoding="utf8") as file_json:
                json_content = json.load(file_json)
            if not json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT:

            if json_content["__DutLib__"] == SEMVER_DUTLIB_CURRENT:
                pass
            elif json_content["__DutLib__"] == VersionInfo(major=1, minor=0):
                print("DMT:DutLib:load(): Loading an old lib. This will work, if the machine if the path stays the same. Otherwise, add 'save_dir' key to the dut_lib.json manually.")
            else:
                raise IOError("DMT.DutLib: Tried to load a DutLib with unkown version.")

            for key, value in json_content.items():
@@ -610,6 +616,11 @@ class DutLib(object):
            dut_lib.date_tapeout = json_content["date_tapeout"]
            dut_lib.date_received = json_content["date_received"]

            try:
                dut_lib._save_dir = json_content["save_dir"]
            except KeyError:
                pass

        elif (lib_directory / "dut_lib.p").exists():
            with (lib_directory / "dut_lib.p").open(mode="rb") as handle:
                dut_lib = cpickle.load(handle)
@@ -645,23 +656,24 @@ class DutLib(object):
                dut_lib.duts.append(DutView.load_dut(file_dut))

        # correct dut paths:
        if save_dir_old:
            if dut_lib.dut_ref_dut_dir is not None:
                dut_lib.dut_ref_dut_dir = Path(dut_lib.dut_ref_dut_dir)
                if not dut_lib.dut_ref_dut_dir.exists():
                    dut_lib.dut_ref_dut_dir = Path(
                    str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory))
                        str(dut_lib.dut_ref_dut_dir).replace(save_dir_old, str(lib_directory), 1)
                    )
            if dut_lib.dut_internal_dut_dir is not None:
                dut_lib.dut_internal_dut_dir = Path(dut_lib.dut_internal_dut_dir)
                if not dut_lib.dut_internal_dut_dir.exists():
                    dut_lib.dut_internal_dut_dir = Path(
                    str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory))
                        str(dut_lib.dut_internal_dut_dir).replace(save_dir_old, str(lib_directory), 1)
                    )
            if dut_lib.dut_intrinsic_dut_dir is not None:
                dut_lib.dut_intrinsic_dut_dir = Path(dut_lib.dut_intrinsic_dut_dir)
                if not dut_lib.dut_intrinsic_dut_dir.exists():
                    dut_lib.dut_intrinsic_dut_dir = Path(
                    str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory))
                        str(dut_lib.dut_intrinsic_dut_dir).replace(save_dir_old, str(lib_directory), 1)
                    )

        for dut in dut_lib.duts:
+3 −1
Original line number Diff line number Diff line
@@ -742,6 +742,7 @@ class DutView(object):
        data: Union[DataFrame, Sweep, str, os.Pathlike],
        key: Union[str, None] = None,
        force: bool = True,
        validate: bool = True,
        **kwargs,
    ):
        """Add a measurement or simulation data to the DutView's data.
@@ -787,6 +788,7 @@ class DutView(object):
            self.data[key] = data
        elif isinstance(data, Sweep):
            # simulation valid?
            if not validate:
                self.validate_simulation_successful(data)
            # try special import
            self.import_output_data(data)
+23 −18
Original line number Diff line number Diff line
@@ -131,7 +131,7 @@ class SimCon(object, metaclass=Singleton):
            {"dut": dut_a, "sweep": sweep_a} for dut_a, sweep_a in itertools.product(dut, sweep)
        ]

    def run_and_read(self, force=False, remove_simulations=False, parallel_read=False):
    def run_and_read(self, force=False, remove_simulations=False, parallel_read=False, validate=True):
        """Run all queued simulations and load the results into the Duts' databases.

        Parameters
@@ -195,14 +195,14 @@ class SimCon(object, metaclass=Singleton):
                    if parallel_read:
                        print("Checking which simulations need to be run in parallel:")
                        sims_checked = parallel(
                            delayed(_check_simulation_needed)(i_sim, n_tot, **sim)
                            delayed(_check_simulation_needed)(i_sim, n_tot, validate=validate, **sim)
                            for i_sim, sim in enumerate(self.sim_list)
                        )
                    else:
                        print("Checking which simulations need to be run:")
                        # parallel not working with VAE modelcard currently since get_circuit is monkey patched
                        sims_checked = [
                            _check_simulation_needed(i_sim, n_tot, **sim)
                            _check_simulation_needed(i_sim, n_tot, validate=validate, **sim)
                            for i_sim, sim in enumerate(self.sim_list)
                        ]

@@ -232,7 +232,7 @@ class SimCon(object, metaclass=Singleton):
                    print("Reading in the results in parallel:")
                    sims_read = parallel(
                        delayed(_read_process_results)(
                            process["success"], process["dut"], process["sweep"]
                            process["success"], process["dut"], process["sweep"], validate=validate
                        )
                        for process in process_finished
                    )
@@ -240,7 +240,7 @@ class SimCon(object, metaclass=Singleton):
                    print("Reading in the results:")
                    # parallel not working with VAE modelcard currently since get_circuit is monkey patched
                    sims_read = [
                        _read_process_results(process["success"], process["dut"], process["sweep"])
                        _read_process_results(process["success"], process["dut"], process["sweep"], validate=validate)
                        for process in process_finished
                    ]
                all_sim_success = all(sim["success"] for sim in sims_read)
@@ -800,7 +800,7 @@ class SimCon(object, metaclass=Singleton):
                return 0


def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=None):
def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, validate=True, sweep_exists=None):
    """Function to check if the simulation is needed or already present in the database

    Parameter
@@ -821,6 +821,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No
    print_progress_bar(i_sim, n_tot, prefix="Progress", length=50)
    try:
        # was it simulated already successfully ?
        if validate:
            dut.validate_simulation_successful(sweep)
            print(
                f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and results are valid, only data needs to be read.",
@@ -830,8 +831,12 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No
                dut_name,
                sim_name,
            )
        else:
            print(
                f"\n Simulation of DuT {dut_name} with sweep {sim_name} not checked for validity.",
            )
        logging.debug("The simulation folder of this simulation was %s", dut.get_sim_folder(sweep))
        dut.add_data(sweep)
        dut.add_data(sweep, validate=validate)
    except SimulationFail:
        print(
            f"\n Simulation of DuT {dut_name} with sweep {sim_name} already done and failed.",
@@ -846,7 +851,7 @@ def _check_simulation_needed(i_sim, n_tot, dut=None, sweep=None, sweep_exists=No
    return dut.data


def _read_process_results(success, dut, sweep):
def _read_process_results(success, dut, sweep, validate=True):
    """Read the process results

    Parameter
@@ -866,7 +871,7 @@ def _read_process_results(success, dut, sweep):
    # inform data_manager about the finished simulations
    try:
        if success:
            dut.add_data(sweep)
            dut.add_data(sweep, validate=validate)
            logging.info("Simulation of DuT %s with sweep %s successfull.", dut_name, sim_name)
        else:
            color_red = "\033[91m"
+1 −1
Original line number Diff line number Diff line
@@ -585,7 +585,7 @@ class DutNgspice(DutCircuit):
                str_netlist += (
                    "set wr_vecnames\n"
                    + f"tran {tau/40} {3*tau}\n"
                    + f"wrdata output_ngspice_tr_{i_row}_{i_tr}.ngspice_tr alli allv\n"
                    + f"wrdata output_ngspice_tr_{i_tr}.ngspice_tr alli allv\n" # TODO one file per ngspice variable "index", how to?
                    + "unset wr_vecnames\n"
                )