Skip to content

Commit 0cb90a1

Browse files
[CI][CD] Add xpu3.6 workflow runner and fix iluvater3.6 delivery (#777)
--------- Co-authored-by: flagtree-bot <flagtree_ai@163.com>
1 parent 64d8243 commit 0cb90a1

7 files changed

Lines changed: 284 additions & 47 deletions

File tree

.github/workflows/iluvatar3.6-delivery.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99
default: '0.6.0'
1010
PYTHON_VER:
1111
required: true
12-
default: '3.10'
12+
default: '3.12'
1313
PLATFORM:
1414
required: true
1515
default: 'x86_64'
@@ -24,7 +24,7 @@ on:
2424
PYTHON_VER:
2525
type: string
2626
required: true
27-
default: '3.10'
27+
default: '3.12'
2828
PLATFORM:
2929
type: string
3030
required: true
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Xpu3.6-Build-And-Test
2+
3+
on:
4+
push:
5+
branches: [ "triton_v3.6.x" ]
6+
pull_request:
7+
branches: [ "triton_v3.6.x" ]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
xpu-build-and-test:
15+
runs-on: xpu3.6
16+
if: ${{ github.repository == 'FlagTree/flagtree' || github.repository == 'flagos-ai/flagtree' }}
17+
steps:
18+
- name: Setup environment
19+
shell: bash
20+
run: |
21+
source ~/env.sh
22+
env | grep -E '^(http_proxy|https_proxy|all_proxy|no_proxy)=' >> $GITHUB_ENV || true
23+
24+
- name: Smart Checkout
25+
uses: flagos-ai/FlagTree/.github/actions/smart-checkout@main
26+
with:
27+
checkout_version: 'v6'
28+
29+
- name: Check if backend-relevant files changed
30+
id: check_backend
31+
uses: flagos-ai/FlagTree/.github/actions/check-backend-changed@main
32+
with:
33+
backend: xpu
34+
35+
- name: FlagTree Build on Xpu
36+
if: steps.check_backend.outputs.should_skip != 'true'
37+
shell: bash
38+
run: |
39+
set -x
40+
export FLAGTREE_BACKEND=xpu
41+
MAX_JOBS=32 python3 -m pip install . --no-build-isolation
42+
43+
- name: FlagTree Test on Xpu
44+
if: steps.check_backend.outputs.should_skip != 'true'
45+
shell: bash
46+
run: |
47+
set -x
48+
source ~/env.sh
49+
export XPU_EVENT_KL3_ENABLE=1
50+
cd third_party/xpu/python/test/unit
51+
python3 -m pytest -s . \
52+
--ignore=language/test_compile_errors.py \
53+
--ignore=language/test_random.py \
54+
--ignore=runtime/test_bindings.py \
55+
--ignore=runtime/test_cache.py \
56+
--ignore=runtime/test_subproc.py \
57+
-k "not test_decorator_with_def"
58+
python3 -m pytest -s runtime/test_cache.py \
59+
-k "test_changed_line_numbers_invalidate_cache or \
60+
test_local_shadows_global or \
61+
test_use_builtin or \
62+
test_no_cache_module_as_global or \
63+
test_cache_builtin_as_global or \
64+
test_no_cache_callable or \
65+
test_memory_leak"
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
name: CD-Xpu3.6
2+
3+
permissions:
4+
contents: write
5+
6+
on:
7+
workflow_dispatch:
8+
inputs:
9+
WHL_VER:
10+
description: '0.6.0.dev1 < 0.6.0a1 < 0.6.0b1 < 0.6.0rc1 < 0.6.0 < 0.6.0.post1'
11+
required: true
12+
default: '0.6.0'
13+
PYTHON_VER:
14+
required: true
15+
default: '3.10'
16+
PLATFORM:
17+
required: true
18+
default: 'x86_64'
19+
FLAGTREE_PYPI_KEY:
20+
required: false
21+
workflow_call:
22+
inputs:
23+
WHL_VER:
24+
type: string
25+
required: true
26+
default: '0.6.0'
27+
PYTHON_VER:
28+
type: string
29+
required: true
30+
default: '3.10'
31+
PLATFORM:
32+
type: string
33+
required: true
34+
default: 'x86_64'
35+
FLAGTREE_PYPI_KEY:
36+
type: string
37+
required: false
38+
39+
concurrency:
40+
group: ${{ github.workflow }}-${{ inputs.WHL_VER }}-${{ inputs.PYTHON_VER }}-${{ inputs.PLATFORM }}
41+
cancel-in-progress: true
42+
43+
jobs:
44+
delivery:
45+
runs-on: xpu3.6-cd
46+
if: ${{ github.repository == 'FlagTree/flagtree' || github.repository == 'flagos-ai/flagtree' }}
47+
steps:
48+
- name: Check branch
49+
shell: bash
50+
run: |
51+
TARGET_BRANCH="${{ github.ref_name }}"
52+
if [[ ! "$TARGET_BRANCH" =~ ^(triton_v3.6.x)$ ]]; then
53+
echo "❌ This workflow must be run from branch 'triton_v3.6.x', but got '${TARGET_BRANCH}'"
54+
exit 1
55+
fi
56+
echo "TARGET_BRANCH=$TARGET_BRANCH" >> $GITHUB_ENV
57+
echo "✅ Branch check passed: ${TARGET_BRANCH}"
58+
59+
- name: Setup environment
60+
shell: bash
61+
run: |
62+
source ~/env.sh
63+
env | grep -E '^(http_proxy|https_proxy|all_proxy|no_proxy)=' >> $GITHUB_ENV || true
64+
65+
- name: Smart Checkout
66+
uses: flagos-ai/FlagTree/.github/actions/smart-checkout@main
67+
with:
68+
checkout_version: 'v6'
69+
70+
- name: FlagTree bdist_wheel on Xpu (triton_v3.6.x branch)
71+
if: ${{ env.TARGET_BRANCH == 'triton_v3.6.x' }}
72+
shell: bash
73+
run: |
74+
set -x
75+
TRITON_VER="3.6"
76+
CHIP=""
77+
export FLAGTREE_BACKEND=xpu
78+
WHL_VER=${{ inputs.WHL_VER }}
79+
PYTHON_VER=${{ inputs.PYTHON_VER }}
80+
export FLAGTREE_WHEEL_VERSION="${WHL_VER}+${FLAGTREE_BACKEND}${CHIP}${TRITON_VER}"
81+
82+
RES="--index-url=https://resource.flagos.net/repository/flagos-pypi-hosted/simple"
83+
if python${PYTHON_VER} -m pip download --no-deps "flagtree===${FLAGTREE_WHEEL_VERSION}" -d . $RES >/dev/null 2>&1; then
84+
echo "❌ flagtree===${FLAGTREE_WHEEL_VERSION} already exists!"
85+
exit 1
86+
else
87+
echo "✅ flagtree===${FLAGTREE_WHEEL_VERSION} does not exist, proceed to build"
88+
fi
89+
90+
rm -rf ./build ./*.egg-info
91+
{ export FLAGTREE_PYPI_KEY=${{ inputs.FLAGTREE_PYPI_KEY }}; } 2>/dev/null
92+
export TRITON_APPEND_CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release"
93+
MAX_JOBS=32 python${PYTHON_VER} setup.py bdist_wheel -d ~/dist-flagtree
94+
env | grep -E '^(FLAGTREE_WHEEL_VERSION)=' >> $GITHUB_ENV || true
95+
96+
- name: FlagTree upload whl
97+
shell: bash
98+
run: |
99+
set -x
100+
PLATFORM=${{ inputs.PLATFORM }}
101+
PYTHON_VER=${{ inputs.PYTHON_VER }}
102+
CP_VER=$(printf '%s' "$PYTHON_VER" | tr -d '.')
103+
FLAGTREE_WHL="flagtree-${FLAGTREE_WHEEL_VERSION}-cp${CP_VER}-cp${CP_VER}-linux_${PLATFORM}.whl"
104+
pushd ~/dist-flagtree
105+
twine check ${FLAGTREE_WHL}
106+
echo "Upload ${FLAGTREE_WHL}"
107+
bash upload_flagtree_whl.sh "${FLAGTREE_WHL}"
108+
popd
109+
110+
- name: FlagTree push tag
111+
shell: bash
112+
env:
113+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
114+
run: |
115+
set -x
116+
git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git
117+
TAG="${FLAGTREE_WHEEL_VERSION}"
118+
git config user.name "flagtree-bot"
119+
git config user.email "flagtree_ai@163.com"
120+
if git rev-parse "${TAG}" >/dev/null 2>&1; then
121+
echo "⚠️ Tag '${TAG}' already exists, force moving to current commit"
122+
git tag -f -a "${TAG}" -m "pypi ${TAG}"
123+
else
124+
git tag -a "${TAG}" -m "pypi ${TAG}"
125+
fi
126+
MAX_RETRY=100
127+
RETRY_INTERVAL=10
128+
success=false
129+
for i in $(seq 1 $MAX_RETRY); do
130+
echo "Attempt ${i}/${MAX_RETRY}:"
131+
if git push --force origin "${TAG}"; then
132+
success=true
133+
break
134+
fi
135+
echo "Push failed, retrying in ${RETRY_INTERVAL}s..."
136+
sleep $RETRY_INTERVAL
137+
done
138+
if [ "$success" != "true" ]; then
139+
echo "git push failed after $MAX_RETRY attempts"
140+
exit 1
141+
fi

python/setup_tools/setup_helper.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,18 @@ def check_pybind11_abi():
444444
hook_call(cache=cache)
445445

446446

447-
def overlay_backend_runtime_so():
447+
def overlay_backend_runtime_so(build_py_command=None, backends=None):
448448
hook_call = get_hook_instance("overlay_runtime_so")
449449
if hook_call:
450-
hook_call(cache=cache)
450+
hook_call(cache=cache, build_py_command=build_py_command, backends=backends)
451+
452+
453+
def get_backend_package_data(backends):
454+
hook_call = get_hook_instance("get_package_data")
455+
if not hook_call:
456+
return {}
457+
write_flagtree_backend_file()
458+
return hook_call(backends)
451459

452460

453461
def write_backend_site_pth(dest_dir):

python/setup_tools/utils/xpu.py

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,27 +257,73 @@ def check_pybind11_abi(cache):
257257
ensure_pybind11_matches_sdnn(scan_dir)
258258

259259

260-
def overlay_runtime_so(cache):
260+
def collect_xpu_backend_package_data(backend):
261+
files = []
262+
driver_c = Path(backend.backend_dir) / "driver.c"
263+
if driver_c.exists():
264+
files.append("driver.c")
265+
xpu3_dir = Path(backend.backend_dir) / "xpu3"
266+
if xpu3_dir.is_dir():
267+
files.extend(str(path.relative_to(backend.backend_dir)) for path in xpu3_dir.rglob("*") if path.is_file())
268+
return files
269+
270+
271+
def ensure_xpu_launch_static_lib(backend):
272+
src = Path(backend.src_dir) / "device" / "liblaunch.a"
273+
if not src.exists():
274+
print(f"[XPU] liblaunch.a not found at {src}; packaged launcher may fail to link", file=sys.stderr)
275+
return
276+
dst = Path(backend.backend_dir) / "xpu3" / "lib" / "liblaunch.a"
277+
dst.parent.mkdir(parents=True, exist_ok=True)
278+
shutil.copy2(src, dst)
279+
print(f"[XPU] copied liblaunch.a: {src} -> {dst}", file=sys.stderr)
280+
281+
282+
def get_package_data(backends):
283+
package_data = {"triton": ["FLAGTREE_BACKEND"]}
284+
for backend in backends:
285+
if backend.name == "xpu":
286+
files = collect_xpu_backend_package_data(backend)
287+
if files:
288+
package_data["triton.backends.xpu"] = files
289+
break
290+
return package_data
291+
292+
293+
def overlay_runtime_so(cache, build_py_command=None, backends=None):
261294
"""Overwrite third_party/xpu/backend/xpu3/so with the fixed runtime .so set."""
262295
try:
263296
src = Path(cache.get("xpu-runtime-so"))
264297
except KeyError:
265-
return
266-
if not src.is_dir():
298+
src = None
299+
if src is None or not src.is_dir():
267300
print(f"[XPU] runtime-so overlay skipped: {src} not found")
301+
else:
302+
dst = Path(cache.flagtree_dir) / "third_party" / "xpu" / "backend" / "xpu3" / "so"
303+
if dst.exists():
304+
shutil.rmtree(dst)
305+
os.makedirs(dst, exist_ok=True)
306+
for item in os.listdir(src):
307+
s = src / item
308+
d = dst / item
309+
if s.is_dir():
310+
shutil.copytree(s, d, symlinks=True)
311+
else:
312+
shutil.copy2(s, d)
313+
print(f"[XPU] runtime-so overlay applied: {src} -> {dst}")
314+
315+
if build_py_command is None or backends is None:
268316
return
269-
dst = Path(cache.flagtree_dir) / "third_party" / "xpu" / "backend" / "xpu3" / "so"
270-
if dst.exists():
271-
shutil.rmtree(dst)
272-
os.makedirs(dst, exist_ok=True)
273-
for item in os.listdir(src):
274-
s = src / item
275-
d = dst / item
276-
if s.is_dir():
277-
shutil.copytree(s, d, symlinks=True)
278-
else:
279-
shutil.copy2(s, d)
280-
print(f"[XPU] runtime-so overlay applied: {src} -> {dst}")
317+
build_py_command.distribution.package_data = build_py_command.distribution.package_data or {}
318+
for backend in backends:
319+
if backend.name == "xpu":
320+
ensure_xpu_launch_static_lib(backend)
321+
files = collect_xpu_backend_package_data(backend)
322+
if files:
323+
build_py_command.distribution.package_data["triton.backends.xpu"] = files
324+
build_py_command.package_data = build_py_command.distribution.package_data
325+
build_py_command.__dict__.pop("data_files", None)
326+
break
281327

282328

283329
_XPU_LIBSTDCXX_PTH_NAME = "zzz_flagtree_xpu_libstdcxx.pth"

setup.py

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ def run(self) -> None:
406406
# Re-apply the fixed xpu runtime .so overlay after cmake: device/CMakeLists.txt
407407
# copies the stale liblaunch_shared.so/libxpujitc.so into backend/xpu3/so during
408408
# build_ext, so we overwrite them again before build_py packages the wheel.
409-
helper.overlay_backend_runtime_so()
409+
helper.overlay_backend_runtime_so(self, backends)
410410
ret = super().run()
411411
# xpu-only: ensure triton/FLAGTREE_BACKEND lands in the wheel: build_py only
412412
# copies .py by default, so this extension-less marker (read by
@@ -741,31 +741,7 @@ def get_packages():
741741

742742

743743
def get_package_data():
744-
package_data = {}
745-
if helper.flagtree_backend == "xpu":
746-
# xpu-only: declare the FLAGTREE_BACKEND marker as package data so build_py
747-
# copies it into build_lib/triton (and thus into the wheel + final install).
748-
# Writing it to the source tree here guarantees the file physically exists
749-
# when build_py globs package_data, instead of relying only on a post-run
750-
# write into build_lib. Gated to xpu so other backends' wheels are unchanged.
751-
helper.write_flagtree_backend_file()
752-
package_data["triton"] = ["FLAGTREE_BACKEND"]
753-
for backend in backends:
754-
if backend.name != "xpu":
755-
continue
756-
files = []
757-
driver_c = os.path.join(backend.backend_dir, "driver.c")
758-
if os.path.exists(driver_c):
759-
files.append("driver.c")
760-
xpu3_dir = os.path.join(backend.backend_dir, "xpu3")
761-
if os.path.isdir(xpu3_dir):
762-
for root, _, filenames in os.walk(xpu3_dir):
763-
for filename in filenames:
764-
files.append(os.path.relpath(os.path.join(root, filename), backend.backend_dir))
765-
if files:
766-
package_data["triton.backends.xpu"] = files
767-
break
768-
return package_data
744+
return helper.get_backend_package_data(backends)
769745

770746

771747
def add_link_to_backends(external_only):

third_party/xpu/backend/driver.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ def get_xpu_library_dirs(arch: int = -1):
2929
include_dir = [os.path.join(dirname, f"xpu{arch}", "include")]
3030
libdevice_dir = os.path.join(dirname, f"xpu{arch}", "lib")
3131
library_dir = os.path.join(dirname, f"xpu{arch}", "so")
32+
launch_lib = "liblaunch.a" if os.path.exists(os.path.join(libdevice_dir, "liblaunch.a")) else "launch"
3233
if os.path.exists(os.path.join(library_dir, "libLaunch_shared.a")) or os.path.exists(
3334
os.path.join(library_dir, "liblaunch_shared.so")):
34-
libraries = ["launch", "xpurt", "launch_shared"]
35+
libraries = [launch_lib, "xpurt", "launch_shared"]
3536
else:
36-
libraries = ["launch", "xpurt"]
37+
libraries = [launch_lib, "xpurt"]
3738
return include_dir, [libdevice_dir, library_dir], libraries
3839

3940

0 commit comments

Comments
 (0)