docs: def run(self, workers=1):
          """ Runs the executor with n workers.
  
          :param workers: Number of parallel processes used in the execution. Default is a single process. If set to
              `None` the number of workers will be the number of processors of the system.
          :type workers: int or None
          """
          self.report_folder = self._get_report_folder()
          if self.save_logs and not os.path.isdir(self.report_folder):
              os.mkdir(self.report_folder)
  
          execution_num = len(self.execution_args)
          log_paths = [self._get_log_filename(idx) if self.save_logs else None
                       for idx in range(execution_num)]
  
          processing_args = [(self.workflow, init_args, log_path) for init_args, log_path in zip(self.execution_args,
                                                                                                 log_paths)]
  
          with concurrent.futures.ProcessPoolExecutor(max_workers=workers) as executor:
              self.execution_stats = list(tqdm(executor.map(self._execute_workflow, processing_args),
                                               total=len(processing_args)))
  
          self.execution_logs = [None] * execution_num
          if self.save_logs:
              for idx, log_path in enumerate(log_paths):
                  with open(log_path) as fin:
                      self.execution_logs[idx] = fin.read()