name: python
on:
  push:
    branches: [master]
    paths:
    - '.github/workflows/python.yml'
    - 'CMakeLists.txt'
    - 'cmake/**'
    - 'src/*'
    - 'src/layer/*'
    - 'src/layer/x86/**'
    - 'src/layer/vulkan/**'
    - 'python/**'
  pull_request:
    branches: [master]
    paths:
    - '.github/workflows/python.yml'
    - 'CMakeLists.txt'
    - 'cmake/**'
    - 'src/*'
    - 'src/layer/*'
    - 'src/layer/x86/**'
    - 'src/layer/vulkan/**'
    - 'python/**'
concurrency:
  group: python-${{ github.ref }}
  cancel-in-progress: true
env:
  DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
  MAC_DEPLOYMENT_TARGET: '11.0'
  ENABLE_BITCODE: OFF
  ENABLE_ARC: OFF
  ENABLE_VISIBILITY: OFF
  CMAKE_BUILD_PARALLEL_LEVEL: 4
  UseMultiToolTask: true
permissions:
  contents: read

jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-13, windows-latest]
        python-version: [3.9, 3.12]

    runs-on: ${{ matrix.os }}

    steps:
    - uses: actions/checkout@v4
      with:
        submodules: true

    - name: cache-swiftshader
      if: matrix.os == 'ubuntu-latest'
      id: cache-swiftshader
      uses: actions/cache@v4
      with:
        path: swiftshader-install
        key: swiftshader-linux-install-20240622
    - name: checkout-swiftshader
      if: matrix.os == 'ubuntu-latest' && steps.cache-swiftshader.outputs.cache-hit != 'true'
      uses: actions/checkout@v4
      with:
        repository: google/swiftshader
        path: swiftshader
        ref: de870ac7518fe2b6bb651ecc22fc36647cf7b986
    - name: checkout-swiftshader-submodules
      if: matrix.os == 'ubuntu-latest' && steps.cache-swiftshader.outputs.cache-hit != 'true'
      run: |
        cd swiftshader
        git -c submodule."third_party/git-hooks".update=none submodule update --init --recursive
    - name: swiftshader
      if: matrix.os == 'ubuntu-latest' && steps.cache-swiftshader.outputs.cache-hit != 'true'
      run: |
        cd swiftshader
        mkdir -p build; cd build
        cmake -DCMAKE_INSTALL_PREFIX=install -DSWIFTSHADER_BUILD_EGL=FALSE -DSWIFTSHADER_BUILD_GLESv2=FALSE -DSWIFTSHADER_BUILD_GLES_CM=FALSE -DSWIFTSHADER_BUILD_VULKAN=TRUE -DSWIFTSHADER_BUILD_PVR=FALSE -DSWIFTSHADER_BUILD_TESTS=FALSE -DSWIFTSHADER_ENABLE_ASTC=FALSE -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE -DREACTOR_BACKEND=Subzero -DREACTOR_DEFAULT_OPT_LEVEL=Default -DCMAKE_BUILD_TYPE=Release ..
        cmake --build . -j $(nproc)
        mkdir $GITHUB_WORKSPACE/swiftshader-install
        cp Linux/* $GITHUB_WORKSPACE/swiftshader-install

    - name: setup-python
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python-version }}
    - name: install-deps
      run: |
        python -m pip install --upgrade pip
        pip install pytest setuptools wheel twine importlib-metadata

    - name: build
      if: matrix.os == 'ubuntu-latest'
      env:
        CC: clang
        CXX: clang++
      run: |
        mkdir build && cd build
        cmake -DNCNN_VULKAN=ON -DNCNN_PYTHON=ON -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF ..
        cmake --build . -j $(nproc)
    - name: build
      if: matrix.os == 'macos-13'
      run: |
        mkdir build && cd build
        cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DPLATFORM=MAC -DARCHS="x86_64" \
            -DDEPLOYMENT_TARGET=$MAC_DEPLOYMENT_TARGET -DENABLE_BITCODE=$ENABLE_BITCODE -DENABLE_ARC=$ENABLE_ARC -DENABLE_VISIBILITY=$ENABLE_VISIBILITY \
            -DNCNN_VULKAN=OFF -DNCNN_PYTHON=ON -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF ..
        cmake --build . -j 4
    - name: build
      if: matrix.os == 'windows-latest'
      run: |
        mkdir build; cd build
        cmake -T v142,host=x64 -A x64 -DNCNN_VULKAN=OFF -DNCNN_PYTHON=ON -DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF ..
        cmake --build . --config Release -j 4
    - name: build-python
      run: cd python && pip install .
    - name: test
      if: matrix.os == 'ubuntu-latest'
      run: |
        export VK_ICD_FILENAMES="$GITHUB_WORKSPACE/swiftshader-install/vk_swiftshader_icd.json"
        cd python && pytest tests
    - name: test
      if: matrix.os != 'ubuntu-latest'
      run: |
        cd python && pytest tests
