Find an optimal set of parameters for the execution of the task
        This method can change the ABINIT input variables and/or the
        submission parameters e.g. the number of CPUs for MPI and OpenMp.

        Set:
           self.pconfs where pconfs is a :class:`ParalHints` object with the configuration reported by
           autoparal and optimal is the optimal configuration selected.
           Returns 0 if success

def autoparal_run(self):
        """
        Find an optimal set of parameters for the execution of the task
        This method can change the ABINIT input variables and/or the
        submission parameters e.g. the number of CPUs for MPI and OpenMp.

        Set:
           self.pconfs where pconfs is a :class:`ParalHints` object with the configuration reported by
           autoparal and optimal is the optimal configuration selected.
           Returns 0 if success
        """
        policy = self.manager.policy

        if policy.autoparal == 0: # or policy.max_ncpus in [None, 1]:
            logger.info("Nothing to do in autoparal, returning (None, None)")
            return 0

        if policy.autoparal != 1:
            raise NotImplementedError("autoparal != 1")

        ############################################################################
        # Run ABINIT in sequential to get the possible configurations with max_ncpus
        ############################################################################

        # Set the variables for automatic parallelization
        # Will get all the possible configurations up to max_ncpus
        # Return immediately if max_ncpus == 1
        max_ncpus = self.manager.max_cores
        if max_ncpus == 1: return 0

        autoparal_vars = dict(autoparal=policy.autoparal, max_ncpus=max_ncpus, mem_test=0)
        self.set_vars(autoparal_vars)

        # Run the job in a shell subprocess with mpi_procs = 1
        # we don't want to make a request to the queue manager for this simple job!
        # Return code is always != 0
        process = self.manager.to_shell_manager(mpi_procs=1).launch(self)
        self.history.pop()
        retcode = process.wait()
        # To avoid: ResourceWarning: unclosed file <_io.BufferedReader name=87> in py3k
        process.stderr.close()
        #process.stdout.close()

        # Remove the variables added for the automatic parallelization
        self.input.remove_vars(list(autoparal_vars.keys()))

        ##############################################################
        # Parse the autoparal configurations from the main output file
        ##############################################################
        parser = ParalHintsParser()
        try:
            pconfs = parser.parse(self.output_file.path)
        except parser.Error:
            # In principle Abinit should have written a complete log file
            # because we called .wait() but sometimes the Yaml doc is incomplete and
            # the parser raises. Let's wait 5 secs and then try again.
            time.sleep(5)
            try:
                pconfs = parser.parse(self.output_file.path)
            except parser.Error:
                logger.critical("Error while parsing Autoparal section:\n%s" % straceback())
                return 2

        ######################################################
        # Select the optimal configuration according to policy
        ######################################################
        optconf = self.find_optconf(pconfs)

        ####################################################
        # Change the input file and/or the submission script
        ####################################################
        self.set_vars(optconf.vars)

        # Write autoparal configurations to JSON file.
        d = pconfs.as_dict()
        d["optimal_conf"] = optconf
        json_pretty_dump(d, os.path.join(self.workdir, "autoparal.json"))

        ##############
        # Finalization
        ##############
        # Reset the status, remove garbage files ...
        self.set_status(self.S_INIT, msg='finished autoparal run')

        # Remove the output file since Abinit likes to create new files
        # with extension .outA, .outB if the file already exists.
        os.remove(self.output_file.path)
        os.remove(self.log_file.path)
        os.remove(self.stderr_file.path)

        return 0