-
Notifications
You must be signed in to change notification settings - Fork 989
Add Pico2 build validation CI (trunk only) #18900
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
46afb15
Add Pico2 build validation CI (trunk only)
psiddh ee8e84f
Address review: fix size validation, timeout, concurrency, CMSIS check
psiddh a1f6544
Add pull_request trigger to validate CI workflow
psiddh 9927201
Skip selective build for CMSIS-NN models
psiddh 664cd2d
Remove temporary pull_request trigger, fix ref for PR runs
psiddh 0ee15b8
Add pipefail and self-trigger path
psiddh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,169 @@ | ||
| name: Pico2 Build Validation | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main, release/*] | ||
| paths: | ||
|
psiddh marked this conversation as resolved.
psiddh marked this conversation as resolved.
|
||
| - examples/raspberry_pi/pico2/** | ||
| - backends/cortex_m/** | ||
|
psiddh marked this conversation as resolved.
|
||
| - .ci/scripts/** | ||
| - examples/arm/** | ||
|
psiddh marked this conversation as resolved.
psiddh marked this conversation as resolved.
|
||
| - .github/workflows/test-pico2-build.yml | ||
| schedule: | ||
| # Run daily at 3 AM UTC to catch upstream breakages | ||
| - cron: '0 3 * * *' | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.sha }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| test-pico2-fp32-build: | ||
| name: test-pico2-fp32-build | ||
| uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| with: | ||
| runner: linux.2xlarge.memory | ||
| docker-image: ci-image:executorch-ubuntu-22.04-arm-sdk | ||
| submodules: 'recursive' | ||
| ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | ||
| timeout: 120 | ||
| script: | | ||
| set -euo pipefail | ||
| # Activate conda environment from the docker image | ||
| CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]") | ||
| conda activate "${CONDA_ENV}" | ||
|
|
||
| source .ci/scripts/utils.sh | ||
|
psiddh marked this conversation as resolved.
|
||
| install_executorch "--use-pt-pinned-commit" | ||
|
|
||
| # Install ARM baremetal toolchain | ||
| .ci/scripts/setup-arm-baremetal-tools.sh | ||
| source examples/arm/arm-scratch/setup_path.sh | ||
|
|
||
| echo "=== Step 1: Export FP32 model ===" | ||
| cd examples/raspberry_pi/pico2 | ||
| python export_mlp_mnist.py | ||
| test -f balanced_tiny_mlp_mnist.pte | ||
| echo "FP32 model exported: $(ls -la balanced_tiny_mlp_mnist.pte)" | ||
| cd - | ||
|
|
||
| echo "=== Step 2: Build FP32 firmware ===" | ||
| ./examples/raspberry_pi/pico2/build_firmware_pico.sh --model=balanced_tiny_mlp_mnist.pte | ||
|
|
||
| echo "=== Step 3: Validate FP32 artifacts ===" | ||
| ELF_FILE=examples/raspberry_pi/pico2/build/executorch_pico.elf | ||
| UF2_FILE=examples/raspberry_pi/pico2/build/executorch_pico.uf2 | ||
|
|
||
| test -f "${ELF_FILE}" || { echo "FAIL: .elf not found"; exit 1; } | ||
| test -f "${UF2_FILE}" || { echo "FAIL: .uf2 not found"; exit 1; } | ||
|
|
||
| echo "--- Section sizes ---" | ||
| arm-none-eabi-size -A "${ELF_FILE}" | ||
|
|
||
| echo "--- Section headers ---" | ||
| arm-none-eabi-objdump -h "${ELF_FILE}" | ||
|
|
||
| echo "--- Key symbols ---" | ||
| arm-none-eabi-nm --print-size --size-sort --radix=d "${ELF_FILE}" | tail -20 | ||
|
|
||
| # Validate binary fits in Pico2 memory using aggregated totals: | ||
| # flash = text + data (4MB = 4194304 bytes) | ||
| # SRAM = data + bss (520KB = 532480 bytes) | ||
| eval $(arm-none-eabi-size "${ELF_FILE}" | awk 'NR==2 {printf "TEXT_SIZE=%d DATA_SIZE=%d BSS_SIZE=%d", $1, $2, $3}') | ||
|
|
||
| FLASH_USED=$((TEXT_SIZE + DATA_SIZE)) | ||
| SRAM_USED=$((DATA_SIZE + BSS_SIZE)) | ||
| echo "FP32 binary: text=${TEXT_SIZE} data=${DATA_SIZE} bss=${BSS_SIZE} => flash=${FLASH_USED} sram=${SRAM_USED}" | ||
|
|
||
| if [ "${FLASH_USED}" -gt 4194304 ]; then | ||
| echo "FAIL: flash usage (${FLASH_USED}) exceeds 4MB" | ||
| exit 1 | ||
| fi | ||
| if [ "${SRAM_USED}" -gt 532480 ]; then | ||
| echo "FAIL: SRAM usage (${SRAM_USED}) exceeds 520KB" | ||
| exit 1 | ||
| fi | ||
| echo "PASS: FP32 firmware fits in Pico2 memory (SRAM: ${SRAM_USED}/532480, Flash: ${FLASH_USED}/4194304)" | ||
|
|
||
| test-pico2-cmsis-build: | ||
| name: test-pico2-cmsis-nn-build | ||
| uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main | ||
| permissions: | ||
| id-token: write | ||
| contents: read | ||
| with: | ||
| runner: linux.2xlarge.memory | ||
| docker-image: ci-image:executorch-ubuntu-22.04-arm-sdk | ||
| submodules: 'recursive' | ||
| ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} | ||
| timeout: 120 | ||
| script: | | ||
| set -euo pipefail | ||
| # Activate conda environment from the docker image | ||
| CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]") | ||
| conda activate "${CONDA_ENV}" | ||
|
|
||
| source .ci/scripts/utils.sh | ||
|
psiddh marked this conversation as resolved.
|
||
| install_executorch "--use-pt-pinned-commit" | ||
|
|
||
| # Install ARM baremetal toolchain | ||
| .ci/scripts/setup-arm-baremetal-tools.sh | ||
| source examples/arm/arm-scratch/setup_path.sh | ||
|
|
||
| echo "=== Step 1: Export INT8 CMSIS-NN model ===" | ||
| cd examples/raspberry_pi/pico2 | ||
| python export_mlp_mnist_cmsis.py | ||
| test -f balanced_tiny_mlp_mnist_cmsis.pte | ||
| echo "INT8 model exported: $(ls -la balanced_tiny_mlp_mnist_cmsis.pte)" | ||
| cd - | ||
|
|
||
| echo "=== Step 2: Build CMSIS-NN firmware ===" | ||
| ./examples/raspberry_pi/pico2/build_firmware_pico.sh --cmsis --model=balanced_tiny_mlp_mnist_cmsis.pte | ||
|
|
||
| echo "=== Step 3: Validate CMSIS-NN artifacts ===" | ||
| ELF_FILE=examples/raspberry_pi/pico2/build/executorch_pico.elf | ||
| UF2_FILE=examples/raspberry_pi/pico2/build/executorch_pico.uf2 | ||
|
|
||
| test -f "${ELF_FILE}" || { echo "FAIL: .elf not found"; exit 1; } | ||
| test -f "${UF2_FILE}" || { echo "FAIL: .uf2 not found"; exit 1; } | ||
|
|
||
| echo "--- Section sizes ---" | ||
| arm-none-eabi-size -A "${ELF_FILE}" | ||
|
|
||
| echo "--- Section headers ---" | ||
| arm-none-eabi-objdump -h "${ELF_FILE}" | ||
|
|
||
| echo "--- Key symbols ---" | ||
| arm-none-eabi-nm --print-size --size-sort --radix=d "${ELF_FILE}" | tail -20 | ||
|
|
||
| # Verify CMSIS-NN symbols are linked | ||
| CMSIS_NN_SYMBOLS=$(arm-none-eabi-nm "${ELF_FILE}" | grep -E '(cmsis_nn|arm_nn)' || true) | ||
| if [ -n "${CMSIS_NN_SYMBOLS}" ]; then | ||
| echo "PASS: CMSIS-NN symbols found in binary" | ||
| printf '%s\n' "${CMSIS_NN_SYMBOLS}" | head -20 | ||
| else | ||
| echo "FAIL: No CMSIS-NN symbols detected — cortex_m backend may not be linked correctly" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Validate binary fits in Pico2 memory using aggregated totals: | ||
| # flash = text + data (4MB = 4194304 bytes) | ||
| # SRAM = data + bss (520KB = 532480 bytes) | ||
| eval $(arm-none-eabi-size "${ELF_FILE}" | awk 'NR==2 {printf "TEXT_SIZE=%d DATA_SIZE=%d BSS_SIZE=%d", $1, $2, $3}') | ||
|
|
||
| FLASH_USED=$((TEXT_SIZE + DATA_SIZE)) | ||
| SRAM_USED=$((DATA_SIZE + BSS_SIZE)) | ||
| echo "CMSIS-NN binary: text=${TEXT_SIZE} data=${DATA_SIZE} bss=${BSS_SIZE} => flash=${FLASH_USED} sram=${SRAM_USED}" | ||
|
|
||
| if [ "${FLASH_USED}" -gt 4194304 ]; then | ||
| echo "FAIL: flash usage (${FLASH_USED}) exceeds 4MB" | ||
| exit 1 | ||
| fi | ||
| if [ "${SRAM_USED}" -gt 532480 ]; then | ||
| echo "FAIL: SRAM usage (${SRAM_USED}) exceeds 520KB" | ||
| exit 1 | ||
| fi | ||
| echo "PASS: CMSIS-NN firmware fits in Pico2 memory (SRAM: ${SRAM_USED}/532480, Flash: ${FLASH_USED}/4194304)" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.