|  | # | 
|  | # Nightly-only jobs | 
|  | # | 
|  | # This file is conditionally included in the main | 
|  | # .gitlab-ci.yml only when doing nightly builds | 
|  | # so the builds here do not explicitly need to be | 
|  | # made nightly-only using rules. | 
|  | # | 
|  |  | 
|  | default: | 
|  | timeout: 11 hours | 
|  |  | 
|  | # Simple x86_64 Linux build | 
|  | Linux Nightly Build: | 
|  | stage: build | 
|  | interruptible: true | 
|  | # CMake 4.0.0 removed compatibility with CMake < 3.5. Add | 
|  | # -DCMAKE_POLICY_VERSION_MINIMUM=3.5 to try configuring anyway. | 
|  | variables: | 
|  | CMAKE_FLAGS: >- | 
|  | -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | 
|  | -DCMAKE_BUILD_TYPE=RelWithDebInfo | 
|  | -DAOM_EXTRA_C_FLAGS="--coverage" | 
|  | -DAOM_EXTRA_CXX_FLAGS="--coverage" | 
|  | -DAOM_EXTRA_EXE_LINKER_FLAGS="--coverage" | 
|  | script: | 
|  | - 'echo "CMake Flags: $CMAKE_FLAGS"' | 
|  | - cmake -B "aom_nightly_build" -GNinja $CMAKE_FLAGS | 
|  | - cmake --build "aom_nightly_build" --target aomenc | 
|  | - cmake --build "aom_nightly_build" --target test_libaom | 
|  | needs: [] | 
|  | artifacts: | 
|  | expire_in: 1 day | 
|  | paths: | 
|  | - 'aom_nightly_build/aomenc' | 
|  | - 'aom_nightly_build/test_libaom' | 
|  | - 'aom_nightly_build/**/*.gcno' | 
|  | - 'aom_nightly_build/**/*.[hc]' | 
|  | - 'aom_nightly_build/**/*.[hc]pp' | 
|  | - 'aom_nightly_build/**/*.cc' | 
|  | - 'aom_nightly_build/**/*.inc' | 
|  |  | 
|  | # Full unit tests run (with coverage report) | 
|  | Linux All Unit Test: | 
|  | stage: test | 
|  | interruptible: true | 
|  | parallel: 24 | 
|  | variables: | 
|  | LIBAOM_TEST_DATA_PATH: ${CI_PROJECT_DIR}/libaom-test-data | 
|  | GTEST_TOTAL_SHARDS: ${CI_NODE_TOTAL} | 
|  | GTEST_OUTPUT: "xml:report.xml" | 
|  | before_script: | 
|  | - export GTEST_SHARD_INDEX=$((CI_NODE_INDEX - 1)) | 
|  | script: | 
|  | - cd aom_nightly_build | 
|  | - ./test_libaom | 
|  | # Ignore parse errors due to a bug in `gcovr 7.0`: | 
|  | # https://github.com/gcovr/gcovr/issues/882 | 
|  | # Ignore errors about 'no_working_dir_found' because | 
|  | # tarballs for third_party code (e.g. tensorflow and dependencies) are NOT | 
|  | # extracted here and so the source files from those are NOT available. | 
|  | - >- | 
|  | gcovr | 
|  | --gcov-ignore-parse-errors | 
|  | --gcov-ignore-errors=no_working_dir_found | 
|  | --gcov-executable gcov-14 | 
|  | --exclude ../third_party --exclude _deps --exclude abseil-cpp --exclude | 
|  | benchmark --exclude cpuinfo --exclude eigen --exclude farmhash --exclude | 
|  | fft2d --exclude flatbuffers --exclude flatbuffers-flatc --exclude fp16 | 
|  | --exclude FP16 --exclude FXdiv --exclude psimd  --exclude ml_dtypes | 
|  | --exclude neon2sse  --exclude protobuf --exclude pthreadpool --exclude | 
|  | pthreadpool-source --exclude ruy --exclude xnnpack --exclude XNNPACK | 
|  | --exclude gemmlowp  --exclude googletest | 
|  | --exclude-directories "third_party" | 
|  | --exclude-directories "aom_nightly_build/third_party" | 
|  | --json -o "coverage_${CI_NODE_INDEX}.json" | 
|  | -r ../ . >  "coverage_${CI_NODE_INDEX}.log" 2>&1 | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Nightly Build' | 
|  | artifacts: | 
|  | when: always | 
|  | reports: | 
|  | junit: ./aom_nightly_build/report.xml | 
|  | paths: | 
|  | - aom_nightly_build/coverage_*.json | 
|  | - aom_nightly_build/coverage_*.log | 
|  |  | 
|  | # Produce actual coverage report from the | 
|  | # "Linux All Unit Test" job that ran in the | 
|  | # test stage before. | 
|  | Coverage Report: | 
|  | stage: report | 
|  | interruptible: true | 
|  | script: | 
|  | - mkdir -p coverage-html | 
|  | - cd aom_nightly_build | 
|  | - >- | 
|  | gcovr | 
|  | --gcov-executable gcov-14 | 
|  | --add-tracefile "coverage_*.json" | 
|  | --exclude ../third_party --exclude _deps --exclude abseil-cpp --exclude | 
|  | benchmark --exclude cpuinfo --exclude eigen --exclude farmhash --exclude | 
|  | fft2d --exclude flatbuffers --exclude flatbuffers-flatc --exclude fp16 | 
|  | --exclude FP16 --exclude FXdiv --exclude psimd  --exclude ml_dtypes | 
|  | --exclude neon2sse  --exclude protobuf --exclude pthreadpool --exclude | 
|  | pthreadpool-source --exclude ruy --exclude xnnpack --exclude XNNPACK | 
|  | --exclude gemmlowp  --exclude googletest | 
|  | --xml ../coverage.xml | 
|  | --html --html-details ../coverage-html/coverage.html | 
|  | --print-summary | 
|  | -r ../ . | 
|  | needs: | 
|  | - 'Linux Nightly Build' | 
|  | - 'Linux All Unit Test' | 
|  | coverage: '/lines:\s(\d+.\d+\%)/' | 
|  | artifacts: | 
|  | reports: | 
|  | coverage_report: | 
|  | coverage_format: cobertura | 
|  | path: coverage.xml | 
|  | paths: | 
|  | - coverage-html | 
|  |  | 
|  |  | 
|  | # | 
|  | # Tests run with varying SIMD levels | 
|  | # [sse2, sse3, ssse3, sse4_1, sse4_2, avx2] | 
|  | # | 
|  | # This is not done with a big matrix, because | 
|  | # GitLab CI has a limitation on expanding matrices | 
|  | # being limited to 50 jobs only. If that limit is | 
|  | # ever raised, this should be re-written using a | 
|  | # matrix! | 
|  | # | 
|  |  | 
|  | # Common unit-optim template | 
|  | # This is inherited by all the SIMD-level jobs | 
|  | .common-linux-unit-optim: | 
|  | stage: test | 
|  | interruptible: true | 
|  | parallel: 10 | 
|  | variables: | 
|  | LIBAOM_TEST_DATA_PATH: ${CI_PROJECT_DIR}/libaom-test-data | 
|  | GTEST_TOTAL_SHARDS: ${CI_NODE_TOTAL} | 
|  | GTEST_OUTPUT: "xml:report.xml" | 
|  | script: | 
|  | - cd aom_nightly_build | 
|  | - | | 
|  | case "${AOM_OPTIM_LEVEL}" in | 
|  | sse) export AOM_SIMD_CAPS_MASK=0x3 ;; | 
|  | sse2) export AOM_SIMD_CAPS_MASK=0x7 ;; | 
|  | sse3) export AOM_SIMD_CAPS_MASK=0xf ;; | 
|  | ssse3) export AOM_SIMD_CAPS_MASK=0x1f ;; | 
|  | sse4_1) export AOM_SIMD_CAPS_MASK=0x3f ;; | 
|  | # sse4_2 was added *after* avx2 so the mask is a little weird | 
|  | sse4_2) export AOM_SIMD_CAPS_MASK=0x13f ;; | 
|  | avx2) export AOM_SIMD_CAPS_MASK=0x1ff ;; | 
|  | esac | 
|  |  | 
|  | test_filter="-C*:MMX*:SSE*:SSSE*:AVX*:*Large*" | 
|  |  | 
|  | - ./test_libaom --gtest_filter=${test_filter} | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Nightly Build' | 
|  | artifacts: | 
|  | when: always | 
|  | reports: | 
|  | junit: ./aom_nightly_build/report.xml | 
|  | before_script: | 
|  | - export GTEST_SHARD_INDEX=$((CI_NODE_INDEX - 1)) | 
|  |  | 
|  | Linux Unit (x86_64, sse2): | 
|  | extends: .common-linux-unit-optim | 
|  | variables: | 
|  | AOM_OPTIM_LEVEL: sse2 | 
|  |  | 
|  | Linux Unit (x86_64, ssse3): | 
|  | extends: .common-linux-unit-optim | 
|  | variables: | 
|  | AOM_OPTIM_LEVEL: ssse3 | 
|  |  | 
|  | Linux Unit (x86_64, sse4_2): | 
|  | extends: .common-linux-unit-optim | 
|  | variables: | 
|  | AOM_OPTIM_LEVEL: sse4_2 | 
|  |  | 
|  | # | 
|  | # Sanitizer jobs | 
|  | # The following jobs run the unit tests but | 
|  | # with a built where the respective sanitizers | 
|  | # are enabled. | 
|  | # | 
|  | # This is not using a matrix as the jobs | 
|  | # depend on other jobs that were built by | 
|  | # a matrix job before and a matrix can not | 
|  | # depend on other matrix-jobs unfortunately. | 
|  | # | 
|  |  | 
|  | # Common sanitizer unit tests template | 
|  | # This is inherited by all sanitizer test jobs | 
|  | .sanitizer-common-nigtly: | 
|  | stage: test | 
|  | interruptible: true | 
|  | parallel: 24 | 
|  | variables: | 
|  | LIBAOM_TEST_DATA_PATH: ${CI_PROJECT_DIR}/libaom-test-data | 
|  | GTEST_TOTAL_SHARDS: ${CI_NODE_TOTAL} | 
|  | GTEST_OUTPUT: "xml:report.xml" | 
|  | SANITIZER_OPTIONS: "\ | 
|  | :handle_segv=1\ | 
|  | :handle_abort=1\ | 
|  | :handle_sigfpe=1\ | 
|  | :fast_unwind_on_fatal=1\ | 
|  | :allocator_may_return_null=1" | 
|  | before_script: | 
|  | - export PATH="/usr/lib/llvm-18/bin:${PATH}" | 
|  | - export GTEST_SHARD_INDEX=$((CI_NODE_INDEX - 1)) | 
|  | script: | 
|  | - | | 
|  | case $AOM_SANITIZER_TYPE in | 
|  | address) | 
|  | SANITIZER_OPTIONS="${SANITIZER_OPTIONS}:detect_stack_use_after_return=1" | 
|  | SANITIZER_OPTIONS="${SANITIZER_OPTIONS}:max_uar_stack_size_log=17" | 
|  | export ASAN_OPTIONS="${SANITIZER_OPTIONS}" | 
|  | ;; | 
|  | thread) | 
|  | # The thread sanitizer uses a subset. | 
|  | TSAN_OPTIONS="handle_sigfpe=1" | 
|  | TSAN_OPTIONS="$TSAN_OPTIONS handle_segv=1" | 
|  | TSAN_OPTIONS="$TSAN_OPTIONS handle_abort=1" | 
|  | export TSAN_OPTIONS | 
|  | ;; | 
|  | undefined|integer) | 
|  | SANITIZER_OPTIONS="${SANITIZER_OPTIONS}:print_stacktrace=1:suppressions=.gitlab/UBSan.supp" | 
|  | export UBSAN_OPTIONS="${SANITIZER_OPTIONS}" | 
|  | ;; | 
|  | esac | 
|  | - | | 
|  | filter="*Large*" | 
|  | # As of 17 May 2018 there are no large threading tests. | 
|  | [ "${AOM_SANITIZER_TYPE}" = "thread" ] && filter="*Thread*Large*" || : | 
|  | - ./aom_build/${AOM_SANITIZER_TYPE}/test_libaom --gtest_filter="${filter}" 2> >(tee -a sanitizer.log >&2) | 
|  | - | | 
|  | # Looking for sanitizer output in log... | 
|  | grep -q "\(ERROR\|WARNING\): \(Address\|Thread\|Memory\|Leak\)Sanitizer:" sanitizer.log && { | 
|  | echo "Found sanitizer errors or warnings, check the log:" | 
|  | cat sanitizer.log | 
|  | exit 1 | 
|  | } | 
|  | # Looking for UBSan output in log (differs from the common format) | 
|  | grep -q ":[[:digit:]]\+:[[:digit:]]\+: runtime error:" sanitizer.log && { | 
|  | echo "Found sanitizer errors or warnings, check the log:" | 
|  | cat sanitizer.log | 
|  | exit 1 | 
|  | } | 
|  | echo "No sanitizer errors found" | 
|  | artifacts: | 
|  | expose_as: 'Nightly sanitizer logs' | 
|  | name: "sanitizer.log-$CI_JOB_ID" | 
|  | when: on_failure | 
|  | paths: | 
|  | - sanitizer.log | 
|  |  | 
|  | Linux Sanitizer (address) Test Nightly: | 
|  | extends: .sanitizer-common-nigtly | 
|  | parallel: 34 | 
|  | variables: | 
|  | AOM_SANITIZER_TYPE: address | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Sanitizers (x86_64-clang): [address]' | 
|  |  | 
|  | Linux Sanitizer (undefined) Test Nightly: | 
|  | extends: .sanitizer-common-nigtly | 
|  | parallel: 34 | 
|  | variables: | 
|  | AOM_SANITIZER_TYPE: undefined | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Sanitizers (x86_64-clang): [undefined]' | 
|  |  | 
|  | Linux Sanitizer (integer) Test Nightly: | 
|  | extends: .sanitizer-common-nigtly | 
|  | variables: | 
|  | AOM_SANITIZER_TYPE: integer | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Sanitizers (x86_64-clang): [integer]' | 
|  |  | 
|  | Linux Sanitizer (thread) Test Nightly: | 
|  | extends: .sanitizer-common-nigtly | 
|  | parallel: 16 | 
|  | variables: | 
|  | AOM_SANITIZER_TYPE: thread | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Sanitizers (x86_64-clang): [thread]' | 
|  |  | 
|  |  | 
|  | # Memory sanitizer (MSan) needs special setup where some standard libraries | 
|  | # have to be built with memory sanitizer. Hence, the separate build and test | 
|  | # jobs for MSan. | 
|  | Linux Sanitizers (x86_64-clang) (Memory): | 
|  | stage: build | 
|  | interruptible: true | 
|  | script: | 
|  | - LLVM_VERSION_MAJOR=18 | 
|  | - LLVM_VERSION="${LLVM_VERSION_MAJOR}.1.3" | 
|  | - export PATH="/usr/lib/llvm-${LLVM_VERSION_MAJOR}/bin:${PATH}" | 
|  | # Build cxx and cxxabi with msan. | 
|  | - git clone --depth=1 --branch llvmorg-${LLVM_VERSION}  https://github.com/llvm/llvm-project | 
|  | - LLVM_MSAN_BUILD_DIR=${PWD}/llvm-project/msan_out | 
|  | - cmake -G Ninja -S llvm-project/runtimes -B "${LLVM_MSAN_BUILD_DIR}" | 
|  | -DCMAKE_BUILD_TYPE=Release | 
|  | -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" | 
|  | -DCMAKE_C_COMPILER=clang | 
|  | -DCMAKE_CXX_COMPILER=clang++ | 
|  | -DLLVM_USE_SANITIZER=MemoryWithOrigins | 
|  | -DLIBCXXABI_USE_LLVM_UNWINDER=OFF | 
|  | - cmake --build "${LLVM_MSAN_BUILD_DIR}" --config Release -- cxx cxxabi unwind | 
|  | # Build AVM with msan. | 
|  | - AVM_MSAN_BUILD_DIR="aom_build/memory" | 
|  | - | | 
|  | MSAN_CFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2" | 
|  | MSAN_CFLAGS="${MSAN_CFLAGS} -fno-omit-frame-pointer -g -O2" | 
|  | MSAN_CFLAGS="${MSAN_CFLAGS} -I${LLVM_MSAN_BUILD_DIR}/include" | 
|  | - | | 
|  | MSAN_CXXFLAGS="${MSAN_CFLAGS}" | 
|  | MSAN_CXXFLAGS="${MSAN_CXXFLAGS} -I${LLVM_MSAN_BUILD_DIR}/include/c++/v1" | 
|  | MSAN_CXXFLAGS="${MSAN_CXXFLAGS} -stdlib=libc++" | 
|  | - MSAN_LD_FLAGS="${MSAN_CXXFLAGS} -L${LLVM_MSAN_BUILD_DIR}/lib -lc++abi" | 
|  | - export CFLAGS="${MSAN_CFLAGS}" | 
|  | - export CXXFLAGS="${MSAN_CXXFLAGS}" | 
|  | - export LDFLAGS="${MSAN_LD_FLAGS}" | 
|  | - echo "CFLAGS = ${CFLAGS}" | 
|  | - echo "CXXFLAGS = ${CXXFLAGS}" | 
|  | - echo "LDFLAGS = ${LDFLAGS}" | 
|  | - cmake -B "${AVM_MSAN_BUILD_DIR}" -G Ninja | 
|  | -DAOM_TARGET_CPU=generic | 
|  | -DCMAKE_C_COMPILER=clang | 
|  | -DCMAKE_CXX_COMPILER=clang++ | 
|  | -DCMAKE_POLICY_VERSION_MINIMUM=3.5 | 
|  | -DENABLE_CCACHE=1 | 
|  | -DENABLE_EXAMPLES=0 | 
|  | - cmake --build "${AVM_MSAN_BUILD_DIR}" --target test_libaom | 
|  | needs: [] | 
|  | artifacts: | 
|  | expire_in: 1 day | 
|  | paths: | 
|  | - aom_build/*/test_libaom | 
|  | - llvm-project/msan_out/lib/ | 
|  |  | 
|  | Linux Sanitizer (memory) Test Nightly: | 
|  | stage: test | 
|  | interruptible: true | 
|  | parallel: 20 | 
|  | variables: | 
|  | LIBAOM_TEST_DATA_PATH: ${CI_PROJECT_DIR}/libaom-test-data | 
|  | GTEST_TOTAL_SHARDS: ${CI_NODE_TOTAL} | 
|  | GTEST_OUTPUT: "xml:report.xml" | 
|  | SANITIZER_OPTIONS: "\ | 
|  | :handle_segv=1\ | 
|  | :handle_abort=1\ | 
|  | :handle_sigfpe=1\ | 
|  | :fast_unwind_on_fatal=1\ | 
|  | :allocator_may_return_null=1" | 
|  | before_script: | 
|  | - export PATH="/usr/lib/llvm-18/bin:${PATH}" | 
|  | - export GTEST_SHARD_INDEX=$((CI_NODE_INDEX - 1)) | 
|  | script: | 
|  | - export MSAN_OPTIONS="${SANITIZER_OPTIONS}" | 
|  | - export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${PWD}/llvm-project/msan_out/lib" | 
|  | - filter="-*Large*:*MD5Test*:*TestVectorTest*:*InvalidFile*:*ExternalFrameBuffer*:*UninstantiatedParameterizedTestSuite*" | 
|  | - ./aom_build/memory/test_libaom --gtest_filter="${filter}" | 
|  | needs: | 
|  | - 'Test Data' | 
|  | - 'Linux Sanitizers (x86_64-clang) (Memory)' | 
|  |  | 
|  |  | 
|  | # Encode 2 GOPs in parallel and serial manner and ensure that results match. | 
|  | .gop-enc-common: | 
|  | stage: test | 
|  | interruptible: true | 
|  | variables: | 
|  | AOMENC_LIMIT: 130 | 
|  | AOMENC_SKIP: 0 | 
|  | AOMENC_QP: 160 | 
|  | AOMENC_INPUT: Vertical_Bayshore_270x480_2997.y4m | 
|  | AOMENC_OUTPUT: serial_2gops | 
|  | before_script: | 
|  | - curl -s -S -f -O https://gitlab.com/AOMediaCodec/aom-testing/-/raw/master/test-files/${AOMENC_INPUT}.xz | 
|  | - unxz ${AOMENC_INPUT}.xz | 
|  | script: | 
|  | - aom_nightly_build/aomenc | 
|  | --debug | 
|  | --cpu-used=0 | 
|  | --passes=1 | 
|  | --lag-in-frames=19 | 
|  | --auto-alt-ref=1 | 
|  | --min-gf-interval=16 | 
|  | --max-gf-interval=16 | 
|  | --gf-min-pyr-height=4 | 
|  | --gf-max-pyr-height=4 | 
|  | --kf-min-dist=65 | 
|  | --kf-max-dist=65 | 
|  | --use-fixed-qp-offsets=1 | 
|  | --deltaq-mode=0 | 
|  | --enable-tpl-model=0 | 
|  | --end-usage=q | 
|  | --qp=${AOMENC_QP} | 
|  | --enable-keyframe-filtering=0 | 
|  | --obu | 
|  | --limit=${AOMENC_LIMIT} | 
|  | --skip=${AOMENC_SKIP} | 
|  | -o "${AOMENC_OUTPUT}.obu" | 
|  | "${AOMENC_INPUT}" 2>&1 | tee "${AOMENC_OUTPUT}.psnr.log" | 
|  | - '[ -f "${AOMENC_OUTPUT}.obu" ] || exit 1' | 
|  | artifacts: | 
|  | when: always | 
|  | paths: | 
|  | - ${AOMENC_OUTPUT}.* | 
|  | needs: | 
|  | - 'Linux Nightly Build' | 
|  |  | 
|  |  | 
|  | Serial Encode (2 GOPs): | 
|  | extends: .gop-enc-common | 
|  |  | 
|  |  | 
|  | Parallel Encode (1st GOP): | 
|  | extends: .gop-enc-common | 
|  | variables: | 
|  | AOMENC_LIMIT: 65 | 
|  | AOMENC_SKIP: 0 | 
|  | AOMENC_OUTPUT: parallel_gop1 | 
|  |  | 
|  |  | 
|  | Parallel Encode (2nd GOP): | 
|  | extends: .gop-enc-common | 
|  | variables: | 
|  | AOMENC_LIMIT: 130 | 
|  | AOMENC_SKIP: 65 | 
|  | AOMENC_OUTPUT: parallel_gop2 | 
|  |  | 
|  |  | 
|  | Serial Parallel compare: | 
|  | stage: report | 
|  | interruptible: true | 
|  | script: | 
|  | - cat parallel_gop1.obu parallel_gop2.obu > parallel_2gops.obu | 
|  | - diff serial_2gops.obu parallel_2gops.obu | 
|  | needs: | 
|  | - 'Serial Encode (2 GOPs)' | 
|  | - 'Parallel Encode (1st GOP)' | 
|  | - 'Parallel Encode (2nd GOP)' |