name: model jobs

on:
  workflow_call:
    inputs:
      folder_slices:
        required: true
        type: string
      machine_type:
        required: true
        type: string
      slice_id:
        required: true
        type: number
      docker:
        required: true
        type: string
      commit_sha:
        required: false
        type: string
      report_name_prefix:
        required: false
        default: run_models_gpu
        type: string
      runner_type:
        required: false
        type: string
      report_repo_id:
        required: false
        type: string
      pytest_marker:
        required: false
        type: string

env:
  HF_HOME: /mnt/cache
  TRANSFORMERS_IS_CI: yes
  OMP_NUM_THREADS: 8
  MKL_NUM_THREADS: 8
  RUN_SLOW: yes
  # For gated repositories, we still need to agree to share information on the Hub repo. page in order to get access.
  # This token is created under the bot `hf-transformers-bot`.
  HF_HUB_READ_TOKEN: ${{ secrets.HF_HUB_READ_TOKEN }}
  TF_FORCE_GPU_ALLOW_GROWTH: true
  CUDA_VISIBLE_DEVICES: 0,1

jobs:
  run_models_gpu:
    name: " "
    strategy:
      max-parallel: 8
      fail-fast: false
      matrix:
        folders: ${{ fromJson(inputs.folder_slices)[inputs.slice_id] }}
    runs-on:
      group: '${{ inputs.machine_type }}'
    container:
      image: ${{ inputs.docker }}
      options: --gpus all --shm-size "16gb" --ipc host -v /mnt/cache/.cache/huggingface:/mnt/cache/
    outputs:
      machine_type: ${{ steps.set_machine_type.outputs.machine_type }}
    steps:
      - name: Echo input and matrix info
        shell: bash
        env:
          folder_slices: ${{ inputs.folder_slices }}
          matrix_folders: ${{ matrix.folders }}
          slice_data: ${{ toJson(fromJson(inputs.folder_slices)[inputs.slice_id]) }}
        run: |
          echo "$folder_slices"
          echo "$matrix_folders"
          echo "$slice_data"

      - name: Echo folder ${{ matrix.folders }}
        shell: bash
        # For folders like `models/bert`, set an env. var. (`matrix_folders`) to `models_bert`, which will be used to
        # set the artifact folder names (because the character `/` is not allowed).
        env:
          matrix_folders_raw: ${{ matrix.folders }}
        run: |
          echo "$matrix_folders_raw"
          matrix_folders="${matrix_folders_raw/'models/'/'models_'}"
          echo "$matrix_folders"
          echo "matrix_folders=$matrix_folders" >> $GITHUB_ENV

      - name: Update clone
        working-directory: /transformers
        env:
          commit_sha: ${{ inputs.commit_sha || github.sha }}
        run: |
          git fetch origin "$commit_sha" && git checkout "$commit_sha"

      - name: Reinstall transformers in edit mode (remove the one installed during docker image build)
        working-directory: /transformers
        run: python3 -m pip uninstall -y transformers && python3 -m pip install -e .

      - name: Update / Install some packages (for Past CI)
        if: ${{ contains(inputs.docker, '-past-') }}
        working-directory: /transformers
        run: |
          python3 -m pip install -U datasets

      - name: Update / Install some packages (for Past CI)
        if: ${{ contains(inputs.docker, '-past-') && contains(inputs.docker, '-pytorch-') }}
        working-directory: /transformers
        run: |
          python3 -m pip install --no-cache-dir git+https://github.com/huggingface/accelerate@main#egg=accelerate

      - name: NVIDIA-SMI
        run: |
          nvidia-smi

      - name: Environment
        working-directory: /transformers
        run: |
          python3 utils/print_env.py

      - name: Show installed libraries and their versions
        working-directory: /transformers
        run: pip freeze

      - name: Set `machine_type` for report and artifact names
        id: set_machine_type
        working-directory: /transformers
        shell: bash
        env:
          input_machine_type: ${{ inputs.machine_type }}
        run: |
          echo "$input_machine_type"

          if [ "$input_machine_type" = "aws-g5-4xlarge-cache" ]; then
            machine_type=single-gpu
          elif [ "$input_machine_type" = "aws-g5-12xlarge-cache" ]; then
            machine_type=multi-gpu
          else
            machine_type="$input_machine_type"
          fi

          echo "$machine_type"
          echo "machine_type=$machine_type" >> $GITHUB_ENV
          echo "machine_type=$machine_type" >> $GITHUB_OUTPUT

      - name: Create report directory if it doesn't exist
        shell: bash
        env:
          report_name_prefix: ${{ inputs.report_name_prefix }}
        run: |
          mkdir -p "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"
          echo "dummy" > "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/dummy.txt"
          ls -la "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"

      - name: Run all tests on GPU
        working-directory: /transformers
        env:
          report_name_prefix: ${{ inputs.report_name_prefix }}
          pytest_marker: ${{ inputs.pytest_marker }}
          model: ${{ matrix.folders }}
        run: |
          script -q -c "PATCH_TESTING_METHODS_TO_COLLECT_OUTPUTS=yes _PATCHED_TESTING_METHODS_OUTPUT_DIR=/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports python3 -m pytest -rsfE -v -m '${pytest_marker}' --make-reports=${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports tests/${model}" test_outputs.txt
          ls -la
          # Extract the exit code from the output file
          EXIT_CODE=$(tail -1 test_outputs.txt | grep -o 'COMMAND_EXIT_CODE="[0-9]*"' | cut -d'"' -f2)
          exit ${EXIT_CODE:-1}

      - name: Failure short reports
        if: ${{ failure() }}
        # This step is only to show information on Github Actions log.
        # Always mark this step as successful, even if the report directory or the file `failures_short.txt` in it doesn't exist
        continue-on-error: true
        env:
          report_name_prefix: ${{ inputs.report_name_prefix }}
        run: cat "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/failures_short.txt"

      - name: Captured information
        if: ${{ failure() }}
        continue-on-error: true
        env:
          report_name_prefix: ${{ inputs.report_name_prefix }}
        run: |
          cat "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports/captured_info.txt"

      - name: Copy test_outputs.txt
        if: ${{ always() }}
        continue-on-error: true
        env:
          report_name_prefix: ${{ inputs.report_name_prefix }}
        run: |
          cp /transformers/test_outputs.txt "/transformers/reports/${machine_type}_${report_name_prefix}_${matrix_folders}_test_reports"

      - name: "Test suite reports artifacts: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports"
        if: ${{ always() }}
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports
          path: /transformers/reports/${{ env.machine_type }}_${{ inputs.report_name_prefix }}_${{ env.matrix_folders }}_test_reports

  collated_reports:
    name: Collated Reports
    if: ${{ always() && inputs.runner_type != '' }}
    needs: run_models_gpu
    uses: huggingface/transformers/.github/workflows/collated-reports.yml@main
    with:
      job: run_models_gpu
      report_repo_id: ${{ inputs.report_repo_id }}
      gpu_name: ${{ inputs.runner_type }}
      machine_type: ${{ needs.run_models_gpu.outputs.machine_type }}
    secrets: inherit
