diff --git a/.asf.yaml b/.asf.yaml index afa7097e3690..9e337392aee8 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -45,5 +45,18 @@ github: # participation, permission is given on a three month # cycle. PMC may review and recycle slots when necessary. collaborators: + - hpanda-naut - denise-k + - driazati - tvm-bot # For automated feedback in PR review. + + # See https://cwiki.apache.org/confluence/display/INFRA/Git+-+.asf.yaml+features#Git.asf.yamlfeatures-Branchprotection + protected_branches: + main: + required_status_checks: + contexts: + # Require a passing run from Jenkins + - tvm-ci/pr-head + + required_pull_request_reviews: + required_approving_review_count: 1 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000000..29e2373f30ff --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +Jenkinsfile linguist-generated=true + diff --git a/.github/CODEOWNERS b/.github/CODEOWNERSHIP similarity index 91% rename from .github/CODEOWNERS rename to .github/CODEOWNERSHIP index 97cf467cca07..682dff7fe3c0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERSHIP @@ -30,6 +30,17 @@ # The sub modules should be ordered first by depth. # Making sure we append new sub-module rules after exisiting modules rules. +############################################################################### +# IMPORTANT NOTE +# This file is intentionally not named CODEOWNERS to avoid getting picked up +# by GitHub's code owners -> review mechanism. For details see +# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +# and https://github.com/apache/tvm-rfcs/pull/58 +# +# This file is kept to allow manual inspection of who is responsible for +# different segments of the codebase. +############################################################################### + ############################## # Top-level Fallbacks ############################## diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 61b4b02b1154..9a3917c656ec 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -8,12 +8,26 @@ runs: path: ~/conda_pkgs_dir key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('conda/build-environment.yaml') }} - uses: conda-incubator/setup-miniconda@v2 + continue-on-error: true + id: conda1 with: activate-environment: tvm-build channel-priority: strict environment-file: conda/build-environment.yaml auto-activate-base: false use-only-tar-bz2: true + python-version: 3.7 + condarc-file: conda/condarc + - uses: conda-incubator/setup-miniconda@v2 + if: steps.conda1.outcome == 'failure' + with: + activate-environment: tvm-build + channel-priority: strict + environment-file: conda/build-environment.yaml + auto-activate-base: false + use-only-tar-bz2: true + python-version: 3.7 + condarc-file: conda/condarc - name: Conda info shell: pwsh run: | diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000000..38f8c629c3d5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# See https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file +version: 2 + +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 0 + + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 0 \ No newline at end of file diff --git a/.github/workflows/docs_bot.yml b/.github/workflows/docs_bot.yml new file mode 100644 index 000000000000..9480a1176f15 --- /dev/null +++ b/.github/workflows/docs_bot.yml @@ -0,0 +1,18 @@ + +name: docs-bot +on: + status +jobs: + run-docs-bot: + if: ${{ github.repository == 'apache/tvm' && github.event.state == 'success' && github.event.context == 'tvm-ci/pr-head' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Comment link to docs + env: + COMMIT_SHA: ${{ github.event.sha }} + TARGET_URL: ${{ github.event.target_url }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -eux + python tests/scripts/github_docs_comment.py \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0edf9989371..313c440cbd21 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,60 +38,124 @@ jobs: MacOS: runs-on: macOS-latest steps: - - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - name: Set up environment - uses: ./.github/actions/setup - - name: Conda Build - shell: bash -l {0} - run: >- - conda build --output-folder=conda/pkg conda/recipe && - conda install tvm -c ./conda/pkg - - name: Build iOS RPC - run: | - IOS_VERSION="14.0" - CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_SYSTEM_NAME=iOS \ - -DCMAKE_SYSTEM_VERSION=${IOS_VERSION} \ - -DCMAKE_OSX_SYSROOT=iphonesimulator \ - -DCMAKE_OSX_ARCHITECTURES=x86_64 \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \ - -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON \ - -DUSE_IOS_RPC=ON" - - mkdir build-ios-simulator - cd build-ios-simulator - cmake .. ${CMAKE_FLAGS} - cmake --build . --target ios_rpc - - name: Test - shell: bash -l {0} - run: >- - python -m pytest -v tests/python/all-platform-minimal-test - - name: Test iOS RPC - shell: bash -l {0} - run: >- - python -m pip install tornado psutil cloudpickle && - export PYTHONPATH=tests/python/contrib:${PYTHONPATH} && - export BUNDLE_ID=org.apache.tvmrpc && - export BUNDLE_PATH=build-ios-simulator/apps/ios_rpc/ios_rpc/src/ios_rpc-build/Release-iphonesimulator/tvmrpc.app && - python -m pytest -v tests/python/contrib/test_rpc_server_device.py + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: Set up environment + uses: ./.github/actions/setup + - name: Conda Build + shell: bash -l {0} + run: >- + conda build --output-folder=conda/pkg conda/recipe && + conda install tvm -c ./conda/pkg + - name: Build iOS RPC + run: | + IOS_VERSION="14.0" + CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_SYSTEM_VERSION=${IOS_VERSION} \ + -DCMAKE_OSX_SYSROOT=iphonesimulator \ + -DCMAKE_OSX_ARCHITECTURES=x86_64 \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \ + -DCMAKE_BUILD_WITH_INSTALL_NAME_DIR=ON \ + -DUSE_IOS_RPC=ON" + + mkdir build-ios-simulator + cd build-ios-simulator + cmake .. ${CMAKE_FLAGS} + cmake --build . --target ios_rpc + - name: Test + shell: bash -l {0} + run: >- + python -m pytest -v tests/python/all-platform-minimal-test + - name: Test iOS RPC + shell: bash -l {0} + run: >- + python -m pip install tornado psutil cloudpickle && + export PYTHONPATH=tests/python/contrib:${PYTHONPATH} && + export BUNDLE_ID=org.apache.tvmrpc && + export BUNDLE_PATH=build-ios-simulator/apps/ios_rpc/ios_rpc/src/ios_rpc-build/Release-iphonesimulator/tvmrpc.app && + python -m pytest -v tests/python/contrib/test_rpc_server_device.py Windows: - runs-on: windows-2016 + runs-on: windows-2019 steps: - - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - name: Set up environment - uses: ./.github/actions/setup - - name: Conda Build - shell: cmd /C call {0} - run: >- - conda build --output-folder=conda/pkg conda/recipe && - conda install tvm -c ./conda/pkg - - name: Test - shell: cmd /C call {0} - run: >- - python -m pytest -v tests/python/all-platform-minimal-test + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: Set up environment + uses: ./.github/actions/setup + - name: Conda Build + shell: cmd /C call {0} + run: >- + conda build --output-folder=conda/pkg conda/recipe && + conda install tvm -c ./conda/pkg + - name: Test + shell: cmd /C call {0} + run: >- + python -m pytest -v tests/python/all-platform-minimal-test + Android: + runs-on: Ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: Set up environment + uses: ./.github/actions/setup + - name: Set up java + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '11' + - name: Build TVM + shell: bash -l {0} + run: | + mkdir build + cd build + ../tests/scripts/task_config_build_jvm.sh . + cmake .. + make + - name: Build TVM4J + run: | + make jvmpkg + - name: Build android_rpc + working-directory: apps/android_rpc + run: | + export PATH="${ANDROID_NDK_HOME}:$PATH" + gradle clean build + - name: Upload android_rpc APK + uses: actions/upload-artifact@v2 + with: + name: android_rpc-debug.apk + path: ./apps/android_rpc/app/build/outputs/apk/debug/app-debug.apk + - name: Build android_deploy + working-directory: apps/android_deploy + run: | + export PATH="${ANDROID_NDK_HOME}:$PATH" + gradle clean build + - name: Upload android_deploy APK + uses: actions/upload-artifact@v2 + with: + name: android_deploy-debug.apk + path: ./apps/android_deploy/app/build/outputs/apk/debug/app-debug.apk + - name: Build android_camera + working-directory: apps/android_camera + run: | + mkdir -p app/src/main/assets/models/ + export TVM_NDK_CC=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android30-clang++ + export TVM_HOME=~/work/tvm/tvm + export PYTHONPATH=$TVM_HOME/python:${PYTHONPATH} + python3 ${TVM_HOME}/python/gen_requirements.py + pip3 install -r ${TVM_HOME}/python/requirements/core.txt + cd models + pip3 install -r requirements.txt + python3 prepare_model.py + cd .. + export PATH="${ANDROID_NDK_HOME}:$PATH" + gradle clean build + - name: Upload android_camera APK + uses: actions/upload-artifact@v2 + with: + name: android_camera-debug.apk + path: ./apps/android_camera/app/build/outputs/apk/debug/app-debug.apk \ No newline at end of file diff --git a/.github/workflows/nightly_docker_update.yml b/.github/workflows/nightly_docker_update.yml new file mode 100644 index 000000000000..08945555af34 --- /dev/null +++ b/.github/workflows/nightly_docker_update.yml @@ -0,0 +1,31 @@ + +name: Nightly Docker Update +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + +concurrency: + group: nightly-docker-update + cancel-in-progress: true + +jobs: + open_update_pr: + permissions: + actions: write + checks: write + contents: write + id-token: write + issues: write + pull-requests: write + statuses: write + if: github.repository == 'apache/tvm' + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Open PR to update Docker images + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -eux + python tests/scripts/open_docker_update_pr.py diff --git a/.github/workflows/tvmbot.yml b/.github/workflows/tvmbot.yml new file mode 100644 index 000000000000..784f6899a3be --- /dev/null +++ b/.github/workflows/tvmbot.yml @@ -0,0 +1,29 @@ + +name: tvm-bot +on: + status: + pull_request_review: + types: + - submitted + issue_comment: + +concurrency: + group: merge-${{ github.event.pull_request.number }}-${{ github.event.issue.number }} + cancel-in-progress: true + +jobs: + run-tvm-bot: + if: ${{ github.event.issue.pull_request && github.repository == 'apache/tvm' }} + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Run tvm-bot + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TVM_BOT_JENKINS_TOKEN: ${{ secrets.TVM_BOT_JENKINS_TOKEN }} + PR_NUMBER: ${{ github.event.issue.number }} + ISSUE_COMMENT: ${{ toJson(github.event.comment) }} + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + set -eux + python tests/scripts/github_tvmbot.py --pr "$PR_NUMBER" --run-url "$RUN_URL" --trigger-comment-json "$ISSUE_COMMENT" diff --git a/.github/workflows/upload_ci_resource.yml b/.github/workflows/upload_ci_resource.yml new file mode 100644 index 000000000000..10bba56583c9 --- /dev/null +++ b/.github/workflows/upload_ci_resource.yml @@ -0,0 +1,58 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name: Upload CI Resource + +on: + workflow_dispatch: + inputs: + url: + description: 'URL of the file (e.g. "https://example.com/file.zip")' + required: true + type: string + sha256: + description: 'SHA256 of the file' + required: true + type: string + upload_path: + description: 'Path of the file in S3 (e.g. "my_folder/something.zip")' + required: true + type: string + +concurrency: + group: upload-ci-resource + cancel-in-progress: true + +jobs: + upload-ci-resource: + if: github.repository == 'apache/tvm' + runs-on: ubuntu-20.04 + steps: + - name: Download item and upload to S3 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_ACCESS_KEY_ID: ${{ secrets.CI_RESOURCES_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CI_RESOURCES_AWS_SECRET_ACCESS_KEY }} + URL: ${{ inputs.url }} + SHA256: ${{ inputs.sha256 }} + UPLOAD_PATH: ${{ inputs.upload_path }} + AWS_DEFAULT_REGION: us-west-2 + run: | + set -eux + curl -L -o downloaded_file "$URL" + echo "$SHA256 downloaded_file" | sha256sum --check + aws s3 cp downloaded_file "s3://tvm-ci-resources/$UPLOAD_PATH" + echo "The item is available at https://tvm-ci-resources.s3.us-west-2.amazonaws.com/$UPLOAD_PATH" diff --git a/.gitignore b/.gitignore index 63fcd1062454..e9b9743f1359 100644 --- a/.gitignore +++ b/.gitignore @@ -256,3 +256,15 @@ jvm/target src/runtime/hexagon/rpc/hexagon_rpc.h src/runtime/hexagon/rpc/hexagon_rpc_skel.c src/runtime/hexagon/rpc/hexagon_rpc_stub.c + +# Local tvm-site checkout +tvm-site/ + +# Generated docs files +gallery/how_to/work_with_microtvm/micro_tvmc.py + +# Test sample data files +!tests/python/ci/sample_prs/*.json + +# Used in CI to communicate between Python and Jenkins +.docker-image-names/ diff --git a/.gitmodules b/.gitmodules index 8dfda44d10a0..e03336443d73 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,18 +1,18 @@ [submodule "dmlc-core"] path = 3rdparty/dmlc-core - url = https://github.com/dmlc/dmlc-core + url = https://github.com/dmlc/dmlc-core.git [submodule "dlpack"] path = 3rdparty/dlpack - url = https://github.com/dmlc/dlpack + url = https://github.com/dmlc/dlpack.git [submodule "3rdparty/rang"] path = 3rdparty/rang - url = https://github.com/agauniyal/rang + url = https://github.com/agauniyal/rang.git [submodule "3rdparty/vta-hw"] path = 3rdparty/vta-hw - url = https://github.com/apache/incubator-tvm-vta + url = https://github.com/apache/tvm-vta.git [submodule "3rdparty/libbacktrace"] path = 3rdparty/libbacktrace url = https://github.com/tlc-pack/libbacktrace.git [submodule "3rdparty/cutlass"] path = 3rdparty/cutlass - url = https://github.com/NVIDIA/cutlass + url = https://github.com/NVIDIA/cutlass.git diff --git a/3rdparty/dmlc-core b/3rdparty/dmlc-core index 21cc7de0dc9f..09511cf9fe5f 160000 --- a/3rdparty/dmlc-core +++ b/3rdparty/dmlc-core @@ -1 +1 @@ -Subproject commit 21cc7de0dc9fd6acb796e1be6181fa8e6b6c8f41 +Subproject commit 09511cf9fe5ff103900a5eafb50870dc84cc17c8 diff --git a/CMakeLists.txt b/CMakeLists.txt index aef255614110..8dc03ee0f40e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(tvm C CXX) # Utility functions include(cmake/utils/Utils.cmake) include(cmake/utils/Summary.cmake) +include(cmake/utils/Linker.cmake) include(cmake/utils/FindCUDA.cmake) include(cmake/utils/FindOpenCL.cmake) include(cmake/utils/FindVulkan.cmake) @@ -25,6 +26,7 @@ endif() # Alernatively, use cmake -DOPTION=VALUE through command-line. tvm_option(USE_CUDA "Build with CUDA" OFF) tvm_option(USE_OPENCL "Build with OpenCL" OFF) +tvm_option(USE_OPENCL_GTEST "Path to OpenCL specific gtest version for runtime cpp tests." /path/to/opencl/gtest) tvm_option(USE_VULKAN "Build with Vulkan" OFF) @@ -39,9 +41,10 @@ tvm_option(USE_SPIRV_KHR_INTEGER_DOT_PRODUCT "whether enable SPIRV_KHR_DOT_PRODU tvm_option(USE_METAL "Build with Metal" OFF) tvm_option(USE_ROCM "Build with ROCM" OFF) tvm_option(ROCM_PATH "The path to rocm" /opt/rocm) -tvm_option(USE_HEXAGON_DEVICE "Build with Hexagon device support in TVM runtime" OFF) -tvm_option(USE_HEXAGON_SDK "Path to the Hexagon SDK root (required for Hexagon support in TVM runtime or for building TVM runtime for Hexagon)" /path/to/sdk) +tvm_option(USE_HEXAGON "Build with Hexagon support" OFF) +tvm_option(USE_HEXAGON_SDK "Path to the Hexagon SDK root (required for Hexagon support)" /path/to/sdk) tvm_option(USE_HEXAGON_RPC "Enable Hexagon RPC using minRPC implementation over Android." OFF) +tvm_option(USE_HEXAGON_GTEST "Path to Hexagon specific gtest version for runtime cpp tests." /path/to/hexagon/gtest) tvm_option(USE_RPC "Build with RPC" ON) tvm_option(USE_THREADS "Build with thread support" ON) tvm_option(USE_LLVM "Build with LLVM, can be set to specific llvm-config path" OFF) @@ -67,6 +70,8 @@ tvm_option(USE_LIBBACKTRACE "Build libbacktrace to supply linenumbers on stack t tvm_option(BUILD_STATIC_RUNTIME "Build static version of libtvm_runtime" OFF) tvm_option(USE_PAPI "Use Performance Application Programming Interface (PAPI) to read performance counters" OFF) tvm_option(USE_GTEST "Use GoogleTest for C++ sanity tests" AUTO) +tvm_option(USE_CUSTOM_LOGGING "Use user-defined custom logging, tvm::runtime::detail::LogFatalImpl and tvm::runtime::detail::LogMessageImpl must be implemented" OFF) +tvm_option(USE_ALTERNATIVE_LINKER "Use 'mold' or 'lld' if found when invoking compiler to link artifact" AUTO) # 3rdparty libraries tvm_option(DLPACK_PATH "Path to DLPACK" "3rdparty/dlpack/include") @@ -79,12 +84,12 @@ tvm_option(PICOJSON_PATH "Path to PicoJSON" "3rdparty/picojson") tvm_option(USE_BYODT_POSIT "Build with BYODT software emulated posit custom datatype" OFF) tvm_option(USE_BLAS "The blas library to be linked" none) tvm_option(USE_MKL "MKL root path when use MKL blas" OFF) -tvm_option(USE_MKLDNN "Build with MKLDNN" OFF) -tvm_option(USE_DNNL_CODEGEN "Enable MKLDNN (DNNL) codegen" OFF) +tvm_option(USE_DNNL "Enable DNNL codegen" OFF) tvm_option(USE_CUDNN "Build with cuDNN" OFF) tvm_option(USE_CUBLAS "Build with cuBLAS" OFF) tvm_option(USE_CUTLASS "Build with CUTLASS" OFF) tvm_option(USE_THRUST "Build with Thrust" OFF) +tvm_option(USE_CURAND "Build with cuRAND" OFF) tvm_option(USE_MIOPEN "Build with ROCM:MIOpen" OFF) tvm_option(USE_ROCBLAS "Build with ROCM:RoCBLAS" OFF) tvm_option(USE_SORT "Build with sort support" ON) @@ -106,6 +111,8 @@ tvm_option(USE_TENSORRT_RUNTIME "Build with TensorRT runtime" OFF) tvm_option(USE_RUST_EXT "Build with Rust based compiler extensions, STATIC, DYNAMIC, or OFF" OFF) tvm_option(USE_VITIS_AI "Build with VITIS-AI Codegen support" OFF) tvm_option(SUMMARIZE "Print CMake option summary after configuring" OFF) +tvm_option(USE_CLML "Build with CLML Codegen support" OFF) +tvm_option(USE_CLML_GRAPH_EXECUTOR "Build with CLML graph runtime" OFF) # include directories include_directories(${CMAKE_INCLUDE_PATH}) @@ -274,6 +281,7 @@ tvm_file_glob(GLOB_RECURSE COMPILER_SRCS src/parser/*.cc src/printer/*.cc src/support/*.cc + src/script/*.cc ) tvm_file_glob(GLOB CODEGEN_SRCS @@ -288,6 +296,7 @@ tvm_file_glob(GLOB_RECURSE RELAY_OP_SRCS ) tvm_file_glob(GLOB_RECURSE RELAY_PASS_SRCS src/relay/analysis/*.cc + src/relay/collage/*.cc src/relay/transforms/*.cc src/relay/quantize/*.cc ) @@ -314,20 +323,11 @@ list(APPEND COMPILER_SRCS "src/target/datatype/myfloat/myfloat.cc") tvm_file_glob(GLOB RUNTIME_SRCS src/runtime/*.cc src/runtime/vm/*.cc + src/runtime/minrpc/*.cc ) if(BUILD_FOR_HEXAGON) - # Add file implementing posix_memalign when building the runtime as - # a shared library. - # This function is actually defined in the static libc, but when linking - # a shared library, libc is not linked into it. Some runtime systems - # don't implement posix_runtime, which causes runtime failires. - # To avoid this issue, Hexagon runtime contains an implementation of - # posix_memalign, but it should only be used with the dynamic TVM - # runtime, since it would cause multiple definition errors with the - # static one. if(NOT BUILD_STATIC_RUNTIME) - list(APPEND RUNTIME_SRCS src/runtime/hexagon/android/hexagon_posix.cc) # Allow undefined symbols (there will be some from libc). set(TVM_NO_UNDEFINED_SYMBOLS "") endif() @@ -397,7 +397,6 @@ endif() if(USE_PROFILER) message(STATUS "Build with profiler...") - add_definitions(-DUSE_PROFILER=1) tvm_file_glob(GLOB RUNTIME_GRAPH_EXECUTOR_DEBUG_SRCS src/runtime/graph_executor/debug/*.cc) list(APPEND RUNTIME_SRCS ${RUNTIME_GRAPH_EXECUTOR_DEBUG_SRCS}) set_source_files_properties(${RUNTIME_GRAPH_EXECUTOR_SRCS} @@ -428,6 +427,25 @@ if(USE_GTEST) find_package(GTest REQUIRED) endif() if(GTEST_FOUND) + if(NOT TARGET GTest::gmock) + # GMock is formally supported in CMake 3.20; for now, expect libgmock.a in the same directory, + # and require that folks compiling against GTest::gmock also link against GTest::GTest + # (for the includes dir). + add_library(GTest::gmock STATIC IMPORTED GLOBAL) + get_target_property(GTEST_LIB_PATH GTest::GTest IMPORTED_LOCATION) + if("${GTEST_LIB_PATH}" STREQUAL "GTEST_LIB_PATH-NOTFOUND") + # CMake >= 3.20 makes GTest::GTest into a compatibility target. The real import location is in + # GTest::gtest. + get_target_property(GTEST_LIB_PATH GTest::gtest IMPORTED_LOCATION) + if("${GTEST_LIB_PATH}" STREQUAL "GTEST_LIB_PATH-NOTFOUND") + message(FATAL_ERROR "Neither GTest::GTest nor GTest::gtest targets defined IMPORTED_LOCATION") + endif() + endif() + get_filename_component(GTEST_LIB_DIR "${GTEST_LIB_PATH}" DIRECTORY) + set_target_properties(GTest::gmock PROPERTIES + IMPORTED_LOCATION "${GTEST_LIB_DIR}/libgmock.a") + endif() + enable_testing() include(CTest) endif() @@ -445,7 +463,7 @@ include(cmake/modules/StandaloneCrt.cmake) include(cmake/modules/Zephyr.cmake) include(cmake/modules/Arduino.cmake) include(cmake/modules/CUDA.cmake) -include(cmake/modules/Hexagon.cmake) +include(cmake/modules/Hexagon.cmake) # This must come before logging.cmake include(cmake/modules/OpenCL.cmake) include(cmake/modules/OpenMP.cmake) include(cmake/modules/Vulkan.cmake) @@ -478,6 +496,7 @@ include(cmake/modules/contrib/ArmComputeLib.cmake) include(cmake/modules/contrib/TensorRT.cmake) include(cmake/modules/contrib/VitisAI.cmake) include(cmake/modules/contrib/Verilator.cmake) +include(cmake/modules/contrib/CLML.cmake) include(cmake/modules/Git.cmake) include(cmake/modules/LibInfo.cmake) include(cmake/modules/RustExt.cmake) @@ -586,6 +605,27 @@ endif() target_link_libraries(tvm PRIVATE ${TVM_LINKER_LIBS} ${TVM_RUNTIME_LINKER_LIBS}) target_link_libraries(tvm_runtime PRIVATE ${TVM_RUNTIME_LINKER_LIBS}) +if(BUILD_FOR_HEXAGON AND DEFINED USE_HEXAGON_GTEST AND EXISTS ${USE_HEXAGON_GTEST}) + include(FetchContent) + FetchContent_Declare(googletest SOURCE_DIR "${USE_HEXAGON_GTEST}") + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + target_link_libraries(tvm_runtime PUBLIC gtest) + include_directories("${USE_HEXAGON_GTEST}/include") +endif() + +if(USE_OPENCL AND DEFINED USE_OPENCL_GTEST AND EXISTS ${USE_OPENCL_GTEST}) + include(FetchContent) + FetchContent_Declare(googletest SOURCE_DIR "${USE_OPENCL_GTEST}") + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) + target_link_libraries(tvm_runtime PUBLIC gtest) + target_link_libraries(tvm PUBLIC gtest) + include_directories("${USE_OPENCL_GTEST}/include") + include_directories("${USE_OPENCL_GTEST}/googletest/include") + message(STATUS "Found OpenCL gtest at ${USE_OPENCL_GTEST}") +endif() + # Set flags for clang include(cmake/modules/ClangFlags.cmake) set(CRC16_INCLUDE_PATH "3rdparty/libcrc/include") @@ -612,7 +652,8 @@ if (HIDE_PRIVATE_SYMBOLS AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # once minimum CMake version is bumped up to 3.13 or above. target_link_libraries(tvm PRIVATE ${HIDE_SYMBOLS_LINKER_FLAGS}) target_link_libraries(tvm_runtime PRIVATE ${HIDE_SYMBOLS_LINKER_FLAGS}) - target_compile_definitions(tvm_allvisible PUBLIC DMLC_USE_LOGGING_LIBRARY=) + target_compile_definitions(tvm_allvisible PUBLIC $) + target_compile_definitions(tvm_allvisible PRIVATE $) endif() # Create the `cpptest` target if we can find GTest. If not, we create dummy @@ -621,10 +662,20 @@ if(GTEST_FOUND) tvm_file_glob(GLOB_RECURSE TEST_SRCS tests/cpp/*.cc) add_executable(cpptest ${TEST_SRCS}) # include runtime files for unit testing - target_include_directories(cpptest PUBLIC "src/runtime") - target_link_libraries(cpptest PRIVATE ${TVM_TEST_LIBRARY_NAME} GTest::GTest GTest::Main pthread dl) + target_link_libraries(cpptest PRIVATE ${TVM_TEST_LIBRARY_NAME} GTest::GTest GTest::Main GTest::gmock pthread dl) + if(DEFINED LLVM_LIBS) + target_link_libraries(cpptest PRIVATE ${LLVM_LIBS}) + endif() set_target_properties(cpptest PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(cpptest PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1) + if(USE_RELAY_DEBUG) + target_compile_definitions(cpptest PRIVATE "USE_RELAY_DEBUG") + target_compile_definitions(cpptest PRIVATE "TVM_LOG_DEBUG") + else() + target_compile_definitions(cpptest PRIVATE "NDEBUG") + endif() + # For some reason, compile definitions are not propagated correctly, so we manually add them here + target_compile_definitions(cpptest PUBLIC $) gtest_discover_tests(cpptest) endif() @@ -634,6 +685,12 @@ add_custom_target(runtime DEPENDS tvm_runtime) # Installation rules install(TARGETS tvm EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX}) install(TARGETS tvm_runtime EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX}) +if(BUILD_FOR_HEXAGON AND DEFINED USE_HEXAGON_GTEST AND EXISTS ${USE_HEXAGON_GTEST}) + install(TARGETS gtest EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX}) +endif() +if(USE_OPENCL AND DEFINED USE_OPENCL_GTEST AND EXISTS ${USE_OPENCL_GTEST}) + install(TARGETS gtest EXPORT ${PROJECT_NAME}Targets DESTINATION lib${LIB_SUFFIX}) +endif() if (INSTALL_DEV) install( @@ -732,34 +789,7 @@ if(BUILD_FOR_HEXAGON) endif() endif() -#Caches the build. -#Note that ccache-3.x doesn't support nvcc well, so CUDA kernels may never hit the cache and still -#need to be re-compiled every time. Using ccache 4.0+ can resolve this issue. - -if(USE_CCACHE) # True for AUTO, ON, /path/to/ccache - if("${USE_CCACHE}" STREQUAL "AUTO") # Auto mode - find_program(CCACHE_FOUND ccache) - if(CCACHE_FOUND) - message(STATUS "Found the path to ccache, enabling ccache") - set(PATH_TO_CCACHE ccache) - else() - message(STATUS "Didn't find the path to CCACHE, disabling ccache") - endif(CCACHE_FOUND) - elseif("${USE_CCACHE}" MATCHES ${IS_TRUE_PATTERN}) - find_program(CCACHE_FOUND ccache) - if(CCACHE_FOUND) - message(STATUS "Found the path to ccache, enabling ccache") - set(PATH_TO_CCACHE ccache) - else() - message(FATAL_ERROR "Cannot find ccache. Set USE_CCACHE mode to AUTO or OFF to build without ccache. USE_CCACHE=" "${USE_CCACHE}") - endif(CCACHE_FOUND) - else() # /path/to/ccache - set(PATH_TO_CCACHE USE_CCACHE) - message(STATUS "Setting ccache path to " "${PATH_TO_CCACHE}") - endif() - # Set the flag for ccache - set(CXX_COMPILER_LAUNCHER PATH_TO_CCACHE) -endif(USE_CCACHE) +find_and_set_linker(${USE_ALTERNATIVE_LINKER}) if(${SUMMARIZE}) print_summary() diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0b3e60572924..8580eb55755b 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -35,16 +35,20 @@ We do encourage everyone to work anything they are interested in. - [Tianqi Chen](https://github.com/tqchen) (PMC): @tqchen - topi, compiler, relay, docs - [Wei Chen](https://github.com/wweic): @wweic - runtime, relay, vm - [Zhi Chen](https://github.com/zhiics) (PMC): @zhiics - relay, quantization, pass manager -- [Siyuan Feng](https://github.com/Hzfengsy): @Hzfengsy - tir +- [Siyuan Feng](https://github.com/Hzfengsy) (PMC): @Hzfengsy - tir - [Josh Fromm](https://github.com/jwfromm): @jwfromm - frontends, quantization, topi +- [Mehrdad Hessar](https://github.com/mehrdadh): @mehrdadh - microTVM, hexagon - [Bohan Hou](https://github.com/spectrometerHBH): @spectrometerHBH - tir, arith, tvm-script - [Yuwei Hu](https://github.com/Huyuwei): @Huyuwei - topi, frontends +- [Luke Hutton](https://github.com/lhutton1): @lhutton1 - ethos-u, arm - [Nick Hynes](https://github.com/nhynes): @nhynes: - sgx, rust - [Animesh Jain](https://github.com/anijain2305): @anijain2305 - quantization, relay - [Chenfan Jia](https://github.com/jcf94): @jcf94 - auto_scheduler - [Ziheng Jiang](https://github.com/ZihengJiang) (PMC): @ZihengJiang - relay, compiler - [Manupa Karunaratne](https://github.com/manupa-arm): @manupa-arm - ethos-u, memory planner - [Marisa Kirisame](https://github.com/MarisaKirisame): @MarisaKirisame - relay +- [Tristan Konolige](https://github.com/tkonolige): @tkonolige - profiling, relay, tir, runtime +- [Ruihang Lai](https://github.com/MasterJH5574): @MasterJH5574 - tir, tvm-script - [Wuwei Lin](https://github.com/vinx13): @vinx13 - relay, topi - [Yizhi Liu](https://github.com/yzhliu) (PMC): @yzhliu - jvm, topi, relay - [Hao Lu](https://github.com/hlu1): @hlu1 - nnpack, frontends @@ -57,9 +61,11 @@ We do encourage everyone to work anything they are interested in. - [Trevor Morris](https://github.com/trevor-m): @trevor-m - byoc, compiler - [Leandro Nunes](https://github.com/leandron) (PMC): @leandron - tvmc - [Lily Orth-Smith](https://github.com/electriclilies): @electriclilies - relay -- [Krzysztof Parzyszek](https://github.com/kparzysz-quic): @kparzysz-quic - hexagon, llvm +- [Krzysztof Parzyszek](https://github.com/kparzysz-quic) (PMC): @kparzysz-quic - hexagon, llvm - [Andrew Reusch](https://github.com/areusch): (PMC) @areusch - runtime, microTVM +- [David Riazati](https://github.com/driazati): @driazati - ci, community - [Jared Roesch](https://github.com/jroesch) (PMC): @jroesch - relay +- [Gustavo Romero](https://github.com/gromero): @gromero - microtvm, tvmc - [Giuseppe Rossini](https://github.com/giuseros): @giuseros - aot, arm - [Siju Samuel](https://github.com/siju-samuel): @siju-samuel - frontends - [Christopher Sidebottom](https://github.com/Mousius): @Mousius - arm, ethos-u, relay @@ -77,6 +83,8 @@ We do encourage everyone to work anything they are interested in. - [Eddie Yan](https://github.com/eqy) (PMC): @eqy - runtime, autotvm, rpc, topi - [Hao Yu](https://github.com/comaniac): @comaniac (PMC) - relay, byoc, auto_scheduler - [Lianmin Zheng](https://github.com/merrymercy) (PMC): @merrymercy - autotvm, auto_scheduler, topi, relay +- [Xiyou Zhou](https://github.com/zxybazh): @zxybazh - relay +- [wrongtest](https://github.com/wrongtest): @wrongtest - tir, tvm-script, arith ## Reviewers @@ -87,6 +95,7 @@ We do encourage everyone to work anything they are interested in. - [Liangfu Chen](https://github.com/liangfu): @liangfu - [Tianqi Chen](https://github.com/tqchen): @tqchen - [Zhi Chen](https://github.com/zhiics): @zhiics +- [Valery Chernov](https://github.com/vvchernov): @vvchernov - [Neo Chien](https://github.com/cchung100m): @cchung100m - [Meghan Cowan](https://github.com/cowanmeg): @cowanmeg - [Balint Cristian](https://github.com/cbalint13): @cbalint13 @@ -95,7 +104,9 @@ We do encourage everyone to work anything they are interested in. - [Haozheng Fan](https://github.com/hzfan): @hzfan - [Siyuan Feng](https://github.com/Hzfengsy): @Hzfengsy - [Josh Fromm](https://github.com/jwfromm): @jwfromm +- [Alexey Gladyshev](https://github.com/KJlaccHoeUM9l): @KJlaccHoeUM9l - [Sergei Grechanik](https://github.com/sgrechanik-h): @sgrechanik-h +- [Altan Haan](https://github.com/altanh): @altanh - [Mehrdad Hessar](https://github.com/mehrdadh): @mehrdadh - [Bohan Hou](https://github.com/spectrometerHBH): @spectrometerHBH - [Yuwei Hu](https://github.com/Huyuwei): @Huyuwei @@ -105,10 +116,14 @@ We do encourage everyone to work anything they are interested in. - [Chenfan Jia](https://github.com/jcf94): @jcf94 - [Hua Jiang](https://github.com/huajsj): @huajsj - [Ziheng Jiang](https://github.com/ZihengJiang): @ZihengJiang +- [Hongyi Jin](https://github.com/jinhongyii): @jinhongyii - [Manupa Karunaratne](https://github.com/manupa-arm): @manupa-arm +- [Elen Kalda](https://github.com/ekalda): @ekalda - [Marisa Kirisame](https://github.com/MarisaKirisame): @MarisaKirisame - [Tristan Konolige](https://github.com/tkonolige): @tkonolige +- [Denise Kutnick](https://github.com/denise-k): @denise-k - [Ruihang Lai](https://github.com/MasterJH5574): @MasterJH5574 +- [Nicola Lancellotti](https://github.com/nicolalancellotti): @NicolaLancellotti - [Wuwei Lin](https://github.com/vinx13): @vinx13 - [Andrew Liu](https://github.com/hypercubestart): @hypercubestart - [Henry Liu](https://github.com/optima2005): @optima2005 @@ -129,10 +144,15 @@ We do encourage everyone to work anything they are interested in. - [Jiawei Liu](https://github.com/ganler): @ganler - [Lily Orth-Smith](https://github.com/electriclilies): @electriclilies - [Wei Pan](https://github.com/wpan11nv): @wpan11nv +- [Michalis Papadimitriou](https://github.com/mikepapadim): @mikepapadim +- [Ashutosh Parkhi](https://github.com/ashutosh-arm): @ashutosh-arm - [Krzysztof Parzyszek](https://github.com/kparzysz-quic): @kparzysz-quic +- [Alexander Peskov](https://github.com/apeskov): @apeskov - [Pariksheet Pinjari](https://github.com/PariksheetPinjari909): @PariksheetPinjari909 - [Josh Pollock](https://github.com/joshpoll): @joshpoll +- [Ramana Radhakrishnan](https://github.com/u99127): @u99127 - [Andrew Reusch](https://github.com/areusch): @areusch +- [David Riazati](https://github.com/driazati): @driazati - [Jared Roesch](https://github.com/jroesch): @jroesch - [Gustavo Romero](https://github.com/gromero): @gromero - [Giuseppe Rossini](https://github.com/giuseros): @giuseros @@ -149,6 +169,7 @@ We do encourage everyone to work anything they are interested in. - [Zhixun Tan](https://github.com/phisiart): @phisiart - [Andrew Tulloch](https://github.com/ajtulloch): @ajtulloch - [Jorn Tuyls](https://github.com/jtuyls): @jtuyls +- [Gavin Uberti](https://github.com/guberti): @guberti - [Luis Vega](https://github.com/vegaluisjose): @vegaluisjose - [Thomas Viehmann](https://github.com/t-vi): @t-vi - [Yao Wang](https://github.com/kevinthesun): @kevinthesun @@ -163,6 +184,7 @@ We do encourage everyone to work anything they are interested in. - [Zhao Wu](https://github.com/FrozenGene): @FrozenGene - [Bing Xu](https://github.com/antinucleon): @antinucleon - [Eddie Yan](https://github.com/eqy): @eqy +- [Zihao Ye](https://github.com/yzh119): @yzh119 - [Hao Yu](https://github.com/comaniac): @comaniac - [Joshua Z. Zhang](https://github.com/zhreshold): @zhreshold - [Lianmin Zheng](https://github.com/merrymercy): @merrymercy diff --git a/Jenkinsfile b/Jenkinsfile index 4a9ae3532585..c2f640733338 100755 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -39,20 +39,24 @@ // - Periodically cleanup the old versions on local workers // -// Hashtag in the source to build current CI docker builds -// -// -import org.jenkinsci.plugins.pipeline.modeldefinition.Utils +// ============================= IMPORTANT NOTE ============================= +// This file is generated by 'jenkins/generate.py'. Do not edit this file directly! +// Make edits to 'jenkins/Jenkinsfile.j2' and regenerate this with +// 'python3 jenkins/generate.py' +// Note: This timestamp is here to ensure that updates to the Jenkinsfile are +// always rebased on main before merging: +// Generated at 2022-07-15T13:35:24.676914 +import org.jenkinsci.plugins.pipeline.modeldefinition.Utils // NOTE: these lines are scanned by docker/dev_common.sh. Please update the regex as needed. --> -ci_lint = 'tlcpack/ci-lint:v0.68' -ci_gpu = 'tlcpack/ci-gpu:v0.81' -ci_cpu = 'tlcpack/ci-cpu:v0.81' -ci_wasm = 'tlcpack/ci-wasm:v0.71' -ci_i386 = 'tlcpack/ci-i386:v0.74' -ci_qemu = 'tlcpack/ci-qemu:v0.10' -ci_arm = 'tlcpack/ci-arm:v0.07' -ci_hexagon = 'tlcpack/ci-hexagon:v0.01' +ci_lint = 'tlcpack/ci-lint:20220715-060127-37f9d3c49' +ci_gpu = 'tlcpack/ci-gpu:20220715-060127-37f9d3c49' +ci_cpu = 'tlcpack/ci-cpu:20220715-060127-37f9d3c49' +ci_wasm = 'tlcpack/ci-wasm:20220715-060127-37f9d3c49' +ci_i386 = 'tlcpack/ci-i386:20220715-060127-37f9d3c49' +ci_qemu = 'tlcpack/ci-qemu:20220630-060117-558ba99c7' +ci_arm = 'tlcpack/ci-arm:20220715-060127-37f9d3c49' +ci_hexagon = 'tlcpack/ci-hexagon:20220715-060127-37f9d3c49' // <--- End of regex-scanned config. // Parameters to allow overriding (in Jenkins UI), the images @@ -60,32 +64,35 @@ ci_hexagon = 'tlcpack/ci-hexagon:v0.01' // over default values above. properties([ parameters([ - string(name: 'ci_lint_param', defaultValue: ''), - string(name: 'ci_cpu_param', defaultValue: ''), - string(name: 'ci_gpu_param', defaultValue: ''), - string(name: 'ci_wasm_param', defaultValue: ''), + string(name: 'ci_arm_param', defaultValue: ''), + string(name: 'ci_cpu_param', defaultValue: ''), + string(name: 'ci_gpu_param', defaultValue: ''), + string(name: 'ci_hexagon_param', defaultValue: ''), string(name: 'ci_i386_param', defaultValue: ''), + string(name: 'ci_lint_param', defaultValue: ''), string(name: 'ci_qemu_param', defaultValue: ''), - string(name: 'ci_arm_param', defaultValue: '') + string(name: 'ci_wasm_param', defaultValue: ''), ]) ]) -// tvm libraries -tvm_runtime = 'build/libtvm_runtime.so, build/config.cmake' -tvm_lib = 'build/libtvm.so, ' + tvm_runtime -// LLVM upstream lib -tvm_multilib = 'build/libtvm.so, ' + - 'build/libvta_fsim.so, ' + - tvm_runtime - -tvm_multilib_tsim = 'build/libvta_tsim.so, ' + - tvm_multilib +// Global variable assigned during Sanity Check that holds the sha1 which should be +// merged into the PR in all branches. +upstream_revision = null // command to start a docker container -docker_run = 'docker/bash.sh' +docker_run = 'docker/bash.sh --env CI --env TVM_SHARD_INDEX --env TVM_NUM_SHARDS --env RUN_DISPLAY_URL --env PLATFORM' +docker_build = 'docker/build.sh' // timeout in minutes -max_time = 240 +max_time = 180 +rebuild_docker_images = false + +// Filenames for stashing between build and test steps +s3_prefix = "tvm-jenkins-artifacts-prod/tvm/${env.BRANCH_NAME}/${env.BUILD_NUMBER}" + +// General note: Jenkins has limits on the size of a method (or top level code) +// that are pretty strict, so most usage of groovy methods in these templates +// are purely to satisfy the JVM def per_exec_ws(folder) { return "workspace/exec_${env.EXECUTOR_NUMBER}/" + folder } @@ -93,15 +100,80 @@ def per_exec_ws(folder) { // initialize source codes def init_git() { checkout scm + + // Add more info about job node sh ( script: './tests/scripts/task_show_node_info.sh', label: 'Show executor node info', ) - retry(5) { - timeout(time: 2, unit: 'MINUTES') { - sh (script: 'git submodule update --init -f', label: 'Update git submodules') - } + + // Determine merge commit to use for all stages + sh ( + script: 'git fetch origin main', + label: 'Fetch upstream', + ) + if (upstream_revision == null) { + upstream_revision = sh( + script: 'git log -1 FETCH_HEAD --format=\'%H\'', + label: 'Determine upstream revision', + returnStdout: true, + ).trim() + } + sh ( + script: "git -c user.name=TVM-Jenkins -c user.email=jenkins@tvm.apache.org merge ${upstream_revision}", + label: 'Merge to origin/main' + ) + + sh( + script: ''' + set -eux + n=0 + max_retries=3 + backoff_max=30 + until [ "$n" -ge $max_retries ] + do + timeout 5m git submodule update --init -f --jobs 0 && break + n=$((n+1)) + if [ "$n" -eq $max_retries ]; then + echo "failed to update $n / $max_retries, giving up" + exit 1 + fi + + WAIT=$((RANDOM % "$backoff_max")) + echo "failed to update $n / $max_retries, waiting $WAIT to try again" + sleep $WAIT + done + ''', + label: 'Update git submodules', + ) +} + +def docker_init(image) { + // Clear out all Docker images that aren't going to be used + sh( + script: """ + set -eux + docker image ls --all + IMAGES=\$(docker image ls --all --format '{{.Repository}}:{{.Tag}} {{.ID}}') + + echo -e "Found images:\\n\$IMAGES" + echo "\$IMAGES" | { grep -vE '${image}' || test \$? = 1; } | { xargs docker rmi || test \$? = 123; } + + docker image ls --all + """, + label: 'Clean old Docker images', + ) + + if (image.contains("amazonaws.com")) { + // If this string is in the image name it's from ECR and needs to be pulled + // with the right credentials + ecr_pull(image) + } else { + sh( + script: "docker pull ${image}", + label: 'Pull docker image', + ) } } @@ -132,7 +204,7 @@ def cancel_previous_build() { } def should_skip_ci(pr_number) { - if (!env.BRANCH_NAME.startsWith('PR-')) { + if (env.BRANCH_NAME == null || !env.BRANCH_NAME.startsWith('PR-')) { // never skip CI on build sourced from a branch return false } @@ -159,45 +231,81 @@ def should_skip_ci(pr_number) { return git_skip_ci_code == 0 } -// skips builds from branch indexing; sourced from https://www.jvt.me/posts/2020/02/23/jenkins-multibranch-skip-branch-index/ -// execute this before anything else, including requesting any time on an agent -if (currentBuild.getBuildCauses().toString().contains('BranchIndexingCause')) { - print "INFO: Build skipped due to trigger being Branch Indexing" - currentBuild.result = 'ABORTED' // optional, gives a better hint to the user that it's been skipped, rather than the default which shows it's successful - return -} +def prepare() { + stage('Prepare') { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/prepare") { + init_git() -cancel_previous_build() + if (env.DETERMINE_DOCKER_IMAGES == 'yes') { + sh( + script: "./tests/scripts/determine_docker_images.py ci_arm=${ci_arm} ci_cpu=${ci_cpu} ci_gpu=${ci_gpu} ci_hexagon=${ci_hexagon} ci_i386=${ci_i386} ci_lint=${ci_lint} ci_qemu=${ci_qemu} ci_wasm=${ci_wasm} ", + label: 'Decide whether to use tlcpack or tlcpackstaging for Docker images', + ) + // Pull image names from the results of should_rebuild_docker.py + ci_arm = sh( + script: "cat .docker-image-names/ci_arm", + label: "Find docker image name for ci_arm", + returnStdout: true, + ).trim() + ci_cpu = sh( + script: "cat .docker-image-names/ci_cpu", + label: "Find docker image name for ci_cpu", + returnStdout: true, + ).trim() + ci_gpu = sh( + script: "cat .docker-image-names/ci_gpu", + label: "Find docker image name for ci_gpu", + returnStdout: true, + ).trim() + ci_hexagon = sh( + script: "cat .docker-image-names/ci_hexagon", + label: "Find docker image name for ci_hexagon", + returnStdout: true, + ).trim() + ci_i386 = sh( + script: "cat .docker-image-names/ci_i386", + label: "Find docker image name for ci_i386", + returnStdout: true, + ).trim() + ci_lint = sh( + script: "cat .docker-image-names/ci_lint", + label: "Find docker image name for ci_lint", + returnStdout: true, + ).trim() + ci_qemu = sh( + script: "cat .docker-image-names/ci_qemu", + label: "Find docker image name for ci_qemu", + returnStdout: true, + ).trim() + ci_wasm = sh( + script: "cat .docker-image-names/ci_wasm", + label: "Find docker image name for ci_wasm", + returnStdout: true, + ).trim() + } + + ci_arm = params.ci_arm_param ?: ci_arm + ci_cpu = params.ci_cpu_param ?: ci_cpu + ci_gpu = params.ci_gpu_param ?: ci_gpu + ci_hexagon = params.ci_hexagon_param ?: ci_hexagon + ci_i386 = params.ci_i386_param ?: ci_i386 + ci_lint = params.ci_lint_param ?: ci_lint + ci_qemu = params.ci_qemu_param ?: ci_qemu + ci_wasm = params.ci_wasm_param ?: ci_wasm + + sh (script: """ + echo "Docker images being used in this build:" + echo " ci_arm = ${ci_arm}" + echo " ci_cpu = ${ci_cpu}" + echo " ci_gpu = ${ci_gpu}" + echo " ci_hexagon = ${ci_hexagon}" + echo " ci_i386 = ${ci_i386}" + echo " ci_lint = ${ci_lint}" + echo " ci_qemu = ${ci_qemu}" + echo " ci_wasm = ${ci_wasm}" + """, label: 'Docker image names') -stage('Prepare') { - node('CPU') { - // When something is provided in ci_*_param, use it, otherwise default with ci_* - ci_lint = params.ci_lint_param ?: ci_lint - ci_cpu = params.ci_cpu_param ?: ci_cpu - ci_gpu = params.ci_gpu_param ?: ci_gpu - ci_wasm = params.ci_wasm_param ?: ci_wasm - ci_i386 = params.ci_i386_param ?: ci_i386 - ci_qemu = params.ci_qemu_param ?: ci_qemu - ci_arm = params.ci_arm_param ?: ci_arm - - sh (script: """ - echo "Docker images being used in this build:" - echo " ci_lint = ${ci_lint}" - echo " ci_cpu = ${ci_cpu}" - echo " ci_gpu = ${ci_gpu}" - echo " ci_wasm = ${ci_wasm}" - echo " ci_i386 = ${ci_i386}" - echo " ci_qemu = ${ci_qemu}" - echo " ci_arm = ${ci_arm}" - """, label: 'Docker image names') - } -} - -stage('Sanity Check') { - timeout(time: max_time, unit: 'MINUTES') { - node('CPU') { - ws(per_exec_ws('tvm/sanity')) { - init_git() is_docs_only_build = sh ( returnStatus: true, script: './tests/scripts/git_change_docs.sh', @@ -205,59 +313,252 @@ stage('Sanity Check') { ) skip_ci = should_skip_ci(env.CHANGE_ID) skip_slow_tests = should_skip_slow_tests(env.CHANGE_ID) - sh ( - script: "${docker_run} ${ci_lint} ./tests/scripts/task_lint.sh", - label: 'Run lint', + rebuild_docker_images = sh ( + returnStatus: true, + script: './tests/scripts/git_change_docker.sh', + label: 'Check for any docker changes', ) + if (skip_ci) { + // Don't rebuild when skipping CI + rebuild_docker_images = false + } } } } } +def ecr_push(full_name) { + aws_account_id = sh( + returnStdout: true, + script: 'aws sts get-caller-identity | grep Account | cut -f4 -d\\"', + label: 'Get AWS ID' + ).trim() - -// Run make. First try to do an incremental make from a previous workspace in hope to -// accelerate the compilation. If something is wrong, clean the workspace and then -// build from scratch. -def make(docker_type, path, make_flag) { - timeout(time: max_time, unit: 'MINUTES') { - try { - cmake_build(docker_type, path, make_flag) - // always run cpp test when build - cpp_unittest(docker_type) - } catch (hudson.AbortException ae) { - // script exited due to user abort, directly throw instead of retry - if (ae.getMessage().contains('script returned exit code 143')) { - throw ae - } - echo 'Incremental compilation failed. Fall back to build from scratch' - sh ( - script: "${docker_run} ${docker_type} ./tests/scripts/task_clean.sh ${path}", - label: 'Clear old cmake workspace', + def ecr_name = "${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com/${full_name}" + try { + withEnv([ + "AWS_ACCOUNT_ID=${aws_account_id}", + 'AWS_DEFAULT_REGION=us-west-2', + "AWS_ECR_REPO=${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com"]) { + sh( + script: ''' + set -eux + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ECR_REPO + ''', + label: 'Log in to ECR' + ) + sh( + script: """ + set -x + docker tag ${full_name} \$AWS_ECR_REPO/${full_name} + docker push \$AWS_ECR_REPO/${full_name} + """, + label: 'Upload image to ECR' + ) + } + } finally { + withEnv([ + "AWS_ACCOUNT_ID=${aws_account_id}", + 'AWS_DEFAULT_REGION=us-west-2', + "AWS_ECR_REPO=${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com"]) { + sh( + script: 'docker logout $AWS_ECR_REPO', + label: 'Clean up login credentials' ) - cmake_build(docker_type, path, make_flag) - cpp_unittest(docker_type) } } + return ecr_name } -// pack libraries for later use -def pack_lib(name, libs) { - sh (script: """ - echo "Packing ${libs} into ${name}" - echo ${libs} | sed -e 's/,/ /g' | xargs md5sum - """, label: 'Stash libraries and show md5') - stash includes: libs, name: name +def ecr_pull(full_name) { + aws_account_id = sh( + returnStdout: true, + script: 'aws sts get-caller-identity | grep Account | cut -f4 -d\\"', + label: 'Get AWS ID' + ).trim() + + try { + withEnv([ + "AWS_ACCOUNT_ID=${aws_account_id}", + 'AWS_DEFAULT_REGION=us-west-2', + "AWS_ECR_REPO=${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com"]) { + sh( + script: ''' + set -eux + aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ECR_REPO + ''', + label: 'Log in to ECR' + ) + sh( + script: """ + set -eux + docker pull ${full_name} + """, + label: 'Pull image from ECR' + ) + } + } finally { + withEnv([ + "AWS_ACCOUNT_ID=${aws_account_id}", + 'AWS_DEFAULT_REGION=us-west-2', + "AWS_ECR_REPO=${aws_account_id}.dkr.ecr.us-west-2.amazonaws.com"]) { + sh( + script: 'docker logout $AWS_ECR_REPO', + label: 'Clean up login credentials' + ) + } + } } -// unpack libraries saved before -def unpack_lib(name, libs) { - unstash name - sh (script: """ - echo "Unpacked ${libs} from ${name}" - echo ${libs} | sed -e 's/,/ /g' | xargs md5sum - """, label: 'Unstash libraries and show md5') +def build_image(image_name) { + hash = sh( + returnStdout: true, + script: 'git log -1 --format=\'%h\'' + ).trim() + def full_name = "${image_name}:${env.BRANCH_NAME}-${hash}-${env.BUILD_NUMBER}" + sh( + script: "${docker_build} ${image_name} --spec ${full_name}", + label: 'Build docker image' + ) + return ecr_push(full_name) } + +def build_docker_images() { + stage('Docker Image Build') { + parallel( + 'ci_arm': { + node('ARM') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_arm = build_image('ci_arm') + build_image('ci_arm') + } + } + }, + 'ci_cpu': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_cpu = build_image('ci_cpu') + build_image('ci_cpu') + } + } + }, + 'ci_gpu': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_gpu = build_image('ci_gpu') + build_image('ci_gpu') + } + } + }, + 'ci_hexagon': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_hexagon = build_image('ci_hexagon') + build_image('ci_hexagon') + } + } + }, + 'ci_i386': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_i386 = build_image('ci_i386') + build_image('ci_i386') + } + } + }, + 'ci_lint': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_lint = build_image('ci_lint') + build_image('ci_lint') + } + } + }, + 'ci_qemu': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_qemu = build_image('ci_qemu') + build_image('ci_qemu') + } + } + }, + 'ci_wasm': { + node('CPU') { + timeout(time: max_time, unit: 'MINUTES') { + init_git() + // We're purposefully not setting the built image here since they + // are not yet being uploaded to tlcpack + // ci_wasm = build_image('ci_wasm') + build_image('ci_wasm') + } + } + }, + ) + } +} +def lint() { + stage('Lint') { + parallel( + 'Lint 1 of 2': { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/lint") { + docker_init(ci_lint) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=0'], { + sh ( + script: "${docker_run} ${ci_lint} ./tests/scripts/task_lint.sh", + label: 'Run lint', + ) + }) + } + } + } + }, + 'Lint 2 of 2': { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/lint") { + docker_init(ci_lint) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=1'], { + sh ( + script: "${docker_run} ${ci_lint} ./tests/scripts/task_lint.sh", + label: 'Run lint', + ) + }) + } + } + } + }, + ) + } +} def ci_setup(image) { sh ( script: "${docker_run} ${image} ./tests/scripts/task_ci_setup.sh", @@ -281,48 +582,137 @@ def fsim_test(image) { def cmake_build(image, path, make_flag) { sh ( - script: "${docker_run} ${image} ./tests/scripts/task_build.py --num-executors ${CI_NUM_EXECUTORS} --sccache-bucket tvm-sccache-prod", + script: "${docker_run} --env CI_NUM_EXECUTORS ${image} ./tests/scripts/task_build.py --sccache-bucket tvm-sccache-prod", label: 'Run cmake build', ) } def cpp_unittest(image) { sh ( - script: "${docker_run} ${image} ./tests/scripts/task_cpp_unittest.sh", + script: "${docker_run} --env CI_NUM_EXECUTORS ${image} ./tests/scripts/task_cpp_unittest.sh", label: 'Build and run C++ tests', ) } + +def add_microtvm_permissions() { + sh( + script: 'find build/microtvm_template_projects -type f | grep qemu-hack | xargs chmod +x', + label: 'Add execute permissions for microTVM files', + ) +} + +def add_hexagon_permissions() { + sh( + script: 'find build/hexagon_api_output -type f | xargs chmod +x', + label: 'Add execute permissions for hexagon files', + ) +} + +// Run make. First try to do an incremental make from a previous workspace in hope to +// accelerate the compilation. If something is wrong, clean the workspace and then +// build from scratch. +def make(docker_type, path, make_flag) { + timeout(time: max_time, unit: 'MINUTES') { + try { + cmake_build(docker_type, path, make_flag) + } catch (hudson.AbortException ae) { + // script exited due to user abort, directly throw instead of retry + if (ae.getMessage().contains('script returned exit code 143')) { + throw ae + } + echo 'Incremental compilation failed. Fall back to build from scratch' + sh ( + script: "${docker_run} ${docker_type} ./tests/scripts/task_clean.sh ${path}", + label: 'Clear old cmake workspace', + ) + cmake_build(docker_type, path, make_flag) + } + } +} + + +def build() { stage('Build') { environment { SKIP_SLOW_TESTS = "${skip_slow_tests}" } - parallel 'BUILD: GPU': { + parallel( + 'BUILD: GPU': { if (!skip_ci) { - node('GPUBUILD') { - ws(per_exec_ws('tvm/build-gpu')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-gpu") { + docker_init(ci_gpu) init_git() - sh "${docker_run} ${ci_gpu} ./tests/scripts/task_config_build_gpu.sh" - make(ci_gpu, 'build', '-j2') - pack_lib('gpu', tvm_multilib) + sh "${docker_run} --no-gpu ${ci_gpu} ./tests/scripts/task_config_build_gpu.sh build" + make("${ci_gpu} --no-gpu", 'build', '-j2') + sh( + script: """ + set -eux + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/gpu/build/libtvm.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress build/libvta_fsim.so s3://${s3_prefix}/gpu/build/libvta_fsim.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/gpu/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/gpu/build/config.cmake + aws s3 cp --no-progress build/microtvm_template_projects s3://${s3_prefix}/gpu/build/microtvm_template_projects --recursive + """, + label: 'Upload artifacts to S3', + ) + + // compiler test - sh "${docker_run} ${ci_gpu} ./tests/scripts/task_config_build_gpu_other.sh" - make(ci_gpu, 'build2', '-j2') + sh "${docker_run} --no-gpu ${ci_gpu} ./tests/scripts/task_config_build_gpu_other.sh build2" + make("${ci_gpu} --no-gpu", 'build2', '-j2') + sh( + script: """ + set -eux + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/gpu2/build/libtvm.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress build/libvta_fsim.so s3://${s3_prefix}/gpu2/build/libvta_fsim.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/gpu2/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/gpu2/build/config.cmake + """, + label: 'Upload artifacts to S3', + ) + } } } }, 'BUILD: CPU': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/build-cpu')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-cpu") { + docker_init(ci_cpu) init_git() sh ( - script: "${docker_run} ${ci_cpu} ./tests/scripts/task_config_build_cpu.sh", + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_config_build_cpu.sh build", label: 'Create CPU cmake config', ) make(ci_cpu, 'build', '-j2') - pack_lib('cpu', tvm_multilib_tsim) + sh( + script: """ + set -eux + md5sum build/libvta_tsim.so + aws s3 cp --no-progress build/libvta_tsim.so s3://${s3_prefix}/cpu/build/libvta_tsim.so + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/cpu/build/libtvm.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress build/libvta_fsim.so s3://${s3_prefix}/cpu/build/libvta_fsim.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/cpu/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/cpu/build/config.cmake + """, + label: 'Upload artifacts to S3', + ) + timeout(time: max_time, unit: 'MINUTES') { ci_setup(ci_cpu) // sh "${docker_run} ${ci_cpu} ./tests/scripts/task_golang.sh" @@ -337,14 +727,16 @@ stage('Build') { }, 'BUILD: WASM': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/build-wasm')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-wasm") { + docker_init(ci_wasm) init_git() sh ( - script: "${docker_run} ${ci_wasm} ./tests/scripts/task_config_build_wasm.sh", + script: "${docker_run} ${ci_wasm} ./tests/scripts/task_config_build_wasm.sh build", label: 'Create WASM cmake config', ) make(ci_wasm, 'build', '-j2') + cpp_unittest(ci_wasm) timeout(time: max_time, unit: 'MINUTES') { ci_setup(ci_wasm) sh ( @@ -360,15 +752,32 @@ stage('Build') { }, 'BUILD: i386': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/build-i386')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-i386") { + docker_init(ci_i386) init_git() sh ( - script: "${docker_run} ${ci_i386} ./tests/scripts/task_config_build_i386.sh", + script: "${docker_run} ${ci_i386} ./tests/scripts/task_config_build_i386.sh build", label: 'Create i386 cmake config', ) make(ci_i386, 'build', '-j2') - pack_lib('i386', tvm_multilib_tsim) + sh( + script: """ + set -eux + md5sum build/libvta_tsim.so + aws s3 cp --no-progress build/libvta_tsim.so s3://${s3_prefix}/i386/build/libvta_tsim.so + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/i386/build/libtvm.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress build/libvta_fsim.so s3://${s3_prefix}/i386/build/libvta_fsim.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/i386/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/i386/build/config.cmake + """, + label: 'Upload artifacts to S3', + ) + } } } else { @@ -377,15 +786,30 @@ stage('Build') { }, 'BUILD: arm': { if (!skip_ci && is_docs_only_build != 1) { - node('ARM') { - ws(per_exec_ws('tvm/build-arm')) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-arm") { + docker_init(ci_arm) init_git() sh ( - script: "${docker_run} ${ci_arm} ./tests/scripts/task_config_build_arm.sh", + script: "${docker_run} ${ci_arm} ./tests/scripts/task_config_build_arm.sh build", label: 'Create ARM cmake config', ) make(ci_arm, 'build', '-j4') - pack_lib('arm', tvm_multilib) + sh( + script: """ + set -eux + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/arm/build/libtvm.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress build/libvta_fsim.so s3://${s3_prefix}/arm/build/libvta_fsim.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/arm/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/arm/build/config.cmake + """, + label: 'Upload artifacts to S3', + ) + } } } else { @@ -394,29 +818,29 @@ stage('Build') { }, 'BUILD: QEMU': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/build-qemu')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-qemu") { + docker_init(ci_qemu) init_git() sh ( - script: "${docker_run} ${ci_qemu} ./tests/scripts/task_config_build_qemu.sh", + script: "${docker_run} ${ci_qemu} ./tests/scripts/task_config_build_qemu.sh build", label: 'Create QEMU cmake config', ) - try { - make(ci_qemu, 'build', '-j2') - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_qemu) - sh ( - script: "${docker_run} ${ci_qemu} ./tests/scripts/task_python_microtvm.sh", - label: 'Run microTVM tests', - ) - sh ( - script: "${docker_run} ${ci_qemu} ./tests/scripts/task_demo_microtvm.sh", - label: 'Run microTVM demos', - ) - } - } finally { - junit 'build/pytest-results/*.xml' - } + make(ci_qemu, 'build', '-j2') + sh( + script: """ + set -eux + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/qemu/build/libtvm.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/qemu/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/qemu/build/config.cmake + aws s3 cp --no-progress build/microtvm_template_projects s3://${s3_prefix}/qemu/build/microtvm_template_projects --recursive + """, + label: 'Upload artifacts to S3', + ) + } } } else { @@ -425,50 +849,149 @@ stage('Build') { }, 'BUILD: Hexagon': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/build-hexagon')) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/build-hexagon") { + docker_init(ci_hexagon) init_git() sh ( - script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_config_build_hexagon.sh", + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_config_build_hexagon.sh build", label: 'Create Hexagon cmake config', ) - try { - make(ci_hexagon, 'build', '-j2') - sh ( - script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_build_hexagon_api.sh", - label: 'Build Hexagon API', - ) - sh ( - script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", - label: 'Run Hexagon tests', - ) - sh ( - script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon_simulator.sh", - label: 'Run Hexagon tests on simulator', - ) - } finally { - junit 'build/pytest-results/*.xml' - } + make(ci_hexagon, 'build', '-j2') + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_build_hexagon_api.sh", + label: 'Build Hexagon API', + ) + sh( + script: """ + set -eux + md5sum build/libtvm.so + aws s3 cp --no-progress build/libtvm.so s3://${s3_prefix}/hexagon/build/libtvm.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress build/libtvm_runtime.so s3://${s3_prefix}/hexagon/build/libtvm_runtime.so + md5sum build/config.cmake + aws s3 cp --no-progress build/config.cmake s3://${s3_prefix}/hexagon/build/config.cmake + aws s3 cp --no-progress build/hexagon_api_output s3://${s3_prefix}/hexagon/build/hexagon_api_output --recursive + """, + label: 'Upload artifacts to S3', + ) + } } } else { Utils.markStageSkippedForConditional('BUILD: Hexagon') } - } + }, + ) +} } -stage('Test') { - environment { - SKIP_SLOW_TESTS = "${skip_slow_tests}" +// We have to do this whacky split of the code from where it's used since the +// JVM limits method length to 64k and we easily exceed that with all this +// autogenerated code. This makes it so each test step is in its own method so +// that each individual method isn't too big. + +def shard_run_unittest_GPU_1_of_3() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=3', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu2/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu2/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu2/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu2/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + cpp_unittest(ci_gpu) + + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + cpp_unittest(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_unittest_gpuonly.sh", + label: 'Run Python GPU unit tests', + ) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_integration_gpuonly.sh", + label: 'Run Python GPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('unittest: GPU 1 of 3') } - parallel 'unittest: GPU': { - if (!skip_ci && is_docs_only_build != 1) { - node('TensorCore') { - ws(per_exec_ws('tvm/ut-python-gpu')) { - try { - init_git() - unpack_lib('gpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { +} + +def shard_run_unittest_GPU_2_of_3() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=3', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + ci_setup(ci_gpu) sh ( script: "${docker_run} ${ci_gpu} ./tests/scripts/task_java_unittest.sh", @@ -482,99 +1005,1806 @@ stage('Test') { script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_integration_gpuonly.sh", label: 'Run Python GPU integration tests', ) - } - } finally { - junit 'build/pytest-results/*.xml' + }) } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' } } - } else { - Utils.markStageSkippedForConditional('unittest: GPU') } - }, - 'integration: CPU': { - if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/ut-python-cpu')) { - try { - init_git() - unpack_lib('cpu', tvm_multilib_tsim) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_cpu) + } else { + Utils.markStageSkippedForConditional('unittest: GPU 2 of 3') + } +} + +def shard_run_unittest_GPU_3_of_3() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=3', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) sh ( - script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", - label: 'Run CPU integration tests', + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_unittest_gpuonly.sh", + label: 'Run Python GPU unit tests', ) - } - } finally { - junit 'build/pytest-results/*.xml' - } - } - } - } else { - Utils.markStageSkippedForConditional('integration: CPU') + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_integration_gpuonly.sh", + label: 'Run Python GPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('unittest: GPU 3 of 3') + } +} + + +def shard_run_integration_CPU_1_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 1 of 6') + } +} + +def shard_run_integration_CPU_2_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 2 of 6') + } +} + +def shard_run_integration_CPU_3_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 3 of 6') + } +} + +def shard_run_integration_CPU_4_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 4 of 6') + } +} + +def shard_run_integration_CPU_5_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=4'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 5 of 6') + } +} + +def shard_run_integration_CPU_6_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-cpu") { + try { + docker_init(ci_cpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=cpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=5'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: CPU 6 of 6') + } +} + + +def shard_run_python_i386_1_of_5() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-i386") { + try { + docker_init(ci_i386) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=i386', + 'TVM_NUM_SHARDS=5', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_i386) + cpp_unittest(ci_i386) + python_unittest(ci_i386) + sh ( + script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", + label: 'Run i386 integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('python: i386 1 of 5') + } +} + +def shard_run_python_i386_2_of_5() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-i386") { + try { + docker_init(ci_i386) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=i386', + 'TVM_NUM_SHARDS=5', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_i386) + python_unittest(ci_i386) + sh ( + script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", + label: 'Run i386 integration tests', + ) + fsim_test(ci_i386) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('python: i386 2 of 5') + } +} + +def shard_run_python_i386_3_of_5() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-i386") { + try { + docker_init(ci_i386) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=i386', + 'TVM_NUM_SHARDS=5', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_i386) + python_unittest(ci_i386) + sh ( + script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", + label: 'Run i386 integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('python: i386 3 of 5') + } +} + +def shard_run_python_i386_4_of_5() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-i386") { + try { + docker_init(ci_i386) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=i386', + 'TVM_NUM_SHARDS=5', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_i386) + python_unittest(ci_i386) + sh ( + script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", + label: 'Run i386 integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('python: i386 4 of 5') + } +} + +def shard_run_python_i386_5_of_5() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/integration-python-i386") { + try { + docker_init(ci_i386) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=i386', + 'TVM_NUM_SHARDS=5', + 'TVM_SHARD_INDEX=4'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/i386/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_i386) + python_unittest(ci_i386) + sh ( + script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", + label: 'Run i386 integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('python: i386 5 of 5') + } +} + + +def shard_run_test_Hexagon_1_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + cpp_unittest(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 1 of 7') + } +} + +def shard_run_test_Hexagon_2_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 2 of 7') + } +} + +def shard_run_test_Hexagon_3_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 3 of 7') + } +} + +def shard_run_test_Hexagon_4_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 4 of 7') + } +} + +def shard_run_test_Hexagon_5_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=4'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 5 of 7') + } +} + +def shard_run_test_Hexagon_6_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=5'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 6 of 7') + } +} + +def shard_run_test_Hexagon_7_of_7() { + if (!skip_ci && is_docs_only_build != 1) { + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-hexagon") { + try { + docker_init(ci_hexagon) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=hexagon', + 'TVM_NUM_SHARDS=7', + 'TVM_SHARD_INDEX=6'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/hexagon/build/hexagon_api_output build/hexagon_api_output --recursive + """, + label: 'Download artifacts from S3', + ) + + add_hexagon_permissions() + ci_setup(ci_hexagon) + sh ( + script: "${docker_run} ${ci_hexagon} ./tests/scripts/task_python_hexagon.sh", + label: 'Run Hexagon tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('test: Hexagon 7 of 7') + } +} + + +def shard_run_integration_aarch64_1_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + python_unittest(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: aarch64 1 of 4') + } +} + +def shard_run_integration_aarch64_2_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + python_unittest(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: aarch64 2 of 4') + } +} + +def shard_run_integration_aarch64_3_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + python_unittest(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: aarch64 3 of 4') + } +} + +def shard_run_integration_aarch64_4_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + python_unittest(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_integration.sh", + label: 'Run CPU integration tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('integration: aarch64 4 of 4') + } +} + + +def shard_run_topi_GPU_1_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/topi-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_topi.sh", + label: 'Run TOPI tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('topi: GPU 1 of 4') + } +} + +def shard_run_topi_GPU_2_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/topi-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_topi.sh", + label: 'Run TOPI tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('topi: GPU 2 of 4') + } +} + +def shard_run_topi_GPU_3_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/topi-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_topi.sh", + label: 'Run TOPI tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('topi: GPU 3 of 4') + } +} + +def shard_run_topi_GPU_4_of_4() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/topi-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=4', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_topi.sh", + label: 'Run TOPI tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('topi: GPU 4 of 4') + } +} + + +def shard_run_frontend_GPU_1_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('frontend: GPU 1 of 6') + } +} + +def shard_run_frontend_GPU_2_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('frontend: GPU 2 of 6') + } +} + +def shard_run_frontend_GPU_3_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=2'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('frontend: GPU 3 of 6') + } +} + +def shard_run_frontend_GPU_4_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=3'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) + sh ( + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } } - }, - 'unittest: CPU': { - if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/ut-python-cpu')) { - try { - init_git() - unpack_lib('cpu', tvm_multilib_tsim) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_cpu) - python_unittest(ci_cpu) - fsim_test(ci_cpu) + } else { + Utils.markStageSkippedForConditional('frontend: GPU 4 of 6') + } +} + +def shard_run_frontend_GPU_5_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=4'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) sh ( - script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_vta_tsim.sh", - label: 'Run VTA tests in TSIM', + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', ) - } - } finally { - junit 'build/pytest-results/*.xml' + }) } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' } } - } else { - Utils.markStageSkippedForConditional('unittest: CPU') } - }, - 'python3: i386': { - if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/ut-python-i386')) { - try { - init_git() - unpack_lib('i386', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_i386) - python_unittest(ci_i386) + } else { + Utils.markStageSkippedForConditional('frontend: GPU 5 of 6') + } +} + +def shard_run_frontend_GPU_6_of_6() { + if (!skip_ci && is_docs_only_build != 1) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-gpu") { + try { + docker_init(ci_gpu) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=gpu', + 'TVM_NUM_SHARDS=6', + 'TVM_SHARD_INDEX=5'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_gpu) sh ( - script: "${docker_run} ${ci_i386} ./tests/scripts/task_python_integration_i386only.sh", - label: 'Run i386 integration tests', + script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh", + label: 'Run Python frontend tests', ) - fsim_test(ci_i386) - } - } finally { - junit 'build/pytest-results/*.xml' + }) } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' } } - } else { - Utils.markStageSkippedForConditional('python3: i386') } - }, - 'python3: arm': { - if (!skip_ci && is_docs_only_build != 1) { - node('ARM') { - ws(per_exec_ws('tvm/ut-python-arm')) { - try { - init_git() - unpack_lib('arm', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { + } else { + Utils.markStageSkippedForConditional('frontend: GPU 6 of 6') + } +} + + +def shard_run_topi_aarch64_1_of_2() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + ci_setup(ci_arm) - python_unittest(ci_arm) + cpp_unittest(ci_arm) sh ( script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_arm_compute_library.sh", label: 'Run test_arm_compute_lib test', @@ -583,102 +2813,459 @@ stage('Test') { script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_topi.sh", label: 'Run TOPI tests', ) - // sh "${docker_run} ${ci_arm} ./tests/scripts/task_python_integration.sh" - } - } finally { - junit 'build/pytest-results/*.xml' + }) } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' } } - } else { - Utils.markStageSkippedForConditional('python3: arm') } - }, - 'topi: GPU': { - if (!skip_ci && is_docs_only_build != 1) { - node('GPU') { - ws(per_exec_ws('tvm/topi-python-gpu')) { - try { - init_git() - unpack_lib('gpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_gpu) + } else { + Utils.markStageSkippedForConditional('topi: aarch64 1 of 2') + } +} + +def shard_run_topi_aarch64_2_of_2() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) sh ( - script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_topi.sh", + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_arm_compute_library.sh", + label: 'Run test_arm_compute_lib test', + ) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_topi.sh", label: 'Run TOPI tests', ) - } - } finally { - junit 'build/pytest-results/*.xml' + }) } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('topi: aarch64 2 of 2') + } +} + + +def shard_run_frontend_aarch64_1_of_2() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=0'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_frontend_cpu.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' + } + } + } + } else { + Utils.markStageSkippedForConditional('frontend: aarch64 1 of 2') + } +} + +def shard_run_frontend_aarch64_2_of_2() { + if (!skip_ci && is_docs_only_build != 1) { + node('ARM-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-arm") { + try { + docker_init(ci_arm) + init_git() + timeout(time: max_time, unit: 'MINUTES') { + withEnv([ + 'PLATFORM=arm', + 'TVM_NUM_SHARDS=2', + 'TVM_SHARD_INDEX=1'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/arm/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_arm) + sh ( + script: "${docker_run} ${ci_arm} ./tests/scripts/task_python_frontend_cpu.sh", + label: 'Run Python frontend tests', + ) + }) + } + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', + ) + + junit 'build/pytest-results/*.xml' } } - } else { - Utils.markStageSkippedForConditional('topi: GPU') } + } else { + Utils.markStageSkippedForConditional('frontend: aarch64 2 of 2') + } +} + + + +def test() { +stage('Test') { + environment { + SKIP_SLOW_TESTS = "${skip_slow_tests}" + } + parallel( + 'unittest: GPU 1 of 3': { + shard_run_unittest_GPU_1_of_3() + }, + 'unittest: GPU 2 of 3': { + shard_run_unittest_GPU_2_of_3() + }, + 'unittest: GPU 3 of 3': { + shard_run_unittest_GPU_3_of_3() + }, + 'integration: CPU 1 of 6': { + shard_run_integration_CPU_1_of_6() + }, + 'integration: CPU 2 of 6': { + shard_run_integration_CPU_2_of_6() + }, + 'integration: CPU 3 of 6': { + shard_run_integration_CPU_3_of_6() + }, + 'integration: CPU 4 of 6': { + shard_run_integration_CPU_4_of_6() + }, + 'integration: CPU 5 of 6': { + shard_run_integration_CPU_5_of_6() + }, + 'integration: CPU 6 of 6': { + shard_run_integration_CPU_6_of_6() + }, + 'python: i386 1 of 5': { + shard_run_python_i386_1_of_5() + }, + 'python: i386 2 of 5': { + shard_run_python_i386_2_of_5() + }, + 'python: i386 3 of 5': { + shard_run_python_i386_3_of_5() + }, + 'python: i386 4 of 5': { + shard_run_python_i386_4_of_5() + }, + 'python: i386 5 of 5': { + shard_run_python_i386_5_of_5() + }, + 'test: Hexagon 1 of 7': { + shard_run_test_Hexagon_1_of_7() + }, + 'test: Hexagon 2 of 7': { + shard_run_test_Hexagon_2_of_7() + }, + 'test: Hexagon 3 of 7': { + shard_run_test_Hexagon_3_of_7() + }, + 'test: Hexagon 4 of 7': { + shard_run_test_Hexagon_4_of_7() + }, + 'test: Hexagon 5 of 7': { + shard_run_test_Hexagon_5_of_7() + }, + 'test: Hexagon 6 of 7': { + shard_run_test_Hexagon_6_of_7() + }, + 'test: Hexagon 7 of 7': { + shard_run_test_Hexagon_7_of_7() + }, + 'integration: aarch64 1 of 4': { + shard_run_integration_aarch64_1_of_4() + }, + 'integration: aarch64 2 of 4': { + shard_run_integration_aarch64_2_of_4() + }, + 'integration: aarch64 3 of 4': { + shard_run_integration_aarch64_3_of_4() + }, + 'integration: aarch64 4 of 4': { + shard_run_integration_aarch64_4_of_4() + }, + 'topi: GPU 1 of 4': { + shard_run_topi_GPU_1_of_4() + }, + 'topi: GPU 2 of 4': { + shard_run_topi_GPU_2_of_4() + }, + 'topi: GPU 3 of 4': { + shard_run_topi_GPU_3_of_4() }, - 'frontend: GPU 1': { + 'topi: GPU 4 of 4': { + shard_run_topi_GPU_4_of_4() + }, + 'frontend: GPU 1 of 6': { + shard_run_frontend_GPU_1_of_6() + }, + 'frontend: GPU 2 of 6': { + shard_run_frontend_GPU_2_of_6() + }, + 'frontend: GPU 3 of 6': { + shard_run_frontend_GPU_3_of_6() + }, + 'frontend: GPU 4 of 6': { + shard_run_frontend_GPU_4_of_6() + }, + 'frontend: GPU 5 of 6': { + shard_run_frontend_GPU_5_of_6() + }, + 'frontend: GPU 6 of 6': { + shard_run_frontend_GPU_6_of_6() + }, + 'topi: aarch64 1 of 2': { + shard_run_topi_aarch64_1_of_2() + }, + 'topi: aarch64 2 of 2': { + shard_run_topi_aarch64_2_of_2() + }, + 'frontend: aarch64 1 of 2': { + shard_run_frontend_aarch64_1_of_2() + }, + 'frontend: aarch64 2 of 2': { + shard_run_frontend_aarch64_2_of_2() + }, + 'unittest: CPU': { if (!skip_ci && is_docs_only_build != 1) { - node('GPU') { - ws(per_exec_ws('tvm/frontend-python-gpu')) { - try { - init_git() - unpack_lib('gpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_gpu) - sh ( - script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh 1", - label: 'Run Python frontend tests (shard 1)', + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/ut-python-cpu") { + timeout(time: max_time, unit: 'MINUTES') { + try { + docker_init(ci_cpu) + init_git() + withEnv(['PLATFORM=cpu'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_tsim.so build/libvta_tsim.so + md5sum build/libvta_tsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + cpp_unittest(ci_cpu) + python_unittest(ci_cpu) + fsim_test(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_vta_tsim.sh", + label: 'Run VTA tests in TSIM', + ) + }) + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', ) + + junit 'build/pytest-results/*.xml' } - } finally { - junit 'build/pytest-results/*.xml' } } } - } else { - Utils.markStageSkippedForConditional('frontend: GPU 1') + } else { + Utils.markStageSkippedForConditional('unittest: CPU') } }, - 'frontend: GPU 2': { + 'test: QEMU': { if (!skip_ci && is_docs_only_build != 1) { - node('GPU') { - ws(per_exec_ws('tvm/frontend-python-gpu')) { - try { - init_git() - unpack_lib('gpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_gpu) - sh ( - script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_frontend.sh 2", - label: 'Run Python frontend tests (shard 2)', + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/test-qemu") { + timeout(time: max_time, unit: 'MINUTES') { + try { + docker_init(ci_qemu) + init_git() + withEnv(['PLATFORM=qemu'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/qemu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/qemu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/qemu/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/qemu/build/microtvm_template_projects build/microtvm_template_projects --recursive + """, + label: 'Download artifacts from S3', + ) + + add_microtvm_permissions() + ci_setup(ci_qemu) + cpp_unittest(ci_qemu) + sh ( + script: "${docker_run} ${ci_qemu} ./tests/scripts/task_python_microtvm.sh", + label: 'Run microTVM tests', + ) + sh ( + script: "${docker_run} ${ci_qemu} ./tests/scripts/task_demo_microtvm.sh", + label: 'Run microTVM demos', + ) + }) + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', ) + + junit 'build/pytest-results/*.xml' } - } finally { - junit 'build/pytest-results/*.xml' } } } - } else { - Utils.markStageSkippedForConditional('frontend: GPU 2') + } else { + Utils.markStageSkippedForConditional('test: QEMU') } }, 'frontend: CPU': { if (!skip_ci && is_docs_only_build != 1) { - node('CPU') { - ws(per_exec_ws('tvm/frontend-python-cpu')) { - try { - init_git() - unpack_lib('cpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { - ci_setup(ci_cpu) - sh ( - script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_frontend_cpu.sh", - label: 'Run Python frontend tests', + node('CPU-SMALL') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/frontend-python-cpu") { + timeout(time: max_time, unit: 'MINUTES') { + try { + docker_init(ci_cpu) + init_git() + withEnv(['PLATFORM=cpu'], { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/cpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + """, + label: 'Download artifacts from S3', + ) + + ci_setup(ci_cpu) + sh ( + script: "${docker_run} ${ci_cpu} ./tests/scripts/task_python_frontend_cpu.sh", + label: 'Run Python frontend tests', + ) + }) + } finally { + sh( + script: """ + set -eux + aws s3 cp --no-progress build/pytest-results s3://${s3_prefix}/pytest-results --recursive + """, + label: 'Upload JUnits to S3', ) + + junit 'build/pytest-results/*.xml' } - } finally { - junit 'build/pytest-results/*.xml' } } } @@ -688,25 +3275,54 @@ stage('Test') { }, 'docs: GPU': { if (!skip_ci) { - node('TensorCore') { - ws(per_exec_ws('tvm/docs-python-gpu')) { + node('GPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/docs-python-gpu") { + docker_init(ci_gpu) init_git() - unpack_lib('gpu', tvm_multilib) - timeout(time: max_time, unit: 'MINUTES') { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm.so build/libtvm.so + md5sum build/libtvm.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libvta_fsim.so build/libvta_fsim.so + md5sum build/libvta_fsim.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/libtvm_runtime.so build/libtvm_runtime.so + md5sum build/libtvm_runtime.so + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/config.cmake build/config.cmake + md5sum build/config.cmake + aws s3 cp --no-progress s3://${s3_prefix}/gpu/build/microtvm_template_projects build/microtvm_template_projects --recursive + """, + label: 'Download artifacts from S3', + ) + + add_microtvm_permissions() + timeout(time: 180, unit: 'MINUTES') { ci_setup(ci_gpu) sh ( script: "${docker_run} ${ci_gpu} ./tests/scripts/task_python_docs.sh", label: 'Build docs', ) } - pack_lib('docs', 'docs.tgz') + sh( + script: """ + set -eux + md5sum docs.tgz + aws s3 cp --no-progress docs.tgz s3://${s3_prefix}/docs/docs.tgz + """, + label: 'Upload artifacts to S3', + ) + + sh( + script: "aws s3 cp --no-progress _docs s3://${s3_prefix}/docs --recursive", + label: 'Upload docs to S3', + ) } } } - } + }, + ) } - -/* +}/* stage('Build packages') { parallel 'conda CPU': { node('CPU') { @@ -724,14 +3340,136 @@ stage('Build packages') { } */ -stage('Deploy') { - node('doc') { - ws(per_exec_ws('tvm/deploy-docs')) { - if (env.BRANCH_NAME == 'main') { - unpack_lib('docs', 'docs.tgz') - sh 'cp docs.tgz /var/docs/docs.tgz' - sh 'tar xf docs.tgz -C /var/docs' + +def update_docker(ecr_image, hub_image) { + if (!ecr_image.contains("amazonaws.com")) { + sh("echo Skipping '${ecr_image}' since it doesn't look like an ECR image") + return + } + docker_init(ecr_image) + sh( + script: """ + set -eux + docker tag \ + ${ecr_image} \ + ${hub_image} + docker push ${hub_image} + """, + label: "Update ${hub_image} on Docker Hub", + ) +} + +def deploy_docs() { + // Note: This code must stay in the Jenkinsfile to ensure that it runs + // from a trusted context only + sh( + script: ''' + set -eux + rm -rf tvm-site + git clone -b $DOCS_DEPLOY_BRANCH --depth=1 https://github.com/apache/tvm-site + cd tvm-site + git status + git checkout -B $DOCS_DEPLOY_BRANCH + + git ls-tree HEAD docs/ --name-only | grep -vP '^docs/v\\d' | xargs rm -rf + mkdir -p docs + tar xf ../docs.tgz -C docs + COMMIT=$(cat docs/commit_hash) + git add . + git config user.name tvm-bot + git config user.email 95660001+tvm-bot@users.noreply.github.com + git commit -m"deploying docs (apache/tvm@$COMMIT)" + git status + ''', + label: 'Unpack docs and update tvm-site' + ) + + withCredentials([string( + credentialsId: 'docs-push-token', + variable: 'GITHUB_TOKEN', + )]) { + sh( + script: ''' + cd tvm-site + git remote add deploy https://$GITHUB_TOKEN:x-oauth-basic@github.com/apache/tvm-site.git + git push deploy $DOCS_DEPLOY_BRANCH + ''', + label: 'Upload docs to apache/tvm-site' + ) + } +} + + +def deploy() { + stage('Deploy') { + if (env.BRANCH_NAME == 'main' && env.DOCS_DEPLOY_ENABLED == 'yes') { + node('CPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/deploy-docs") { + sh( + script: """ + set -eux + aws s3 cp --no-progress s3://${s3_prefix}/docs/docs.tgz docs.tgz + md5sum docs.tgz + """, + label: 'Download artifacts from S3', + ) + + deploy_docs() + } + } + } + if (env.BRANCH_NAME == 'main' && env.DEPLOY_DOCKER_IMAGES == 'yes' && rebuild_docker_images && upstream_revision != null) { + node('CPU') { + ws("workspace/exec_${env.EXECUTOR_NUMBER}/tvm/deploy-docker") { + try { + withCredentials([string( + credentialsId: 'dockerhub-tlcpackstaging-key', + variable: 'DOCKERHUB_KEY', + )]) { + sh( + script: 'docker login -u tlcpackstaging -p ${DOCKERHUB_KEY}', + label: 'Log in to Docker Hub', + ) + } + def date_Ymd_HMS = sh( + script: 'python3 -c \'import datetime; print(datetime.datetime.now().strftime("%Y%m%d-%H%M%S"))\'', + label: 'Determine date', + returnStdout: true, + ).trim() + def tag = "${date_Ymd_HMS}-${upstream_revision.substring(0, 8)}" + update_docker(ci_arm, "tlcpackstaging/ci_arm:${tag}") + update_docker(ci_cpu, "tlcpackstaging/ci_cpu:${tag}") + update_docker(ci_gpu, "tlcpackstaging/ci_gpu:${tag}") + update_docker(ci_hexagon, "tlcpackstaging/ci_hexagon:${tag}") + update_docker(ci_i386, "tlcpackstaging/ci_i386:${tag}") + update_docker(ci_lint, "tlcpackstaging/ci_lint:${tag}") + update_docker(ci_qemu, "tlcpackstaging/ci_qemu:${tag}") + update_docker(ci_wasm, "tlcpackstaging/ci_wasm:${tag}") + } finally { + sh( + script: 'docker logout', + label: 'Clean up login credentials' + ) + } + } } } } } + + +cancel_previous_build() + +prepare() + +if (rebuild_docker_images) { + build_docker_images() +} + +lint() + +build() + +test() + +deploy() diff --git a/KEYS b/KEYS index a819d8f3bdda..41a620e796bc 100644 --- a/KEYS +++ b/KEYS @@ -416,3 +416,51 @@ A1PPxm4/KsXX/IZZOuM/tlT0vAahQsvXMNUVMg7v/PWuB6V47UdenKpXd10oloF7 MMtVW5sxG8OoBpUIhJUCtYTlwGCyGWSR7+rsHSR2HydLk1RWcYNI3XgJ0ng= =+gLd -----END PGP PUBLIC KEY BLOCK----- +pub rsa3072 2022-07-12 [SC] [expires: 2024-07-11] + B3C6A14C13B8C6727BC2FD2F07FA463F1C926F48 +uid [ultimate] David Riazati +sig 3 07FA463F1C926F48 2022-07-12 David Riazati +sub rsa3072 2022-07-12 [E] [expires: 2024-07-11] +sig 07FA463F1C926F48 2022-07-12 David Riazati + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGNBGLNzqUBDAC9p7OMYiiVHTQIIUr1/fDXaJ3sJ0rlkaPQJpPBrtuqGjN5utDu +26BWQqPxx36aABw44UmTRwV4UNf+3McYSJoCODfVpHOKsKk0Ql5CDzG3Ngpdu9ZR +UxV6s2DNHkSUjpd5vRfZF09WnQ0WITEhKz8Wnm82B/NkvRmTzYqlpP+zOT3+WPFh +5maMPOP0bvEfiT22zQqOOyKraYPrtf5ZBSip1fYohOlyS/aJcqOChMuKMOBVrxqH +9EmHjEkN0a+nAdWnGmCoGZONsD4ifXL17AUOaGSpEko6Nj7nXyTKI0laBhj6f8uw +v8M3xDBkIm7oiTuwrCeDa4e9YtP6Vzvj6MxrpNIMN0XRs/DRYH0lgTI1Zv/0SzkO +OAa9tOCiq95jkMjZik/vyQ55WwkMgYDmngsP/PBEW2ztdVLoLeal2p4HNfBM1BQO +RFOGnurR2Vmy1jGPyfpuBNMyjRgFC43s7SLiTYKCi1QxyY5u6dRgjIxkG+jyiY3B +GFMAtPt5iJHUox0AEQEAAbQjRGF2aWQgUmlhemF0aSA8ZHJpYXphdGlAYXBhY2hl +Lm9yZz6JAdQEEwEKAD4WIQSzxqFME7jGcnvC/S8H+kY/HJJvSAUCYs3OpQIbAwUJ +A8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRAH+kY/HJJvSJHEC/wMgDH/ +jBI6AciNp9sPv2p8tFRDywq2nUOameYFaIMq1r644IAzUUU3PSACMT1lCxGjFFsE +vJYx1GORrpqjwArrK1D3zZ0yb4X38DFAU+7DTGEKzKoz3h+Ka0GyOe90CI/KqqWL +XNeePwvOzIWhZ0U8vqUkgXwHyfG1dwocEx5A1zlTeznkth2AnRELnjhFcj28V2VX +dUQmZ8qOYxXtjSk9xJtQ/BbARiNINeKqzG1aPWgjTtFFp3UTl/jWCr5RBlWMA+BU +N9alE/ozRPx89Uilz2reaC7xX8tHv5F+P7SPVwMhJyYQ7F577CtM0b4vTu4U15wE +VlWF25ymTbSt5kam9jFbeR0Zkc0/LuLEdGWRGbDFI9Hj1rGeBejTm+PjwK3TidDn +KbvpUgvseNfqUQPcbjEsuwYVUtR/LEeQxt2tK/odQwWlHR7BQApFhV7VSJVP99Fp +YNFN7AsiD7+k4fOl5Qeq/t6X7x+gXMkxsRvtJMwB/fTAWbuBxdQBdIkP/KC5AY0E +Ys3OpQEMALhC8woP92ONpgRKHhH3s65cY4EYLhfhkbOqU8KcbPJX0qx1gM68jWqm +aCvez9KO+aB2jEyWG65XsOJXM6RqFtgvFMKG+ETLIgPydqt9l4f5AhnrPXmrxf7l +b8unuFMyoga7DyKnB6hQzEVqZgbKR+U6lWaoFtGTFYlaOdUz268OErrW3592frh0 +VKTdCyBdGPfiwKnzL4+LjU7SuiI9r1nBH5ZYicGmgOKQHP0KQRUy66Cq0S7p0rpp +9owbh2FHkXJ0bryl7AMV5JurEk0FSA483qQjyqHEQCSKVySgUBBFw9UPH0LkUbYv +jk43VFoUYexlJ47KFIRJdQZdLyyqsSy0xzqiCQXFwQPECIFHN/GTMuAHcaCfah/z +u4KDkqArzNzG1pl/DYVuaMo9LmBtzB7kfxPKcvm0atp6WHydcQ92N9ZU9z2zBh7T +u6Akzl+eONsix7F0oldwtG7Glic+1HafyyjhZfV8o6r7rYURnsotDfdzYjpL/xWe +xWkUSv2GbwARAQABiQG8BBgBCgAmFiEEs8ahTBO4xnJ7wv0vB/pGPxySb0gFAmLN +zqUCGwwFCQPCZwAACgkQB/pGPxySb0g+0wv+MQO/9mVo4eblTeFMLpLlU1tbDXIF +n5bDxbd1ekq/fKLrWZpT+MQGprGMXbgTehgeBIMvFvANLr2KHUb4HpXTX1GceVHv +A5uN/JQ+/H+IF3SoipcFPDR67uESVSZQfrky6HG8M9hH4OPdW4LbyEBke13Z2LlK +sQWJFznDnqCqmvLDvvliGBGhMM3RvTn5upgA47gwcJ1Z4xZU+k1nyhAiAgxGxpjO +rtj/Dv7r7gdnDBo5omu0fQLqulSY1UeHsOQXlkR6zMOMDdKgybcScQHQhta0Hcs+ +DWxpfJ92vH/3wGchSA1f0Fp2WCiQ/wp7sfe1esShDN12AwlpDBjK583d0R+DLpVY +8DbRCdvtwIN2f5KD+LhBbBX66AADVKVRIPgGDRGxc85X06nVWOQGHrGD+tCjxBNM +aLLvg9K8HxeWTvQvowCAyFJo4NfIrS/7gMm5JcWMAqVFJ+IVxZNxZUIYV0VBC/AN +rSSBN90DWxIgPhlAqgO0ofkbPSVwF/9i7nd3 +=XBuV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/Makefile b/Makefile index 05bd7245f830..d5dd45161cf1 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ $(foreach CMAKE_TARGET,$(CMAKE_TARGETS),$(eval $(GEN_CMAKE_RULE))) # scripts that are executed in the CI should be in tests/lint. This # allows docker/lint.sh to behave similarly to the CI. format: - ./tests/lint/git-clang-format.sh -i origin/main + ./tests/lint/git-clang-format.sh -i --rev origin/main black . cd rust && which cargo && cargo fmt --all diff --git a/NEWS.md b/NEWS.md index d48c2a4dec72..90bcfbf0876c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -318,7 +318,7 @@ The community also continues to bring high quality improvements to the existing * Tutorial: Using the template-free auto-scheduler on CPU (#6488) #### BYOC -* External codegen support in Relay (#4482),(#4544) +* External codegen support in Relay (#4482), (#4544) * Bring Your Own Codegen Guide -- Part 1 #4602 * Bring Your Own Codegen Guide -- Part 2 #4718 * Relay annotation and partitioning for external compilers #4570 @@ -2140,7 +2140,7 @@ Rust language support in TVM includes two parts. 1. The frontend wraps the curre * Increate the robuteness of CI test (#2841, #2798, #2793, #2788, #2781, #2727, #2710, #2711, #2923) * Improve conda build (#2742) * Add caffe2 nnvm frontend to CI (#3018) -* Use bridge network and expose port on macOS when launch docker image (#3086) +* Use bridge network and expose port on macOS when launch docker image (#3086) * Run DarkNet tests (#2673) * Add file type check (#3116) * Always run cpptest during build to ensure library correctness (#3147) diff --git a/apps/android_camera/README.md b/apps/android_camera/README.md index c292ce40c582..f659e905f281 100644 --- a/apps/android_camera/README.md +++ b/apps/android_camera/README.md @@ -1,28 +1,107 @@ -[//]: # Licensed to the Apache Software Foundation (ASF) under one -[//]: # or more contributor license agreements. See the NOTICE file -[//]: # distributed with this work for additional information -[//]: # regarding copyright ownership. The ASF licenses this file -[//]: # to you under the Apache License, Version 2.0 (the -[//]: # "License"); you may not use this file except in compliance -[//]: # with the License. You may obtain a copy of the License at -[//]: # -[//]: # http://www.apache.org/licenses/LICENSE-2.0 -[//]: # -[//]: # Unless required by applicable law or agreed to in writing, -[//]: # software distributed under the License is distributed on an -[//]: # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -[//]: # KIND, either express or implied. See the License for the -[//]: # specific language governing permissions and limitations -[//]: # under the License. - -Android Camera Demo Sample App -============================== - -The Android Camera Demo Sample App provides a basic implementation of an Android -app that uses the tvm runtime to perform image classification in real time. - -Converting Models ------------------ + + + + + + + + + + + + + + + + + + +# Android Camera Demo Sample App + +The Android Camera Demo Sample App provides a basic implementation of an Android app that uses the tvm runtime to perform image classification in real time. + +You will need JDK, [Android NDK](https://developer.android.com/ndk) and an Android device to use this. + +## Build and Installation + +### Prepare Models The `models/prepare_models.py` script provides a example flow for dumping model parameter files for use by the app. + +1. Set path to the NDK CC: `export TVM_NDK_CC=[Path to CC, e.g. /opt/android-toolchain-arm64/bin/aarch64-linux-android-g++]` +2. Switch to the script directory: `cd models` +3. Run script: `python3 prepare_model.py` + +#### Sample output +``` +mobilenet_v2 +getting model... +building... +dumping lib... +dumping graph... +dumping params... +dumping labels... +resnet18_v1 +getting model... +building... +dumping lib... +dumping graph... +dumping params... +dumping labels... +``` + +### Build APK + +We use [Gradle](https://gradle.org) to build. Please follow [the installation instruction](https://gradle.org/install) for your operating system. + +Before you build the Android application, please refer to [TVM4J Installation Guide](https://github.com/apache/tvm/blob/main/jvm/README.md) and install tvm4j-core to your local maven repository. You can find tvm4j dependency declare in `app/build.gradle`. Modify it if it is necessary. + +``` +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', { + exclude group: 'com.android.support', module: 'support-annotations' + }) + implementation 'androidx.appcompat:appcompat:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.3' + implementation 'com.google.android.material:material:1.5.0' + implementation 'org.apache.tvm:tvm4j-core:0.0.1-SNAPSHOT' + testImplementation 'junit:junit:4.13.2' + + implementation "androidx.concurrent:concurrent-futures:1.0.0" + implementation "androidx.camera:camera-core:1.0.0-beta01" + implementation "androidx.camera:camera-camera2:1.0.0-beta01" + implementation "androidx.camera:camera-view:1.0.0-alpha08" + implementation "androidx.camera:camera-extensions:1.0.0-alpha08" + implementation "androidx.camera:camera-lifecycle:1.0.0-beta01" +} +``` + +Now use Gradle to compile JNI, resolve Java dependencies and build the Android application together with tvm4j. Run following script to generate the apk file. + +```bash +export ANDROID_HOME=[Path to your Android SDK, e.g., ~/Android/sdk] +cd apps/android_camera +gradle clean build +``` + +In `app/build/outputs/apk` you'll find `app-release-unsigned.apk`, use `dev_tools/gen_keystore.sh` to generate a signature and use `dev_tools/sign_apk.sh` to get the signed apk file `app/build/outputs/apk/release/tv8mdemo-release.apk`. + +Upload `tv8mdemo-release.apk` to your Android device and install it: + +```bash +$ANDROID_HOME/platform-tools/adb install app/build/outputs/apk/release/tv8mdemo-release.apk +``` + +If you see error: + + adb: failed to install app/build/outputs/apk/release/tv8mdemo-release.apk: + Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: + Package ml.apache.tvm.android.androidcamerademo signatures do not match the previously installed version; ignoring!] + +Run uninstall first: + +```bash +$ANDROID_HOME/platform-tools/adb uninstall ml.apache.tvm.android.androidcamerademo +``` diff --git a/apps/android_camera/app/build.gradle b/apps/android_camera/app/build.gradle index 8a772a3d29f3..c7767559e4df 100644 --- a/apps/android_camera/app/build.gradle +++ b/apps/android_camera/app/build.gradle @@ -17,20 +17,47 @@ apply plugin: 'com.android.application' +task generateJniHeaders(type: Exec, description: 'Generate JNI Headers') { + def headerPath = "${project.projectDir}/src/main/jni" + def classPath = "${project.projectDir}/../../../jvm/core/target/*" + def filePath = "${project.projectDir}/../../../jvm/core/src/main/java/org/apache/tvm/LibInfo.java" + commandLine "javac", "-h", headerPath, "-classpath", classPath, filePath + doLast { + file("${headerPath}/org_apache_tvm_LibInfo.h").renameTo(file("${headerPath}/org_apache_tvm_native_c_api.h")) + } +} + +task copyFiles(type: Copy, description: 'Copy Sources for ndk-build') { + dependsOn "generateJniHeaders" + def ndkFilesPath = "${project.projectDir}/../../../jvm/native/src/main/native" + def srcPath = "${project.projectDir}/src/main/jni/" + + from "${ndkFilesPath}/org_apache_tvm_native_c_api.cc", "${ndkFilesPath}/jni_helper_func.h" + into srcPath +} + +task deleteLibs(type: Delete, description: "Delete Compiled Libraries") { + dependsOn "copyFiles" + def libsPath = "${project.projectDir}/src/main/libs" + delete libsPath +} + task buildJni(type: Exec, description: 'Build JNI libs') { - commandLine 'sh', 'src/main/jni/build.sh' + dependsOn "deleteLibs" + def buildPath = "${project.projectDir}/src/main/jni" + commandLine "ndk-build", "--directory", buildPath } tasks.withType(JavaCompile) { - //compileTask -> compileTask.dependsOn buildJni + compileTask -> compileTask.dependsOn buildJni } android { - compileSdkVersion 29 + compileSdkVersion 31 defaultConfig { applicationId "ml.apache.tvm.android.androidcamerademo" minSdkVersion 24 - targetSdkVersion 29 + targetSdkVersion 26 renderscriptTargetApi 18 renderscriptSupportModeEnabled true versionCode 1 @@ -53,7 +80,10 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - buildToolsVersion = '29.0.3' + + lintOptions { + disable "Instantiatable" // MainActivity and RPCActivity must extend android.app.Activity + } } dependencies { @@ -61,13 +91,13 @@ dependencies { androidTestImplementation('androidx.test.espresso:espresso-core:3.2.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'com.google.android.material:material:1.1.0' - implementation 'org.apache.tvm:tvm4j-core:0.0.1-SNAPSHOT' - testImplementation 'junit:junit:4.13' + implementation 'androidx.appcompat:appcompat:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.3' + implementation 'com.google.android.material:material:1.5.0' + implementation files('../../../jvm/core/target/tvm4j-core-0.0.1-SNAPSHOT.jar') + testImplementation 'junit:junit:4.13.2' - implementation("androidx.concurrent:concurrent-futures:1.0.0") + implementation "androidx.concurrent:concurrent-futures:1.0.0" implementation "androidx.camera:camera-core:1.0.0-beta01" implementation "androidx.camera:camera-camera2:1.0.0-beta01" // If you want to use the CameraX View class diff --git a/apps/android_camera/app/src/main/AndroidManifest.xml b/apps/android_camera/app/src/main/AndroidManifest.xml index 0821286d5543..e5b6465c5874 100644 --- a/apps/android_camera/app/src/main/AndroidManifest.xml +++ b/apps/android_camera/app/src/main/AndroidManifest.xml @@ -28,7 +28,7 @@ tools:ignore="AllowBackup,MissingApplicationIcon"> diff --git a/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/Camera2BasicFragment.java b/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/Camera2BasicFragment.java index 8a5f54a3e399..3a55a62d739c 100644 --- a/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/Camera2BasicFragment.java +++ b/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/Camera2BasicFragment.java @@ -382,7 +382,7 @@ private Bitmap YUV_420_888_toRGB(Image image, int width, int height) { } private float[] getFrame(ImageProxy imageProxy) { - @SuppressLint("UnsafeExperimentalUsageError") + @SuppressLint("UnsafeOptInUsageError") Image image = imageProxy.getImage(); // extract the jpeg content if (image == null) { diff --git a/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/MainActivity.java b/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/MainActivity.java index f9c573a5d1fe..06b1c9730d05 100644 --- a/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/MainActivity.java +++ b/apps/android_camera/app/src/main/java/org/apache/tvm/android/androidcamerademo/MainActivity.java @@ -78,6 +78,7 @@ private void startFragment() { @Override public void onRequestPermissionsResult( int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (allPermissionsGranted()) { startFragment(); } else { diff --git a/apps/android_camera/app/src/main/jni/Android.mk b/apps/android_camera/app/src/main/jni/Android.mk index a5eacb0c0c2d..4ff3da8f3327 100644 --- a/apps/android_camera/app/src/main/jni/Android.mk +++ b/apps/android_camera/app/src/main/jni/Android.mk @@ -34,11 +34,14 @@ endif include $(config) LOCAL_SRC_FILES := org_apache_tvm_native_c_api.cc + LOCAL_LDFLAGS := -L$(SYSROOT)/usr/lib/ -llog LOCAL_C_INCLUDES := $(ROOT_PATH)/include \ + $(ROOT_PATH)/src/runtime/rpc \ $(ROOT_PATH)/3rdparty/dlpack/include \ $(ROOT_PATH)/3rdparty/dmlc-core/include \ + $(MY_PATH) LOCAL_MODULE = tvm4j_runtime_packed diff --git a/apps/android_camera/app/src/main/jni/tvm_runtime.h b/apps/android_camera/app/src/main/jni/tvm_runtime.h index 07a812c4b840..b20227b34db4 100644 --- a/apps/android_camera/app/src/main/jni/tvm_runtime.h +++ b/apps/android_camera/app/src/main/jni/tvm_runtime.h @@ -40,11 +40,16 @@ #include "../src/runtime/graph_executor/graph_executor.cc" #include "../src/runtime/library_module.cc" #include "../src/runtime/logging.cc" +#include "../src/runtime/minrpc/minrpc_logger.cc" #include "../src/runtime/module.cc" #include "../src/runtime/ndarray.cc" #include "../src/runtime/object.cc" +#include "../src/runtime/profiling.cc" #include "../src/runtime/registry.cc" +#include "../src/runtime/rpc/rpc_channel.cc" +#include "../src/runtime/rpc/rpc_endpoint.cc" #include "../src/runtime/rpc/rpc_event_impl.cc" +#include "../src/runtime/rpc/rpc_local_session.cc" #include "../src/runtime/rpc/rpc_module.cc" #include "../src/runtime/rpc/rpc_server_env.cc" #include "../src/runtime/rpc/rpc_session.cc" @@ -74,7 +79,7 @@ namespace tvm { namespace runtime { namespace detail { // Override logging mechanism -void LogFatalImpl(const std::string& file, int lineno, const std::string& message) { +[[noreturn]] void LogFatalImpl(const std::string& file, int lineno, const std::string& message) { std::string m = file + ":" + std::to_string(lineno) + ": " + message; __android_log_write(ANDROID_LOG_DEBUG, "TVM_RUNTIME", m.c_str()); throw InternalError(file, lineno, message); diff --git a/apps/android_camera/app/src/main/res/layout/listview_row.xml b/apps/android_camera/app/src/main/res/layout/listview_row.xml index 4c233dc40379..5038a27557e9 100644 --- a/apps/android_camera/app/src/main/res/layout/listview_row.xml +++ b/apps/android_camera/app/src/main/res/layout/listview_row.xml @@ -20,7 +20,7 @@ android:id="@+id/listview_row_text" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginRight="2dp" + android:layout_marginEnd="2dp" android:background="@drawable/item_selector" android:padding="10dp" android:textSize="18sp" diff --git a/apps/android_camera/build.gradle b/apps/android_camera/build.gradle index a58bc631dac5..1cd5ac9b656f 100644 --- a/apps/android_camera/build.gradle +++ b/apps/android_camera/build.gradle @@ -19,14 +19,14 @@ buildscript { repositories { - jcenter() + gradlePluginPortal() maven { url 'https://maven.google.com' } - google() } dependencies { - classpath 'com.android.tools.build:gradle:3.6.1' + classpath 'com.android.tools.build:gradle:7.1.2' + // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -34,16 +34,15 @@ buildscript { allprojects { repositories { - jcenter() + gradlePluginPortal() maven { - url 'https://maven.google.com' + url 'https://maven.google.com' } mavenLocal() mavenCentral() - google() } } task clean(type: Delete) { delete rootProject.buildDir -} \ No newline at end of file +} diff --git a/apps/android_camera/gradle.properties b/apps/android_camera/gradle.properties index f1328bf5fd43..1add1b540993 100644 --- a/apps/android_camera/gradle.properties +++ b/apps/android_camera/gradle.properties @@ -1,4 +1,3 @@ - # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information diff --git a/apps/android_camera/models/prepare_model.py b/apps/android_camera/models/prepare_model.py index 2ea1b0a120af..959e93f8b47b 100644 --- a/apps/android_camera/models/prepare_model.py +++ b/apps/android_camera/models/prepare_model.py @@ -106,7 +106,7 @@ def main(model_str, output_path): f.write(graph) print("dumping params...") with open(output_path_str + "/" + "deploy_param.params", "wb") as f: - f.write(runtime.save_param_dict(params)) + f.write(tvm.runtime.save_param_dict(params)) print("dumping labels...") synset_url = "".join( [ diff --git a/apps/android_camera/models/requirements.txt b/apps/android_camera/models/requirements.txt new file mode 100644 index 000000000000..98aa53def46f --- /dev/null +++ b/apps/android_camera/models/requirements.txt @@ -0,0 +1,4 @@ +keras +mxnet +scipy +tensorflow \ No newline at end of file diff --git a/apps/android_deploy/app/build.gradle b/apps/android_deploy/app/build.gradle index c00528ba49fd..2949775349bb 100644 --- a/apps/android_deploy/app/build.gradle +++ b/apps/android_deploy/app/build.gradle @@ -26,8 +26,35 @@ apply from: "download-models.gradle" apply plugin: 'com.android.application' +task generateJniHeaders(type: Exec, description: 'Generate JNI Headers') { + def headerPath = "${project.projectDir}/src/main/jni" + def classPath = "${project.projectDir}/../../../jvm/core/target/*" + def filePath = "${project.projectDir}/../../../jvm/core/src/main/java/org/apache/tvm/LibInfo.java" + commandLine "javac", "-h", headerPath, "-classpath", classPath, filePath + doLast { + file("${headerPath}/org_apache_tvm_LibInfo.h").renameTo(file("${headerPath}/org_apache_tvm_native_c_api.h")) + } +} + +task copyFiles(type: Copy, description: 'Copy Sources for ndk-build') { + dependsOn "generateJniHeaders" + def ndkFilesPath = "${project.projectDir}/../../../jvm/native/src/main/native" + def srcPath = "${project.projectDir}/src/main/jni/" + + from "${ndkFilesPath}/org_apache_tvm_native_c_api.cc", "${ndkFilesPath}/jni_helper_func.h" + into srcPath +} + +task deleteLibs(type: Delete, description: "Delete Compiled Libraries") { + dependsOn "copyFiles" + def libsPath = "${project.projectDir}/src/main/libs" + delete libsPath +} + task buildJni(type: Exec, description: 'Build JNI libs') { - commandLine 'sh', 'src/main/jni/build.sh' + dependsOn "deleteLibs" + def buildPath = "${project.projectDir}/src/main/jni" + commandLine "ndk-build", "--directory", buildPath } tasks.withType(JavaCompile) { @@ -35,11 +62,10 @@ tasks.withType(JavaCompile) { } android { - compileSdkVersion 26 - buildToolsVersion "26.0.1" + compileSdkVersion 31 defaultConfig { applicationId "org.apache.tvm.android.demo" - minSdkVersion 17 + minSdkVersion 24 targetSdkVersion 26 versionCode 1 versionName "1.0" @@ -55,19 +81,24 @@ android { main { jni.srcDirs = [] jniLibs.srcDirs = ['src/main/libs'] - assets.srcDirs = [project.ext.ASSET_DIR] } } + + lintOptions { + disable "Instantiatable" // MainActivity and RPCActivity must extend android.app.Activity + disable "MissingApplicationIcon" // Should explicitly set android:icon, there is no default + disable "UnsafeNativeCodeLocation" // Shared libraries should not be placed in the res or assets directories. + } } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(dir: 'libs', include: ['*.jar']) + androidTestImplementation('com.android.support.test.espresso:espresso-core:3.4.0', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile 'com.android.support:appcompat-v7:26.0.1' - compile 'com.android.support.constraint:constraint-layout:1.0.2' - compile 'com.android.support:design:26.0.1' - compile 'org.apache.tvm:tvm4j-core:0.0.1-SNAPSHOT' - testCompile 'junit:junit:4.12' -} + implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'com.android.support.constraint:constraint-layout:2.1.3' + implementation 'com.android.support:design:28.0.0' + implementation files('../../../jvm/core/target/tvm4j-core-0.0.1-SNAPSHOT.jar') + testImplementation 'junit:junit:4.13.2' +} \ No newline at end of file diff --git a/apps/android_deploy/app/download-models.gradle b/apps/android_deploy/app/download-models.gradle index ed660e0221ee..4d1620bfd953 100644 --- a/apps/android_deploy/app/download-models.gradle +++ b/apps/android_deploy/app/download-models.gradle @@ -34,7 +34,7 @@ buildscript { jcenter() } dependencies { - classpath 'de.undercouch:gradle-download-task:3.2.0' + classpath 'de.undercouch:gradle-download-task:5.0.4' } } diff --git a/apps/android_deploy/app/src/main/AndroidManifest.xml b/apps/android_deploy/app/src/main/AndroidManifest.xml index bf3463f4d9c6..ce1b1fac4552 100644 --- a/apps/android_deploy/app/src/main/AndroidManifest.xml +++ b/apps/android_deploy/app/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ under the License. + + android:exported="true" + android:screenOrientation="unspecified"> @@ -52,6 +53,4 @@ under the License. - - diff --git a/apps/android_deploy/app/src/main/java/org/apache/tvm/android/demo/MainActivity.java b/apps/android_deploy/app/src/main/java/org/apache/tvm/android/demo/MainActivity.java index 85cc7a277b4d..6320b6aa8afd 100644 --- a/apps/android_deploy/app/src/main/java/org/apache/tvm/android/demo/MainActivity.java +++ b/apps/android_deploy/app/src/main/java/org/apache/tvm/android/demo/MainActivity.java @@ -35,9 +35,9 @@ import android.os.Environment; import android.os.SystemClock; import android.provider.MediaStore; -import android.support.v4.content.FileProvider; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; +import androidx.core.content.FileProvider; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import android.util.Log; import android.view.View; import android.widget.ImageView; @@ -51,6 +51,7 @@ import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Locale; import java.util.Vector; import org.apache.tvm.Function; @@ -487,7 +488,7 @@ private final String getTempLibFilePath(String fileName) throws IOException { */ private File createImageFile() { // Create an image file name - String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); @@ -527,6 +528,7 @@ public void onClick(DialogInterface dialog, int id) { @Override public void onRequestPermissionsResult (final int requestCode, final String[] permissions, final int[] grantResults){ + super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == PERMISSIONS_REQUEST) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED diff --git a/apps/android_deploy/app/src/main/jni/build.sh b/apps/android_deploy/app/src/main/jni/build.sh deleted file mode 100644 index 001d206ffd5d..000000000000 --- a/apps/android_deploy/app/src/main/jni/build.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -PATH="$PATH:/usr/local/bin" -CURR_DIR=$(cd `dirname $0`; pwd) -ROOT_DIR="$CURR_DIR/../../../../../.." -javac -h $CURR_DIR -classpath "$ROOT_DIR/jvm/core/target/*" $ROOT_DIR/jvm/core/src/main/java/org/apache/tvm/LibInfo.java || exit -1 -mv $CURR_DIR/org_apache_tvm_LibInfo.h $CURR_DIR/org_apache_tvm_native_c_api.h -cp -f $ROOT_DIR/jvm/native/src/main/native/org_apache_tvm_native_c_api.cc $CURR_DIR/ || exit -1 -cp -f $ROOT_DIR/jvm/native/src/main/native/jni_helper_func.h $CURR_DIR/ || exit -1 -rm -rf $CURR_DIR/../libs -ndk-build --directory=$CURR_DIR diff --git a/apps/android_deploy/app/src/main/res/layout/activity_main.xml b/apps/android_deploy/app/src/main/res/layout/activity_main.xml index 0778374223d8..4b019e1fbdb3 100644 --- a/apps/android_deploy/app/src/main/res/layout/activity_main.xml +++ b/apps/android_deploy/app/src/main/res/layout/activity_main.xml @@ -19,29 +19,28 @@ specific language governing permissions and limitations under the License. --> - - - + android:layout_height="match_parent" + tools:context="org.apache.tvm.tvmrpc.MainActivity"> - + android:theme="@style/AppTheme.AppBarOverlay"> - + - + - + + diff --git a/apps/android_deploy/app/src/main/res/layout/content_main.xml b/apps/android_deploy/app/src/main/res/layout/content_main.xml index aa1b0ea72b3e..6bf3c19f7f81 100644 --- a/apps/android_deploy/app/src/main/res/layout/content_main.xml +++ b/apps/android_deploy/app/src/main/res/layout/content_main.xml @@ -35,10 +35,10 @@ under the License.