This repository was archived by the owner on Jul 22, 2026. It is now read-only.
conf #4163
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | ||
| on: | ||
| push: | ||
| pull_request: | ||
| schedule: | ||
| - cron: '0 8 * * *' | ||
| workflow_dispatch: | ||
| jobs: | ||
| clang-format: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: DoozyX/clang-format-lint-action@v0.15 | ||
| with: | ||
| source: './app ./include ./src ./test' | ||
| build-linux: | ||
| strategy: | ||
| matrix: | ||
| include: | ||
| - build_type: DEBUG | ||
| - build_type: RELEASE | ||
| stats: false | ||
| - build_type: RELEASE | ||
| stats: true | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Set binary paths | ||
| id: set_binaries | ||
| run: | | ||
| echo "ACC_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT | ||
| - name: Setup ccache | ||
| uses: hendrikmuhs/ccache-action@v1.2 | ||
| with: | ||
| key: ccache-${{ github.job }}-${{ matrix.build_type }} | ||
| max-size: 2G | ||
| - name: Build | ||
| run: | | ||
| cmake -S . -B build -G Ninja \ | ||
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ | ||
| -DOPENCV_PATH=build/3rdparty/opencv_build \ | ||
| ${{ matrix.stats && '-DENABLE_STATISTIC_TENSORS=ON' || '' }} \ | ||
| ${{ matrix.stats && '-DENABLE_STATISTIC_TIME=ON' || '' }} \ | ||
| ${{ matrix.stats && '-DENABLE_STATISTIC_WEIGHTS=ON' || '' }} | ||
| cmake --build build --parallel | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| - name: Prepare ALL libs | ||
| run: | | ||
| mkdir -p build/bin/all_libs | ||
| cp -a build/3rdparty/opencv_build/lib/* build/bin/all_libs/ 2>/dev/null || true | ||
| ldd build/bin/ACC | grep "=> /" | awk '{print $3}' | xargs -I {} cp {} build/bin/all_libs/ 2>/dev/null || true | ||
| - name: Upload artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: mnist-${{ matrix.build_type }}${{ matrix.stats && '-stats' || '' }} | ||
| path: | | ||
| ${{ steps.set_binaries.outputs.ACC_BINARY }} | ||
| build/bin/all_libs/* | ||
| build/bin/opencv_libs/* | ||
| build/setenv.sh | ||
| - name: Test | ||
| run: cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| - name: Test (valgrind) | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y valgrind | ||
| valgrind cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| build-linux-clang: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Install prerequisites | ||
| run: | | ||
| sudo apt install clang libomp-dev | ||
| - name: Setup ccache | ||
| uses: hendrikmuhs/ccache-action@v1.2 | ||
| with: | ||
| key: ccache-${{ github.job }} | ||
| - name: Build | ||
| run: | | ||
| cmake -S . -B build -G Ninja \ | ||
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_C_COMPILER=clang \ | ||
| -DCMAKE_CXX_COMPILER=clang++ | ||
| cmake --build build --parallel | ||
| - name: Test | ||
| run: cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| - name: Test (valgrind) | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y valgrind | ||
| valgrind cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| build-macos: | ||
| runs-on: macos-15 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Install prerequisites | ||
| run: | | ||
| brew install libomp ninja | ||
| brew link libomp --overwrite --force | ||
| - name: Setup ccache | ||
| uses: hendrikmuhs/ccache-action@v1.2 | ||
| with: | ||
| key: ccache-${{ github.job }} | ||
| - name: Build | ||
| run: | | ||
| OPENMP_PATH=$(brew --prefix libomp) | ||
| echo "OpenMP path: $OPENMP_PATH" | ||
| cmake -S . -B build -G Ninja \ | ||
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_PREFIX_PATH=$OPENMP_PATH \ | ||
| -DCMAKE_INCLUDE_PATH=$OPENMP_PATH/include \ | ||
| -DCMAKE_LIBRARY_PATH=$OPENMP_PATH/lib \ | ||
| -DOpenMP_C_FLAGS="-Xclang -fopenmp -I$OPENMP_PATH/include" \ | ||
| -DOpenMP_CXX_FLAGS="-Xclang -fopenmp -I$OPENMP_PATH/include" \ | ||
| -DOpenMP_C_LIB_NAMES="omp" \ | ||
| -DOpenMP_CXX_LIB_NAMES="omp" \ | ||
| -DOpenMP_omp_LIBRARY="$OPENMP_PATH/lib/libomp.dylib" \ | ||
| -DCMAKE_EXE_LINKER_FLAGS="-L$OPENMP_PATH/lib -lomp" \ | ||
| -DCMAKE_SHARED_LINKER_FLAGS="-L$OPENMP_PATH/lib -lomp" | ||
| cmake --build build --parallel | ||
| env: | ||
| LDFLAGS: "-L$(brew --prefix libomp)/lib -lomp" | ||
| CPPFLAGS: "-I$(brew --prefix libomp)/include" | ||
| - name: Test | ||
| run: cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| build-windows: | ||
| runs-on: windows-2025 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Add msbuild to PATH | ||
| uses: microsoft/setup-msbuild@v2 | ||
| with: | ||
| vs-version: 'latest' | ||
| - name: Setup ccache | ||
| uses: Chocobo1/setup-ccache-action@v1 | ||
| with: | ||
| windows_compile_environment: msvc | ||
| - name: Setup ninja | ||
| uses: seanmiddleditch/gha-setup-ninja@v6 | ||
| - name: Setup MSVC for Ninja again | ||
| uses: ilammy/msvc-dev-cmd@v1 | ||
| - name: Build | ||
| run: | | ||
| cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_BUILD_TYPE=Release | ||
| cmake --build build --parallel --config Release | ||
| - name: Test | ||
| run: | | ||
| cd build | ||
| ctest --output-on-failure | ||
| build-linux-arm64: | ||
| runs-on: ubuntu-24.04-arm | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Install prerequisites | ||
| run: sudo apt-get update && sudo apt-get install -y libomp-dev build-essential cmake | ||
| - name: Setup ccache | ||
| uses: hendrikmuhs/ccache-action@v1.2 | ||
| with: | ||
| key: ccache-${{ github.job }} | ||
| - name: Build and Test | ||
| run: | | ||
| cmake -S . -B build -G Ninja \ | ||
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_BUILD_TYPE=Release | ||
| cmake --build build --parallel | ||
| cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| codecov: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: true | ||
| - name: Install dependencies | ||
| run: sudo apt-get update && sudo apt-get install -y gcovr | ||
| - name: Setup ccache | ||
| uses: hendrikmuhs/ccache-action@v1.2 | ||
| with: | ||
| key: ccache-${{ github.job }}-${{ matrix.build_type }} | ||
| max-size: 2G | ||
| - name: Build | ||
| run: | | ||
| cmake -S . -B build -G Ninja \ | ||
| -DCMAKE_C_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ | ||
| -DCMAKE_C_FLAGS="--coverage" \ | ||
| -DCMAKE_CXX_FLAGS="--coverage" \ | ||
| -DCMAKE_BUILD_TYPE=RelWithDebInfo | ||
| cmake --build build --parallel | ||
| - name: Test | ||
| run: cmake --build build -t test | ||
| env: | ||
| CTEST_OUTPUT_ON_FAILURE: 1 | ||
| - name: Generate Coverage Data | ||
| run: gcovr -r . --xml -o coverage.xml --gcov-ignore-parse-errors | ||
| - name: Upload coverage reports to Codecov | ||
| uses: codecov/codecov-action@v4.0.1 | ||
| with: | ||
| token: ${{ secrets.CODECOV_TOKEN }} | ||
| slug: embedded-dev-research/ITLabAI | ||
| evaluate-model-alexnet: | ||
| runs-on: ubuntu-latest | ||
| needs: [build-linux] | ||
| permissions: | ||
| contents: write | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Download binary and libs | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: mnist-RELEASE | ||
| path: build/ | ||
| - name: Set binary path | ||
| id: set_eval_binary | ||
| run: | | ||
| echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT | ||
| - name: Install system dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y libgtk-3-0 libtbb12 libjpeg-dev libpng-dev libtiff-dev libopenjp2-7 libdnnl3 | ||
| sudo ldconfig | ||
| - name: Generate model JSON | ||
| run: | | ||
| cd docs && mkdir -p jsons | ||
| cd .. | ||
| cd app/Converters | ||
| pip install -r requirements.txt | ||
| python parser.py | ||
| cd ../.. | ||
| - name: Cache MNIST test dataset | ||
| id: cache-mnist | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: docs/mnist/mnist/test | ||
| key: mnist-dataset-e2d09c892023700f68bfa9f30ac91a4dffaa23b151deeaca627101b3d73ef83d | ||
| - name: Download MNIST test dataset | ||
| if: steps.cache-mnist.outputs.cache-hit != 'true' | ||
| run: | | ||
| mkdir -p docs/mnist/mnist/test | ||
| wget -q https://github.com/DeepTrackAI/MNIST_dataset/archive/main.zip -O main.zip | ||
| unzip -q main.zip | ||
| cp MNIST_dataset-main/mnist/test/*.png docs/mnist/mnist/test/ | ||
| rm -rf main.zip MNIST_dataset-main | ||
| - name: Prepare environment | ||
| run: | | ||
| chmod +x "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" | ||
| export LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH | ||
| - name: Run evaluation | ||
| run: | | ||
| export LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH | ||
| "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist > accuracy.txt 2>&1 | ||
| if [ $? -ne 0 ]; then | ||
| exit 1 | ||
| fi | ||
| - name: Extract accuracy value | ||
| run: | | ||
| ACCURACY=$(grep -oE '[0-9]+\.?[0-9]*%' accuracy.txt | head -1 || echo "0%") | ||
| echo "$ACCURACY" > accuracy_value.txt | ||
| - name: Update README (main only) | ||
| run: | | ||
| ACCURACY=$(sed 's/%//g' accuracy_value.txt) | ||
| CURRENT_ACCURACY=$(sed -nE 's/.*<!--ACCURACY_PLACEHOLDER-->Accuracy: ([0-9]+(\.[0-9]+)?)% \(updated: [0-9-]+\)<!--END_ACCURACY-->.*/\1/p' README.md | head -n1) | ||
| if [ -n "$CURRENT_ACCURACY" ] && [ "$CURRENT_ACCURACY" = "$ACCURACY" ]; then | ||
| echo "Accuracy unchanged; keeping existing README update date" | ||
| exit 0 | ||
| fi | ||
| DATE=$(date '+%Y-%m-%d') | ||
| UPDATE_TEXT="<!--ACCURACY_PLACEHOLDER-->Accuracy: ${ACCURACY}% (updated: ${DATE})<!--END_ACCURACY-->" | ||
| ESCAPED_UPDATE_TEXT=$(printf '%s\n' "$UPDATE_TEXT" | sed 's/[&|\\]/\\&/g') | ||
| sed -i "s|<!--ACCURACY_PLACEHOLDER-->.*<!--END_ACCURACY-->|${ESCAPED_UPDATE_TEXT}|" README.md | ||
| - name: Commit and push changes (main only) | ||
| if: github.ref == 'refs/heads/main' && github.repository == 'embedded-dev-research/itlab_2023' | ||
| run: | | ||
| git config --global user.name "GitHub Actions" | ||
| git config --global user.email "actions@github.com" | ||
| git add README.md | ||
| if git diff --cached --quiet; then | ||
| echo "No changes to commit" | ||
| else | ||
| git commit -m "[CI] Update accuracy: $(cat accuracy_value.txt)" | ||
| for attempt in 1 2 3 4 5; do | ||
| git pull --rebase origin main && git push origin HEAD:main && break | ||
| git rebase --abort || true | ||
| [ "$attempt" -eq 5 ] && { echo "Failed to push README update after ${attempt} attempts"; exit 1; } | ||
| sleep 5 | ||
| done | ||
| fi | ||
| download-dataset: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Cache ImageNet-Paste dataset | ||
| id: cache-imagenet | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| restore-keys: | | ||
| imagenet-paste-v1- | ||
| imagenet-paste- | ||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.10' | ||
| - name: Install Python dependencies from requirements.txt | ||
| run: | | ||
| cd app/Converters | ||
| pip install -r requirements.txt | ||
| cd ../.. | ||
| - name: Download ImageNet-Paste dataset | ||
| if: steps.cache-imagenet.outputs.cache-hit != 'true' | ||
| env: | ||
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | ||
| run: | | ||
| mkdir -p docs/ImageNet/test | ||
| cd app/Converters | ||
| python download_imagenet.py | ||
| cd ../.. | ||
| - name: Save ImageNet-Paste dataset | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| evaluate-models-onnx: | ||
| runs-on: ubuntu-latest | ||
| needs: [build-linux, download-dataset] | ||
| permissions: | ||
| contents: write | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| model: [googlenet, densenet, resnet, yolo] | ||
| include: | ||
| - model: googlenet | ||
| parser: parser_onnx.py | ||
| model_file: GoogLeNet.onnx | ||
| model_path: docs/models/GoogLeNet.onnx | ||
| model_url: '' | ||
| extra_args: "--onednn 10000" | ||
| - model: densenet | ||
| parser: parser_onnx.py | ||
| model_file: densenet121_Opset16.onnx | ||
| model_url: https://github.com/onnx/models/raw/refs/heads/main/Computer_Vision/densenet121_Opset16_timm/densenet121_Opset16.onnx?download= | ||
| extra_args: "--onednn 10000" | ||
| - model: resnet | ||
| parser: parser_onnx.py | ||
| model_file: resnest101e_Opset16.onnx | ||
| model_url: https://github.com/onnx/models/raw/refs/heads/main/Computer_Vision/resnest101e_Opset16_timm/resnest101e_Opset16.onnx?download= | ||
| extra_args: "--onednn 10000" | ||
| - model: yolo | ||
| parser: parser_onnx.py | ||
| model_file: yolo11x-cls.pt | ||
| model_url: https://github.com/ultralytics/assets/releases/download/v8.4.0/yolo11x-cls.pt | ||
| extra_args: "--onednn 10000" | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Download binary and libs | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: mnist-RELEASE | ||
| path: build/ | ||
| - name: Set binary path | ||
| id: set_eval_binary | ||
| run: | | ||
| echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT | ||
| - name: Install system dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y libgtk-3-0 libtbb12 libjpeg-dev libpng-dev libtiff-dev libopenjp2-7 libdnnl3 | ||
| sudo ldconfig | ||
| - name: Download model (if URL provided) | ||
| if: matrix.model_url != '' | ||
| run: | | ||
| mkdir -p docs/models | ||
| wget -O docs/models/${{ matrix.model_file }} ${{ matrix.model_url }} | ||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.10' | ||
| - name: Install Python dependencies from requirements.txt | ||
| run: | | ||
| cd app/Converters | ||
| pip install -r requirements.txt | ||
| cd ../.. | ||
| - name: Cache model JSON files | ||
| id: cache-model-json | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: docs/jsons | ||
| key: model-json-${{ matrix.model }}-${{ hashFiles('app/Converters/parser_onnx.py', 'app/Converters/requirements.txt') }} | ||
| restore-keys: | | ||
| model-json-${{ matrix.model }}- | ||
| model-json- | ||
| - name: Generate model JSON | ||
| if: steps.cache-model-json.outputs.cache-hit != 'true' | ||
| run: | | ||
| mkdir -p docs/jsons | ||
| cd app/Converters | ||
| python ${{ matrix.parser }} ${{ matrix.model }} | ||
| cd ../.. | ||
| - name: Restore ImageNet-Paste dataset | ||
| id: cache-imagenet | ||
| uses: actions/cache/restore@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| restore-keys: | | ||
| imagenet-paste-v1- | ||
| imagenet-paste- | ||
| - name: Prepare environment | ||
| run: | | ||
| chmod +x "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" | ||
| echo "LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu" >> $GITHUB_ENV | ||
| - name: Run evaluation | ||
| run: | | ||
| DATASET_PATH="docs/ImageNet/test" | ||
| MODEL="${{ matrix.model }}" | ||
| EXTRA_ARGS="${{ matrix.extra_args }}" | ||
| "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" \ | ||
| --model $MODEL \ | ||
| $EXTRA_ARGS > accuracy_$MODEL.txt 2>&1 | ||
| if [ $? -ne 0 ]; then | ||
| echo "Ошибка при оценке модели $MODEL" | ||
| cat accuracy_$MODEL.txt | ||
| exit 1 | ||
| fi | ||
| echo "Результат оценки:" | ||
| cat accuracy_$MODEL.txt | ||
| - name: Extract accuracy value | ||
| run: | | ||
| ACCURACY=$(grep -oE '[0-9]+\.?[0-9]*%' accuracy_${{ matrix.model }}.txt | head -1 || echo "0%") | ||
| echo "$ACCURACY" > accuracy_value_${{ matrix.model }}.txt | ||
| echo "Accuracy for ${{ matrix.model }}: $ACCURACY" | ||
| - name: Upload accuracy artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: accuracy-${{ matrix.model }} | ||
| path: | | ||
| accuracy_${{ matrix.model }}.txt | ||
| accuracy_value_${{ matrix.model }}.txt | ||
| - name: Update README for model | ||
| run: | | ||
| TOP1_ACC=$(sed -nE 's/^Top-1 Accuracy: ([0-9]+(\.[0-9]+)?)%$/\1/p' accuracy_${{ matrix.model }}.txt | head -n1) | ||
| TOP5_ACC=$(sed -nE 's/^Top-5 Accuracy: ([0-9]+(\.[0-9]+)?)%$/\1/p' accuracy_${{ matrix.model }}.txt | head -n1) | ||
| if [ -z "$TOP1_ACC" ] || [ -z "$TOP5_ACC" ]; then | ||
| echo "Ошибка: Не удалось извлечь точность из файла accuracy_${{ matrix.model }}.txt" | ||
| cat accuracy_${{ matrix.model }}.txt | ||
| exit 1 | ||
| fi | ||
| CURRENT_TOP1=$(sed -nE "s/.*<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->Accuracy: Top-1: ([0-9]+(\\.[0-9]+)?)% \\| Top-5: ([0-9]+(\\.[0-9]+)?)% \\(updated: [0-9-]+\\)<!--END_ACCURACY_${{ matrix.model }}-->.*/\\1/p" README.md | head -n1) | ||
| CURRENT_TOP5=$(sed -nE "s/.*<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->Accuracy: Top-1: ([0-9]+(\\.[0-9]+)?)% \\| Top-5: ([0-9]+(\\.[0-9]+)?)% \\(updated: [0-9-]+\\)<!--END_ACCURACY_${{ matrix.model }}-->.*/\\3/p" README.md | head -n1) | ||
| if [ -n "$CURRENT_TOP1" ] && [ -n "$CURRENT_TOP5" ] && \ | ||
| [ "$CURRENT_TOP1" = "$TOP1_ACC" ] && [ "$CURRENT_TOP5" = "$TOP5_ACC" ]; then | ||
| echo "Accuracy for ${{ matrix.model }} unchanged; keeping existing README update date" | ||
| exit 0 | ||
| fi | ||
| DATE=$(date '+%Y-%m-%d') | ||
| UPDATE_TEXT="<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->Accuracy: Top-1: ${TOP1_ACC}% | Top-5: ${TOP5_ACC}% (updated: ${DATE})<!--END_ACCURACY_${{ matrix.model }}-->" | ||
| ESCAPED_UPDATE_TEXT=$(printf '%s\n' "$UPDATE_TEXT" | sed 's/[&|\\]/\\&/g') | ||
| if grep -q "<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->" README.md; then | ||
| sed -i "s|<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->.*<!--END_ACCURACY_${{ matrix.model }}-->|${ESCAPED_UPDATE_TEXT}|" README.md | ||
| else | ||
| echo "Ошибка: Плейсхолдер <!--ACCURACY_${{ matrix.model }}_PLACEHOLDER--> не найден в README.md" | ||
| echo "Содержимое README.md:" | ||
| cat README.md | ||
| exit 1 | ||
| fi | ||
| - name: Commit and push changes (main only) | ||
| if: github.ref == 'refs/heads/main' && github.repository == 'embedded-dev-research/ITLabAI' | ||
| run: | | ||
| git config --global user.name "GitHub Actions" | ||
| git config --global user.email "actions@github.com" | ||
| git add README.md | ||
| if git diff --cached --quiet; then | ||
| echo "No changes to commit" | ||
| else | ||
| git commit -m "[CI] Update accuracy for ${{ matrix.model }}: $(cat accuracy_value_${{ matrix.model }}.txt)" | ||
| for attempt in 1 2 3 4 5; do | ||
| git pull --rebase origin main && git push origin HEAD:main && break | ||
| git rebase --abort || true | ||
| [ "$attempt" -eq 5 ] && { echo "Failed to push README update after ${attempt} attempts"; exit 1; } | ||
| sleep 5 | ||
| done | ||
| fi | ||
| download-dataset: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Cache ImageNet-Paste dataset | ||
| id: cache-imagenet | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| restore-keys: | | ||
| imagenet-paste-v1- | ||
| imagenet-paste- | ||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.10' | ||
| - name: Install Python dependencies from requirements.txt | ||
| run: | | ||
| cd app/Converters | ||
| pip install -r requirements.txt | ||
| cd ../.. | ||
| - name: Download ImageNet-Paste dataset | ||
| if: steps.cache-imagenet.outputs.cache-hit != 'true' | ||
| env: | ||
| HF_TOKEN: ${{ secrets.HF_TOKEN }} | ||
| run: | | ||
| mkdir -p docs/ImageNet/test | ||
| cd app/Converters | ||
| python download_imagenet.py | ||
| cd ../.. | ||
| - name: Debug cache info | ||
| run: | | ||
| echo "Cache hit: ${{ steps.cache-imagenet.outputs.cache-hit }}" | ||
| echo "Cache key: ${{ steps.cache-imagenet.outputs.cache-primary-key }}" | ||
| echo "Dataset size:" | ||
| du -sh docs/ImageNet | ||
| - name: Save ImageNet-Paste dataset | ||
| uses: actions/cache/save@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| evaluate-models-onnx: | ||
| runs-on: ubuntu-latest | ||
| needs: [build-linux, download-dataset] | ||
| permissions: | ||
| contents: write | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| model: [googlenet, densenet, resnet, yolo] | ||
| parallel_flag: ["--parallel tbb 1000", "--parallel tbb 10000"] | ||
| include: | ||
| - model: googlenet | ||
| parser: parser_onnx.py | ||
| model_file: GoogLeNet.onnx | ||
| model_path: docs/models/GoogLeNet.onnx | ||
| model_url: '' | ||
| - model: densenet | ||
| parser: parser_onnx.py | ||
| model_file: densenet121_Opset16.onnx | ||
| model_url: https://github.com/onnx/models/raw/refs/heads/main/Computer_Vision/densenet121_Opset16_timm/densenet121_Opset16.onnx?download= | ||
| - model: resnet | ||
| parser: parser_onnx.py | ||
| model_file: resnest101e_Opset16.onnx | ||
| model_url: https://github.com/onnx/models/raw/refs/heads/main/Computer_Vision/resnest101e_Opset16_timm/resnest101e_Opset16.onnx?download= | ||
| - model: yolo | ||
| parser: parser_onnx.py | ||
| model_file: yolo11x-cls.pt | ||
| model_url: https://github.com/ultralytics/assets/releases/download/v8.4.0/yolo11x-cls.pt | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - name: Download binary and libs | ||
| uses: actions/download-artifact@v4 | ||
| with: | ||
| name: mnist-RELEASE | ||
| path: build/ | ||
| - name: Set binary path | ||
| id: set_eval_binary | ||
| run: | | ||
| echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT | ||
| - name: Install system dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y libgtk-3-0 libtbb12 libjpeg-dev libpng-dev libtiff-dev libopenjp2-7 libdnnl3 | ||
| sudo ldconfig | ||
| - name: Download model (if URL provided) | ||
| if: matrix.model_url != '' | ||
| run: | | ||
| mkdir -p docs/models | ||
| echo "Скачивание ${{ matrix.model_file }} из ${{ matrix.model_url }}" | ||
| wget -O docs/models/${{ matrix.model_file }} ${{ matrix.model_url }} | ||
| ls -la docs/models/ | ||
| - name: Setup Python | ||
| uses: actions/setup-python@v4 | ||
| with: | ||
| python-version: '3.10' | ||
| - name: Install Python dependencies from requirements.txt | ||
| run: | | ||
| cd app/Converters | ||
| pip install -r requirements.txt | ||
| cd ../.. | ||
| - name: Cache model JSON files | ||
| id: cache-model-json | ||
| uses: actions/cache@v4 | ||
| with: | ||
| path: docs/jsons | ||
| key: model-json-${{ matrix.model }}-${{ hashFiles('app/Converters/parser_onnx.py', 'app/Converters/requirements.txt') }} | ||
| restore-keys: | | ||
| model-json-${{ matrix.model }}- | ||
| model-json- | ||
| - name: Generate model JSON | ||
| if: steps.cache-model-json.outputs.cache-hit != 'true' | ||
| run: | | ||
| mkdir -p docs/jsons | ||
| cd app/Converters | ||
| python ${{ matrix.parser }} ${{ matrix.model }} | ||
| cd ../.. | ||
| - name: Restore ImageNet-Paste dataset | ||
| id: cache-imagenet | ||
| uses: actions/cache/restore@v4 | ||
| with: | ||
| path: docs/ImageNet | ||
| key: imagenet-paste-v1 | ||
| restore-keys: | | ||
| imagenet-paste-v1- | ||
| imagenet-paste- | ||
| - name: Prepare environment | ||
| run: | | ||
| chmod +x "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" | ||
| echo "LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu" >> $GITHUB_ENV | ||
| - name: Increase system limits | ||
| run: | | ||
| sudo prlimit --pid $$ --as=unlimited | ||
| ulimit -s unlimited | ||
| ulimit -c unlimited | ||
| echo "Новые лимиты:" | ||
| ulimit -a | ||
| - name: Run evaluation | ||
| run: | | ||
| DATASET_PATH="docs/ImageNet/test" | ||
| MODEL="${{ matrix.model }}" | ||
| EXTRA_ARGS="${{ matrix.extra_args }}" | ||
| echo "Запуск оценки для модели $MODEL" | ||
| echo "Команда: ${{ steps.set_eval_binary.outputs.EVAL_BINARY }} --model $MODEL $EXTRA_ARGS" | ||
| echo "Системная информация до запуска:" | ||
| echo "--- Память ---" | ||
| free -h | ||
| echo "--- CPU ---" | ||
| top -bn1 | head -5 | ||
| echo "--- Диск ---" | ||
| df -h docs/ImageNet/test/ | ||
| TIMESTAMP=$(date +%s) | ||
| MONITOR_LOG="monitor_$MODEL.log" | ||
| monitor_process() { | ||
| local pid=$1 | ||
| local log_file=$2 | ||
| echo "Мониторинг процесса $pid..." | ||
| while kill -0 $pid 2>/dev/null; do | ||
| NOW=$(date '+%H:%M:%S') | ||
| MEM=$(ps -o rss= -p $pid 2>/dev/null | awk '{print $1/1024 " MB"}' || echo "N/A") | ||
| CPU=$(ps -o pcpu= -p $pid 2>/dev/null || echo "N/A") | ||
| TOTAL_MEM=$(free -m | awk 'NR==2{print $3 " MB / " $2 " MB"}') | ||
| echo "[$NOW] PID: $pid | MEM: $MEM | CPU: $CPU% | System MEM: $TOTAL_MEM" >> $log_file | ||
| sleep 2 | ||
| done | ||
| echo "Процесс $pid завершен" >> $log_file | ||
| } | ||
| echo "Запуск ACC в фоновом режиме..." | ||
| "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" \ | ||
| --model $MODEL \ | ||
| $EXTRA_ARGS > accuracy_$MODEL.txt 2>&1 & | ||
| ACC_PID=$! | ||
| echo "PID процесса: $ACC_PID" | ||
| monitor_process $ACC_PID $MONITOR_LOG & | ||
| MONITOR_PID=$! | ||
| wait $ACC_PID | ||
| EXIT_CODE=$? | ||
| kill $MONITOR_PID 2>/dev/null || true | ||
| echo "Результаты мониторинга:" | ||
| if [ -f "$MONITOR_LOG" ]; then | ||
| cat "$MONITOR_LOG" | ||
| else | ||
| echo "Лог мониторинга не создан" | ||
| fi | ||
| echo "Системная информация после запуска:" | ||
| free -h | ||
| echo "Код завершения: $EXIT_CODE" | ||
| if [ $EXIT_CODE -eq 143 ]; then | ||
| echo "Ошибка 143 (SIGTERM) - процесс убит системой" | ||
| if sudo dmesg | tail -20 | grep -i "killed process" | grep -q "$ACC_PID"; then | ||
| echo "Подтверждено: процесс убит OOM Killer" | ||
| sudo dmesg | tail -20 | grep -i "killed process" | tail -5 | ||
| else | ||
| echo "Не найдено подтверждение OOM Killer в логах" | ||
| sudo dmesg | tail -20 | ||
| fi | ||
| elif [ $EXIT_CODE -ne 0 ]; then | ||
| echo "Ошибка при оценке модели $MODEL (код: $EXIT_CODE)" | ||
| else | ||
| echo "Оценка успешно завершена" | ||
| fi | ||
| echo "Лог ACC:" | ||
| if [ -f "accuracy_$MODEL.txt" ]; then | ||
| cat "accuracy_$MODEL.txt" | ||
| else | ||
| echo "Файл лога не создан" | ||
| fi | ||
| # Выход с ошибкой если нужно | ||
| if [ $EXIT_CODE -ne 0 ]; then | ||
| exit $EXIT_CODE | ||
| fi | ||
| - name: Extract accuracy value | ||
| run: | | ||
| ACCURACY=$(grep -oE '[0-9]+\.?[0-9]*%' accuracy_${{ matrix.model }}.txt | head -1 || echo "0%") | ||
| echo "$ACCURACY" > accuracy_value_${{ matrix.model }}.txt | ||
| echo "Accuracy for ${{ matrix.model }}: $ACCURACY" | ||
| - name: Upload accuracy artifacts | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: accuracy-${{ matrix.model }} | ||
| path: | | ||
| accuracy_${{ matrix.model }}.txt | ||
| accuracy_value_${{ matrix.model }}.txt | ||
| - name: Update README for model (master only) | ||
| if: github.ref == 'refs/heads/master' | ||
| run: | | ||
| TOP1_ACC=$(grep -oE 'Top-1 Accuracy: [0-9]+\.?[0-9]*%' accuracy_${{ matrix.model }}.txt | grep -oE '[0-9]+\.?[0-9]*') | ||
| TOP5_ACC=$(grep -oE 'Top-5 Accuracy: [0-9]+\.?[0-9]*%' accuracy_${{ matrix.model }}.txt | grep -oE '[0-9]+\.?[0-9]*') | ||
| DATE=$(date '+%Y-%m-%d') | ||
| if [ -z "$TOP1_ACC" ] || [ -z "$TOP5_ACC" ]; then | ||
| echo "Ошибка: Не удалось извлечь точность из файла accuracy_${{ matrix.model }}.txt" | ||
| cat accuracy_${{ matrix.model }}.txt | ||
| exit 1 | ||
| fi | ||
| UPDATE_TEXT="<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->Accuracy: Top-1: ${TOP1_ACC}% | Top-5: ${TOP5_ACC}% (updated: ${DATE})<!--END_ACCURACY_${{ matrix.model }}-->" | ||
| if grep -q "<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->" README.md; then | ||
| sed -i "s|<!--ACCURACY_${{ matrix.model }}_PLACEHOLDER-->.*<!--END_ACCURACY_${{ matrix.model }}-->|${UPDATE_TEXT}|" README.md | ||
| echo "Обновлена точность для ${{ matrix.model }} в README" | ||
| else | ||
| echo "Ошибка: Плейсхолдер <!--ACCURACY_${{ matrix.model }}_PLACEHOLDER--> не найден в README.md" | ||
| echo "Содержимое README.md:" | ||
| cat README.md | ||
| exit 1 | ||
| fi | ||
| - name: Commit and push changes (main only) | ||
| if: github.ref == 'refs/heads/main' | ||
| run: | | ||
| git config --global user.name "GitHub Actions" | ||
| git config --global user.email "actions@github.com" | ||
| git add README.md | ||
| if git diff-index --quiet HEAD --; then | ||
| echo "No changes to commit" | ||
| else | ||
| git commit -m "[CI] Update accuracy for ${{ matrix.model }}: $(cat accuracy_value_${{ matrix.model }}.txt)" | ||
| git push origin master | ||
| fi | ||