tan-cli 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Renesas DRP-AI compiler adapter (host model compiler).
|
|
3
|
+
|
|
4
|
+
DRP-AI uses the DRP-AI TVM toolchain (github.com/renesas-rz/rzv_drp-ai_tvm),
|
|
5
|
+
powered by the EdgeCortix MERA(TM) compiler. Its high-level driver is the
|
|
6
|
+
``compile_onnx_model_quant.py`` tutorial script: it takes an ONNX model + a
|
|
7
|
+
calibration image directory and emits a multi-file "Runtime Model Data" object
|
|
8
|
+
DIRECTORY (drp_desc.bin / weight.bin / addr_map.txt / deploy.json / deploy.so /
|
|
9
|
+
preprocess/ ...) that the on-device DRP-AI TVM runtime (MeraDrpRuntimeWrapper)
|
|
10
|
+
loads via ``LoadModel(<dir>)``. The toolchain build also needs the cross
|
|
11
|
+
toolchain root and (for V2N/V2H) the ``PRODUCT`` env set; the tutorial script
|
|
12
|
+
hard-requires ``PRODUCT in {V2H, V2N}``.
|
|
13
|
+
|
|
14
|
+
Because the artifact is a *directory*, the adapter packs it into a single
|
|
15
|
+
deterministic ``.tar`` byte blob with ``blob_format`` ``"drpai_dir"`` (the
|
|
16
|
+
device-side ``_fmt_enum`` maps that to ``ALP_INFERENCE_MODEL_DRPAI``; the
|
|
17
|
+
``.alpmodel`` loader stages the tar back out to a dir before handing the path
|
|
18
|
+
to the runtime).
|
|
19
|
+
|
|
20
|
+
The toolchain is large and account-/source-gated (the prebuilt MERA2 wheels +
|
|
21
|
+
the DRP-AI Translator), so it is NOT bundled. ``is_available()`` is True only
|
|
22
|
+
when ``ALP_DRPAI_TVM_HOME`` points at a built install; otherwise the drpai
|
|
23
|
+
target is a coverage skip (detect-and-skip), mirroring the DEEPX ``dxcom``
|
|
24
|
+
adapter. The A55 DRP-AI runtime backend is ``src/yocto/inference_drpai.cpp``
|
|
25
|
+
(bench-gated)."""
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
import io
|
|
28
|
+
import os
|
|
29
|
+
import re
|
|
30
|
+
import subprocess
|
|
31
|
+
import tarfile
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
|
|
34
|
+
from tan.core.subprocess_env import spawn_env
|
|
35
|
+
from . import CompilerAdapter, Blob
|
|
36
|
+
|
|
37
|
+
# The TVM/MERA build runs quantization + DRP-AI translation; minutes for a real
|
|
38
|
+
# model, bounded so CI (when it ever runs) can't hang.
|
|
39
|
+
_DRPAI_TIMEOUT_S = 1800
|
|
40
|
+
|
|
41
|
+
# Files the DRP-AI Translator is contractually required to emit into the object
|
|
42
|
+
# dir (per run_drp_quant_compiler.sh's expected_result_files). We assert at
|
|
43
|
+
# least the core descriptor + weights landed before declaring success.
|
|
44
|
+
_REQUIRED_ARTIFACTS = ("drp_desc.bin", "weight.bin", "addr_map.txt")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _tvm_home() -> Path | None:
|
|
48
|
+
root = os.environ.get("ALP_DRPAI_TVM_HOME")
|
|
49
|
+
return Path(root) if root and Path(root).is_dir() else None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _parse_shape_dims(input_shape) -> list[int] | None:
|
|
53
|
+
"""Parse input_shape into a list of dimension ints, accepting either
|
|
54
|
+
spelling board.yaml (YAML) can hand us: a comma-separated string
|
|
55
|
+
(``"1,3,224,224"``) or an already-parsed YAML flow-sequence list/tuple
|
|
56
|
+
(``[1, 3, 224, 224]``). Returns None when it parses as neither -- callers
|
|
57
|
+
treat that as "not the 224x224 classifier geometry" rather than
|
|
58
|
+
crashing on a malformed value."""
|
|
59
|
+
if isinstance(input_shape, (list, tuple)):
|
|
60
|
+
try:
|
|
61
|
+
return [int(d) for d in input_shape]
|
|
62
|
+
except (TypeError, ValueError):
|
|
63
|
+
return None
|
|
64
|
+
if not isinstance(input_shape, str):
|
|
65
|
+
return None
|
|
66
|
+
try:
|
|
67
|
+
return [int(d.strip()) for d in input_shape.split(",")]
|
|
68
|
+
except ValueError:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _is_224_imagenet_shape(input_shape) -> bool:
|
|
73
|
+
"""True when input_shape is the 224x224 ImageNet-classifier geometry the
|
|
74
|
+
vendor tutorial's ``--images`` path hard-codes.
|
|
75
|
+
|
|
76
|
+
``compile_onnx_model_quant.py`` always runs calibration images through
|
|
77
|
+
``pre_process_imagenet_pytorch()``, whose body ignores the ``dims``
|
|
78
|
+
argument it accepts and unconditionally does resize(256) +
|
|
79
|
+
center_crop(224) -- so ``--images`` only ever produces correctly-shaped
|
|
80
|
+
calibration tensors for a 3-channel, 224x224 model in NCHW
|
|
81
|
+
(``1,3,224,224``, the layout ONNX -- the only format this adapter accepts,
|
|
82
|
+
see accepts() -- uses by convention). Anything else -- e.g. a detector's
|
|
83
|
+
real geometry like YOLOX's ``1,3,640,640`` -- silently mismatches and the
|
|
84
|
+
vendor tool aborts deep inside with a shape-broadcast error after the
|
|
85
|
+
(multi-minute) compile has already run. See alp-sdk#1271.
|
|
86
|
+
|
|
87
|
+
Compares the PARSED dimensions (via _parse_shape_dims), never a
|
|
88
|
+
stringified spelling: ``str([1, 3, 224, 224])`` is
|
|
89
|
+
``'[1, 3, 224, 224]'``, and ``.split(",")`` on THAT tears into
|
|
90
|
+
``'[1'``, ``' 3'``, ``' 224'``, ``' 224]'`` -- none of which parse as
|
|
91
|
+
plain ints -- so a valid YAML-list 224x224 shape was misdiagnosed as
|
|
92
|
+
unsupported when this used to normalize input_shape to str() first
|
|
93
|
+
(alp-sdk#1271 round 4)."""
|
|
94
|
+
return _parse_shape_dims(input_shape) == [1, 3, 224, 224]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _compiler_version(tvm_home: Path) -> str:
|
|
98
|
+
"""Best-effort toolchain version from the DRP-AI TVM checkout.
|
|
99
|
+
|
|
100
|
+
Reads the repo's setup version file when present; falls back to a plain
|
|
101
|
+
'drp-ai_tvm' tag. Never raises -- version reporting is non-fatal.
|
|
102
|
+
|
|
103
|
+
`UnicodeDecodeError` is caught alongside `OSError` (tan-cli#1116,
|
|
104
|
+
measured escaping before this fix): it is a `ValueError`, not an
|
|
105
|
+
`OSError`, so a non-UTF-8 version file used to raise raw past this
|
|
106
|
+
function's own "Never raises" contract instead of falling through to
|
|
107
|
+
the next candidate the same way a missing or unreadable one already
|
|
108
|
+
does."""
|
|
109
|
+
for rel in ("setup/version", "version", "VERSION"):
|
|
110
|
+
vf = tvm_home / rel
|
|
111
|
+
try:
|
|
112
|
+
txt = vf.read_text(encoding="utf-8").strip()
|
|
113
|
+
except (OSError, UnicodeDecodeError):
|
|
114
|
+
continue
|
|
115
|
+
m = re.search(r"\d+\.\d+(?:\.\d+)?", txt)
|
|
116
|
+
if m:
|
|
117
|
+
return f"drp-ai_tvm {m.group(0)}"
|
|
118
|
+
return "drp-ai_tvm"
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _tar_dir(obj_dir: Path) -> bytes:
|
|
122
|
+
"""Pack the object dir into a single deterministic .tar byte blob.
|
|
123
|
+
|
|
124
|
+
Deterministic: sorted entries, zeroed mtime/uid/gid/owner so the same
|
|
125
|
+
inputs reproduce byte-identical blobs (matters for content-addressed
|
|
126
|
+
.alpmodel builds + CI diffing)."""
|
|
127
|
+
buf = io.BytesIO()
|
|
128
|
+
with tarfile.open(fileobj=buf, mode="w") as tar:
|
|
129
|
+
for path in sorted(obj_dir.rglob("*")):
|
|
130
|
+
if not path.is_file():
|
|
131
|
+
continue
|
|
132
|
+
info = tarfile.TarInfo(name=str(path.relative_to(obj_dir)))
|
|
133
|
+
data = path.read_bytes()
|
|
134
|
+
info.size = len(data)
|
|
135
|
+
info.mtime = 0
|
|
136
|
+
info.uid = info.gid = 0
|
|
137
|
+
info.uname = info.gname = ""
|
|
138
|
+
tar.addfile(info, io.BytesIO(data))
|
|
139
|
+
return buf.getvalue()
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class DrpaiAdapter(CompilerAdapter):
|
|
143
|
+
backend = "drpai"
|
|
144
|
+
requires_compile_opts = True # needs input shape/name + calib images
|
|
145
|
+
|
|
146
|
+
def is_available(self) -> bool:
|
|
147
|
+
return _tvm_home() is not None
|
|
148
|
+
|
|
149
|
+
def accepts(self, src_format: str) -> bool:
|
|
150
|
+
return src_format == "onnx" # DRP-AI TVM ingests ONNX
|
|
151
|
+
|
|
152
|
+
def compile(self, source: Path, *, accel_config: str, out_dir: Path,
|
|
153
|
+
opts: dict | None = None,
|
|
154
|
+
vela_memory_mode: str | None = None,
|
|
155
|
+
vela_system_config: str | None = None,
|
|
156
|
+
vela_vendor_system_config: str | None = None,
|
|
157
|
+
vela_vendor_config_filename: str | None = None,
|
|
158
|
+
soc_declares_dram: bool | None = None) -> Blob:
|
|
159
|
+
tvm_home = _tvm_home()
|
|
160
|
+
if tvm_home is None:
|
|
161
|
+
raise RuntimeError(
|
|
162
|
+
"DRP-AI compile needs the DRP-AI TVM toolchain; set "
|
|
163
|
+
"ALP_DRPAI_TVM_HOME to a built rzv_drp-ai_tvm install")
|
|
164
|
+
|
|
165
|
+
opts = opts or {}
|
|
166
|
+
# The TVM driver needs the model input geometry + a calibration image
|
|
167
|
+
# set (post-training INT8 quantization); these come from board.yaml
|
|
168
|
+
# models[].compile.drpai. (accel_config is "" for DRP-AI -- targets.py
|
|
169
|
+
# only populates it for Ethos-U; the DRP-AI product comes from the
|
|
170
|
+
# models[].compile.drpai config, not accel_config.)
|
|
171
|
+
input_shape = opts.get("input_shape")
|
|
172
|
+
input_name = opts.get("input_name")
|
|
173
|
+
images = opts.get("images")
|
|
174
|
+
if not input_shape or not input_name or not images:
|
|
175
|
+
raise RuntimeError(
|
|
176
|
+
"DRP-AI compile needs models[].compile.drpai with "
|
|
177
|
+
"input_shape, input_name and images (a calibration image dir)")
|
|
178
|
+
|
|
179
|
+
# The vendor tutorial's --images path only preprocesses to 224x224
|
|
180
|
+
# (see _is_224_imagenet_shape). Fail here, before the multi-minute
|
|
181
|
+
# compile runs, instead of forwarding a detector/segmentation
|
|
182
|
+
# geometry into a `could not broadcast` crash deep in vendor code.
|
|
183
|
+
# board.yaml (YAML) can hand us input_shape as either a comma string
|
|
184
|
+
# ("1,3,224,224") or an already-parsed flow-sequence list
|
|
185
|
+
# ([1, 3, 224, 224]); _is_224_imagenet_shape/_parse_shape_dims compare
|
|
186
|
+
# the PARSED dimensions for both spellings, never a stringified form
|
|
187
|
+
# -- str([1, 3, 224, 224]) is '[1, 3, 224, 224]', which .split(",")
|
|
188
|
+
# tears into tokens ('[1', ' 224]', ...) that don't parse as ints,
|
|
189
|
+
# misdiagnosing a valid 224x224 list shape as unsupported.
|
|
190
|
+
if not _is_224_imagenet_shape(input_shape):
|
|
191
|
+
raise RuntimeError(
|
|
192
|
+
f"DRP-AI --images calibration only works for the 224x224 "
|
|
193
|
+
f"ImageNet classifier geometry the vendor tutorial hard-codes "
|
|
194
|
+
f"in pre_process_imagenet_pytorch() (resize-256 + "
|
|
195
|
+
f"center-crop-224); got input_shape={input_shape!r}. A "
|
|
196
|
+
f"detector/segmentation model at this geometry cannot be "
|
|
197
|
+
f"calibrated against real images through this path yet "
|
|
198
|
+
f"(tracked in alp-sdk#1271) -- there is no random-frame "
|
|
199
|
+
f"fallback wired into this adapter today, so this compile "
|
|
200
|
+
f"cannot proceed with calibrated accuracy.")
|
|
201
|
+
# Vendor CLI's -s wants a comma-joined string ("1,3,224,224") --
|
|
202
|
+
# never Python's str() of a list -- so build it from the parsed
|
|
203
|
+
# dims, not from whatever spelling opts.input_shape arrived in.
|
|
204
|
+
shape_arg = ",".join(str(d) for d in _parse_shape_dims(input_shape))
|
|
205
|
+
|
|
206
|
+
product = (opts.get("product") or accel_config or "V2N").upper()
|
|
207
|
+
if product not in ("V2N", "V2H"):
|
|
208
|
+
raise RuntimeError(
|
|
209
|
+
f"DRP-AI compile: unsupported product {product!r} "
|
|
210
|
+
"(expected V2N or V2H)")
|
|
211
|
+
|
|
212
|
+
obj_dir = out_dir / f"{source.stem}_drpai"
|
|
213
|
+
obj_dir.mkdir(parents=True, exist_ok=True)
|
|
214
|
+
|
|
215
|
+
# The tutorial driver lives in the toolchain checkout; invoke it with
|
|
216
|
+
# the model, the output object dir, the input geometry and the
|
|
217
|
+
# calibration images. PRODUCT is consumed from the environment.
|
|
218
|
+
script = tvm_home / "tutorials" / "compile_onnx_model_quant.py"
|
|
219
|
+
cmd = [
|
|
220
|
+
"python3", str(script), str(source),
|
|
221
|
+
"-o", str(obj_dir),
|
|
222
|
+
"-s", shape_arg,
|
|
223
|
+
"-i", str(input_name),
|
|
224
|
+
"--images", str(images),
|
|
225
|
+
]
|
|
226
|
+
env = spawn_env({"PRODUCT": product})
|
|
227
|
+
try:
|
|
228
|
+
proc = subprocess.run(cmd, capture_output=True, text=True,
|
|
229
|
+
timeout=_DRPAI_TIMEOUT_S, env=env)
|
|
230
|
+
except subprocess.TimeoutExpired as exc:
|
|
231
|
+
raise RuntimeError(f"DRP-AI compile timed out after {exc.timeout}s") from exc
|
|
232
|
+
if proc.returncode != 0:
|
|
233
|
+
raise RuntimeError(
|
|
234
|
+
f"DRP-AI compile failed: {proc.stderr.strip() or proc.stdout.strip()}")
|
|
235
|
+
|
|
236
|
+
missing = [f for f in _REQUIRED_ARTIFACTS if not (obj_dir / f).is_file()]
|
|
237
|
+
if missing:
|
|
238
|
+
raise RuntimeError(
|
|
239
|
+
f"DRP-AI compile produced no {', '.join(missing)} in {obj_dir}")
|
|
240
|
+
|
|
241
|
+
return Blob(format="drpai_dir", payload=_tar_dir(obj_dir),
|
|
242
|
+
compiler_version=_compiler_version(tvm_home))
|