diff --git a/.ci/scripts/setup-xtensa-tools.sh b/.ci/scripts/setup-xtensa-tools.sh index 8510c32c859..64900ce58d0 100755 --- a/.ci/scripts/setup-xtensa-tools.sh +++ b/.ci/scripts/setup-xtensa-tools.sh @@ -16,7 +16,7 @@ # # Usage: # XTENSA_S3_BUCKET= .ci/scripts/setup-xtensa-tools.sh -# backend = hifi4 | vision | fusion_g3 +# backend = hifi4 | vision | fusion_g3 | hifi1s | hifi5s # # In GitHub Actions this appends the toolchain env to $GITHUB_ENV so later # steps inherit it. Run locally to populate a workspace for manual builds. @@ -27,7 +27,7 @@ set -euo pipefail BACKEND="${1:-}" if [[ -z "${BACKEND}" ]]; then - echo "ERROR: usage: XTENSA_S3_BUCKET= $0 " >&2 + echo "ERROR: usage: XTENSA_S3_BUCKET= $0 " >&2 exit 1 fi @@ -45,6 +45,7 @@ S3_CORE_PREFIX="${XTENSA_S3_CORE_PREFIX:-}" # The toolchain's clang major must match the core's codegen plugin: # hifi4 / fusion_g3 cores (RI-2022.10, clang 10) -> RI-2022.9 host tools # vision core (RJ-2025.5, clang 15) -> RJ-2025.5 host tools +# hifi1s / hifi5s SDKs (RJ-2026.6, LLVM 19) -> RJ-2026.6 host tools case "${BACKEND}" in hifi4) CORE_NAME="hifi4_ss_spfpu_7_et_ci2" @@ -67,15 +68,29 @@ case "${BACKEND}" in TOOLCHAIN_VER="RJ-2025.5-linux" OPT_FLAG="EXECUTORCH_VISION_OPT" ;; + hifi1s) + CORE_NAME="hifi1s_ao_7" + CORE_TARBALL="hifi1s_ao_7.tgz" + TOOLCHAIN_TARBALL="XtensaTools_RJ_2026_6_linux.tgz" + TOOLCHAIN_VER="RJ-2026.6-linux" + OPT_FLAG="EXECUTORCH_NNLIB_OPT" + ;; + hifi5s) + CORE_NAME="hifi5s_ao_7" + CORE_TARBALL="hifi5s_ao_7.tgz" + TOOLCHAIN_TARBALL="XtensaTools_RJ_2026_6_linux.tgz" + TOOLCHAIN_VER="RJ-2026.6-linux" + OPT_FLAG="EXECUTORCH_NNLIB_OPT" + ;; *) - echo "ERROR: unknown backend '${BACKEND}' (expected hifi4|vision|fusion_g3)" >&2 + echo "ERROR: unknown backend '${BACKEND}' (expected hifi4|vision|fusion_g3|hifi1s|hifi5s)" >&2 exit 1 ;; esac XTENSA_ROOT="${XTENSA_ROOT:-/tmp/xtensa}" TOOLS_ROOT="${XTENSA_ROOT}/tools" # contains -linux/XtensaTools -CORES_ROOT="${XTENSA_ROOT}/cores" # contains -linux/ +CORES_ROOT="${XTENSA_ROOT}/cores" # contains -linux/ or REGISTRY_ROOT="${XTENSA_ROOT}/registry/${CORE_NAME}" DL_DIR="${XTENSA_ROOT}/download" mkdir -p "${TOOLS_ROOT}" "${CORES_ROOT}" "${REGISTRY_ROOT}" "${DL_DIR}" @@ -114,8 +129,10 @@ fi # 2. Core config (ISA libs, params, examples, bundled magic-key license). s3_get "${S3_CORE_PREFIX:+${S3_CORE_PREFIX}/}${CORE_TARBALL}" "${DL_DIR}/${CORE_TARBALL}" extract_tgz "${DL_DIR}/${CORE_TARBALL}" "${CORES_ROOT}" -CORE_DIR=$(echo "${CORES_ROOT}"/*/"${CORE_NAME}") -if [[ ! -d "${CORE_DIR}" ]]; then +# The et_ci2 core tarballs wrap the core in a -linux/ directory; the +# SDKs exported straight from XPG put it at the top level. +CORE_DIR=$(find "${CORES_ROOT}" -maxdepth 2 -type d -name "${CORE_NAME}" | head -1) +if [[ -z "${CORE_DIR}" || ! -d "${CORE_DIR}" ]]; then echo "ERROR: core dir for ${CORE_NAME} not found under ${CORES_ROOT}" >&2 exit 1 fi diff --git a/.github/workflows/_xtensa_build.yml b/.github/workflows/_xtensa_build.yml index 327cc7c9e25..f5a22fccdf1 100644 --- a/.github/workflows/_xtensa_build.yml +++ b/.github/workflows/_xtensa_build.yml @@ -12,7 +12,7 @@ on: workflow_call: inputs: backend: - description: "Cadence backend to build (hifi4 | vision | fusion_g3)" + description: "Cadence backend to build (hifi4 | vision | fusion_g3 | hifi1s | hifi5s)" required: true type: string ref: diff --git a/.github/workflows/_xtensa_test.yml b/.github/workflows/_xtensa_test.yml index e691826d80c..d2a7bd50519 100644 --- a/.github/workflows/_xtensa_test.yml +++ b/.github/workflows/_xtensa_test.yml @@ -11,7 +11,7 @@ on: workflow_call: inputs: backend: - description: "Cadence backend to test (hifi4 | vision | fusion_g3)" + description: "Cadence backend to test (hifi4 | vision | fusion_g3 | hifi1s | hifi5s)" required: true type: string ref: diff --git a/.github/workflows/build-cadence-runner.yml b/.github/workflows/build-cadence-runner.yml index 723d7bd99d4..eb61db697c5 100644 --- a/.github/workflows/build-cadence-runner.yml +++ b/.github/workflows/build-cadence-runner.yml @@ -167,3 +167,71 @@ jobs: ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }} docker-image: ${{ needs.docker-image.outputs.image }} allow-fork-checkout: ${{ github.event_name == 'pull_request_target' }} + + hifi1s-build: + needs: docker-image + if: >- + github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || + (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.pull_request.author_association)) + permissions: + id-token: write + contents: read + uses: ./.github/workflows/_xtensa_build.yml + with: + backend: hifi1s + ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }} + docker-image: ${{ needs.docker-image.outputs.image }} + allow-fork-checkout: ${{ github.event_name == 'pull_request_target' }} + + hifi1s-op-test: + needs: [docker-image, hifi1s-build] + if: >- + github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || + (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.pull_request.author_association)) + permissions: + id-token: write + contents: read + uses: ./.github/workflows/_xtensa_test.yml + with: + backend: hifi1s + ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }} + docker-image: ${{ needs.docker-image.outputs.image }} + allow-fork-checkout: ${{ github.event_name == 'pull_request_target' }} + + hifi5s-build: + needs: docker-image + if: >- + github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || + (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.pull_request.author_association)) + permissions: + id-token: write + contents: read + uses: ./.github/workflows/_xtensa_build.yml + with: + backend: hifi5s + ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }} + docker-image: ${{ needs.docker-image.outputs.image }} + allow-fork-checkout: ${{ github.event_name == 'pull_request_target' }} + + hifi5s-op-test: + needs: [docker-image, hifi5s-build] + if: >- + github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || + (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR", "CONTRIBUTOR"]'), github.event.pull_request.author_association)) + permissions: + id-token: write + contents: read + uses: ./.github/workflows/_xtensa_test.yml + with: + backend: hifi5s + ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }} + docker-image: ${{ needs.docker-image.outputs.image }} + allow-fork-checkout: ${{ github.event_name == 'pull_request_target' }} diff --git a/backends/cadence/hifi/operators/CMakeLists.txt b/backends/cadence/hifi/operators/CMakeLists.txt index d7948bbf1b4..12066133e2b 100644 --- a/backends/cadence/hifi/operators/CMakeLists.txt +++ b/backends/cadence/hifi/operators/CMakeLists.txt @@ -122,6 +122,7 @@ add_library( ${_generic_custom_ops__srcs} "op_quantized_add_asym8sxasym8s_asym8s_per_tensor_out.cpp" "op_quantized_add_asym8uxasym8u_asym8u_per_tensor_out.cpp" + "op_quantized_fully_connected_packed_out.cpp" "op_quantized_linear_out.cpp" "op_quantized_layer_norm.cpp" "op_quantized_linear_asym8sxasym8s_asym8s_per_tensor_out.cpp" diff --git a/backends/cadence/hifi/operators/tests/CMakeLists.txt b/backends/cadence/hifi/operators/tests/CMakeLists.txt index 0398400a1d5..589b0195a82 100644 --- a/backends/cadence/hifi/operators/tests/CMakeLists.txt +++ b/backends/cadence/hifi/operators/tests/CMakeLists.txt @@ -45,21 +45,14 @@ if(NOT TARGET gtest) endif() # Op-level gtests, one source per operator. Each calls its kernel directly and -# checks with EXPECT_TENSOR_EQ, mirroring the BUCK tests. +# checks with EXPECT_TENSOR_EQ, mirroring the BUCK tests. Globbed so a new +# test_op_*.cpp is built without editing this file. +file(GLOB _cadence_hifi_op_test_srcs CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/test_op_*.cpp" +) add_executable( cadence_hifi_op_tests - test_op_cat.cpp - test_op_dequantize_per_tensor_out.cpp - test_op_div.cpp - test_op_im2row_out.cpp - test_op_log2.cpp - test_op_permute_copy.cpp - test_op_quantize_per_tensor.cpp - test_op_quantized_conv2d_out.cpp - test_op_quantized_matmul_out.cpp - test_op_quantized_relu_out.cpp - test_op_relu.cpp - test_op_transpose_copy.cpp + ${_cadence_hifi_op_test_srcs} ${EXECUTORCH_ROOT}/runtime/core/exec_aten/testing_util/tensor_util.cpp ) target_compile_definitions(cadence_hifi_op_tests PRIVATE GTEST_HAS_PTHREAD=0)