Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 106 additions & 21 deletions examples/arm/aot_arm_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import argparse
import logging
import os

import torch

Expand Down Expand Up @@ -48,6 +49,19 @@ def get_model_and_inputs_from_name(model_name: str):
model, example_inputs, _ = EagerModelFactory.create_model(
*MODEL_NAME_TO_MODEL[model_name]
)
# Case 3: Model is in an external python file loaded as a module.
# ModelUnderTest should be a torch.nn.module instance
# ModelInputs should be a tuple of inputs to the forward function
elif model_name.endswith(".py"):
import importlib.util

# load model's module and add it
spec = importlib.util.spec_from_file_location("tmp_model", model_name)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
model = module.ModelUnderTest
example_inputs = module.ModelInputs

else:
raise RuntimeError(
f"Model '{model_name}' is not a valid name. Use --help for a list of available models."
Expand Down Expand Up @@ -133,7 +147,51 @@ def forward(self, x):
"softmax": SoftmaxModule,
}

if __name__ == "__main__":
targets = [
"ethos-u85-128",
"ethos-u55-128",
"TOSA",
]


def get_compile_spec(target: str, intermediates: bool) -> ArmCompileSpecBuilder:
spec_builder = None
if target == "TOSA":
spec_builder = (
ArmCompileSpecBuilder().tosa_compile_spec().set_permute_memory_format(True)
)
elif target == "ethos-u55-128":
spec_builder = (
ArmCompileSpecBuilder()
.ethosu_compile_spec(
"ethos-u55-128",
system_config="Ethos_U55_High_End_Embedded",
memory_mode="Shared_Sram",
extra_flags="--debug-force-regor --output-format=raw",
)
.set_permute_memory_format(args.model_name in MODEL_NAME_TO_MODEL.keys())
.set_quantize_io(True)
)
elif target == "ethos-u85-128":
spec_builder = (
ArmCompileSpecBuilder()
.ethosu_compile_spec(
"ethos-u85-128",
system_config="Ethos_U85_SYS_DRAM_Mid",
memory_mode="Shared_Sram",
extra_flags="--output-format=raw",
)
.set_permute_memory_format(True)
.set_quantize_io(True)
)

if intermediates is not None:
spec_builder.dump_intermediate_artifacts_to(args.intermediates)

return spec_builder.build()


def get_args():
parser = argparse.ArgumentParser()
parser.add_argument(
"-m",
Expand All @@ -149,6 +207,15 @@ def forward(self, x):
default=False,
help="Flag for producing ArmBackend delegated model",
)
parser.add_argument(
"-t",
"--target",
action="store",
required=False,
default="ethos-u55-128",
choices=targets,
help=f"For ArmBackend delegated models, pick the target, and therefore the instruction set generated. valid targets are {targets}",
)
parser.add_argument(
"-q",
"--quantize",
Expand All @@ -167,8 +234,26 @@ def forward(self, x):
parser.add_argument(
"--debug", action="store_true", help="Set the logging level to debug."
)

parser.add_argument(
"-i",
"--intermediates",
action="store",
required=False,
help="Store intermediate output (like TOSA artefacts) somewhere.",
)
parser.add_argument(
"-o",
"--output",
action="store",
required=False,
help="Location for outputs, if not the default of cwd.",
)
args = parser.parse_args()
return args


if __name__ == "__main__":
args = get_args()

if args.debug:
logging.basicConfig(level=logging.DEBUG, format=FORMAT, force=True)
Expand All @@ -191,7 +276,7 @@ def forward(self, x):
):
raise RuntimeError(f"Model {args.model_name} cannot be delegated.")

# 1. pick model from one of the supported lists
# Pick model from one of the supported lists
model, example_inputs = get_model_and_inputs_from_name(args.model_name)
model = model.eval()

Expand All @@ -209,23 +294,18 @@ def forward(self, x):
_check_ir_validity=False,
),
)

# As we can target multiple output encodings from ArmBackend, one must
# be specified.
compile_spec = (
get_compile_spec(args.target, args.intermediates)
if args.delegate is True
else None
)

logging.debug(f"Exported graph:\n{edge.exported_program().graph}")
if args.delegate is True:
edge = edge.to_backend(
ArmPartitioner(
ArmCompileSpecBuilder()
.ethosu_compile_spec(
"ethos-u55-128",
system_config="Ethos_U55_High_End_Embedded",
memory_mode="Shared_Sram",
)
.set_permute_memory_format(
args.model_name in MODEL_NAME_TO_MODEL.keys()
)
.set_quantize_io(True)
.build()
)
)
edge = edge.to_backend(ArmPartitioner(compile_spec))
logging.debug(f"Lowered graph:\n{edge.exported_program().graph}")

try:
Expand All @@ -241,7 +321,12 @@ def forward(self, x):
else:
raise e

model_name = f"{args.model_name}" + (
"_arm_delegate" if args.delegate is True else ""
model_name = os.path.basename(os.path.splitext(args.model_name)[0])
output_name = f"{model_name}" + (
f"_arm_delegate_{args.target}" if args.delegate is True else ""
)
save_pte_program(exec_prog, model_name)

if args.output is not None:
output_name = os.path.join(args.output, output_name)

save_pte_program(exec_prog, output_name)
6 changes: 4 additions & 2 deletions examples/arm/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ function generate_pte_file() {

local model_filename=${model}.pte
if [[ "${delegate}" == *"--delegate"* ]]; then
model_filename=${model}_arm_delegate.pte
# Name aligned with default aot_arm_compiler output - run.sh only supports
# running on Corstone-300 with Ethos-U55 FVP at the moment.
model_filename=${model}_arm_delegate_ethos-u55-128.pte
fi
cd $et_root_dir

Expand All @@ -56,7 +58,7 @@ function generate_pte_file() {
SO_LIB=$(find cmake-out-aot-lib -name libquantized_ops_aot_lib.so)

python3 -m examples.arm.aot_arm_compiler --model_name="${model}" ${delegate} --so_library="$SO_LIB" 1>&2
[[ -f ${pte_file} ]] || { echo "Failed to generate a pte file - ${pte_file}"; exit 1; }
[[ -f ${pte_file} ]] || { >&2 echo "Failed to generate a pte file - ${pte_file}"; exit 1; }
echo "${pte_file}"
}

Expand Down
Loading