Skip to content

Commit 53551c1

Browse files
authored
Qualcomm AI Engine Direct - [GenAI Pipeline] PR2: Strategy Interfaces & Stage Wrappers (#20795)
## Summary This PR adds the strategy interfaces, and stage wrappers for the GenAI pipeline. This is the second of 7 PRs establishing the framework skeleton. It builds on PR1 (data model + engine routing) and introduces the Strategy pattern ABCs, concrete stage delegation wrappers and Executorch strategy stubs. No existing files are modified (except `__init__.py` introduced in PR1 for imports). ### What's included #### Strategy ABCs (one class per file): - `ModelPreparationStrategy` — in `strategies/model_preparation/` - `QuantizationStrategy` — in `strategies/quantization/` - `CompilationStrategy` — in `strategies/compilation/` - `InferenceStrategy` — in `strategies/inference/` Each ABC defines `invoke(context, input_config) -> output_config`. #### Strategy stubs (raise `NotImplementedError`): - `ExecuTorchModelPreparationStrategy` - `ExecuTorchQuantizationStrategy` - `ExecuTorchCompilationStrategy` - `ExecuTorchInferenceStrategy` #### Stage wrappers: - `ModelPreparationStage`, `QuantizationStage`, `CompilationStage`, `InferenceStage`. - Each delegates to its injected strategy via `invoke()`. - `name` property returns stage constant from `pipeline_types.py`. #### Pipeline stage ABC: - `PipelineStage` — abstract base with `name` property and `invoke()` method. #### Unit tests (16 tests across 6 test files): - Strategy ABC enforcement (cannot instantiate, must implement `invoke()`). - Strategy stub tests (`NotImplementedError` raised). - Stage delegation tests (`assert_called_once_with`). - Stage name tests (use constants). ### PR Review Checklist - All new classes follow single responsibility (one class per file) - Yes. - All dependencies are injected via constructor with sensible defaults - Yes. - All external calls are behind injectable interfaces - N/A, no external calls. - Unit tests cover every public method - Yes. - No existing files are modified (Phase 1 constraint) - Yes (only `__init__.py` updated to add `PipelineStage` export). - Docstrings on all public classes and methods - Yes. - Type annotations on all function signatures - Yes. - Logging follows the strategy in the LLD - N/A, no logging in this PR. ### Related PRs - PR 1: Core data model, engine routing & exceptions: #20409 - PR 2: Strategy interfaces & stage wrappers: this PR. - PR 3: Pipeline orchestrator: pending. - PR 4: Adapter interfaces & default implementations: pending. - PR 5: Model preparation & quantization strategies: pending - PR 6: Compilation & inference strategy implementations: pending. - PR 7: Integration & E2E tests: pending. ## Test plan ``` python -m pytest \ backends/qualcomm/genai_pipeline/tests/strategies/ \ backends/qualcomm/genai_pipeline/tests/stages/ \ -v ``` All 16 unit-tests passed. ### Test Coverage Command to run: ``` coverage run --rcfile=backends/qualcomm/.coveragerc \ -m pytest \ backends/qualcomm/genai_pipeline/tests/strategies/ \ backends/qualcomm/genai_pipeline/tests/stages/ \ -v coverage report --rcfile=backends/qualcomm/.coveragerc \ --include="backends/qualcomm/genai_pipeline/pipeline_stage.py,backends/qualcomm/genai_pipeline/strategies/*,backends/qualcomm/genai_pipeline/stages/*" ``` Result: ``` Name Stmts Miss Branch BrPart Cover Missing ------------------------------------------------------------------------------------------------------------------------------------------ backends/qualcomm/genai_pipeline/stages/compilation_stage.py 14 0 0 0 100% backends/qualcomm/genai_pipeline/stages/inference_stage.py 14 0 0 0 100% backends/qualcomm/genai_pipeline/stages/model_preparation_stage.py 14 3 0 0 79% 24, 28, 35 backends/qualcomm/genai_pipeline/stages/quantization_stage.py 14 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/compilation/compilation_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/compilation/executorch_compilation_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/inference/executorch_inference_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/inference/inference_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/model_preparation/model_preparation_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/quantization/executorch_quantization_strategy.py 7 0 0 0 100% backends/qualcomm/genai_pipeline/strategies/quantization/quantization_strategy.py 7 0 0 0 100% ------------------------------------------------------------------------------------------------------------------------------------------ TOTAL 110 3 0 0 97% ```
1 parent 776ba0c commit 53551c1

26 files changed

Lines changed: 844 additions & 0 deletions

backends/qualcomm/genai_pipeline/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"PipelineContext",
4444
"PipelineContextBuilder",
4545
"PipelineError",
46+
"PipelineStage",
4647
"QuantizationInputConfig",
4748
"QuantizationOutputConfig",
4849
"StageError",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from abc import ABC, abstractmethod
8+
from typing import Any
9+
10+
11+
class PipelineStage(ABC):
12+
"""Abstract base class for all pipeline stages.
13+
14+
Each stage delegates its work to an engine-specific strategy
15+
resolved by the EngineProxy.
16+
"""
17+
18+
@property
19+
@abstractmethod
20+
def name(self) -> str: ...
21+
22+
@abstractmethod
23+
def invoke(self, context: Any, input_config: Any) -> Any:
24+
"""Execute this pipeline stage.
25+
26+
Args:
27+
context: The PipelineContext providing global pipeline settings.
28+
input_config: The stage-specific input configuration dataclass.
29+
30+
Returns:
31+
The stage-specific output configuration dataclass.
32+
"""
33+
...
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.stages.compilation_stage import (
8+
CompilationStage,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.stages.inference_stage import (
11+
InferenceStage,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.stages.model_preparation_stage import (
14+
ModelPreparationStage,
15+
)
16+
from executorch.backends.qualcomm.genai_pipeline.stages.quantization_stage import (
17+
QuantizationStage,
18+
)
19+
20+
__all__ = [
21+
"CompilationStage",
22+
"InferenceStage",
23+
"ModelPreparationStage",
24+
"QuantizationStage",
25+
]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_input_config import (
8+
CompilationInputConfig,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_output_config import (
11+
CompilationOutputConfig,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import PipelineContext
14+
from executorch.backends.qualcomm.genai_pipeline.pipeline_stage import PipelineStage
15+
from executorch.backends.qualcomm.genai_pipeline.pipeline_types import STAGE_COMPILATION
16+
from executorch.backends.qualcomm.genai_pipeline.strategies.compilation.compilation_strategy import (
17+
CompilationStrategy,
18+
)
19+
20+
21+
class CompilationStage(PipelineStage):
22+
23+
def __init__(self, strategy: CompilationStrategy) -> None:
24+
self._strategy = strategy
25+
26+
@property
27+
def name(self) -> str:
28+
return STAGE_COMPILATION
29+
30+
def invoke(
31+
self,
32+
context: PipelineContext,
33+
input_config: CompilationInputConfig,
34+
) -> CompilationOutputConfig:
35+
return self._strategy.invoke(context, input_config)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.configs.inference_input_config import (
8+
InferenceInputConfig,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.configs.inference_output_config import (
11+
InferenceOutputConfig,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import PipelineContext
14+
from executorch.backends.qualcomm.genai_pipeline.pipeline_stage import PipelineStage
15+
from executorch.backends.qualcomm.genai_pipeline.pipeline_types import STAGE_INFERENCE
16+
from executorch.backends.qualcomm.genai_pipeline.strategies.inference.inference_strategy import (
17+
InferenceStrategy,
18+
)
19+
20+
21+
class InferenceStage(PipelineStage):
22+
23+
def __init__(self, strategy: InferenceStrategy) -> None:
24+
self._strategy = strategy
25+
26+
@property
27+
def name(self) -> str:
28+
return STAGE_INFERENCE
29+
30+
def invoke(
31+
self,
32+
context: PipelineContext,
33+
input_config: InferenceInputConfig,
34+
) -> InferenceOutputConfig:
35+
return self._strategy.invoke(context, input_config)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.configs.model_preparation_input_config import (
8+
ModelPreparationInputConfig,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.configs.model_preparation_output_config import (
11+
ModelPreparationOutputConfig,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import PipelineContext
14+
from executorch.backends.qualcomm.genai_pipeline.pipeline_stage import PipelineStage
15+
from executorch.backends.qualcomm.genai_pipeline.pipeline_types import (
16+
STAGE_MODEL_PREPARATION,
17+
)
18+
from executorch.backends.qualcomm.genai_pipeline.strategies.model_preparation.model_preparation_strategy import (
19+
ModelPreparationStrategy,
20+
)
21+
22+
23+
class ModelPreparationStage(PipelineStage):
24+
25+
def __init__(self, strategy: ModelPreparationStrategy) -> None:
26+
self._strategy = strategy
27+
28+
@property
29+
def name(self) -> str:
30+
return STAGE_MODEL_PREPARATION
31+
32+
def invoke(
33+
self,
34+
context: PipelineContext,
35+
input_config: ModelPreparationInputConfig,
36+
) -> ModelPreparationOutputConfig:
37+
return self._strategy.invoke(context, input_config)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.configs.quantization_input_config import (
8+
QuantizationInputConfig,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.configs.quantization_output_config import (
11+
QuantizationOutputConfig,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import PipelineContext
14+
from executorch.backends.qualcomm.genai_pipeline.pipeline_stage import PipelineStage
15+
from executorch.backends.qualcomm.genai_pipeline.pipeline_types import (
16+
STAGE_QUANTIZATION,
17+
)
18+
from executorch.backends.qualcomm.genai_pipeline.strategies.quantization.quantization_strategy import (
19+
QuantizationStrategy,
20+
)
21+
22+
23+
class QuantizationStage(PipelineStage):
24+
25+
def __init__(self, strategy: QuantizationStrategy) -> None:
26+
self._strategy = strategy
27+
28+
@property
29+
def name(self) -> str:
30+
return STAGE_QUANTIZATION
31+
32+
def invoke(
33+
self,
34+
context: PipelineContext,
35+
input_config: QuantizationInputConfig,
36+
) -> QuantizationOutputConfig:
37+
return self._strategy.invoke(context, input_config)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.strategies.compilation.compilation_strategy import (
8+
CompilationStrategy,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.strategies.inference.inference_strategy import (
11+
InferenceStrategy,
12+
)
13+
from executorch.backends.qualcomm.genai_pipeline.strategies.model_preparation.model_preparation_strategy import (
14+
ModelPreparationStrategy,
15+
)
16+
from executorch.backends.qualcomm.genai_pipeline.strategies.quantization.quantization_strategy import (
17+
QuantizationStrategy,
18+
)
19+
20+
__all__ = [
21+
"CompilationStrategy",
22+
"InferenceStrategy",
23+
"ModelPreparationStrategy",
24+
"QuantizationStrategy",
25+
]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from executorch.backends.qualcomm.genai_pipeline.strategies.compilation.compilation_strategy import (
8+
CompilationStrategy,
9+
)
10+
from executorch.backends.qualcomm.genai_pipeline.strategies.compilation.executorch_compilation_strategy import (
11+
ExecuTorchCompilationStrategy,
12+
)
13+
14+
__all__ = ["CompilationStrategy", "ExecuTorchCompilationStrategy"]
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright (c) Qualcomm Innovation Center, Inc.
2+
# All rights reserved
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
from abc import ABC, abstractmethod
8+
9+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_input_config import (
10+
CompilationInputConfig,
11+
)
12+
from executorch.backends.qualcomm.genai_pipeline.configs.compilation_output_config import (
13+
CompilationOutputConfig,
14+
)
15+
from executorch.backends.qualcomm.genai_pipeline.pipeline_context import PipelineContext
16+
17+
18+
class CompilationStrategy(ABC):
19+
@abstractmethod
20+
def invoke(
21+
self,
22+
context: PipelineContext,
23+
input_config: CompilationInputConfig,
24+
) -> CompilationOutputConfig:
25+
"""Compile the model to on-device artifacts.
26+
27+
Args:
28+
context: The pipeline context with global settings.
29+
input_config: The compilation input configuration.
30+
31+
Returns:
32+
CompilationOutputConfig with artifact paths.
33+
"""
34+
...

0 commit comments

Comments
 (0)