Skip to content

Commit 9d1c48a

Browse files
authored
[CICD] Upload unittest coverage report to FlagCICD platform && Access FlagCICD runner (flagos-ai#58)
# Description Simplifies and consolidates the coverage report generation logic in the CI unittest workflow, reducing redundant steps and dependencies. Need to test **uploading reports to FlagCICD step** in CI env. ## Type of change - [x] New feature (non-breaking change which adds functionality) - [x] Infra/Build change (changes to CI/CD workflows or build scripts) - [x] Code refactoring - [ ] Documentation change - [ ] Bug fix - [ ] Breaking change ## Changes - Merged `Generate Coverage Report` into the `Execute Tests` step — coverage `combine` and `json` generation now run inline after `bash test.sh`, following the same pattern as Megatron-LM-FL - Coverage collection is gated on `test_type == 'unittest'` to avoid running for lint/debug groups, and `pip install` is done only once - Removed `fetch-depth: 0` from checkout steps (not required for unit test runs) - Removed unused/leftover scripts from the repository ## TODO # Checklist: - [x] I have read and followed the contributing guidelines. - [x] The functionality is complete - [x] I have commented my code, particularly in coverage report uploading steps - [x] My changes generate no new warnings - [x] I have added/updated tests that prove my feature works on Cuda and Metax platform. - [x] New and existing unit tests pass locally on Cuda and Metax platform.
1 parent ebcfadc commit 9d1c48a

8 files changed

Lines changed: 86 additions & 72 deletions

File tree

.github/configs/cuda.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ display_name: 'NVIDIA CUDA (A100)'
88
ci_image: harbor.baai.ac.cn/flagscale/cuda12.8.1-torch2.7.1-python3.10-te2.9:20260209
99

1010
# Runner labels for self-hosted A100 node
11+
# runner_labels:
12+
# - self-hosted
13+
# - Linux
14+
# - X64
15+
# - nvidia
16+
# - gpu-8
1117
runner_labels:
12-
- self-hosted
13-
- Linux
14-
- X64
15-
- nvidia
16-
- gpu-8
18+
- nv-8g-cicd-te
1719

1820
# Container volumes
1921
container_volumes:
2022
- /home/flagscale_cicd/flask/static:/workspace/report
21-
# - .:/opt/transformerengine
22-
# - ./ci_logs:/logs
2323
# - /home/flagscale_cicd/data:/opt/data
2424

2525
# Container options

.github/configs/metax.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ hardware_name: metax
66
display_name: 'Metax Tests'
77

88
ci_image: localhost:5000/megatron-lm-with-te:v1
9+
# ci_image: harbor.baai.ac.cn/flagscale/megatron-lm-with-te:202603231839
910

1011
runner_labels:
1112
- self-hosted
1213
- Linux
1314
- X64
1415
- metax
1516
- dev
17+
# runner_labels:
18+
# - mx-4g-cicd-te
1619

1720
container_volumes:
1821
- /nfs/metax_fs:/nfs/metax_fs

.github/workflows/all_tests_common.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ jobs:
9292
uses: ./.github/workflows/unit_tests_common.yml
9393
name: unit_tests
9494
with:
95-
setup_commands: ${{ inputs.setup_commands }}
9695
platform: ${{ inputs.platform }}
9796
device: ${{ matrix.device }}
9897
image: ${{ needs.checkout_and_config.outputs.ci_image }}
9998
runs_on: ${{ needs.checkout_and_config.outputs.runs_on }}
10099
container_volumes: ${{ needs.checkout_and_config.outputs.container_volumes }}
101100
container_options: ${{ needs.checkout_and_config.outputs.container_options }}
101+
setup_commands: ${{ inputs.setup_commands }}
102102
ignored_tests: ${{ needs.checkout_and_config.outputs.ignored_tests }}
103103
build_env: ${{ needs.checkout_and_config.outputs.build_env }}
104104

.github/workflows/all_tests_cuda.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name: cuda_tests
22

33
on:
4-
# push:
5-
# branches: ["main"]
6-
# pull_request:
7-
# branches: ["main"]
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["main"]
88
workflow_dispatch:
99

1010
concurrency:

.github/workflows/qa-l0-te-cpp-unittest-pytorch-lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
7373
# Install Python dependencies with version pinning
7474
echo "=== Installing Python Dependencies ==="
75-
pip install transformers expecttest
75+
pip install transformers expecttest nvdlfw-inspect --quiet
7676
7777
# Build and install transformer_engine with verbose output
7878
echo "=== Building & Installing Transformer Engine ==="

.github/workflows/unit_tests_common.yml

Lines changed: 69 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,46 @@ jobs:
115115
# For debugging, you can force this to true
116116
echo "should_run=true" >> $GITHUB_OUTPUT
117117
118-
- name: Checkout Source Code
119-
if: steps.should_run.outputs.should_run == 'true'
118+
# Cuda requires git safe.directory configuration and 3 checkout attempts to handle submodule-heavy repos
119+
- name: Configure Git Safe Directory on Cuda
120+
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'cuda'
121+
run: /usr/bin/git config --global safe.directory '*'
122+
123+
- name: Checkout Source Code on Cuda (attempt 1)
124+
id: checkout1
125+
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'cuda'
120126
uses: actions/checkout@v4
127+
continue-on-error: true
121128
with:
129+
fetch-depth: 0
130+
submodules: recursive
122131
set-safe-directory: true
123132

124-
# - name: Activate Python environment
125-
# run: |
126-
# if [[ "$PLATFORM" == "cuda" ]] && [ -f /opt/miniconda3/etc/profile.d/conda.sh ]; then
127-
# source /opt/miniconda3/etc/profile.d/conda.sh
128-
# conda activate flagscale-train
129-
# elif [ -f /opt/conda/etc/profile.d/conda.sh ]; then
130-
# source /opt/conda/etc/profile.d/conda.sh
131-
# conda activate base
132-
# fi
133-
# echo "PATH=$PATH" >> $GITHUB_ENV
134-
# echo "Python: $(which python3) ($(python3 --version 2>&1))"
133+
- name: Checkout Source Code on Cuda (attempt 2)
134+
id: checkout2
135+
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'cuda' && steps.checkout1.outcome == 'failure'
136+
uses: actions/checkout@v4
137+
continue-on-error: true
138+
with:
139+
fetch-depth: 0
140+
submodules: recursive
141+
set-safe-directory: true
142+
143+
- name: Checkout Source Code on Cuda (attempt 3)
144+
id: checkout3
145+
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'cuda' && steps.checkout2.outcome == 'failure'
146+
uses: actions/checkout@v4
147+
with:
148+
fetch-depth: 0
149+
submodules: recursive
150+
set-safe-directory: true
151+
152+
# Metax no need submodules
153+
- name: Checkout Source Code on Metax
154+
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'metax'
155+
uses: actions/checkout@v4
156+
with:
157+
fetch-depth: 0
135158

136159
- name: Environment Setup on Cuda
137160
if: steps.should_run.outputs.should_run == 'true' && inputs.platform == 'cuda'
@@ -149,8 +172,10 @@ jobs:
149172
150173
echo "===== Step 2: Build & Install TransformerEngine ====="
151174
cd $GITHUB_WORKSPACE
152-
pip install nvdlfw-inspect --no-deps
153-
pip install --no-build-isolation . -v --no-deps
175+
176+
pip install nvdlfw-inspect --quiet
177+
pip install expecttest --quiet
178+
pip install . -v --no-deps --no-build-isolation
154179
155180
echo "===== Step 3: Verify Installation ====="
156181
python3 tests/pytorch/test_sanity_import.py
@@ -186,7 +211,8 @@ jobs:
186211
echo "===== Step 4: Remove Existing TransformerEngine ====="
187212
# Prevent conflicts with preinstalled or incompatible versions
188213
python3 -m pip uninstall transformer_engine -y || true
189-
python3 -m pip install nvdlfw-inspect --no-deps || true
214+
python3 -m pip install nvdlfw-inspect --quiet
215+
python3 -m pip install expecttest --quiet
190216
191217
# echo "===== Step 5: Install Metax Binary Backend ====="
192218
# # Install prebuilt Metax backend (required for MACA operators)
@@ -229,7 +255,6 @@ jobs:
229255
working-directory: ${{ github.workspace }}
230256
run: |
231257
set -euo pipefail
232-
${{ inputs.setup_commands }}
233258
234259
# Load platform-specific environment variables
235260
while IFS='=' read -r key value; do
@@ -257,11 +282,15 @@ jobs:
257282
# Ensure log directory exists regardless of volume mount state
258283
mkdir -p /logs
259284
260-
# Enable coverage collection for all pytest invocations in test.sh
261-
# PYTEST_ADDOPTS is automatically appended to every pytest call
262-
if [ "${{ inputs.upload_coverage }}" = "true" ]; then
263-
pip3 install pytest-cov 2>/dev/null || true
264-
export PYTEST_ADDOPTS="--cov=transformer_engine --cov-append --cov-report="
285+
# Coverage setup: install once + configure collection via PYTEST_ADDOPTS
286+
COVERAGE_ENABLED=false
287+
if [ "${{ inputs.upload_coverage }}" = "true" ] && [ "${{ matrix.test_group.test_type }}" = "unittest" ]; then
288+
if pip3 install coverage pytest-cov --quiet 2>/dev/null; then
289+
export PYTEST_ADDOPTS="--cov=transformer_engine --cov-append --cov-report="
290+
COVERAGE_ENABLED=true
291+
else
292+
echo "WARNING: Failed to install coverage/pytest-cov, coverage collection disabled"
293+
fi
265294
fi
266295
267296
if [[ "${{ matrix.test_group.name }}" == *"lint"* ]]; then
@@ -274,55 +303,39 @@ jobs:
274303
fi
275304
276305
bash ${{ matrix.test_group.path }}
277-
timeout-minutes: 60
306+
exit_code=$?
307+
308+
# Combine coverage fragments and generate JSON report
309+
if [ "$COVERAGE_ENABLED" = "true" ]; then
310+
python3 -m coverage combine --keep 2>/dev/null || true
311+
python3 -m coverage json \
312+
-o "coverage-${{ inputs.platform }}-${{ inputs.device }}-${{ matrix.test_group.name }}.json" \
313+
--include="transformer_engine/*" 2>/dev/null \
314+
|| echo "WARNING: No coverage data found"
315+
fi
278316
279-
- name: Generate Coverage Report
280-
if: inputs.upload_coverage && matrix.test_group.test_type == 'unittest'
281-
working-directory: ${{ github.workspace }}
282-
env:
283-
PLATFORM: ${{ inputs.platform }}
284-
DEVICE: ${{ inputs.device }}
285-
run: |
286-
# Install coverage (may already be present)
287-
pip3 install coverage pytest-cov 2>/dev/null || true
288-
289-
# Merge all .coverage* files produced by sub-processes (torchrun spawns workers)
290-
python3 -m coverage combine --keep 2>/dev/null || true
291-
# Generate JSON coverage report (requires .coverage data from pytest --cov)
292-
python3 -m coverage json -o "coverage-${PLATFORM}-${DEVICE}.json" \
293-
--include="transformer_engine/*" 2>/dev/null || echo "WARNING: No coverage data found, skipping coverage-${PLATFORM}-${DEVICE}.json"
294-
continue-on-error: true
317+
exit $exit_code
318+
timeout-minutes: 60
295319

296320
- name: Upload Coverage Report
297321
if: inputs.upload_coverage && matrix.test_group.test_type == 'unittest'
298322
uses: actions/upload-artifact@v4
299323
continue-on-error: true
300324
with:
301-
name: coverage-${{ inputs.platform }}-${{ inputs.device }}
325+
name: coverage-${{ inputs.platform }}-${{ inputs.device }}-${{ matrix.test_group.name }}
302326
path: |
303-
coverage-${{ inputs.platform }}-${{ inputs.device }}.json
304-
305-
- name: Check FlagCICD Reachability
306-
if: inputs.upload_coverage && matrix.test_group.test_type == 'unittest'
307-
id: check_flagcicd
308-
continue-on-error: true
309-
run: |
310-
if curl -sf --max-time 3 --connect-timeout 2 \
311-
"http://flagcicd-inner.flagos.net:8000/" -o /dev/null 2>/dev/null; then
312-
echo "reachable=true" >> $GITHUB_OUTPUT
313-
else
314-
echo "reachable=false" >> $GITHUB_OUTPUT
315-
echo "INFO: flagcicd-inner.flagos.net unreachable from this runner, skipping report upload"
316-
fi
327+
coverage-${{ inputs.platform }}-${{ inputs.device }}-${{ matrix.test_group.name }}.json
317328
318329
- name: Upload Coverage Report to FlagCICD
319-
if: inputs.upload_coverage && matrix.test_group.test_type == 'unittest' && steps.check_flagcicd.outputs.reachable == 'true'
330+
if: inputs.upload_coverage && matrix.test_group.test_type == 'unittest'
320331
uses: flagos-ai/FlagOps/actions/post-pytest-report@v2
321332
continue-on-error: true
333+
env:
334+
NO_PROXY: "flagcicd-inner.flagos.net"
322335
with:
323336
backend_url: 'http://flagcicd-inner.flagos.net:8000/metrics/'
324337
user_id: '000000000000000000'
325-
report_path: 'coverage-${{ inputs.platform }}-${{ inputs.device }}.json'
338+
report_path: 'coverage-${{ inputs.platform }}-${{ inputs.device }}-${{ matrix.test_group.name }}.json'
326339
fail_on_error: 'false'
327340

328341
# - name: Debug - keep container alive on failure

qa/L0_pytorch_debug_unittest/test.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ FAIL=0
1818

1919
# It is not installed as a requirement,
2020
# because it is not available on PyPI.
21-
pip uninstall -y nvdlfw-inspect
22-
pip install git+https://github.com/NVIDIA/nvidia-dlfw-inspect.git
2321
pip install pytest==8.2.1
2422

2523
run_test_step() {

qa/L0_pytorch_lint/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ set -e
66

77
: "${TE_PATH:=/opt/transformerengine}"
88

9-
pip3 install cpplint==1.6.0 pylint==3.3.1
9+
pip3 install cpplint==1.6.0 pylint==3.3.4
1010
if [ -z "${PYTHON_ONLY}" ]
1111
then
1212
cd $TE_PATH

0 commit comments

Comments
 (0)