def run(
        self,
        input_model_config: ModelConfig,
        accelerator_specs: list["AcceleratorSpec"],
        packaging_config: Optional[Union["PackagingConfig", list["PackagingConfig"]]] = None,
        output_dir: str = None,
        evaluate_input_model: bool = True,
        log_to_file: bool = False,
        log_severity_level: int = 1,
    ):
        """Run all the registered Olive passes on the input model and produce one or more candidate models.

        Args:
            input_model_config: input Olive model configuration
            accelerator_specs: list of accelerator specs
            packaging_config: packaging configuration, if packaging_config is provided, the output
                model will be packaged into a zip file.
            output_dir: output directory for the output model
            evaluate_input_model: if evaluate_input_model is True, run the evaluation on the input model.
            log_to_file: if save logs to a file.
            log_severity_level: severity level of the logger.

        Return:
            Search mode:
                1. One accelerator spec:
                    output_dir/footprints.json: footprint of the run
                    output_dir/pareto_frontier_footprints.json: pareto frontier footprints
                    output_dir/run_history.txt: run history
                    output_dir/input_model_metrics.json: evaluation results of the input model
                    output_dir/...: output model files

                2. Multiple accelerator specs:
                    output_dir/{accelerator_spec}/...: Same as 1 but for each accelerator spec
                    output_dir/...: output model files

            No search mode:
                1. One accelerator spec
                    output_dir/footprints.json: footprint of the run
                    output_dir/run_history.txt: run history
                    output_dir/input_model_metrics.json: evaluation results of the input model
                    output_dir/output_footprints.json: footprint of the output models
                    output_dir/...: output model files

                    A. One pass flow:
                        output_dir/metrics.json: evaluation results of the output model
                        output_dir/...: output model files

                2. Multiple accelerator specs
                    output_dir/{accelerator_spec}/...: Same as 1 but for each accelerator spec
                    output_dir/...: output model files

        """
        if not accelerator_specs:
            raise ValueError("No accelerator specified")

        if not self._initialized:
            self.initialize(log_to_file, log_severity_level)

        output_dir: Path = (Path(output_dir) if output_dir else Path.cwd()).resolve()
        output_dir.mkdir(parents=True, exist_ok=True)

        outputs = {}
        output_subdirs = {}
        accelerator_output_dir_list = []
        for accelerator_spec in accelerator_specs:
            logger.info("Running Olive on accelerator: %s", accelerator_spec)
            output_subdirs[accelerator_spec] = accelerator_output_dir = (
                output_dir / str(accelerator_spec) if len(accelerator_specs) > 1 else output_dir
            )
            accelerator_output_dir.mkdir(parents=True, exist_ok=True)
            accelerator_output_dir_list.append(accelerator_output_dir)
            with self._create_system(accelerator_spec):
                run_result = self.run_accelerator(
                    input_model_config,
                    accelerator_output_dir,
                    evaluate_input_model,
                    accelerator_spec,
                )

                if run_result:
                    outputs[accelerator_spec] = run_result

        for accelerator_spec in self.footprints:
            logger.info("Run history for %s:", accelerator_spec)
            run_history = self.footprints[accelerator_spec].summarize_run_history()
            self.dump_run_history(run_history, output_subdirs[accelerator_spec] / "run_history.txt")

        workflow_output = WorkflowOutput(outputs, self.footprints)
        if self.input_passes_configs and workflow_output.has_output_model():
            if packaging_config:
                # TODO(trajep): should we support packaging pytorch model?
                logger.info("Package top ranked %d models as artifacts", len(workflow_output.get_output_models()))
                generate_output_artifacts(
                    packaging_config,
                    workflow_output,
                    output_dir,
                    self.azureml_client_config,
                )
            else:
                logger.debug("No packaging config provided, skip packaging artifacts")

            best_node = workflow_output.get_best_candidate()
            model_json = self.cache.save_model(model_id=best_node.model_id, output_dir=output_dir, overwrite=True)
            best_node._update_with_model_config(model_json)  # pylint: disable=W0212
            logger.info("Saved output model to %s", output_dir)
            if len(accelerator_output_dir_list) > 1 and self.skip_saving_artifacts:
                [shutil.rmtree(folder) for folder in accelerator_output_dir_list if folder.exists()]
        else:
            logger.warning("No output model")

        return workflow_output
Run all the registered Olive passes on the input model and produce one or more candidate models.

        Args:
            input_model_config: input Olive model configuration
            accelerator_specs: list of accelerator specs
            packaging_config: packaging configuration, if packaging_config is provided, the output
                model will be packaged into a zip file.
            output_dir: output directory for the output model
            evaluate_input_model: if evaluate_input_model is True, run the evaluation on the input model.
            log_to_file: if save logs to a file.
            log_severity_level: severity level of the logger.

        Return:
            Search mode:
                1. One accelerator spec:
                    output_dir/footprints.json: footprint of the run
                    output_dir/pareto_frontier_footprints.json: pareto frontier footprints
                    output_dir/run_history.txt: run history
                    output_dir/input_model_metrics.json: evaluation results of the input model
                    output_dir/...: output model files

                2. Multiple accelerator specs:
                    output_dir/{accelerator_spec}/...: Same as 1 but for each accelerator spec
                    output_dir/...: output model files

            No search mode:
                1. One accelerator spec
                    output_dir/footprints.json: footprint of the run
                    output_dir/run_history.txt: run history
                    output_dir/input_model_metrics.json: evaluation results of the input model
                    output_dir/output_footprints.json: footprint of the output models
                    output_dir/...: output model files

                    A. One pass flow:
                        output_dir/metrics.json: evaluation results of the output model
                        output_dir/...: output model files

                2. Multiple accelerator specs
                    output_dir/{accelerator_spec}/...: Same as 1 but for each accelerator spec
                    output_dir/...: output model files

        
olive/engine/engine.py