Starts the calculation by performing the following steps:

            - build dirs and files
            - call the _setup method
            - execute the job file by executing/submitting the job script.

        Main entry point for the `Launcher`.

        ==============  ==============================================================
        kwargs          Meaning
        ==============  ==============================================================
        autoparal       False to skip the autoparal step (default True)
        exec_args       List of arguments passed to executable.
        ==============  ==============================================================

        Returns:
            1 if task was started, 0 otherwise.

def start(self, **kwargs):
        """
        Starts the calculation by performing the following steps:

            - build dirs and files
            - call the _setup method
            - execute the job file by executing/submitting the job script.

        Main entry point for the `Launcher`.

        ==============  ==============================================================
        kwargs          Meaning
        ==============  ==============================================================
        autoparal       False to skip the autoparal step (default True)
        exec_args       List of arguments passed to executable.
        ==============  ==============================================================

        Returns:
            1 if task was started, 0 otherwise.

        """
        if self.status >= self.S_SUB:
            raise self.Error("Task status: %s" % str(self.status))

        if self.start_lockfile.exists:
            self.history.warning("Found lock file: %s" % self.start_lockfile.path)
            return 0

        self.start_lockfile.write("Started on %s" % time.asctime())

        self.build()
        self._setup()

        # Add the variables needed to connect the node.
        for d in self.deps:
            cvars = d.connecting_vars()
            self.history.info("Adding connecting vars %s" % cvars)
            self.set_vars(cvars)

            # Get (python) data from other nodes
            d.apply_getters(self)

        # Automatic parallelization
        if kwargs.pop("autoparal", True) and hasattr(self, "autoparal_run"):
            try:
                self.autoparal_run()
            #except QueueAdapterError as exc:
            #    # If autoparal cannot find a qadapter to run the calculation raises an Exception
            #    self.history.critical(exc)
            #    msg = "Error while trying to run autoparal in task:%s\n%s" % (repr(task), straceback())
            #    cprint(msg, "yellow")
            #    self.set_status(self.S_QCRITICAL, msg=msg)
            #    return 0
            except Exception as exc:
                # Sometimes autoparal_run fails because Abinit aborts
                # at the level of the parser e.g. cannot find the spacegroup
                # due to some numerical noise in the structure.
                # In this case we call fix_abicritical and then we try to run autoparal again.
                self.history.critical("First call to autoparal failed with `%s`. Will try fix_abicritical" % exc)
                msg = "autoparal_fake_run raised:\n%s" % straceback()
                logger.critical(msg)

                fixed = self.fix_abicritical()
                if not fixed:
                    self.set_status(self.S_ABICRITICAL, msg="fix_abicritical could not solve the problem")
                    return 0

                try:
                    self.autoparal_run()
                    self.history.info("Second call to autoparal succeeded!")
                    #cprint("Second call to autoparal succeeded!", "green")

                except Exception as exc:
                    self.history.critical("Second call to autoparal failed with %s. Cannot recover!", exc)
                    msg = "Tried autoparal again but got:\n%s" % straceback()
                    cprint(msg, "red")
                    self.set_status(self.S_ABICRITICAL, msg=msg)
                    return 0

        # Start the calculation in a subprocess and return.
        self._process = self.manager.launch(self, **kwargs)
        return 1