aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenjamin Klimczak <benjamin.klimczak@arm.com>2022-06-28 10:29:35 +0100
committerBenjamin Klimczak <benjamin.klimczak@arm.com>2022-07-08 10:57:19 +0100
commitc9b4089b3037b5943565d76242d3016b8776f8d2 (patch)
tree3de24f79dedf0f26f492a7fa1562bf684e13a055 /src
parentba2c7fcccf37e8c81946f0776714c64f73191787 (diff)
downloadmlia-c9b4089b3037b5943565d76242d3016b8776f8d2.tar.gz
MLIA-546 Merge AIET into MLIA
Merge the deprecated AIET interface for backend execution into MLIA: - Execute backends directly (without subprocess and the aiet CLI) - Fix issues with the unit tests - Remove src/aiet and tests/aiet - Re-factor code to replace 'aiet' with 'backend' - Adapt and improve unit tests after re-factoring - Remove dependencies that are not needed anymore (click and cloup) Change-Id: I450734c6a3f705ba9afde41862b29e797e511f7c
Diffstat (limited to 'src')
-rw-r--r--src/aiet/__init__.py7
-rw-r--r--src/aiet/backend/tool.py109
-rw-r--r--src/aiet/cli/__init__.py28
-rw-r--r--src/aiet/cli/application.py362
-rw-r--r--src/aiet/cli/common.py173
-rw-r--r--src/aiet/cli/completion.py72
-rw-r--r--src/aiet/cli/system.py122
-rw-r--r--src/aiet/cli/tool.py143
-rw-r--r--src/aiet/main.py13
-rw-r--r--src/aiet/resources/tools/vela/aiet-config.json73
-rw-r--r--src/aiet/resources/tools/vela/aiet-config.json.license3
-rw-r--r--src/aiet/resources/tools/vela/check_model.py75
-rw-r--r--src/aiet/resources/tools/vela/run_vela.py65
-rw-r--r--src/aiet/resources/tools/vela/vela.ini53
-rw-r--r--src/aiet/utils/__init__.py3
-rw-r--r--src/aiet/utils/helpers.py17
-rw-r--r--src/mlia/backend/__init__.py (renamed from src/aiet/backend/__init__.py)0
-rw-r--r--src/mlia/backend/application.py (renamed from src/aiet/backend/application.py)28
-rw-r--r--src/mlia/backend/common.py (renamed from src/aiet/backend/common.py)22
-rw-r--r--src/mlia/backend/config.py (renamed from src/aiet/backend/config.py)18
-rw-r--r--src/mlia/backend/controller.py (renamed from src/aiet/backend/controller.py)16
-rw-r--r--src/mlia/backend/execution.py (renamed from src/aiet/backend/execution.py)148
-rw-r--r--src/mlia/backend/fs.py (renamed from src/aiet/utils/fs.py)19
-rw-r--r--src/mlia/backend/manager.py (renamed from src/mlia/tools/aiet_wrapper.py)108
-rw-r--r--src/mlia/backend/output_parser.py (renamed from src/aiet/backend/output_parser.py)0
-rw-r--r--src/mlia/backend/proc.py (renamed from src/aiet/utils/proc.py)2
-rw-r--r--src/mlia/backend/protocol.py (renamed from src/aiet/backend/protocol.py)8
-rw-r--r--src/mlia/backend/source.py (renamed from src/aiet/backend/source.py)18
-rw-r--r--src/mlia/backend/system.py (renamed from src/aiet/backend/system.py)34
-rw-r--r--src/mlia/cli/config.py6
-rw-r--r--src/mlia/devices/ethosu/performance.py37
-rw-r--r--src/mlia/resources/aiet/applications/APPLICATIONS.txt5
-rw-r--r--src/mlia/resources/aiet/systems/SYSTEMS.txt3
-rw-r--r--src/mlia/resources/backends/applications/.gitignore (renamed from src/aiet/resources/applications/.gitignore)0
-rw-r--r--src/mlia/resources/backends/systems/.gitignore (renamed from src/aiet/resources/systems/.gitignore)0
-rw-r--r--src/mlia/tools/metadata/corstone.py61
-rw-r--r--src/mlia/utils/proc.py20
37 files changed, 230 insertions, 1641 deletions
diff --git a/src/aiet/__init__.py b/src/aiet/__init__.py
deleted file mode 100644
index 49304b1..0000000
--- a/src/aiet/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Init of aiet."""
-import pkg_resources
-
-
-__version__ = pkg_resources.get_distribution("mlia").version
diff --git a/src/aiet/backend/tool.py b/src/aiet/backend/tool.py
deleted file mode 100644
index d643665..0000000
--- a/src/aiet/backend/tool.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Tool backend module."""
-from typing import Any
-from typing import cast
-from typing import Dict
-from typing import List
-from typing import Optional
-
-from aiet.backend.common import Backend
-from aiet.backend.common import ConfigurationException
-from aiet.backend.common import get_backend_configs
-from aiet.backend.common import get_backend_directories
-from aiet.backend.common import load_application_or_tool_configs
-from aiet.backend.common import load_config
-from aiet.backend.config import ExtendedToolConfig
-from aiet.backend.config import ToolConfig
-
-
-def get_available_tool_directory_names() -> List[str]:
- """Return a list of directory names for all available tools."""
- return [entry.name for entry in get_backend_directories("tools")]
-
-
-def get_available_tools() -> List["Tool"]:
- """Return a list with all available tools."""
- available_tools = []
- for config_json in get_backend_configs("tools"):
- config_entries = cast(List[ExtendedToolConfig], load_config(config_json))
- for config_entry in config_entries:
- config_entry["config_location"] = config_json.parent.absolute()
- tools = load_tools(config_entry)
- available_tools += tools
-
- return sorted(available_tools, key=lambda tool: tool.name)
-
-
-def get_tool(tool_name: str, system_name: Optional[str] = None) -> List["Tool"]:
- """Return a tool instance with the same name passed as argument."""
- return [
- tool
- for tool in get_available_tools()
- if tool.name == tool_name and (not system_name or tool.can_run_on(system_name))
- ]
-
-
-def get_unique_tool_names(system_name: Optional[str] = None) -> List[str]:
- """Extract a list of unique tool names of all tools available."""
- return list(
- set(
- tool.name
- for tool in get_available_tools()
- if not system_name or tool.can_run_on(system_name)
- )
- )
-
-
-class Tool(Backend):
- """Class for representing a single tool component."""
-
- def __init__(self, config: ToolConfig) -> None:
- """Construct a Tool instance from a dict."""
- super().__init__(config)
-
- self.supported_systems = config.get("supported_systems", [])
-
- if "run" not in self.commands:
- raise ConfigurationException("A Tool must have a 'run' command.")
-
- def __eq__(self, other: object) -> bool:
- """Overload operator ==."""
- if not isinstance(other, Tool):
- return False
-
- return (
- super().__eq__(other)
- and self.name == other.name
- and set(self.supported_systems) == set(other.supported_systems)
- )
-
- def can_run_on(self, system_name: str) -> bool:
- """Check if the tool can run on the system passed as argument."""
- return system_name in self.supported_systems
-
- def get_details(self) -> Dict[str, Any]:
- """Return dictionary with all relevant information of the Tool instance."""
- output = {
- "type": "tool",
- "name": self.name,
- "description": self.description,
- "supported_systems": self.supported_systems,
- "commands": self._get_command_details(),
- }
-
- return output
-
-
-def load_tools(config: ExtendedToolConfig) -> List[Tool]:
- """Load tool.
-
- Tool configuration could contain different parameters/commands for different
- supported systems. For each supported system this function will return separate
- Tool instance with appropriate configuration.
- """
- configs = load_application_or_tool_configs(
- config, ToolConfig, is_system_required=False
- )
- tools = [Tool(cfg) for cfg in configs]
- return tools
diff --git a/src/aiet/cli/__init__.py b/src/aiet/cli/__init__.py
deleted file mode 100644
index bcd17c3..0000000
--- a/src/aiet/cli/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Module to mange the CLI interface."""
-import click
-
-from aiet import __version__
-from aiet.cli.application import application_cmd
-from aiet.cli.completion import completion_cmd
-from aiet.cli.system import system_cmd
-from aiet.cli.tool import tool_cmd
-from aiet.utils.helpers import set_verbosity
-
-
-@click.group()
-@click.version_option(__version__)
-@click.option(
- "-v", "--verbose", default=0, count=True, callback=set_verbosity, expose_value=False
-)
-@click.pass_context
-def cli(ctx: click.Context) -> None: # pylint: disable=unused-argument
- """AIET: AI Evaluation Toolkit."""
- # Unused arguments must be present here in definition to pass click context.
-
-
-cli.add_command(application_cmd)
-cli.add_command(system_cmd)
-cli.add_command(tool_cmd)
-cli.add_command(completion_cmd)
diff --git a/src/aiet/cli/application.py b/src/aiet/cli/application.py
deleted file mode 100644
index 59b652d..0000000
--- a/src/aiet/cli/application.py
+++ /dev/null
@@ -1,362 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-FileCopyrightText: Copyright (c) 2021, Gianluca Gippetto. All rights reserved.
-# SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
-"""Module to manage the CLI interface of applications."""
-import json
-import logging
-import re
-from pathlib import Path
-from typing import Any
-from typing import IO
-from typing import List
-from typing import Optional
-from typing import Tuple
-
-import click
-import cloup
-
-from aiet.backend.application import get_application
-from aiet.backend.application import get_available_application_directory_names
-from aiet.backend.application import get_unique_application_names
-from aiet.backend.application import install_application
-from aiet.backend.application import remove_application
-from aiet.backend.common import DataPaths
-from aiet.backend.execution import execute_application_command
-from aiet.backend.execution import run_application
-from aiet.backend.system import get_available_systems
-from aiet.cli.common import get_format
-from aiet.cli.common import middleware_exception_handler
-from aiet.cli.common import middleware_signal_handler
-from aiet.cli.common import print_command_details
-from aiet.cli.common import set_format
-
-
-@click.group(name="application")
-@click.option(
- "-f",
- "--format",
- "format_",
- type=click.Choice(["cli", "json"]),
- default="cli",
- show_default=True,
-)
-@click.pass_context
-def application_cmd(ctx: click.Context, format_: str) -> None:
- """Sub command to manage applications."""
- set_format(ctx, format_)
-
-
-@application_cmd.command(name="list")
-@click.pass_context
-@click.option(
- "-s",
- "--system",
- "system_name",
- type=click.Choice([s.name for s in get_available_systems()]),
- required=False,
-)
-def list_cmd(ctx: click.Context, system_name: str) -> None:
- """List all available applications."""
- unique_application_names = get_unique_application_names(system_name)
- unique_application_names.sort()
- if get_format(ctx) == "json":
- data = {"type": "application", "available": unique_application_names}
- print(json.dumps(data))
- else:
- print("Available applications:\n")
- print(*unique_application_names, sep="\n")
-
-
-@application_cmd.command(name="details")
-@click.option(
- "-n",
- "--name",
- "application_name",
- type=click.Choice(get_unique_application_names()),
- required=True,
-)
-@click.option(
- "-s",
- "--system",
- "system_name",
- type=click.Choice([s.name for s in get_available_systems()]),
- required=False,
-)
-@click.pass_context
-def details_cmd(ctx: click.Context, application_name: str, system_name: str) -> None:
- """Details of a specific application."""
- applications = get_application(application_name, system_name)
- if not applications:
- raise click.UsageError(
- "Application '{}' doesn't support the system '{}'".format(
- application_name, system_name
- )
- )
-
- if get_format(ctx) == "json":
- applications_details = [s.get_details() for s in applications]
- print(json.dumps(applications_details))
- else:
- for application in applications:
- application_details = application.get_details()
- application_details_template = (
- 'Application "{name}" details\nDescription: {description}'
- )
-
- print(
- application_details_template.format(
- name=application_details["name"],
- description=application_details["description"],
- )
- )
-
- print(
- "\nSupported systems: {}".format(
- ", ".join(application_details["supported_systems"])
- )
- )
-
- command_details = application_details["commands"]
-
- for command, details in command_details.items():
- print("\n{} commands:".format(command))
- print_command_details(details)
-
-
-# pylint: disable=too-many-arguments
-@application_cmd.command(name="execute")
-@click.option(
- "-n",
- "--name",
- "application_name",
- type=click.Choice(get_unique_application_names()),
- required=True,
-)
-@click.option(
- "-s",
- "--system",
- "system_name",
- type=click.Choice([s.name for s in get_available_systems()]),
- required=True,
-)
-@click.option(
- "-c",
- "--command",
- "command_name",
- type=click.Choice(["build", "run"]),
- required=True,
-)
-@click.option("-p", "--param", "application_params", multiple=True)
-@click.option("--system-param", "system_params", multiple=True)
-@click.option("-d", "--deploy", "deploy_params", multiple=True)
-@middleware_signal_handler
-@middleware_exception_handler
-def execute_cmd(
- application_name: str,
- system_name: str,
- command_name: str,
- application_params: List[str],
- system_params: List[str],
- deploy_params: List[str],
-) -> None:
- """Execute application commands. DEPRECATED! Use 'aiet application run' instead."""
- logging.warning(
- "Please use 'aiet application run' instead. Use of 'aiet application "
- "execute' is deprecated and might be removed in a future release."
- )
-
- custom_deploy_data = get_custom_deploy_data(command_name, deploy_params)
-
- execute_application_command(
- command_name,
- application_name,
- application_params,
- system_name,
- system_params,
- custom_deploy_data,
- )
-
-
-@cloup.command(name="run")
-@cloup.option(
- "-n",
- "--name",
- "application_name",
- type=click.Choice(get_unique_application_names()),
-)
-@cloup.option(
- "-s",
- "--system",
- "system_name",
- type=click.Choice([s.name for s in get_available_systems()]),
-)
-@cloup.option("-p", "--param", "application_params", multiple=True)
-@cloup.option("--system-param", "system_params", multiple=True)
-@cloup.option("-d", "--deploy", "deploy_params", multiple=True)
-@click.option(
- "-r",
- "--report",
- "report_file",
- type=Path,
- help="Create a report file in JSON format containing metrics parsed from "
- "the simulation output as specified in the aiet-config.json.",
-)
-@cloup.option(
- "--config",
- "config_file",
- type=click.File("r"),
- help="Read options from a config file rather than from the command line. "
- "The config file is a json file.",
-)
-@cloup.constraint(
- cloup.constraints.If(
- cloup.constraints.conditions.Not(
- cloup.constraints.conditions.IsSet("config_file")
- ),
- then=cloup.constraints.require_all,
- ),
- ["system_name", "application_name"],
-)
-@cloup.constraint(
- cloup.constraints.If("config_file", then=cloup.constraints.accept_none),
- [
- "system_name",
- "application_name",
- "application_params",
- "system_params",
- "deploy_params",
- ],
-)
-@middleware_signal_handler
-@middleware_exception_handler
-def run_cmd(
- application_name: str,
- system_name: str,
- application_params: List[str],
- system_params: List[str],
- deploy_params: List[str],
- report_file: Optional[Path],
- config_file: Optional[IO[str]],
-) -> None:
- """Execute application commands."""
- if config_file:
- payload_data = json.load(config_file)
- (
- system_name,
- application_name,
- application_params,
- system_params,
- deploy_params,
- report_file,
- ) = parse_payload_run_config(payload_data)
-
- custom_deploy_data = get_custom_deploy_data("run", deploy_params)
-
- run_application(
- application_name,
- application_params,
- system_name,
- system_params,
- custom_deploy_data,
- report_file,
- )
-
-
-application_cmd.add_command(run_cmd)
-
-
-def parse_payload_run_config(
- payload_data: dict,
-) -> Tuple[str, str, List[str], List[str], List[str], Optional[Path]]:
- """Parse the payload into a tuple."""
- system_id = payload_data.get("id")
- arguments: Optional[Any] = payload_data.get("arguments")
-
- if not isinstance(system_id, str):
- raise click.ClickException("invalid payload json: no system 'id'")
- if not isinstance(arguments, dict):
- raise click.ClickException("invalid payload json: no arguments object")
-
- application_name = arguments.pop("application", None)
- if not isinstance(application_name, str):
- raise click.ClickException("invalid payload json: no application_id")
-
- report_path = arguments.pop("report_path", None)
-
- application_params = []
- system_params = []
- deploy_params = []
-
- for (param_key, value) in arguments.items():
- (par, _) = re.subn("^application/", "", param_key)
- (par, found_sys_param) = re.subn("^system/", "", par)
- (par, found_deploy_param) = re.subn("^deploy/", "", par)
-
- param_expr = par + "=" + value
- if found_sys_param:
- system_params.append(param_expr)
- elif found_deploy_param:
- deploy_params.append(par)
- else:
- application_params.append(param_expr)
-
- return (
- system_id,
- application_name,
- application_params,
- system_params,
- deploy_params,
- report_path,
- )
-
-
-def get_custom_deploy_data(
- command_name: str, deploy_params: List[str]
-) -> List[DataPaths]:
- """Get custom deploy data information."""
- custom_deploy_data: List[DataPaths] = []
- if not deploy_params:
- return custom_deploy_data
-
- for param in deploy_params:
- parts = param.split(":")
- if not len(parts) == 2 or any(not part.strip() for part in parts):
- raise click.ClickException(
- "Invalid deploy parameter '{}' for command {}".format(
- param, command_name
- )
- )
- data_path = DataPaths(Path(parts[0]), parts[1])
- if not data_path.src.exists():
- raise click.ClickException("Path {} does not exist".format(data_path.src))
- custom_deploy_data.append(data_path)
-
- return custom_deploy_data
-
-
-@application_cmd.command(name="install")
-@click.option(
- "-s",
- "--source",
- "source",
- required=True,
- help="Path to the directory or archive with application definition",
-)
-def install_cmd(source: str) -> None:
- """Install new application."""
- source_path = Path(source)
- install_application(source_path)
-
-
-@application_cmd.command(name="remove")
-@click.option(
- "-d",
- "--directory_name",
- "directory_name",
- type=click.Choice(get_available_application_directory_names()),
- required=True,
- help="Name of the directory with application",
-)
-def remove_cmd(directory_name: str) -> None:
- """Remove application."""
- remove_application(directory_name)
diff --git a/src/aiet/cli/common.py b/src/aiet/cli/common.py
deleted file mode 100644
index 1d157b6..0000000
--- a/src/aiet/cli/common.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Common functions for cli module."""
-import enum
-import logging
-from functools import wraps
-from signal import SIG_IGN
-from signal import SIGINT
-from signal import signal as signal_handler
-from signal import SIGTERM
-from typing import Any
-from typing import Callable
-from typing import cast
-from typing import Dict
-
-from click import ClickException
-from click import Context
-from click import UsageError
-
-from aiet.backend.common import ConfigurationException
-from aiet.backend.execution import AnotherInstanceIsRunningException
-from aiet.backend.execution import ConnectionException
-from aiet.backend.protocol import SSHConnectionException
-from aiet.utils.proc import CommandFailedException
-
-
-class MiddlewareExitCode(enum.IntEnum):
- """Middleware exit codes."""
-
- SUCCESS = 0
- # exit codes 1 and 2 are used by click
- SHUTDOWN_REQUESTED = 3
- BACKEND_ERROR = 4
- CONCURRENT_ERROR = 5
- CONNECTION_ERROR = 6
- CONFIGURATION_ERROR = 7
- MODEL_OPTIMISED_ERROR = 8
- INVALID_TFLITE_FILE_ERROR = 9
-
-
-class CustomClickException(ClickException):
- """Custom click exception."""
-
- def show(self, file: Any = None) -> None:
- """Override show method."""
- super().show(file)
-
- logging.debug("Execution failed with following exception: ", exc_info=self)
-
-
-class MiddlewareShutdownException(CustomClickException):
- """Exception indicates that user requested middleware shutdown."""
-
- exit_code = int(MiddlewareExitCode.SHUTDOWN_REQUESTED)
-
-
-class BackendException(CustomClickException):
- """Exception indicates that command failed."""
-
- exit_code = int(MiddlewareExitCode.BACKEND_ERROR)
-
-
-class ConcurrentErrorException(CustomClickException):
- """Exception indicates concurrent execution error."""
-
- exit_code = int(MiddlewareExitCode.CONCURRENT_ERROR)
-
-
-class BackendConnectionException(CustomClickException):
- """Exception indicates that connection could not be established."""
-
- exit_code = int(MiddlewareExitCode.CONNECTION_ERROR)
-
-
-class BackendConfigurationException(CustomClickException):
- """Exception indicates some configuration issue."""
-
- exit_code = int(MiddlewareExitCode.CONFIGURATION_ERROR)
-
-
-class ModelOptimisedException(CustomClickException):
- """Exception indicates input file has previously been Vela optimised."""
-
- exit_code = int(MiddlewareExitCode.MODEL_OPTIMISED_ERROR)
-
-
-class InvalidTFLiteFileError(CustomClickException):
- """Exception indicates input TFLite file is misformatted."""
-
- exit_code = int(MiddlewareExitCode.INVALID_TFLITE_FILE_ERROR)
-
-
-def print_command_details(command: Dict) -> None:
- """Print command details including parameters."""
- command_strings = command["command_strings"]
- print("Commands: {}".format(command_strings))
- user_params = command["user_params"]
- for i, param in enumerate(user_params, 1):
- print("User parameter #{}".format(i))
- print("\tName: {}".format(param.get("name", "-")))
- print("\tDescription: {}".format(param["description"]))
- print("\tPossible values: {}".format(param.get("values", "-")))
- print("\tDefault value: {}".format(param.get("default_value", "-")))
- print("\tAlias: {}".format(param.get("alias", "-")))
-
-
-def raise_exception_at_signal(
- signum: int, frame: Any # pylint: disable=unused-argument
-) -> None:
- """Handle signals."""
- # Disable both SIGINT and SIGTERM signals. Further SIGINT and SIGTERM
- # signals will be ignored as we allow a graceful shutdown.
- # Unused arguments must be present here in definition as used in signal handler
- # callback
-
- signal_handler(SIGINT, SIG_IGN)
- signal_handler(SIGTERM, SIG_IGN)
- raise MiddlewareShutdownException("Middleware shutdown requested")
-
-
-def middleware_exception_handler(func: Callable) -> Callable:
- """Handle backend exceptions decorator."""
-
- @wraps(func)
- def wrapper(*args: Any, **kwargs: Any) -> Any:
- try:
- return func(*args, **kwargs)
- except (MiddlewareShutdownException, UsageError, ClickException) as error:
- # click should take care of these exceptions
- raise error
- except ValueError as error:
- raise ClickException(str(error)) from error
- except AnotherInstanceIsRunningException as error:
- raise ConcurrentErrorException(
- "Another instance of the system is running"
- ) from error
- except (SSHConnectionException, ConnectionException) as error:
- raise BackendConnectionException(str(error)) from error
- except ConfigurationException as error:
- raise BackendConfigurationException(str(error)) from error
- except (CommandFailedException, Exception) as error:
- raise BackendException(
- "Execution failed. Please check output for the details."
- ) from error
-
- return wrapper
-
-
-def middleware_signal_handler(func: Callable) -> Callable:
- """Handle signals decorator."""
-
- @wraps(func)
- def wrapper(*args: Any, **kwargs: Any) -> Any:
- # Set up signal handlers for SIGINT (ctrl-c) and SIGTERM (kill command)
- # The handler ignores further signals and it raises an exception
- signal_handler(SIGINT, raise_exception_at_signal)
- signal_handler(SIGTERM, raise_exception_at_signal)
-
- return func(*args, **kwargs)
-
- return wrapper
-
-
-def set_format(ctx: Context, format_: str) -> None:
- """Save format in click context."""
- ctx_obj = ctx.ensure_object(dict)
- ctx_obj["format"] = format_
-
-
-def get_format(ctx: Context) -> str:
- """Get format from click context."""
- ctx_obj = cast(Dict[str, str], ctx.ensure_object(dict))
- return ctx_obj["format"]
diff --git a/src/aiet/cli/completion.py b/src/aiet/cli/completion.py
deleted file mode 100644
index 71f054f..0000000
--- a/src/aiet/cli/completion.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""
-Add auto completion to different shells with these helpers.
-
-See: https://click.palletsprojects.com/en/8.0.x/shell-completion/
-"""
-import click
-
-
-def _get_package_name() -> str:
- return __name__.split(".", maxsplit=1)[0]
-
-
-# aiet completion bash
-@click.group(name="completion")
-def completion_cmd() -> None:
- """Enable auto completion for your shell."""
-
-
-@completion_cmd.command(name="bash")
-def bash_cmd() -> None:
- """
- Enable auto completion for bash.
-
- Use this command to activate completion in the current bash:
-
- eval "`aiet completion bash`"
-
- Use this command to add auto completion to bash globally, if you have aiet
- installed globally (requires starting a new shell afterwards):
-
- aiet completion bash >> ~/.bashrc
- """
- package_name = _get_package_name()
- print(f'eval "$(_{package_name.upper()}_COMPLETE=bash_source {package_name})"')
-
-
-@completion_cmd.command(name="zsh")
-def zsh_cmd() -> None:
- """
- Enable auto completion for zsh.
-
- Use this command to activate completion in the current zsh:
-
- eval "`aiet completion zsh`"
-
- Use this command to add auto completion to zsh globally, if you have aiet
- installed globally (requires starting a new shell afterwards):
-
- aiet completion zsh >> ~/.zshrc
- """
- package_name = _get_package_name()
- print(f'eval "$(_{package_name.upper()}_COMPLETE=zsh_source {package_name})"')
-
-
-@completion_cmd.command(name="fish")
-def fish_cmd() -> None:
- """
- Enable auto completion for fish.
-
- Use this command to activate completion in the current fish:
-
- eval "`aiet completion fish`"
-
- Use this command to add auto completion to fish globally, if you have aiet
- installed globally (requires starting a new shell afterwards):
-
- aiet completion fish >> ~/.config/fish/completions/aiet.fish
- """
- package_name = _get_package_name()
- print(f'eval "(env _{package_name.upper()}_COMPLETE=fish_source {package_name})"')
diff --git a/src/aiet/cli/system.py b/src/aiet/cli/system.py
deleted file mode 100644
index f1f7637..0000000
--- a/src/aiet/cli/system.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Module to manage the CLI interface of systems."""
-import json
-from pathlib import Path
-from typing import cast
-
-import click
-
-from aiet.backend.application import get_available_applications
-from aiet.backend.system import get_available_systems
-from aiet.backend.system import get_available_systems_directory_names
-from aiet.backend.system import get_system
-from aiet.backend.system import install_system
-from aiet.backend.system import remove_system
-from aiet.backend.system import System
-from aiet.cli.common import get_format
-from aiet.cli.common import print_command_details
-from aiet.cli.common import set_format
-
-
-@click.group(name="system")
-@click.option(
- "-f",
- "--format",
- "format_",
- type=click.Choice(["cli", "json"]),
- default="cli",
- show_default=True,
-)
-@click.pass_context
-def system_cmd(ctx: click.Context, format_: str) -> None:
- """Sub command to manage systems."""
- set_format(ctx, format_)
-
-
-@system_cmd.command(name="list")
-@click.pass_context
-def list_cmd(ctx: click.Context) -> None:
- """List all available systems."""
- available_systems = get_available_systems()
- system_names = [system.name for system in available_systems]
- if get_format(ctx) == "json":
- data = {"type": "system", "available": system_names}
- print(json.dumps(data))
- else:
- print("Available systems:\n")
- print(*system_names, sep="\n")
-
-
-@system_cmd.command(name="details")
-@click.option(
- "-n",
- "--name",
- "system_name",
- type=click.Choice([s.name for s in get_available_systems()]),
- required=True,
-)
-@click.pass_context
-def details_cmd(ctx: click.Context, system_name: str) -> None:
- """Details of a specific system."""
- system = cast(System, get_system(system_name))
- applications = [
- s.name for s in get_available_applications() if s.can_run_on(system.name)
- ]
- system_details = system.get_details()
- if get_format(ctx) == "json":
- system_details["available_application"] = applications
- print(json.dumps(system_details))
- else:
- system_details_template = (
- 'System "{name}" details\n'
- "Description: {description}\n"
- "Data Transfer Protocol: {protocol}\n"
- "Available Applications: {available_application}"
- )
- print(
- system_details_template.format(
- name=system_details["name"],
- description=system_details["description"],
- protocol=system_details["data_transfer_protocol"],
- available_application=", ".join(applications),
- )
- )
-
- if system_details["annotations"]:
- print("Annotations:")
- for ann_name, ann_value in system_details["annotations"].items():
- print("\t{}: {}".format(ann_name, ann_value))
-
- command_details = system_details["commands"]
- for command, details in command_details.items():
- print("\n{} commands:".format(command))
- print_command_details(details)
-
-
-@system_cmd.command(name="install")
-@click.option(
- "-s",
- "--source",
- "source",
- required=True,
- help="Path to the directory or archive with system definition",
-)
-def install_cmd(source: str) -> None:
- """Install new system."""
- source_path = Path(source)
- install_system(source_path)
-
-
-@system_cmd.command(name="remove")
-@click.option(
- "-d",
- "--directory_name",
- "directory_name",
- type=click.Choice(get_available_systems_directory_names()),
- required=True,
- help="Name of the directory with system",
-)
-def remove_cmd(directory_name: str) -> None:
- """Remove system by given name."""
- remove_system(directory_name)
diff --git a/src/aiet/cli/tool.py b/src/aiet/cli/tool.py
deleted file mode 100644
index 2c80821..0000000
--- a/src/aiet/cli/tool.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Module to manage the CLI interface of tools."""
-import json
-from typing import Any
-from typing import List
-from typing import Optional
-
-import click
-
-from aiet.backend.execution import execute_tool_command
-from aiet.backend.tool import get_tool
-from aiet.backend.tool import get_unique_tool_names
-from aiet.cli.common import get_format
-from aiet.cli.common import middleware_exception_handler
-from aiet.cli.common import middleware_signal_handler
-from aiet.cli.common import print_command_details
-from aiet.cli.common import set_format
-
-
-@click.group(name="tool")
-@click.option(
- "-f",
- "--format",
- "format_",
- type=click.Choice(["cli", "json"]),
- default="cli",
- show_default=True,
-)
-@click.pass_context
-def tool_cmd(ctx: click.Context, format_: str) -> None:
- """Sub command to manage tools."""
- set_format(ctx, format_)
-
-
-@tool_cmd.command(name="list")
-@click.pass_context
-def list_cmd(ctx: click.Context) -> None:
- """List all available tools."""
- # raise NotImplementedError("TODO")
- tool_names = get_unique_tool_names()
- tool_names.sort()
- if get_format(ctx) == "json":
- data = {"type": "tool", "available": tool_names}
- print(json.dumps(data))
- else:
- print("Available tools:\n")
- print(*tool_names, sep="\n")
-
-
-def validate_system(
- ctx: click.Context,
- _: click.Parameter, # param is not used
- value: Any,
-) -> Any:
- """Validate provided system name depending on the the tool name."""
- tool_name = ctx.params["tool_name"]
- tools = get_tool(tool_name, value)
- if not tools:
- supported_systems = [tool.supported_systems[0] for tool in get_tool(tool_name)]
- raise click.BadParameter(
- message="'{}' is not one of {}.".format(
- value,
- ", ".join("'{}'".format(system) for system in supported_systems),
- ),
- ctx=ctx,
- )
- return value
-
-
-@tool_cmd.command(name="details")
-@click.option(
- "-n",
- "--name",
- "tool_name",
- type=click.Choice(get_unique_tool_names()),
- required=True,
-)
-@click.option(
- "-s",
- "--system",
- "system_name",
- callback=validate_system,
- required=False,
-)
-@click.pass_context
-@middleware_signal_handler
-@middleware_exception_handler
-def details_cmd(ctx: click.Context, tool_name: str, system_name: Optional[str]) -> None:
- """Details of a specific tool."""
- tools = get_tool(tool_name, system_name)
- if get_format(ctx) == "json":
- tools_details = [s.get_details() for s in tools]
- print(json.dumps(tools_details))
- else:
- for tool in tools:
- tool_details = tool.get_details()
- tool_details_template = 'Tool "{name}" details\nDescription: {description}'
-
- print(
- tool_details_template.format(
- name=tool_details["name"],
- description=tool_details["description"],
- )
- )
-
- print(
- "\nSupported systems: {}".format(
- ", ".join(tool_details["supported_systems"])
- )
- )
-
- command_details = tool_details["commands"]
-
- for command, details in command_details.items():
- print("\n{} commands:".format(command))
- print_command_details(details)
-
-
-# pylint: disable=too-many-arguments
-@tool_cmd.command(name="execute")
-@click.option(
- "-n",
- "--name",
- "tool_name",
- type=click.Choice(get_unique_tool_names()),
- required=True,
-)
-@click.option("-p", "--param", "tool_params", multiple=True)
-@click.option(
- "-s",
- "--system",
- "system_name",
- callback=validate_system,
- required=False,
-)
-@middleware_signal_handler
-@middleware_exception_handler
-def execute_cmd(
- tool_name: str, tool_params: List[str], system_name: Optional[str]
-) -> None:
- """Execute tool commands."""
- execute_tool_command(tool_name, tool_params, system_name)
diff --git a/src/aiet/main.py b/src/aiet/main.py
deleted file mode 100644
index 6898ad9..0000000
--- a/src/aiet/main.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Entry point module of AIET."""
-from aiet.cli import cli
-
-
-def main() -> None:
- """Entry point of aiet application."""
- cli() # pylint: disable=no-value-for-parameter
-
-
-if __name__ == "__main__":
- main()
diff --git a/src/aiet/resources/tools/vela/aiet-config.json b/src/aiet/resources/tools/vela/aiet-config.json
deleted file mode 100644
index c12f291..0000000
--- a/src/aiet/resources/tools/vela/aiet-config.json
+++ /dev/null
@@ -1,73 +0,0 @@
-[
- {
- "name": "vela",
- "description": "Neural network model compiler for Arm Ethos-U NPUs",
- "supported_systems": [
- {
- "name": "Corstone-300: Cortex-M55+Ethos-U55"
- },
- {
- "name": "Corstone-310: Cortex-M85+Ethos-U55"
- },
- {
- "name": "Corstone-300: Cortex-M55+Ethos-U65",
- "variables": {
- "accelerator_config_prefix": "ethos-u65",
- "system_config": "Ethos_U65_High_End",
- "shared_sram": "U65_Shared_Sram"
- },
- "user_params": {
- "run": [
- {
- "description": "MACs per cycle",
- "values": [
- "256",
- "512"
- ],
- "default_value": "512",
- "alias": "mac"
- }
- ]
- }
- }
- ],
- "variables": {
- "accelerator_config_prefix": "ethos-u55",
- "system_config": "Ethos_U55_High_End_Embedded",
- "shared_sram": "U55_Shared_Sram"
- },
- "commands": {
- "run": [
- "run_vela {user_params:input} {user_params:output} --config {tool.config_dir}/vela.ini --accelerator-config {variables:accelerator_config_prefix}-{user_params:mac} --system-config {variables:system_config} --memory-mode {variables:shared_sram} --optimise Performance"
- ]
- },
- "user_params": {
- "run": [
- {
- "description": "MACs per cycle",
- "values": [
- "32",
- "64",
- "128",
- "256"
- ],
- "default_value": "128",
- "alias": "mac"
- },
- {
- "name": "--input-model",
- "description": "Path to the TFLite model",
- "values": [],
- "alias": "input"
- },
- {
- "name": "--output-model",
- "description": "Path to the output model file of the vela-optimisation step. The vela output is saved in the parent directory.",
- "values": [],
- "default_value": "output_model.tflite",
- "alias": "output"
- }
- ]
- }
- }
-]
diff --git a/src/aiet/resources/tools/vela/aiet-config.json.license b/src/aiet/resources/tools/vela/aiet-config.json.license
deleted file mode 100644
index 9b83bfc..0000000
--- a/src/aiet/resources/tools/vela/aiet-config.json.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-
-SPDX-License-Identifier: Apache-2.0
diff --git a/src/aiet/resources/tools/vela/check_model.py b/src/aiet/resources/tools/vela/check_model.py
deleted file mode 100644
index 7c700b1..0000000
--- a/src/aiet/resources/tools/vela/check_model.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2020, 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Check if a TFLite model file is Vela-optimised."""
-import struct
-from pathlib import Path
-
-from ethosu.vela.tflite.Model import Model
-
-from aiet.cli.common import InvalidTFLiteFileError
-from aiet.cli.common import ModelOptimisedException
-from aiet.utils.fs import read_file_as_bytearray
-
-
-def get_model_from_file(input_model_file: Path) -> Model:
- """Generate Model instance from TFLite file using flatc generated code."""
- buffer = read_file_as_bytearray(input_model_file)
- try:
- model = Model.GetRootAsModel(buffer, 0)
- except (TypeError, RuntimeError, struct.error) as tflite_error:
- raise InvalidTFLiteFileError(
- f"Error reading in model from {input_model_file}."
- ) from tflite_error
- return model
-
-
-def is_vela_optimised(tflite_model: Model) -> bool:
- """Return True if 'ethos-u' custom operator found in the Model."""
- operators = get_operators_from_model(tflite_model)
-
- custom_codes = get_custom_codes_from_operators(operators)
-
- return check_custom_codes_for_ethosu(custom_codes)
-
-
-def get_operators_from_model(tflite_model: Model) -> list:
- """Return list of the unique operator codes used in the Model."""
- return [
- tflite_model.OperatorCodes(index)
- for index in range(tflite_model.OperatorCodesLength())
- ]
-
-
-def get_custom_codes_from_operators(operators: list) -> list:
- """Return list of each operator's CustomCode() strings, if they exist."""
- return [
- operator.CustomCode()
- for operator in operators
- if operator.CustomCode() is not None
- ]
-
-
-def check_custom_codes_for_ethosu(custom_codes: list) -> bool:
- """Check for existence of ethos-u string in the custom codes."""
- return any(
- custom_code_name.decode("utf-8") == "ethos-u"
- for custom_code_name in custom_codes
- )
-
-
-def check_model(tflite_file_name: str) -> None:
- """Raise an exception if model in given file is Vela optimised."""
- tflite_path = Path(tflite_file_name)
-
- tflite_model = get_model_from_file(tflite_path)
-
- if is_vela_optimised(tflite_model):
- raise ModelOptimisedException(
- f"TFLite model in {tflite_file_name} is already "
- f"vela optimised ('ethos-u' custom op detected)."
- )
-
- print(
- f"TFLite model in {tflite_file_name} is not vela optimised "
- f"('ethos-u' custom op not detected)."
- )
diff --git a/src/aiet/resources/tools/vela/run_vela.py b/src/aiet/resources/tools/vela/run_vela.py
deleted file mode 100644
index 2c1b0be..0000000
--- a/src/aiet/resources/tools/vela/run_vela.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Wrapper to only run Vela when the input is not already optimised."""
-import shutil
-import subprocess
-from pathlib import Path
-from typing import Tuple
-
-import click
-
-from aiet.cli.common import ModelOptimisedException
-from aiet.resources.tools.vela.check_model import check_model
-
-
-def vela_output_model_path(input_model: str, output_dir: str) -> Path:
- """Construct the path to the Vela output file."""
- in_path = Path(input_model)
- tflite_vela = Path(output_dir) / f"{in_path.stem}_vela{in_path.suffix}"
- return tflite_vela
-
-
-def execute_vela(vela_args: Tuple, output_dir: Path, input_model: str) -> None:
- """Execute vela as external call."""
- cmd = ["vela"] + list(vela_args)
- cmd += ["--output-dir", str(output_dir)] # Re-add parsed out_dir to arguments
- cmd += [input_model]
- subprocess.run(cmd, check=True)
-
-
-@click.command(context_settings=dict(ignore_unknown_options=True))
-@click.option(
- "--input-model",
- "-i",
- type=click.Path(exists=True, file_okay=True, readable=True),
- required=True,
-)
-@click.option("--output-model", "-o", type=click.Path(), required=True)
-# Collect the remaining arguments to be directly forwarded to Vela
-@click.argument("vela-args", nargs=-1, type=click.UNPROCESSED)
-def run_vela(input_model: str, output_model: str, vela_args: Tuple) -> None:
- """Check input, run Vela (if needed) and copy optimised file to destination."""
- output_dir = Path(output_model).parent
- try:
- check_model(input_model) # raises an exception if already Vela-optimised
- execute_vela(vela_args, output_dir, input_model)
- print("Vela optimisation complete.")
- src_model = vela_output_model_path(input_model, str(output_dir))
- except ModelOptimisedException as ex:
- # Input already optimized: copy input file to destination path and return
- print(f"Input already vela-optimised.\n{ex}")
- src_model = Path(input_model)
- except subprocess.CalledProcessError as ex:
- print(ex)
- raise SystemExit(ex.returncode) from ex
-
- try:
- shutil.copyfile(src_model, output_model)
- except (shutil.SameFileError, OSError) as ex:
- print(ex)
- raise SystemExit(ex.errno) from ex
-
-
-def main() -> None:
- """Entry point of check_model application."""
- run_vela() # pylint: disable=no-value-for-parameter
diff --git a/src/aiet/resources/tools/vela/vela.ini b/src/aiet/resources/tools/vela/vela.ini
deleted file mode 100644
index 5996553..0000000
--- a/src/aiet/resources/tools/vela/vela.ini
+++ /dev/null
@@ -1,53 +0,0 @@
-; SPDX-FileCopyrightText: Copyright 2021-2022, Arm Limited and/or its affiliates.
-; SPDX-License-Identifier: Apache-2.0
-
-; -----------------------------------------------------------------------------
-; Vela configuration file
-
-; -----------------------------------------------------------------------------
-; System Configuration
-
-; Ethos-U55 High-End Embedded: SRAM (4 GB/s) and Flash (0.5 GB/s)
-[System_Config.Ethos_U55_High_End_Embedded]
-core_clock=500e6
-axi0_port=Sram
-axi1_port=OffChipFlash
-Sram_clock_scale=1.0
-Sram_burst_length=32
-Sram_read_latency=32
-Sram_write_latency=32
-OffChipFlash_clock_scale=0.125
-OffChipFlash_burst_length=128
-OffChipFlash_read_latency=64
-OffChipFlash_write_latency=64
-
-; Ethos-U65 High-End: SRAM (16 GB/s) and DRAM (3.75 GB/s)
-[System_Config.Ethos_U65_High_End]
-core_clock=1e9
-axi0_port=Sram
-axi1_port=Dram
-Sram_clock_scale=1.0
-Sram_burst_length=32
-Sram_read_latency=32
-Sram_write_latency=32
-Dram_clock_scale=0.234375
-Dram_burst_length=128
-Dram_read_latency=500
-Dram_write_latency=250
-
-; -----------------------------------------------------------------------------
-; Memory Mode
-
-; Shared SRAM: the SRAM is shared between the Ethos-U and the Cortex-M software
-; The non-SRAM memory is assumed to be read-only
-[Memory_Mode.U55_Shared_Sram]
-const_mem_area=Axi1
-arena_mem_area=Axi0
-cache_mem_area=Axi0
-arena_cache_size=4194304
-
-[Memory_Mode.U65_Shared_Sram]
-const_mem_area=Axi1
-arena_mem_area=Axi0
-cache_mem_area=Axi0
-arena_cache_size=2097152
diff --git a/src/aiet/utils/__init__.py b/src/aiet/utils/__init__.py
deleted file mode 100644
index fc7ef7c..0000000
--- a/src/aiet/utils/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""This module contains all utils shared across aiet project."""
diff --git a/src/aiet/utils/helpers.py b/src/aiet/utils/helpers.py
deleted file mode 100644
index 6d3cd22..0000000
--- a/src/aiet/utils/helpers.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
-# SPDX-License-Identifier: Apache-2.0
-"""Helpers functions."""
-import logging
-from typing import Any
-
-
-def set_verbosity(
- ctx: Any, option: Any, verbosity: Any # pylint: disable=unused-argument
-) -> None:
- """Set the logging level according to the verbosity."""
- # Unused arguments must be present here in definition as these are required in
- # function definition when set as a callback
- if verbosity == 1:
- logging.getLogger().setLevel(logging.INFO)
- elif verbosity > 1:
- logging.getLogger().setLevel(logging.DEBUG)
diff --git a/src/aiet/backend/__init__.py b/src/mlia/backend/__init__.py
index 3d60372..3d60372 100644
--- a/src/aiet/backend/__init__.py
+++ b/src/mlia/backend/__init__.py
diff --git a/src/aiet/backend/application.py b/src/mlia/backend/application.py
index f6ef815..eb85212 100644
--- a/src/aiet/backend/application.py
+++ b/src/mlia/backend/application.py
@@ -9,19 +9,19 @@ from typing import Dict
from typing import List
from typing import Optional
-from aiet.backend.common import Backend
-from aiet.backend.common import ConfigurationException
-from aiet.backend.common import DataPaths
-from aiet.backend.common import get_backend_configs
-from aiet.backend.common import get_backend_directories
-from aiet.backend.common import load_application_or_tool_configs
-from aiet.backend.common import load_config
-from aiet.backend.common import remove_backend
-from aiet.backend.config import ApplicationConfig
-from aiet.backend.config import ExtendedApplicationConfig
-from aiet.backend.source import create_destination_and_install
-from aiet.backend.source import get_source
-from aiet.utils.fs import get_resources
+from mlia.backend.common import Backend
+from mlia.backend.common import ConfigurationException
+from mlia.backend.common import DataPaths
+from mlia.backend.common import get_backend_configs
+from mlia.backend.common import get_backend_directories
+from mlia.backend.common import load_application_or_tool_configs
+from mlia.backend.common import load_config
+from mlia.backend.common import remove_backend
+from mlia.backend.config import ApplicationConfig
+from mlia.backend.config import ExtendedApplicationConfig
+from mlia.backend.fs import get_backends_path
+from mlia.backend.source import create_destination_and_install
+from mlia.backend.source import get_source
def get_available_application_directory_names() -> List[str]:
@@ -78,7 +78,7 @@ def install_application(source_path: Path) -> None:
"Applications [{}] are already installed".format(",".join(names))
)
- create_destination_and_install(source, get_resources("applications"))
+ create_destination_and_install(source, get_backends_path("applications"))
def remove_application(directory_name: str) -> None:
diff --git a/src/aiet/backend/common.py b/src/mlia/backend/common.py
index b887ee7..2bbb9d3 100644
--- a/src/aiet/backend/common.py
+++ b/src/mlia/backend/common.py
@@ -23,17 +23,17 @@ from typing import Tuple
from typing import Type
from typing import Union
-from aiet.backend.config import BackendConfig
-from aiet.backend.config import BaseBackendConfig
-from aiet.backend.config import NamedExecutionConfig
-from aiet.backend.config import UserParamConfig
-from aiet.backend.config import UserParamsConfig
-from aiet.utils.fs import get_resources
-from aiet.utils.fs import remove_resource
-from aiet.utils.fs import ResourceType
+from mlia.backend.config import BackendConfig
+from mlia.backend.config import BaseBackendConfig
+from mlia.backend.config import NamedExecutionConfig
+from mlia.backend.config import UserParamConfig
+from mlia.backend.config import UserParamsConfig
+from mlia.backend.fs import get_backends_path
+from mlia.backend.fs import remove_resource
+from mlia.backend.fs import ResourceType
-AIET_CONFIG_FILE: Final[str] = "aiet-config.json"
+BACKEND_CONFIG_FILE: Final[str] = "aiet-config.json"
class ConfigurationException(Exception):
@@ -42,7 +42,7 @@ class ConfigurationException(Exception):
def get_backend_config(dir_path: Path) -> Path:
"""Get path to backendir configuration file."""
- return dir_path / AIET_CONFIG_FILE
+ return dir_path / BACKEND_CONFIG_FILE
def get_backend_configs(resource_type: ResourceType) -> Iterable[Path]:
@@ -56,7 +56,7 @@ def get_backend_directories(resource_type: ResourceType) -> Iterable[Path]:
"""Get path to the backend directories for provided resource_type."""
return (
entry
- for entry in get_resources(resource_type).iterdir()
+ for entry in get_backends_path(resource_type).iterdir()
if is_backend_directory(entry)
)
diff --git a/src/aiet/backend/config.py b/src/mlia/backend/config.py
index dd42012..657adef 100644
--- a/src/aiet/backend/config.py
+++ b/src/mlia/backend/config.py
@@ -89,19 +89,5 @@ class SystemConfig(BaseBackendConfig, total=False):
reporting: Dict[str, Dict]
-class ToolConfig(BaseBackendConfig, total=False):
- """Tool configuration."""
-
- supported_systems: List[str]
-
-
-class ExtendedToolConfig(BaseBackendConfig, total=False):
- """Extended tool configuration."""
-
- supported_systems: List[NamedExecutionConfig]
-
-
-BackendItemConfig = Union[ApplicationConfig, SystemConfig, ToolConfig]
-BackendConfig = Union[
- List[ExtendedApplicationConfig], List[SystemConfig], List[ToolConfig]
-]
+BackendItemConfig = Union[ApplicationConfig, SystemConfig]
+BackendConfig = Union[List[ExtendedApplicationConfig], List[SystemConfig]]
diff --git a/src/aiet/backend/controller.py b/src/mlia/backend/controller.py
index 2650902..f1b68a9 100644
--- a/src/aiet/backend/controller.py
+++ b/src/mlia/backend/controller.py
@@ -10,14 +10,14 @@ from typing import Tuple
import psutil
import sh
-from aiet.backend.common import ConfigurationException
-from aiet.utils.fs import read_file_as_string
-from aiet.utils.proc import execute_command
-from aiet.utils.proc import get_stdout_stderr_paths
-from aiet.utils.proc import read_process_info
-from aiet.utils.proc import save_process_info
-from aiet.utils.proc import terminate_command
-from aiet.utils.proc import terminate_external_process
+from mlia.backend.common import ConfigurationException
+from mlia.backend.fs import read_file_as_string
+from mlia.backend.proc import execute_command
+from mlia.backend.proc import get_stdout_stderr_paths
+from mlia.backend.proc import read_process_info
+from mlia.backend.proc import save_process_info
+from mlia.backend.proc import terminate_command
+from mlia.backend.proc import terminate_external_process
class SystemController:
diff --git a/src/aiet/backend/execution.py b/src/mlia/backend/execution.py
index 1653ee2..749ccdb 100644
--- a/src/aiet/backend/execution.py
+++ b/src/mlia/backend/execution.py
@@ -8,7 +8,6 @@ import re
import string
import sys
import time
-import warnings
from collections import defaultdict
from contextlib import contextmanager
from contextlib import ExitStack
@@ -24,32 +23,29 @@ from typing import Optional
from typing import Sequence
from typing import Tuple
from typing import TypedDict
-from typing import Union
from filelock import FileLock
from filelock import Timeout
-from aiet.backend.application import Application
-from aiet.backend.application import get_application
-from aiet.backend.common import Backend
-from aiet.backend.common import ConfigurationException
-from aiet.backend.common import DataPaths
-from aiet.backend.common import Param
-from aiet.backend.common import parse_raw_parameter
-from aiet.backend.common import resolve_all_parameters
-from aiet.backend.output_parser import Base64OutputParser
-from aiet.backend.output_parser import OutputParser
-from aiet.backend.output_parser import RegexOutputParser
-from aiet.backend.system import ControlledSystem
-from aiet.backend.system import get_system
-from aiet.backend.system import StandaloneSystem
-from aiet.backend.system import System
-from aiet.backend.tool import get_tool
-from aiet.backend.tool import Tool
-from aiet.utils.fs import recreate_directory
-from aiet.utils.fs import remove_directory
-from aiet.utils.fs import valid_for_filename
-from aiet.utils.proc import run_and_wait
+from mlia.backend.application import Application
+from mlia.backend.application import get_application
+from mlia.backend.common import Backend
+from mlia.backend.common import ConfigurationException
+from mlia.backend.common import DataPaths
+from mlia.backend.common import Param
+from mlia.backend.common import parse_raw_parameter
+from mlia.backend.common import resolve_all_parameters
+from mlia.backend.fs import recreate_directory
+from mlia.backend.fs import remove_directory
+from mlia.backend.fs import valid_for_filename
+from mlia.backend.output_parser import Base64OutputParser
+from mlia.backend.output_parser import OutputParser
+from mlia.backend.output_parser import RegexOutputParser
+from mlia.backend.proc import run_and_wait
+from mlia.backend.system import ControlledSystem
+from mlia.backend.system import get_system
+from mlia.backend.system import StandaloneSystem
+from mlia.backend.system import System
class AnotherInstanceIsRunningException(Exception):
@@ -73,7 +69,7 @@ class ExecutionContext:
# pylint: disable=too-many-arguments,too-many-instance-attributes
def __init__(
self,
- app: Union[Application, Tool],
+ app: Application,
app_params: List[str],
system: Optional[System],
system_params: List[str],
@@ -106,14 +102,13 @@ class ExecutionContext:
self.param_resolver = ParamResolver(self)
self._resolved_build_dir: Optional[Path] = None
+ self.stdout: Optional[bytearray] = None
+ self.stderr: Optional[bytearray] = None
+
@property
def is_deploy_needed(self) -> bool:
"""Check if application requires data deployment."""
- if isinstance(self.app, Application):
- return (
- len(self.app.get_deploy_data()) > 0 or len(self.custom_deploy_data) > 0
- )
- return False
+ return len(self.app.get_deploy_data()) > 0 or len(self.custom_deploy_data) > 0
@property
def is_locking_required(self) -> bool:
@@ -533,45 +528,6 @@ def get_application_and_system(
return application, system
-def execute_application_command( # pylint: disable=too-many-arguments
- command_name: str,
- application_name: str,
- application_params: List[str],
- system_name: str,
- system_params: List[str],
- custom_deploy_data: List[DataPaths],
-) -> None:
- """Execute application command.
-
- .. deprecated:: 21.12
- """
- warnings.warn(
- "Use 'run_application()' instead. Use of 'execute_application_command()' is "
- "deprecated and might be removed in a future release.",
- DeprecationWarning,
- )
-
- if command_name not in ["build", "run"]:
- raise ConfigurationException("Unsupported command {}".format(command_name))
-
- application, system = get_application_and_system(application_name, system_name)
- validate_parameters(application, [command_name], application_params)
- validate_parameters(system, [command_name], system_params)
-
- ctx = ExecutionContext(
- app=application,
- app_params=application_params,
- system=system,
- system_params=system_params,
- custom_deploy_data=custom_deploy_data,
- )
-
- if command_name == "run":
- execute_application_command_run(ctx)
- else:
- execute_application_command_build(ctx)
-
-
# pylint: disable=too-many-arguments
def run_application(
application_name: str,
@@ -580,7 +536,7 @@ def run_application(
system_params: List[str],
custom_deploy_data: List[DataPaths],
report_file: Optional[Path] = None,
-) -> None:
+) -> ExecutionContext:
"""Run application on the provided system."""
application, system = get_application_and_system(application_name, system_name)
validate_parameters(application, ["build", "run"], application_params)
@@ -607,6 +563,8 @@ def run_application(
execute_application_command_run(ctx)
+ return ctx
+
def execute_application_command_build(ctx: ExecutionContext) -> None:
"""Execute application command 'build'."""
@@ -655,17 +613,14 @@ def execute_application_command_run(ctx: ExecutionContext) -> None:
for command in commands_to_run:
print("Running: {}".format(command))
- exit_code, std_output, std_err = ctx.system.run(command)
+ exit_code, ctx.stdout, ctx.stderr = ctx.system.run(command)
if exit_code != 0:
print("Application exited with exit code {}".format(exit_code))
if ctx.reporter:
- ctx.reporter.parse(std_output)
- std_output = ctx.reporter.get_filtered_output(std_output)
-
- print(std_output.decode("utf8"), end="")
- print(std_err.decode("utf8"), end="")
+ ctx.reporter.parse(ctx.stdout)
+ ctx.stdout = ctx.reporter.get_filtered_output(ctx.stdout)
if ctx.reporter:
report = ctx.reporter.report(ctx)
@@ -717,12 +672,10 @@ def wait(interval: float) -> None:
def deploy_data(ctx: ExecutionContext) -> None:
"""Deploy data to the system."""
- if isinstance(ctx.app, Application):
- # Only application can deploy data (tools can not)
- assert ctx.system is not None, "System is required."
- for item in itertools.chain(ctx.app.get_deploy_data(), ctx.custom_deploy_data):
- print("Deploying {} onto {}".format(item.src, item.dst))
- ctx.system.deploy(item.src, item.dst)
+ assert ctx.system is not None, "System is required."
+ for item in itertools.chain(ctx.app.get_deploy_data(), ctx.custom_deploy_data):
+ print("Deploying {} onto {}".format(item.src, item.dst))
+ ctx.system.deploy(item.src, item.dst)
def build_run_commands(ctx: ExecutionContext) -> List[str]:
@@ -824,36 +777,3 @@ def get_context_managers(
managers.append(controlled_system_manager)
return managers
-
-
-def get_tool_by_system(tool_name: str, system_name: Optional[str]) -> Tool:
- """Return tool (optionally by provided system name."""
- tools = get_tool(tool_name, system_name)
- if not tools:
- raise ConfigurationException(
- "Tool '{}' not found or doesn't support the system '{}'".format(
- tool_name, system_name
- )
- )
- if len(tools) != 1:
- raise ConfigurationException(
- "Please specify the system for tool {}.".format(tool_name)
- )
- tool = tools[0]
-
- return tool
-
-
-def execute_tool_command(
- tool_name: str,
- tool_params: List[str],
- system_name: Optional[str] = None,
-) -> None:
- """Execute the tool command locally calling the 'run' command."""
- tool = get_tool_by_system(tool_name, system_name)
- ctx = ExecutionContext(
- app=tool, app_params=tool_params, system=None, system_params=[]
- )
- commands = tool.build_command("run", tool_params, ctx.param_resolver)
-
- execute_commands_locally(commands, Path.cwd())
diff --git a/src/aiet/utils/fs.py b/src/mlia/backend/fs.py
index ea99a69..9979fcb 100644
--- a/src/aiet/utils/fs.py
+++ b/src/mlia/backend/fs.py
@@ -1,7 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
# SPDX-License-Identifier: Apache-2.0
"""Module to host all file system related functions."""
-import importlib.resources as pkg_resources
import re
import shutil
from pathlib import Path
@@ -9,17 +8,17 @@ from typing import Any
from typing import Literal
from typing import Optional
-ResourceType = Literal["applications", "systems", "tools"]
+from mlia.utils.filesystem import get_mlia_resources
+ResourceType = Literal["applications", "systems"]
-def get_aiet_resources() -> Path:
- """Get resources folder path."""
- with pkg_resources.path("aiet", "__init__.py") as init_path:
- project_root = init_path.parent
- return project_root / "resources"
+def get_backend_resources() -> Path:
+ """Get backend resources folder path."""
+ return get_mlia_resources() / "backends"
-def get_resources(name: ResourceType) -> Path:
+
+def get_backends_path(name: ResourceType) -> Path:
"""Return the absolute path of the specified resource.
It uses importlib to return resources packaged with MANIFEST.in.
@@ -27,7 +26,7 @@ def get_resources(name: ResourceType) -> Path:
if not name:
raise ResourceWarning("Resource name is not provided")
- resource_path = get_aiet_resources() / name
+ resource_path = get_backend_resources() / name
if resource_path.is_dir():
return resource_path
@@ -48,7 +47,7 @@ def copy_directory_content(source: Path, destination: Path) -> None:
def remove_resource(resource_directory: str, resource_type: ResourceType) -> None:
"""Remove resource data."""
- resources = get_resources(resource_type)
+ resources = get_backends_path(resource_type)
resource_location = resources / resource_directory
if not resource_location.exists():
diff --git a/src/mlia/tools/aiet_wrapper.py b/src/mlia/backend/manager.py
index 73e82ee..3a1016c 100644
--- a/src/mlia/tools/aiet_wrapper.py
+++ b/src/mlia/backend/manager.py
@@ -1,6 +1,6 @@
# SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
# SPDX-License-Identifier: Apache-2.0
-"""Module for AIET integration."""
+"""Module for backend integration."""
import logging
import re
from abc import ABC
@@ -14,11 +14,13 @@ from typing import Literal
from typing import Optional
from typing import Tuple
-from aiet.backend.application import get_available_applications
-from aiet.backend.application import install_application
-from aiet.backend.system import get_available_systems
-from aiet.backend.system import install_system
-from mlia.utils.proc import CommandExecutor
+from mlia.backend.application import get_available_applications
+from mlia.backend.application import install_application
+from mlia.backend.common import DataPaths
+from mlia.backend.execution import ExecutionContext
+from mlia.backend.execution import run_application
+from mlia.backend.system import get_available_systems
+from mlia.backend.system import install_system
from mlia.utils.proc import OutputConsumer
from mlia.utils.proc import RunningCommand
@@ -54,7 +56,7 @@ _SYSTEM_TO_APP_MAP = {
def get_system_name(backend: str, device_type: str) -> str:
- """Get the AIET system name for the given backend and device type."""
+ """Get the system name for the given backend and device type."""
return _SUPPORTED_SYSTEMS[backend][device_type]
@@ -71,7 +73,7 @@ def is_supported(backend: str, device_type: Optional[str] = None) -> bool:
def supported_backends() -> List[str]:
- """Get a list of all backends supported by the AIET wrapper."""
+ """Get a list of all backends supported by the backend manager."""
return list(_SUPPORTED_SYSTEMS.keys())
@@ -129,8 +131,8 @@ class ExecutionParams:
deploy_params: List[str]
-class AIETLogWriter(OutputConsumer):
- """Redirect AIET command output to the logger."""
+class LogWriter(OutputConsumer):
+ """Redirect output to the logger."""
def feed(self, line: str) -> None:
"""Process line from the output."""
@@ -211,12 +213,11 @@ class GenericInferenceOutputParser(OutputConsumer):
return sorted(self.PATTERNS.keys() - self.result.keys())
-class AIETRunner:
- """AIET runner."""
+class BackendRunner:
+ """Backend runner."""
- def __init__(self, executor: CommandExecutor) -> None:
- """Init AIET runner instance."""
- self.executor = executor
+ def __init__(self) -> None:
+ """Init BackendRunner instance."""
@staticmethod
def get_installed_systems() -> List[str]:
@@ -270,39 +271,40 @@ class AIETRunner:
"""Install application."""
install_application(app_path)
- def run_application(self, execution_params: ExecutionParams) -> RunningCommand:
+ @staticmethod
+ def run_application(execution_params: ExecutionParams) -> ExecutionContext:
"""Run requested application."""
- command = [
- "aiet",
- "application",
- "run",
- "-n",
+
+ def to_data_paths(paths: str) -> DataPaths:
+ """Split input into two and create new DataPaths object."""
+ src, dst = paths.split(sep=":", maxsplit=1)
+ return DataPaths(Path(src), dst)
+
+ deploy_data_paths = [
+ to_data_paths(paths) for paths in execution_params.deploy_params
+ ]
+
+ ctx = run_application(
execution_params.application,
- "-s",
+ execution_params.application_params,
execution_params.system,
- *self._params("-p", execution_params.application_params),
- *self._params("--system-param", execution_params.system_params),
- *self._params("--deploy", execution_params.deploy_params),
- ]
+ execution_params.system_params,
+ deploy_data_paths,
+ )
- return self._submit(command)
+ return ctx
@staticmethod
def _params(name: str, params: List[str]) -> List[str]:
return [p for item in [(name, param) for param in params] for p in item]
- def _submit(self, command: List[str]) -> RunningCommand:
- """Submit command for the execution."""
- logger.debug("Submit command %s", " ".join(command))
- return self.executor.submit(command)
-
class GenericInferenceRunner(ABC):
"""Abstract class for generic inference runner."""
- def __init__(self, aiet_runner: AIETRunner):
+ def __init__(self, backend_runner: BackendRunner):
"""Init generic inference runner instance."""
- self.aiet_runner = aiet_runner
+ self.backend_runner = backend_runner
self.running_inference: Optional[RunningCommand] = None
def run(
@@ -311,9 +313,9 @@ class GenericInferenceRunner(ABC):
"""Run generic inference for the provided device/model."""
execution_params = self.get_execution_params(model_info)
- self.running_inference = self.aiet_runner.run_application(execution_params)
- self.running_inference.output_consumers = output_consumers
- self.running_inference.consume_output()
+ ctx = self.backend_runner.run_application(execution_params)
+ if ctx.stdout is not None:
+ self.consume_output(ctx.stdout, output_consumers)
def stop(self) -> None:
"""Stop running inference."""
@@ -336,24 +338,31 @@ class GenericInferenceRunner(ABC):
def check_system_and_application(self, system_name: str, app_name: str) -> None:
"""Check if requested system and application installed."""
- if not self.aiet_runner.is_system_installed(system_name):
+ if not self.backend_runner.is_system_installed(system_name):
raise Exception(f"System {system_name} is not installed")
- if not self.aiet_runner.is_application_installed(app_name, system_name):
+ if not self.backend_runner.is_application_installed(app_name, system_name):
raise Exception(
f"Application {app_name} for the system {system_name} "
"is not installed"
)
+ @staticmethod
+ def consume_output(output: bytearray, consumers: List[OutputConsumer]) -> None:
+ """Pass program's output to the consumers."""
+ for line in output.decode("utf8").splitlines():
+ for consumer in consumers:
+ consumer.feed(line)
+
class GenericInferenceRunnerEthosU(GenericInferenceRunner):
"""Generic inference runner on U55/65."""
def __init__(
- self, aiet_runner: AIETRunner, device_info: DeviceInfo, backend: str
+ self, backend_runner: BackendRunner, device_info: DeviceInfo, backend: str
) -> None:
"""Init generic inference runner instance."""
- super().__init__(aiet_runner)
+ super().__init__(backend_runner)
system_name, app_name = self.resolve_system_and_app(device_info, backend)
self.system_name = system_name
@@ -405,8 +414,8 @@ class GenericInferenceRunnerEthosU(GenericInferenceRunner):
def get_generic_runner(device_info: DeviceInfo, backend: str) -> GenericInferenceRunner:
"""Get generic runner for provided device and backend."""
- aiet_runner = get_aiet_runner()
- return GenericInferenceRunnerEthosU(aiet_runner, device_info, backend)
+ backend_runner = get_backend_runner()
+ return GenericInferenceRunnerEthosU(backend_runner, device_info, backend)
def estimate_performance(
@@ -415,7 +424,7 @@ def estimate_performance(
"""Get performance estimations."""
with get_generic_runner(device_info, backend) as generic_runner:
output_parser = GenericInferenceOutputParser()
- output_consumers = [output_parser, AIETLogWriter()]
+ output_consumers = [output_parser, LogWriter()]
generic_runner.run(model_info, output_consumers)
@@ -429,7 +438,10 @@ def estimate_performance(
return PerformanceMetrics(**output_parser.result)
-def get_aiet_runner() -> AIETRunner:
- """Return AIET runner."""
- executor = CommandExecutor()
- return AIETRunner(executor)
+def get_backend_runner() -> BackendRunner:
+ """
+ Return BackendRunner instance.
+
+ Note: This is needed for the unit tests.
+ """
+ return BackendRunner()
diff --git a/src/aiet/backend/output_parser.py b/src/mlia/backend/output_parser.py
index 111772a..111772a 100644
--- a/src/aiet/backend/output_parser.py
+++ b/src/mlia/backend/output_parser.py
diff --git a/src/aiet/utils/proc.py b/src/mlia/backend/proc.py
index b6f4357..90ff414 100644
--- a/src/aiet/utils/proc.py
+++ b/src/mlia/backend/proc.py
@@ -24,7 +24,7 @@ from sh import CommandNotFound
from sh import ErrorReturnCode
from sh import RunningCommand
-from aiet.utils.fs import valid_for_filename
+from mlia.backend.fs import valid_for_filename
class CommandFailedException(Exception):
diff --git a/src/aiet/backend/protocol.py b/src/mlia/backend/protocol.py
index c621436..ebfe69a 100644
--- a/src/aiet/backend/protocol.py
+++ b/src/mlia/backend/protocol.py
@@ -14,10 +14,10 @@ from typing import Union
import paramiko
-from aiet.backend.common import ConfigurationException
-from aiet.backend.config import LocalProtocolConfig
-from aiet.backend.config import SSHConfig
-from aiet.utils.proc import run_and_wait
+from mlia.backend.common import ConfigurationException
+from mlia.backend.config import LocalProtocolConfig
+from mlia.backend.config import SSHConfig
+from mlia.backend.proc import run_and_wait
# Redirect all paramiko thread exceptions to a file otherwise these will be
diff --git a/src/aiet/backend/source.py b/src/mlia/backend/source.py
index dec175a..dcf6835 100644
--- a/src/aiet/backend/source.py
+++ b/src/mlia/backend/source.py
@@ -11,13 +11,13 @@ from tarfile import TarFile
from typing import Optional
from typing import Union
-from aiet.backend.common import AIET_CONFIG_FILE
-from aiet.backend.common import ConfigurationException
-from aiet.backend.common import get_backend_config
-from aiet.backend.common import is_backend_directory
-from aiet.backend.common import load_config
-from aiet.backend.config import BackendConfig
-from aiet.utils.fs import copy_directory_content
+from mlia.backend.common import BACKEND_CONFIG_FILE
+from mlia.backend.common import ConfigurationException
+from mlia.backend.common import get_backend_config
+from mlia.backend.common import is_backend_directory
+from mlia.backend.common import load_config
+from mlia.backend.config import BackendConfig
+from mlia.backend.fs import copy_directory_content
class Source(ABC):
@@ -99,7 +99,7 @@ class TarArchiveSource(Source):
with self._open(self.archive_path) as archive:
try:
- config_entry = archive.getmember(AIET_CONFIG_FILE)
+ config_entry = archive.getmember(BACKEND_CONFIG_FILE)
self._has_top_level_folder = False
except KeyError as error_no_config:
try:
@@ -112,7 +112,7 @@ class TarArchiveSource(Source):
"Archive has no top level directory"
) from error_no_config
- config_path = "{}/{}".format(top_level_dir, AIET_CONFIG_FILE)
+ config_path = "{}/{}".format(top_level_dir, BACKEND_CONFIG_FILE)
config_entry = archive.getmember(config_path)
self._has_top_level_folder = True
diff --git a/src/aiet/backend/system.py b/src/mlia/backend/system.py
index 48f1bb1..469083e 100644
--- a/src/aiet/backend/system.py
+++ b/src/mlia/backend/system.py
@@ -10,22 +10,22 @@ from typing import Optional
from typing import Tuple
from typing import Union
-from aiet.backend.common import Backend
-from aiet.backend.common import ConfigurationException
-from aiet.backend.common import get_backend_configs
-from aiet.backend.common import get_backend_directories
-from aiet.backend.common import load_config
-from aiet.backend.common import remove_backend
-from aiet.backend.config import SystemConfig
-from aiet.backend.controller import SystemController
-from aiet.backend.controller import SystemControllerSingleInstance
-from aiet.backend.protocol import ProtocolFactory
-from aiet.backend.protocol import SupportsClose
-from aiet.backend.protocol import SupportsConnection
-from aiet.backend.protocol import SupportsDeploy
-from aiet.backend.source import create_destination_and_install
-from aiet.backend.source import get_source
-from aiet.utils.fs import get_resources
+from mlia.backend.common import Backend
+from mlia.backend.common import ConfigurationException
+from mlia.backend.common import get_backend_configs
+from mlia.backend.common import get_backend_directories
+from mlia.backend.common import load_config
+from mlia.backend.common import remove_backend
+from mlia.backend.config import SystemConfig
+from mlia.backend.controller import SystemController
+from mlia.backend.controller import SystemControllerSingleInstance
+from mlia.backend.fs import get_backends_path
+from mlia.backend.protocol import ProtocolFactory
+from mlia.backend.protocol import SupportsClose
+from mlia.backend.protocol import SupportsConnection
+from mlia.backend.protocol import SupportsDeploy
+from mlia.backend.source import create_destination_and_install
+from mlia.backend.source import get_source
def get_available_systems_directory_names() -> List[str]:
@@ -75,7 +75,7 @@ def install_system(source_path: Path) -> None:
"Systems [{}] are already installed".format(",".join(names))
)
- create_destination_and_install(source, get_resources("systems"))
+ create_destination_and_install(source, get_backends_path("systems"))
def remove_system(directory_name: str) -> None:
diff --git a/src/mlia/cli/config.py b/src/mlia/cli/config.py
index 838b051..a673230 100644
--- a/src/mlia/cli/config.py
+++ b/src/mlia/cli/config.py
@@ -5,7 +5,7 @@ import logging
from functools import lru_cache
from typing import List
-import mlia.tools.aiet_wrapper as aiet
+import mlia.backend.manager as backend_manager
from mlia.tools.metadata.common import DefaultInstallationManager
from mlia.tools.metadata.common import InstallationManager
from mlia.tools.metadata.corstone import get_corstone_installations
@@ -25,12 +25,12 @@ def get_available_backends() -> List[str]:
"""Return list of the available backends."""
available_backends = ["Vela"]
- # Add backends using AIET
+ # Add backends using backend manager
manager = get_installation_manager()
available_backends.extend(
(
backend
- for backend in aiet.supported_backends()
+ for backend in backend_manager.supported_backends()
if manager.backend_installed(backend)
)
)
diff --git a/src/mlia/devices/ethosu/performance.py b/src/mlia/devices/ethosu/performance.py
index b0718a5..a73045a 100644
--- a/src/mlia/devices/ethosu/performance.py
+++ b/src/mlia/devices/ethosu/performance.py
@@ -10,7 +10,7 @@ from typing import Optional
from typing import Tuple
from typing import Union
-import mlia.tools.aiet_wrapper as aiet
+import mlia.backend.manager as backend_manager
import mlia.tools.vela_wrapper as vela
from mlia.core.context import Context
from mlia.core.performance import PerformanceEstimator
@@ -147,15 +147,15 @@ class VelaPerformanceEstimator(
return memory_usage
-class AIETPerformanceEstimator(
+class CorstonePerformanceEstimator(
PerformanceEstimator[Union[Path, ModelConfiguration], NPUCycles]
):
- """AIET based performance estimator."""
+ """Corstone-based performance estimator."""
def __init__(
self, context: Context, device: EthosUConfiguration, backend: str
) -> None:
- """Init AIET based performance estimator."""
+ """Init Corstone-based performance estimator."""
self.context = context
self.device = device
self.backend = backend
@@ -179,24 +179,24 @@ class AIETPerformanceEstimator(
model_path, self.device.compiler_options, optimized_model_path
)
- model_info = aiet.ModelInfo(model_path=optimized_model_path)
- device_info = aiet.DeviceInfo(
+ model_info = backend_manager.ModelInfo(model_path=optimized_model_path)
+ device_info = backend_manager.DeviceInfo(
device_type=self.device.target, # type: ignore
mac=self.device.mac,
memory_mode=self.device.compiler_options.memory_mode, # type: ignore
)
- aiet_perf_metrics = aiet.estimate_performance(
+ corstone_perf_metrics = backend_manager.estimate_performance(
model_info, device_info, self.backend
)
npu_cycles = NPUCycles(
- aiet_perf_metrics.npu_active_cycles,
- aiet_perf_metrics.npu_idle_cycles,
- aiet_perf_metrics.npu_total_cycles,
- aiet_perf_metrics.npu_axi0_rd_data_beat_received,
- aiet_perf_metrics.npu_axi0_wr_data_beat_written,
- aiet_perf_metrics.npu_axi1_rd_data_beat_received,
+ corstone_perf_metrics.npu_active_cycles,
+ corstone_perf_metrics.npu_idle_cycles,
+ corstone_perf_metrics.npu_total_cycles,
+ corstone_perf_metrics.npu_axi0_rd_data_beat_received,
+ corstone_perf_metrics.npu_axi0_wr_data_beat_written,
+ corstone_perf_metrics.npu_axi1_rd_data_beat_received,
)
logger.info("Done\n")
@@ -220,10 +220,11 @@ class EthosUPerformanceEstimator(
if backends is None:
backends = ["Vela"] # Only Vela is always available as default
for backend in backends:
- if backend != "Vela" and not aiet.is_supported(backend):
+ if backend != "Vela" and not backend_manager.is_supported(backend):
raise ValueError(
f"Unsupported backend '{backend}'. "
- f"Only 'Vela' and {aiet.supported_backends()} are supported."
+ f"Only 'Vela' and {backend_manager.supported_backends()} "
+ "are supported."
)
self.backends = set(backends)
@@ -242,11 +243,11 @@ class EthosUPerformanceEstimator(
if backend == "Vela":
vela_estimator = VelaPerformanceEstimator(self.context, self.device)
memory_usage = vela_estimator.estimate(tflite_model)
- elif backend in aiet.supported_backends():
- aiet_estimator = AIETPerformanceEstimator(
+ elif backend in backend_manager.supported_backends():
+ corstone_estimator = CorstonePerformanceEstimator(
self.context, self.device, backend
)
- npu_cycles = aiet_estimator.estimate(tflite_model)
+ npu_cycles = corstone_estimator.estimate(tflite_model)
else:
logger.warning(
"Backend '%s' is not supported for Ethos-U performance "
diff --git a/src/mlia/resources/aiet/applications/APPLICATIONS.txt b/src/mlia/resources/aiet/applications/APPLICATIONS.txt
index 09127f8..a702e19 100644
--- a/src/mlia/resources/aiet/applications/APPLICATIONS.txt
+++ b/src/mlia/resources/aiet/applications/APPLICATIONS.txt
@@ -1,6 +1,7 @@
SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
SPDX-License-Identifier: Apache-2.0
-This directory contains the Generic Inference Runner application packages for AIET
+This directory contains the application packages for the Generic Inference
+Runner.
-Each package should contain its own aiet-config.json file
+Each package should contain its own aiet-config.json file.
diff --git a/src/mlia/resources/aiet/systems/SYSTEMS.txt b/src/mlia/resources/aiet/systems/SYSTEMS.txt
index bc27e73..3861769 100644
--- a/src/mlia/resources/aiet/systems/SYSTEMS.txt
+++ b/src/mlia/resources/aiet/systems/SYSTEMS.txt
@@ -1,8 +1,7 @@
SPDX-FileCopyrightText: Copyright 2022, Arm Limited and/or its affiliates.
SPDX-License-Identifier: Apache-2.0
-This directory contains the configuration files of the systems for the AIET
-middleware.
+This directory contains the configuration files of the system backends.
Supported systems:
diff --git a/src/aiet/resources/applications/.gitignore b/src/mlia/resources/backends/applications/.gitignore
index 0226166..0226166 100644
--- a/src/aiet/resources/applications/.gitignore
+++ b/src/mlia/resources/backends/applications/.gitignore
diff --git a/src/aiet/resources/systems/.gitignore b/src/mlia/resources/backends/systems/.gitignore
index 0226166..0226166 100644
--- a/src/aiet/resources/systems/.gitignore
+++ b/src/mlia/resources/backends/systems/.gitignore
diff --git a/src/mlia/tools/metadata/corstone.py b/src/mlia/tools/metadata/corstone.py
index 7a9d113..a92f81c 100644
--- a/src/mlia/tools/metadata/corstone.py
+++ b/src/mlia/tools/metadata/corstone.py
@@ -12,7 +12,8 @@ from typing import Iterable
from typing import List
from typing import Optional
-import mlia.tools.aiet_wrapper as aiet
+import mlia.backend.manager as backend_manager
+from mlia.backend.fs import get_backend_resources
from mlia.tools.metadata.common import DownloadAndInstall
from mlia.tools.metadata.common import Installation
from mlia.tools.metadata.common import InstallationType
@@ -41,8 +42,8 @@ PathChecker = Callable[[Path], Optional[BackendInfo]]
BackendInstaller = Callable[[bool, Path], Path]
-class AIETMetadata:
- """AIET installation metadata."""
+class BackendMetadata:
+ """Backend installation metadata."""
def __init__(
self,
@@ -55,7 +56,7 @@ class AIETMetadata:
supported_platforms: Optional[List[str]] = None,
) -> None:
"""
- Initialize AIETMetaData.
+ Initialize BackendMetadata.
Members expected_systems and expected_apps are filled automatically.
"""
@@ -67,15 +68,15 @@ class AIETMetadata:
self.download_artifact = download_artifact
self.supported_platforms = supported_platforms
- self.expected_systems = aiet.get_all_system_names(name)
- self.expected_apps = aiet.get_all_application_names(name)
+ self.expected_systems = backend_manager.get_all_system_names(name)
+ self.expected_apps = backend_manager.get_all_application_names(name)
@property
def expected_resources(self) -> Iterable[Path]:
"""Return list of expected resources."""
resources = [self.system_config, *self.apps_resources]
- return (get_mlia_resources() / resource for resource in resources)
+ return (get_backend_resources() / resource for resource in resources)
@property
def supported_platform(self) -> bool:
@@ -86,49 +87,49 @@ class AIETMetadata:
return platform.system() in self.supported_platforms
-class AIETBasedInstallation(Installation):
- """Backend installation based on AIET functionality."""
+class BackendInstallation(Installation):
+ """Backend installation."""
def __init__(
self,
- aiet_runner: aiet.AIETRunner,
- metadata: AIETMetadata,
+ backend_runner: backend_manager.BackendRunner,
+ metadata: BackendMetadata,
path_checker: PathChecker,
backend_installer: Optional[BackendInstaller],
) -> None:
- """Init the tool installation."""
- self.aiet_runner = aiet_runner
+ """Init the backend installation."""
+ self.backend_runner = backend_runner
self.metadata = metadata
self.path_checker = path_checker
self.backend_installer = backend_installer
@property
def name(self) -> str:
- """Return name of the tool."""
+ """Return name of the backend."""
return self.metadata.name
@property
def description(self) -> str:
- """Return description of the tool."""
+ """Return description of the backend."""
return self.metadata.description
@property
def already_installed(self) -> bool:
- """Return true if tool already installed."""
- return self.aiet_runner.all_installed(
+ """Return true if backend already installed."""
+ return self.backend_runner.all_installed(
self.metadata.expected_systems, self.metadata.expected_apps
)
@property
def could_be_installed(self) -> bool:
- """Return true if tool could be installed."""
+ """Return true if backend could be installed."""
if not self.metadata.supported_platform:
return False
return all_paths_valid(self.metadata.expected_resources)
def supports(self, install_type: InstallationType) -> bool:
- """Return true if tools supported type of the installation."""
+ """Return true if backends supported type of the installation."""
if isinstance(install_type, DownloadAndInstall):
return self.metadata.download_artifact is not None
@@ -138,7 +139,7 @@ class AIETBasedInstallation(Installation):
return False # type: ignore
def install(self, install_type: InstallationType) -> None:
- """Install the tool."""
+ """Install the backend."""
if isinstance(install_type, DownloadAndInstall):
download_artifact = self.metadata.download_artifact
assert download_artifact is not None, "No artifact provided"
@@ -153,7 +154,7 @@ class AIETBasedInstallation(Installation):
raise Exception(f"Unable to install {install_type}")
def install_from(self, backend_info: BackendInfo) -> None:
- """Install tool from the directory."""
+ """Install backend from the directory."""
mlia_resources = get_mlia_resources()
with temp_directory() as tmpdir:
@@ -169,15 +170,15 @@ class AIETBasedInstallation(Installation):
copy_all(*resources_to_copy, dest=fvp_dist_dir)
- self.aiet_runner.install_system(fvp_dist_dir)
+ self.backend_runner.install_system(fvp_dist_dir)
for app in self.metadata.apps_resources:
- self.aiet_runner.install_application(mlia_resources / app)
+ self.backend_runner.install_application(mlia_resources / app)
def download_and_install(
self, download_artifact: DownloadArtifact, eula_agrement: bool
) -> None:
- """Download and install the tool."""
+ """Download and install the backend."""
with temp_directory() as tmpdir:
try:
downloaded_to = download_artifact.download_to(tmpdir)
@@ -307,10 +308,10 @@ class Corstone300Installer:
def get_corstone_300_installation() -> Installation:
"""Get Corstone-300 installation."""
- corstone_300 = AIETBasedInstallation(
- aiet_runner=aiet.get_aiet_runner(),
+ corstone_300 = BackendInstallation(
+ backend_runner=backend_manager.BackendRunner(),
# pylint: disable=line-too-long
- metadata=AIETMetadata(
+ metadata=BackendMetadata(
name="Corstone-300",
description="Corstone-300 FVP",
system_config="aiet/systems/corstone-300/aiet-config.json",
@@ -356,10 +357,10 @@ def get_corstone_300_installation() -> Installation:
def get_corstone_310_installation() -> Installation:
"""Get Corstone-310 installation."""
- corstone_310 = AIETBasedInstallation(
- aiet_runner=aiet.get_aiet_runner(),
+ corstone_310 = BackendInstallation(
+ backend_runner=backend_manager.BackendRunner(),
# pylint: disable=line-too-long
- metadata=AIETMetadata(
+ metadata=BackendMetadata(
name="Corstone-310",
description="Corstone-310 FVP",
system_config="aiet/systems/corstone-310/aiet-config.json",
diff --git a/src/mlia/utils/proc.py b/src/mlia/utils/proc.py
index 39aca43..18a4305 100644
--- a/src/mlia/utils/proc.py
+++ b/src/mlia/utils/proc.py
@@ -8,7 +8,6 @@ import time
from abc import ABC
from abc import abstractmethod
from contextlib import contextmanager
-from contextlib import suppress
from pathlib import Path
from typing import Any
from typing import Generator
@@ -23,7 +22,7 @@ class OutputConsumer(ABC):
@abstractmethod
def feed(self, line: str) -> None:
- """Feed new line to the consumerr."""
+ """Feed new line to the consumer."""
class RunningCommand:
@@ -32,7 +31,7 @@ class RunningCommand:
def __init__(self, process: subprocess.Popen) -> None:
"""Init running command instance."""
self.process = process
- self._output_consumers: Optional[List[OutputConsumer]] = None
+ self.output_consumers: List[OutputConsumer] = []
def is_alive(self) -> bool:
"""Return true if process is still alive."""
@@ -57,25 +56,14 @@ class RunningCommand:
"""Send signal to the process."""
self.process.send_signal(signal_num)
- @property
- def output_consumers(self) -> Optional[List[OutputConsumer]]:
- """Property output_consumers."""
- return self._output_consumers
-
- @output_consumers.setter
- def output_consumers(self, output_consumers: List[OutputConsumer]) -> None:
- """Set output consumers."""
- self._output_consumers = output_consumers
-
def consume_output(self) -> None:
"""Pass program's output to the consumers."""
- if self.process is None or self.output_consumers is None:
+ if self.process is None or not self.output_consumers:
return
for line in self.stdout():
for consumer in self.output_consumers:
- with suppress():
- consumer.feed(line)
+ consumer.feed(line)
def stop(
self, wait: bool = True, num_of_attempts: int = 5, interval: float = 0.5