aboutsummaryrefslogtreecommitdiff
path: root/src/mlia/devices/cortexa
diff options
context:
space:
mode:
Diffstat (limited to 'src/mlia/devices/cortexa')
-rw-r--r--src/mlia/devices/cortexa/__init__.py3
-rw-r--r--src/mlia/devices/cortexa/advice_generation.py153
-rw-r--r--src/mlia/devices/cortexa/advisor.py92
-rw-r--r--src/mlia/devices/cortexa/config.py20
-rw-r--r--src/mlia/devices/cortexa/data_analysis.py128
-rw-r--r--src/mlia/devices/cortexa/data_collection.py51
-rw-r--r--src/mlia/devices/cortexa/events.py24
-rw-r--r--src/mlia/devices/cortexa/handlers.py39
-rw-r--r--src/mlia/devices/cortexa/operator_compatibility.py184
-rw-r--r--src/mlia/devices/cortexa/operators.py148
-rw-r--r--src/mlia/devices/cortexa/reporters.py140
11 files changed, 0 insertions, 982 deletions
diff --git a/src/mlia/devices/cortexa/__init__.py b/src/mlia/devices/cortexa/__init__.py
deleted file mode 100644
index 3a987e7..0000000
--- a/src/mlia/devices/cortexa/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A devices module."""
diff --git a/src/mlia/devices/cortexa/advice_generation.py b/src/mlia/devices/cortexa/advice_generation.py
deleted file mode 100644
index bab9530..0000000
--- a/src/mlia/devices/cortexa/advice_generation.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A advice generation."""
-from functools import singledispatchmethod
-
-from mlia.core.advice_generation import advice_category
-from mlia.core.advice_generation import FactBasedAdviceProducer
-from mlia.core.common import AdviceCategory
-from mlia.core.common import DataItem
-from mlia.devices.cortexa.data_analysis import ModelHasCustomOperators
-from mlia.devices.cortexa.data_analysis import ModelIsCortexACompatible
-from mlia.devices.cortexa.data_analysis import ModelIsNotCortexACompatible
-from mlia.devices.cortexa.data_analysis import ModelIsNotTFLiteCompatible
-from mlia.devices.cortexa.data_analysis import TFLiteCompatibilityCheckFailed
-
-
-class CortexAAdviceProducer(FactBasedAdviceProducer):
- """Cortex-A advice producer."""
-
- cortex_a_disclaimer = (
- "Note that the provided compatibility information is general. "
- "At runtime individual operators in the given model might fall back to "
- "the TensorFlow Lite reference or might produce errors based on the "
- "specific parameters."
- )
-
- @singledispatchmethod
- def produce_advice(self, _data_item: DataItem) -> None: # type: ignore
- """Produce advice."""
-
- @produce_advice.register
- @advice_category(AdviceCategory.ALL, AdviceCategory.OPERATORS)
- def handle_model_is_cortex_a_compatible(
- self, data_item: ModelIsCortexACompatible
- ) -> None:
- """Advice for Cortex-A compatibility."""
- self.add_advice(
- [
- f"Model is fully compatible with {data_item.backend_info} for "
- "Cortex-A.",
- self.cortex_a_disclaimer,
- ]
- )
-
- @produce_advice.register
- @advice_category(AdviceCategory.ALL, AdviceCategory.OPERATORS)
- def handle_model_is_not_cortex_a_compatible(
- self, data_item: ModelIsNotCortexACompatible
- ) -> None:
- """Advice for Cortex-A compatibility."""
- if data_item.unsupported_ops:
- self.add_advice(
- [
- "The following operators are not supported by "
- f"{data_item.backend_info} and will fall back to the "
- "TensorFlow Lite runtime:",
- "\n".join(f" - {op}" for op in data_item.unsupported_ops),
- ]
- )
-
- if data_item.activation_func_support:
- self.add_advice(
- [
- "The fused activation functions of the following operators "
- f"are not supported by {data_item.backend_info}. Please "
- "consider using one of the supported activation functions "
- "instead:",
- "\n".join(
- f" - {op}\n"
- f" - Used unsupported: {act.used_unsupported}\n"
- f" - Supported: {act.supported}"
- for op, act in data_item.activation_func_support.items()
- ),
- ]
- )
-
- self.add_advice(
- [
- "Please, refer to the full table of operators above for more "
- "information.",
- self.cortex_a_disclaimer,
- ]
- )
-
- @produce_advice.register
- @advice_category(AdviceCategory.ALL, AdviceCategory.OPERATORS)
- def handle_model_is_not_tflite_compatible(
- self, data_item: ModelIsNotTFLiteCompatible
- ) -> None:
- """Advice for TensorFlow Lite compatibility."""
- if data_item.flex_ops:
- self.add_advice(
- [
- "The following operators are not natively "
- "supported by TensorFlow Lite: "
- f"{', '.join(data_item.flex_ops)}.",
- "Using select TensorFlow operators in TensorFlow Lite model "
- "requires special initialization of TFLiteConverter and "
- "TensorFlow Lite run-time.",
- "Please refer to the TensorFlow documentation for more "
- "details: https://www.tensorflow.org/lite/guide/ops_select",
- "Note, such models are not supported by the ML Inference Advisor.",
- ]
- )
-
- if data_item.custom_ops:
- self.add_advice(
- [
- "The following operators appear to be custom and not natively "
- "supported by TensorFlow Lite: "
- f"{', '.join(data_item.custom_ops)}.",
- "Using custom operators in TensorFlow Lite model "
- "requires special initialization of TFLiteConverter and "
- "TensorFlow Lite run-time.",
- "Please refer to the TensorFlow documentation for more "
- "details: https://www.tensorflow.org/lite/guide/ops_custom",
- "Note, such models are not supported by the ML Inference Advisor.",
- ]
- )
-
- if not data_item.flex_ops and not data_item.custom_ops:
- self.add_advice(
- [
- "Model could not be converted into TensorFlow Lite format.",
- "Please refer to the table for more details.",
- ]
- )
-
- @produce_advice.register
- @advice_category(AdviceCategory.ALL, AdviceCategory.OPERATORS)
- def handle_tflite_check_failed(
- self, _data_item: TFLiteCompatibilityCheckFailed
- ) -> None:
- """Advice for the failed TensorFlow Lite compatibility checks."""
- self.add_advice(
- [
- "Model could not be converted into TensorFlow Lite format.",
- "Please refer to the table for more details.",
- ]
- )
-
- @produce_advice.register
- @advice_category(AdviceCategory.ALL, AdviceCategory.OPERATORS)
- def handle_model_has_custom_operators(
- self, _data_item: ModelHasCustomOperators
- ) -> None:
- """Advice for the models with custom operators."""
- self.add_advice(
- [
- "Models with custom operators require special initialization "
- "and currently are not supported by the ML Inference Advisor.",
- ]
- )
diff --git a/src/mlia/devices/cortexa/advisor.py b/src/mlia/devices/cortexa/advisor.py
deleted file mode 100644
index ffbbea5..0000000
--- a/src/mlia/devices/cortexa/advisor.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A MLIA module."""
-from __future__ import annotations
-
-from pathlib import Path
-from typing import Any
-
-from mlia.core.advice_generation import AdviceProducer
-from mlia.core.advisor import DefaultInferenceAdvisor
-from mlia.core.advisor import InferenceAdvisor
-from mlia.core.common import AdviceCategory
-from mlia.core.context import Context
-from mlia.core.context import ExecutionContext
-from mlia.core.data_analysis import DataAnalyzer
-from mlia.core.data_collection import DataCollector
-from mlia.core.events import Event
-from mlia.core.typing import PathOrFileLike
-from mlia.devices.cortexa.advice_generation import CortexAAdviceProducer
-from mlia.devices.cortexa.config import CortexAConfiguration
-from mlia.devices.cortexa.data_analysis import CortexADataAnalyzer
-from mlia.devices.cortexa.data_collection import CortexAOperatorCompatibility
-from mlia.devices.cortexa.events import CortexAAdvisorStartedEvent
-from mlia.devices.cortexa.handlers import CortexAEventHandler
-
-
-class CortexAInferenceAdvisor(DefaultInferenceAdvisor):
- """Cortex-A Inference Advisor."""
-
- @classmethod
- def name(cls) -> str:
- """Return name of the advisor."""
- return "cortex_a_inference_advisor"
-
- def get_collectors(self, context: Context) -> list[DataCollector]:
- """Return list of the data collectors."""
- model = self.get_model(context)
-
- collectors: list[DataCollector] = []
-
- if AdviceCategory.OPERATORS in context.advice_category:
- collectors.append(CortexAOperatorCompatibility(model))
-
- return collectors
-
- def get_analyzers(self, context: Context) -> list[DataAnalyzer]:
- """Return list of the data analyzers."""
- return [
- CortexADataAnalyzer(),
- ]
-
- def get_producers(self, context: Context) -> list[AdviceProducer]:
- """Return list of the advice producers."""
- return [CortexAAdviceProducer()]
-
- def get_events(self, context: Context) -> list[Event]:
- """Return list of the startup events."""
- model = self.get_model(context)
- target_profile = self.get_target_profile(context)
-
- return [
- CortexAAdvisorStartedEvent(model, CortexAConfiguration(target_profile)),
- ]
-
-
-def configure_and_get_cortexa_advisor(
- context: ExecutionContext,
- target_profile: str,
- model: str | Path,
- output: PathOrFileLike | None = None,
- **_extra_args: Any,
-) -> InferenceAdvisor:
- """Create and configure Cortex-A advisor."""
- if context.event_handlers is None:
- context.event_handlers = [CortexAEventHandler(output)]
-
- if context.config_parameters is None:
- context.config_parameters = _get_config_parameters(model, target_profile)
-
- return CortexAInferenceAdvisor()
-
-
-def _get_config_parameters(model: str | Path, target_profile: str) -> dict[str, Any]:
- """Get configuration parameters for the advisor."""
- advisor_parameters: dict[str, Any] = {
- "cortex_a_inference_advisor": {
- "model": str(model),
- "target_profile": target_profile,
- },
- }
-
- return advisor_parameters
diff --git a/src/mlia/devices/cortexa/config.py b/src/mlia/devices/cortexa/config.py
deleted file mode 100644
index ec0cf0a..0000000
--- a/src/mlia/devices/cortexa/config.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A configuration."""
-from __future__ import annotations
-
-from mlia.devices.config import IPConfiguration
-from mlia.utils.filesystem import get_profile
-
-
-class CortexAConfiguration(IPConfiguration): # pylint: disable=too-few-public-methods
- """Cortex-A configuration."""
-
- def __init__(self, target_profile: str) -> None:
- """Init Cortex-A target configuration."""
- target_data = get_profile(target_profile)
-
- target = target_data["target"]
- if target != "cortex-a":
- raise Exception(f"Wrong target {target} for Cortex-A configuration")
- super().__init__(target)
diff --git a/src/mlia/devices/cortexa/data_analysis.py b/src/mlia/devices/cortexa/data_analysis.py
deleted file mode 100644
index 04bc819..0000000
--- a/src/mlia/devices/cortexa/data_analysis.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A data analysis module."""
-from __future__ import annotations
-
-from collections import defaultdict
-from dataclasses import dataclass
-from dataclasses import field
-from functools import singledispatchmethod
-
-from mlia.core.common import DataItem
-from mlia.core.data_analysis import Fact
-from mlia.core.data_analysis import FactExtractor
-from mlia.devices.cortexa.operators import CortexACompatibilityInfo
-from mlia.devices.cortexa.operators import Operator
-from mlia.nn.tensorflow.tflite_compat import TFLiteCompatibilityInfo
-
-
-class CortexADataAnalyzer(FactExtractor):
- """Cortex-A data analyzer."""
-
- @singledispatchmethod
- def analyze_data(self, data_item: DataItem) -> None: # type: ignore
- """Analyse the data."""
-
- @analyze_data.register
- def analyze_operator_compatibility(
- self, data_item: CortexACompatibilityInfo
- ) -> None:
- """Analyse operator compatibility information."""
- if data_item.cortex_a_compatible:
- self.add_fact(ModelIsCortexACompatible(data_item.backend_info))
- else:
- unsupported_ops = set()
- activation_func_support: defaultdict[
- str, ModelIsNotCortexACompatible.ActivationFunctionSupport
- ] = defaultdict(ModelIsNotCortexACompatible.ActivationFunctionSupport)
- for oper in data_item.operators:
- if oper.support_type == Operator.SupportType.OP_NOT_SUPPORTED:
- unsupported_ops.add(oper.full_name)
-
- if oper.support_type == Operator.SupportType.ACTIVATION_NOT_SUPPORTED:
- # Add used but unsupported actication functions
- activation_func_support[oper.full_name].used_unsupported.add(
- oper.activation_func.name
- )
- # Add supported activation functions
- activation_func_support[oper.full_name].supported.update(
- oper.supported_activation_functions
- )
-
- assert (
- unsupported_ops or activation_func_support or not data_item.operators
- ), (
- "The model is marked as not compatible with Cortex-A but there "
- "are no unsupported ops activation functions listed."
- )
-
- self.add_fact(
- ModelIsNotCortexACompatible(
- data_item.backend_info, unsupported_ops, activation_func_support
- )
- )
-
- @analyze_data.register
- def analyze_tflite_compatibility(self, data_item: TFLiteCompatibilityInfo) -> None:
- """Analyze TensorFlow Lite compatibility information."""
- if data_item.compatible:
- return
-
- if data_item.conversion_failed_with_errors:
- self.add_fact(
- ModelIsNotTFLiteCompatible(
- custom_ops=data_item.required_custom_ops,
- flex_ops=data_item.required_flex_ops,
- )
- )
-
- if data_item.check_failed_with_unknown_error:
- self.add_fact(TFLiteCompatibilityCheckFailed())
-
- if data_item.conversion_failed_for_model_with_custom_ops:
- self.add_fact(ModelHasCustomOperators())
-
-
-@dataclass
-class CortexACompatibility(Fact):
- """Base class for Cortex-A compatibility providing backend info."""
-
- backend_info: str
-
-
-@dataclass
-class ModelIsCortexACompatible(CortexACompatibility):
- """Model is completely compatible with Cortex-A."""
-
-
-@dataclass
-class ModelIsNotCortexACompatible(CortexACompatibility):
- """Model is not compatible with Cortex-A."""
-
- @dataclass
- class ActivationFunctionSupport:
- """Activation function support per operator."""
-
- used_unsupported: set[str] = field(default_factory=set)
- supported: set[str] = field(default_factory=set)
-
- unsupported_ops: set[str]
- activation_func_support: dict[str, ActivationFunctionSupport]
-
-
-@dataclass
-class ModelIsNotTFLiteCompatible(Fact):
- """Model could not be converted into TensorFlow Lite format."""
-
- custom_ops: list[str] | None = None
- flex_ops: list[str] | None = None
-
-
-@dataclass
-class TFLiteCompatibilityCheckFailed(Fact):
- """TensorFlow Lite compatibility check failed by unknown reason."""
-
-
-@dataclass
-class ModelHasCustomOperators(Fact):
- """Model could not be loaded because it contains custom ops."""
diff --git a/src/mlia/devices/cortexa/data_collection.py b/src/mlia/devices/cortexa/data_collection.py
deleted file mode 100644
index f4d5a82..0000000
--- a/src/mlia/devices/cortexa/data_collection.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Data collection module for Cortex-A."""
-from __future__ import annotations
-
-import logging
-from pathlib import Path
-
-from mlia.core.data_collection import ContextAwareDataCollector
-from mlia.devices.cortexa.operators import CortexACompatibilityInfo
-from mlia.devices.cortexa.operators import get_cortex_a_compatibility_info
-from mlia.nn.tensorflow.config import get_tflite_model
-from mlia.nn.tensorflow.tflite_compat import TFLiteChecker
-from mlia.nn.tensorflow.tflite_compat import TFLiteCompatibilityInfo
-from mlia.nn.tensorflow.utils import is_tflite_model
-from mlia.utils.logging import log_action
-
-
-logger = logging.getLogger(__name__)
-
-
-class CortexAOperatorCompatibility(ContextAwareDataCollector):
- """Collect operator compatibility information."""
-
- def __init__(self, model: Path) -> None:
- """Init operator compatibility data collector."""
- self.model = model
-
- def collect_data(self) -> TFLiteCompatibilityInfo | CortexACompatibilityInfo | None:
- """Collect operator compatibility information."""
- if not is_tflite_model(self.model):
- with log_action("Checking TensorFlow Lite compatibility ..."):
- tflite_checker = TFLiteChecker()
- tflite_compat = tflite_checker.check_compatibility(self.model)
-
- if not tflite_compat.compatible:
- return tflite_compat
-
- tflite_model = get_tflite_model(self.model, self.context)
-
- with log_action("Checking operator compatibility ..."):
- return (
- get_cortex_a_compatibility_info( # pylint: disable=assignment-from-none
- Path(tflite_model.model_path)
- )
- )
-
- @classmethod
- def name(cls) -> str:
- """Return name of the collector."""
- return "cortex_a_operator_compatibility"
diff --git a/src/mlia/devices/cortexa/events.py b/src/mlia/devices/cortexa/events.py
deleted file mode 100644
index dece4c7..0000000
--- a/src/mlia/devices/cortexa/events.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A MLIA module events."""
-from dataclasses import dataclass
-from pathlib import Path
-
-from mlia.core.events import Event
-from mlia.core.events import EventDispatcher
-from mlia.devices.cortexa.config import CortexAConfiguration
-
-
-@dataclass
-class CortexAAdvisorStartedEvent(Event):
- """Event with Cortex-A advisor parameters."""
-
- model: Path
- device: CortexAConfiguration
-
-
-class CortexAAdvisorEventHandler(EventDispatcher):
- """Event handler for the Cortex-A inference advisor."""
-
- def on_cortex_a_advisor_started(self, event: CortexAAdvisorStartedEvent) -> None:
- """Handle CortexAAdvisorStarted event."""
diff --git a/src/mlia/devices/cortexa/handlers.py b/src/mlia/devices/cortexa/handlers.py
deleted file mode 100644
index 7ed2b75..0000000
--- a/src/mlia/devices/cortexa/handlers.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Event handler."""
-from __future__ import annotations
-
-import logging
-
-from mlia.core.events import CollectedDataEvent
-from mlia.core.handlers import WorkflowEventsHandler
-from mlia.core.typing import PathOrFileLike
-from mlia.devices.cortexa.events import CortexAAdvisorEventHandler
-from mlia.devices.cortexa.events import CortexAAdvisorStartedEvent
-from mlia.devices.cortexa.operators import CortexACompatibilityInfo
-from mlia.devices.cortexa.reporters import cortex_a_formatters
-from mlia.nn.tensorflow.tflite_compat import TFLiteCompatibilityInfo
-
-logger = logging.getLogger(__name__)
-
-
-class CortexAEventHandler(WorkflowEventsHandler, CortexAAdvisorEventHandler):
- """CLI event handler."""
-
- def __init__(self, output: PathOrFileLike | None = None) -> None:
- """Init event handler."""
- super().__init__(cortex_a_formatters, output)
-
- def on_collected_data(self, event: CollectedDataEvent) -> None:
- """Handle CollectedDataEvent event."""
- data_item = event.data_item
-
- if isinstance(data_item, CortexACompatibilityInfo):
- self.reporter.submit(data_item.operators, delay_print=True)
-
- if isinstance(data_item, TFLiteCompatibilityInfo) and not data_item.compatible:
- self.reporter.submit(data_item, delay_print=True)
-
- def on_cortex_a_advisor_started(self, event: CortexAAdvisorStartedEvent) -> None:
- """Handle CortexAAdvisorStarted event."""
- self.reporter.submit(event.device)
diff --git a/src/mlia/devices/cortexa/operator_compatibility.py b/src/mlia/devices/cortexa/operator_compatibility.py
deleted file mode 100644
index c474e75..0000000
--- a/src/mlia/devices/cortexa/operator_compatibility.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Collection of Cortex-A operator compatibility information."""
-from __future__ import annotations
-
-from typing import Any
-
-ARMNN_TFLITE_DELEGATE: dict[str, dict[str, Any]] = {
- "metadata": {
- "backend": "Arm NN TensorFlow Lite delegate",
- "version": "22.08",
- },
- # BUILTIN OPERATORS
- "builtin_ops": {
- "ABS": {},
- "ADD": {},
- "ARG_MAX": {},
- "ARG_MIN": {},
- "AVERAGE_POOL_2D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "BATCH_TO_SPACE_ND": {},
- "CAST": {},
- "CONCATENATION": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "CONV_2D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "CONV_3D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "DEPTH_TO_SPACE": {},
- "DEPTHWISE_CONV_2D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "DEQUANTIZE": {},
- "DIV": {},
- "EQUAL": {},
- "ELU": {},
- "EXP": {},
- "EXPAND_DIMS": {},
- "FILL": {},
- "FLOOR": {},
- "FLOOR_DIV": {},
- "FULLY_CONNECTED": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "GATHER": {},
- "GATHER_ND": {},
- "GREATER": {},
- "GREATER_EQUAL": {},
- "HARD_SWISH": {},
- "L2_NORMALIZATION": {},
- "L2_POOL_2D": {},
- "LESS": {},
- "LESS_EQUAL": {},
- "LOCAL_RESPONSE_NORMALIZATION": {},
- "LOG": {},
- "LOGICAL_AND": {},
- "LOGICAL_NOT": {},
- "LOGICAL_OR": {},
- "LOGISTIC": {},
- "LOG_SOFTMAX": {},
- "LSTM": {},
- "MAXIMUM": {},
- "MAX_POOL_2D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "TANH",
- "NONE",
- ]
- },
- "MEAN": {},
- "MINIMUM": {},
- "MIRROR_PAD": {},
- "MUL": {},
- "NEG": {},
- "NOT_EQUAL": {},
- "PACK": {},
- "PAD": {},
- "PADV2": {},
- "PRELU": {},
- "QUANTIZE": {},
- "RANK": {},
- "REDUCE_MAX": {},
- "REDUCE_MIN": {},
- "REDUCE_PROD": {},
- "RELU": {},
- "RELU6": {},
- "RELU_N1_TO_1": {},
- "RESHAPE": {},
- "RESIZE_BILINEAR": {},
- "RESIZE_NEAREST_NEIGHBOR": {},
- "RSQRT": {},
- "SHAPE": {},
- "SIN": {},
- "SOFTMAX": {},
- "SPACE_TO_BATCH_ND": {},
- "SPACE_TO_DEPTH": {},
- "SPLIT": {},
- "SPLIT_V": {},
- "SQRT": {},
- "SQUEEZE": {},
- "STRIDED_SLICE": {},
- "SUB": {},
- "SUM": {},
- "TANH": {},
- "TRANSPOSE": {},
- "TRANSPOSE_CONV": {},
- "UNIDIRECTIONAL_SEQUENCE_LSTM": {},
- "UNPACK": {},
- },
- # CUSTOM OPERATORS
- "custom_ops": {
- "AveragePool3D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "SIGN_BIT",
- "TANH",
- "NONE",
- ]
- },
- "MaxPool3D": {
- "supported_fused_activation": [
- "RELU",
- "RELU6",
- "RELU_N1_TO_1",
- "SIGMOID",
- "SIGN_BIT",
- "TANH",
- "NONE",
- ]
- },
- },
-}
diff --git a/src/mlia/devices/cortexa/operators.py b/src/mlia/devices/cortexa/operators.py
deleted file mode 100644
index 3e84d64..0000000
--- a/src/mlia/devices/cortexa/operators.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Cortex-A tools module."""
-from __future__ import annotations
-
-from dataclasses import dataclass
-from enum import Enum
-from pathlib import Path
-from typing import Any
-from typing import ClassVar
-
-from mlia.devices.cortexa.operator_compatibility import (
- ARMNN_TFLITE_DELEGATE as TFLITE_DELEGATE_COMPAT,
-)
-from mlia.nn.tensorflow.tflite_graph import Op
-from mlia.nn.tensorflow.tflite_graph import parse_subgraphs
-from mlia.nn.tensorflow.tflite_graph import TFL_ACTIVATION_FUNCTION
-
-
-@dataclass
-class Operator:
- """Cortex-A compatibility information of the operator."""
-
- BUILTIN_COMPATIBILITY = TFLITE_DELEGATE_COMPAT["builtin_ops"]
- CUSTOM_COMPATIBILITY = TFLITE_DELEGATE_COMPAT["custom_ops"]
-
- class SupportType(Enum):
- """Type of operator support."""
-
- COMPATIBLE = "Compatible"
- OP_NOT_SUPPORTED = "Operator not supported"
- ACTIVATION_NOT_SUPPORTED = "Activation not supported"
-
- name: str
- location: str
- support_type: SupportType
- activation_func: TFL_ACTIVATION_FUNCTION
- custom_name: str | None = None
-
- @property
- def is_cortex_a_compatible(self) -> bool:
- """Check if this operator is compatible."""
- return self.support_type == Operator.SupportType.COMPATIBLE
-
- @property
- def full_name(self) -> str:
- """Returun the full name including the custom name if applicable."""
- return self.name + (f" - '{self.custom_name}'" if self.custom_name else "")
-
- @property
- def is_custom(self) -> bool:
- """Check if this is a custom operator."""
- return bool(self.custom_name)
-
- @property
- def compatibility_data(self) -> dict[str, dict[str, Any]]:
- """Get the compatibility data (builtin or custom ops)."""
- return (
- Operator.CUSTOM_COMPATIBILITY
- if self.is_custom
- else Operator.BUILTIN_COMPATIBILITY
- )
-
- @property
- def supported_activation_functions(self) -> list[str]:
- """Return a list of fused activation functions supported by this op."""
- op_name = self.custom_name if self.custom_name else self.name
- return self.compatibility_data[op_name].get("supported_fused_activation", [])
-
- @classmethod
- def from_tflite_op(cls, tfl_op: Op, location: str) -> Operator:
- """Create a new instance from TensorFlow Lite operator and location."""
- support_type = cls._get_support_type(tfl_op)
- activation_func = (
- tfl_op.builtin_options["fused_activation_function"]
- if (
- tfl_op.builtin_options
- and "fused_activation_function" in tfl_op.builtin_options
- )
- else TFL_ACTIVATION_FUNCTION.NONE
- )
- return Operator(
- tfl_op.type,
- location,
- support_type,
- activation_func=activation_func,
- custom_name=(tfl_op.custom_type if tfl_op.is_custom else None),
- )
-
- @staticmethod
- def _get_support_type(tfl_op: Op) -> Operator.SupportType:
- """Get the support type from the TensorFlow Lite operator."""
- compat_data = (
- Operator.CUSTOM_COMPATIBILITY
- if tfl_op.is_custom
- else Operator.BUILTIN_COMPATIBILITY
- )
- op_type = tfl_op.custom_type if tfl_op.is_custom else tfl_op.type
-
- if op_type not in compat_data:
- return Operator.SupportType.OP_NOT_SUPPORTED
-
- compat_op = compat_data[op_type]
- if "supported_fused_activation" in compat_op:
- assert tfl_op.builtin_options
- assert "fused_activation_function" in tfl_op.builtin_options
- if (
- tfl_op.builtin_options["fused_activation_function"]
- not in compat_op["supported_fused_activation"]
- ):
- return Operator.SupportType.ACTIVATION_NOT_SUPPORTED
-
- return Operator.SupportType.COMPATIBLE
-
-
-@dataclass
-class CortexACompatibilityInfo:
- """Model's operators."""
-
- cortex_a_compatible: bool
- operators: list[Operator]
- backend_info: ClassVar[str] = (
- f"{TFLITE_DELEGATE_COMPAT['metadata']['backend']} "
- f"{TFLITE_DELEGATE_COMPAT['metadata']['version']}"
- )
-
-
-def get_cortex_a_compatibility_info(model_path: Path) -> CortexACompatibilityInfo:
- """Return list of model's operators."""
- model = parse_subgraphs(model_path)
-
- op_list = [
- Operator.from_tflite_op(oper, f"subgraph:{g_idx},oper:{op_idx}")
- for g_idx, g in enumerate(model)
- for op_idx, oper in enumerate(g)
- ]
- all_compatible = all(oper.is_cortex_a_compatible for oper in op_list)
- compat_info = CortexACompatibilityInfo(all_compatible, op_list)
-
- return compat_info
-
-
-def report() -> None:
- """Generate supported operators report."""
- raise Exception(
- "Generating a supported operators report is not "
- "currently supported with Cortex-A target profile."
- )
diff --git a/src/mlia/devices/cortexa/reporters.py b/src/mlia/devices/cortexa/reporters.py
deleted file mode 100644
index 84de10b..0000000
--- a/src/mlia/devices/cortexa/reporters.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Reports module."""
-from __future__ import annotations
-
-from typing import Any
-from typing import Callable
-from typing import cast
-
-from mlia.core.advice_generation import Advice
-from mlia.core.reporters import report_advice
-from mlia.core.reporting import Cell
-from mlia.core.reporting import Column
-from mlia.core.reporting import Format
-from mlia.core.reporting import NestedReport
-from mlia.core.reporting import Report
-from mlia.core.reporting import ReportItem
-from mlia.core.reporting import Table
-from mlia.devices.cortexa.config import CortexAConfiguration
-from mlia.devices.cortexa.operators import Operator
-from mlia.nn.tensorflow.tflite_compat import TFLiteCompatibilityInfo
-from mlia.utils.console import style_improvement
-from mlia.utils.types import is_list_of
-
-
-def report_device(device: CortexAConfiguration) -> Report:
- """Generate report for the device."""
- return NestedReport(
- "Device information",
- "device",
- [
- ReportItem("Target", alias="target", value=device.target),
- ],
- )
-
-
-def report_tflite_compatiblity(compat_info: TFLiteCompatibilityInfo) -> Report:
- """Generate report for the TensorFlow Lite compatibility information."""
- if compat_info.conversion_errors:
- return Table(
- [
- Column("#", only_for=["plain_text"]),
- Column("Operator", alias="operator"),
- Column(
- "Operator location",
- alias="operator_location",
- fmt=Format(wrap_width=25),
- ),
- Column("Error code", alias="error_code"),
- Column(
- "Error message", alias="error_message", fmt=Format(wrap_width=25)
- ),
- ],
- [
- (
- index + 1,
- err.operator,
- ", ".join(err.location),
- err.code.name,
- err.message,
- )
- for index, err in enumerate(compat_info.conversion_errors)
- ],
- name="TensorFlow Lite conversion errors",
- alias="tensorflow_lite_conversion_errors",
- )
-
- return Table(
- columns=[
- Column("Reason", alias="reason"),
- Column(
- "Exception details",
- alias="exception_details",
- fmt=Format(wrap_width=40),
- ),
- ],
- rows=[
- (
- "TensorFlow Lite compatibility check failed with exception",
- str(compat_info.conversion_exception),
- ),
- ],
- name="TensorFlow Lite compatibility errors",
- alias="tflite_compatibility",
- )
-
-
-def report_cortex_a_operators(ops: list[Operator]) -> Report:
- """Generate report for the operators."""
- return Table(
- [
- Column("#", only_for=["plain_text"]),
- Column(
- "Operator location",
- alias="operator_location",
- fmt=Format(wrap_width=30),
- ),
- Column("Operator name", alias="operator_name", fmt=Format(wrap_width=20)),
- Column(
- "Arm NN TFLite Delegate compatibility",
- alias="cortex_a_compatible",
- fmt=Format(wrap_width=40),
- ),
- ],
- [
- (
- index + 1,
- op.location,
- op.full_name,
- Cell(
- op.support_type,
- Format(
- wrap_width=30,
- style=style_improvement(op.is_cortex_a_compatible),
- str_fmt=lambda v: cast(str, v.value),
- ),
- ),
- )
- for index, op in enumerate(ops)
- ],
- name="Operators",
- alias="operators",
- )
-
-
-def cortex_a_formatters(data: Any) -> Callable[[Any], Report]:
- """Find appropriate formatter for the provided data."""
- if is_list_of(data, Advice):
- return report_advice
-
- if isinstance(data, CortexAConfiguration):
- return report_device
-
- if isinstance(data, TFLiteCompatibilityInfo):
- return report_tflite_compatiblity
-
- if is_list_of(data, Operator):
- return report_cortex_a_operators
-
- raise Exception(f"Unable to find appropriate formatter for {data}")