diff --git a/.claude/skill/pto_debug_skill.md b/.claude/skill/pto_debug_skill.md index 99d04aca0c..389b3c9611 100644 --- a/.claude/skill/pto_debug_skill.md +++ b/.claude/skill/pto_debug_skill.md @@ -20,7 +20,7 @@ PTOAS 编译器调试工作流。给定一个 `.pto` 文件,AI 自动生成配 3. 全局替换:tadd→, TADD→ 4. 按 cases.py 调整 shape/dtype/eps 5. 修改 gen_data.py 的 golden 公式 -6. 运行: python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t -p build/tools/ptoas/ptoas +6. 运行: python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t 7. 如果比对失败 → 阶段 2 TPrint 调试 ``` @@ -29,7 +29,8 @@ PTOAS 编译器调试工作流。给定一个 `.pto` 文件,AI 自动生成配 ## 前置 ```bash -source scripts/ptoas_env.sh +LLVM_BUILD_DIR=/path/to/llvm/build ./quick_install.sh +source "${ASCEND_HOME_PATH}/bin/setenv.bash" ``` 所有命令从 repo root 执行。 @@ -45,7 +46,7 @@ source scripts/ptoas_env.sh | PTO IR 样本/测试 | `test/samples//` | | ST testcase | `test/tilelang_st/npu/a5/src/st/testcase/` | | ST 运行脚本 | `test/tilelang_st/script/run_st.py` | -| ptoas 二进制 | `build/tools/ptoas/ptoas` | +| ptoas 命令 | 当前 Python 环境安装的 `ptoas`(可用 `PTOAS_BIN` 覆盖) | | ODS 定义 | `include/PTO/IR/PTOOps.td` | | VPTO ODS 定义 | `include/PTO/IR/VPTOOps.td` | | C++ IR/Verifier | `lib/PTO/IR/PTO.cpp` | @@ -668,22 +669,22 @@ TPrint 不匹配时,按以下顺序排查: **完整验证**: ```bash -ninja -C build ptoas && \ +ninja -C build ptoas && pip install -e . --no-build-isolation && \ rm -rf test/tilelang_st/npu/a5/src/st/build && \ - python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t -p build/tools/ptoas/ptoas + python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t ``` ### run_st.py 常用参数 ```bash # 运行单个 op 的所有 case -python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd -p build/tools/ptoas/ptoas +python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd # 只运行特定 case -python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd -c f32_16x64 -p build/tools/ptoas/ptoas +python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd -c f32_16x64 # 跳过构建(使用已有 build) -python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd -p build/tools/ptoas/ptoas --without-build +python3 test/tilelang_st/script/run_st.py -r sim -v a5 -t tadd --without-build ``` --- diff --git a/.codex/skills/build-ptoas-wsl/SKILL.md b/.codex/skills/build-ptoas-wsl/SKILL.md index dabd88045d..e99749963f 100644 --- a/.codex/skills/build-ptoas-wsl/SKILL.md +++ b/.codex/skills/build-ptoas-wsl/SKILL.md @@ -1,13 +1,13 @@ --- name: build-ptoas-wsl -description: Build PTOAS from source inside WSL using the repository README workflow. Use when Codex is asked to build, configure, install, test, or troubleshoot ptoas/PTOAS in WSL or Ubuntu, including LLVM/MLIR llvmorg-19.1.7 setup, CMake/Ninja out-of-tree builds, pybind11 Python bindings, runtime environment variables, CLI smoke tests, or Python dialect import validation. +description: Build PTOAS from source inside WSL using the repository README workflow. Use when Codex is asked to build, configure, install, test, or troubleshoot ptoas/PTOAS in WSL or Ubuntu, including the VPTO LLVM 21 setup, editable scikit-build-core installs, CMake/Ninja incremental builds, namespaced MLIR Python bindings, CLI smoke tests, or Python dialect import validation. --- # Build PTOAS in WSL ## Overview -Use this skill to build PTOAS in a Linux environment under WSL. Keep the build aligned with the README: LLVM/MLIR must be `llvmorg-19.1.7`, LLVM must be built with shared libraries and MLIR Python bindings, and PTOAS is built out-of-tree against that LLVM build. +Use this skill to build PTOAS in a Linux environment under WSL. Keep the build aligned with the README: use the VPTO-enabled LLVM branch `feature-vpto-llvm21`, build shared LLVM/MLIR libraries with Python bindings, and install PTOAS through the repository's standard editable PEP 517 workflow. Prefer running Linux build commands through WSL, not Windows PowerShell/CMake. If the user is already in a Windows checkout, either convert the path to `/mnt/c/...` for a quick build or clone/copy into the WSL ext4 filesystem for better performance. @@ -31,10 +31,11 @@ wsl.exe -- bash -lc 'uname -a; cat /etc/os-release | head' ```bash sudo apt-get update sudo apt-get install -y git cmake ninja-build build-essential python3 python3-pip python3-dev -python3 -m pip install --user pybind11==2.12.0 numpy +python3 -m pip install --user \ + 'scikit-build-core>=0.12.2,<2' 'pybind11<3' 'nanobind>=2.4' numpy ``` -Pin `pybind11==2.12.0`; LLVM/MLIR Python bindings are not compatible with pybind11 3.x in this workflow. +Keep `pybind11<3`; LLVM/MLIR Python bindings are not compatible with pybind11 3.x in this workflow. ## Environment Variables @@ -45,7 +46,6 @@ export WORKSPACE_DIR=$HOME/llvm-workspace export LLVM_SOURCE_DIR=$WORKSPACE_DIR/llvm-project export LLVM_BUILD_DIR=$LLVM_SOURCE_DIR/build-shared export PTO_SOURCE_DIR=$WORKSPACE_DIR/PTOAS -export PTO_INSTALL_DIR=$PTO_SOURCE_DIR/install mkdir -p "$WORKSPACE_DIR" ``` @@ -65,18 +65,22 @@ Build LLVM only once per WSL workspace unless the user requests a clean rebuild. ```bash cd "$WORKSPACE_DIR" if [ ! -d "$LLVM_SOURCE_DIR/.git" ]; then - git clone https://github.com/llvm/llvm-project.git "$LLVM_SOURCE_DIR" + git clone https://github.com/vpto-dev/llvm-project.git "$LLVM_SOURCE_DIR" fi cd "$LLVM_SOURCE_DIR" git fetch --tags -git checkout llvmorg-19.1.7 +git checkout feature-vpto-llvm21 cmake -G Ninja -S llvm -B "$LLVM_BUILD_DIR" \ -DLLVM_ENABLE_PROJECTS="mlir;clang" \ -DBUILD_SHARED_LIBS=ON \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ + -DLLVM_ENABLE_ASSERTIONS=ON \ -DPython3_EXECUTABLE="$(which python3)" \ + -DPython_EXECUTABLE="$(which python3)" \ + -Dpybind11_DIR="$(python3 -m pybind11 --cmakedir)" \ + -Dnanobind_DIR="$(python3 -m nanobind --cmake_dir)" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_TARGETS_TO_BUILD="host" @@ -102,22 +106,13 @@ if [ ! -d "$PTO_SOURCE_DIR/.git" ]; then fi cd "$PTO_SOURCE_DIR" -export PYBIND11_CMAKE_DIR="$(python3 -m pybind11 --cmakedir)" +PYTHON_BIN=python3 \ +LLVM_BUILD_DIR="$LLVM_BUILD_DIR" \ +PTO_BUILD_DIR="$PTO_SOURCE_DIR/build" \ + ./quick_install.sh -cmake -G Ninja \ - -S . \ - -B build \ - -DLLVM_DIR="$LLVM_BUILD_DIR/lib/cmake/llvm" \ - -DMLIR_DIR="$LLVM_BUILD_DIR/lib/cmake/mlir" \ - -DPython3_EXECUTABLE="$(which python3)" \ - -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="$PYBIND11_CMAKE_DIR" \ - -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR="$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core" \ - -DCMAKE_INSTALL_PREFIX="$PTO_INSTALL_DIR" - -ninja -C build -ninja -C build install +# Reuse the persistent CMake tree for incremental builds and checks. +ninja -C "$PTO_SOURCE_DIR/build" check-pto ``` Expected outputs: @@ -125,19 +120,25 @@ Expected outputs: ```bash test -x "$PTO_SOURCE_DIR/build/tools/ptoas/ptoas" test -x "$PTO_SOURCE_DIR/build/tools/ptobc/ptobc" -find "$PTO_SOURCE_DIR/build/python" -name '_pto.cpython-*.so' -print -test -f "$PTO_INSTALL_DIR/mlir/dialects/pto.py" +test -n "$(find "$PTO_SOURCE_DIR/build/python/ptoas" \ + -name '_core.cpython-*.so' -print -quit)" +test -f "$PTO_SOURCE_DIR/build/python/ptoas/mlir/dialects/pto.py" ``` ## Runtime Environment -After installation, set the runtime paths before using `ptoas`, `ptobc`, or Python imports. +`quick_install.sh` performs an editable install into the selected Python environment. +Use the installed `ptoas` console script and import `ptoas.mlir` directly. Do not add +LLVM's top-level `mlir_core` package or the deleted top-level `pto` package to +`PYTHONPATH`. + +Only when invoking artifacts directly from the CMake build tree, expose that single +tree explicitly: ```bash -export MLIR_PYTHON_ROOT=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core -export PTO_PYTHON_ROOT=$PTO_INSTALL_DIR -export PYTHONPATH=$MLIR_PYTHON_ROOT:$PTO_PYTHON_ROOT:$PYTHONPATH -export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH +export PTOAS_BUILD_PYTHON_ROOT=$PTO_SOURCE_DIR/build/python +export PYTHONPATH=$PTOAS_BUILD_PYTHON_ROOT:$PYTHONPATH +export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_SOURCE_DIR/build/lib:$LD_LIBRARY_PATH export PATH=$PTO_SOURCE_DIR/build/tools/ptoas:$PTO_SOURCE_DIR/build/tools/ptobc:$PATH ``` @@ -160,8 +161,8 @@ Validate Python dialect loading: ```bash python3 - <<'PY' -from mlir.ir import Context, Module, Location -from mlir.dialects import pto +from ptoas.mlir.ir import Context, Module, Location +from ptoas.mlir.dialects import pto with Context() as ctx, Location.unknown(): pto.register_dialect(ctx, load=True) @@ -172,8 +173,16 @@ PY ## Troubleshooting -- `def_property family does not currently support keep_alive`: reinstall `pybind11==2.12.0`, clear the affected CMake cache if needed, and reconfigure. -- CMake cannot find LLVM or MLIR: confirm `LLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm` and `MLIR_DIR=$LLVM_BUILD_DIR/lib/cmake/mlir` exist and were produced by the `llvmorg-19.1.7` build. -- Python cannot import `mlir.dialects.pto`: re-export `PYTHONPATH` with MLIR core first and PTO install second, and confirm `_pto.cpython-*.so` exists under MLIR's `_mlir_libs`. -- Runtime linker errors for LLVM or PTO libraries: re-export `LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH`. +- `def_property family does not currently support keep_alive`: reinstall a supported + `pybind11<3`, clear the affected CMake cache if needed, and reconfigure. +- CMake cannot find LLVM or MLIR: confirm + `LLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm` and + `MLIR_DIR=$LLVM_BUILD_DIR/lib/cmake/mlir` exist in the + `feature-vpto-llvm21` build. +- Python cannot import `ptoas.mlir.dialects.pto`: confirm the editable install is + active, then check `build/python/ptoas/_core.cpython-*.so` and + `build/python/ptoas/mlir/_mlir_libs/_mlir*.so` in the same build tree. For + direct build-tree imports, prepend only `build/python` to `PYTHONPATH`. +- Runtime linker errors for LLVM or PTO libraries: re-export + `LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_SOURCE_DIR/build/lib:$LD_LIBRARY_PATH`. - Builds are very slow under `/mnt/c`: move the workspace into the WSL Linux filesystem, for example `$HOME/llvm-workspace`. diff --git a/.github/scripts/compute_vmi_version.py b/.github/scripts/compute_vmi_version.py deleted file mode 100644 index 3d37f87217..0000000000 --- a/.github/scripts/compute_vmi_version.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import argparse -import pathlib -import re -import sys - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser( - description="Compute the VMI release version from the top-level CMakeLists.txt." - ) - parser.add_argument( - "--cmake-file", - default="CMakeLists.txt", - help="Path to the top-level CMakeLists.txt file.", - ) - parser.add_argument( - "--check-tag", - help="Optional release tag to validate, e.g. vmi-v0.1.0.", - ) - return parser.parse_args() - - -def read_version(cmake_file: pathlib.Path) -> str: - content = cmake_file.read_text(encoding="utf-8") - match = re.search( - r'set\s*\(\s*PTOAS_VMI_VERSION\s+"([0-9]+\.[0-9]+\.[0-9]+)"\s*\)', - content, - ) - if not match: - raise ValueError( - f'could not find \'set(PTOAS_VMI_VERSION "x.y.z")\' in {cmake_file}' - ) - return match.group(1) - - -def normalize_tag(tag: str) -> str: - normalized = tag.strip() - if normalized.startswith("vmi-"): - normalized = normalized[len("vmi-"):] - if normalized.startswith("v"): - normalized = normalized[1:] - return normalized - - -def main() -> int: - args = parse_args() - cmake_file = pathlib.Path(args.cmake_file) - version = read_version(cmake_file) - - if args.check_tag is not None: - normalized_tag = normalize_tag(args.check_tag) - if normalized_tag != version: - print( - f"release tag '{args.check_tag}' does not match computed version '{version}'", - file=sys.stderr, - ) - return 1 - - print(version) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/.github/scripts/update_vmi_version.py b/.github/scripts/update_vmi_version.py deleted file mode 100644 index 8c029009d6..0000000000 --- a/.github/scripts/update_vmi_version.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import argparse -import pathlib -import re -import sys - - -VMI_VERSION_RE = re.compile( - r'(set\s*\(\s*PTOAS_VMI_VERSION\s+")([0-9]+\.[0-9]+\.[0-9]+)("\s*\))' -) -TAG_VERSION_RE = re.compile(r"^vmi-v([0-9]+)\.([0-9]+)\.([0-9]+)$") - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser( - description="Update the VMI version in the top-level CMakeLists.txt." - ) - parser.add_argument( - "--cmake-file", - default="CMakeLists.txt", - help="Path to the top-level CMakeLists.txt file.", - ) - parser.add_argument( - "--version", - required=True, - help="Released VMI version, for example vmi-v0.1.3.", - ) - parser.add_argument( - "--next", - action="store_true", - help="Advance the resolved version by one patch step.", - ) - return parser.parse_args() - - -def normalize_version(version: str) -> str: - match = TAG_VERSION_RE.fullmatch(version.strip()) - if not match: - raise ValueError(f"invalid VMI release tag '{version}'") - return ".".join(match.groups()) - - -def bump_version(version: str) -> str: - major, minor, patch = (int(part) for part in version.split(".")) - return f"{major}.{minor}.{patch + 1}" - - -def update_version(cmake_file: pathlib.Path, version: str) -> bool: - content = cmake_file.read_text(encoding="utf-8") - updated, count = VMI_VERSION_RE.subn( - lambda match: f"{match.group(1)}{version}{match.group(3)}", - content, - count=1, - ) - if count != 1: - raise ValueError( - f'could not find \'set(PTOAS_VMI_VERSION "x.y.z")\' in {cmake_file}' - ) - if updated == content: - return False - cmake_file.write_text(updated, encoding="utf-8") - return True - - -def main() -> int: - args = parse_args() - version = normalize_version(args.version) - if args.next: - version = bump_version(version) - update_version(pathlib.Path(args.cmake_file), version) - print(version) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/.github/workflows/build_wheel.yml b/.github/workflows/build_wheel.yml index 98a8ac0c9f..3107aac34b 100644 --- a/.github/workflows/build_wheel.yml +++ b/.github/workflows/build_wheel.yml @@ -10,8 +10,8 @@ name: Build Wheel on: push: - tags-ignore: - - '**' + branches: + - main pull_request: # Nightly build & publish (UTC time). schedule: @@ -29,7 +29,11 @@ on: types: [prereleased, released] permissions: - contents: write + contents: read + +concurrency: + group: build-wheel-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} env: LLVM_REPO: https://github.com/vpto-dev/llvm-project.git @@ -41,7 +45,7 @@ jobs: if: github.event_name != 'release' || startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v') # Non-release runs keep a single-Python matrix for faster gates; # release/nightly runs fan out to publish the full wheel set plus binary artifacts. - name: Build ptoas-bin (${{ matrix.arch }}, py${{ matrix.python }}) + name: Build ptoas wheel (${{ matrix.arch }}, py${{ matrix.python }}) runs-on: ${{ matrix.arch == 'x86_64' && 'ubuntu-latest' || 'ubuntu-24.04-arm' }} strategy: fail-fast: false @@ -59,34 +63,47 @@ jobs: - name: Set Python version run: | case "${{ matrix.python }}" in - "3.9") PY_VER="cp39-cp39" ;; "3.10") PY_VER="cp310-cp310" ;; "3.11") PY_VER="cp311-cp311" ;; "3.12") PY_VER="cp312-cp312" ;; - *) PY_VER="cp311-cp311" ;; + *) + echo "Unsupported Python version: ${{ matrix.python }}" >&2 + exit 1 + ;; esac echo "PY_VER=$PY_VER" >> $GITHUB_ENV echo "PY_PATH=/opt/python/$PY_VER" >> $GITHUB_ENV + echo "/opt/python/$PY_VER/bin" >> $GITHUB_PATH + + - name: Install system dependencies + run: | + dnf install -y ninja-build cmake git ccache gcc-c++ lld zip binutils patchelf chrpath + dnf clean all + + - name: Install Python dependencies + run: | + # LLVM/MLIR Python bindings are not yet compatible with pybind11 3.x + # (see pybind11 static_assert on def_property + keep_alive). + pip install --no-cache-dir numpy 'pybind11<3' nanobind 'scikit-build-core>=0.12.2,<2' auditwheel - - name: Compute PTOAS CLI version + - name: Resolve PTOAS distribution version run: | if [ "${GITHUB_EVENT_NAME}" = "release" ]; then case "${GITHUB_REF_NAME}" in vmi-v*) - EXPECTED_RELEASE_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_vmi_version.py \ - --check-tag "${GITHUB_REF_NAME}")" + EXPECTED_RELEASE_VERSION="$(python packaging/ptoas-vmi/prepare_source.py --print-version)" PTOAS_VERSION="${GITHUB_REF_NAME#vmi-v}" PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas-vmi" ;; ptoas-v*) - EXPECTED_RELEASE_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_ptoas_version.py --mode release)" + EXPECTED_RELEASE_VERSION="$(python .github/scripts/compute_ptoas_version.py --mode release)" PTOAS_VERSION="${GITHUB_REF_NAME#ptoas-v}" PTOAS_CLI_VERSION="${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas" ;; v*) - EXPECTED_RELEASE_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_ptoas_version.py --mode release)" + EXPECTED_RELEASE_VERSION="$(python .github/scripts/compute_ptoas_version.py --mode release)" PTOAS_VERSION="${GITHUB_REF_NAME#v}" PTOAS_CLI_VERSION="${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas" @@ -97,19 +114,19 @@ jobs: ;; esac if [ "${PTOAS_VERSION}" != "${EXPECTED_RELEASE_VERSION}" ]; then - echo "release tag '${GITHUB_REF_NAME}' does not match computed version '${EXPECTED_RELEASE_VERSION}'" >&2 + echo "release tag '${GITHUB_REF_NAME}' does not match project version '${EXPECTED_RELEASE_VERSION}'" >&2 exit 1 fi elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "${{ inputs.release_kind }}" = "vmi" ]; then - PTOAS_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_vmi_version.py)" + PTOAS_VERSION="$(python packaging/ptoas-vmi/prepare_source.py --print-version)" PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas-vmi" elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then - PTOAS_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_ptoas_version.py --mode release)" + PTOAS_VERSION="$(python .github/scripts/compute_ptoas_version.py --mode release)" PTOAS_CLI_VERSION="${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas" else - PTOAS_VERSION="$(${PY_PATH}/bin/python .github/scripts/compute_ptoas_version.py --mode dev)" + PTOAS_VERSION="$(python .github/scripts/compute_ptoas_version.py --mode dev)" PTOAS_CLI_VERSION="${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas" fi @@ -120,22 +137,9 @@ jobs: echo "Using PTOAS wheel version: ${PTOAS_VERSION}" echo "Using PTOAS Python package name: ${PTOAS_PYTHON_PACKAGE_NAME}" - - name: Install system dependencies - run: | - dnf install -y ninja-build cmake git ccache gcc-c++ lld zip binutils patchelf chrpath - dnf clean all - - - name: Install Python dependencies - run: | - export PATH="${PY_PATH}/bin:$PATH" - # LLVM/MLIR Python bindings are not yet compatible with pybind11 3.x - # (see pybind11 static_assert on def_property + keep_alive). - pip install --no-cache-dir numpy 'pybind11<3' nanobind setuptools wheel auditwheel - - - name: Test PEP 517 build backend + - name: Validate PEP 517 project metadata run: | - export PATH="${PY_PATH}/bin:$PATH" - PYTHONPATH="$GITHUB_WORKSPACE" python test/python/test_ptoas_build_backend.py + python -m scikit_build_core.build project-table - name: Set build directories run: | @@ -144,7 +148,6 @@ jobs: echo "LLVM_BUILD_DIR=/llvm-workspace/llvm-project/build-release" >> $GITHUB_ENV echo "PTO_SOURCE_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "PTO_BUILD_DIR=$GITHUB_WORKSPACE/build-release" >> $GITHUB_ENV - echo "PTO_INSTALL_DIR=$GITHUB_WORKSPACE/install-release" >> $GITHUB_ENV - name: Resolve LLVM source SHA id: llvm-source @@ -172,21 +175,12 @@ jobs: git remote add origin "${LLVM_REPO}" fi git remote set-url origin "${LLVM_REPO}" - git fetch --depth 1 origin "${LLVM_REF}" - git checkout --force FETCH_HEAD - - - name: Warn when default-branch cache is missing for PR/release runs - if: steps.cache-llvm.outputs.cache-hit != 'true' && (github.event_name == 'pull_request' || github.event_name == 'release') - run: | - echo "LLVM cache miss while running on PR/release." - echo "PR/release runs are cache-consumers only and should reuse cache generated on the default branch." - echo "Please run this workflow on the default branch first to populate cache key:" - echo "llvm-${{ steps.llvm-source.outputs.sha }}-manylinux_2_34-${{ matrix.arch }}-${{ matrix.python }}-${{ env.LLVM_CACHE_FLAVOR }}" + git fetch --depth 1 origin "${{ steps.llvm-source.outputs.sha }}" + git checkout --force "${{ steps.llvm-source.outputs.sha }}" - name: Build LLVM/MLIR if: steps.cache-llvm.outputs.cache-hit != 'true' run: | - export PATH="${PY_PATH}/bin:$PATH" cd $LLVM_SOURCE_DIR cmake -C "$PTO_SOURCE_DIR/cmake/LinuxHardeningCache.cmake" -G Ninja -S llvm -B $LLVM_BUILD_DIR \ -DLLVM_ENABLE_PROJECTS="mlir;clang" \ @@ -203,8 +197,7 @@ jobs: # Upload cache immediately after the build step to avoid later steps polluting the release build tree. - name: Save LLVM cache - # Allow cache writes except for PR/release runs to avoid duplicated tag/merge caches. - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name != 'pull_request' && github.event_name != 'release' + if: steps.cache-llvm.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: /llvm-workspace/llvm-project/build-release @@ -214,45 +207,39 @@ jobs: env: CMAKE_BUILD_PARALLEL_LEVEL: "2" run: | - export PATH="${PY_PATH}/bin:$PATH" - PTOAS_RELEASE_VERSION_OVERRIDE="${PTOAS_CLI_VERSION}" \ - pip install . --no-build-isolation - - - name: Create Python wheel - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: | - export PATH="${PY_PATH}/bin:$PATH" - export PTOAS_PYTHON_PACKAGE_NAME="${PTOAS_PYTHON_PACKAGE_NAME}" - export PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_VERSION}" - bash $PTO_SOURCE_DIR/docker/create_wheel.sh + if [ "${PTOAS_PYTHON_PACKAGE_NAME}" = "ptoas-vmi" ]; then + PTOAS_WHEEL_SOURCE_DIR="${PTO_SOURCE_DIR}/.work/ptoas-vmi-source" + python packaging/ptoas-vmi/prepare_source.py \ + --output-dir "${PTOAS_WHEEL_SOURCE_DIR}" + else + PTOAS_WHEEL_SOURCE_DIR="${PTO_SOURCE_DIR}" + fi + rm -rf "${PTO_SOURCE_DIR}/build/wheel-dist" + mkdir -p "${PTO_SOURCE_DIR}/build/wheel-dist" + SKBUILD_BUILD_DIR="${PTO_BUILD_DIR}" \ + python -m pip wheel "${PTOAS_WHEEL_SOURCE_DIR}" \ + --no-build-isolation --no-deps \ + --wheel-dir "${PTO_SOURCE_DIR}/build/wheel-dist" - name: Validate wheel payload and launcher contract - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' run: | - export PATH="${PY_PATH}/bin:$PATH" python "$PTO_SOURCE_DIR/docker/validate_wheel_payload.py" "$PTO_SOURCE_DIR/build/wheel-dist" - name: Repair wheel with auditwheel - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' run: | - export PATH="${PY_PATH}/bin:$PATH" export PTO_WHEEL_DIST_DIR=$PTO_SOURCE_DIR/build/wheel-dist export PTO_WHEELHOUSE=$GITHUB_WORKSPACE/wheelhouse - export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH mkdir -p "$PTO_WHEELHOUSE" + # The raw wheel intentionally keeps package-relative RPATHs. Give + # auditwheel the external LLVM build only while resolving and + # bundling its shared dependencies. + export LD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" auditwheel repair --plat manylinux_2_34_${{ matrix.arch }} "$PTO_WHEEL_DIST_DIR"/ptoas*.whl -w "$PTO_WHEELHOUSE" - name: Test wheel installation - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: | - export PATH="${PY_PATH}/bin:$PATH" - pip install $GITHUB_WORKSPACE/wheelhouse/ptoas*.whl - bash $PTO_SOURCE_DIR/docker/test_wheel_imports.sh - - - name: Test ptoas CLI run: | - export PATH="${PY_PATH}/bin:$PATH" - bash $PTO_SOURCE_DIR/docker/test_ptoas_cli.sh + PTO_TEST_WHEEL_PATH="$GITHUB_WORKSPACE/wheelhouse/ptoas*.whl" \ + bash $PTO_SOURCE_DIR/docker/test_wheel_imports.sh - name: Upload wheel artifact if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -264,7 +251,13 @@ jobs: - name: Collect ptoas binary and dependencies if: matrix.python == '3.11' run: | - bash $PTO_SOURCE_DIR/docker/collect_ptoas_dist.sh $GITHUB_WORKSPACE/ptoas-dist + rm -rf "$GITHUB_WORKSPACE/ptoas-dist" + cmake --install "${PTO_BUILD_DIR}" \ + --prefix "$GITHUB_WORKSPACE/ptoas-dist" \ + --component PTOAS_Python + cmake --install "${PTO_BUILD_DIR}" \ + --prefix "$GITHUB_WORKSPACE/ptoas-dist" \ + --component PTOAS_CompilerArchive - name: Archive ptoas binary artifact if: matrix.python == '3.11' @@ -273,6 +266,31 @@ jobs: tar -czf "$GITHUB_WORKSPACE/ptoas-bin-${{ matrix.arch }}.tar.gz" \ -C "$GITHUB_WORKSPACE/ptoas-dist" . + - name: Smoke test archived ptoas binary artifact + if: matrix.python == '3.11' + run: | + TEST_DIR="$RUNNER_TEMP/ptoas-dist-smoke-${{ matrix.arch }}" + rm -rf "$TEST_DIR" + mkdir -p "$TEST_DIR/extracted" + tar -xzf "$GITHUB_WORKSPACE/ptoas-bin-${{ matrix.arch }}.tar.gz" \ + -C "$TEST_DIR/extracted" + + test -x "$TEST_DIR/extracted/bin/ptoas" + test -f "$TEST_DIR/extracted/ptoas/_cli.py" + test -f "$TEST_DIR/extracted/ptoas/mlir/ir.py" + test -f "$TEST_DIR/extracted/ptodsl/__init__.py" + test -f "$TEST_DIR/extracted/tilelang_dsl/__init__.py" + test -d "$TEST_DIR/extracted/share/ptoas/TileOps" + test "$(cat "$TEST_DIR/extracted/.ptoas-python-version")" = "3.11" + compgen -G "$TEST_DIR/extracted/ptoas/_core*.so" >/dev/null + + env -u PYTHONPATH -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ + "$TEST_DIR/extracted/bin/ptoas" --version + env -u PYTHONPATH -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ + "$TEST_DIR/extracted/bin/ptoas" \ + "$PTO_SOURCE_DIR/test/lit/pto/kernel_kind_vector_scf_while_emitc.pto" \ + >/dev/null + - name: Upload ptoas binary artifact if: matrix.python == '3.11' uses: actions/upload-artifact@v4 @@ -285,6 +303,8 @@ jobs: if: (github.event_name == 'release' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v'))) || github.event_name == 'schedule' needs: build_wheel runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Compute release metadata @@ -375,6 +395,8 @@ jobs: if: github.event_name == 'release' && github.event.action == 'released' && (startsWith(github.ref_name, 'ptoas-v') || (startsWith(github.ref_name, 'v') && !startsWith(github.ref_name, 'vmi-v'))) needs: upload_release_assets runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Checkout default branch @@ -402,36 +424,3 @@ jobs: git add CMakeLists.txt git commit -m "chore(release): bump base version to v${{ steps.bump.outputs.next_base_version }}" git push origin HEAD:${{ github.event.repository.default_branch }} - - bump_vmi_version: - name: Bump VMI version after release - if: github.event_name == 'release' && github.event.action == 'released' && startsWith(github.ref_name, 'vmi-v') - needs: upload_release_assets - runs-on: ubuntu-latest - - steps: - - name: Checkout default branch - uses: actions/checkout@v4 - with: - ref: ${{ github.event.repository.default_branch }} - - - name: Update VMI version - id: bump - run: | - next_vmi_version="$(python3 .github/scripts/update_vmi_version.py \ - --version "${GITHUB_REF_NAME}" \ - --next)" - echo "next_vmi_version=${next_vmi_version}" >> "$GITHUB_OUTPUT" - - - name: Commit version bump - run: | - if git diff --quiet -- CMakeLists.txt; then - echo "CMakeLists.txt already matches the next VMI version." - exit 0 - fi - - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add CMakeLists.txt - git commit -m "chore(release): bump VMI version to v${{ steps.bump.outputs.next_vmi_version }}" - git push origin HEAD:${{ github.event.repository.default_branch }} diff --git a/.github/workflows/build_wheel_mac.yml b/.github/workflows/build_wheel_mac.yml index 9948a32759..855742ddba 100644 --- a/.github/workflows/build_wheel_mac.yml +++ b/.github/workflows/build_wheel_mac.yml @@ -28,7 +28,11 @@ on: types: [prereleased, released] permissions: - contents: write + contents: read + +concurrency: + group: build-wheel-macos-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} env: LLVM_REPO: https://github.com/vpto-dev/llvm-project.git @@ -40,16 +44,13 @@ jobs: if: github.event_name != 'release' || startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v') # Non-release runs keep a single-Python matrix for faster gates; # release/nightly runs fan out to publish the full wheel set plus binary artifacts. - name: Build ptoas-bin (macOS ${{ matrix.arch }}, py${{ matrix.python }}) + name: Build ptoas wheel (macOS ${{ matrix.arch }}, py${{ matrix.python }}) runs-on: ${{ matrix.arch == 'x86_64' && 'macos-15-intel' || 'macos-26' }} strategy: fail-fast: false matrix: python: ${{ fromJson((github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && '["3.10","3.11","3.12"]' || '["3.11"]') }} arch: ["x86_64", "aarch64"] - exclude: - - python: "3.10" - arch: "x86_64" steps: - name: Checkout repository @@ -73,13 +74,22 @@ jobs: run: | echo "PY_PATH=$(python -c 'import sys; print(sys.prefix)')" >> $GITHUB_ENV - - name: Compute PTOAS CLI version + - name: Install system dependencies + run: | + brew install ninja ccache + + - name: Install Python dependencies + run: | + # LLVM/MLIR Python bindings are not yet compatible with pybind11 3.x + # (see pybind11 static_assert on def_property + keep_alive). + pip install --no-cache-dir numpy 'pybind11<3' nanobind 'scikit-build-core>=0.12.2,<2' delocate + + - name: Resolve PTOAS distribution version run: | if [ "${GITHUB_EVENT_NAME}" = "release" ]; then case "${GITHUB_REF_NAME}" in vmi-v*) - EXPECTED_RELEASE_VERSION="$(python .github/scripts/compute_vmi_version.py \ - --check-tag "${GITHUB_REF_NAME}")" + EXPECTED_RELEASE_VERSION="$(python packaging/ptoas-vmi/prepare_source.py --print-version)" PTOAS_VERSION="${GITHUB_REF_NAME#vmi-v}" PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas-vmi" @@ -102,11 +112,11 @@ jobs: ;; esac if [ "${PTOAS_VERSION}" != "${EXPECTED_RELEASE_VERSION}" ]; then - echo "release tag '${GITHUB_REF_NAME}' does not match computed version '${EXPECTED_RELEASE_VERSION}'" >&2 + echo "release tag '${GITHUB_REF_NAME}' does not match project version '${EXPECTED_RELEASE_VERSION}'" >&2 exit 1 fi elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ] && [ "${{ inputs.release_kind }}" = "vmi" ]; then - PTOAS_VERSION="$(python .github/scripts/compute_vmi_version.py)" + PTOAS_VERSION="$(python packaging/ptoas-vmi/prepare_source.py --print-version)" PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}" PTOAS_PYTHON_PACKAGE_NAME="ptoas-vmi" elif [ "${GITHUB_EVENT_NAME}" = "workflow_dispatch" ]; then @@ -125,15 +135,9 @@ jobs: echo "Using PTOAS wheel version: ${PTOAS_VERSION}" echo "Using PTOAS Python package name: ${PTOAS_PYTHON_PACKAGE_NAME}" - - name: Install system dependencies + - name: Validate PEP 517 project metadata run: | - brew install ninja ccache - - - name: Install Python dependencies - run: | - # LLVM/MLIR Python bindings are not yet compatible with pybind11 3.x - # (see pybind11 static_assert on def_property + keep_alive). - pip install --no-cache-dir numpy 'pybind11<3' nanobind setuptools wheel delocate + python -m scikit_build_core.build project-table - name: Set build directories run: | @@ -142,7 +146,6 @@ jobs: echo "LLVM_BUILD_DIR=${RUNNER_TEMP}/llvm-workspace/llvm-project/build-release" >> $GITHUB_ENV echo "PTO_SOURCE_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV echo "PTO_BUILD_DIR=$GITHUB_WORKSPACE/build-release" >> $GITHUB_ENV - echo "PTO_INSTALL_DIR=$GITHUB_WORKSPACE/install-release" >> $GITHUB_ENV - name: Resolve LLVM source SHA id: llvm-source @@ -170,16 +173,8 @@ jobs: git remote add origin "${LLVM_REPO}" fi git remote set-url origin "${LLVM_REPO}" - git fetch --depth 1 origin "${LLVM_REF}" - git checkout --force FETCH_HEAD - - - name: Warn when default-branch cache is missing for PR/release runs - if: steps.cache-llvm.outputs.cache-hit != 'true' && (github.event_name == 'pull_request' || github.event_name == 'release') - run: | - echo "LLVM cache miss while running on PR/release." - echo "PR/release runs are cache-consumers only and should reuse cache generated on the default branch." - echo "Please run this workflow on the default branch first to populate cache key:" - echo "llvm-${{ steps.llvm-source.outputs.sha }}-${{ steps.runner-meta.outputs.label }}-${{ matrix.arch }}-${{ matrix.python }}-${{ env.LLVM_CACHE_FLAVOR }}" + git fetch --depth 1 origin "${{ steps.llvm-source.outputs.sha }}" + git checkout --force "${{ steps.llvm-source.outputs.sha }}" - name: Build LLVM/MLIR if: steps.cache-llvm.outputs.cache-hit != 'true' @@ -200,8 +195,7 @@ jobs: # Upload cache immediately after the build step to avoid later steps polluting the release build tree. - name: Save LLVM cache - # Allow cache writes except for PR/release runs to avoid duplicated tag/merge caches. - if: steps.cache-llvm.outputs.cache-hit != 'true' && github.event_name != 'pull_request' && github.event_name != 'release' + if: steps.cache-llvm.outputs.cache-hit != 'true' uses: actions/cache/save@v4 with: path: ${{ runner.temp }}/llvm-workspace/llvm-project/build-release @@ -209,37 +203,36 @@ jobs: - name: Build PTOAS run: | - PTOAS_RELEASE_VERSION_OVERRIDE="${PTOAS_CLI_VERSION}" \ - pip install . --no-build-isolation - - - name: Create Python wheel - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: | - export PTO_WHEEL_DIST_DIR=$PTO_SOURCE_DIR/build/wheel-dist - export PTOAS_PYTHON_PACKAGE_NAME="${PTOAS_PYTHON_PACKAGE_NAME}" - export PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_VERSION}" + if [ "${PTOAS_PYTHON_PACKAGE_NAME}" = "ptoas-vmi" ]; then + PTOAS_WHEEL_SOURCE_DIR="${PTO_SOURCE_DIR}/.work/ptoas-vmi-source" + python packaging/ptoas-vmi/prepare_source.py \ + --output-dir "${PTOAS_WHEEL_SOURCE_DIR}" + else + PTOAS_WHEEL_SOURCE_DIR="${PTO_SOURCE_DIR}" + fi if [ "${{ matrix.arch }}" = "x86_64" ]; then TARGET_ARCH="x86_64" else TARGET_ARCH="arm64" fi - # setup-python may provide a universal2 interpreter on macOS. - # Force a single-arch wheel tag to match the matrix target and delocate checks. - export WHEEL_PLAT_NAME=$(python "$PTO_SOURCE_DIR/docker/get_macos_wheel_plat_name.py" "$TARGET_ARCH") - bash $PTO_SOURCE_DIR/docker/create_wheel.sh + export _PYTHON_HOST_PLATFORM="$(python "$PTO_SOURCE_DIR/docker/get_macos_wheel_plat_name.py" "$TARGET_ARCH")" + rm -rf "${PTO_SOURCE_DIR}/build/wheel-dist" + mkdir -p "${PTO_SOURCE_DIR}/build/wheel-dist" + SKBUILD_BUILD_DIR="${PTO_BUILD_DIR}" \ + python -m pip wheel "${PTOAS_WHEEL_SOURCE_DIR}" \ + --no-build-isolation --no-deps \ + --wheel-dir "${PTO_SOURCE_DIR}/build/wheel-dist" shopt -s nullglob - built_wheels=("$PTO_WHEEL_DIST_DIR"/ptoas*.whl) + built_wheels=("$PTO_SOURCE_DIR"/build/wheel-dist/ptoas*.whl) if [ "${#built_wheels[@]}" -gt 0 ]; then printf 'Built wheel file: %s\n' "$(basename "${built_wheels[0]}")" fi - name: Validate wheel payload and launcher contract - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' run: | python "$PTO_SOURCE_DIR/docker/validate_wheel_payload.py" "$PTO_SOURCE_DIR/build/wheel-dist" - name: Repair wheel with delocate - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' run: | set -euo pipefail export PTO_WHEEL_DIST_DIR=$PTO_SOURCE_DIR/build/wheel-dist @@ -266,6 +259,10 @@ jobs: echo "delocate dependency summary:" delocate-listdeps "${wheels[0]}" || true + # The raw wheel intentionally keeps package-relative RPATHs. Give + # delocate the external LLVM build only while resolving and bundling + # its shared dependencies. + export DYLD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}" delocate-wheel \ --require-archs "${REQUIRED_ARCH}" \ --wheel-dir "$PTO_WHEELHOUSE" \ @@ -315,16 +312,9 @@ jobs: ls -lh "$PTO_WHEELHOUSE" - name: Test wheel installation - if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: | - pip install $GITHUB_WORKSPACE/wheelhouse/ptoas*.whl - export DYLD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:${DYLD_LIBRARY_PATH} - bash $PTO_SOURCE_DIR/docker/test_wheel_imports.sh - - - name: Test ptoas CLI run: | - export DYLD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:${DYLD_LIBRARY_PATH} - bash $PTO_SOURCE_DIR/docker/test_ptoas_cli.sh + PTO_TEST_WHEEL_PATH="$GITHUB_WORKSPACE/wheelhouse/ptoas*.whl" \ + bash $PTO_SOURCE_DIR/docker/test_wheel_imports.sh - name: Upload wheel artifact if: github.event_name == 'release' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -336,7 +326,13 @@ jobs: - name: Collect ptoas binary and dependencies if: matrix.python == '3.11' run: | - bash "$PTO_SOURCE_DIR/docker/collect_ptoas_dist_mac.sh" "$GITHUB_WORKSPACE/ptoas-dist" + rm -rf "$GITHUB_WORKSPACE/ptoas-dist" + cmake --install "${PTO_BUILD_DIR}" \ + --prefix "$GITHUB_WORKSPACE/ptoas-dist" \ + --component PTOAS_Python + cmake --install "${PTO_BUILD_DIR}" \ + --prefix "$GITHUB_WORKSPACE/ptoas-dist" \ + --component PTOAS_CompilerArchive - name: Archive ptoas binary artifact if: matrix.python == '3.11' @@ -354,8 +350,13 @@ jobs: tar -xzf "$GITHUB_WORKSPACE/ptoas-bin-macos-${{ matrix.arch }}.tar.gz" -C "$TEST_DIR/extracted" test -x "$TEST_DIR/extracted/bin/ptoas" - test -f "$TEST_DIR/extracted/ptoas/_runtime_entry.py" - test -f "$TEST_DIR/extracted/ptoas_wheel_bootstrap.py" + test -f "$TEST_DIR/extracted/ptoas/_cli.py" + test -f "$TEST_DIR/extracted/ptoas/mlir/ir.py" + test -f "$TEST_DIR/extracted/ptodsl/__init__.py" + test -f "$TEST_DIR/extracted/tilelang_dsl/__init__.py" + test -d "$TEST_DIR/extracted/share/ptoas/TileOps" + test "$(cat "$TEST_DIR/extracted/.ptoas-python-version")" = "3.11" + compgen -G "$TEST_DIR/extracted/ptoas/_core*.so" >/dev/null env -u PYTHONPATH -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ "$TEST_DIR/extracted/bin/ptoas" --version @@ -364,39 +365,6 @@ jobs: "$PTO_SOURCE_DIR/test/lit/pto/kernel_kind_vector_scf_while_emitc.pto" \ >/dev/null - - name: Smoke test wheel imports after collecting artifacts - if: (github.event_name == 'release' || github.event_name == 'schedule') && matrix.python == '3.11' - run: | - # Test the copied wheel artifact from an isolated env with no build-tree - # paths, so post-collect/release regressions (e.g. ARM cs_invalid_page) - # are caught before upload. - brew install uv - uv python install 3.11 - TEST_DIR="$RUNNER_TEMP/wheel-smoke-test" - VENV_DIR="$TEST_DIR/.venv" - mkdir -p "$TEST_DIR" - cd "$TEST_DIR" - uv venv --python 3.11 "$VENV_DIR" - source "$VENV_DIR/bin/activate" - - unset PYTHONPATH - unset DYLD_LIBRARY_PATH - unset LD_LIBRARY_PATH - - shopt -s nullglob - wheels=("$GITHUB_WORKSPACE"/wheelhouse/ptoas*.whl) - if [ "${#wheels[@]}" -ne 1 ]; then - echo "Expected exactly one wheel in \$GITHUB_WORKSPACE/wheelhouse, found ${#wheels[@]}:" - printf ' %s\n' "${wheels[@]}" - exit 1 - fi - uv pip install "${wheels[0]}" - - if [ "${{ matrix.arch }}" = "aarch64" ]; then - export DYLD_PRINT_LIBRARIES=1 - fi - bash "$GITHUB_WORKSPACE/docker/test_wheel_imports.sh" - - name: Upload ptoas binary artifact if: matrix.python == '3.11' uses: actions/upload-artifact@v4 @@ -409,6 +377,8 @@ jobs: if: (github.event_name == 'release' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v'))) || github.event_name == 'schedule' needs: build_wheel runs-on: ubuntu-latest + permissions: + contents: write steps: - name: Compute release metadata diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad780e9c0a..f741ab16da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,11 +102,8 @@ jobs: LLVM_BUILD_DIR: ${{ github.workspace }}/llvm-project/llvm/build-assert LLVM_DIR: ${{ github.workspace }}/llvm-project/llvm/build-assert PTO_BUILD_DIR: ${{ github.workspace }}/build-assert - PTO_INSTALL_DIR: ${{ github.workspace }}/install-assert - PTO_WHEELHOUSE: ${{ github.workspace }}/wheelhouse-assert PTOAS_VENV: ${{ github.workspace }}/.venv-ptoas-assert - MLIR_PYTHONPATH: ${{ github.workspace }}/llvm-project/llvm/build-assert/tools/mlir/python_packages/mlir_core - LLVM_CACHE_FLAVOR: llvm21-assert-shared-mlirpy-hardening-v1 + LLVM_CACHE_FLAVOR: llvm21-assert-shared-mlirpy-hardening-v2 steps: - name: Checkout uses: actions/checkout@v4 @@ -114,7 +111,7 @@ jobs: fetch-depth: 1 persist-credentials: false - - name: Install dependencies + - name: Install dependencies and create developer environment run: | # GitHub-hosted runners may include Microsoft apt sources unrelated to # PTOAS; these can intermittently return 403 and break apt-get update. @@ -131,9 +128,13 @@ jobs: python3 python3-pip python3-venv \ clang-${PTOAS_CLANG_MAJOR} lld-${PTOAS_CLANG_MAJOR} \ libedit-dev zlib1g-dev libxml2-dev libzstd-dev - python3 -m pip install --upgrade pip + rm -rf "${PTOAS_VENV}" + python3 -m venv "${PTOAS_VENV}" + "${PTOAS_VENV}/bin/python" -m pip install --upgrade pip # LLVM/MLIR Python bindings are not yet compatible with pybind11 3.x. - python3 -m pip install setuptools wheel 'pybind11<3' nanobind numpy + "${PTOAS_VENV}/bin/pip" install \ + 'scikit-build-core>=0.12.2,<2' 'pybind11<3' \ + nanobind numpy ml-dtypes - name: Define payload paths shell: bash @@ -198,8 +199,8 @@ jobs: fi git remote set-url origin "${LLVM_REPO}" - git fetch --depth 1 origin "${LLVM_REF}" - git checkout --force FETCH_HEAD + git fetch --depth 1 origin "${LLVM_SOURCE_SHA}" + git checkout --force "${LLVM_SOURCE_SHA}" - name: Build LLVM/MLIR (only if cache miss) if: steps.cache-llvm.outputs.cache-hit != 'true' @@ -210,10 +211,10 @@ jobs: -DBUILD_SHARED_LIBS=ON \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DPython3_EXECUTABLE=python3 \ - -DPython_EXECUTABLE=python3 \ - -Dpybind11_DIR="$(python3 -m pybind11 --cmakedir)" \ - -Dnanobind_DIR="$(python3 -m nanobind --cmake_dir)" \ + -DPython3_EXECUTABLE="${PTOAS_VENV}/bin/python" \ + -DPython_EXECUTABLE="${PTOAS_VENV}/bin/python" \ + -Dpybind11_DIR="$("${PTOAS_VENV}/bin/python" -m pybind11 --cmakedir)" \ + -Dnanobind_DIR="$("${PTOAS_VENV}/bin/python" -m nanobind --cmake_dir)" \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER="${PTOAS_CMAKE_C_COMPILER}" \ -DCMAKE_CXX_COMPILER="${PTOAS_CMAKE_CXX_COMPILER}" \ @@ -252,72 +253,49 @@ jobs: -DPython3_EXECUTABLE="${cmake4_venv}/bin/python" \ -DPython3_FIND_STRATEGY=LOCATION \ -Dpybind11_DIR="$("${cmake4_venv}/bin/python" -m pybind11 --cmakedir)" \ + -Dnanobind_DIR="$("${cmake4_venv}/bin/python" -m nanobind --cmake_dir)" \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR="${MLIR_PYTHONPATH}" \ -DPTO_ENABLE_PYTHON_BINDING=ON \ - -DPTOAS_VALIDATE_CMAKE4_FETCHCONTENT_COMPAT=ON \ - -DPTOAS_ENABLE_WERROR=OFF \ -DBUILD_TESTING=ON \ -DCMAKE_C_COMPILER="${PTOAS_CMAKE_C_COMPILER}" \ -DCMAKE_CXX_COMPILER="${PTOAS_CMAKE_CXX_COMPILER}" \ -Werror=dev - - name: Create PTOAS test venv - shell: bash - run: | - set -euo pipefail - rm -rf "${PTOAS_VENV}" - python3 -m venv "${PTOAS_VENV}" - "${PTOAS_VENV}/bin/python" -m pip install --upgrade pip - "${PTOAS_VENV}/bin/pip" install setuptools wheel 'pybind11<3' nanobind numpy ml-dtypes - - - name: Build PTOAS wheel + - name: Install PTOAS editable run: | set -euo pipefail rm -rf "${PTO_BUILD_DIR}" - rm -rf "${PTO_INSTALL_DIR}" - rm -rf "${PTO_WHEELHOUSE}" - mkdir -p "${PTO_WHEELHOUSE}" - # LLVM_BUILD_DIR is the env var read by the build backend (_ptoas_build_backend.py). + # Keep a persistent CMake build tree for CTest and lit while exposing + # the current sources and Python extension through the developer venv. LLVM_BUILD_DIR="${LLVM_DIR}" \ - PTO_BUILD_DIR="${PTO_BUILD_DIR}" \ - CMAKE_C_COMPILER="${PTOAS_CMAKE_C_COMPILER}" \ - CMAKE_CXX_COMPILER="${PTOAS_CMAKE_CXX_COMPILER}" \ - PTO_INSTALL_DIR="${PTO_INSTALL_DIR}" \ - "${PTOAS_VENV}/bin/python" -m pip wheel . --no-build-isolation --no-deps --wheel-dir "${PTO_WHEELHOUSE}" + CC="${PTOAS_CMAKE_C_COMPILER}" \ + CXX="${PTOAS_CMAKE_CXX_COMPILER}" \ + "${PTOAS_VENV}/bin/python" -m pip install --editable . \ + --no-build-isolation --no-deps \ + --config-settings="build-dir=${PTO_BUILD_DIR}" - - name: Install PTOAS wheel into test venv + - name: Test PTOAS editable install shell: bash run: | set -euo pipefail - readarray -t ptoas_wheels < <(find "${PTO_WHEELHOUSE}" -maxdepth 1 -type f -name 'ptoas*.whl' | sort) - if [[ "${#ptoas_wheels[@]}" -ne 1 ]]; then - echo "ERROR: expected exactly one PTOAS wheel in ${PTO_WHEELHOUSE}, found ${#ptoas_wheels[@]}" >&2 - printf ' %s\n' "${ptoas_wheels[@]}" >&2 - exit 1 - fi - - "${PTOAS_VENV}/bin/pip" install --force-reinstall "${ptoas_wheels[0]}" - PATH="${PTOAS_VENV}/bin:${PATH}" bash docker/test_wheel_imports.sh + PATH="${PTOAS_VENV}/bin:${PATH}" \ + PYTHON="${PTOAS_VENV}/bin/python" \ + bash docker/test_wheel_imports.sh - name: Run PTODSL Python tests shell: bash env: LLVM_DIR: ${{ env.LLVM_DIR }} - PTO_INSTALL_DIR: ${{ env.PTO_INSTALL_DIR }} run: | - export PATH="${PTOAS_VENV}/bin:${LLVM_DIR}/bin:${PTO_INSTALL_DIR}/bin:${PATH}" - export LD_LIBRARY_PATH="${LLVM_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" + export PATH="${PTOAS_VENV}/bin:${LLVM_DIR}/bin:${PATH}" ctest --test-dir "${PTO_BUILD_DIR}" --output-on-failure -L PTODSL - name: Run lit tests shell: bash env: LLVM_DIR: ${{ env.LLVM_DIR }} - PTO_INSTALL_DIR: ${{ env.PTO_INSTALL_DIR }} run: | - export PATH="${PTOAS_VENV}/bin:${LLVM_DIR}/bin:${PTO_INSTALL_DIR}/bin:${PATH}" - export LD_LIBRARY_PATH="${LLVM_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" + export PATH="${PTOAS_VENV}/bin:${LLVM_DIR}/bin:${PATH}" ninja -C "${PTO_BUILD_DIR}" check-pto - name: Run sample tests (py -> pto -> cpp) @@ -325,15 +303,13 @@ jobs: env: CI_EVENT_NAME: ${{ github.event_name }} WORKFLOW_SOC_VERSION: ${{ github.event.inputs.soc_version || 'Ascend910' }} - PTOAS_BIN: ${{ env.PTO_INSTALL_DIR }}/bin/ptoas + PTOAS_BIN: ${{ env.PTOAS_VENV }}/bin/ptoas PTOBC_BIN: ${{ env.PTO_BUILD_DIR }}/tools/ptobc/ptobc PTO_BUILD_DIR: ${{ env.PTO_BUILD_DIR }} PYTHON_BIN: ${{ env.PTOAS_VENV }}/bin/python - PTO_INSTALL_DIR: ${{ env.PTO_INSTALL_DIR }} run: | set -euo pipefail - export PATH="${PTOAS_VENV}/bin:${PTO_INSTALL_DIR}/bin:${PATH}" - export LD_LIBRARY_PATH="${LLVM_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" + export PATH="${PTOAS_VENV}/bin:${PATH}" export PTOAS_OUT_DIR="${PAYLOAD_DIR}/test/samples" if [[ "${CI_EVENT_NAME}" == "workflow_dispatch" || "${CI_EVENT_NAME}" == "schedule" ]]; then # Board-validation payloads must only contain the arch-matching diff --git a/.github/workflows/ci_sim.yml b/.github/workflows/ci_sim.yml index 795e077919..54ddedf6ef 100644 --- a/.github/workflows/ci_sim.yml +++ b/.github/workflows/ci_sim.yml @@ -111,8 +111,6 @@ jobs: env: LLVM_REPO: https://github.com/vpto-dev/llvm-project.git LLVM_REF: feature-vpto-llvm21 - PTO_INSTALL_DIR: ${{ github.workspace }}/install - PTO_WHEELHOUSE: ${{ github.workspace }}/.work/ptoas-wheelhouse PTOAS_VENV: ${{ github.workspace }}/.work/ptoas-sim-venv VPTO_SIM_WORKSPACE: ${{ github.workspace }}/.work/vpto-sim-ci TILELANG_DSL_WORKSPACE: ${{ github.workspace }}/.work/tilelang-dsl-ci @@ -155,7 +153,7 @@ jobs: fi echo "ASCEND_HOME_PATH=${ASCEND_HOME_PATH_DETECTED}" >> "${GITHUB_ENV}" - echo "PTOAS_BIN=${GITHUB_WORKSPACE}/install/bin/ptoas" >> "${GITHUB_ENV}" + echo "PTOAS_BIN=${PTOAS_VENV}/bin/ptoas" >> "${GITHUB_ENV}" - name: Ensure runner dependencies shell: bash @@ -171,7 +169,7 @@ jobs: if [[ "${#missing_tools[@]}" -gt 0 ]]; then if command -v sudo >/dev/null 2>&1 && command -v apt-get >/dev/null 2>&1; then sudo apt-get update - sudo apt-get install -y python3 python3-pip git cmake ninja-build make + sudo apt-get install -y python3 python3-pip python3-venv git cmake ninja-build make else echo "ERROR: missing required tools on self-hosted runner: ${missing_tools[*]}" >&2 echo "ERROR: automatic installation requires sudo + apt-get" >&2 @@ -179,43 +177,46 @@ jobs: fi fi - python3 -m pip --version >/dev/null 2>&1 || { + if ! python3 -m ensurepip --version >/dev/null 2>&1; then if command -v sudo >/dev/null 2>&1 && command -v apt-get >/dev/null 2>&1; then sudo apt-get update - sudo apt-get install -y python3-pip + sudo apt-get install -y python3-pip python3-venv else - echo "ERROR: python3-pip is required on self-hosted runner" >&2 + echo "ERROR: python3-venv is required on self-hosted runner" >&2 exit 1 fi - } - - need_pip_install=0 - python3 -c "import numpy" >/dev/null 2>&1 || need_pip_install=1 - python3 -c "import setuptools, wheel" >/dev/null 2>&1 || need_pip_install=1 - python3 -m pybind11 --cmakedir >/dev/null 2>&1 || need_pip_install=1 - python3 -m nanobind --cmake_dir >/dev/null 2>&1 || need_pip_install=1 - python3 -c "import ml_dtypes" >/dev/null 2>&1 || need_pip_install=1 + fi - if [[ "${need_pip_install}" -eq 1 ]]; then - python3 -m pip install --upgrade pip - python3 -m pip install setuptools wheel 'pybind11<3' nanobind numpy ml-dtypes + - name: Configure ccache + shell: bash + run: | + set -euo pipefail + if ! command -v ccache >/dev/null 2>&1; then + if command -v sudo >/dev/null 2>&1 && command -v apt-get >/dev/null 2>&1; then + sudo apt-get update + sudo apt-get install -y ccache + else + echo "ccache is unavailable; continuing without a compiler launcher" + exit 0 + fi fi + ccache --version + echo "CMAKE_C_COMPILER_LAUNCHER=ccache" >> "${GITHUB_ENV}" + echo "CMAKE_CXX_COMPILER_LAUNCHER=ccache" >> "${GITHUB_ENV}" + - name: Resolve LLVM directories shell: bash run: | set -euo pipefail echo "LLVM_ROOT=${RUNNER_TOOL_CACHE}/llvm-project" >> "${GITHUB_ENV}" echo "LLVM_DIR=${RUNNER_TOOL_CACHE}/llvm-project/llvm/build-assert" >> "${GITHUB_ENV}" - echo "MLIR_PYTHONPATH=${RUNNER_TOOL_CACHE}/llvm-project/llvm/build-assert/tools/mlir/python_packages/mlir_core" >> "${GITHUB_ENV}" - name: Resolve PTODSL build directories shell: bash run: | set -euo pipefail echo "PTO_DSL_ST_BUILD_DIR=${GITHUB_WORKSPACE}/build-ptodsl" >> "${GITHUB_ENV}" - echo "PTO_DSL_ST_INSTALL_DIR=${GITHUB_WORKSPACE}/install-ptodsl" >> "${GITHUB_ENV}" - echo "PTO_DSL_ST_WHEELHOUSE=${GITHUB_WORKSPACE}/.work/ptodsl-wheelhouse" >> "${GITHUB_ENV}" - name: Resolve LLVM cache key id: llvm-cache-key @@ -231,7 +232,7 @@ jobs: exit 1 fi echo "sha=${sha}" >> "${GITHUB_OUTPUT}" - echo "key=llvm-build-${sha}-assert-v1" >> "${GITHUB_OUTPUT}" + echo "key=llvm-build-${sha}-assert-v2" >> "${GITHUB_OUTPUT}" - name: Restore LLVM build cache id: llvm-cache @@ -247,10 +248,6 @@ jobs: set -euo pipefail rm -rf "${GITHUB_WORKSPACE}/build" rm -rf "${GITHUB_WORKSPACE}/build-ptodsl" - rm -rf "${PTO_INSTALL_DIR}" - rm -rf "${PTO_DSL_ST_INSTALL_DIR}" - rm -rf "${PTO_DSL_ST_WHEELHOUSE}" - rm -rf "${PTO_WHEELHOUSE}" rm -rf "${PTOAS_VENV}" rm -rf "${VPTO_SIM_WORKSPACE}" rm -rf "${TILELANG_DSL_WORKSPACE}" @@ -259,6 +256,16 @@ jobs: rm -rf "${PTO_ISA_ROOT}" rm -rf "${GITHUB_WORKSPACE}/.work/camodel" + - name: Create PTOAS simulator environment + shell: bash + run: | + set -euo pipefail + python3 -m venv "${PTOAS_VENV}" + "${PTOAS_VENV}/bin/python" -m pip install --upgrade pip + "${PTOAS_VENV}/bin/pip" install \ + 'scikit-build-core>=0.12.2,<2' 'pybind11<3' \ + nanobind numpy ml-dtypes + - name: Prepare LLVM source shell: bash run: | @@ -272,9 +279,9 @@ jobs: fi git remote set-url origin "${LLVM_REPO}" - ref="${LLVM_TAG:-${LLVM_REF}}" - git fetch --depth 1 origin "${ref}" - git checkout --force FETCH_HEAD + sha="${{ steps.llvm-cache-key.outputs.sha }}" + git fetch --depth 1 origin "${sha}" + git checkout --force "${sha}" - name: Build LLVM/MLIR if: steps.llvm-cache.outputs.cache-hit != 'true' @@ -296,10 +303,10 @@ jobs: -DBUILD_SHARED_LIBS=ON \ -DLLVM_ENABLE_ASSERTIONS=ON \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DPython3_EXECUTABLE=python3 \ - -DPython_EXECUTABLE=python3 \ - -Dpybind11_DIR="$(python3 -m pybind11 --cmakedir)" \ - -Dnanobind_DIR="$(python3 -m nanobind --cmake_dir)" \ + -DPython3_EXECUTABLE="${PTOAS_VENV}/bin/python" \ + -DPython_EXECUTABLE="${PTOAS_VENV}/bin/python" \ + -Dpybind11_DIR="$("${PTOAS_VENV}/bin/python" -m pybind11 --cmakedir)" \ + -Dnanobind_DIR="$("${PTOAS_VENV}/bin/python" -m nanobind --cmake_dir)" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_TARGETS_TO_BUILD="host" @@ -313,39 +320,20 @@ jobs: path: ${{ env.LLVM_DIR }} key: ${{ steps.llvm-cache-key.outputs.key }} - - name: Build PTOAS wheel + - name: Install PTOAS editable shell: bash run: | set -euo pipefail - rm -rf "${PTO_INSTALL_DIR}" - rm -rf "${PTO_WHEELHOUSE}" - mkdir -p "${PTO_WHEELHOUSE}" # Pin system compilers for the same reason as LLVM above. export CC=gcc export CXX=g++ - # LLVM_BUILD_DIR / PTO_INSTALL_DIR are read by the build backend - # while producing the wheel payload and staging native runtime bits. LLVM_BUILD_DIR="${LLVM_DIR}" \ - PTO_INSTALL_DIR="${PTO_INSTALL_DIR}" \ - python3 -m pip wheel . --no-build-isolation --no-deps --wheel-dir "${PTO_WHEELHOUSE}" - - - name: Create PTOAS simulator venv - shell: bash - run: | - set -euo pipefail - rm -rf "${PTOAS_VENV}" - python3 -m venv "${PTOAS_VENV}" - "${PTOAS_VENV}/bin/python" -m pip install --upgrade pip - - readarray -t ptoas_wheels < <(find "${PTO_WHEELHOUSE}" -maxdepth 1 -type f -name 'ptoas*.whl' | sort) - if [[ "${#ptoas_wheels[@]}" -ne 1 ]]; then - echo "ERROR: expected exactly one PTOAS wheel in ${PTO_WHEELHOUSE}, found ${#ptoas_wheels[@]}" >&2 - printf ' %s\n' "${ptoas_wheels[@]}" >&2 - exit 1 - fi - - "${PTOAS_VENV}/bin/pip" install numpy ml-dtypes "${ptoas_wheels[0]}" - PATH="${PTOAS_VENV}/bin:${PATH}" bash docker/test_wheel_imports.sh + "${PTOAS_VENV}/bin/python" -m pip install --editable . \ + --no-build-isolation --no-deps \ + --config-settings="build-dir=${GITHUB_WORKSPACE}/build" + PATH="${PTOAS_VENV}/bin:${PATH}" \ + PYTHON="${PTOAS_VENV}/bin/python" \ + bash docker/test_wheel_imports.sh - name: Checkout PyPTO uses: actions/checkout@v4 @@ -609,6 +597,7 @@ jobs: deps = [ ("setuptools", "setuptools"), ("wheel", "wheel"), + ("scikit_build_core", "scikit-build-core>=0.12.2,<2"), ("nanobind", "nanobind"), ("numpy", "numpy"), ("ml_dtypes", "ml-dtypes"), @@ -710,10 +699,10 @@ jobs: set -euo pipefail mkdir -p "${TILELANG_DSL_WORKSPACE}" export LLVM_BUILD_DIR="${LLVM_DIR}" - export MLIR_PYTHON_ROOT="${MLIR_PYTHONPATH}" ASCEND_HOME_PATH="${ASCEND_HOME_PATH}" \ PTOAS_BIN="${PTOAS_BIN}" \ - bash test/tilelang_st/script/run_ci.sh -r sim -v a5 --jobs 64 --smoke \ + bash test/tilelang_st/script/run_ci.sh -r sim -v a5 \ + --build-jobs 32 --jobs 64 --smoke \ 2>&1 | tee "${TILELANG_DSL_WORKSPACE}/run_ci.log" - name: Restore PTODSL LLVM build cache @@ -785,32 +774,17 @@ jobs: path: ${{ env.PTO_DSL_ST_LLVM_DIR }} key: llvm-build-${{ steps.llvm-cache-key.outputs.sha }}-assert-${{ env.PTO_DSL_ST_PYTHON_TAG }}-v2 - - name: Build PTODSL PTOAS wheel + - name: Install PTODSL PTOAS editable shell: bash run: | set -euo pipefail - rm -rf "${PTO_DSL_ST_BUILD_DIR}" "${PTO_DSL_ST_INSTALL_DIR}" - rm -rf "${PTO_DSL_ST_WHEELHOUSE}" - mkdir -p "${PTO_DSL_ST_WHEELHOUSE}" + rm -rf "${PTO_DSL_ST_BUILD_DIR}" export CC=gcc export CXX=g++ LLVM_BUILD_DIR="${PTO_DSL_ST_LLVM_DIR}" \ - PTO_BUILD_DIR="${PTO_DSL_ST_BUILD_DIR}" \ - PTO_INSTALL_DIR="${PTO_DSL_ST_INSTALL_DIR}" \ - "${PTO_DSL_ST_PYTHON_BIN}" -m pip wheel . --no-build-isolation --no-deps --wheel-dir "${PTO_DSL_ST_WHEELHOUSE}" - - - name: Install PTODSL PTOAS wheel - shell: bash - run: | - set -euo pipefail - readarray -t ptodsl_wheels < <(find "${PTO_DSL_ST_WHEELHOUSE}" -maxdepth 1 -type f -name 'ptoas*.whl' | sort) - if [[ "${#ptodsl_wheels[@]}" -ne 1 ]]; then - echo "ERROR: expected exactly one PTOAS wheel in ${PTO_DSL_ST_WHEELHOUSE}, found ${#ptodsl_wheels[@]}" >&2 - printf ' %s\n' "${ptodsl_wheels[@]}" >&2 - exit 1 - fi - - "${PTO_DSL_ST_PYTHON_BIN}" -m pip install --force-reinstall "${ptodsl_wheels[0]}" + "${PTO_DSL_ST_PYTHON_BIN}" -m pip install --editable . \ + --no-build-isolation --no-deps \ + --config-settings="build-dir=${PTO_DSL_ST_BUILD_DIR}" - name: Probe PTODSL runtime Python shell: bash @@ -823,12 +797,12 @@ jobs: probe_ptodsl_python() { "${PTO_DSL_ST_PYTHON_BIN}" - <<'PY' import sys - import mlir.ir # noqa: F401 + import ptoas.mlir.ir # noqa: F401 from ptodsl import pto # noqa: F401 - from mlir.dialects import pto as _pto # noqa: F401 + from ptoas.mlir.dialects import pto as _pto # noqa: F401 print(sys.executable) - print("ptodsl/mlir import ok") + print("ptodsl/ptoas.mlir import ok") PY } @@ -939,7 +913,6 @@ jobs: set -euo pipefail mkdir -p "${TILELANG_DSL_UT_WORKSPACE}" export PATH="${PTOAS_VENV}/bin:${PATH}" - export LD_LIBRARY_PATH="${LLVM_DIR}/lib:${PTO_INSTALL_DIR}/lib:${GITHUB_WORKSPACE}/build/lib:${LD_LIBRARY_PATH:-}" cd tilelang-dsl/python python3 -m unittest discover -s ../tests -p 'test_*.py' \ 2>&1 | tee "${TILELANG_DSL_UT_WORKSPACE}/unittest.log" diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ad8933b5a..720ad96cbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,93 +18,53 @@ if(POLICY CMP0169) set(CMAKE_POLICY_DEFAULT_CMP0169 OLD) endif() -function(ptoas_get_cmake_cache_value cache_file variable out_var) - if(NOT EXISTS "${cache_file}") - set(${out_var} "" PARENT_SCOPE) - return() - endif() - - file(STRINGS "${cache_file}" cache_lines - REGEX "^${variable}:[^=]*=") - if(cache_lines) - list(GET cache_lines 0 cache_line) - string(REGEX REPLACE "^[^=]*=" "" cache_value "${cache_line}") - set(${out_var} "${cache_value}" PARENT_SCOPE) - else() - set(${out_var} "" PARENT_SCOPE) - endif() -endfunction() +# Standard Python build backends pass environment variables through to CMake +# but do not synthesize project-specific cache arguments. Accept the existing +# LLVM_BUILD_DIR convention directly so `pip wheel .` and `pip install .` can +# use the same configured LLVM tree as developer CMake builds. +if((NOT DEFINED LLVM_DIR OR LLVM_DIR STREQUAL "") + AND DEFINED ENV{LLVM_BUILD_DIR} + AND NOT "$ENV{LLVM_BUILD_DIR}" STREQUAL "") + set(LLVM_DIR "$ENV{LLVM_BUILD_DIR}/lib/cmake/llvm" CACHE PATH + "LLVM package directory derived from LLVM_BUILD_DIR") +endif() +if((NOT DEFINED MLIR_DIR OR MLIR_DIR STREQUAL "") + AND DEFINED ENV{LLVM_BUILD_DIR} + AND NOT "$ENV{LLVM_BUILD_DIR}" STREQUAL "") + set(MLIR_DIR "$ENV{LLVM_BUILD_DIR}/lib/cmake/mlir" CACHE PATH + "MLIR package directory derived from LLVM_BUILD_DIR") +endif() -function(ptoas_get_llvm_build_dir_from_llvm_dir out_var) - if(NOT DEFINED LLVM_DIR OR LLVM_DIR STREQUAL "") - set(${out_var} "" PARENT_SCOPE) - return() - endif() +project(ptoas VERSION 0.55) - get_filename_component(llvm_cmake_dir "${LLVM_DIR}" REALPATH) - get_filename_component(llvm_build_dir "${llvm_cmake_dir}/../../.." REALPATH) - if(EXISTS "${llvm_build_dir}/CMakeCache.txt") - set(${out_var} "${llvm_build_dir}" PARENT_SCOPE) - else() - set(${out_var} "" PARENT_SCOPE) - endif() -endfunction() +# Wheel builds carry the same Linux hardening policy as release CMake builds. +# Including the cache settings here keeps the policy backend-independent. +if(SKBUILD AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/LinuxHardeningCache.cmake") +endif() -function(ptoas_preseed_compilers_from_llvm_cache) - ptoas_get_llvm_build_dir_from_llvm_dir(llvm_build_dir) - if(llvm_build_dir STREQUAL "") +set(PTOAS_RELEASE_VERSION_OVERRIDE "" + CACHE STRING "Override the version printed by ptoas --version") +# scikit-build-core owns wheel metadata and supplies its resolved PEP 621 +# version here. The optional label distinguishes distributions that install the +# same CLI without making CMake a second source of package-version truth. +set(PTOAS_CLI_VERSION_LABEL "" + CACHE STRING "Optional label prepended to the packaged ptoas version") + +# Editable installs intentionally link against the developer's external LLVM +# build instead of bundling it. Apply that contract explicitly to every native +# Python target; generated and project-owned extensions live in different +# CMake directories and must use the same install RPATH policy. +function(ptoas_append_editable_llvm_rpath target_name) + if(NOT SKBUILD_STATE STREQUAL "editable") return() endif() - - set(llvm_cache "${llvm_build_dir}/CMakeCache.txt") - if(NOT DEFINED CMAKE_C_COMPILER AND "$ENV{CC}" STREQUAL "") - ptoas_get_cmake_cache_value("${llvm_cache}" "CMAKE_C_COMPILER" - llvm_c_compiler) - if(llvm_c_compiler AND EXISTS "${llvm_c_compiler}") - set(CMAKE_C_COMPILER "${llvm_c_compiler}" CACHE FILEPATH - "C compiler inherited from the configured LLVM build" FORCE) - endif() - endif() - - if(NOT DEFINED CMAKE_CXX_COMPILER AND "$ENV{CXX}" STREQUAL "") - ptoas_get_cmake_cache_value("${llvm_cache}" "CMAKE_CXX_COMPILER" - llvm_cxx_compiler) - if(llvm_cxx_compiler AND EXISTS "${llvm_cxx_compiler}") - set(CMAKE_CXX_COMPILER "${llvm_cxx_compiler}" CACHE FILEPATH - "C++ compiler inherited from the configured LLVM build" FORCE) - endif() - endif() + get_filename_component(_ptoas_editable_llvm_library_dir + "${LLVM_BUILD_LIBRARY_DIR}" REALPATH) + set_property(TARGET "${target_name}" APPEND PROPERTY + INSTALL_RPATH "${_ptoas_editable_llvm_library_dir}") endfunction() -ptoas_preseed_compilers_from_llvm_cache() - -project(ptoas VERSION 0.55) -set(PTOAS_VMI_VERSION "0.1.4") - -option(PTOAS_VALIDATE_CMAKE4_FETCHCONTENT_COMPAT - "Validate CMake 4 compatibility for legacy FetchContent users" OFF) -if(PTOAS_VALIDATE_CMAKE4_FETCHCONTENT_COMPAT) - set(_ptoas_cmp0169_check_dir "${CMAKE_BINARY_DIR}/cmake-cmp0169-compat") - file(MAKE_DIRECTORY "${_ptoas_cmp0169_check_dir}/nested/cann-cmake") - file(WRITE "${_ptoas_cmp0169_check_dir}/nested/cann-cmake/CMakeLists.txt" - "cmake_minimum_required(VERSION 3.20)\n" - "project(ptoas_cmp0169_cann_cmake_fixture NONE)\n") - file(WRITE "${_ptoas_cmp0169_check_dir}/nested/CMakeLists.txt" [=[ -cmake_minimum_required(VERSION 3.20) -project(ptoas_cmp0169_nested_fixture NONE) -include(FetchContent) -FetchContent_Declare(cann-cmake SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/cann-cmake") -FetchContent_GetProperties(cann-cmake) -if(NOT cann-cmake_POPULATED) - FetchContent_Populate(cann-cmake) -endif() -]=]) - add_subdirectory("${_ptoas_cmp0169_check_dir}/nested" - "${_ptoas_cmp0169_check_dir}/nested-build") -endif() - -set(PTOAS_RELEASE_VERSION_OVERRIDE "" - CACHE STRING "Override the version printed by ptoas --version") set(PTOAS_EXACT_GIT_TAG_VERSION "") if(EXISTS "${PROJECT_SOURCE_DIR}/.git") find_package(Git QUIET) @@ -127,6 +87,13 @@ set(PTOAS_CLI_VERSION "${PROJECT_VERSION}") if(PTOAS_EXACT_GIT_TAG_VERSION) set(PTOAS_CLI_VERSION "${PTOAS_EXACT_GIT_TAG_VERSION}") endif() +if(SKBUILD AND SKBUILD_PROJECT_VERSION_FULL) + set(PTOAS_CLI_VERSION "${SKBUILD_PROJECT_VERSION_FULL}") +endif() +if(PTOAS_CLI_VERSION_LABEL) + set(PTOAS_CLI_VERSION + "${PTOAS_CLI_VERSION_LABEL} ${PTOAS_CLI_VERSION}") +endif() if(PTOAS_RELEASE_VERSION_OVERRIDE) set(PTOAS_CLI_VERSION "${PTOAS_RELEASE_VERSION_OVERRIDE}") endif() @@ -155,33 +122,6 @@ if(NOT LLVM_VERSION_MAJOR STREQUAL "21") "LLVM ${LLVM_PACKAGE_VERSION}. Please point LLVM_DIR/MLIR_DIR to an " "LLVM 21 build, for example vpto-dev/llvm-project:feature-vpto-llvm21.") endif() -get_filename_component(PTO_LLVM_BUILD_LIBRARY_DIR - "${LLVM_BUILD_LIBRARY_DIR}" REALPATH) -ptoas_get_llvm_build_dir_from_llvm_dir(PTO_LLVM_BUILD_DIR) -if(PTO_LLVM_BUILD_DIR) - ptoas_get_cmake_cache_value("${PTO_LLVM_BUILD_DIR}/CMakeCache.txt" - "CMAKE_CXX_COMPILER" - PTO_LLVM_CXX_COMPILER) -endif() -if(PTO_LLVM_CXX_COMPILER AND EXISTS "${PTO_LLVM_CXX_COMPILER}") - execute_process( - COMMAND "${PTO_LLVM_CXX_COMPILER}" --version - OUTPUT_VARIABLE PTO_LLVM_CXX_VERSION_TEXT - ERROR_VARIABLE PTO_LLVM_CXX_VERSION_TEXT - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - if(PTO_LLVM_CXX_VERSION_TEXT MATCHES "[Cc]lang" - AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - message(FATAL_ERROR - "PTOAS is being configured with GNU C++ (${CMAKE_CXX_COMPILER}), " - "but the selected LLVM build was compiled with a Clang-compatible " - "compiler (${PTO_LLVM_CXX_COMPILER}). MLIR TypeID fallback strings are " - "compiler-family sensitive across shared libraries; use " - "-DCMAKE_CXX_COMPILER=${PTO_LLVM_CXX_COMPILER} or leave the compiler " - "unset so PTOAS can inherit it from LLVM_DIR.") - endif() -endif() - # 将 LLVM 模块路径加入 CMake 搜索路径 list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}") @@ -204,13 +144,14 @@ include(AddMLIR) # 3. 配置构建环境 # ========================================================= # Keep warning policy in CMake so CI, wheel, and external build entrypoints -# all enforce the same diagnostics contract. +# all enforce the same diagnostics contract. Warnings are errors by default; +# directories that compile only third-party sources may opt out narrowly. option(PTOAS_ENABLE_WERROR "Treat PTOAS warnings as errors" ON) if(PTOAS_ENABLE_WERROR) if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") - add_compile_options($<$:-Werror>) + add_compile_options("$<$:-Werror>") elseif(MSVC) - add_compile_options($<$:/WX>) + add_compile_options("$<$:/WX>") endif() endif() @@ -222,12 +163,12 @@ if(APPLE) endforeach() endif() -include_directories(${LLVM_INCLUDE_DIRS}) -include_directories(${MLIR_INCLUDE_DIRS}) +include_directories(SYSTEM ${LLVM_INCLUDE_DIRS}) +include_directories(SYSTEM ${MLIR_INCLUDE_DIRS}) include_directories(${PROJECT_SOURCE_DIR}/include) include_directories(${PROJECT_BINARY_DIR}/include) -link_directories(${PTO_LLVM_BUILD_LIBRARY_DIR}) +link_directories(${LLVM_BUILD_LIBRARY_DIR}) add_definitions(${LLVM_DEFINITIONS}) # ========================================================= @@ -241,13 +182,10 @@ option(PTO_ENABLE_PYTHON_BINDING "Enable Python bindings" ON) include(cmake/VfSimulator.cmake) if(PTO_ENABLE_PYTHON_BINDING) - find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED) - find_package(pybind11 CONFIG REQUIRED) + include(MLIRDetectPythonEnv) + include(AddMLIRPython) + mlir_configure_python_dev_packages() - # 设置 Python 扩展的输出目录,方便调试 - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/python/pto) - - add_subdirectory(python) add_subdirectory(ptodsl) add_subdirectory(tilelang-dsl) endif() @@ -256,8 +194,8 @@ endif() # 4. 添加子目录 # ========================================================= if(BUILD_TESTING AND NOT TARGET ptoas_runtime_deps) - # Define this aggregate target before tools/ptoas runs so it can attach - # ptoas_runtime as a dependency during configure. + # Define this aggregate target before tools/ptoas runs so it can attach the + # staged ptoas._core package as a dependency during configure. add_custom_target(ptoas_runtime_deps) endif() add_subdirectory(include) @@ -270,18 +208,15 @@ add_subdirectory(tools) if(BUILD_TESTING) enable_testing() if(PTO_ENABLE_PYTHON_BINDING) - get_filename_component(_llvm_root "${LLVM_DIR}/../../.." ABSOLUTE) get_filename_component(_pto_python_bin_dir "${Python3_EXECUTABLE}" DIRECTORY) set(_pto_python_test_pythonpath - "${CMAKE_BINARY_DIR}/python:${MLIR_PYTHON_PACKAGE_DIR}:${CMAKE_INSTALL_PREFIX}:$ENV{PYTHONPATH}" + "${CMAKE_BINARY_DIR}/python:$ENV{PYTHONPATH}" ) - if(DEFINED ENV{PTO_INSTALL_DIR} AND NOT "$ENV{PTO_INSTALL_DIR}" STREQUAL "") - set(_pto_python_test_pythonpath "$ENV{PTO_INSTALL_DIR}:${_pto_python_test_pythonpath}") - endif() set(_pto_python_test_env "PYTHONPATH=${_pto_python_test_pythonpath}" - "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${_llvm_root}/lib:${CMAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}" + "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${LLVM_BUILD_LIBRARY_DIR}:${CMAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}" "PATH=${CMAKE_BINARY_DIR}/tools/ptoas:${CMAKE_INSTALL_PREFIX}/bin:${_pto_python_bin_dir}:$ENV{PATH}" + "PTOAS_BIN=${CMAKE_BINARY_DIR}/tools/ptoas/ptoas" ) add_subdirectory(ptodsl/tests) @@ -313,6 +248,15 @@ if(BUILD_TESTING) LABELS "PTO" ENVIRONMENT "${_pto_python_test_env}" ) + add_test( + NAME pto_low_precision_types + COMMAND "${Python3_EXECUTABLE}" -S + "${CMAKE_CURRENT_SOURCE_DIR}/test/python/low_precision_types.py" + ) + set_tests_properties(pto_low_precision_types PROPERTIES + LABELS "PTO" + ENVIRONMENT "${_pto_python_test_env}" + ) endif() add_subdirectory(tools/ptobc/tests) endif() @@ -324,7 +268,12 @@ if(BUILD_TESTING) add_subdirectory(test/lit) set(_pto_check_ctest_depends) - foreach(_target IN ITEMS PTOPythonModules ptoas_runtime_deps ptobc) + foreach(_target IN ITEMS + PTOAS_Python + PTODSLPackage + TileLangDSLPackage + ptoas_runtime_deps + ptobc) if(TARGET ${_target}) list(APPEND _pto_check_ctest_depends ${_target}) endif() diff --git a/README.md b/README.md index 608bf263cd..ac3c4b41f8 100644 --- a/README.md +++ b/README.md @@ -68,10 +68,10 @@ mkdir -p $WORKSPACE_DIR * **OS**: Linux (Ubuntu 20.04+ 推荐) * **Compiler**: GCC >= 9 或 Clang (支持 C++17) * **Build System**: CMake >= 3.20, Ninja -* **Python**: 3.8+ -* **Python Packages**: `pybind11<3`, `nanobind`, `numpy` +* **Python**: 3.10+ +* **Python Packages**: `scikit-build-core`, `pybind11<3`, `nanobind`, `numpy` ```bash -python3 -m pip install 'pybind11<3' nanobind numpy +python3 -m pip install 'scikit-build-core>=0.12.2,<2' 'pybind11<3' nanobind numpy ``` @@ -123,52 +123,21 @@ cd $WORKSPACE_DIR git clone https://gitcode.com/cann/pto-as.git PTOAS cd $PTO_SOURCE_DIR -# 2. 获取 pybind11 的 CMake 路径 -export PYBIND11_CMAKE_DIR=$(python3 -m pybind11 --cmakedir) +# 2. 安装到当前 Python 环境,并保留可增量构建的 build tree +PYTHON_BIN=python3 \ +LLVM_BUILD_DIR="$LLVM_BUILD_DIR" \ +PTO_BUILD_DIR="$PTO_SOURCE_DIR/build" \ + ./quick_install.sh -# 3. 配置 CMake -# 注意:此处直接使用了 3.0 章节中定义的变量,无需手动修改 -cmake -G Ninja \ - -S . \ - -B build \ - -DLLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm \ - -DMLIR_DIR=$LLVM_BUILD_DIR/lib/cmake/mlir \ - -DPython3_EXECUTABLE=$(which python3) \ - -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="${PYBIND11_CMAKE_DIR}" \ - -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core \ - -DCMAKE_INSTALL_PREFIX="$PTO_INSTALL_DIR" - -# 4. 编译并安装 -ninja -C build-llvm21 -ninja -C build-llvm21 install - -# 5. 检查构建产物 -# build 输出(便于本地开发/调试) -$PTO_SOURCE_DIR/build-llvm21/python/ -├── mlir -│ ├── _mlir_libs -│ │ └── _pto.cpython-*.so -│ └── dialects -│ ├── pto.py -│ └── _pto_ops_gen.py - -# install 输出(Python 方言文件和原生扩展) -$PTO_INSTALL_DIR/ -└── mlir - ├── dialects - │ ├── pto.py - │ └── _pto_ops_gen.py - └── _mlir_libs - └── _pto.cpython-*.so - -# CLI 工具 -$PTO_SOURCE_DIR/build-llvm21/tools/ptoas/ptoas -$PTO_SOURCE_DIR/build-llvm21/tools/ptobc/ptobc +# 3. 后续可直接复用同一个 build tree +ninja -C "$PTO_SOURCE_DIR/build" check-pto ``` +`quick_install.sh` 使用 editable install,并关闭 build isolation,避免把临时 +构建环境中的 pybind11 路径写入持久化 `CMakeCache.txt`。`ptoas` 会直接安装到 +`PYTHON_BIN` 对应的当前环境中。 + ### 3.4 Python 安装合同 (Python Distribution Contract) 如果你要使用 Python 绑定、PTODSL资源,推荐使用仓库根目录 @@ -195,7 +164,7 @@ pip install /path/to/ptoas*.whl ```python import ptodsl from ptodsl import pto, scalar -from mlir.dialects import pto as mlir_pto +from ptoas.mlir.dialects import pto as mlir_pto ``` > 说明: @@ -208,39 +177,28 @@ from mlir.dialects import pto as mlir_pto > - `ptoas-bin-*.tar.gz` 这类 compiler-only 二进制 tarball 只提供 CLI/toolchain, > **不是** PTODSL-capable Python distribution;仅解压 tarball 不能保证 > `import ptodsl` 可用。 -> - release tag 约定:`ptoas-vX.Y` 发布主工具链,`vmi-vA.B.C` 发布 VMI 文档/规范。 +> - release tag 约定:`ptoas-vX.Y` 发布主工具链,`vmi-vA.B.C` 发布 +> `ptoas-vmi` distribution。创建 VMI release tag 前,应通过发布 PR 将 +> `packaging/ptoas-vmi/pyproject.toml.patch` 中的版本更新为相同的 `A.B.C`。 +> VMI 发布流程会从当前 Git revision 导出完整源码快照,只在 staging tree +> 中应用该 metadata patch,再直接从 staging tree 构建 wheel;不会修改工作区 +> 根目录的 `pyproject.toml`,也不会在普通门禁或 release 中生成、发布 sdist。 --- ## 4. 运行环境配置 (Runtime Environment) 如果你已经通过 `pip install .`、`pip install -e .` 或 `pip install ptoas*.whl` -完成安装,那么 `import ptodsl` / `from mlir.dialects import pto` / `ptoas` +完成安装,那么 `import ptodsl` / `from ptoas.mlir.dialects import pto` / `ptoas` 都不应再依赖手动设置 `PYTHONPATH`。 -下面这组环境变量主要用于**直接消费 build/install tree** 的场景,例如: - -- 不走 pip 安装,直接调试 CMake install 输出 -- 调试 `ptoas` CLI、动态库搜索路径或 MLIR Python overlay -- 复用仓库脚本做 compile-only / simulator / sample 生成 - -您可以将以下命令添加到 `.bashrc` 或启动脚本中。 +需要 CANN、Bisheng、simulator 或 NPU 时,在完成 PTOAS 安装后再加载 +CANN 自带的环境脚本。PTOAS 的 Python 包和 CLI 仍由当前 pip 环境提供, +不需要手工添加 build/install tree 到 `PYTHONPATH` 或 `PATH`。 ```bash -# --- 运行时变量配置 (基于之前定义的路径) --- - -# 1. Python Path: 拼接 MLIR Core 和 PTO Core -# 这样在 python 中 import mlir.dialects.pto 时能正确找到 -export MLIR_PYTHON_ROOT=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core -export PTO_PYTHON_ROOT=$PTO_INSTALL_DIR/ -export PYTHONPATH=$PTO_PYTHON_ROOT:$MLIR_PYTHON_ROOT:$PYTHONPATH - -# 2. Library Path: 确保能加载 LLVM 和 PTO 的动态库 -export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH - -# 3. PATH: 将 ptoas / ptobc 添加到命令行路径 -export PATH=$PTO_SOURCE_DIR/build-llvm21/tools/ptoas:$PTO_SOURCE_DIR/build-llvm21/tools/ptobc:$PATH - +source "${ASCEND_HOME_PATH}/bin/setenv.bash" +ptoas --version ``` --- @@ -276,9 +234,9 @@ ptoas --version 在支持的 `ptoas` 安装环境中,PTO Dialect 与 PTODSL 都可以直接导入。 ```python -from mlir.ir import Context, Module, Location -# [关键] 从 mlir.dialects 导入 pto,这是 Out-of-tree 绑定的标准用法 -from mlir.dialects import pto +from ptoas.mlir.ir import Context, Module, Location +# PTOAS 自带的 MLIR Python API 位于 ptoas.mlir 命名空间。 +from ptoas.mlir.dialects import pto from ptodsl import pto as jit_pto, scalar with Context() as ctx, Location.unknown(): @@ -301,7 +259,7 @@ cd $PTO_SOURCE_DIR/test/samples/MatMul/ python3 ./tmatmulk.py > ./tmatmulk.pto # 运行ptoas 测试 -$PTO_SOURCE_DIR/build/tools/ptoas/ptoas ./tmatmulk.pto -o ./tmatmulk.cpp +ptoas ./tmatmulk.pto -o ./tmatmulk.cpp ``` ### 5.4 上板验证 diff --git a/README_en.md b/README_en.md index 81d2fb8ab8..046ad24e4d 100644 --- a/README_en.md +++ b/README_en.md @@ -66,11 +66,11 @@ mkdir -p $WORKSPACE_DIR * **OS**: Linux (Ubuntu 20.04+ recommended) * **Compiler**: GCC >= 9 or Clang (C++17 support required) * **Build System**: CMake >= 3.20, Ninja -* **Python**: 3.8+ -* **Python Packages**: `pybind11<3`, `nanobind`, `numpy` +* **Python**: 3.10+ +* **Python Packages**: `scikit-build-core`, `pybind11<3`, `nanobind`, `numpy` ```bash -python3 -m pip install "pybind11<3" nanobind numpy +python3 -m pip install "scikit-build-core>=0.12.2,<2" "pybind11<3" nanobind numpy ``` > **Note**: The current LLVM/MLIR Python bindings are not compatible with `pybind11` 3.x. @@ -113,32 +113,22 @@ cd $WORKSPACE_DIR git clone https://gitcode.com/cann/pto-as.git PTOAS cd $PTO_SOURCE_DIR -# 2. Build and install via pip -# The build backend (pyproject.toml) drives CMake + Ninja automatically. -pip install . --no-build-isolation -``` - -This produces the same artifacts as a manual CMake build: +# 2. Install into the current Python environment while keeping a persistent, +# incrementally reusable build tree. +PYTHON_BIN=python3 \ +LLVM_BUILD_DIR="$LLVM_BUILD_DIR" \ +PTO_BUILD_DIR="$PTO_SOURCE_DIR/build" \ + ./quick_install.sh -```text -# CLI tools -$PTO_SOURCE_DIR/build/tools/ptoas/ptoas -$PTO_SOURCE_DIR/build/tools/ptobc/ptobc - -# Native extension installed into the MLIR Python package -$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core/ -└── mlir - └── _mlir_libs - └── _pto.cpython-*.so - -# Python dialect files -$PTO_INSTALL_DIR/ -└── mlir - └── dialects - ├── pto.py - └── _pto_ops_gen.py +# 3. Reuse the same build tree for subsequent test or development builds. +ninja -C "$PTO_SOURCE_DIR/build" check-pto ``` +`quick_install.sh` uses an editable install with build isolation disabled so a +temporary build environment's pybind11 path is not persisted in +`CMakeCache.txt`. The `ptoas` command is installed into the environment that +owns `PYTHON_BIN`. + ### 3.4 Step 3: Supported Python Install Flows If you want to use Python bindings or PTODSL, prefer the repository-root @@ -162,7 +152,7 @@ After installation, the following imports should work directly: ```python import ptodsl from ptodsl import pto, scalar -from mlir.dialects import pto as mlir_pto +from ptoas.mlir.dialects import pto as mlir_pto ``` > Notes: @@ -171,6 +161,7 @@ from mlir.dialects import pto as mlir_pto > - The VMI release line keeps the `ptoas` CLI name; `ptoas --version` prints `ptoas vmi A.B.C`. > - The `ptoas` and `ptoas-vmi` release wheels are **mutually exclusive**. They both install the same top-level `ptoas` Python package and `ptoas` console script, so do **not** install them into the same Python environment. Mixing them will overwrite files, and uninstalling one can break the other. > - `ptoas-bin-*.tar.gz` compiler-only tarballs provide CLI/toolchain bits, not a PTODSL-capable Python distribution. +> - Release tags use `ptoas-vX.Y` for the main toolchain and `vmi-vA.B.C` for the `ptoas-vmi` distribution. Before creating a VMI release tag, update the version in `packaging/ptoas-vmi/pyproject.toml.patch` to the matching `A.B.C` through the release PR. A VMI build exports the current Git revision, applies that metadata patch only in a staging tree, and builds the wheel directly from that tree. It neither modifies the checkout's top-level `pyproject.toml` nor generates or publishes an sdist in ordinary gates or releases. > - `--no-build-isolation` keeps pip from baking a temporary pybind11 path into `CMakeCache.txt`, which would break later `ninja` reconfigure runs after the temporary virtual environment is removed. If you previously ran `pip install -e .` without the flag and your build is now broken, fix the existing `CMakeCache.txt` with: @@ -208,9 +199,9 @@ In a supported `ptoas` install environment, both the PTO Dialect and PTODSL can be imported directly. ```python -from mlir.ir import Context, Module, Location -# [Key] Import pto from mlir.dialects — the standard pattern for out-of-tree bindings -from mlir.dialects import pto +from ptoas.mlir.ir import Context, Module, Location +# PTOAS ships its MLIR Python API in the ptoas.mlir namespace. +from ptoas.mlir.dialects import pto from ptodsl import pto as jit_pto, scalar with Context() as ctx, Location.unknown(): @@ -232,7 +223,7 @@ cd $PTO_SOURCE_DIR/test/samples/MatMul/ python3 ./tmatmulk.py > ./tmatmulk.pto # Run ptoas tests -$PTO_SOURCE_DIR/build/tools/ptoas/ptoas ./tmatmulk.pto -o ./tmatmulk.cpp +ptoas ./tmatmulk.pto -o ./tmatmulk.cpp ``` ### 4.4 On-Board Validation diff --git a/_ptoas_build_backend.py b/_ptoas_build_backend.py deleted file mode 100644 index 1dfea891db..0000000000 --- a/_ptoas_build_backend.py +++ /dev/null @@ -1,375 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -""" -PEP 517 build backend for ptoas. - -Runs the CMake build (assuming LLVM is already built), then delegates -wheel packaging to docker/create_wheel.sh. - -Environment variables (all optional): - LLVM_BUILD_DIR Path to LLVM build dir - (default: /llvm-workspace/llvm-project/build-shared) - PTO_BUILD_DIR Path to PTOAS build dir (default: /build) - PTO_INSTALL_DIR Install prefix (default: /install) - CMAKE_C_COMPILER Optional C compiler passed through to CMake - CMAKE_CXX_COMPILER Optional C++ compiler passed through to CMake - PTOAS_PYTHON_PACKAGE_NAME Wheel project-name override - PTOAS_PYTHON_PACKAGE_VERSION Wheel version override -""" -from __future__ import annotations - -import base64 -import glob -import hashlib -import io -import os -import re -import shutil -import subprocess -import sys -import zipfile -from pathlib import Path - -_REPO = Path(__file__).parent.resolve() - -def _find_llvm_dir(): - """Return an LLVM install or build-tree prefix, resolving in order: - - 1. ``LLVM_BUILD_DIR`` / ``LLVM_INSTALL_DIR`` env vars - 2. Auto-detect common install locations by probing ``lib/cmake/llvm`` - 3. Default build-tree path - """ - for key in ("LLVM_BUILD_DIR", "LLVM_INSTALL_DIR"): - if key in os.environ: - return Path(os.environ[key]) - - for cand in ("/usr/local/llvm", "/usr/local/Ascend/latest/compiler", - "/opt/llvm"): - if (Path(cand) / "lib" / "cmake" / "llvm").is_dir(): - return Path(cand) - - return Path("/llvm-workspace/llvm-project/build-shared") - - -_LLVM_BUILD_DIR = _find_llvm_dir() -_PTO_INSTALL_DIR = Path( - os.environ.get("PTO_INSTALL_DIR", str(_REPO / "install")) -) -_BUILD_DIR = Path(os.environ.get("PTO_BUILD_DIR", str(_REPO / "build"))) -_PTODSL_SOURCE_ROOT = _REPO / "ptodsl" -_MLIR_PY_PKG = None -if "MLIR_PYTHON_PACKAGE_DIR" in os.environ: - _MLIR_PY_PKG = Path(os.environ["MLIR_PYTHON_PACKAGE_DIR"]) -elif "LLVM_INSTALL_DIR" in os.environ: - _MLIR_PY_PKG = Path(os.environ["LLVM_INSTALL_DIR"]) / "python_packages" / "mlir_core" -else: - _installed = _LLVM_BUILD_DIR / "python_packages" / "mlir_core" - _build_tree = _LLVM_BUILD_DIR / "tools" / "mlir" / "python_packages" / "mlir_core" - _MLIR_PY_PKG = _installed if _installed.exists() else _build_tree -_WHEEL_DIST_DIR = _BUILD_DIR / "wheel-dist" -_PROJECT_VERSION_RE = re.compile( - r"project\s*\(\s*ptoas\s+VERSION\s+([0-9]+\.[0-9]+)\s*\)" -) -_PACKAGE_NAME_RE = re.compile( - r"^[A-Za-z0-9]+(?:[-_.][A-Za-z0-9]+)*$" -) - - -def _default_ptoas_package_name() -> str: - package_name = os.environ.get("PTOAS_PYTHON_PACKAGE_NAME", "").strip() - if not package_name: - return "ptoas" - if not _PACKAGE_NAME_RE.fullmatch(package_name): - raise RuntimeError( - "invalid PTOAS Python package name override " - f"{package_name!r}; expected a normalized project name" - ) - return package_name - - -def _wheel_distribution_name(package_name: str) -> str: - return re.sub(r"[-_.]+", "_", package_name) - - -def _assert_installed_ptodsl_payload() -> None: - """Fail fast if the root install tree did not stage the PTODSL package.""" - installed_init = _PTO_INSTALL_DIR / "ptodsl" / "__init__.py" - if installed_init.exists(): - return - raise RuntimeError( - "PTODSL is missing from the PTOAS install tree. " - f"Expected to find {installed_init}. " - "Root CMake install rules must stage the public 'ptodsl' package " - "before wheel assembly or installed-environment validation." - ) - - -def _assert_installed_ptoas_shared_module() -> None: - installed_shared_module = _PTO_INSTALL_DIR / "lib" / "ptoas.so" - if ( - installed_shared_module.is_file() - and installed_shared_module.stat().st_size > 0 - ): - return - raise RuntimeError( - "PTOAS shared launcher module is missing or empty in the PTOAS install tree. " - f"Expected to find {installed_shared_module}. " - "Wheel assembly now packages the shared module from the install tree." - ) - - -def _assert_editable_ptodsl_source() -> None: - """Fail fast if the editable install cannot point at the PTODSL source.""" - source_init = _PTODSL_SOURCE_ROOT / "ptodsl" / "__init__.py" - if source_init.exists(): - return - raise RuntimeError( - "PTODSL editable source is missing from the repository checkout. " - f"Expected to find {source_init}. " - "Root editable installs must expose the in-repo PTODSL sources." - ) - - -def _default_ptoas_version() -> str: - version = os.environ.get("PTOAS_PYTHON_PACKAGE_VERSION", "").strip() - if version: - return version - cmake_file = _REPO / "CMakeLists.txt" - match = _PROJECT_VERSION_RE.search(cmake_file.read_text(encoding="utf-8")) - if not match: - raise RuntimeError(f"could not find PTOAS version in {cmake_file}") - return match.group(1) - - -def get_requires_for_build_wheel(config_settings=None): - return ["setuptools>=68", "wheel", "pybind11<3"] - - -def get_requires_for_build_editable(config_settings=None): - return ["setuptools>=68", "wheel", "pybind11<3"] - - -def get_requires_for_build_sdist(config_settings=None): - return [] - - -def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): - """Return wheel metadata without running the full build.""" - import email.message - - package_name = _default_ptoas_package_name() - dist_name = _wheel_distribution_name(package_name) - version = _default_ptoas_version() - dist_info = Path(metadata_directory) / f"{dist_name}-{version}.dist-info" - dist_info.mkdir(parents=True, exist_ok=True) - - meta = email.message.Message() - meta["Metadata-Version"] = "2.1" - meta["Name"] = package_name - meta["Version"] = version - meta["Summary"] = "PTO Assembler & Optimizer" - meta["Requires-Python"] = ">=3.9" - meta["License"] = "Apache-2.0" - meta["Requires-Dist"] = "numpy" - (dist_info / "METADATA").write_text(str(meta)) - (dist_info / "WHEEL").write_text( - "Wheel-Version: 1.0\nGenerator: _ptoas_build_backend\n" - "Root-Is-Purelib: True\nTag: py3-none-any\n" - ) - return dist_info.name - - -prepare_metadata_for_build_editable = prepare_metadata_for_build_wheel - - -def build_sdist(sdist_directory, config_settings=None): - raise NotImplementedError( - "ptoas does not support sdist. Use `pip install .` to build a wheel." - ) - - -def _should_use_linux_hardening_cache() -> bool: - return sys.platform.startswith("linux") - - -def _cmake_configure_and_build(skip_install=False): - """CMake configure + build + install.""" - _BUILD_DIR.mkdir(parents=True, exist_ok=True) - - pybind11_dir = subprocess.check_output( - [sys.executable, "-m", "pybind11", "--cmakedir"], text=True - ).strip() - - cmake_cmd = [ - "cmake", "-GNinja", - f"-S{_REPO}", f"-B{_BUILD_DIR}", - "-DCMAKE_BUILD_TYPE=Release", - "-DPTO_ENABLE_PYTHON_BINDING=ON", - f"-DLLVM_DIR={_LLVM_BUILD_DIR}/lib/cmake/llvm", - f"-DMLIR_DIR={_LLVM_BUILD_DIR}/lib/cmake/mlir", - f"-DPython3_ROOT_DIR={sys.prefix}", - f"-DPython3_EXECUTABLE={sys.executable}", - "-DPython3_FIND_STRATEGY=LOCATION", - f"-Dpybind11_DIR={pybind11_dir}", - f"-DMLIR_PYTHON_PACKAGE_DIR={_MLIR_PY_PKG}", - f"-DCMAKE_INSTALL_PREFIX={_PTO_INSTALL_DIR}", - ] - - for compiler_var in ("CMAKE_C_COMPILER", "CMAKE_CXX_COMPILER"): - compiler = os.environ.get(compiler_var, "").strip() - if compiler: - cmake_cmd.append(f"-D{compiler_var}={compiler}") - - release_version = os.environ.get("PTOAS_RELEASE_VERSION_OVERRIDE", "") - if release_version: - cmake_cmd.append(f"-DPTOAS_RELEASE_VERSION_OVERRIDE={release_version}") - - hardening_cache = _REPO / "cmake" / "LinuxHardeningCache.cmake" - if _should_use_linux_hardening_cache() and hardening_cache.exists(): - cmake_cmd.insert(1, f"-C{hardening_cache}") - - subprocess.check_call(cmake_cmd) - subprocess.check_call(["cmake", "--build", str(_BUILD_DIR)]) - if not skip_install: - subprocess.check_call( - ["cmake", "--build", str(_BUILD_DIR), "--target", "install"] - ) - _assert_installed_ptodsl_payload() - _assert_installed_ptoas_shared_module() - - -def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): - _cmake_configure_and_build() - - package_name = _default_ptoas_package_name() - dist_name = _wheel_distribution_name(package_name) - env = os.environ.copy() - env.update({ - "PTO_SOURCE_DIR": str(_REPO), - "PTO_INSTALL_DIR": str(_PTO_INSTALL_DIR), - "PTO_BUILD_DIR": str(_BUILD_DIR), - "LLVM_BUILD_DIR": str(_LLVM_BUILD_DIR), - "PTO_WHEEL_DIST_DIR": str(_WHEEL_DIST_DIR), - # Keep wheel packaging on the same interpreter pip used to invoke the - # backend. This avoids drifting to a different `python3` on PATH in - # conda/self-hosted CI environments. - "PYTHON": sys.executable, - }) - subprocess.check_call( - ["bash", str(_REPO / "docker" / "create_wheel.sh")], - env=env, - ) - - wheels = sorted( - glob.glob(str(_WHEEL_DIST_DIR / f"{dist_name}-*.whl")), - key=os.path.getmtime, - ) - if not wheels: - raise RuntimeError( - f"No {dist_name}-*.whl found in {_WHEEL_DIST_DIR} after build." - ) - - wheel_path = Path(wheels[-1]) - dest = Path(wheel_directory) / wheel_path.name - shutil.copy2(wheel_path, dest) - return dest.name - - -def build_editable(wheel_directory, config_settings=None, metadata_directory=None): - """PEP 660 editable install. - - Builds the C++ extensions in-place, then produces a minimal wheel that - installs a .pth file pointing sys.path at the local PTODSL sources plus - the installed/runtime build outputs. No files are copied into - site-packages except the .pth file itself. - """ - _cmake_configure_and_build(skip_install=True) - _assert_editable_ptodsl_source() - - package_name = _default_ptoas_package_name() - dist_name = _wheel_distribution_name(package_name) - version = _default_ptoas_version() - - # Paths that must be on sys.path for the package to be importable - pth_paths = [ - # mlir.* namespace + _pto.so (installed there by CMake) - str(_MLIR_PY_PKG), - # Prefer the repository PTODSL sources so editable installs pick up - # local Python edits instead of staged/install-tree copies. - str(_PTODSL_SOURCE_ROOT), - # Handwritten Python sources (pto/dialects/pto.py, etc.). - str(_REPO / "python"), - # Installed PTOAS runtime overlay (TileOps/resources when present). - str(_PTO_INSTALL_DIR), - # Generated files (_pto.so, _pto_ops_gen.py) under mlir/ namespace. - str(_BUILD_DIR / "python"), - ] - - # Use executable .pth content so editable installs can deterministically - # prepend the repository PTODSL sources ahead of pre-existing build-tree - # entries in the caller's Python environment. - pth_content = ( - "import sys; " - f"pth_paths = {pth_paths!r}; " - "[sys.path.remove(path) for path in pth_paths if path in sys.path]; " - "sys.path[:0] = pth_paths\n" - ) - pth_filename = f"{dist_name}-editable.pth" - - # ---- Build the editable wheel (a zip with .pth + dist-info) ---- - tag = f"py3-none-any" - wheel_name = f"{dist_name}-{version}-{tag}.whl" - wheel_path = Path(wheel_directory) / wheel_name - - dist_info_dir = f"{dist_name}-{version}.dist-info" - - def _sha256_record(data: bytes) -> str: - digest = hashlib.sha256(data).digest() - b64 = base64.urlsafe_b64encode(digest).rstrip(b"=").decode() - return f"sha256={b64}" - - pth_bytes = pth_content.encode() - wheel_meta = ( - "Wheel-Version: 1.0\n" - "Generator: _ptoas_build_backend\n" - "Root-Is-Purelib: True\n" - f"Tag: {tag}\n" - "Build: editable\n" - ).encode() - entry_points = ( - "[console_scripts]\n" - "ptoas=ptoas_wheel_bootstrap:main\n" - ).encode() - metadata_content = ( - "Metadata-Version: 2.1\n" - f"Name: {package_name}\n" - f"Version: {version}\n" - "Summary: PTO Assembler & Optimizer\n" - "Requires-Python: >=3.9\n" - "License: Apache-2.0\n" - "Requires-Dist: numpy\n" - ).encode() - - record_lines = [ - f"{pth_filename},{_sha256_record(pth_bytes)},{len(pth_bytes)}", - f"{dist_info_dir}/WHEEL,{_sha256_record(wheel_meta)},{len(wheel_meta)}", - f"{dist_info_dir}/entry_points.txt,{_sha256_record(entry_points)},{len(entry_points)}", - f"{dist_info_dir}/METADATA,{_sha256_record(metadata_content)},{len(metadata_content)}", - f"{dist_info_dir}/RECORD,,", - ] - record_content = "\n".join(record_lines).encode() - - with zipfile.ZipFile(wheel_path, "w", compression=zipfile.ZIP_DEFLATED) as zf: - zf.writestr(pth_filename, pth_bytes) - zf.writestr(f"{dist_info_dir}/WHEEL", wheel_meta) - zf.writestr(f"{dist_info_dir}/entry_points.txt", entry_points) - zf.writestr(f"{dist_info_dir}/METADATA", metadata_content) - zf.writestr(f"{dist_info_dir}/RECORD", record_content) - - return wheel_name diff --git a/cmake/RelocatePTOASCompilerArchive.cmake.in b/cmake/RelocatePTOASCompilerArchive.cmake.in new file mode 100644 index 0000000000..843207adf1 --- /dev/null +++ b/cmake/RelocatePTOASCompilerArchive.cmake.in @@ -0,0 +1,205 @@ +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +# Relocate a staged PTOAS compiler archive. This script intentionally runs at +# install time: CMake inspects the binaries that are present in the explicit +# staging prefix, computes their runtime dependency closure, and copies only +# external dependencies into /lib. + +# A full developer `cmake --install` keeps the normal install-tree contract. +# Relocation is an explicit archive-staging operation selected with +# `--component PTOAS_CompilerArchive`. +if(NOT CMAKE_INSTALL_COMPONENT STREQUAL "PTOAS_CompilerArchive") + return() +endif() + +set(_ptoas_archive_root "${CMAKE_INSTALL_PREFIX}") +set(_ptoas_package_root "${_ptoas_archive_root}/ptoas") +set(_ptoas_mlir_lib_root "${_ptoas_package_root}/mlir/_mlir_libs") +set(_ptoas_external_lib_root "${_ptoas_archive_root}/lib") + +if(NOT EXISTS "${_ptoas_package_root}/_cli.py") + message(FATAL_ERROR + "PTOAS compiler archive is missing ptoas/_cli.py under ${_ptoas_archive_root}; " + "install component PTOAS_Python before PTOAS_CompilerArchive") +endif() + +set(_ptoas_known_native_files + "${_ptoas_package_root}/$" + "${_ptoas_mlir_lib_root}/$" +) +foreach(_ptoas_native IN LISTS _ptoas_known_native_files) + if(NOT EXISTS "${_ptoas_native}") + message(FATAL_ERROR + "PTOAS compiler archive is missing native entry point ${_ptoas_native}; " + "install component PTOAS_Python before PTOAS_CompilerArchive") + endif() +endforeach() + +# AddMLIRPython owns the concrete module target list. Treat its installed +# extension directory as the plugin boundary, as opposed to scanning the +# complete archive tree for arbitrary shared libraries. +file(GLOB _ptoas_generated_native_files LIST_DIRECTORIES FALSE + "${_ptoas_mlir_lib_root}/*.so" + "${_ptoas_mlir_lib_root}/*.so.*" + "${_ptoas_mlir_lib_root}/*.dylib") +set(_ptoas_archive_native_files + ${_ptoas_known_native_files} + ${_ptoas_generated_native_files}) +list(REMOVE_DUPLICATES _ptoas_archive_native_files) +if(NOT _ptoas_generated_native_files) + message(FATAL_ERROR + "PTOAS compiler archive contains no MLIR native modules under " + "${_ptoas_mlir_lib_root}; " + "install component PTOAS_Python before PTOAS_CompilerArchive") +endif() + +file(MAKE_DIRECTORY "${_ptoas_external_lib_root}") + +# CMake's DIRECTORIES argument to GET_RUNTIME_DEPENDENCIES has no effect on +# Apple platforms, so it cannot resolve LLVM's @rpath dependencies from an +# external build tree. Let delocate perform both dependency discovery and +# Mach-O install-name relocation, just as it does for the macOS wheel. +if(APPLE) + find_program(_ptoas_delocate_path NAMES delocate-path REQUIRED) + set(_ptoas_dyld_library_path "@LLVM_BUILD_LIBRARY_DIR@") + if(DEFINED ENV{DYLD_LIBRARY_PATH} + AND NOT "$ENV{DYLD_LIBRARY_PATH}" STREQUAL "") + string(APPEND _ptoas_dyld_library_path ":$ENV{DYLD_LIBRARY_PATH}") + endif() + execute_process( + COMMAND "${CMAKE_COMMAND}" -E env + "DYLD_LIBRARY_PATH=${_ptoas_dyld_library_path}" + "${_ptoas_delocate_path}" + --dylibs-only + --lib-path "${_ptoas_external_lib_root}" + "${_ptoas_package_root}" + RESULT_VARIABLE _ptoas_delocate_result + COMMAND_ECHO STDOUT) + if(NOT _ptoas_delocate_result EQUAL 0) + message(FATAL_ERROR "delocate-path failed for PTOAS compiler archive") + endif() + return() +endif() + +set(_ptoas_dependency_search_dirs + "${_ptoas_mlir_lib_root}" + "${_ptoas_archive_root}/lib" + "@LLVM_BUILD_LIBRARY_DIR@") + +file(GET_RUNTIME_DEPENDENCIES + LIBRARIES ${_ptoas_archive_native_files} + DIRECTORIES ${_ptoas_dependency_search_dirs} + RESOLVED_DEPENDENCIES_VAR _ptoas_resolved_dependencies + UNRESOLVED_DEPENDENCIES_VAR _ptoas_unresolved_dependencies + CONFLICTING_DEPENDENCIES_PREFIX _ptoas_conflicting_dependencies + POST_EXCLUDE_REGEXES + "^/lib/.*" + "^/lib64/.*" + "^/usr/lib/.*" + "^/usr/lib64/.*" + "^/System/Library/.*") + +if(_ptoas_unresolved_dependencies) + list(JOIN _ptoas_unresolved_dependencies "\n " _ptoas_unresolved_text) + message(FATAL_ERROR + "Unresolved PTOAS compiler archive dependencies:\n ${_ptoas_unresolved_text}") +endif() + +# A basename collision is harmless only when every candidate has identical +# contents. Otherwise flattening the dependency closure into lib/ would make +# the selected ABI depend on search order. +foreach(_ptoas_conflicting_name IN LISTS + _ptoas_conflicting_dependencies_FILENAMES) + set(_ptoas_conflicting_paths_var + "_ptoas_conflicting_dependencies_${_ptoas_conflicting_name}") + set(_ptoas_conflicting_paths ${${_ptoas_conflicting_paths_var}}) + list(GET _ptoas_conflicting_paths 0 _ptoas_selected_dependency) + file(SHA256 "${_ptoas_selected_dependency}" _ptoas_selected_sha256) + set(_ptoas_conflict_is_identical TRUE) + foreach(_ptoas_conflicting_path IN LISTS _ptoas_conflicting_paths) + file(SHA256 "${_ptoas_conflicting_path}" _ptoas_conflicting_sha256) + if(NOT _ptoas_conflicting_sha256 STREQUAL _ptoas_selected_sha256) + set(_ptoas_conflict_is_identical FALSE) + break() + endif() + endforeach() + + if(NOT _ptoas_conflict_is_identical) + list(JOIN _ptoas_conflicting_paths "\n " _ptoas_conflicting_text) + message(FATAL_ERROR + "Conflicting PTOAS compiler archive dependency " + "${_ptoas_conflicting_name}:\n ${_ptoas_conflicting_text}") + endif() + list(APPEND _ptoas_resolved_dependencies "${_ptoas_selected_dependency}") +endforeach() +list(REMOVE_DUPLICATES _ptoas_resolved_dependencies) + +foreach(_ptoas_dependency IN LISTS _ptoas_resolved_dependencies) + file(REAL_PATH "${_ptoas_dependency}" _ptoas_dependency_real) + string(FIND "${_ptoas_dependency_real}" "${_ptoas_archive_root}/" _ptoas_is_staged) + if(_ptoas_is_staged EQUAL 0) + continue() + endif() + + get_filename_component(_ptoas_dependency_name "${_ptoas_dependency_real}" NAME) + if(_ptoas_dependency_name MATCHES "^libPTOASPythonCAPI") + continue() + endif() + file(INSTALL "${_ptoas_dependency}" + DESTINATION "${_ptoas_external_lib_root}" + TYPE SHARED_LIBRARY + FOLLOW_SYMLINK_CHAIN) +endforeach() + +if(UNIX) + find_program(_ptoas_patchelf NAMES patchelf REQUIRED) + + function(_ptoas_origin_relative_rpath _ptoas_output _ptoas_from _ptoas_to) + file(RELATIVE_PATH _ptoas_relative_path "${_ptoas_from}" "${_ptoas_to}") + if(_ptoas_relative_path STREQUAL "") + set(_ptoas_rpath "$ORIGIN") + else() + set(_ptoas_rpath "$ORIGIN/${_ptoas_relative_path}") + endif() + set(${_ptoas_output} "${_ptoas_rpath}" PARENT_SCOPE) + endfunction() + + foreach(_ptoas_native IN LISTS _ptoas_archive_native_files) + if(IS_SYMLINK "${_ptoas_native}") + continue() + endif() + get_filename_component(_ptoas_native_dir "${_ptoas_native}" DIRECTORY) + _ptoas_origin_relative_rpath( + _ptoas_mlir_lib_rpath "${_ptoas_native_dir}" "${_ptoas_mlir_lib_root}") + _ptoas_origin_relative_rpath( + _ptoas_external_lib_rpath "${_ptoas_native_dir}" "${_ptoas_external_lib_root}") + set(_ptoas_native_rpaths + "$ORIGIN" + "${_ptoas_mlir_lib_rpath}" + "${_ptoas_external_lib_rpath}") + list(REMOVE_DUPLICATES _ptoas_native_rpaths) + list(JOIN _ptoas_native_rpaths ":" _ptoas_native_rpath) + execute_process( + COMMAND "${_ptoas_patchelf}" --set-rpath "${_ptoas_native_rpath}" + "${_ptoas_native}" + COMMAND_ERROR_IS_FATAL ANY) + endforeach() + + file(GLOB _ptoas_external_libraries LIST_DIRECTORIES FALSE + "${_ptoas_external_lib_root}/*.so" + "${_ptoas_external_lib_root}/*.so.*") + foreach(_ptoas_library IN LISTS _ptoas_external_libraries) + if(IS_SYMLINK "${_ptoas_library}") + continue() + endif() + execute_process( + COMMAND "${_ptoas_patchelf}" --set-rpath "$ORIGIN" "${_ptoas_library}" + COMMAND_ERROR_IS_FATAL ANY) + endforeach() +endif() diff --git a/docker/Dockerfile b/docker/Dockerfile index f04c7a29c9..59b92eb174 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -20,7 +20,7 @@ ENV PATH="${PY_PATH}/bin:${PATH}" # dependency RUN dnf install -y ninja-build cmake git ccache gcc-c++ lld zip binutils patchelf chrpath && dnf clean all -RUN pip install --no-cache-dir numpy 'pybind11<3' nanobind setuptools wheel auditwheel +RUN pip install --no-cache-dir numpy 'pybind11<3' nanobind 'scikit-build-core>=0.12.2,<2' auditwheel COPY cmake/LinuxHardeningCache.cmake /tmp/LinuxHardeningCache.cmake @@ -31,7 +31,6 @@ ENV LLVM_BUILD_DIR=$LLVM_SOURCE_DIR/build-release ENV PTO_SOURCE_DIR=$WORKSPACE_DIR/PTOAS ENV PTO_BUILD_DIR=$PTO_SOURCE_DIR/build-release -ENV PTO_INSTALL_DIR=$PTO_SOURCE_DIR/install-release # build LLVM WORKDIR $WORKSPACE_DIR @@ -52,43 +51,29 @@ RUN cmake -C /tmp/LinuxHardeningCache.cmake -G Ninja -S llvm -B $LLVM_BUILD_DIR RUN ninja -C $LLVM_BUILD_DIR -# build ptoas +# build the ptoas wheel through the standard PEP 517 backend WORKDIR $WORKSPACE_DIR RUN git clone https://github.com/zhangstevenunity/PTOAS.git # TODO: tag git commit of PTOAS repo WORKDIR $PTO_SOURCE_DIR -RUN cmake -C /tmp/LinuxHardeningCache.cmake -G Ninja \ - -S . \ - -B $PTO_BUILD_DIR \ - -DLLVM_DIR=$LLVM_BUILD_DIR/lib/cmake/llvm \ - -DMLIR_DIR=$LLVM_BUILD_DIR/lib/cmake/mlir \ - -DPython3_ROOT_DIR=${PY_PATH} \ - -DPython3_EXECUTABLE=${PY_PATH}/bin/python \ - -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR=$(python -m pybind11 --cmakedir) \ - -DMLIR_PYTHON_PACKAGE_DIR=${LLVM_BUILD_DIR}/tools/mlir/python_packages/mlir_core \ - -DCMAKE_INSTALL_PREFIX=${PTO_INSTALL_DIR} \ - -DCMAKE_BUILD_TYPE=Release - -RUN ninja -C $PTO_BUILD_DIR && ninja -C $PTO_BUILD_DIR install - -# create python wheel ENV PTO_WHEEL_DIST_DIR=$PTO_SOURCE_DIR/build/wheel-dist -RUN bash "$PTO_SOURCE_DIR/docker/create_wheel.sh" +RUN SKBUILD_BUILD_DIR=$PTO_BUILD_DIR \ + python -m pip wheel . --no-build-isolation --no-deps \ + --wheel-dir "$PTO_WHEEL_DIST_DIR" # fix missing so -RUN export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH \ +RUN export LD_LIBRARY_PATH=$LLVM_BUILD_DIR/lib:$LD_LIBRARY_PATH \ && auditwheel repair --plat manylinux_2_34_${ARCH} "$PTO_WHEEL_DIST_DIR"/ptoas*.whl -w /wheelhouse RUN pip install /wheelhouse/ptoas*.whl # test the installed wheel contract without adjusting $PYTHONPATH WORKDIR /test -RUN bash "$PTO_SOURCE_DIR/docker/test_wheel_imports.sh" +RUN PTO_TEST_WHEEL_PATH="/wheelhouse/ptoas*.whl" \ + bash "$PTO_SOURCE_DIR/docker/test_wheel_imports.sh" -# test ptoas cli -ENV PATH=$PTO_BUILD_DIR/tools/ptoas:$PATH +# test the wheel-provided ptoas cli RUN which ptoas WORKDIR $PTO_SOURCE_DIR/test/samples/MatMul/ diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 193815e853..71a8dce2b9 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -75,7 +75,6 @@ RUN pip install --no-cache-dir torch==2.9.0 --index-url https://download.pytorch # ========================================================================= ENV PATH="${LLVM_INSTALL_DIR}/bin:${ASCEND_HOME_PATH}/compiler/bin:${PATH}" ENV LD_LIBRARY_PATH="${LLVM_INSTALL_DIR}/lib:${ASCEND_HOME_PATH}/lib64:${ASCEND_HOME_PATH}/lib64/plugin/opskernel:${ASCEND_HOME_PATH}/lib64/plugin/nnengine:${ASCEND_HOME_PATH}/opp/built-in/op_impl/ai_core/tbe/op_tiling/lib/linux/aarch64:${LD_LIBRARY_PATH}" -ENV MLIR_PYTHON_ROOT="${LLVM_INSTALL_DIR}/python_packages/mlir_core" ENV BISHENG_OPTS="-I${PTO_LIB_PATH}/include/pto -fPIC -shared -O2 -std=c++17 --npu-arch=dav-2201 -DMEMORY_BASE" diff --git a/docker/collect_ptoas_dist.sh b/docker/collect_ptoas_dist.sh deleted file mode 100755 index 83f9f7299f..0000000000 --- a/docker/collect_ptoas_dist.sh +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -# Collect ptoas binary and its dependencies into a self-contained distribution. -# -# Usage: ./collect_ptoas_dist.sh -# -# Required environment variables: -# LLVM_BUILD_DIR - Path to LLVM build directory -# PTO_BUILD_DIR - Path to PTO build directory (optional, defaults to PTO_SOURCE_DIR/build) -# PTO_INSTALL_DIR - Path to PTO install directory -# PTO_SOURCE_DIR - Path to PTO source directory -# -# Output structure: -# / -# bin/ptoas - Python wrapper entrypoint -# ptoas/ - Launcher package used by the wrapper -# ptoas_wheel_bootstrap.py - Compatibility bootstrap module -# lib/ptoas.so - Shared runtime loaded by the launcher -# lib/*.so* - Required shared library dependencies -# share/ptoas/TileOps - TileLang template library -# tilelang_dsl/ - TileLang DSL Python package -# -# This compiler-oriented binary artifact intentionally does not bundle the -# PTODSL Python package. PTODSL is provided only by the `ptoas` wheel. - -set -euo pipefail - -if [ $# -lt 1 ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -PTOAS_DIST_DIR="$1" - -# Validate required environment variables -for var in LLVM_BUILD_DIR PTO_INSTALL_DIR PTO_SOURCE_DIR; do - if [ -z "${!var}" ]; then - echo "Error: $var environment variable is not set" >&2 - exit 1 - fi -done - -export LD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" - -PTO_BUILD_DIR="${PTO_BUILD_DIR:-${PTO_SOURCE_DIR}/build}" -PTOAS_BIN="${PTO_BUILD_DIR}/tools/ptoas/ptoas" -PTOAS_SHARED_MODULE="${PTO_INSTALL_DIR}/lib/ptoas.so" -PTOAS_DEPS_DIR="${PTOAS_DIST_DIR}/lib" -PTOAS_SHARED_MODULE_DIST_PATH="${PTOAS_DEPS_DIR}/ptoas.so" -PTOAS_TILEOPS_SRC_DIR="${PTO_INSTALL_DIR}/share/ptoas/TileOps" -PTOAS_TILEOPS_DIST_DIR="${PTOAS_DIST_DIR}/share/ptoas/TileOps" -PTOAS_TILELANG_DSL_SRC_DIR="${PTO_INSTALL_DIR}/tilelang_dsl" -PTOAS_TILELANG_DSL_DIST_DIR="${PTOAS_DIST_DIR}/tilelang_dsl" -PTOAS_WRAPPER_PKG_SRC_DIR="${PTO_INSTALL_DIR}/ptoas" -PTOAS_WRAPPER_PKG_DIST_DIR="${PTOAS_DIST_DIR}/ptoas" -PTOAS_WHEEL_BOOTSTRAP_SRC="${PTO_INSTALL_DIR}/ptoas_wheel_bootstrap.py" -PTOAS_WHEEL_BOOTSTRAP_DIST_PATH="${PTOAS_DIST_DIR}/ptoas_wheel_bootstrap.py" - -if [ ! -f "$PTOAS_BIN" ]; then - echo "Error: ptoas wrapper not found at $PTOAS_BIN" >&2 - exit 1 -fi -if [ ! -f "$PTOAS_SHARED_MODULE" ]; then - echo "Error: shared launcher module not found at $PTOAS_SHARED_MODULE" >&2 - exit 1 -fi -if [ ! -d "$PTOAS_WRAPPER_PKG_SRC_DIR" ]; then - echo "Error: ptoas Python package not found at $PTOAS_WRAPPER_PKG_SRC_DIR" >&2 - exit 1 -fi -if [ ! -f "$PTOAS_WHEEL_BOOTSTRAP_SRC" ]; then - echo "Error: ptoas wheel bootstrap module not found at $PTOAS_WHEEL_BOOTSTRAP_SRC" >&2 - exit 1 -fi - -remove_rpath() { - local path="$1" - if ! has_rpath "$path"; then - return - fi - if ! can_scrub_rpath; then - echo "WARN: skipping RPATH/RUNPATH scrub for ${path}; install patchelf or chrpath to harden local dist artifacts" >&2 - return - fi - if command -v patchelf >/dev/null 2>&1; then - patchelf --remove-rpath "$path" - fi - if has_rpath "$path" && command -v chrpath >/dev/null 2>&1; then - chrpath -d "$path" - fi - if has_rpath "$path"; then - echo "Error: failed to scrub RPATH/RUNPATH from ${path}" >&2 - exit 1 - fi -} - -strip_symbols() { - local path="$1" - strip --strip-unneeded "$path" -} - -has_rpath() { - local path="$1" - if command -v patchelf >/dev/null 2>&1; then - local rpath_value - rpath_value="$(patchelf --print-rpath "$path" 2>/dev/null || true)" - [[ -n "$rpath_value" ]] - return - fi - readelf -d "$path" 2>/dev/null | grep -Eq '(RPATH|RUNPATH)' -} - -can_scrub_rpath() { - command -v patchelf >/dev/null 2>&1 || command -v chrpath >/dev/null 2>&1 -} - -assert_relro() { - local path="$1" - if ! readelf -l "$path" 2>/dev/null | grep -q 'GNU_RELRO'; then - echo "WARN: RELRO segment missing in ${path}" >&2 - return - fi - if ! readelf -d "$path" 2>/dev/null | grep -Eq '(BIND_NOW|FLAGS.*NOW|FLAGS_1.*NOW)'; then - echo "WARN: NOW binding missing in ${path}" >&2 - fi -} - -assert_no_symtab() { - local path="$1" - if readelf -S "$path" 2>/dev/null | grep -Eq '[[:space:]]\\.symtab[[:space:]]'; then - echo "Error: symbol table still present in ${path}" >&2 - exit 1 - fi -} - -assert_no_rpath() { - local path="$1" - if ! can_scrub_rpath; then - return - fi - if has_rpath "$path"; then - echo "Error: runtime search path still present in ${path}" >&2 - exit 1 - fi -} - -harden_elf() { - local path="$1" - remove_rpath "$path" - strip_symbols "$path" - assert_relro "$path" - assert_no_symtab "$path" - assert_no_rpath "$path" -} - -# Create output directories -mkdir -p \ - "${PTOAS_DIST_DIR}/bin" \ - "${PTOAS_DEPS_DIR}" \ - "$(dirname "${PTOAS_TILEOPS_DIST_DIR}")" -rm -rf "${PTOAS_WRAPPER_PKG_DIST_DIR}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" -cp -R "${PTOAS_WRAPPER_PKG_SRC_DIR}" "${PTOAS_WRAPPER_PKG_DIST_DIR}" -cp "${PTOAS_WHEEL_BOOTSTRAP_SRC}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" - -# Copy ptoas binary -echo "Copying ptoas wrapper..." -cp "$PTOAS_BIN" "${PTOAS_DIST_DIR}/bin/" -chmod +x "${PTOAS_DIST_DIR}/bin/ptoas" - -echo "Copying ptoas shared runtime..." -cp -fL "$PTOAS_SHARED_MODULE" "${PTOAS_SHARED_MODULE_DIST_PATH}" - -# Collect non-system *.so dependencies needed by the packaged shared runtime. -echo "Collecting shared library dependencies..." -linux_runtime_dep_paths() { - local path="$1" - ldd "$path" 2>/dev/null | awk ' - /=> \// { print $3 } - /^\// { print $1 } - ' -} - -should_bundle_linux_dep() { - local path="$1" - case "$path" in - /lib/*|/lib64/*|/usr/lib/*|/usr/lib64/*) - return 1 - ;; - esac - return 0 -} - -copy_so() { - local f="$1" - [[ -f "$f" ]] || return 0 - local name - name=$(basename "$f") - [[ -f "${PTOAS_DEPS_DIR}/${name}" ]] && return 0 - cp -L -n "$f" "${PTOAS_DEPS_DIR}/" 2>/dev/null || true - harden_elf "${PTOAS_DEPS_DIR}/${name}" - while read -r res; do - [[ -n "$res" ]] || continue - should_bundle_linux_dep "$res" || continue - copy_so "$res" - done < <(linux_runtime_dep_paths "$f") -} - -while read -r res; do - [[ -n "$res" ]] || continue - should_bundle_linux_dep "$res" || continue - copy_so "$res" -done < <(linux_runtime_dep_paths "$PTOAS_BIN") -while read -r res; do - [[ -n "$res" ]] || continue - should_bundle_linux_dep "$res" || continue - copy_so "$res" -done < <(linux_runtime_dep_paths "$PTOAS_SHARED_MODULE") - -while read -r packaged; do - harden_elf "$packaged" -done < <(find "${PTOAS_DEPS_DIR}" -type f | sort) - -echo "Copying TileLang runtime resources..." -if [ ! -d "${PTOAS_TILEOPS_SRC_DIR}" ]; then - echo "Error: TileOps resource directory not found at ${PTOAS_TILEOPS_SRC_DIR}" >&2 - exit 1 -fi -if [ ! -d "${PTOAS_TILELANG_DSL_SRC_DIR}" ]; then - echo "Error: tilelang_dsl package directory not found at ${PTOAS_TILELANG_DSL_SRC_DIR}" >&2 - exit 1 -fi -rm -rf "${PTOAS_TILEOPS_DIST_DIR}" "${PTOAS_TILELANG_DSL_DIST_DIR}" -cp -R "${PTOAS_TILEOPS_SRC_DIR}" "${PTOAS_TILEOPS_DIST_DIR}" -cp -R "${PTOAS_TILELANG_DSL_SRC_DIR}" "${PTOAS_TILELANG_DSL_DIST_DIR}" - -echo "Smoke testing packaged ptoas dist..." -VERSION_OUTPUT="$(env -u PYTHONPATH -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ - "${PTOAS_DIST_DIR}/bin/ptoas" --version | tr -d '\r')" -echo "$VERSION_OUTPUT" -EXPECTED_PTOAS_CLI_VERSION="${PTOAS_CLI_VERSION:-${PTOAS_VERSION:-}}" -if [ -n "${EXPECTED_PTOAS_CLI_VERSION}" ]; then - EXPECTED_VERSION_OUTPUT="ptoas ${EXPECTED_PTOAS_CLI_VERSION}" - if [ "${VERSION_OUTPUT}" != "${EXPECTED_VERSION_OUTPUT}" ]; then - echo "Error: expected '${EXPECTED_VERSION_OUTPUT}', got '${VERSION_OUTPUT}'" >&2 - exit 1 - fi -else - echo "$VERSION_OUTPUT" | grep -Eq '^ptoas [0-9]+\.[0-9]+$' -fi - -test -d "${PTOAS_TILEOPS_DIST_DIR}" -test -f "${PTOAS_TILELANG_DSL_DIST_DIR}/__init__.py" -test -f "${PTOAS_SHARED_MODULE_DIST_PATH}" -test -f "${PTOAS_WRAPPER_PKG_DIST_DIR}/_runtime_entry.py" -test -f "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" -if [ -e "${PTOAS_DIST_DIR}/ptodsl" ]; then - echo "Error: compiler-oriented ptoas dist must not bundle PTODSL" >&2 - exit 1 -fi - -# Show collected files -echo "" -echo "=== ptoas distribution contents ===" -ls -la "${PTOAS_DIST_DIR}/" -ls -la "${PTOAS_DIST_DIR}/bin/" -ls -la "${PTOAS_DIST_DIR}/share/ptoas/" -ls -la "${PTOAS_TILELANG_DSL_DIST_DIR}" -SO_COUNT=$(find "${PTOAS_DEPS_DIR}" -name "*.so*" 2>/dev/null | wc -l) -echo "=== Collected .so dependencies (${SO_COUNT} files) ===" -du -sh "${PTOAS_DEPS_DIR}/" -echo "" -echo "Distribution created at: ${PTOAS_DIST_DIR}" diff --git a/docker/collect_ptoas_dist_mac.sh b/docker/collect_ptoas_dist_mac.sh deleted file mode 100644 index ee4a1f1f7e..0000000000 --- a/docker/collect_ptoas_dist_mac.sh +++ /dev/null @@ -1,399 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -# Collect ptoas binary and macOS dylib dependencies into a self-contained distribution. -# -# Usage: ./collect_ptoas_dist_mac.sh -# -# Required environment variables: -# LLVM_BUILD_DIR - Path to LLVM build directory -# PTO_BUILD_DIR - Path to PTO build directory (optional, defaults to PTO_SOURCE_DIR/build) -# PTO_INSTALL_DIR - Path to PTO install directory -# PTO_SOURCE_DIR - Path to PTO source directory -# -# Output structure: -# / -# bin/ptoas - Python wrapper entrypoint -# ptoas/ - Launcher package used by the wrapper -# ptoas_wheel_bootstrap.py - Compatibility bootstrap module -# lib/ptoas.so - Shared runtime loaded by the launcher -# lib/*.dylib - Required shared library dependencies -# share/ptoas/TileOps - TileLang template library -# tilelang_dsl/ - TileLang DSL Python package -# -# This compiler-oriented binary artifact intentionally does not bundle the -# PTODSL Python package. PTODSL is provided only by the `ptoas` wheel. - -set -euo pipefail - -if [ $# -lt 1 ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -PTOAS_DIST_DIR="$1" - -# Validate required environment variables -for var in LLVM_BUILD_DIR PTO_INSTALL_DIR PTO_SOURCE_DIR; do - if [ -z "${!var:-}" ]; then - echo "Error: $var environment variable is not set" >&2 - exit 1 - fi -done - -PTO_BUILD_DIR="${PTO_BUILD_DIR:-${PTO_SOURCE_DIR}/build}" -PTOAS_BIN="${PTO_BUILD_DIR}/tools/ptoas/ptoas" -PTOAS_SHARED_MODULE="${PTO_INSTALL_DIR}/lib/ptoas.so" -PTOAS_DEPS_DIR="${PTOAS_DIST_DIR}/lib" -PTOAS_SHARED_MODULE_DIST_PATH="${PTOAS_DEPS_DIR}/ptoas.so" -PTOAS_TILEOPS_SRC_DIR="${PTO_INSTALL_DIR}/share/ptoas/TileOps" -PTOAS_TILEOPS_DIST_DIR="${PTOAS_DIST_DIR}/share/ptoas/TileOps" -PTOAS_TILELANG_DSL_SRC_DIR="${PTO_INSTALL_DIR}/tilelang_dsl" -PTOAS_TILELANG_DSL_DIST_DIR="${PTOAS_DIST_DIR}/tilelang_dsl" -PTOAS_WRAPPER_PKG_SRC_DIR="${PTO_INSTALL_DIR}/ptoas" -PTOAS_WRAPPER_PKG_DIST_DIR="${PTOAS_DIST_DIR}/ptoas" -PTOAS_WHEEL_BOOTSTRAP_SRC="${PTO_INSTALL_DIR}/ptoas_wheel_bootstrap.py" -PTOAS_WHEEL_BOOTSTRAP_DIST_PATH="${PTOAS_DIST_DIR}/ptoas_wheel_bootstrap.py" -UNRESOLVED_NON_SYSTEM_COUNT=0 - -if [ ! -f "$PTOAS_BIN" ]; then - echo "Error: ptoas wrapper not found at $PTOAS_BIN" >&2 - exit 1 -fi -if [ ! -f "$PTOAS_SHARED_MODULE" ]; then - echo "Error: shared launcher module not found at $PTOAS_SHARED_MODULE" >&2 - exit 1 -fi -if [ ! -d "$PTOAS_WRAPPER_PKG_SRC_DIR" ]; then - echo "Error: ptoas Python package not found at $PTOAS_WRAPPER_PKG_SRC_DIR" >&2 - exit 1 -fi -if [ ! -f "$PTOAS_WHEEL_BOOTSTRAP_SRC" ]; then - echo "Error: ptoas wheel bootstrap module not found at $PTOAS_WHEEL_BOOTSTRAP_SRC" >&2 - exit 1 -fi - -mkdir -p \ - "${PTOAS_DIST_DIR}/bin" \ - "${PTOAS_DEPS_DIR}" \ - "$(dirname "${PTOAS_TILEOPS_DIST_DIR}")" -rm -rf "${PTOAS_WRAPPER_PKG_DIST_DIR}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" -cp -R "${PTOAS_WRAPPER_PKG_SRC_DIR}" "${PTOAS_WRAPPER_PKG_DIST_DIR}" -cp "${PTOAS_WHEEL_BOOTSTRAP_SRC}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" -cp -fL "$PTOAS_BIN" "${PTOAS_DIST_DIR}/bin/" -chmod +x "${PTOAS_DIST_DIR}/bin/ptoas" -cp -fL "$PTOAS_SHARED_MODULE" "${PTOAS_SHARED_MODULE_DIST_PATH}" - -# Resolve @rpath / @loader_path / @executable_path / absolute install names. -resolve_dep_path() { - local owner="$1" - local dep="$2" - local owner_dir - owner_dir="$(dirname "$owner")" - - # macOS GitHub runners use bash 3.2; avoid mapfile for compatibility. - local owner_rpaths=() - local rp_line - while IFS= read -r rp_line; do - [ -n "$rp_line" ] && owner_rpaths+=("$rp_line") - done < <( - otool -l "$owner" | awk ' - $1=="cmd" && $2=="LC_RPATH" {want=1; next} - want && $1=="path" {print $2; want=0} - ' - ) - - local dep_tail="$dep" - if [[ "$dep" == @rpath/* ]]; then - dep_tail="${dep#@rpath/}" - fi - - local candidates=() - if [[ "$dep" = /* ]]; then - candidates+=("$dep") - fi - if [[ "$dep" == @loader_path/* ]]; then - candidates+=("${owner_dir}/${dep#@loader_path/}") - fi - if [[ "$dep" == @executable_path/* ]]; then - candidates+=("${PTOAS_DIST_DIR}/bin/${dep#@executable_path/}") - fi - if [[ "$dep" == @rpath/* ]]; then - for rp in "${owner_rpaths[@]:-}"; do - case "$rp" in - @loader_path/*) rp="${owner_dir}/${rp#@loader_path/}" ;; - @executable_path/*) rp="${PTOAS_DIST_DIR}/bin/${rp#@executable_path/}" ;; - esac - candidates+=("${rp}/${dep_tail}") - done - candidates+=( - "${LLVM_BUILD_DIR}/lib/${dep_tail}" - "${PTO_INSTALL_DIR}/lib/${dep_tail}" - "${owner_dir}/${dep_tail}" - ) - fi - - local c - for c in "${candidates[@]}"; do - if [[ -f "$c" ]]; then - echo "$c" - return 0 - fi - done - return 1 -} - -collect_dylibs() { - local bin="$1" - while read -r dep; do - [ -n "$dep" ] || continue - local resolved - resolved="$(resolve_dep_path "$bin" "$dep" || true)" - if [ -z "$resolved" ]; then - case "$dep" in - /usr/lib/*|/System/Library/*) - # Expected on macOS: system libs are provided by the host. - ;; - *) - echo "WARN: unresolved non-system dep for $bin -> $dep" - UNRESOLVED_NON_SYSTEM_COUNT=$((UNRESOLVED_NON_SYSTEM_COUNT + 1)) - ;; - esac - continue - fi - - local base - base="$(basename "$resolved")" - if [ ! -f "${PTOAS_DEPS_DIR}/${base}" ]; then - cp -fL "$resolved" "${PTOAS_DEPS_DIR}/${base}" - install_name_tool -id "@loader_path/${base}" "${PTOAS_DEPS_DIR}/${base}" || true - collect_dylibs "${PTOAS_DEPS_DIR}/${base}" - fi - install_name_tool -change "$dep" "@loader_path/../lib/${base}" "$bin" || true - done < <(otool -L "$bin" | awk 'NR>1 {print $1}') -} - -rewrite_packaged_install_names() { - python3 - "${PTOAS_DIST_DIR}" "${PTOAS_DEPS_DIR}" <<'PY' -import os -import subprocess -import sys -from pathlib import Path - -dist_dir = Path(sys.argv[1]).resolve() -deps_dir = Path(sys.argv[2]).resolve() -bin_dir = (dist_dir / "bin").resolve() -allowed_prefixes = ( - "@loader_path/", - "@rpath/", - "@executable_path/", - "/usr/lib/", - "/System/Library/", -) - - -def is_under(path: Path, root: Path) -> bool: - try: - path.relative_to(root) - return True - except ValueError: - return False - - -def packaged_dep_ref(owner: Path, dep_base: str) -> str: - if is_under(owner, bin_dir): - return f"@loader_path/../lib/{dep_base}" - if is_under(owner, deps_dir): - return f"@loader_path/{dep_base}" - return f"@loader_path/{dep_base}" - - -def iter_targets(): - for root in (bin_dir, deps_dir): - if not root.exists(): - continue - for base, _, files in os.walk(root): - for name in sorted(files): - if name.endswith(".dylib") or name.endswith(".so"): - yield Path(base, name).resolve() - - -def iter_deps(target: Path): - try: - output = subprocess.check_output( - ["otool", "-L", str(target)], - stderr=subprocess.STDOUT, - text=True, - ) - except subprocess.CalledProcessError as exc: - sys.stderr.write( - f"ERROR: failed to inspect install names for {target}: " - f"{exc.output.strip()}\n" - ) - raise SystemExit(exc.returncode or 1) - - for line in output.splitlines()[1:]: - dep = line.strip().split(" ", 1)[0] - if dep: - yield dep - - -for target in iter_targets(): - for dep in iter_deps(target): - if dep.startswith(allowed_prefixes): - continue - - dep_base = os.path.basename(dep) - if not (deps_dir / dep_base).is_file(): - continue - - replacement = packaged_dep_ref(target, dep_base) - if dep == replacement: - continue - - print(f"rewrite install name: {target} :: {dep} -> {replacement}") - try: - subprocess.check_call( - ["install_name_tool", "-change", dep, replacement, str(target)] - ) - except subprocess.CalledProcessError as exc: - sys.stderr.write( - f"ERROR: failed to rewrite install name for {target}: {dep} -> " - f"{replacement} (exit {exc.returncode})\n" - ) - raise SystemExit(exc.returncode or 1) -PY -} - -echo "Collecting dylib dependencies..." -collect_dylibs "${PTOAS_SHARED_MODULE_DIST_PATH}" - -echo "Copying TileLang runtime resources..." -if [[ ! -d "${PTOAS_TILEOPS_SRC_DIR}" ]]; then - echo "Error: TileOps resource directory not found at ${PTOAS_TILEOPS_SRC_DIR}" >&2 - exit 1 -fi -if [[ ! -d "${PTOAS_TILELANG_DSL_SRC_DIR}" ]]; then - echo "Error: tilelang_dsl package directory not found at ${PTOAS_TILELANG_DSL_SRC_DIR}" >&2 - exit 1 -fi -rm -rf "${PTOAS_TILEOPS_DIST_DIR}" "${PTOAS_TILELANG_DSL_DIST_DIR}" -cp -R "${PTOAS_TILEOPS_SRC_DIR}" "${PTOAS_TILEOPS_DIST_DIR}" -cp -R "${PTOAS_TILELANG_DSL_SRC_DIR}" "${PTOAS_TILELANG_DSL_DIST_DIR}" -if [[ -e "${PTOAS_DIST_DIR}/ptodsl" ]]; then - echo "Error: compiler-oriented ptoas dist must not bundle PTODSL" >&2 - exit 1 -fi - -echo "Rewriting packaged install names..." -rewrite_packaged_install_names - -echo "Validating packaged dependency install names..." -if ! python3 - "${PTOAS_DIST_DIR}" <<'PY' -import os -import subprocess -import sys - -root = sys.argv[1] -allowed_prefixes = ( - "@loader_path/", - "@rpath/", - "@executable_path/", - "/usr/lib/", - "/System/Library/", -) - -bad = [] -for base, _, files in os.walk(root): - for name in files: - if not name.endswith(".dylib") and not name.endswith(".so"): - continue - path = os.path.join(base, name) - try: - output = subprocess.check_output( - ["otool", "-L", path], - stderr=subprocess.STDOUT, - text=True, - ) - except subprocess.CalledProcessError as exc: - print(f"ERROR: failed to inspect {path}: {exc.output.strip()}", - file=sys.stderr) - sys.exit(2) - - for line in output.splitlines()[1:]: - dep = line.strip().split(" ", 1)[0] - if dep.startswith(allowed_prefixes): - continue - bad.append((path, dep)) - -for path, dep in bad: - print(f"ERROR: non-portable dependency in {path} -> {dep}", file=sys.stderr) - -print(f"portable dependency scan checked {root} ({len(bad)} offending deps)") -sys.exit(1 if bad else 0) -PY -then - echo "Error: found non-portable dependency install names" >&2 - exit 1 -fi - -if ! command -v codesign >/dev/null 2>&1; then - echo "Error: codesign is required on macOS to sign packaged artifacts" >&2 - exit 1 -fi - -echo "Ad-hoc signing packaged binaries and dylibs..." -shopt -s nullglob -SIGN_TARGETS=("${PTOAS_DEPS_DIR}"/*.so "${PTOAS_DEPS_DIR}"/*.dylib) -for target in "${SIGN_TARGETS[@]}"; do - codesign --force --sign - --timestamp=none "$target" -done - -echo "Verifying code signatures..." -for target in "${SIGN_TARGETS[@]}"; do - codesign --verify --strict --verbose=2 "$target" -done -shopt -u nullglob - -echo "Smoke testing packaged ptoas dist..." -VERSION_OUTPUT="$(env -u PYTHONPATH -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ - "${PTOAS_DIST_DIR}/bin/ptoas" --version | tr -d '\r')" -echo "$VERSION_OUTPUT" -EXPECTED_PTOAS_CLI_VERSION="${PTOAS_CLI_VERSION:-${PTOAS_VERSION:-}}" -if [ -n "${EXPECTED_PTOAS_CLI_VERSION}" ]; then - EXPECTED_VERSION_OUTPUT="ptoas ${EXPECTED_PTOAS_CLI_VERSION}" - if [ "${VERSION_OUTPUT}" != "${EXPECTED_VERSION_OUTPUT}" ]; then - echo "Error: expected '${EXPECTED_VERSION_OUTPUT}', got '${VERSION_OUTPUT}'" >&2 - exit 1 - fi -else - echo "$VERSION_OUTPUT" | grep -Eq '^ptoas [0-9]+\.[0-9]+$' -fi -test -d "${PTOAS_TILEOPS_DIST_DIR}" -test -f "${PTOAS_TILELANG_DSL_DIST_DIR}/__init__.py" -test -f "${PTOAS_SHARED_MODULE_DIST_PATH}" -test -f "${PTOAS_WRAPPER_PKG_DIST_DIR}/_runtime_entry.py" -test -f "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}" -env -u DYLD_LIBRARY_PATH -u LD_LIBRARY_PATH \ - "${PTOAS_DIST_DIR}/bin/ptoas" \ - "${PTO_SOURCE_DIR}/test/lit/pto/kernel_kind_vector_scf_while_emitc.pto" \ - >/dev/null - -echo "" -echo "=== ptoas distribution contents ===" -ls -la "${PTOAS_DIST_DIR}/" -ls -la "${PTOAS_DIST_DIR}/bin/" -ls -la "${PTOAS_DIST_DIR}/share/ptoas/" -ls -la "${PTOAS_TILELANG_DSL_DIST_DIR}" -DYLIB_COUNT=$(find "${PTOAS_DEPS_DIR}" -name "*.dylib" 2>/dev/null | wc -l) -echo "=== Collected .dylib dependencies (${DYLIB_COUNT} files) ===" -du -sh "${PTOAS_DEPS_DIR}/" -echo "=== Unresolved non-system deps: ${UNRESOLVED_NON_SYSTEM_COUNT} ===" -echo "" -echo "Distribution created at: ${PTOAS_DIST_DIR}" diff --git a/docker/copy_ptoas_deps.sh b/docker/copy_ptoas_deps.sh deleted file mode 100644 index 6ddc187138..0000000000 --- a/docker/copy_ptoas_deps.sh +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -# Collect only non-system *.so actually needed by the packaged ptoas shared -# runtime. The `ptoas` wrapper is a Python script, so dependency discovery must -# start from `ptoas.so` instead of running `ldd` on the wrapper itself. -# -# Expects: LLVM_BUILD_DIR, PTO_INSTALL_DIR, PTOAS_DEPS_DIR - -set -euo pipefail - -export LD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" -PTOAS_SHARED_MODULE="${PTO_INSTALL_DIR}/lib/ptoas.so" - -if [[ ! -f "${PTOAS_SHARED_MODULE}" ]]; then - echo "Error: shared launcher module not found at ${PTOAS_SHARED_MODULE}" >&2 - exit 1 -fi - -remove_rpath() { - local path="$1" - if ! has_rpath "$path"; then - return - fi - if ! can_scrub_rpath; then - echo "WARN: skipping RPATH/RUNPATH scrub for ${path}; install patchelf or chrpath to harden local dist artifacts" >&2 - return - fi - if command -v patchelf >/dev/null 2>&1; then - patchelf --remove-rpath "$path" - fi - if has_rpath "$path" && command -v chrpath >/dev/null 2>&1; then - chrpath -d "$path" - fi - if has_rpath "$path"; then - echo "Error: failed to scrub RPATH/RUNPATH from ${path}" >&2 - exit 1 - fi -} - -strip_symbols() { - local path="$1" - strip --strip-unneeded "$path" -} - -has_rpath() { - local path="$1" - if command -v patchelf >/dev/null 2>&1; then - local rpath_value - rpath_value="$(patchelf --print-rpath "$path" 2>/dev/null || true)" - [[ -n "$rpath_value" ]] - return - fi - readelf -d "$path" 2>/dev/null | grep -Eq '(RPATH|RUNPATH)' -} - -can_scrub_rpath() { - command -v patchelf >/dev/null 2>&1 || command -v chrpath >/dev/null 2>&1 -} - -assert_relro() { - local path="$1" - if ! readelf -l "$path" 2>/dev/null | grep -q 'GNU_RELRO'; then - echo "WARN: RELRO segment missing in ${path}" >&2 - return - fi - if ! readelf -d "$path" 2>/dev/null | grep -Eq '(BIND_NOW|FLAGS.*NOW|FLAGS_1.*NOW)'; then - echo "WARN: NOW binding missing in ${path}" >&2 - fi -} - -assert_no_symtab() { - local path="$1" - if readelf -S "$path" 2>/dev/null | grep -Eq '[[:space:]]\\.symtab[[:space:]]'; then - echo "Error: symbol table still present in ${path}" >&2 - exit 1 - fi -} - -assert_no_rpath() { - local path="$1" - if ! can_scrub_rpath; then - return - fi - if has_rpath "$path"; then - echo "Error: runtime search path still present in ${path}" >&2 - exit 1 - fi -} - -harden_elf() { - local path="$1" - remove_rpath "$path" - strip_symbols "$path" - assert_relro "$path" - assert_no_symtab "$path" - assert_no_rpath "$path" -} - -copy_so() { - local f="$1" - [[ -f "$f" ]] || return 0 - local name - name=$(basename "$f") - [[ -f "${PTOAS_DEPS_DIR}/${name}" ]] && return 0 - cp -L -n "$f" "${PTOAS_DEPS_DIR}/" 2>/dev/null || true - harden_elf "${PTOAS_DEPS_DIR}/${name}" - while read -r res; do - [[ -n "$res" ]] || continue - should_bundle_linux_dep "$res" || continue - copy_so "$res" - done < <(linux_runtime_dep_paths "$f") -} - -linux_runtime_dep_paths() { - local path="$1" - ldd "$path" 2>/dev/null | awk ' - /=> \// { print $3 } - /^\// { print $1 } - ' -} - -should_bundle_linux_dep() { - local path="$1" - case "$path" in - /lib/*|/lib64/*|/usr/lib/*|/usr/lib64/*) - return 1 - ;; - esac - return 0 -} - -mkdir -p "$PTOAS_DEPS_DIR" -while read -r res; do - [[ -n "$res" ]] || continue - should_bundle_linux_dep "$res" || continue - copy_so "$res" -done < <(linux_runtime_dep_paths "$PTOAS_SHARED_MODULE") - -while read -r packaged; do - harden_elf "$packaged" -done < <(find "$PTOAS_DEPS_DIR" -type f | sort) diff --git a/docker/create_wheel.sh b/docker/create_wheel.sh deleted file mode 100755 index 36a9f8fa6d..0000000000 --- a/docker/create_wheel.sh +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -set -euo pipefail - -for var in PTO_SOURCE_DIR PTO_INSTALL_DIR LLVM_BUILD_DIR; do - if [[ -z "${!var:-}" ]]; then - echo "Error: $var environment variable is not set" >&2 - exit 1 - fi -done - -WHEEL_STAGING_DIR="${PTO_WHEEL_STAGING_DIR:-${PTO_SOURCE_DIR}/build/wheel-staging}" -WHEEL_DIST_DIR="${PTO_WHEEL_DIST_DIR:-${PTO_SOURCE_DIR}/build/wheel-dist}" -RUNTIME_STAGING_DIR="${PTO_RUNTIME_STAGING_DIR:-${PTO_SOURCE_DIR}/build/runtime-staging}" -PTO_BUILD_DIR="${PTO_BUILD_DIR:-${PTO_SOURCE_DIR}/build}" -PYTHON_BIN="${PYTHON:-python3}" -PTOAS_PYTHON_PACKAGE_NAME="${PTOAS_PYTHON_PACKAGE_NAME:-ptoas}" -PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_PYTHON_PACKAGE_VERSION:-${PTOAS_VERSION:-}}" -PTOAS_CLI_VERSION="${PTOAS_CLI_VERSION:-${PTOAS_VERSION:-}}" -if [[ ! "${PTOAS_PYTHON_PACKAGE_NAME}" =~ ^[A-Za-z0-9]+([-_.][A-Za-z0-9]+)*$ ]]; then - echo "Error: invalid PTOAS_PYTHON_PACKAGE_NAME '${PTOAS_PYTHON_PACKAGE_NAME}'; expected a normalized project name" >&2 - exit 1 -fi -PTOAS_WHEEL_DISTRIBUTION_NAME="$(printf '%s' "${PTOAS_PYTHON_PACKAGE_NAME}" | sed -E 's/[-_.]+/_/g')" -PTOAS_WRAPPER_PKG_DIR="${PTO_SOURCE_DIR}/ptodsl/ptoas" -PTOAS_WHEEL_BOOTSTRAP="${PTO_SOURCE_DIR}/ptodsl/ptoas_wheel_bootstrap.py" -PTODSL_INSTALL_DIR="${PTO_INSTALL_DIR}/ptodsl" -MLIR_PYTHON_PACKAGE_DIR="${LLVM_BUILD_DIR}/tools/mlir/python_packages/mlir_core" - -if [[ -z "${PTOAS_PYTHON_PACKAGE_VERSION}" ]]; then - PTOAS_PYTHON_PACKAGE_VERSION="$("${PYTHON_BIN}" "${PTO_SOURCE_DIR}/.github/scripts/compute_ptoas_version.py" \ - --cmake-file "${PTO_SOURCE_DIR}/CMakeLists.txt" --mode dev)" -fi -export PTOAS_PYTHON_PACKAGE_VERSION - -linux_runtime_dep_paths() { - local path="$1" - local library_path="${2:-}" - if [[ -n "${library_path}" ]]; then - env LD_LIBRARY_PATH="${library_path}" ldd "$path" 2>/dev/null | awk ' - /=> \// { print $3 } - /^\// { print $1 } - ' - return - fi - ldd "$path" 2>/dev/null | awk ' - /=> \// { print $3 } - /^\// { print $1 } - ' -} - -should_bundle_linux_dep() { - local path="$1" - case "$path" in - /lib/*|/lib64/*|/usr/lib/*|/usr/lib64/*) - return 1 - ;; - esac - return 0 -} - -assemble_linux_wheel_runtime() { - local ptoas_wrapper="${PTO_INSTALL_DIR}/bin/ptoas" - if [[ ! -f "${ptoas_wrapper}" ]]; then - ptoas_wrapper="${PTO_BUILD_DIR}/tools/ptoas/ptoas" - fi - if [[ ! -f "${ptoas_wrapper}" ]]; then - echo "Error: ptoas wrapper not found in build tree or install tree" >&2 - exit 1 - fi - if [[ ! -d "${PTO_INSTALL_DIR}/share/ptoas/TileOps" ]]; then - echo "Error: TileOps resource directory not found at ${PTO_INSTALL_DIR}/share/ptoas/TileOps" >&2 - exit 1 - fi - - mkdir -p "${RUNTIME_STAGING_DIR}/lib" "${RUNTIME_STAGING_DIR}/share/ptoas" - cp -R "${PTO_INSTALL_DIR}/share/ptoas/TileOps" "${RUNTIME_STAGING_DIR}/share/ptoas/TileOps" - cp "${PTO_INSTALL_DIR}/lib/ptoas.so" "${RUNTIME_STAGING_DIR}/lib/ptoas.so" - - # Resolve transitive MLIR/LLVM dependencies through the build tree so - # ldd can discover non-installed libs such as libMLIRMlirOptMain.so.*. - local dep_ld_library_path="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" - while read -r dep_path; do - [[ -n "${dep_path}" ]] || continue - should_bundle_linux_dep "${dep_path}" || continue - cp -L -n "${dep_path}" "${RUNTIME_STAGING_DIR}/lib/" - done < <(linux_runtime_dep_paths "${PTO_INSTALL_DIR}/lib/ptoas.so" "${dep_ld_library_path}" | sort -u) - - local version_output - local version_ld_library_path="${LLVM_BUILD_DIR}/lib:${RUNTIME_STAGING_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" - version_output="$( - env -u PYTHONPATH -u DYLD_LIBRARY_PATH \ - LD_LIBRARY_PATH="${version_ld_library_path}" \ - "${ptoas_wrapper}" --version | tr -d '\r' - )" - echo "${version_output}" - if [[ -n "${PTOAS_CLI_VERSION:-}" ]]; then - local expected_version_output="ptoas ${PTOAS_CLI_VERSION}" - if [[ "${version_output}" != "${expected_version_output}" ]]; then - echo "Error: expected '${expected_version_output}', got '${version_output}'" >&2 - exit 1 - fi - else - echo "${version_output}" | grep -Eq '^ptoas [0-9]+\.[0-9]+$' - fi -} - -echo "Creating Python wheel..." -echo "Wheel package version: ${PTOAS_PYTHON_PACKAGE_VERSION}" - -rm -rf "${WHEEL_STAGING_DIR}" "${WHEEL_DIST_DIR}" "${RUNTIME_STAGING_DIR}" -mkdir -p "${WHEEL_STAGING_DIR}" "${WHEEL_DIST_DIR}" - -echo "Assembling unified runtime staging tree..." -case "$(uname -s)" in - Darwin) - bash "${PTO_SOURCE_DIR}/docker/collect_ptoas_dist_mac.sh" "${RUNTIME_STAGING_DIR}" - ;; - *) - assemble_linux_wheel_runtime - ;; -esac - -echo "Copying MLIR Python package into wheel staging..." -cp -a "${MLIR_PYTHON_PACKAGE_DIR}/." "${WHEEL_STAGING_DIR}/" - -echo "Overlaying PTO dialect files..." -mkdir -p "${WHEEL_STAGING_DIR}/mlir/dialects" -find "${PTO_INSTALL_DIR}/mlir/dialects" -maxdepth 1 -type f -name '*.py' -exec cp {} "${WHEEL_STAGING_DIR}/mlir/dialects/" \; - -echo "Overlaying PTO native extension..." -mkdir -p "${WHEEL_STAGING_DIR}/mlir/_mlir_libs" -find "${PTO_INSTALL_DIR}/mlir/_mlir_libs" -maxdepth 1 -type f -name '_pto*' -exec cp {} "${WHEEL_STAGING_DIR}/mlir/_mlir_libs/" \; - -echo "Copying TileLang resources..." -rm -rf "${WHEEL_STAGING_DIR}/tilelang_dsl" "${WHEEL_STAGING_DIR}/TileOps" -cp -R "${PTO_INSTALL_DIR}/tilelang_dsl" "${WHEEL_STAGING_DIR}/tilelang_dsl" -cp -R "${PTO_INSTALL_DIR}/share/ptoas/TileOps" "${WHEEL_STAGING_DIR}/TileOps" - -echo "Copying ptodsl package..." -if [[ ! -d "${PTODSL_INSTALL_DIR}" ]]; then - echo "Error: ptodsl package directory not found at ${PTODSL_INSTALL_DIR}" >&2 - exit 1 -fi -if [[ ! -f "${PTODSL_INSTALL_DIR}/__init__.py" ]]; then - echo "Error: ptodsl package is missing ${PTODSL_INSTALL_DIR}/__init__.py" >&2 - exit 1 -fi -rm -rf "${WHEEL_STAGING_DIR}/ptodsl" -cp -R "${PTODSL_INSTALL_DIR}" "${WHEEL_STAGING_DIR}/ptodsl" - -echo "Copying ptoas wheel wrapper package..." -if [[ ! -d "${PTOAS_WRAPPER_PKG_DIR}" ]]; then - echo "Error: ptoas wrapper package directory not found at ${PTOAS_WRAPPER_PKG_DIR}" >&2 - exit 1 -fi -if [[ ! -f "${PTOAS_WRAPPER_PKG_DIR}/__init__.py" ]]; then - echo "Error: ptoas wrapper package is missing ${PTOAS_WRAPPER_PKG_DIR}/__init__.py" >&2 - exit 1 -fi -cp -R "${PTOAS_WRAPPER_PKG_DIR}" "${WHEEL_STAGING_DIR}/ptoas" -if [[ ! -f "${PTOAS_WHEEL_BOOTSTRAP}" ]]; then - echo "Error: ptoas wheel bootstrap module not found at ${PTOAS_WHEEL_BOOTSTRAP}" >&2 - exit 1 -fi -cp "${PTOAS_WHEEL_BOOTSTRAP}" "${WHEEL_STAGING_DIR}/ptoas_wheel_bootstrap.py" - -echo "Embedding unified runtime payload for wheel-side ptoas launcher..." -mkdir -p "${WHEEL_STAGING_DIR}/ptoas/_runtime" -cp -R "${RUNTIME_STAGING_DIR}/share" "${WHEEL_STAGING_DIR}/ptoas/_runtime/share" -cp -R "${RUNTIME_STAGING_DIR}/lib" "${WHEEL_STAGING_DIR}/ptoas/_runtime/lib" - -echo "Removing packaging residue..." -find "${WHEEL_STAGING_DIR}" \( -name '*.egg-info' -o -name '*.dist-info' \) -prune -exec rm -rf {} + -find "${WHEEL_STAGING_DIR}" -name '__pycache__' -prune -exec rm -rf {} + - -export PTO_WHEEL_STAGING_DIR="${WHEEL_STAGING_DIR}" -export PTO_WHEEL_DIST_DIR="${WHEEL_DIST_DIR}" -export PTOAS_PYTHON_PACKAGE_NAME -export PTOAS_PYTHON_PACKAGE_VERSION -export PTOAS_WHEEL_DISTRIBUTION_NAME - -echo "Building wheel archive directly..." -"${PYTHON_BIN}" - <<'PY' -import base64 -import csv -import hashlib -import os -import platform -import re -import sys -import zipfile -from pathlib import Path - -staging = Path(os.environ["PTO_WHEEL_STAGING_DIR"]) -dist = Path(os.environ["PTO_WHEEL_DIST_DIR"]) -project_name = os.environ["PTOAS_PYTHON_PACKAGE_NAME"] -version = os.environ["PTOAS_PYTHON_PACKAGE_VERSION"] -dist_name = os.environ.get("PTOAS_WHEEL_DISTRIBUTION_NAME") or re.sub( - r"[-_.]+", "_", project_name -) - -py_tag = f"cp{sys.version_info.major}{sys.version_info.minor}" -if sys.platform == "darwin": - platform_tag = os.environ.get("WHEEL_PLAT_NAME") or "macosx_11_0_arm64" -else: - arch = platform.machine().lower().replace("-", "_") - platform_tag = os.environ.get("WHEEL_PLAT_NAME") or f"linux_{arch}" - -wheel_name = f"{dist_name}-{version}-{py_tag}-{py_tag}-{platform_tag}.whl" -wheel_path = dist / wheel_name -dist_info = f"{dist_name}-{version}.dist-info" - -metadata = "\n".join([ - "Metadata-Version: 2.1", - f"Name: {project_name}", - f"Version: {version}", - "Summary: PTO Assembler & Optimizer", - "Requires-Python: >=3.9", - "License: Apache-2.0", - "Requires-Dist: numpy", - "", -]).encode("utf-8") - -wheel = "\n".join([ - "Wheel-Version: 1.0", - "Generator: create_wheel.sh", - "Root-Is-Purelib: false", - f"Tag: {py_tag}-{py_tag}-{platform_tag}", - "", -]).encode("utf-8") - -record_rows = [] -has_ptodsl_init = False -has_ptoas_shared_module = False - -def hash_bytes(data: bytes) -> str: - digest = hashlib.sha256(data).digest() - return "sha256=" + base64.urlsafe_b64encode(digest).rstrip(b"=").decode("ascii") - -with zipfile.ZipFile(wheel_path, "w", compression=zipfile.ZIP_DEFLATED) as zf: - for path in sorted(staging.rglob("*")): - if not path.is_file(): - continue - rel = path.relative_to(staging).as_posix() - data = path.read_bytes() - zf.write(path, rel) - record_rows.append((rel, hash_bytes(data), str(len(data)))) - if rel == "ptodsl/__init__.py": - has_ptodsl_init = True - if rel == "ptoas/_runtime/lib/ptoas.so": - has_ptoas_shared_module = True - - entry_points = "\n".join([ - "[console_scripts]", - "ptoas=ptoas_wheel_bootstrap:main", - "", - ]).encode("utf-8") - - for rel, data in [ - (f"{dist_info}/METADATA", metadata), - (f"{dist_info}/WHEEL", wheel), - (f"{dist_info}/entry_points.txt", entry_points), - ]: - zf.writestr(rel, data) - record_rows.append((rel, hash_bytes(data), str(len(data)))) - - record_rel = f"{dist_info}/RECORD" - from io import StringIO - buf = StringIO() - writer = csv.writer(buf, lineterminator="\n") - for row in record_rows: - writer.writerow(row) - writer.writerow((record_rel, "", "")) - record_bytes = buf.getvalue().encode("utf-8") - zf.writestr(record_rel, record_bytes) - -if not has_ptodsl_init: - raise SystemExit("Wheel staging payload is missing ptodsl/__init__.py") -if not has_ptoas_shared_module: - raise SystemExit("Wheel staging payload is missing ptoas/_runtime/lib/ptoas.so") - -with zipfile.ZipFile(wheel_path) as zf: - if "ptodsl/__init__.py" not in zf.namelist(): - raise SystemExit("Built wheel is missing ptodsl/__init__.py") - if "ptoas/_runtime/lib/ptoas.so" not in zf.namelist(): - raise SystemExit("Built wheel is missing ptoas/_runtime/lib/ptoas.so") - if "ptoas/_runtime/bin/ptoas" in zf.namelist(): - raise SystemExit("Built wheel unexpectedly contains ptoas/_runtime/bin/ptoas") - -print(f"Wheel created at {wheel_path}") -PY - -echo "Wheel package name: ${PTOAS_PYTHON_PACKAGE_NAME}" -echo "Wheel created at ${WHEEL_DIST_DIR}/" -ls -la "${WHEEL_DIST_DIR}/"*.whl - -EXPECTED_WHEEL_GLOB="${WHEEL_DIST_DIR}/${PTOAS_WHEEL_DISTRIBUTION_NAME}-${PTOAS_PYTHON_PACKAGE_VERSION}-"*.whl -if ! compgen -G "${EXPECTED_WHEEL_GLOB}" >/dev/null 2>&1; then - echo "Error: expected wheel matching ${EXPECTED_WHEEL_GLOB}" >&2 - exit 1 -fi diff --git a/docker/setup.py b/docker/setup.py deleted file mode 100644 index e6820d5faf..0000000000 --- a/docker/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import os -import pathlib -import re - -from setuptools import setup, find_namespace_packages - - -_PROJECT_VERSION_RE = re.compile( - r"project\s*\(\s*ptoas\s+VERSION\s+([0-9]+\.[0-9]+)\s*\)" -) - - -def read_package_name() -> str: - package_name = os.environ.get("PTOAS_PYTHON_PACKAGE_NAME", "").strip() - return package_name or "ptoas" - - -def read_package_version() -> str: - version = os.environ.get("PTOAS_PYTHON_PACKAGE_VERSION", "").strip() - if version: - return version - cmake_file = pathlib.Path(__file__).resolve().parents[1] / "CMakeLists.txt" - match = _PROJECT_VERSION_RE.search(cmake_file.read_text(encoding="utf-8")) - if not match: - raise RuntimeError(f"could not find PTOAS version in {cmake_file}") - return match.group(1) - -setup( - name=read_package_name(), - version=read_package_version(), - description="PTO Assembler & Optimizer", - # NOTE: find_namespace_packages detects folders even without __init__.py - packages=find_namespace_packages(), - # NOTE: The * at the end captures .so.22, .so.22.1, etc. - package_data={ - "mlir": [ - "**/*.so*", - "**/*.pyd", - "**/*.py", - "_mlir_libs/*.so*", - ], - }, - include_package_data=True, - zip_safe=False, - python_requires=">=3.9", -) diff --git a/docker/setup_mac.py b/docker/setup_mac.py deleted file mode 100644 index c61ad3e1a5..0000000000 --- a/docker/setup_mac.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import os -import pathlib -import re - -from setuptools import find_namespace_packages, setup -from setuptools.dist import Distribution - - -class BinaryDistribution(Distribution): - """Force a platform-tagged wheel for macOS artifacts.""" - - def has_ext_modules(self): - return True - - -def read_package_name() -> str: - package_name = os.environ.get("PTOAS_PYTHON_PACKAGE_NAME", "").strip() - return package_name or "ptoas" - - -def read_package_version() -> str: - version = os.environ.get("PTOAS_PYTHON_PACKAGE_VERSION", "").strip() - if version: - return version - cmake_file = pathlib.Path(__file__).resolve().parents[1] / "CMakeLists.txt" - project_version_re = re.compile( - r"project\s*\(\s*ptoas\s+VERSION\s+([0-9]+\.[0-9]+)\s*\)" - ) - match = project_version_re.search(cmake_file.read_text(encoding="utf-8")) - if not match: - raise RuntimeError(f"could not find PTOAS version in {cmake_file}") - return match.group(1) - -setup( - name=read_package_name(), - version=read_package_version(), - description="PTO Assembler & Optimizer", - # NOTE: find_namespace_packages detects folders even without __init__.py - packages=find_namespace_packages(), - # Include native libraries used by macOS wheels (.dylib), while keeping - # existing patterns so this file remains robust across build layouts. - package_data={ - "mlir": [ - "**/*.dylib", - "_mlir_libs/*.dylib", - "**/*.so*", - "**/*.pyd", - "**/*.py", - "_mlir_libs/*.so*", - ], - }, - include_package_data=True, - zip_safe=False, - python_requires=">=3.9", - distclass=BinaryDistribution, -) diff --git a/docker/test_ptoas_cli.sh b/docker/test_ptoas_cli.sh index 6902d679ae..8ce29e1b87 100755 --- a/docker/test_ptoas_cli.sh +++ b/docker/test_ptoas_cli.sh @@ -13,35 +13,22 @@ # # Required environment variables: # PTO_SOURCE_DIR - Path to PTO source directory -# PTO_BUILD_DIR - Path to PTO build directory -# LLVM_BUILD_DIR - Path to LLVM build directory -# PTO_INSTALL_DIR - Path to PTO install directory -# PTOAS_BIN - Path to the Python ptoas wrapper (optional) +# PTOAS_BIN - Exact ptoas entrypoint under test -set -e +set -euo pipefail # Validate required environment variables -for var in PTO_SOURCE_DIR PTO_BUILD_DIR LLVM_BUILD_DIR PTO_INSTALL_DIR; do - if [ -z "${!var}" ]; then +for var in PTO_SOURCE_DIR PTOAS_BIN; do + if [ -z "${!var:-}" ]; then echo "Error: $var environment variable is not set" >&2 exit 1 fi done -# Setup environment -export PATH="${PTO_BUILD_DIR}/tools/ptoas:${PATH}" -export LD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH}" -export DYLD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${DYLD_LIBRARY_PATH}" - -if [ -n "${PTOAS_BIN:-}" ]; then - if [ ! -x "${PTOAS_BIN}" ]; then - echo "Error: PTOAS_BIN is not executable: ${PTOAS_BIN}" >&2 - exit 1 - fi -else - PTOAS_BIN="$(command -v ptoas)" +if [ ! -x "${PTOAS_BIN}" ]; then + echo "Error: PTOAS_BIN is not executable: ${PTOAS_BIN}" >&2 + exit 1 fi - echo "Testing ptoas CLI..." echo "${PTOAS_BIN}" diff --git a/docker/test_wheel_imports.sh b/docker/test_wheel_imports.sh index 50d20694a0..aff59bcc2a 100755 --- a/docker/test_wheel_imports.sh +++ b/docker/test_wheel_imports.sh @@ -12,8 +12,8 @@ # Usage: ./test_wheel_imports.sh # # This script tests that the installed wheel can import: -# - mlir.ir -# - mlir.dialects.pto +# - ptoas.mlir.ir +# - ptoas.mlir.dialects.pto # - ptodsl # - from ptodsl import pto, scalar # - ptoas CLI entry @@ -76,11 +76,21 @@ cd /tmp PTOAS_ENTRYPOINT="$(command -v ptoas)" PYTHON_ENTRYPOINT="$(command -v "${PYTHON_BIN}")" -echo "Testing mlir.ir import..." -"$PYTHON_BIN" -c "import mlir.ir; print('mlir.ir imported successfully')" +echo "Testing ptoas.mlir.ir import..." +"$PYTHON_BIN" -c "from ptoas.mlir import ir; print('ptoas.mlir.ir imported successfully')" echo "Testing pto dialect import..." -"$PYTHON_BIN" -c "from mlir.dialects import pto; print('pto dialect imported successfully')" +"$PYTHON_BIN" -c "from ptoas.mlir.dialects import pto; print('pto dialect imported successfully')" + +echo "Testing that PTOAS does not claim the top-level mlir namespace..." +"$PYTHON_BIN" - <<'PY' +try: + import mlir # noqa: F401 +except ImportError: + pass +else: + raise SystemExit("the ptoas wheel unexpectedly provides a top-level mlir package") +PY echo "Testing ptodsl import..." "$PYTHON_BIN" -c "import ptodsl; print(f'ptodsl imported successfully from {ptodsl.__file__}')" @@ -89,6 +99,7 @@ echo "Testing ptodsl public imports..." "$PYTHON_BIN" -c "from ptodsl import pto, scalar; print('ptodsl public imports imported successfully')" echo "Testing installed ptoas console entry..." +"$PYTHON_BIN" -c "from ptoas import _core; print(f'ptoas native extension imported successfully from {_core.__file__}')" PTOAS_VERSION_OUTPUT="$(ptoas --version | tr -d '\r')" echo "${PTOAS_VERSION_OUTPUT}" EXPECTED_PTOAS_CLI_VERSION="${PTOAS_CLI_VERSION:-${PTOAS_VERSION:-}}" @@ -102,33 +113,6 @@ else echo "${PTOAS_VERSION_OUTPUT}" | grep -Eq '^ptoas [0-9]+\.[0-9]+$' fi -echo "Testing installed ptoas console entry under polluted Python and LLVM paths..." -POLLUTED_ENV_DIR="${TEST_TMPDIR}/polluted-env" -mkdir -p "${POLLUTED_ENV_DIR}/ptoas" -cat > "${POLLUTED_ENV_DIR}/ptoas/__init__.py" <<'PY' -raise RuntimeError("shadow ptoas package must not be imported") -PY -cat > "${POLLUTED_ENV_DIR}/ptoas/_runtime_entry.py" <<'PY' -raise RuntimeError("shadow runtime entry must not be imported") -PY -POLLUTED_PTOAS_VERSION_OUTPUT="$( - env \ - PYTHONPATH="${POLLUTED_ENV_DIR}" \ - LD_LIBRARY_PATH="/tmp/polluted-llvm" \ - DYLD_LIBRARY_PATH="/tmp/polluted-dylib" \ - "${PTOAS_ENTRYPOINT}" --version | tr -d '\r' -)" -echo "${POLLUTED_PTOAS_VERSION_OUTPUT}" -if [[ -n "${EXPECTED_PTOAS_CLI_VERSION}" ]]; then - EXPECTED_VERSION_OUTPUT="ptoas ${EXPECTED_PTOAS_CLI_VERSION}" - if [[ "${POLLUTED_PTOAS_VERSION_OUTPUT}" != "${EXPECTED_VERSION_OUTPUT}" ]]; then - echo "Error: expected '${EXPECTED_VERSION_OUTPUT}', got '${POLLUTED_PTOAS_VERSION_OUTPUT}'" >&2 - exit 1 - fi -else - echo "${POLLUTED_PTOAS_VERSION_OUTPUT}" | grep -Eq '^ptoas [0-9]+\.[0-9]+$' -fi - echo "Testing installed ptoas console entry in a clean environment..." CLEAN_ENV_DIR="${TEST_TMPDIR}/clean-env" CLEAN_ENV_PTO="${CLEAN_ENV_DIR}/wheel-clean-env-probe.pto" diff --git a/docker/validate_wheel_payload.py b/docker/validate_wheel_payload.py index 15da0c69cc..0b67082e39 100644 --- a/docker/validate_wheel_payload.py +++ b/docker/validate_wheel_payload.py @@ -12,22 +12,40 @@ from __future__ import annotations import argparse +import importlib.machinery import zipfile from pathlib import Path REQUIRED_FILES = { - "ptoas_wheel_bootstrap.py", "ptoas/__init__.py", - "ptoas/_launcher.py", - "ptoas/_runtime_entry.py", - "ptoas/_runtime/lib/ptoas.so", + "ptoas/_cli.py", + "ptoas/_runtime/share/ptoas/TileOps/__init__.py", + "ptoas/mlir/ir.py", + "ptoas/mlir/dialects/pto.py", } FORBIDDEN_FILES = { "ptoas/_runtime/bin/ptoas", } -PTOAS_ENTRYPOINT_TARGET = "ptoas_wheel_bootstrap:main" +PTOAS_ENTRYPOINT_TARGET = "ptoas._cli:main" WHEEL_GLOB = "ptoas*.whl" +NATIVE_MODULE_PATHS = { + f"ptoas/_core{suffix}" + for suffix in importlib.machinery.EXTENSION_SUFFIXES +} +MLIR_NATIVE_MODULE_PREFIX = "ptoas/mlir/_mlir_libs/" +COMMON_CAPI_LIBRARY_PATHS = { + f"{MLIR_NATIVE_MODULE_PREFIX}libPTOASPythonCAPI{suffix}" + for suffix in (".so", ".dylib") +} +MLIR_NATIVE_MODULE_PATHS = { + f"{MLIR_NATIVE_MODULE_PREFIX}_mlir{suffix}" + for suffix in importlib.machinery.EXTENSION_SUFFIXES +} +SITE_INITIALIZER_PATHS = { + f"{MLIR_NATIVE_MODULE_PREFIX}_site_initialize_0{suffix}" + for suffix in importlib.machinery.EXTENSION_SUFFIXES +} def _resolve_wheel(candidate: str) -> Path: @@ -83,6 +101,41 @@ def validate_wheel_payload(wheel: Path) -> None: if missing: raise SystemExit(f"wheel is missing required payload files: {missing}") + native_modules = sorted(NATIVE_MODULE_PATHS & names) + if len(native_modules) != 1: + raise SystemExit( + "wheel must contain exactly one importable ptoas._core extension, " + f"found {native_modules}" + ) + + mlir_native_modules = sorted(MLIR_NATIVE_MODULE_PATHS & names) + if len(mlir_native_modules) != 1: + raise SystemExit( + "wheel must contain exactly one ptoas-owned MLIR native module, " + f"found {mlir_native_modules}" + ) + + common_capi_libraries = sorted(COMMON_CAPI_LIBRARY_PATHS & names) + if len(common_capi_libraries) != 1: + raise SystemExit( + "wheel must contain exactly one PTOAS MLIR common CAPI library, " + f"found {common_capi_libraries}" + ) + + site_initializers = sorted(SITE_INITIALIZER_PATHS & names) + if len(site_initializers) != 1: + raise SystemExit( + "wheel must contain exactly one PTOAS MLIR site initializer, " + f"found {site_initializers}" + ) + + top_level_mlir = sorted(name for name in names if name.startswith("mlir/")) + if top_level_mlir: + raise SystemExit( + "wheel must not install a top-level mlir package; " + f"found {top_level_mlir[:10]}" + ) + present_forbidden = sorted(FORBIDDEN_FILES & names) if present_forbidden: raise SystemExit( @@ -107,7 +160,7 @@ def validate_wheel_payload(wheel: Path) -> None: if console_scripts.get("ptoas") != PTOAS_ENTRYPOINT_TARGET: raise SystemExit( "wheel entry points do not route ptoas through " - "ptoas_wheel_bootstrap:main" + f"{PTOAS_ENTRYPOINT_TARGET}" ) diff --git a/docs/build_with_installed_llvm.md b/docs/build_with_installed_llvm.md index 7b09173b27..06e751dfc4 100644 --- a/docs/build_with_installed_llvm.md +++ b/docs/build_with_installed_llvm.md @@ -73,15 +73,15 @@ README 第 3.2 节是 LLVM/MLIR 的下载和编译步骤。当前场景下 LLVM 这里沿用 README 第 3.3 节的流程,但 `LLVM_DIR` 和 `MLIR_DIR` 需要改为 `/opt/llvm/lib/cmake/...`。 -`MLIR_PYTHON_PACKAGE_DIR` 仍然指向 LLVM 的 MLIR Python package。PTOAS 的 -`pto.py`、`_pto_ops_gen.py` 和 `_pto.cpython-*.so` 会安装到 -`CMAKE_INSTALL_PREFIX`,不会写入共享的 LLVM 安装目录。 +PTOAS 使用 MLIR 导出的 Python source-set 在自己的 build/install tree 中 +组装完整的 `mlir` package,不再复制或 overlay LLVM build tree 中已经生成的 +Python package。 ```bash cd "$PTO_SOURCE_DIR" -# 1. 获取 pybind11 的 CMake 路径 -export PYBIND11_CMAKE_DIR=$(python3 -m pybind11 --cmakedir) +# 1. 安装 MLIR Python binding 的构建依赖 +python3 -m pip install 'pybind11<3' 'nanobind>=2.4' # 2. 配置 CMake cmake -G Ninja \ @@ -91,9 +91,7 @@ cmake -G Ninja \ -DMLIR_DIR=$LLVM_INSTALL_DIR/lib/cmake/mlir \ -DPython3_EXECUTABLE=$(which python3) \ -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="${PYBIND11_CMAKE_DIR}" \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR="$LLVM_INSTALL_DIR/python_packages/mlir_core" \ -DCMAKE_INSTALL_PREFIX="$PTO_INSTALL_DIR" # 3. 编译并安装 @@ -108,12 +106,12 @@ cmake --install build - build 目录: - `$PTO_SOURCE_DIR/build/tools/ptoas/ptoas` - `$PTO_SOURCE_DIR/build/tools/ptobc/ptobc` - - `$PTO_SOURCE_DIR/build/python/mlir/_mlir_libs/_pto.cpython-*.so` + - `$PTO_SOURCE_DIR/build/python/ptoas/_core.cpython-*.so` - `$PTO_SOURCE_DIR/build/python/mlir/dialects/pto.py` - install 目录: - `$PTO_INSTALL_DIR/bin/ptoas` - - `$PTO_INSTALL_DIR/mlir/_mlir_libs/_pto.cpython-*.so` - - `$PTO_INSTALL_DIR/mlir/dialects/pto.py` + - `$PTO_INSTALL_DIR/ptoas/_core.cpython-*.so` + - `$PTO_INSTALL_DIR/ptoas/mlir/dialects/pto.py` - `$PTO_INSTALL_DIR/share/ptoas/oplib/level3` ## 补充:运行环境 @@ -122,7 +120,7 @@ cmake --install build ```bash export PATH=$PTO_SOURCE_DIR/build/tools/ptoas:$PATH -export PYTHONPATH=$LLVM_INSTALL_DIR/python_packages/mlir_core:$PTO_SOURCE_DIR/build/python:$PYTHONPATH +export PYTHONPATH=$PTO_SOURCE_DIR/build/python:$PYTHONPATH export LD_LIBRARY_PATH=$LLVM_INSTALL_DIR/lib:$PTO_SOURCE_DIR/build/lib:$LD_LIBRARY_PATH ``` @@ -130,7 +128,7 @@ export LD_LIBRARY_PATH=$LLVM_INSTALL_DIR/lib:$PTO_SOURCE_DIR/build/lib:$LD_LIBRA ```bash export PATH=$PTO_INSTALL_DIR/bin:$PATH -export PYTHONPATH=$LLVM_INSTALL_DIR/python_packages/mlir_core:$PTO_INSTALL_DIR:$PYTHONPATH +export PYTHONPATH=$PTO_INSTALL_DIR:$PYTHONPATH export LD_LIBRARY_PATH=$LLVM_INSTALL_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PATH ``` @@ -145,12 +143,11 @@ export LD_LIBRARY_PATH=$LLVM_INSTALL_DIR/lib:$PTO_INSTALL_DIR/lib:$LD_LIBRARY_PA - `LLVM_DIR=/opt/llvm/lib/cmake/llvm` - `MLIR_DIR=/opt/llvm/lib/cmake/mlir` -- `MLIR_PYTHON_PACKAGE_DIR=/opt/llvm/python_packages/mlir_core` - `CMAKE_INSTALL_PREFIX=$PTO_INSTALL_DIR` 最小验证结果: - build 版 `ptoas --version` 输出 `ptoas 0.22` - build 版 `ptoas` 可成功处理 `test/lit/pto/empty_func.pto` -- install 版 Python 绑定可在 `PYTHONPATH=/opt/llvm/python_packages/mlir_core:$PTO_INSTALL_DIR` 下正常导入 +- install 版 Python 绑定可在 `PYTHONPATH=$PTO_INSTALL_DIR` 下正常导入 - 若 install 版 `ptoas` 配合 `LD_LIBRARY_PATH=/opt/llvm/lib:$PTO_INSTALL_DIR/lib`,可正常执行 diff --git a/docs/designs/ci-board-validation-guide.md b/docs/designs/ci-board-validation-guide.md index bb963841d9..a9506fc8f4 100644 --- a/docs/designs/ci-board-validation-guide.md +++ b/docs/designs/ci-board-validation-guide.md @@ -103,16 +103,14 @@ ninja -C llvm/build-shared ```bash export LLVM_DIR=$PWD/llvm-project/llvm/build-shared export PTO_INSTALL_DIR=$PWD/install -export PYBIND11_CMAKE_DIR="$(python3 -m pybind11 --cmakedir)" +python3 -m pip install 'pybind11<3' 'nanobind>=2.4' cmake -G Ninja -S . -B build \ -DLLVM_DIR="$LLVM_DIR/lib/cmake/llvm" \ -DMLIR_DIR="$LLVM_DIR/lib/cmake/mlir" \ -DPython3_EXECUTABLE=python3 \ -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="$PYBIND11_CMAKE_DIR" \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR="$LLVM_DIR/tools/mlir/python_packages/mlir_core" \ -DCMAKE_INSTALL_PREFIX="$PTO_INSTALL_DIR" \ -DCMAKE_BUILD_TYPE=Release @@ -124,11 +122,8 @@ ninja -C build install ### 3.3 跑样例生成链路 ```bash -export MLIR_PYTHON_ROOT=$PWD/llvm-project/llvm/build-shared/tools/mlir/python_packages/mlir_core -export PTO_PYTHON_ROOT=$PWD/install -export PYTHONPATH="$MLIR_PYTHON_ROOT:$PTO_PYTHON_ROOT:${PYTHONPATH:-}" -export LD_LIBRARY_PATH="$LLVM_DIR/lib:$PTO_INSTALL_DIR/lib:${LD_LIBRARY_PATH:-}" -export PTOAS_BIN=$PWD/build/tools/ptoas/ptoas +LLVM_BUILD_DIR="$LLVM_DIR" ./quick_install.sh +export PTOAS_BIN="$(command -v ptoas)" bash test/samples/runop.sh --enablebc all ``` diff --git a/docs/designs/ptoas-mlir-namespace-and-native-isolation.md b/docs/designs/ptoas-mlir-namespace-and-native-isolation.md new file mode 100644 index 0000000000..40eecde609 --- /dev/null +++ b/docs/designs/ptoas-mlir-namespace-and-native-isolation.md @@ -0,0 +1,692 @@ +// Copyright (c) 2026 Huawei Technologies Co., Ltd. +// This program is free software, you can redistribute it and/or modify it under the terms and conditions of +// CANN Open Software License Agreement Version 2.0 (the "License"). +// Please refer to the License for details. You may not use this file except in compliance with the License. +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// See LICENSE in the root of the software repository for the full text of the License. + +# PTOAS MLIR Python Namespace and Native Isolation Design + +## Status + +This document records the agreed migration direction and its constraints. The +design is **proposed and not yet implemented**. Until the migration lands, the +current public imports remain `mlir.ir` and `mlir.dialects.pto`. + +The intended public API is: + +```python +from ptoas.mlir import ir +from ptoas.mlir.ir import Context, Module +from ptoas.mlir.dialects import pto +``` + +The migration must remove the PTOAS-owned top-level `mlir` package rather than +installing a compatibility alias that would recreate the namespace collision. + +## Goals + +1. Place the complete PTOAS-owned MLIR Python runtime under `ptoas.mlir`. +2. Allow PTOAS and another self-contained MLIR distribution, such as IREE, + CIRCT, torch-mlir, or JAX, to coexist in one Python environment. +3. Give all PTOAS MLIR extensions one project-specific nanobind domain. +4. Keep one native MLIR runtime inside PTOAS so that `ptoas.mlir`, the PTO + dialect facade, PTODSL, and `ptoas._core` share object identity. +5. Use MLIR's exported CMake source graph and standard wheel repair tools + instead of copying package trees or implementing a custom loader. +6. Define and test the supported boundary between independently packaged MLIR + runtimes. +7. Keep the repaired wheel as the official Python distribution, while retaining + `ptoas-bin` as a CI and board-validation compatibility artifact. Generate + that artifact from a deterministic CMake install-tree staging directory; + do not make it a second Python package distribution. + +## Non-Goals + +- Do not make `ptoas.mlir.ir.Module` interchangeable with an IREE, CIRCT, + torch-mlir, JAX, or system-MLIR `Module`. +- Do not install or populate a top-level `mlir` compatibility package. +- Do not scan repositories, neighboring build trees, `PYTHONPATH`, or library + directories at Python import time. +- Do not preload LLVM/MLIR libraries with `RTLD_GLOBAL` or a custom bootstrap + loader. +- Do not switch the LLVM SDK from shared to static libraries as part of the + namespace migration. +- Do not modify LLVM/MLIR sources to implement the package layout. +- Do not make the compiler archive a second PyPI-style distribution with its + own metadata, Python dependency resolver, or import bootstrap. +- Do not scan the source tree or arbitrary build directories while assembling + the archive. Its contents must come from an explicit install prefix. +- Do not pretend that `auditwheel repair` or `delocate` is a generic tarball + relocation tool. They remain the standard repair tools for wheels; any + archive-native relocation must be a small, explicit packaging step. + +## Industry and Upstream References + +The design separates mechanisms with direct upstream/industry precedent from +the PTOAS-specific compatibility artifact required by the current board-test +workflow. + +### Directly Referenced Mechanisms + +- LLVM's standalone example uses `MLIR_PYTHON_PACKAGE_PREFIX`, + `add_mlir_python_common_capi_library`, and `add_mlir_python_modules` to embed + MLIR bindings in a downstream namespace. +- torch-mlir explicitly vendors MLIR in the `torch_mlir` namespace and defines + `MLIR_PYTHON_PACKAGE_PREFIX=torch_mlir.`. +- IREE defines `MLIR_PYTHON_PACKAGE_PREFIX=iree.compiler.`, installs its MLIR + tree below `iree/compiler`, and makes the Python bindings consume one + project-owned shared compiler implementation. Its compiler tools are found + relative to the installed Python package rather than by scanning build or + source trees. +- CIRCT defines `MLIR_PYTHON_PACKAGE_PREFIX=circt.`, installs below `circt`, and + uses a project-owned `CIRCTBindingsPythonCAPI` library. +- JAX packages its MLIR bindings below `jaxlib.mlir` with a private + `_mlir_libs` directory. +- Linux native wheels conventionally use `auditwheel repair`; auditwheel copies + external libraries, gives them content-derived names, rewrites `DT_NEEDED`, + and installs package-relative RPATH entries. +- macOS native wheels conventionally use `delocate`, which copies dependent + dylibs and rewrites install names and RPATH entries. +- CMake install components and CPack archive an explicit install graph into a + deterministic prefix. They are the standard boundary for a native install + tree, although they do not replace wheel-specific dependency repair. + +These references directly support the `ptoas.mlir` namespace, project-owned +common CAPI, project-specific nanobind domain, and repaired-wheel architecture. + +### Distribution and Archive Boundary + +There is no universal MLIR or Python packaging standard for publishing a +compiler-only tarball alongside a Python wheel. Comparable projects either +publish wheels only or maintain a project-specific compiler/binary package. +The standard Python distribution remains the repaired wheel; `auditwheel` and +`delocate` are intentionally wheel-oriented tools. + +PTOAS must currently retain a `ptoas-bin` archive because the PR board-test +monitor downloads the Linux artifact before running compiler cases. This is a +compatibility artifact, not a second public Python distribution. The archive +will be assembled from a dedicated CMake install-tree staging prefix, using +the same `ptoas` package layout and runtime contract as the wheel. CPack/TGZ or +an equivalent archive of that install prefix is the appropriate packaging +boundary; a script must not reconstruct a package by scanning the repository. + +The archive and wheel have different native packaging constraints. Wheel +repair can be delegated to `auditwheel`/`delocate`. A relocatable install-tree +archive may still need a narrowly scoped platform step to ensure that bundled +non-system libraries use relative RPATHs or install names. That step must not +also copy Python sources, invent a second package layout, or run a second +general-purpose dependency-discovery pipeline hidden inside the launcher. + +Relevant upstream sources: + +- `llvm-project/mlir/examples/standalone/python/CMakeLists.txt` +- `llvm-project/mlir/cmake/modules/AddMLIRPython.cmake` +- `llvm/torch-mlir/python/CMakeLists.txt` +- `iree-org/iree/compiler/bindings/python/CMakeLists.txt` +- `iree-org/iree/compiler/bindings/python/iree/compiler/tools/binaries.py` +- `llvm/circt/lib/Bindings/Python/CMakeLists.txt` +- `cmake/Help/module/CPack.rst` +- `pypa/auditwheel` +- `matthew-brett/delocate` + +## Target Package Layout + +```text +ptoas/ +├── __init__.py +├── _cli.py +├── _core..so +├── _runtime/ +└── mlir/ + ├── __init__.py + ├── ir.py + ├── passmanager.py + ├── dialects/ + │ ├── arith.py + │ ├── func.py + │ ├── llvm.py + │ ├── math.py + │ ├── memref.py + │ ├── pto.py + │ └── scf.py + └── _mlir_libs/ + ├── _mlir..so + ├── _site_initialize_0..so + └── libPTOASPythonCAPI.so +``` + +The corresponding native ownership graph is: + +```text +ptoas.mlir.ir + │ + ▼ +ptoas/mlir/_mlir_libs/_mlir.so + │ + ├──────────────────────┐ + ▼ ▼ +libPTOASPythonCAPI.so ◄── ptoas/_core.so + │ + ▼ +repaired, content-named LLVM/MLIR shared libraries +``` + +All PTOAS binding modules must resolve MLIR objects through the same +`PTOASPythonCAPI` and the same underlying LLVM/MLIR shared libraries. + +## Python Namespace Configuration + +Moving files under `ptoas/mlir` is not sufficient. Native MLIR bindings also +use the package prefix to locate Python classes and capsules. The binding +targets must therefore be compiled with: + +```cmake +add_compile_definitions( + "MLIR_PYTHON_PACKAGE_PREFIX=ptoas.mlir." +) +``` + +The definition must apply to the MLIR-generated extension targets and to +`PTOASPythonCore`. Since `_core` is built in a separate CMake directory, it may +need an explicit target-scoped compile definition in addition to the binding +directory definition. + +The staged and installed package roots should become: + +```cmake +set(PTOAS_MLIR_PYTHON_PACKAGE_DIR + "${CMAKE_BINARY_DIR}/python/ptoas/mlir") + +add_mlir_python_common_capi_library(PTOASPythonCAPI + INSTALL_DESTINATION "ptoas/mlir/_mlir_libs" + OUTPUT_DIRECTORY "${PTOAS_MLIR_PYTHON_PACKAGE_DIR}/_mlir_libs" + ... +) + +add_mlir_python_modules(PTOAS_Python + ROOT_PREFIX "${PTOAS_MLIR_PYTHON_PACKAGE_DIR}" + INSTALL_PREFIX "ptoas/mlir" + ... +) +``` + +The generated package remains owned by the `PTOAS_Python` CMake install +component. It should not be copied from an LLVM build tree or added as a second +`tool.scikit-build.wheel.packages` source tree. + +## Nanobind Domain Isolation + +MLIR's nanobind domain determines which extension modules share native Python +type registrations. All modules inside one PTOAS MLIR runtime must use one +domain, while other MLIR distributions must use different domains. + +Use: + +```cmake +set(MLIR_BINDINGS_PYTHON_NB_DOMAIN "ptoas_mlir") +``` + +### Current LLVM Fork Constraint + +The LLVM fork currently used by PTOAS has an older `AddMLIRPython.cmake` API. +Its `add_mlir_python_modules` function accepts `ROOT_PREFIX` and +`INSTALL_PREFIX`, but does not accept the newer per-call +`MLIR_BINDINGS_PYTHON_NB_DOMAIN` argument. It reads the CMake variable when it +creates nanobind extension targets. + +Therefore the current implementation must set the variable before calling +`add_mlir_python_modules`; passing an extra argument to that function is not a +valid implementation for the current SDK. When the LLVM fork adopts the newer +upstream API, this can be converted to a per-package argument without changing +the public layout. + +`ptoas._core` currently uses pybind11, so the nanobind domain does not directly +configure `_core`. Its interoperability with MLIR objects instead depends on +the package prefix, MLIR's adaptor/C API boundary, and the shared common CAPI. + +## Common CAPI and Runtime Identity + +`PTOASPythonCAPI` is already a project-owned common CAPI name and should remain +the single native binding runtime for PTOAS. The migration must preserve these +relationships: + +- `_mlir` links `PTOASPythonCAPI`. +- `_site_initialize_0` links the same common CAPI. +- `ptoas._core` links the same common CAPI. +- `ptoas._core` initializes the matching Python runtime with: + + ```cpp + py::module_::import("ptoas.mlir.ir"); + ``` + +- `ptoas.mlir.dialects.pto` imports `ptoas._core` for project-owned PTO types + and enums. +- No PTOAS component imports or links a second system `MLIRPythonCAPI`. + +`ptoas.__init__` should stay minimal and must not eagerly import `_core` or +`ptoas.mlir`, avoiding an import cycle between `_core`, `ir`, and the PTO +dialect facade. + +## Dynamic Library Isolation + +### Linux Repaired Wheels + +PTOAS currently builds its LLVM SDK with `BUILD_SHARED_LIBS=ON`. This produces +many `libLLVM*.so` and `libMLIR*.so` dependencies. The release wheel must +continue through `auditwheel repair`. + +Auditwheel provides the distribution isolation for those external libraries: + +1. Copy each non-system dependency into the wheel-owned `ptoas.libs` tree. +2. Rename it with a content-derived hash. +3. Rewrite its ELF SONAME. +4. Rewrite consumers' `DT_NEEDED` entries. +5. Install package-relative RPATH entries. + +PTOAS's repaired wheel already demonstrates this pattern with names such as: + +```text +ptoas.libs/libMLIRArithDialect-00278e1e.so.21.1 +ptoas.libs/libLLVMTransformUtils-2cda0d9b.so.21.1 +``` + +The project should not manually rename or enumerate all LLVM/MLIR libraries. +The internal common CAPI name is already project-specific; auditwheel owns the +external dependency names. + +### macOS Repaired Wheels + +The macOS wheel must continue through `delocate`. Delocate owns copying dylibs +and rewriting install names and RPATH entries. PTOAS should not add a parallel +`install_name_tool` implementation. + +### `_core` Package-Local RPATH + +After nesting MLIR under `ptoas`, `_core` and its common CAPI are laid out as: + +```text +ptoas/_core.so +ptoas/mlir/_mlir_libs/libPTOASPythonCAPI.so +``` + +The package-local install RPATH must therefore be: + +```text +Linux: $ORIGIN;$ORIGIN/mlir/_mlir_libs +macOS: @loader_path;@loader_path/mlir/_mlir_libs +``` + +The old `$ORIGIN/../mlir/_mlir_libs` path belongs to the current sibling +packages and must not survive the migration. + +For the common CAPI under `ptoas/mlir/_mlir_libs`, the +`RELATIVE_INSTALL_ROOT` value must be recomputed from the new location rather +than copied from the old configuration. From this location back to the Python +install prefix is normally three levels (`../../..`). The final value must be +verified from installed ELF/Mach-O metadata because auditwheel and delocate +will subsequently replace distribution-wheel dependency paths. + +### Editable and Build-Tree Installs + +Editable and direct build-tree installations do not pass through wheel repair. +They may use RPATH entries that refer to the selected developer LLVM build. +This is sufficient for a convenient PTOAS development environment, but it does +not guarantee same-process coexistence with an unrelated developer MLIR build. + +The supported isolation contract applies most strongly to repaired release +wheels. Editable multi-MLIR coexistence is best effort unless both projects +were intentionally built against one compatible runtime. + +### Compiler Compatibility Archive + +The `ptoas-bin` archive is compiler-oriented and includes PTODSL as an internal +compiler runtime dependency. PTOAS defaults to the PTODSL TileLib backend, so +excluding `ptodsl/` would make an extracted archive unable to compile `.pto` +input containing unexpanded TileOps with the normal CLI defaults. The archive +must therefore contain both PTODSL and the installed nested MLIR package: + +```text +ptodsl/ +ptoas/_core.so +ptoas/mlir/ +ptoas/mlir/_mlir_libs/_mlir.so +ptoas/mlir/_mlir_libs/libPTOASPythonCAPI.so +``` + +This does not make the archive a general PTODSL development distribution. +`ptodsl/` and `ptoas.mlir` are present so the compiler's default TileLib path +works without changing CLI semantics. The repaired wheel remains the supported +Python installation for authoring and importing PTODSL applications. + +The repaired wheel remains the canonical Python distribution. Wheel and +archive packaging share the same CMake target graph but use different install +contracts. The archive is produced from an explicit compiler-runtime install +component so that its contents are owned by CMake rather than reconstructed +from source paths: + +```text +configured CMake build + │ + ├── wheel install components + │ └── raw wheel + │ └── auditwheel / delocate + │ └── repaired Python wheel + │ + └── PTOAS_Python + compiler-runtime install components + └── archive staging prefix + └── native relocation, if required + └── tar/CPack board artifact +``` + +The staging prefix must contain only the compiler archive contract: + +```text +bin/ptoas +ptodsl/ +ptoas/ +ptoas/mlir/ +ptoas/_runtime/share/ptoas/TileOps/ +tilelang_dsl/ +lib/ # only if native dependencies are bundled +``` + +The archive exposes PTODSL only as part of the compiler runtime contract. It +does not include wheel metadata or claim to satisfy normal `pip` dependency +resolution. Board validation invokes the packaged compiler rather than using +the archive as an installable Python distribution. + +Archive assembly is limited to install-tree and relocation operations: + +- install `PTOAS_Python` and then `PTOAS_CompilerArchive` with an explicit, + shared staging prefix; +- preserve the package-relative `ptoas/`, `ptoas/mlir/`, and `ptodsl/` layout; +- place any bundled non-system native dependencies below the archive prefix + and use `$ORIGIN`/`@loader_path`-relative linkage; +- create the tarball from that prefix with CPack/TGZ or an equivalent simple + archive command; +- smoke test the extracted archive with a clean environment. + +The archive's `lib/` directory, when needed, is an install-tree convention and +is distinct from auditwheel's wheel-local `*.libs` sidecar. We must not copy a +wheel sidecar into an unrelated layout without also preserving the native +linkage that refers to it. + +Native dependency discovery for the archive should use CMake's install-time +`file(GET_RUNTIME_DEPENDENCIES)`, which is available within PTOAS's existing +CMake 3.20 minimum, rather than handwritten recursive `ldd` or `otool` +parsers. Package-owned files such as `PTOASPythonCAPI`, `_mlir`, and site +initializers remain under `ptoas/mlir/_mlir_libs` and must be excluded from the +external dependency copy into `lib/`. + +The archive relocation contract is: + +```text +Linux ptoas/_core.so: + $ORIGIN;$ORIGIN/mlir/_mlir_libs;$ORIGIN/../lib +Linux ptoas/mlir/_mlir_libs/*: + $ORIGIN;$ORIGIN/../../../lib +Linux lib/*.so*: + $ORIGIN + +macOS ptoas/_core.so: + @loader_path;@loader_path/mlir/_mlir_libs;@loader_path/../lib +macOS ptoas/mlir/_mlir_libs/*: + @loader_path;@loader_path/../../../lib +macOS lib/*.dylib: + @loader_path +``` + +Linux uses `patchelf` only to apply this staging-tree RPATH contract after +CMake resolves and copies dependencies. macOS uses `delocate-path` for the +equivalent directory relocation instead of maintaining a project-owned Mach-O +dependency parser. Neither platform searches for libraries at Python import +time. + +The current compatibility archive is built from the CPython 3.11 workflow and +contains CPython-ABI-specific extension modules. It therefore requires CPython +3.11 at runtime. The existing `ptoas-bin-` artifact names remain +unchanged for the external board-test monitor; the build and extracted-archive +tests must validate the interpreter version explicitly. Moving to abi3 or +publishing per-Python archive names is outside this migration. + +The single-runtime invariant is inherited from the shared CMake target graph: + +- exactly one package-owned `PTOASPythonCAPI` is retained; +- `_core`, `_mlir`, and site initializers link the same project-owned common + CAPI before the wheel and archive take their platform-specific packaging + paths; +- LLVM/MLIR dependencies in the archive use relative install-tree RPATHs or + install names and contain no build-tree absolute paths; +- any platform relocation helper is limited to the archive staging prefix and + is separately validated from the wheel repair path. + +The standalone archive is intended to launch a fresh compiler process. Unlike +the repaired wheel, it does not promise arbitrary same-process import +coexistence with another MLIR distribution. Its required invariant is narrower +but strict: one archive invocation loads one internally consistent PTOAS native +runtime built from the same CMake targets as the wheel and relocated only for +the archive's own install-tree layout. + +## Why Not Switch Directly to Static LLVM + +Changing only `BUILD_SHARED_LIBS=OFF` can make `_mlir.so` and `_core.so` +statically embed separate copies of MLIR. That would duplicate registries, +TypeIDs, command-line options, and native global state inside one process and +could break PTOAS's own cross-module object identity. + +A future single-DSO design must instead follow an IREE-style ownership model: + +```text +libPTOASCompiler.so +├── LLVM/MLIR implementation +├── PTO dialect and passes +├── compiler driver +└── exported C API + +_mlir.so ──► libPTOASCompiler.so +_core.so ──► libPTOASCompiler.so +``` + +That is a separate architectural change requiring a deliberate exported API +boundary and symbol-visibility policy. It is not a prerequisite for the +namespace migration because repaired wheels already isolate external shared +libraries with package-local, content-derived names. + +## Public API Migration + +Production imports, tests, samples, and documentation must move together: + +```python +# Old +from mlir import ir +from mlir.ir import Module +from mlir.dialects import pto + +# New +from ptoas.mlir import ir +from ptoas.mlir.ir import Module +from ptoas.mlir.dialects import pto +``` + +The affected surfaces include: + +- PTO dialect Python facade and generated source graph; +- PTODSL implementation and public MLIR object documentation; +- TileLang DSL pybind backend; +- PTOAS Python tests; +- sample programs; +- README installation and Python API examples; +- wheel payload validation and import smoke tests; +- native `mlir.ir` import strings. + +Because README and wheel tests currently promise top-level `mlir`, removing it +is a public API break and requires an explicit release note. A default alias is +not an acceptable compatibility mechanism because it defeats package +isolation. + +## Supported Coexistence Boundary + +| Scenario | Contract | +|---|---| +| Install PTOAS and another namespaced MLIR wheel in one environment | Supported target | +| Import both repaired wheels in one interpreter | Must be validated | +| Create independent contexts and modules in each runtime | Supported target | +| Pass a PTOAS `Module`, `Type`, or `Value` into another runtime | Unsupported | +| Exchange textual MLIR, bytecode, or files | Supported integration boundary | +| Mix editable builds backed by unrelated LLVM trees | Best effort, not guaranteed | + +No public function should imply that independently packaged MLIR native objects +are interchangeable. Cross-project integration must serialize the IR or use a +subprocess unless the projects deliberately share one compatible runtime. + +## Validation Plan + +### Package Contract + +- The wheel contains `ptoas/mlir/ir.py` and + `ptoas/mlir/dialects/pto.py`. +- The wheel does not contain a top-level `mlir/` tree. +- `ptoas._core` and exactly one PTOAS `_mlir` core extension are present. +- Importing PTOAS does not create `sys.modules["mlir"]`. + +### Functional Imports + +```python +from ptoas.mlir import ir +from ptoas.mlir.dialects import pto +import ptodsl +from ptodsl import pto as dsl_pto, scalar +``` + +The test must create a context and module, register the PTO dialect, compile a +minimal PTODSL kernel, and invoke the installed `ptoas` console script. + +### Runtime Identity + +- PTO types created through `ptoas._core` work with + `ptoas.mlir.ir.Context`. +- PTODSL returns `ptoas.mlir.ir.Module` objects. +- PTOAS binding modules all resolve the same `PTOASPythonCAPI`. +- Import order between `ptoas._core`, `ptoas.mlir.ir`, and + `ptoas.mlir.dialects.pto` is deterministic and cycle-free. + +### Linux Wheel Dependencies + +- `auditwheel show` reports an accepted manylinux policy. +- Repaired LLVM/MLIR dependencies have content-derived names. +- `readelf -d` contains no absolute LLVM build path. +- No non-system `libLLVM*` or `libMLIR*` dependency remains outside the wheel. + +### macOS Wheel Dependencies + +- `delocate-listdeps` reports no external developer LLVM path. +- `otool -L` contains only system or wheel-owned dylibs. +- No absolute LLVM build or install path remains. + +### Compiler Archive Dependencies + +- The archive contains `ptoas/mlir` and `ptodsl` so the default PTODSL TileLib + backend works without extra CLI options. +- The archive is produced by an explicit CMake compiler-runtime install + component, not by scanning the source tree or an arbitrary install tree. +- Package-relative paths are preserved and the archive contains no source, + build, or install-prefix absolute paths. +- Exactly one package-owned `PTOASPythonCAPI` exists. +- `_core`, `_mlir`, site initializers, and the common CAPI resolve through the + archive's own relative native paths. +- Any native dependency relocation is performed only on the staging prefix and + is not implemented by Python import-time path scanning. +- Runtime dependency discovery uses CMake + `file(GET_RUNTIME_DEPENDENCIES)` rather than recursive shell parsing. +- Package-owned MLIR extensions and `PTOASPythonCAPI` remain under + `ptoas/mlir/_mlir_libs`; only external native dependencies are copied to + the archive `lib/` directory. +- The archive reports a clear error unless it is launched with CPython 3.11. +- The extracted archive runs `ptoas --version` and compiles a representative + `.pto` input containing an unexpanded TileOp through the default PTODSL + backend with `PYTHONPATH`, `LD_LIBRARY_PATH`, and `DYLD_LIBRARY_PATH` unset. +- PR workflows continue to upload the artifact name consumed by the external + board-test monitor until that consumer is explicitly migrated. + +### Coexistence + +A packaging or release integration job should install one representative +namespaced MLIR distribution, preferably IREE, and test both import orders: + +```python +import ptoas.mlir.ir +import iree.compiler.ir +``` + +and: + +```python +import iree.compiler.ir +import ptoas.mlir.ir +``` + +Each runtime should create and verify its own context/module. The test must not +pass objects between runtimes. This heavier check belongs in wheel packaging or +release validation rather than every source-only PR job. + +### Repository Regression + +- Python binding and PTODSL tests; +- TileLang DSL backend tests; +- PTOAS lit tests; +- VMI lit and simulator regression where Python samples are involved; +- Linux and macOS wheel build, repair, clean-install, and CLI smoke tests. + +## Implementation Sequence + +1. Add `ptoas.mlir` package prefix and staging/install destinations. +2. Set the current LLVM fork's global nanobind domain to `ptoas_mlir`. +3. Keep and relocate the single `PTOASPythonCAPI`. +4. Update `_core` package import and package-local RPATH. +5. Add a dedicated compiler-runtime install component and explicit archive + staging prefix; remove source-tree and arbitrary-prefix discovery from the + collectors. +6. Include PTODSL in the compiler-runtime component so the default TileLib + backend remains functional. +7. Replace recursive native dependency parsing with install-time CMake + `file(GET_RUNTIME_DEPENDENCIES)`, then apply the documented Linux/macOS + staging-tree relocation contract. +8. Update the PTO dialect facade and all production Python imports. +9. Update samples, tests, README, workflow artifacts, and wheel/archive + contract validation without renaming the board-test artifact consumed by + the external monitor. +10. Remove top-level `mlir` from the wheel without a default alias. +11. Run build-tree, editable, lit, simulator, repaired-wheel, and extracted + standalone-archive regressions. +12. Validate dynamic dependencies and representative same-process wheel + coexistence. +13. Consider a monolithic `libPTOASCompiler` only as a later, separately + justified optimization for wheel size, startup time, or stronger symbol + isolation. + +## Decision Summary + +- Public namespace: `ptoas.mlir`. +- Public PTO dialect: `ptoas.mlir.dialects.pto`. +- Native compiler module: `ptoas._core`. +- MLIR Python package prefix: `ptoas.mlir.`. +- Nanobind domain: `ptoas_mlir`. +- Common native runtime: one `PTOASPythonCAPI`. +- Linux distribution isolation: `auditwheel repair`. +- macOS distribution isolation: `delocate`. +- Official Python distribution: repaired wheel with the `ptoas` console script. +- Board-validation artifact: compiler-only tarball from the CMake + compiler-runtime install component, preserving the nested `ptoas.mlir` + package layout, including PTODSL for the default TileLib backend, and using + relative native paths. +- Compiler archive Python ABI: CPython 3.11 until a separate abi3 or + per-Python archive design is adopted. +- Archive dependency discovery: CMake `file(GET_RUNTIME_DEPENDENCIES)`; + platform tools perform only staging-tree relocation. +- Board-test compatibility: retain the current `ptoas-bin` artifact contract + until the external monitor is migrated deliberately. +- Cross-runtime native objects: unsupported. +- Top-level `mlir` compatibility alias: not installed. +- Static or monolithic LLVM redesign: deferred to a separate proposal. diff --git a/docs/designs/ptoas-python-launcher-layout.md b/docs/designs/ptoas-python-launcher-layout.md index 3cf5a59d42..1a9d3d2d29 100644 --- a/docs/designs/ptoas-python-launcher-layout.md +++ b/docs/designs/ptoas-python-launcher-layout.md @@ -12,122 +12,151 @@ This document records the internal launcher contract for the Python-backed `ptoas` command. The user-facing README should describe how to install and run -PTOAS, but it should not expose this implementation detail. +PTOAS without exposing these implementation details. -The wheel launcher intentionally uses a Python wrapper instead of packaging the -native `ptoas` executable as the console entry. This avoids auditwheel / -manylinux handling issues for native executables while still letting the wheel -ship the native compiler implementation as a shared library. - -## Goals - -- Keep wheel, build-tree, and install-tree startup deterministic. -- Resolve Python packages and runtime payloads from the current distribution - layout only. -- Avoid falling back to unrelated source checkouts, editable installs, or - ambient `PYTHONPATH` entries. -- Avoid loading duplicated LLVM/MLIR shared libraries inside one Python process. -- Keep `ptoas._launcher` importable temporarily as a compatibility shim, but do - not treat it as a stable public API. +The PTOAS-owned MLIR Python runtime lives under `ptoas.mlir`; its namespace and +native-library isolation requirements are recorded separately in +[`ptoas-mlir-namespace-and-native-isolation.md`](ptoas-mlir-namespace-and-native-isolation.md). ## Entry Model -The launcher has three layers: +The wheel launcher uses the standard Python console-script and native-extension +model. Build-tree and install-tree entrypoints are narrow CMake adapters around +the same Python CLI and native extension: ```text -distribution-specific entry - -> layout resolver - -> ptoas._runtime_entry.launch() - -> ctypes loads ptoas.so - -> calls ptoas_entrypoint(argc, argv) +wheel console script -> ptoas._cli.main() +CMake tree wrapper -> add its own Python root -> ptoas._cli.launch() +both -> import ptoas._core -> ptoas._core.main(argv) ``` -`ptoas._runtime_entry` is the shared execution layer. It should not guess which -distribution layout is active; callers pass a resolved `PTOASRuntimeLayout`. - -## Wheel Layout - -Wheel console scripts point to the top-level `ptoas_wheel_bootstrap:main` -module, not to `ptoas._launcher:main`. - -The bootstrap module lives outside the `ptoas` package so that the console entry -can identify the installed wheel root before importing `ptoas`. This prevents a -polluted `PYTHONPATH` from resolving a shadow `ptoas` package from a source -checkout or another environment. - -Wheel startup is a two-stage process: +`ptoas._core` is the single PTOAS-owned native extension. It provides the +compiler entry point and the native PTO dialect bindings used by the public +`ptoas.mlir.dialects.pto` facade. CMake and Python own the platform and ABI-specific +filename. Launcher and packaging code refer to the import name and never +construct `.so`, `.dylib`, or `.pyd` paths. -1. Stage 1 resolves the wheel-owned package root and runtime root. -2. Stage 1 `execve`s the same console script with a sanitized environment. -3. Stage 2 imports the wheel-owned `ptoas._runtime_entry`. -4. Stage 2 calls the shared `ptoas_entrypoint` from - `ptoas/_runtime/lib/ptoas.so`. +The LLVM-based driver implementation is compiled as an object library so it +can use LLVM's RTTI and exception settings independently from pybind11. Those +objects are linked into the Python extension; no separate native executable is +produced. Wheel and standalone-archive entrypoints therefore use the same +extension and CLI module. -In stage 2, the environment is isolated: - -- `PYTHONPATH` is set to the wheel site-packages root. -- `LD_LIBRARY_PATH` is set to `ptoas/_runtime/lib`. -- `DYLD_LIBRARY_PATH` is set to `ptoas/_runtime/lib`. - -Wheel mode must not preload every shared library under `ptoas/_runtime/lib` -before loading `ptoas.so`. Auditwheel may rewrite `ptoas.so` dependencies to -hashed libraries under `.libs`. If the launcher preloads the -unhashed runtime copies first and `ptoas.so` then loads the auditwheel-rewritten -copies, LLVM/MLIR command-line options can be registered twice in the same -process. +## Wheel Layout -Therefore wheel mode lets the dynamic loader resolve `ptoas.so` dependencies -from the already-sanitized process environment and the auditwheel RPATH. +Wheel console scripts point directly to `ptoas._cli:main`. The CLI imports the +native extension through Python's normal package machinery and resolves TileOps +package data relative to the installed extension. It does not re-execute itself, +load modules by file path, rewrite `PYTHONPATH`, or override Python's standard +package precedence rules. + +Editable installs use scikit-build-core's redirect mode. The backend maps the +Python sources to the checkout and the CMake-installed native extension to the +editable build output without package-local path manipulation. + +Auditwheel and delocate discover the native extension through the standard +wheel binary scan, bundle its dependencies, and rewrite its runtime search +paths. The launcher does not preload or enumerate those libraries. + +Wheel and editable builds use `scikit-build-core` directly as the PEP 517/660 +backend. Project metadata and the console entry point live in `pyproject.toml`; +wheel tags, metadata, RECORD generation, CMake configure/build/install, and +editable redirects are owned by the backend rather than repository scripts. + +The top-level `pyproject.toml` is the single canonical project configuration. +For the mutually exclusive `ptoas-vmi` distribution, +`packaging/ptoas-vmi/prepare_source.py` is the single staging entry point. It +exports every tracked file from one Git revision and applies +`pyproject.toml.patch`; the wheel is built directly from that tree. The patch +changes only the distribution name, static VMI version, description, CLI label, +and sdist inclusion mode; all CMake and Python package paths remain rooted in +the staged source tree. The checkout's top-level metadata is never modified. + +Git owns source selection instead of a hand-maintained directory list. +scikit-build-core then owns PEP 517 metadata and wheel assembly. If an sdist is +requested independently, manual inclusion makes the backend include the complete +tracked snapshot without applying `.gitignore` a second time. +Submodule contents and untracked/generated working-tree files are intentionally +outside this source-distribution contract. Ordinary gates and releases do not +generate or publish a VMI sdist. + +CMake's `PTOAS_Python` install component contains only the generated/native +wheel payload. Python source packages are declared through +`tool.scikit-build.wheel.packages`, which also lets editable installs redirect +imports to the source tree without namespace-package or custom `.pth` logic. ## Build-Tree Layout -The build-tree wrapper is generated for one build directory and resolves only -that tree's staged payload: +The build-tree wrapper resolves only its own generated outputs: - wrapper: `/tools/ptoas/ptoas` - Python root: `/python` -- runtime root: `/runtime-staging` -- shared entry: `/runtime-staging/lib/ptoas.so` - -If the staged Python package or runtime payload is missing, the wrapper fails -with a layout error. It must not repair startup by searching unrelated Python -roots or source checkouts. +- native module: importable as `ptoas._core` from the Python root +- TileOps: `/python/ptoas/_runtime/share/ptoas/TileOps` -Build-tree mode prepends the tree-owned Python and library paths to the current -environment. Because changing `LD_LIBRARY_PATH` after process startup is not a -reliable way to affect subsequent `dlopen` resolution on glibc, build-tree mode -may preload runtime libraries before loading `ptoas.so`. +Missing Python packages or TileOps resources are hard layout errors. The +wrapper only adds `/python` to `sys.path`; `ptoas._cli` owns the common +runtime-resource resolution and native invocation. ## Install-Tree Layout -The install-tree wrapper resolves only files installed under the same prefix: +The install-tree wrapper resolves only files under the same prefix: - wrapper: `/bin/ptoas` -- Python root: the installed PTOAS Python package root under that prefix -- runtime root: the installed PTOAS runtime payload under that prefix -- shared entry: `/lib/ptoas.so` +- Python root: `` +- native module: importable as `ptoas._core` from the Python root +- TileOps: `/ptoas/_runtime/share/ptoas/TileOps` -As with build-tree mode, missing installed payloads are hard layout errors, not -signals to search another checkout or wheel. +The install-tree wrapper only adds `` to `sys.path`, then delegates to +the same `ptoas._cli` module used by wheels. -Install-tree mode follows the same dynamic-library policy as build-tree mode: -it may preload runtime libraries before loading `ptoas.so` because the process -was not re-execed with a fully isolated library environment. +Both tree wrappers are CMake packaging adapters, not general runtime discovery +helpers. Each wrapper adds exactly the Python root belonging to its own tree; +it never scans repositories, neighboring build directories, or environment +variables for another installation. -## Compatibility Shim +## Standalone Archive Layout -`ptoas._launcher` remains importable for a transition period and forwards to the -new launcher path. New code should invoke the `ptoas` command instead of -importing `ptoas._launcher` directly. +Standalone compiler archives contain the installed Python wrapper and package: -The shim exists only to keep older internal scripts from breaking immediately. -It should not grow new layout-resolution logic. - -## Non-Goals +```text +bin/ptoas +ptoas/_cli.py +ptoas/_core..so +ptoas/_runtime/share/ptoas/TileOps +ptoas/mlir/ +ptodsl/ +lib/ +tilelang_dsl/ +``` -- Support installing `ptoas` and `ptoas-vmi` into the same Python environment. - Those distributions share the same import package and console script and are - intentionally mutually exclusive. -- Support arbitrary `PTOAS_PYTHON_ROOT` fallback search in normal launcher - operation. -- Replace the wheel Python wrapper with a native executable console entry. +The archive is assembled by installing `PTOAS_Python` and then +`PTOAS_CompilerArchive` into one staging prefix. The second component owns the +wrapper and compiler-time Python resources and performs relocation against the +already staged native payload. Packaging code does not scan source trees or +assemble Python packages from unrelated build directories. + +The current archive is built against CPython 3.11 and requires a CPython 3.11 +interpreter. `bin/ptoas` adds the archive root to `sys.path`, then uses the same +`ptoas._cli -> ptoas._core` path as the install tree. The packaged `ptodsl/` +tree supports the compiler's default PTODSL TileLib backend; it does not turn +the archive into a normal pip-installable PTODSL distribution. + +Linux archives use package-relative and archive-relative `$ORIGIN` RPATHs; +macOS archives use the equivalent `@loader_path` install names. Package-owned +MLIR extensions remain under `ptoas/mlir/_mlir_libs`, while only external +native dependencies are collected under the archive `lib/` directory. + +## PTODSL and TileLib Runtime + +PTODSL imports MLIR and the PTO dialect through normal Python package +resolution. Wheel and editable installs provide those packages through their +declared installation layout. CTest and direct developer-tree runs must set an +explicit matching `PYTHONPATH`; PTODSL does not guess repository, LLVM build, +or PTOAS install paths at import time. + +TileOp expansion remains a lazy, separate daemon process. The PTOAS CLI passes +the packaged PTODSL root and the active Python executable to the native driver, +which starts the daemon only when expansion is required. Keeping the daemon out +of the compiler process also prevents independently packaged MLIR/LLVM Python +bindings from registering runtime state in the native PTOAS process. diff --git a/docs/designs/ptoas-tileop-expand-design.md b/docs/designs/ptoas-tileop-expand-design.md index 9c5c49c577..56fffc09fc 100644 --- a/docs/designs/ptoas-tileop-expand-design.md +++ b/docs/designs/ptoas-tileop-expand-design.md @@ -1248,9 +1248,10 @@ Python 侧的 case 名、dtype、shape、valid_shape、eps(以及必要时的 ##### 运行方式 统一入口为 `test/tilelang_st/script/run_st.py`。前置条件: -- `ptoas` 已编译(默认路径 `build/tools/ptoas/ptoas`,也可通过 `-p` 指定或 `PTOAS_BIN` 环境变量) +- `ptoas` 已通过 `./quick_install.sh` 或 editable install 安装到当前 + Python 环境(也可通过 `-p` 指定或 `PTOAS_BIN` 环境变量覆盖) - `ASCEND_HOME_PATH` 已设置 -- 建议先执行 `source scripts/ptoas_env.sh` +- simulator / NPU 运行前已加载 CANN `setenv.bash` ```bash # simulator 上跑 tsub 全部 case diff --git a/docs/designs/tilelang-st-framework.md b/docs/designs/tilelang-st-framework.md index 60a48bb051..189cafc83a 100644 --- a/docs/designs/tilelang-st-framework.md +++ b/docs/designs/tilelang-st-framework.md @@ -140,15 +140,17 @@ test/tilelang_st/ 运行 TileLang ST 之前,建议先确认下面几件事: -- 仓库里的 `ptoas` 已经编出来,默认路径是 `build/tools/ptoas/ptoas` +- `ptoas` 已经通过 `./quick_install.sh` 或 `pip install -e . --no-build-isolation` + 安装到当前 Python 环境 - `ASCEND_HOME_PATH` 已经设置正确 -- 如果需要手工跑 `ptoas`、`bisheng` 或 lit,优先先执行: +- 如果需要 simulator、NPU 或 `bisheng`,再加载 CANN 环境: ```bash -source scripts/ptoas_env.sh +source "${ASCEND_HOME_PATH}/bin/setenv.bash" ``` -`run_st.py` 会在运行时补充 simulator / NPU 相关环境,但它不会替你构建 `ptoas`。 +`run_st.py` 会优先使用 `PTOAS_BIN`,否则使用当前 `PATH` 中由 pip +安装的 `ptoas`。它不会替你构建或安装 PTOAS。 ### 5.1 运行已有 testcase diff --git a/docs/no_npu_compile_only_guide_zh.md b/docs/no_npu_compile_only_guide_zh.md index 7c9b96ca99..c96b7a1b35 100644 --- a/docs/no_npu_compile_only_guide_zh.md +++ b/docs/no_npu_compile_only_guide_zh.md @@ -187,7 +187,7 @@ export PTOAS_BIN=$PWD/build/tools/ptoas/ptoas export PTOBC_BIN=$PWD/build/tools/ptobc/ptobc export PYTHON_BIN=/usr/bin/python3 export PTOAS_OUT_DIR="$PAYLOAD_ROOT/test/samples" -export PYTHONPATH="$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core:$PTO_INSTALL_DIR:${PYTHONPATH:-}" +export PYTHONPATH="$PTO_INSTALL_DIR:${PYTHONPATH:-}" export LD_LIBRARY_PATH="$LLVM_BUILD_DIR/lib:$PTO_INSTALL_DIR/lib:${LD_LIBRARY_PATH:-}" export SOC_VERSION="$TARGET_SOC_VERSION" diff --git a/lib/Bindings/Python/CMakeLists.txt b/lib/Bindings/Python/CMakeLists.txt index 4e484668bd..04ed2a183b 100644 --- a/lib/Bindings/Python/CMakeLists.txt +++ b/lib/Bindings/Python/CMakeLists.txt @@ -6,133 +6,146 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -# lib/Bindings/Python/CMakeLists.txt - -find_package(Python3 COMPONENTS Interpreter Development.Module REQUIRED) -find_package(pybind11 CONFIG REQUIRED) - -include(TableGen) -include(AddMLIR) - -get_filename_component(PTO_LLVM_BUILD_LIBRARY_DIR - "${LLVM_BUILD_LIBRARY_DIR}" REALPATH) - -# ---- 1) Python native extension: mlir._mlir_libs._pto ---- -pybind11_add_module(_pto MODULE - PTOModule.cpp -) - -target_include_directories(_pto PRIVATE - ${CMAKE_SOURCE_DIR}/include -) +include(AddMLIRPython) + +# Keep the complete PTOAS-owned MLIR Python runtime below the project namespace +# so it can coexist with independently packaged MLIR distributions. This is a +# package-prefix contract as well as a Python import path: MLIR's generated +# capsules and nanobind registration code use the same value. +add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=ptoas.mlir.") +set(MLIR_BINDINGS_PYTHON_NB_DOMAIN "ptoas_mlir") + +# Do not carry toolchain-injected paths, such as a Conda compiler RPATH, into +# installed Python modules. Wheel builds retain AddMLIRPython's package-relative +# RPATHs for repair; editable builds append only the external LLVM directory. +set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH ON) + +# This directory materializes C++ sources exported by upstream MLIR. PTOAS +# keeps -Werror enabled globally, but upstream sources are not part of the +# project warning contract. Scope the exception to this directory; the +# project-owned ptoas._core extension is built in tools/ptoas and therefore +# remains under -Werror. +if(PTOAS_ENABLE_WERROR) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + add_compile_options("$<$:-Wno-error>") + elseif(MSVC) + add_compile_options("$<$:/WX->") + endif() +endif() -target_link_options(_pto PRIVATE) +# Build the `ptoas.mlir` Python package from MLIR's exported source declarations and +# add PTOAS's dialect to the same package. This is the composition mechanism +# supported by AddMLIRPython and avoids copying or overlaying another build's +# package tree. +set(PTOAS_MLIR_PYTHON_PACKAGE_DIR "${CMAKE_BINARY_DIR}/python/ptoas/mlir") -target_link_libraries(_pto PRIVATE +declare_mlir_python_sources(PTOASPythonSources) - PTOCAPI - PTOIR - MLIRIR - MLIRCAPIIR - MLIRSupport - MLIRArithDialect - MLIRMemRefDialect - MLIRSCFDialect - MLIRDestinationStyleOpInterface - MLIRInferTypeOpInterface - MLIRSideEffectInterfaces - MLIRCallInterfaces - MLIRControlFlowInterfaces - MLIRLoopLikeInterface - MLIRViewLikeInterface - MLIRFunctionInterfaces - MLIRLLVMDialect +declare_mlir_dialect_python_bindings( + ADD_TO_PARENT PTOASPythonSources + ROOT_DIR "${CMAKE_SOURCE_DIR}/python/pto" + TD_FILE dialects/PTOOps.td + SOURCES dialects/pto.py + DIALECT_NAME pto ) -# 关键:放到 mlir/_mlir_libs 下(匹配 MLIR dialect python 的 import 习惯) -set_target_properties(_pto PROPERTIES - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/python/mlir/_mlir_libs" - BUILD_RPATH "${PTO_LLVM_BUILD_LIBRARY_DIR}" - INSTALL_RPATH "${PTO_LLVM_BUILD_LIBRARY_DIR}" +# Use MLIR's standard site-initializer hook to seed each Python Context with +# the selected upstream dialects shipped by PTOAS. Declaring the extension in +# the Python source graph lets AddMLIRPython own its build, installation, and +# common-CAPI dependency collection. +set(PTOAS_PYTHON_REGISTRATION_SOURCE + "${CMAKE_CURRENT_SOURCE_DIR}/PythonRegistration.cpp") +declare_mlir_python_extension(PTOASPythonSources.Registration + MODULE_NAME _site_initialize_0 + ADD_TO_PARENT PTOASPythonSources + ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + PYTHON_BINDINGS_LIBRARY nanobind + SOURCES PythonRegistration.cpp + EMBED_CAPI_LINK_LIBS + MLIRCAPIArith + MLIRCAPIFunc + MLIRCAPILLVM + MLIRCAPIMath + MLIRCAPIMemRef + MLIRCAPISCF ) -# macOS: 避免 ld 警告 "-undefined suppress is deprecated",仅保留 -undefined dynamic_lookup -if(APPLE) - target_link_options(_pto PRIVATE "LINKER:-undefined,dynamic_lookup") -endif() -if(NOT MLIR_PYTHON_PACKAGE_DIR) - message(FATAL_ERROR "MLIR_PYTHON_PACKAGE_DIR must be set when PTO_ENABLE_PYTHON_BINDING=ON") +# This directory otherwise materializes only upstream MLIR/nanobind C++ +# sources under -Wno-error. Keep the project-owned registration source under +# PTOAS's default strict warning policy while retaining one declarative Python +# package graph. +if(PTOAS_ENABLE_WERROR) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang") + set_property(SOURCE "${PTOAS_PYTHON_REGISTRATION_SOURCE}" APPEND PROPERTY + COMPILE_OPTIONS -Werror) + elseif(MSVC) + set_property(SOURCE "${PTOAS_PYTHON_REGISTRATION_SOURCE}" APPEND PROPERTY + COMPILE_OPTIONS /WX) + endif() endif() -install(TARGETS _pto - LIBRARY DESTINATION "mlir/_mlir_libs" -) - -# ---- 2) Generate ODS Python op bindings: _pto_ops_gen.py ---- -set(PTO_TD_DIR "${CMAKE_SOURCE_DIR}/include/PTO/IR") -set(LLVM_TARGET_DEFINITIONS ${PTO_TD_DIR}/PTOOps.td) - -mlir_tablegen(_pto_ops_gen.py - -gen-python-op-bindings - --bind-dialect=pto -) - -add_public_tablegen_target(PTOPythonGen) -add_dependencies(_pto PTOPythonGen) - -# ---- 3) Copy generated python + handwritten pto.py into build/python ---- -set(PTO_PY_SRC "${CMAKE_SOURCE_DIR}/python/pto/dialects/pto.py") - -add_custom_command(TARGET _pto POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/python/mlir/dialects" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${PTO_PY_SRC}" - "${CMAKE_BINARY_DIR}/python/mlir/dialects/pto.py" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${CMAKE_CURRENT_BINARY_DIR}/_pto_ops_gen.py" - "${CMAKE_BINARY_DIR}/python/mlir/dialects/_pto_ops_gen.py" - VERBATIM +# Package only the upstream Python APIs used by PTOAS and PTODSL. In +# particular, do not instantiate MLIRPythonSources or RegisterEverything: +# downstream MLIR packages are expected to select their public dialect set +# explicitly rather than linking every upstream dialect, translation and pass. +set(PTOAS_MLIR_PYTHON_SOURCE_SETS + MLIRPythonSources.Core + MLIRPythonSources.Dialects.arith + MLIRPythonSources.Dialects.builtin + MLIRPythonSources.Dialects.func + MLIRPythonSources.Dialects.llvm + MLIRPythonSources.Dialects.math + MLIRPythonSources.Dialects.memref + MLIRPythonSources.Dialects.scf ) -install(FILES - "${PTO_PY_SRC}" - "${CMAKE_CURRENT_BINARY_DIR}/_pto_ops_gen.py" - DESTINATION mlir/dialects +# Keep one common CAPI DSO for the upstream MLIR Python package. PTOAS owns a +# single ptoas._core extension, built in tools/ptoas, which links this common +# CAPI and contains both the PTO dialect implementation and compiler driver. +add_mlir_python_common_capi_library(PTOASPythonCAPI + INSTALL_COMPONENT PTOAS_Python + INSTALL_DESTINATION "ptoas/mlir/_mlir_libs" + OUTPUT_DIRECTORY "${PTOAS_MLIR_PYTHON_PACKAGE_DIR}/_mlir_libs" + RELATIVE_INSTALL_ROOT "../../../" + DECLARED_HEADERS + MLIRPythonCAPI.HeaderSources + DECLARED_SOURCES + ${PTOAS_MLIR_PYTHON_SOURCE_SETS} + PTOASPythonSources + # MLIRPythonExtension.Core currently obtains its rewrite CAPI through + # RegisterEverything. PTOAS deliberately omits RegisterEverything, so retain + # the missing direct dependency until upstream Core declares it itself. + EMBED_LIBS + MLIRCAPITransforms ) - -# Keep the MLIR build-tree Python package self-consistent as well. When users -# import `mlir.dialects.pto` directly from MLIR_PYTHON_PACKAGE_DIR, the wrapper -# modules must be updated alongside the native `_pto` extension during normal -# builds, not just during `cmake --install`. -add_custom_command(TARGET _pto POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/dialects" - COMMAND ${CMAKE_COMMAND} -E make_directory - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/_mlir_libs" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${PTO_PY_SRC}" - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/dialects/pto.py" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "${CMAKE_CURRENT_BINARY_DIR}/_pto_ops_gen.py" - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/dialects/_pto_ops_gen.py" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "$" - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/_mlir_libs/$" - VERBATIM +# Imported MLIR aggregate objects do not expose a source language from which +# CMake can infer the linker driver. The common CAPI is C++, matching MLIR's +# own in-tree target. +set_property(TARGET PTOASPythonCAPI PROPERTY LINKER_LANGUAGE CXX) + +add_mlir_python_modules(PTOAS_Python + ROOT_PREFIX "${PTOAS_MLIR_PYTHON_PACKAGE_DIR}" + INSTALL_PREFIX ptoas/mlir + DECLARED_SOURCES + ${PTOAS_MLIR_PYTHON_SOURCE_SETS} + PTOASPythonSources + COMMON_CAPI_LINK_LIBS + PTOASPythonCAPI ) -add_custom_command(TARGET _pto POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory - "${CMAKE_BINARY_DIR}/python/mlir/_mlir_libs" - COMMAND ${CMAKE_COMMAND} -E make_directory - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/_mlir_libs" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "$" - "${MLIR_PYTHON_PACKAGE_DIR}/mlir/_mlir_libs/$" - VERBATIM -) +# AddMLIRPython deliberately resets each generated target's install RPATH to +# its package-relative layout. Append the external LLVM directory afterwards +# for editable installs, where those dependencies are not bundled into the +# Python environment. Discover the native targets by CMake type so additional +# generated MLIR extensions inherit the same contract automatically. +if(SKBUILD_STATE STREQUAL "editable") + get_property(_ptoas_python_directory_targets + DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) + foreach(_ptoas_python_target IN LISTS _ptoas_python_directory_targets) + get_target_property(_ptoas_python_target_type + "${_ptoas_python_target}" TYPE) + if(_ptoas_python_target_type MATCHES "^(MODULE|SHARED)_LIBRARY$") + ptoas_append_editable_llvm_rpath("${_ptoas_python_target}") + endif() + endforeach() +endif() diff --git a/lib/Bindings/Python/PTOModule.cpp b/lib/Bindings/Python/PTOModule.cpp index 432d08e262..b9abb1cc30 100644 --- a/lib/Bindings/Python/PTOModule.cpp +++ b/lib/Bindings/Python/PTOModule.cpp @@ -8,14 +8,13 @@ //===- DialectPTO.cpp -----------------------------------------------------===// // -// Python bindings for the PTO dialect types (pybind11 version). -// -// This file is intended to be built via declare_mlir_python_extension(...) -// with PYTHON_BINDINGS_LIBRARY pybind11, and linked with MLIRCAPIPTO. +// Python bindings for the PTO dialect types in the project-owned ptoas._core +// extension. The public Python facade remains ptoas.mlir.dialects.pto. // //===----------------------------------------------------------------------===// -#include "pybind11/pybind11.h" +#include "PTOModule.h" + #include "pybind11/stl.h" #include "mlir/Bindings/Python/PybindAdaptors.h" #include "mlir/CAPI/IR.h" @@ -119,8 +118,7 @@ void populatePTODialectSubmodule(pybind11::module &m) { (void)m; } -static void bindPTOModule(pybind11::module &m) { - m.doc() = "PTO dialect Python bindings (pybind11)."; +void mlir::pto::python::populatePTODialectBindings(pybind11::module_ &m) { // -------------------------------------------------------------------------- // Dialect registration helper @@ -1440,7 +1438,3 @@ static void bindPTOModule(pybind11::module &m) { populatePTODialectSubmodule(m); } - -PYBIND11_MODULE(_pto, m) { - bindPTOModule(m); -} diff --git a/lib/Bindings/Python/PTOModule.h b/lib/Bindings/Python/PTOModule.h new file mode 100644 index 0000000000..6fdf04a2b4 --- /dev/null +++ b/lib/Bindings/Python/PTOModule.h @@ -0,0 +1,22 @@ +// Copyright (c) 2026 Huawei Technologies Co., Ltd. +// This program is free software, you can redistribute it and/or modify it under the terms and conditions of +// CANN Open Software License Agreement Version 2.0 (the "License"). +// Please refer to the License for details. You may not use this file except in compliance with the License. +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// See LICENSE in the root of the software repository for the full text of the License. + +#ifndef PTOAS_LIB_BINDINGS_PYTHON_PTOMODULE_H +#define PTOAS_LIB_BINDINGS_PYTHON_PTOMODULE_H + +#include "pybind11/pybind11.h" + +namespace mlir::pto::python { + +/// Adds PTO dialect types, attributes, enums, and registration helpers to the +/// project-owned ptoas._core extension module. +void populatePTODialectBindings(pybind11::module_ &module); + +} // namespace mlir::pto::python + +#endif // PTOAS_LIB_BINDINGS_PYTHON_PTOMODULE_H diff --git a/lib/Bindings/Python/PythonRegistration.cpp b/lib/Bindings/Python/PythonRegistration.cpp new file mode 100644 index 0000000000..5fec0b0e7e --- /dev/null +++ b/lib/Bindings/Python/PythonRegistration.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2026 Huawei Technologies Co., Ltd. +// This program is free software, you can redistribute it and/or modify it under the terms and conditions of +// CANN Open Software License Agreement Version 2.0 (the "License"). +// Please refer to the License for details. You may not use this file except in compliance with the License. +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// See LICENSE in the root of the software repository for the full text of the License. + +#include "mlir-c/Dialect/Arith.h" +#include "mlir-c/Dialect/Func.h" +#include "mlir-c/Dialect/LLVM.h" +#include "mlir-c/Dialect/Math.h" +#include "mlir-c/Dialect/MemRef.h" +#include "mlir-c/Dialect/SCF.h" +#include "mlir-c/IR.h" +#include "mlir/Bindings/Python/NanobindAdaptors.h" + +NB_MODULE(_site_initialize_0, module) { + module.doc() = "PTOAS MLIR dialect registration"; + module.def("register_dialects", [](MlirDialectRegistry registry) { + mlirDialectHandleInsertDialect(mlirGetDialectHandle__arith__(), registry); + mlirDialectHandleInsertDialect(mlirGetDialectHandle__func__(), registry); + mlirDialectHandleInsertDialect(mlirGetDialectHandle__llvm__(), registry); + mlirDialectHandleInsertDialect(mlirGetDialectHandle__math__(), registry); + mlirDialectHandleInsertDialect(mlirGetDialectHandle__memref__(), registry); + mlirDialectHandleInsertDialect(mlirGetDialectHandle__scf__(), registry); + }); +} diff --git a/packaging/ptoas-vmi/prepare_source.py b/packaging/ptoas-vmi/prepare_source.py new file mode 100644 index 0000000000..a4a5752bc0 --- /dev/null +++ b/packaging/ptoas-vmi/prepare_source.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +"""Prepare the complete source tree used to build the ``ptoas-vmi`` wheel.""" + +from __future__ import annotations + +import argparse +import os +import re +import shutil +import subprocess +import sys +import tarfile +import tempfile +from pathlib import Path + + +SCRIPT_PATH = Path(__file__).resolve() +REPOSITORY_ROOT = SCRIPT_PATH.parents[2] +METADATA_PATCH = SCRIPT_PATH.with_name("pyproject.toml.patch") +DEFAULT_OUTPUT_DIR = REPOSITORY_ROOT / ".work" / "ptoas-vmi-source" +VERSION_PATTERN = re.compile(r'^\+version = "([0-9]+\.[0-9]+\.[0-9]+)"$', re.M) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--output-dir", + type=Path, + default=DEFAULT_OUTPUT_DIR, + help="Staging directory to replace (default: .work/ptoas-vmi-source).", + ) + parser.add_argument( + "--revision", + default="HEAD", + help="Git revision to archive (default: HEAD).", + ) + parser.add_argument( + "--print-version", + action="store_true", + help="Print the configured VMI version without preparing a source tree.", + ) + return parser.parse_args() + + +def read_vmi_version() -> str: + versions = VERSION_PATTERN.findall(METADATA_PATCH.read_text(encoding="utf-8")) + if len(versions) != 1: + raise ValueError("VMI metadata patch does not set one static X.Y.Z version") + return versions[0] + + +def _check_output_dir(output_dir: Path) -> None: + try: + relative = output_dir.relative_to(REPOSITORY_ROOT) + except ValueError: + if output_dir.exists() and ( + not output_dir.is_dir() or any(output_dir.iterdir()) + ): + raise ValueError( + f"external output directory must be absent or empty: {output_dir}" + ) + return + if len(relative.parts) < 2 or relative.parts[0] != ".work": + raise ValueError( + f"repository-local output directory must be below .work: {output_dir}" + ) + + +def _remove_path(path: Path) -> None: + if path.is_symlink() or path.is_file(): + path.unlink() + elif path.exists(): + shutil.rmtree(path) + + +def prepare_source(output_dir: Path, revision: str) -> dict[str, str]: + output_dir = output_dir.expanduser().resolve() + _check_output_dir(output_dir) + output_dir.parent.mkdir(parents=True, exist_ok=True) + temporary_dir = Path( + tempfile.mkdtemp(prefix=f".{output_dir.name}-", dir=output_dir.parent) + ) + archive_path: Path | None = None + try: + resolved_revision = subprocess.run( + [ + "git", + "-C", + str(REPOSITORY_ROOT), + "rev-parse", + "--verify", + f"{revision}^{{commit}}", + ], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + with tempfile.NamedTemporaryFile( + prefix="ptoas-vmi-source-", + suffix=".tar", + dir=output_dir.parent, + delete=False, + ) as archive_file: + archive_path = Path(archive_file.name) + + subprocess.run( + [ + "git", + "-C", + str(REPOSITORY_ROOT), + "archive", + "--format=tar", + f"--output={archive_path}", + resolved_revision, + ], + check=True, + ) + with tarfile.open(archive_path, mode="r:") as archive: + for member in archive.getmembers(): + member_path = Path(member.name) + if member_path.is_absolute() or ".." in member_path.parts: + raise ValueError( + f"git archive contains an unsafe path: {member.name}" + ) + if member.issym() or member.islnk(): + raise ValueError( + f"git archive contains an unsupported link: {member.name}" + ) + archive.extractall(temporary_dir) + + apply_environment = os.environ.copy() + apply_environment.update( + { + "GIT_DIR": str(temporary_dir / ".git-not-present"), + "GIT_WORK_TREE": str(temporary_dir), + } + ) + subprocess.run( + ["git", "apply", str(METADATA_PATCH)], + cwd=temporary_dir, + env=apply_environment, + check=True, + ) + + version = read_vmi_version() + staged_text = (temporary_dir / "pyproject.toml").read_text(encoding="utf-8") + required_fragments = ( + 'name = "ptoas-vmi"', + f'version = "{version}"', + 'PTOAS_CLI_VERSION_LABEL = "vmi"', + 'sdist.inclusion-mode = "manual"', + ) + missing = [item for item in required_fragments if item not in staged_text] + if missing: + raise ValueError(f"VMI metadata patch is incomplete: {missing}") + if "../" in staged_text: + raise ValueError("staged pyproject.toml contains an external relative path") + + _remove_path(output_dir) + temporary_dir.replace(output_dir) + except BaseException: + _remove_path(temporary_dir) + raise + finally: + if archive_path is not None: + archive_path.unlink(missing_ok=True) + + return {"version": version, "source": str(output_dir)} + + +def main() -> int: + args = parse_args() + try: + if args.print_version: + print(read_vmi_version()) + return 0 + outputs = prepare_source(args.output_dir, args.revision) + print(outputs["source"]) + except (OSError, RuntimeError, subprocess.CalledProcessError, ValueError) as error: + print(f"error: {error}", file=sys.stderr) + return 1 + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/packaging/ptoas-vmi/pyproject.toml.patch b/packaging/ptoas-vmi/pyproject.toml.patch new file mode 100644 index 0000000000..97cf810a8f --- /dev/null +++ b/packaging/ptoas-vmi/pyproject.toml.patch @@ -0,0 +1,29 @@ +diff --git a/pyproject.toml b/pyproject.toml +--- a/pyproject.toml ++++ b/pyproject.toml +@@ -18,7 +18,7 @@ build-backend = "scikit_build_core.build" + [project] +-name = "ptoas" +-dynamic = ["version"] +-description = "PTO Assembler & Optimizer" ++name = "ptoas-vmi" ++version = "0.1.4" ++description = "PTO Assembler & Optimizer with VMI support" + readme = "README.md" + requires-python = ">=3.10" + license = "Apache-2.0" +@@ -43,4 +43,5 @@ cmake.version = "CMakeLists.txt" + ninja.version = ">=1.10" + build.verbose = false + editable.mode = "redirect" ++sdist.inclusion-mode = "manual" + install.components = ["PTOAS_Python"] +@@ -53,7 +54,3 @@ tilelang_dsl = "tilelang-dsl/python/tilelang_dsl" + [tool.scikit-build.cmake.define] + PTOAS_RELEASE_VERSION_OVERRIDE = { env = "PTOAS_RELEASE_VERSION_OVERRIDE", default = "" } +- +-[tool.scikit-build.metadata.version] +-provider = "scikit_build_core.metadata.regex" +-input = "CMakeLists.txt" +-regex = 'project\s*\(\s*ptoas\s+VERSION\s+(?P[0-9]+\.[0-9]+)\s*\)' ++PTOAS_CLI_VERSION_LABEL = "vmi" diff --git a/ptodsl/CMakeLists.txt b/ptodsl/CMakeLists.txt index 4123b99996..c8d1e9ba25 100644 --- a/ptodsl/CMakeLists.txt +++ b/ptodsl/CMakeLists.txt @@ -12,51 +12,32 @@ set(PTODSL_PACKAGE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ptodsl") -set(PTOAS_PY_PACKAGE_SRC_DIR - "${CMAKE_CURRENT_SOURCE_DIR}/ptoas") -set(PTOAS_WHEEL_BOOTSTRAP_SOURCE - "${CMAKE_CURRENT_SOURCE_DIR}/ptoas_wheel_bootstrap.py") -set(PTODSL_BUILD_ROOT "${CMAKE_BINARY_DIR}/python") set(PTODSL_BUILD_PACKAGE_DIR - "${PTODSL_BUILD_ROOT}/ptodsl") -set(PTOAS_PY_BUILD_PACKAGE_DIR - "${PTODSL_BUILD_ROOT}/ptoas") + "${CMAKE_BINARY_DIR}/python/ptodsl") -add_custom_target(PTODSLPackage ALL - COMMAND ${CMAKE_COMMAND} -E make_directory "${PTODSL_BUILD_ROOT}" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${PTODSL_BUILD_PACKAGE_DIR}" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${PTOAS_PY_BUILD_PACKAGE_DIR}" - COMMAND ${CMAKE_COMMAND} -E copy_directory - "${PTODSL_PACKAGE_SRC_DIR}" - "${PTODSL_BUILD_PACKAGE_DIR}" - COMMAND ${CMAKE_COMMAND} -E copy_directory - "${PTOAS_PY_PACKAGE_SRC_DIR}" - "${PTOAS_PY_BUILD_PACKAGE_DIR}" - COMMAND ${CMAKE_COMMAND} -E copy - "${PTOAS_WHEEL_BOOTSTRAP_SOURCE}" - "${PTODSL_BUILD_ROOT}/ptoas_wheel_bootstrap.py" - COMMENT "Staging ptodsl package into build/python" - VERBATIM +declare_mlir_python_sources(PTODSLPythonSources + ROOT_DIR "${PTODSL_PACKAGE_SRC_DIR}" + SOURCES_GLOB "*.py" ) +add_mlir_python_sources_target(PTODSLPackageStage + OUTPUT_DIRECTORY "${PTODSL_BUILD_PACKAGE_DIR}" + SOURCES_TARGETS PTODSLPythonSources +) +add_custom_target(PTODSLPackage ALL) +add_dependencies(PTODSLPackage PTODSLPackageStage) install( DIRECTORY "${PTODSL_PACKAGE_SRC_DIR}" DESTINATION "." - COMPONENT PTOAS_Runtime + COMPONENT PTOAS_CompilerArchive PATTERN "__pycache__" EXCLUDE PATTERN "*.pyc" EXCLUDE ) install( - DIRECTORY "${PTOAS_PY_PACKAGE_SRC_DIR}" + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ptoas" DESTINATION "." - COMPONENT PTOAS_Runtime + COMPONENT PTOAS_CompilerArchive PATTERN "__pycache__" EXCLUDE PATTERN "*.pyc" EXCLUDE ) - -install( - FILES "${PTOAS_WHEEL_BOOTSTRAP_SOURCE}" - DESTINATION "." - COMPONENT PTOAS_Runtime -) diff --git a/ptodsl/README.md b/ptodsl/README.md index db05638333..f0023f325f 100644 --- a/ptodsl/README.md +++ b/ptodsl/README.md @@ -18,7 +18,7 @@ ptodsl/ │ ├── __init__.py # exports: pto, scalar │ ├── pto.py # main PTO DSL namespace │ ├── scalar.py # top-level scalar.* helper namespace -│ ├── _bootstrap.py # MLIR path setup + context factory +│ ├── _context.py # MLIR context factory │ ├── _types.py # lazy dtype descriptors and type constructors │ ├── _ops.py # PTO operation wrappers │ ├── _control_flow.py # for_, if_, yield_ context managers @@ -62,20 +62,24 @@ python3 -c "import ptodsl; from ptodsl import pto, scalar; print(ptodsl.__file__ Not supported: - `cd ptodsl && pip install -e .` -- repo-walk / `PYTHONPATH` / `sys.path` repair just to locate the `ptodsl` package +- runtime repository walks or `sys.path` repair to locate MLIR/PTO bindings + +Direct CTest/developer-tree execution must provide the matching MLIR and PTO +Python roots explicitly through the test environment or `PYTHONPATH`; PTODSL +does not search nearby build and install directories at import time. Artifact boundary: - `ptoas` wheel: PTODSL-capable Python distribution - `ptoas-bin-*.tar.gz`: compiler-only artifact, does **not** imply `import ptodsl` -If you are working from a source checkout and want the repository helper -scripts (`scripts/sim_dsl.sh`, sample runners, direct CLI debugging) to pick up -the local build/install tree, you may still source: +For source development, install the checkout into the active Python environment. +The editable install retains an incremental CMake build tree without requiring +manual `PYTHONPATH` or build-tree wrapper setup: ```bash cd $PTOAS_REPO_ROOT -source scripts/ptoas_env.sh +LLVM_BUILD_DIR=/path/to/llvm/build ./quick_install.sh ``` --- @@ -89,11 +93,11 @@ ptoas --pto-arch=a5 --pto-backend=vpto --emit-vpto \ input.pto -o - ``` -The source-tree build bakes in `$PTOAS_REPO_ROOT/ptodsl` as the package root. -The `PTODSL_PYTHON_ROOT` environment variable from `scripts/ptoas_env.sh` -overrides that default. Use `--ptodsl-pkg-path=/path/to/package/root` for an -explicit command-line override. PTODSL daemon failures are reported as errors -and never fall back to the TileLang implementation. Use +Wheel and CMake-tree launchers pass the Python root containing their own +installed or staged `ptodsl` package to the native driver. Use +`--ptodsl-pkg-path=/path/to/package/root` for an explicit command-line +override. PTODSL daemon failures are reported as errors and never fall back to +the TileLang implementation. Use `--tile-lib-backend=tilelang` only when explicitly comparing against the legacy TileLangDSL template library. @@ -131,7 +135,6 @@ Set up the environment in each new shell: ```bash cd $PTOAS_REPO_ROOT pip install -e . --no-build-isolation -source scripts/ptoas_env.sh source "${ASCEND_HOME_PATH}/bin/setenv.bash" ``` diff --git a/ptodsl/docs/developer_guide/tilelib-debugging-playbook.md b/ptodsl/docs/developer_guide/tilelib-debugging-playbook.md index db519c5165..324764b93d 100644 --- a/ptodsl/docs/developer_guide/tilelib-debugging-playbook.md +++ b/ptodsl/docs/developer_guide/tilelib-debugging-playbook.md @@ -12,7 +12,7 @@ usually live in different layers. Build PTOAS after C++ or TableGen changes: ```bash -cmake --build build-llvm21 --target ptoas_runtime +cmake --build build-llvm21 --target PTOASPythonCore ``` Stage PTODSL after Python package changes: diff --git a/ptodsl/examples/softmax_lowlevel.py b/ptodsl/examples/softmax_lowlevel.py index b962551fab..4d673ca93d 100644 --- a/ptodsl/examples/softmax_lowlevel.py +++ b/ptodsl/examples/softmax_lowlevel.py @@ -14,7 +14,7 @@ using raw MLIR Python binding calls, with no additional abstraction layer. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, F32Type, @@ -28,7 +28,7 @@ Type, UnitAttr, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def build(): diff --git a/ptodsl/examples/tadd_lowlevel.py b/ptodsl/examples/tadd_lowlevel.py index 8dd98c77dc..fbae54c7b8 100644 --- a/ptodsl/examples/tadd_lowlevel.py +++ b/ptodsl/examples/tadd_lowlevel.py @@ -41,7 +41,7 @@ } """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, F32Type, @@ -54,7 +54,7 @@ StringAttr, Type, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def build(): diff --git a/ptodsl/ptoas/__init__.py b/ptodsl/ptoas/__init__.py index 20c98a7808..e7a40405e2 100644 --- a/ptodsl/ptoas/__init__.py +++ b/ptodsl/ptoas/__init__.py @@ -6,5 +6,4 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -"""PTOAS wheel runtime helpers.""" - +"""Python package for the PTOAS command-line interface.""" diff --git a/ptodsl/ptoas/_cli.py b/ptodsl/ptoas/_cli.py new file mode 100644 index 0000000000..7798275f28 --- /dev/null +++ b/ptodsl/ptoas/_cli.py @@ -0,0 +1,83 @@ +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +"""Standard Python console entry point for PTOAS.""" + +from __future__ import annotations + +import os +import sys +from pathlib import Path +from typing import Sequence + + +def _resolve_wrapper_path(argv0: str | None = None) -> Path: + candidate = argv0 if argv0 is not None else sys.argv[0] + wrapper = Path(candidate) + if wrapper.exists(): + return wrapper.resolve() + + raise SystemExit(f"unable to locate the active ptoas entry point: {candidate}") + + +def _load_native_module(): + from ptoas import _core + + return _core + + +def _resolve_runtime_paths(native_module) -> tuple[Path, Path]: + module_file = getattr(native_module, "__file__", None) + if not module_file: + raise SystemExit("ptoas._core does not expose a module file") + + package_root = Path(module_file).resolve().parent + python_root = package_root.parent + runtime_root = package_root / "_runtime" + tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" + if not tileops_dir.is_dir(): + raise SystemExit( + "unable to locate packaged PTOAS TileOps resources: expected " + f"{tileops_dir}" + ) + return python_root, tileops_dir.resolve() + + +def _has_cli_option(arguments: Sequence[str], option: str) -> bool: + option_with_value = f"{option}=" + return any( + argument == option or argument.startswith(option_with_value) + for argument in arguments + ) + + +def launch(user_args: Sequence[str], *, wrapper: Path | None = None) -> int: + native_module = _load_native_module() + python_root, tileops_dir = _resolve_runtime_paths(native_module) + wrapper = wrapper.resolve() if wrapper is not None else _resolve_wrapper_path() + + os.environ["PTOAS_BIN"] = str(wrapper) + os.environ["PTOAS_PYTHON_EXE"] = sys.executable + argv = [str(wrapper)] + if not _has_cli_option(user_args, "--tilelang-path"): + argv.extend(["--tilelang-path", str(tileops_dir)]) + if not _has_cli_option(user_args, "--tilelang-pkg-path"): + argv.extend(["--tilelang-pkg-path", str(python_root)]) + if not _has_cli_option(user_args, "--ptodsl-pkg-path"): + argv.extend(["--ptodsl-pkg-path", str(python_root)]) + argv.extend(user_args) + + return int(native_module.main(argv)) + + +def main() -> int: + return launch(sys.argv[1:]) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/ptodsl/ptoas/_runtime_entry.py b/ptodsl/ptoas/_runtime_entry.py deleted file mode 100644 index 2fa032727d..0000000000 --- a/ptodsl/ptoas/_runtime_entry.py +++ /dev/null @@ -1,144 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -"""Shared runtime entry helpers for `ptoas` Python launchers. - -This module owns the common in-process ctypes launch contract. Thin entry -wrappers such as the wheel console entry and the build/install-tree wrapper -should resolve their own filesystem layouts, then delegate here for -environment setup and `ptoas_entrypoint` execution. -""" - -from __future__ import annotations - -import ctypes -import os -import sys -from dataclasses import dataclass -from pathlib import Path -from typing import MutableMapping, Sequence - - -@dataclass(frozen=True) -class PTOASRuntimeLayout: - wrapper: Path - runtime_root: Path - python_root: Path - shared_module: Path - tileops_dir: Path - isolated_env: bool - - -def _prepend_env_path(env: MutableMapping[str, str], name: str, value: Path) -> None: - if not value.exists(): - return - current = env.get(name, "") - rendered = str(value) - parts = [part for part in current.split(os.pathsep) if part] - if rendered in parts: - parts.remove(rendered) - parts.insert(0, rendered) - env[name] = os.pathsep.join(parts) - - -def _has_cli_option(argv: Sequence[str], option: str) -> bool: - option_with_value = f"{option}=" - for arg in argv: - if arg == option or arg.startswith(option_with_value): - return True - return False - - -def _iter_runtime_library_files(runtime_lib_dir: Path) -> list[Path]: - if not runtime_lib_dir.is_dir(): - return [] - - libraries: dict[Path, None] = {} - for pattern in ("*.so", "*.so.*", "*.dylib", "*.dylib.*"): - for candidate in sorted(runtime_lib_dir.glob(pattern)): - if candidate.is_file(): - libraries[candidate.resolve()] = None - return list(libraries) - - -def _preload_runtime_libraries(shared_module: Path, runtime_lib_dir: Path) -> None: - runtime_lib_dir = runtime_lib_dir.resolve() - if not runtime_lib_dir.is_dir(): - return - - shared_module = shared_module.resolve() - pending = [ - path for path in _iter_runtime_library_files(runtime_lib_dir) - if path != shared_module and path.name != shared_module.name - ] - if not pending: - return - - mode = getattr(ctypes, "RTLD_GLOBAL", 0) - last_error: OSError | None = None - while pending: - next_pending: list[Path] = [] - made_progress = False - for candidate in pending: - try: - ctypes.CDLL(str(candidate), mode=mode) - made_progress = True - except OSError as exc: - last_error = exc - next_pending.append(candidate) - if not next_pending: - return - if not made_progress: - if last_error is not None: - raise last_error - raise OSError(f"unable to preload runtime libraries from {runtime_lib_dir}") - pending = next_pending - - -def _load_shared_entrypoint(shared_module: Path, runtime_lib_dir: Path, *, preload_runtime_libraries: bool): - if preload_runtime_libraries: - _preload_runtime_libraries(shared_module, runtime_lib_dir) - library = ctypes.CDLL(str(shared_module), mode=getattr(ctypes, "RTLD_GLOBAL", 0)) - entrypoint = library.ptoas_entrypoint - entrypoint.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_char_p)] - entrypoint.restype = ctypes.c_int - return entrypoint - - -def launch(layout: PTOASRuntimeLayout, user_args: Sequence[str]) -> int: - env = os.environ - env["PTOAS_HOME"] = str(layout.runtime_root) - env["PTOAS_BIN"] = str(layout.wrapper) - env["PTOAS_TILEOPS_DIR"] = str(layout.tileops_dir) - env["PTOAS_PYTHON_EXE"] = sys.executable - - _prepend_env_path(env, "PATH", layout.wrapper.parent) - runtime_lib_dir = layout.runtime_root / "lib" - # Keep the wheel-owned packages and libraries first, while preserving - # host paths needed by injected runtimes such as CANN/MSProf. - _prepend_env_path(env, "PYTHONPATH", layout.python_root) - _prepend_env_path(env, "LD_LIBRARY_PATH", runtime_lib_dir) - _prepend_env_path(env, "DYLD_LIBRARY_PATH", runtime_lib_dir) - - argv = [str(layout.wrapper)] - if not _has_cli_option(user_args, "--tilelang-path"): - argv.extend(["--tilelang-path", str(layout.tileops_dir)]) - if not _has_cli_option(user_args, "--tilelang-pkg-path"): - argv.extend(["--tilelang-pkg-path", str(layout.python_root)]) - if not _has_cli_option(user_args, "--ptodsl-pkg-path"): - argv.extend(["--ptodsl-pkg-path", str(layout.python_root)]) - argv.extend(user_args) - - entrypoint = _load_shared_entrypoint( - layout.shared_module, - runtime_lib_dir, - preload_runtime_libraries=not layout.isolated_env, - ) - argv_bytes = [os.fsencode(arg) for arg in argv] - c_argv = (ctypes.c_char_p * len(argv_bytes))(*argv_bytes) - return int(entrypoint(len(argv_bytes), c_argv)) diff --git a/ptodsl/ptoas_wheel_bootstrap.py b/ptodsl/ptoas_wheel_bootstrap.py deleted file mode 100644 index d9da235a63..0000000000 --- a/ptodsl/ptoas_wheel_bootstrap.py +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -"""Shadow-safe wheel bootstrap for the `ptoas` console entry. - -The console script must not import `ptoas._launcher` directly because caller -environments may prepend unrelated `ptoas` packages via `PYTHONPATH`, editable -checkouts, or build-tree staging directories. This bootstrap has a unique -top-level module name, resolves the active wrapper's sibling site-packages -payload, then loads the wheel-owned `ptoas._runtime_entry` helper by file path. -""" - -from __future__ import annotations - -import importlib.util -import os -import shutil -import sys -import sysconfig -from pathlib import Path -from types import ModuleType -from typing import NoReturn - - -def _resolve_wrapper_path(argv0: str | None = None) -> Path: - candidate = argv0 if argv0 is not None else sys.argv[0] - wrapper = Path(candidate) - if wrapper.exists(): - return wrapper.resolve() - - found = shutil.which(wrapper.name or "ptoas") - if found: - return Path(found).resolve() - - raise SystemExit(f"unable to locate the installed ptoas wrapper: {candidate}") - - -def _unique_paths(paths: list[Path]) -> list[Path]: - unique: list[Path] = [] - seen: set[Path] = set() - for path in paths: - candidate = path.resolve() - if candidate in seen: - continue - seen.add(candidate) - unique.append(candidate) - return unique - - -def _prepend_env_path(env: dict[str, str], name: str, value: Path) -> None: - if not value.exists(): - return - rendered = str(value.resolve()) - parts = [part for part in env.get(name, "").split(os.pathsep) if part] - if rendered in parts: - parts.remove(rendered) - parts.insert(0, rendered) - env[name] = os.pathsep.join(parts) - - -def _candidate_wheel_python_roots(wrapper: Path, module_file: str | None = None) -> list[Path]: - candidates: list[Path] = [] - - if module_file: - candidates.append(Path(module_file).resolve().parent) - - for scheme_name in ("purelib", "platlib"): - scheme_path = sysconfig.get_path(scheme_name) - if scheme_path: - candidates.append(Path(scheme_path)) - - if len(wrapper.parents) >= 2: - prefix = wrapper.parents[1] - py_version = f"python{sys.version_info.major}.{sys.version_info.minor}" - candidates.extend( - [ - prefix / "lib" / py_version / "site-packages", - prefix / "lib" / py_version / "dist-packages", - prefix / "lib64" / py_version / "site-packages", - prefix / "Lib" / "site-packages", - ] - ) - - return _unique_paths(candidates) - - -def _resolve_wheel_python_root(wrapper: Path, module_file: str | None = None) -> tuple[Path, Path]: - searched: list[str] = [] - for python_root in _candidate_wheel_python_roots(wrapper, module_file): - package_root = python_root / "ptoas" - runtime_entry = package_root / "_runtime_entry.py" - runtime_root = package_root / "_runtime" - searched.append(str(package_root)) - if runtime_entry.is_file() and runtime_root.is_dir(): - return python_root, package_root - - rendered = ", ".join(searched) if searched else "" - raise SystemExit( - "unable to locate the wheel-installed ptoas package next to the active wrapper; " - "expected /ptoas/_runtime_entry.py and /ptoas/_runtime. " - f"Searched: {rendered}. This usually means an external PYTHONPATH is shadowing the installed wheel." - ) - - -def _resolve_wheel_layout(runtime_entry: ModuleType, package_root: Path, wrapper: Path): - package_root = package_root.resolve() - wrapper = wrapper.resolve() - runtime_root = package_root / "_runtime" - if not runtime_root.is_dir(): - raise SystemExit( - "wheel-installed ptoas is missing the packaged runtime root: " - "expected ptoas/_runtime" - ) - - shared_module = runtime_root / "lib" / "ptoas.so" - if not shared_module.is_file() or shared_module.stat().st_size <= 0: - raise SystemExit( - "wheel-installed ptoas is missing the packaged shared module: " - "expected ptoas/_runtime/lib/ptoas.so" - ) - - tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" - if not tileops_dir.is_dir(): - raise SystemExit( - "wheel-installed ptoas is missing the packaged TileOps directory: " - "expected ptoas/_runtime/share/ptoas/TileOps" - ) - - return runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper, - runtime_root=runtime_root.resolve(), - python_root=package_root.parent.resolve(), - shared_module=shared_module.resolve(), - tileops_dir=tileops_dir.resolve(), - isolated_env=True, - ) - - -def _load_runtime_entry(python_root: Path, package_root: Path) -> ModuleType: - python_root_text = str(python_root) - if python_root_text in sys.path: - sys.path.remove(python_root_text) - sys.path.insert(0, python_root_text) - - runtime_entry_path = package_root / "_runtime_entry.py" - module_name = "_ptoas_wheel_runtime_entry" - spec = importlib.util.spec_from_file_location(module_name, runtime_entry_path) - if spec is None or spec.loader is None: - raise SystemExit(f"unable to load ptoas runtime entry helper from {runtime_entry_path}") - module = importlib.util.module_from_spec(spec) - sys.modules[module_name] = module - spec.loader.exec_module(module) - return module - - -def _prepare_stage2_env(python_root: Path, package_root: Path) -> dict[str, str]: - runtime_lib_dir = package_root / "_runtime" / "lib" - env = os.environ.copy() - env["PTOAS_WHEEL_STAGE2"] = "1" - # Put wheel paths first without discarding host paths required by native - # integrations such as CANN/MSProf. - _prepend_env_path(env, "PYTHONPATH", python_root) - _prepend_env_path(env, "LD_LIBRARY_PATH", runtime_lib_dir) - _prepend_env_path(env, "DYLD_LIBRARY_PATH", runtime_lib_dir) - return env - - -def _maybe_reexec_isolated_process(wrapper: Path, python_root: Path, package_root: Path) -> None: - if os.environ.get("PTOAS_WHEEL_STAGE2") == "1": - return - env = _prepare_stage2_env(python_root, package_root) - os.execve(str(wrapper), [str(wrapper), *sys.argv[1:]], env) - - -def main() -> NoReturn: - wrapper = _resolve_wrapper_path() - python_root, package_root = _resolve_wheel_python_root(wrapper, __file__) - _maybe_reexec_isolated_process(wrapper, python_root, package_root) - runtime_entry = _load_runtime_entry(python_root, package_root) - layout = _resolve_wheel_layout(runtime_entry, package_root, wrapper) - raise SystemExit(runtime_entry.launch(layout, sys.argv[1:])) - - -if __name__ == "__main__": - main() diff --git a/ptodsl/ptodsl/_allreduce.py b/ptodsl/ptodsl/_allreduce.py index 4d14b540c0..24080cb72d 100644 --- a/ptodsl/ptodsl/_allreduce.py +++ b/ptodsl/ptodsl/_allreduce.py @@ -28,8 +28,8 @@ from ._surface_values import unwrap_surface_value from ._types import _resolve, float16 as _f16_dtype, float32 as _f32_dtype, si32 as _si32_dtype, ui32 as _ui32_dtype -from mlir.dialects import pto as _pto -from mlir.ir import F16Type, F32Type, IntegerType +from ptoas.mlir.dialects import pto as _pto +from ptoas.mlir.ir import F16Type, F32Type, IntegerType # ── helpers ──────────────────────────────────────────────────────────────────── diff --git a/ptodsl/ptodsl/_bootstrap.py b/ptodsl/ptodsl/_bootstrap.py deleted file mode 100644 index 86d8954d48..0000000000 --- a/ptodsl/ptodsl/_bootstrap.py +++ /dev/null @@ -1,145 +0,0 @@ -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. -""" -MLIR path bootstrap and context factory. - -Discovers local LLVM MLIR Python bindings plus PTO Python dialect artifacts so -that ``ptodsl`` can import ``mlir`` / ``mlir.dialects.pto`` directly from a -developer workspace without requiring the caller to pre-seed ``PYTHONPATH``. -When the current interpreter already has a complete installed MLIR/PTO stack, -leave ``sys.path`` untouched so wheel installs do not accidentally mix in a -developer checkout from environment variables or nearby directories. -""" - -import importlib.util -import os -import sys -from pathlib import Path - - -def _path_has(path: Path, relative: str) -> bool: - try: - return (path / relative).exists() - except OSError: - return False - - -def _pythonpath_already_provides_mlir_and_pto() -> bool: - """Return true when the caller has already configured compatible MLIR/PTO roots. - - Lit preserves ``PYTHONPATH`` but not the convenience environment variables - used by ``ptoas_env.sh``. In that case we should not prepend repository - default fallbacks like ``build/python`` / ``install`` because they may belong - to an older build tree and can mix Python/native MLIR bindings. - """ - has_mlir_core = False - has_pto_dialect = False - for entry in sys.path: - if not entry: - continue - path = Path(entry) - has_mlir_core = has_mlir_core or _path_has(path, "mlir/ir.py") - has_pto_dialect = has_pto_dialect or _path_has( - path, "mlir/dialects/pto.py" - ) - if has_mlir_core and has_pto_dialect: - return True - return False - - -def _candidate_python_roots() -> list[Path]: - here = Path(__file__).resolve() - repo_root = here.parents[2] - owner_root = repo_root.parent - github_root = owner_root.parent - env_roots = [] - has_explicit_pto_root = False - for env_name in ( - "MLIR_PYTHON_ROOT", - "PTO_PYTHON_BUILD_ROOT", - "PTO_PYTHON_ROOT", - "PTO_INSTALL_DIR", - ): - raw = os.environ.get(env_name) - if raw: - env_roots.append(Path(raw)) - if env_name != "MLIR_PYTHON_ROOT": - has_explicit_pto_root = True - - if not env_roots and _pythonpath_already_provides_mlir_and_pto(): - return [] - - fallback_roots = [ - github_root / "llvm" / "llvm-project" / "build" / "tools" / "mlir" / "python_packages" / "mlir_core", - github_root / "llvm" / "llvm-project" / "install" / "python_packages" / "mlir_core", - github_root / "llvm" / "llvm-project" / "build-shared" / "tools" / "mlir" / "python_packages" / "mlir_core", - ] - if not has_explicit_pto_root: - fallback_roots = [ - repo_root / "build" / "python", - repo_root / "install", - *fallback_roots, - ] - - return [ - *env_roots, - *fallback_roots, - ] - - -def _bootstrap_python_paths() -> None: - ordered_roots: list[str] = [] - seen = set() - for root in _candidate_python_roots(): - if not root or not root.is_dir(): - continue - if not (root / "mlir").exists(): - continue - root_text = str(root) - if root_text in seen: - continue - ordered_roots.append(root_text) - seen.add(root_text) - for root_text in reversed(ordered_roots): - if root_text in sys.path: - sys.path.remove(root_text) - sys.path.insert(0, root_text) - - -def _can_import_active_python_mlir() -> bool: - required_modules = ("mlir.ir", "mlir.dialects.pto") - for module_name in required_modules: - try: - if importlib.util.find_spec(module_name) is None: - return False - except (ImportError, ValueError, ModuleNotFoundError): - return False - return True - - -if not _can_import_active_python_mlir(): - _bootstrap_python_paths() - -from mlir.dialects import pto as _pto_dialect # noqa: E402 -try: - from mlir.dialects import llvm as _llvm_dialect # noqa: E402 -except Exception: # pragma: no cover - depends on the installed MLIR package. - _llvm_dialect = None -from mlir.ir import Context, Location # noqa: E402 - - -def make_context() -> Context: - """Create a fresh MLIR Context with the PTO dialect loaded.""" - ctx = Context() - _pto_dialect.register_dialect(ctx, load=True) - if _llvm_dialect is not None and hasattr(_llvm_dialect, "register_dialect"): - _llvm_dialect.register_dialect(ctx, load=True) - return ctx - - -__all__ = ["make_context"] diff --git a/ptodsl/ptodsl/_builtin_vector.py b/ptodsl/ptodsl/_builtin_vector.py index 6daf049a8d..d1cfa5bac2 100644 --- a/ptodsl/ptodsl/_builtin_vector.py +++ b/ptodsl/ptodsl/_builtin_vector.py @@ -7,14 +7,13 @@ # See LICENSE in the root of the software repository for the full text of the License. """Builtin MLIR vector helpers for PTODSL scalar-contiguous access.""" -from ._bootstrap import make_context # ensure MLIR is on sys.path # noqa: F401 from ._scalar_coercion import coerce_scalar_to_type from ._surface_values import VecValue, unwrap_surface_value from ._types import _resolve, _validate_vec_size, vec_type -from mlir.dialects import arith -from mlir.dialects import llvm -from mlir.ir import IntegerType, VectorType +from ptoas.mlir.dialects import arith +from ptoas.mlir.dialects import llvm +from ptoas.mlir.ir import IntegerType, VectorType def Vec(dtype, size: int, *, init=None): diff --git a/ptodsl/ptodsl/_context.py b/ptodsl/ptodsl/_context.py new file mode 100644 index 0000000000..a3f2fd7be4 --- /dev/null +++ b/ptodsl/ptodsl/_context.py @@ -0,0 +1,30 @@ +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +"""MLIR context construction for an installed or explicitly configured PTODSL.""" + +from ptoas.mlir.dialects import pto as _pto_dialect + +try: + from ptoas.mlir.dialects import llvm as _llvm_dialect +except Exception: # pragma: no cover - depends on the installed MLIR package. + _llvm_dialect = None + +from ptoas.mlir.ir import Context + + +def make_context() -> Context: + """Create a fresh MLIR context with the PTO dialect loaded.""" + ctx = Context() + _pto_dialect.register_dialect(ctx, load=True) + if _llvm_dialect is not None and hasattr(_llvm_dialect, "register_dialect"): + _llvm_dialect.register_dialect(ctx, load=True) + return ctx + + +__all__ = ["make_context"] diff --git a/ptodsl/ptodsl/_control_flow.py b/ptodsl/ptodsl/_control_flow.py index 55f389840c..33d862deb8 100644 --- a/ptodsl/ptodsl/_control_flow.py +++ b/ptodsl/ptodsl/_control_flow.py @@ -21,7 +21,6 @@ ``const_expr(value)`` – trace-time ``if`` escape hatch for AST rewrite """ -from ._bootstrap import make_context # noqa: F401 from ._diagnostics import explicit_mode_required_with_context_error from ._runtime_index_ops import coerce_runtime_index from ._scalar_coercion import coerce_scalar_to_type @@ -29,8 +28,8 @@ from ._tracing.active import current_session from ._surface_values import unwrap_surface_value, wrap_like_surface_value, wrap_surface_value -from mlir.dialects import pto as _pto, scf -from mlir.ir import InsertionPoint +from ptoas.mlir.dialects import pto as _pto, scf +from ptoas.mlir.ir import InsertionPoint # ── vecscope ────────────────────────────────────────────────────────────────── diff --git a/ptodsl/ptodsl/_jit.py b/ptodsl/ptodsl/_jit.py index 26fb8311e5..f90f7809ac 100644 --- a/ptodsl/ptodsl/_jit.py +++ b/ptodsl/ptodsl/_jit.py @@ -28,7 +28,7 @@ current_runtime, ) -from mlir.ir import InsertionPoint +from ptoas.mlir.ir import InsertionPoint _MODULE_ATTRS = ("pto.target_arch",) diff --git a/ptodsl/ptodsl/_ops.py b/ptodsl/ptodsl/_ops.py index c3349f5459..403d3c8ef9 100644 --- a/ptodsl/ptodsl/_ops.py +++ b/ptodsl/ptodsl/_ops.py @@ -24,7 +24,6 @@ from functools import wraps -from ._bootstrap import make_context # noqa: F401 – ensure MLIR on sys.path from ._diagnostics import ( explicit_mode_required_with_context_error, make_tensor_view_invalid_layout_error, @@ -73,8 +72,8 @@ vreg_type, ) -from mlir.dialects import arith, pto as _pto -from mlir.ir import ( +from ptoas.mlir.dialects import arith, pto as _pto +from ptoas.mlir.ir import ( Attribute, BF16Type, F16Type, @@ -236,7 +235,7 @@ def const(value: int, *, dtype=None): """ Emit an ``arith.constant``. - ``dtype`` is a ``_DType`` descriptor or a concrete ``mlir.ir.Type``. + ``dtype`` is a ``_DType`` descriptor or a concrete ``ptoas.mlir.ir.Type``. Defaults to ``index`` when omitted. """ from ._types import index as _idx_dtype diff --git a/ptodsl/ptodsl/_runtime/codegen.py b/ptodsl/ptodsl/_runtime/codegen.py index ba93106c25..f0fa1a4e83 100644 --- a/ptodsl/ptodsl/_runtime/codegen.py +++ b/ptodsl/ptodsl/_runtime/codegen.py @@ -9,8 +9,8 @@ from __future__ import annotations -from .._bootstrap import make_context -from mlir.ir import BF16Type, F16Type, F32Type, IndexType, IntegerType +from .._context import make_context +from ptoas.mlir.ir import BF16Type, F16Type, F32Type, IndexType, IntegerType from .._kernel_signature import DeviceParameterSpec, RuntimeScalarParameterSpec from .._types import _PtrDescriptor, _resolve diff --git a/ptodsl/ptodsl/_runtime/launch.py b/ptodsl/ptodsl/_runtime/launch.py index 5780fe1a93..d6e5c26402 100644 --- a/ptodsl/ptodsl/_runtime/launch.py +++ b/ptodsl/ptodsl/_runtime/launch.py @@ -16,7 +16,7 @@ from .._types import _resolve from .native_build import build_native_library -from mlir.ir import BF16Type, Context, F16Type, F32Type, IndexType, IntegerType +from ptoas.mlir.ir import BF16Type, Context, F16Type, F32Type, IndexType, IntegerType if TYPE_CHECKING: from .._kernel_compilation import CompiledKernelHandle diff --git a/ptodsl/ptodsl/_runtime/toolchain.py b/ptodsl/ptodsl/_runtime/toolchain.py index b41ef53a54..5e774a14de 100644 --- a/ptodsl/ptodsl/_runtime/toolchain.py +++ b/ptodsl/ptodsl/_runtime/toolchain.py @@ -27,36 +27,12 @@ def resolve_ptoas_binary() -> Path: f"PTOAS_BIN is set but does not resolve to an existing executable: {env_override}" ) - for var in ("PTO_BUILD_DIR", "PTO_INSTALL_DIR"): - if var in os.environ: - cand = Path(os.environ[var]) / "tools" / "ptoas" / "ptoas" - if cand.is_file(): - return cand - cand2 = Path(os.environ[var]) / "bin" / "ptoas" - if cand2.is_file(): - return cand2 - - repo_root = Path(__file__).resolve().parents[4] - candidates = [ - repo_root / "build" / "tools" / "ptoas" / "ptoas", - repo_root / "install" / "bin" / "ptoas", - ] - for candidate in candidates: - if candidate.is_file(): - return candidate - - for start in [Path.cwd()] + list(Path.cwd().parents): - for pattern in [start / "build" / "tools" / "ptoas" / "ptoas", - start / "install" / "bin" / "ptoas"]: - if pattern.is_file(): - return pattern - from_path = shutil.which("ptoas") if from_path: return Path(from_path) raise FileNotFoundError( - "unable to locate ptoas; build ptoas or add it to PATH after sourcing scripts/ptoas_env.sh" + "unable to locate ptoas; install it, add it to PATH, or set PTOAS_BIN" ) diff --git a/ptodsl/ptodsl/_runtime_scalar_ops.py b/ptodsl/ptodsl/_runtime_scalar_ops.py index fa0acf0a7b..0fef5843a1 100644 --- a/ptodsl/ptodsl/_runtime_scalar_ops.py +++ b/ptodsl/ptodsl/_runtime_scalar_ops.py @@ -19,8 +19,8 @@ _strip_integer_signedness, ) -from mlir.dialects import arith, math -from mlir.ir import IndexType, IntegerType +from ptoas.mlir.dialects import arith, math +from ptoas.mlir.ir import IndexType, IntegerType _FLOAT_BINARY_OPS = { diff --git a/ptodsl/ptodsl/_scalar_adaptation.py b/ptodsl/ptodsl/_scalar_adaptation.py index faa1fdb8b4..4457c693db 100644 --- a/ptodsl/ptodsl/_scalar_adaptation.py +++ b/ptodsl/ptodsl/_scalar_adaptation.py @@ -17,8 +17,8 @@ _strip_integer_signedness, ) -from mlir.dialects import arith -from mlir.ir import BF16Type, F16Type, F32Type, FloatAttr, IndexType, IntegerType, VectorType +from ptoas.mlir.dialects import arith +from ptoas.mlir.ir import BF16Type, F16Type, F32Type, FloatAttr, IndexType, IntegerType, VectorType def classify_runtime_scalar_type(type_obj): diff --git a/ptodsl/ptodsl/_source_loader.py b/ptodsl/ptodsl/_source_loader.py index b936937ddf..1603d0fc0f 100644 --- a/ptodsl/ptodsl/_source_loader.py +++ b/ptodsl/ptodsl/_source_loader.py @@ -13,14 +13,14 @@ from dataclasses import dataclass from pathlib import Path -from ._bootstrap import make_context +from ._context import make_context from ._diagnostics import ( jit_source_abi_error, jit_source_entry_error, jit_source_file_error, ) -from mlir.ir import Location, Module +from ptoas.mlir.ir import Location, Module @dataclass(frozen=True) diff --git a/ptodsl/ptodsl/_surface_types.py b/ptodsl/ptodsl/_surface_types.py index 7a79fcded1..0074c10e62 100644 --- a/ptodsl/ptodsl/_surface_types.py +++ b/ptodsl/ptodsl/_surface_types.py @@ -9,9 +9,7 @@ from enum import Enum -from ._bootstrap import make_context # noqa: F401 - -from mlir.dialects import pto as _pto +from ptoas.mlir.dialects import pto as _pto class _ConstExprHelper: diff --git a/ptodsl/ptodsl/_surface_values.py b/ptodsl/ptodsl/_surface_values.py index d541e776de..d8fa1fb0e3 100644 --- a/ptodsl/ptodsl/_surface_values.py +++ b/ptodsl/ptodsl/_surface_values.py @@ -22,10 +22,10 @@ from ._surface_types import PartitionTensorView, TensorView, Tile from ._types import _normalize_address_space, _resolve, ptr -from mlir.dialects import arith -from mlir.dialects import memref -from mlir.dialects import pto as _pto -from mlir.ir import IndexType, IntegerAttr, IntegerType, MemRefType, ShapedType, StridedLayoutAttr, Type, VectorType +from ptoas.mlir.dialects import arith +from ptoas.mlir.dialects import memref +from ptoas.mlir.dialects import pto as _pto +from ptoas.mlir.ir import IndexType, IntegerAttr, IntegerType, MemRefType, ShapedType, StridedLayoutAttr, Type, VectorType def _validate_surface_value_access(value): diff --git a/ptodsl/ptodsl/_tile_template_tracing.py b/ptodsl/ptodsl/_tile_template_tracing.py index 571239717d..ea10cf2582 100644 --- a/ptodsl/ptodsl/_tile_template_tracing.py +++ b/ptodsl/ptodsl/_tile_template_tracing.py @@ -58,8 +58,8 @@ vreg_type as _vreg_type, ) -from mlir.dialects import arith, pto as _pto, scf -from mlir.ir import InsertionPoint, IntegerType, Type +from ptoas.mlir.dialects import arith, pto as _pto, scf +from ptoas.mlir.ir import InsertionPoint, IntegerType, Type @dataclass(frozen=True) diff --git a/ptodsl/ptodsl/_tracing/artifacts.py b/ptodsl/ptodsl/_tracing/artifacts.py index 5dc51e3feb..975efe05b4 100644 --- a/ptodsl/ptodsl/_tracing/artifacts.py +++ b/ptodsl/ptodsl/_tracing/artifacts.py @@ -27,7 +27,7 @@ def __init__(self, py_name: str, *, module=None, module_factory=None, mlir_text: self._build_metadata = {} def build(self): - """Return the cached ``mlir.ir.Module``.""" + """Return the cached ``ptoas.mlir.ir.Module``.""" if self._cached_module is None: if self._module_factory is None: raise RuntimeError(f"{self._py_name} has no module factory") @@ -43,7 +43,7 @@ def build(self): return self._cached_module def mlir_module(self): - """Return the cached ``mlir.ir.Module``.""" + """Return the cached ``ptoas.mlir.ir.Module``.""" return self.build() def mlir_text(self) -> str: diff --git a/ptodsl/ptodsl/_tracing/control_flow.py b/ptodsl/ptodsl/_tracing/control_flow.py index 60a2c4ec84..f878e9198e 100644 --- a/ptodsl/ptodsl/_tracing/control_flow.py +++ b/ptodsl/ptodsl/_tracing/control_flow.py @@ -14,9 +14,9 @@ from .._runtime_index_ops import coerce_runtime_index from .._surface_values import unwrap_surface_value -from mlir.dialects import arith -from mlir.dialects import scf -from mlir.ir import InsertionPoint, IntegerType +from ptoas.mlir.dialects import arith +from ptoas.mlir.dialects import scf +from ptoas.mlir.ir import InsertionPoint, IntegerType @dataclass diff --git a/ptodsl/ptodsl/_tracing/module_builder.py b/ptodsl/ptodsl/_tracing/module_builder.py index e5fb99859a..9894ceb62e 100644 --- a/ptodsl/ptodsl/_tracing/module_builder.py +++ b/ptodsl/ptodsl/_tracing/module_builder.py @@ -12,8 +12,8 @@ from dataclasses import dataclass from enum import Enum -from mlir.dialects import func -from mlir.ir import Attribute, InsertionPoint, Module, Operation, StringAttr, UnitAttr +from ptoas.mlir.dialects import func +from ptoas.mlir.ir import Attribute, InsertionPoint, Module, Operation, StringAttr, UnitAttr class ModuleStyle(str, Enum): diff --git a/ptodsl/ptodsl/_tracing/runtime.py b/ptodsl/ptodsl/_tracing/runtime.py index e876c25f05..d9172d95e2 100644 --- a/ptodsl/ptodsl/_tracing/runtime.py +++ b/ptodsl/ptodsl/_tracing/runtime.py @@ -13,11 +13,11 @@ from .module_builder import create_kernel_module from .session import TraceSession from .._diagnostics import kernel_module_return_value_error -from .._bootstrap import make_context +from .._context import make_context from .._types import _resolve -from mlir.dialects import func -from mlir.ir import InsertionPoint, Location +from ptoas.mlir.dialects import func +from ptoas.mlir.ir import InsertionPoint, Location class TracingRuntime: diff --git a/ptodsl/ptodsl/_tracing/session.py b/ptodsl/ptodsl/_tracing/session.py index 617fc05578..e5aa3a2ca0 100644 --- a/ptodsl/ptodsl/_tracing/session.py +++ b/ptodsl/ptodsl/_tracing/session.py @@ -36,9 +36,9 @@ from .._types import _strip_integer_signedness from .module_builder import create_container_child_module -from mlir.dialects import arith, func -from mlir.dialects import pto as _pto -from mlir.ir import ( +from ptoas.mlir.dialects import arith, func +from ptoas.mlir.dialects import pto as _pto +from ptoas.mlir.ir import ( Attribute, FlatSymbolRefAttr, IndexType, diff --git a/ptodsl/ptodsl/_types.py b/ptodsl/ptodsl/_types.py index 269769b56e..4cec4393cd 100644 --- a/ptodsl/ptodsl/_types.py +++ b/ptodsl/ptodsl/_types.py @@ -9,7 +9,7 @@ Lazy MLIR type descriptors and eager type constructors. Type descriptors (``_DType`` subclasses) can be created *before* any MLIR -Context exists – they only resolve to concrete ``mlir.ir.Type`` objects when +Context exists – they only resolve to concrete ``ptoas.mlir.ir.Type`` objects when ``_resolve()`` is called inside an active context. This lets users write:: def softmax(arg0: pto.ptr(pto.float32, "GM"), ...): @@ -19,12 +19,10 @@ def softmax(arg0: pto.ptr(pto.float32, "GM"), ...): the actual type is materialised later by the ``@pto.jit`` decorator. """ -from ._bootstrap import make_context # ensure MLIR is on sys.path - -from mlir.dialects import pto as _pto -from mlir.dialects import arith -from mlir.dialects.builtin import UnrealizedConversionCastOp -from mlir.ir import ( +from ptoas.mlir.dialects import pto as _pto +from ptoas.mlir.dialects import arith +from ptoas.mlir.dialects.builtin import UnrealizedConversionCastOp +from ptoas.mlir.ir import ( BF16Type, F16Type, F32Type, @@ -218,10 +216,10 @@ def _validate_vec_size(size: int, *, context: str) -> int: def _resolve(dtype) -> Type: - """Coerce a ``_DType`` descriptor or a concrete ``mlir.ir.Type`` to a Type.""" + """Coerce a ``_DType`` descriptor or a concrete ``ptoas.mlir.ir.Type`` to a Type.""" if isinstance(dtype, _DType): return dtype.resolve() - return dtype # already an mlir.ir.Type + return dtype # already a ptoas.mlir.ir.Type def _classify_scalar_type(type_obj): diff --git a/ptodsl/ptodsl/_vmi_namespace.py b/ptodsl/ptodsl/_vmi_namespace.py index b22287b23c..aef05c8d82 100644 --- a/ptodsl/ptodsl/_vmi_namespace.py +++ b/ptodsl/ptodsl/_vmi_namespace.py @@ -11,8 +11,8 @@ from collections.abc import Sequence -from mlir.dialects import pto as _pto -from mlir.ir import BF16Type, F16Type, F32Type, Float8E4M3FNType, Float8E5M2Type, IntegerType, MemRefType +from ptoas.mlir.dialects import pto as _pto +from ptoas.mlir.ir import BF16Type, F16Type, F32Type, Float8E4M3FNType, Float8E5M2Type, IntegerType, MemRefType from ._scalar_coercion import coerce_scalar_to_type from ._surface_values import _coerce_index_value, _try_get_constant_index, unwrap_surface_value, wrap_surface_value diff --git a/ptodsl/ptodsl/pto.py b/ptodsl/ptodsl/pto.py index 9c6279d7c7..c9a3156edf 100644 --- a/ptodsl/ptodsl/pto.py +++ b/ptodsl/ptodsl/pto.py @@ -17,7 +17,7 @@ from ptodsl import pto All user-facing symbols live here. Low-level MLIR bindings are accessed -internally as ``_pto`` (``from mlir.dialects import pto as _pto``). +internally as ``_pto`` (``from ptoas.mlir.dialects import pto as _pto``). """ from ._diagnostics import unsupported_public_surface_error diff --git a/ptodsl/ptodsl/scalar.py b/ptodsl/ptodsl/scalar.py index 10b2d3f58e..a646fe728f 100644 --- a/ptodsl/ptodsl/scalar.py +++ b/ptodsl/ptodsl/scalar.py @@ -9,13 +9,12 @@ Scalar arithmetic helpers – exposed as top-level ``scalar.*`` from the ``ptodsl`` package (for example ``from ptodsl import scalar``). -Arithmetic helpers operate on raw ``mlir.ir.Value`` objects and emit the +Arithmetic helpers operate on raw ``ptoas.mlir.ir.Value`` objects and emit the corresponding arith dialect operations at the active insertion point. Scalar memory helpers (`load` / `store`) also accept PTODSL surface-level address views such as `tile[row, col]` and `tile.as_ptr() + offset`. """ -from ._bootstrap import make_context # ensure MLIR is on sys.path # noqa: F401 from ._scalar_coercion import coerce_scalar_to_type from ._scalar_adaptation import classify_runtime_scalar_type from ._runtime_scalar_ops import ( @@ -34,11 +33,11 @@ ) from ._types import _resolve -from mlir.dialects import arith -from mlir.dialects import llvm -from mlir.dialects import math -from mlir.ir import IndexType, IntegerType, MemRefType, Operation, VectorType -from mlir.dialects import pto as _pto +from ptoas.mlir.dialects import arith +from ptoas.mlir.dialects import llvm +from ptoas.mlir.dialects import math +from ptoas.mlir.ir import IndexType, IntegerType, MemRefType, Operation, VectorType +from ptoas.mlir.dialects import pto as _pto def muli(lhs, rhs): diff --git a/ptodsl/ptodsl/tilelib/_render_runtime.py b/ptodsl/ptodsl/tilelib/_render_runtime.py index fc9bd8aa8e..3aa6fed25b 100644 --- a/ptodsl/ptodsl/tilelib/_render_runtime.py +++ b/ptodsl/ptodsl/tilelib/_render_runtime.py @@ -28,7 +28,7 @@ from .metadata import ScalarSpec, TileSpec, VectorSpec, ViewSpec, scalar_descriptor from .._ast_rewrite import rewrite_jit_function -from .._bootstrap import make_context +from .._context import make_context from .._surface_types import Tile from .._surface_values import PartitionTensorViewValue, TensorViewValue, TileValue from .._tracing import KernelModuleSpec, ModuleStyle, TracingRuntime @@ -36,8 +36,8 @@ from .._surface_values import wrap_surface_value from .._types import _DType, _resolve -from mlir.dialects import func -from mlir.ir import Attribute, InsertionPoint, Location, Module, StringAttr, UnitAttr +from ptoas.mlir.dialects import func +from ptoas.mlir.ir import Attribute, InsertionPoint, Location, Module, StringAttr, UnitAttr # ── tile handle handed to the template body ──────────────────────────────────────── diff --git a/ptodsl/ptodsl/tilelib/metadata.py b/ptodsl/ptodsl/tilelib/metadata.py index 9ebaef8877..94ed62903b 100644 --- a/ptodsl/ptodsl/tilelib/metadata.py +++ b/ptodsl/ptodsl/tilelib/metadata.py @@ -40,7 +40,7 @@ _resolve, ) -from mlir.ir import Type +from ptoas.mlir.ir import Type @dataclass(frozen=True) diff --git a/ptodsl/ptodsl/tilelib/templates/a5/tcvt.py b/ptodsl/ptodsl/tilelib/templates/a5/tcvt.py index 17f65cc02d..e54a360d79 100644 --- a/ptodsl/ptodsl/tilelib/templates/a5/tcvt.py +++ b/ptodsl/ptodsl/tilelib/templates/a5/tcvt.py @@ -10,7 +10,7 @@ from ptodsl import pto from ptodsl._surface_values import unwrap_surface_value, wrap_surface_value import ptodsl.tilelib as tilelib -from mlir.dialects import pto as _pto +from ptoas.mlir.dialects import pto as _pto def _rowwise(src_shape, src_valid_shape, dst_shape, dst_valid_shape, src_config, dst_config, **_): diff --git a/ptodsl/tests/CMakeLists.txt b/ptodsl/tests/CMakeLists.txt index 3f4542216f..1bbb4076d2 100644 --- a/ptodsl/tests/CMakeLists.txt +++ b/ptodsl/tests/CMakeLists.txt @@ -7,18 +7,15 @@ # See LICENSE in the root of the software repository for the full text of the License. if(NOT DEFINED _pto_python_test_env) - get_filename_component(_llvm_root "${LLVM_DIR}/../../.." ABSOLUTE) get_filename_component(_pto_python_bin_dir "${Python3_EXECUTABLE}" DIRECTORY) set(_ptodsl_test_pythonpath - "${CMAKE_BINARY_DIR}/python:${MLIR_PYTHON_PACKAGE_DIR}:${CMAKE_INSTALL_PREFIX}:$ENV{PYTHONPATH}" + "${CMAKE_BINARY_DIR}/python:$ENV{PYTHONPATH}" ) - if(DEFINED ENV{PTO_INSTALL_DIR} AND NOT "$ENV{PTO_INSTALL_DIR}" STREQUAL "") - set(_ptodsl_test_pythonpath "$ENV{PTO_INSTALL_DIR}:${_ptodsl_test_pythonpath}") - endif() set(_pto_python_test_env "PYTHONPATH=${_ptodsl_test_pythonpath}" - "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${_llvm_root}/lib:${CMAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}" + "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${LLVM_BUILD_LIBRARY_DIR}:${CMAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}" "PATH=${CMAKE_BINARY_DIR}/tools/ptoas:${CMAKE_INSTALL_PREFIX}/bin:${_pto_python_bin_dir}:$ENV{PATH}" + "PTOAS_BIN=${CMAKE_BINARY_DIR}/tools/ptoas/ptoas" ) endif() @@ -59,7 +56,7 @@ endforeach() if(NOT TARGET check-dsl) set(_ptodsl_check_depends) - foreach(_target IN ITEMS PTODSLPackage PTOPythonModules ptoas_runtime_deps) + foreach(_target IN ITEMS PTODSLPackage PTOAS_Python ptoas_runtime_deps) if(TARGET ${_target}) list(APPEND _ptodsl_check_depends ${_target}) endif() diff --git a/ptodsl/tests/support/docs_fragment_fixtures.py b/ptodsl/tests/support/docs_fragment_fixtures.py index 9aed2ff2ea..85ad735759 100644 --- a/ptodsl/tests/support/docs_fragment_fixtures.py +++ b/ptodsl/tests/support/docs_fragment_fixtures.py @@ -2111,8 +2111,8 @@ def pipe_communication_c2v_local_declaration_probe(): ), "pipe_communication.c2v_local_import": _fixture( f""" - from mlir.dialects import func - from mlir.ir import InsertionPoint + from ptoas.mlir.dialects import func + from ptoas.mlir.ir import InsertionPoint from ptodsl._tracing import current_session @@ -2135,8 +2135,8 @@ def pipe_communication_c2v_local_import_probe(): ), "pipe_communication.c2v_local_producer": _fixture( f""" - from mlir.dialects import func - from mlir.ir import InsertionPoint + from ptoas.mlir.dialects import func + from ptoas.mlir.ir import InsertionPoint from ptodsl._tracing import current_session diff --git a/ptodsl/tests/test_allreduce.py b/ptodsl/tests/test_allreduce.py index 533ba62750..78bac49288 100644 --- a/ptodsl/tests/test_allreduce.py +++ b/ptodsl/tests/test_allreduce.py @@ -7,11 +7,6 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from pathlib import Path -import sys - -sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "ptodsl")) - from ptodsl import pto diff --git a/ptodsl/tests/test_ast_rewrite_example_ir.py b/ptodsl/tests/test_ast_rewrite_example_ir.py index e30a094eaf..b8e3de51b9 100644 --- a/ptodsl/tests/test_ast_rewrite_example_ir.py +++ b/ptodsl/tests/test_ast_rewrite_example_ir.py @@ -14,8 +14,8 @@ REPO_ROOT = Path(__file__).resolve().parents[2] from ptodsl import pto -from ptodsl._bootstrap import make_context -from mlir.ir import Module +from ptodsl._context import make_context +from ptoas.mlir.ir import Module def expect(condition: bool, message: str) -> None: diff --git a/ptodsl/tests/test_bootstrap_runtime_env.py b/ptodsl/tests/test_bootstrap_runtime_env.py deleted file mode 100644 index ffcf1f9eb2..0000000000 --- a/ptodsl/tests/test_bootstrap_runtime_env.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import importlib.util -import sys -import types -import unittest -from pathlib import Path -from unittest import mock - - -class BootstrapRuntimeEnvTests(unittest.TestCase): - def test_bootstrap_keeps_installed_mlir_environment_unchanged(self): - repo_root = Path(__file__).resolve().parents[2] - bootstrap_path = repo_root / "ptodsl" / "ptodsl" / "_bootstrap.py" - module_name = "_test_ptodsl_bootstrap_runtime_env" - spec = importlib.util.spec_from_file_location(module_name, bootstrap_path) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - - mlir_module = types.ModuleType("mlir") - mlir_module.__path__ = [] - mlir_dialects_module = types.ModuleType("mlir.dialects") - mlir_dialects_module.__path__ = [] - mlir_pto_module = types.ModuleType("mlir.dialects.pto") - mlir_llvm_module = types.ModuleType("mlir.dialects.llvm") - mlir_ir_module = types.ModuleType("mlir.ir") - - class FakeContext: - pass - - class FakeLocation: - pass - - def register_pto_dialect(ctx, load=False): - ctx.pto_loaded = load - - def register_llvm_dialect(ctx, load=False): - ctx.llvm_loaded = load - - mlir_ir_module.Context = FakeContext - mlir_ir_module.Location = FakeLocation - mlir_pto_module.register_dialect = register_pto_dialect - mlir_llvm_module.register_dialect = register_llvm_dialect - mlir_dialects_module.pto = mlir_pto_module - mlir_dialects_module.llvm = mlir_llvm_module - mlir_module.dialects = mlir_dialects_module - mlir_module.ir = mlir_ir_module - - fake_sys_modules = { - "mlir": mlir_module, - "mlir.dialects": mlir_dialects_module, - "mlir.dialects.pto": mlir_pto_module, - "mlir.dialects.llvm": mlir_llvm_module, - "mlir.ir": mlir_ir_module, - } - - required_specs = { - "mlir.ir": object(), - "mlir.dialects.pto": object(), - } - original_find_spec = importlib.util.find_spec - original_sys_path = list(sys.path) - - def fake_find_spec(name, package=None): - if name in required_specs: - return required_specs[name] - return original_find_spec(name, package) - - with mock.patch.object(sys, "path", list(original_sys_path)), mock.patch.dict( - sys.modules, fake_sys_modules, clear=False - ), mock.patch("importlib.util.find_spec", side_effect=fake_find_spec): - module = importlib.util.module_from_spec(spec) - sys.modules.pop(module_name, None) - try: - spec.loader.exec_module(module) - self.assertEqual(sys.path, original_sys_path) - ctx = module.make_context() - self.assertTrue(getattr(ctx, "pto_loaded", False)) - self.assertTrue(getattr(ctx, "llvm_loaded", False)) - finally: - sys.modules.pop(module_name, None) - - -if __name__ == "__main__": - unittest.main() diff --git a/ptodsl/ptoas/_launcher.py b/ptodsl/tests/test_context.py similarity index 71% rename from ptodsl/ptoas/_launcher.py rename to ptodsl/tests/test_context.py index a830bbf4ac..b7d9b71800 100644 --- a/ptodsl/ptoas/_launcher.py +++ b/ptodsl/tests/test_context.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Copyright (c) 2026 Huawei Technologies Co., Ltd. # This program is free software, you can redistribute it and/or modify it under the terms and conditions of # CANN Open Software License Agreement Version 2.0 (the "License"). @@ -6,16 +7,17 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -"""Compatibility shim for legacy `ptoas._launcher` imports.""" +import unittest -from __future__ import annotations +from ptodsl._context import make_context -from ptoas_wheel_bootstrap import main as _wheel_bootstrap_main +class ContextTests(unittest.TestCase): + def test_make_context_loads_pto_dialect(self): + context = make_context() -def main() -> None: - _wheel_bootstrap_main() + self.assertIsNotNone(context) if __name__ == "__main__": - main() + unittest.main() diff --git a/ptodsl/tests/test_docs_as_test.py b/ptodsl/tests/test_docs_as_test.py index 6520d2f296..5f3f70dcd6 100644 --- a/ptodsl/tests/test_docs_as_test.py +++ b/ptodsl/tests/test_docs_as_test.py @@ -14,7 +14,6 @@ import json import linecache import re -import shutil import subprocess import sys import tempfile @@ -24,9 +23,10 @@ REPO_ROOT = Path(__file__).resolve().parents[2] USER_GUIDE_ROOT = REPO_ROOT / "ptodsl" / "docs" / "user_guide" from ptodsl import pto, scalar -from ptodsl._bootstrap import make_context +from ptodsl._context import make_context from ptodsl._runtime.launch import LaunchHandle, _marshal_launch_args -from mlir.ir import Module +from ptodsl._runtime.toolchain import resolve_ptoas_binary +from ptoas.mlir.ir import Module from support.docs_fragment_fixtures import FRAGMENT_FIXTURES, render_fragment_fixture FENCE_RE = re.compile(r"^```(?P[A-Za-z0-9_+-]*)\s*$") @@ -131,22 +131,6 @@ def block_label(block: MarkdownCodeBlock, symbol: Optional[str] = None) -> str: return format_doc_context(block.path, block.start_line, symbol) -def resolve_ptoas_binary() -> Path: - candidates = [ - REPO_ROOT / "build" / "tools" / "ptoas" / "ptoas", - REPO_ROOT / "install" / "bin" / "ptoas", - ] - for candidate in candidates: - if candidate.is_file(): - return candidate - - from_path = shutil.which("ptoas") - if from_path: - return Path(from_path) - - raise FileNotFoundError("unable to locate a ptoas binary under build/, install/, or PATH") - - def expect_parse_roundtrip_and_verify(text: str, label: str) -> None: with make_context() as ctx: parsed = Module.parse(text, ctx) diff --git a/ptodsl/tests/test_flash_attention_demo_compile.py b/ptodsl/tests/test_flash_attention_demo_compile.py index ef4d5ee234..d022103a8d 100644 --- a/ptodsl/tests/test_flash_attention_demo_compile.py +++ b/ptodsl/tests/test_flash_attention_demo_compile.py @@ -11,8 +11,8 @@ from pathlib import Path REPO_ROOT = Path(__file__).resolve().parents[2] -from ptodsl._bootstrap import make_context -from mlir.ir import Module +from ptodsl._context import make_context +from ptoas.mlir.ir import Module def expect(condition: bool, message: str) -> None: diff --git a/ptodsl/tests/test_jit_compile.py b/ptodsl/tests/test_jit_compile.py index 7047c31b11..05b0982b95 100644 --- a/ptodsl/tests/test_jit_compile.py +++ b/ptodsl/tests/test_jit_compile.py @@ -22,7 +22,7 @@ from ptodsl import _types as pto_types import ptodsl._vmi_namespace as vmi_namespace from ptodsl._ast_rewrite import PTODSLAstRewriteError -from ptodsl._bootstrap import make_context +from ptodsl._context import make_context from ptodsl._kernel_signature import DeviceParameterSpec, HelperMarkerParameterSpec, RuntimeScalarParameterSpec from ptodsl._tracing.runtime import SignatureTracingRuntime from ptodsl._runtime import native_build as native_build_runtime @@ -30,7 +30,7 @@ from ptodsl._runtime.codegen import generate_launch_cpp from ptodsl._runtime.launch import _marshal_launch_args from ptodsl._tracing import current_session -from mlir.ir import InsertionPoint, Location, Module +from ptoas.mlir.ir import InsertionPoint, Location, Module def expect(condition: bool, message: str) -> None: diff --git a/ptodsl/tests/test_pipe_surface_sample_compile.py b/ptodsl/tests/test_pipe_surface_sample_compile.py index 9ae6391a5a..88541a3635 100644 --- a/ptodsl/tests/test_pipe_surface_sample_compile.py +++ b/ptodsl/tests/test_pipe_surface_sample_compile.py @@ -11,11 +11,12 @@ from importlib.util import module_from_spec, spec_from_file_location from pathlib import Path -import shutil import subprocess import sys import tempfile +from ptodsl._runtime.toolchain import resolve_ptoas_binary as resolve_runtime_ptoas_binary + REPO_ROOT = Path(__file__).resolve().parents[2] SAMPLE = REPO_ROOT / "test" / "samples" / "TPushTPop" / "ptodsl" / "local_c2v" / "kernel.py" @@ -36,18 +37,10 @@ def load_sample_module(): def resolve_ptoas_binary() -> Path | None: - candidates = [ - REPO_ROOT / "build" / "tools" / "ptoas" / "ptoas", - REPO_ROOT / "install" / "bin" / "ptoas", - ] - for candidate in candidates: - if candidate.is_file(): - return candidate - - from_path = shutil.which("ptoas") - if from_path: - return Path(from_path) - return None + try: + return resolve_runtime_ptoas_binary() + except FileNotFoundError: + return None def run_ptoas_frontend(ptoas_bin: Path, mlir_text: str) -> str: diff --git a/ptodsl/tests/test_ptoas_cli.py b/ptodsl/tests/test_ptoas_cli.py new file mode 100644 index 0000000000..7917a2ccb3 --- /dev/null +++ b/ptodsl/tests/test_ptoas_cli.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +import tempfile +import unittest +from pathlib import Path +from types import SimpleNamespace +from unittest import mock + +from ptoas import _cli + + +class PTOASCLITests(unittest.TestCase): + def _make_native_module(self, package_root: Path): + return SimpleNamespace( + __file__=str(package_root / "_core.fake.so"), + main=mock.Mock(return_value=0), + ) + + def test_launch_uses_standard_native_module_and_packaged_resources(self): + with tempfile.TemporaryDirectory() as temp_dir: + package_root = Path(temp_dir) / "site-packages" / "ptoas" + tileops_dir = package_root / "_runtime" / "share" / "ptoas" / "TileOps" + wrapper = Path(temp_dir) / "bin" / "ptoas" + tileops_dir.mkdir(parents=True) + wrapper.parent.mkdir(parents=True) + wrapper.write_text("", encoding="utf-8") + native_module = self._make_native_module(package_root) + + with mock.patch.object( + _cli, "_load_native_module", return_value=native_module + ), mock.patch.dict( + _cli.os.environ, + {"PATH": "/usr/bin"}, + clear=True, + ): + exit_code = _cli.launch(["--version"], wrapper=wrapper) + environment = dict(_cli.os.environ) + + self.assertEqual(exit_code, 0) + native_module.main.assert_called_once_with( + [ + str(wrapper.resolve()), + "--tilelang-path", + str(tileops_dir.resolve()), + "--tilelang-pkg-path", + str(package_root.parent.resolve()), + "--ptodsl-pkg-path", + str(package_root.parent.resolve()), + "--version", + ] + ) + self.assertEqual(environment["PTOAS_BIN"], str(wrapper.resolve())) + self.assertEqual(environment["PTOAS_PYTHON_EXE"], _cli.sys.executable) + self.assertEqual(environment["PATH"], "/usr/bin") + + def test_explicit_resource_options_are_not_overridden(self): + with tempfile.TemporaryDirectory() as temp_dir: + package_root = Path(temp_dir) / "install" / "ptoas" + (package_root / "_runtime" / "share" / "ptoas" / "TileOps").mkdir( + parents=True + ) + wrapper = Path(temp_dir) / "install" / "bin" / "ptoas" + wrapper.parent.mkdir(parents=True) + wrapper.write_text("", encoding="utf-8") + native_module = self._make_native_module(package_root) + arguments = [ + "--tilelang-path=/custom/tileops", + "--tilelang-pkg-path", + "/custom/tilelang", + "--ptodsl-pkg-path=/custom/ptodsl", + "--version", + ] + + with mock.patch.object( + _cli, "_load_native_module", return_value=native_module + ): + _cli.launch(arguments, wrapper=wrapper) + + native_module.main.assert_called_once_with( + [str(wrapper.resolve()), *arguments] + ) + + def test_build_tree_uses_the_same_packaged_resource_layout(self): + with tempfile.TemporaryDirectory() as temp_dir: + build_root = Path(temp_dir) / "build" + package_root = build_root / "python" / "ptoas" + tileops_dir = package_root / "_runtime" / "share" / "ptoas" / "TileOps" + tileops_dir.mkdir(parents=True) + native_module = self._make_native_module(package_root) + + python_root, resolved_tileops = _cli._resolve_runtime_paths( + native_module + ) + + self.assertEqual(python_root, package_root.parent.resolve()) + self.assertEqual(resolved_tileops, tileops_dir.resolve()) + + def test_missing_tileops_resources_is_an_error(self): + with tempfile.TemporaryDirectory() as temp_dir: + package_root = Path(temp_dir) / "site-packages" / "ptoas" + native_module = self._make_native_module(package_root) + + with self.assertRaisesRegex(SystemExit, "TileOps"): + _cli._resolve_runtime_paths(native_module) + + +if __name__ == "__main__": + unittest.main() diff --git a/ptodsl/tests/test_ptoas_frontend_verify.py b/ptodsl/tests/test_ptoas_frontend_verify.py index 18661544bc..c8403171df 100644 --- a/ptodsl/tests/test_ptoas_frontend_verify.py +++ b/ptodsl/tests/test_ptoas_frontend_verify.py @@ -8,7 +8,6 @@ # See LICENSE in the root of the software repository for the full text of the License. from pathlib import Path -import shutil import subprocess import sys import tempfile @@ -18,8 +17,9 @@ REPO_ROOT = Path(__file__).resolve().parents[2] from ptodsl import pto from ptodsl import scalar -from ptodsl._bootstrap import make_context -from mlir.ir import Module +from ptodsl._context import make_context +from ptodsl._runtime.toolchain import resolve_ptoas_binary +from ptoas.mlir.ir import Module def expect(condition: bool, message: str) -> None: @@ -27,22 +27,6 @@ def expect(condition: bool, message: str) -> None: raise AssertionError(message) -def resolve_ptoas_binary() -> Path: - candidates = [ - REPO_ROOT / "build" / "tools" / "ptoas" / "ptoas", - REPO_ROOT / "install" / "bin" / "ptoas", - ] - for candidate in candidates: - if candidate.is_file(): - return candidate - - from_path = shutil.which("ptoas") - if from_path: - return Path(from_path) - - raise FileNotFoundError("unable to locate a ptoas binary under build/, install/, or PATH") - - def emit_example_mlir(example_path: Path) -> str: result = subprocess.run( [sys.executable, str(example_path), "--emit-mlir"], diff --git a/ptodsl/tests/test_ptoas_launcher_shim.py b/ptodsl/tests/test_ptoas_launcher_shim.py deleted file mode 100644 index b56d2fc8e7..0000000000 --- a/ptodsl/tests/test_ptoas_launcher_shim.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import unittest -import importlib.util -import sys -from pathlib import Path -from unittest import mock - -REPO_ROOT = Path(__file__).resolve().parents[2] -LAUNCHER_SOURCE = REPO_ROOT / "ptodsl" / "ptoas" / "_launcher.py" - - -def _load_source_launcher(): - spec = importlib.util.spec_from_file_location("test_ptoas_launcher_shim_source", LAUNCHER_SOURCE) - assert spec is not None - assert spec.loader is not None - module = importlib.util.module_from_spec(spec) - saved_sys_path = list(sys.path) - try: - sys.path.insert(0, str(REPO_ROOT / "ptodsl")) - spec.loader.exec_module(module) - finally: - sys.path = saved_sys_path - return module - - -class LauncherShimTests(unittest.TestCase): - def test_main_forwards_directly_to_wheel_bootstrap(self): - launcher = _load_source_launcher() - - with mock.patch.object(launcher, "_wheel_bootstrap_main") as wheel_main: - launcher.main() - - wheel_main.assert_called_once_with() - - -if __name__ == "__main__": - unittest.main() diff --git a/ptodsl/tests/test_ptoas_runtime_entry.py b/ptodsl/tests/test_ptoas_runtime_entry.py deleted file mode 100644 index 11def2f490..0000000000 --- a/ptodsl/tests/test_ptoas_runtime_entry.py +++ /dev/null @@ -1,249 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import os -import tempfile -import unittest -from pathlib import Path -from unittest import mock - -from ptoas import _runtime_entry - - -class RuntimeEntryTests(unittest.TestCase): - def test_launch_injects_runtime_environment_and_calls_shared_entrypoint(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - wrapper = temp_root / "bin" / "ptoas" - runtime_root = temp_root / "runtime" - python_root = temp_root / "python" - tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" - shared_module = runtime_root / "lib" / "ptoas.so" - wrapper.parent.mkdir(parents=True, exist_ok=True) - runtime_root.mkdir(parents=True, exist_ok=True) - python_root.mkdir(parents=True, exist_ok=True) - tileops_dir.mkdir(parents=True, exist_ok=True) - shared_module.parent.mkdir(parents=True, exist_ok=True) - shared_module.write_text("fake shared module", encoding="utf-8") - - layout = _runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper, - runtime_root=runtime_root, - python_root=python_root, - shared_module=shared_module, - tileops_dir=tileops_dir, - isolated_env=False, - ) - entrypoint = mock.Mock(return_value=0) - - with mock.patch.dict( - _runtime_entry.os.environ, - { - "PYTHONPATH": "/tmp/external-python", - "LD_LIBRARY_PATH": "/tmp/external-lib", - "DYLD_LIBRARY_PATH": "/tmp/external-dylib", - }, - clear=True, - ), mock.patch.object( - _runtime_entry, - "_load_shared_entrypoint", - return_value=entrypoint, - ) as load_shared_entrypoint: - exit_code = _runtime_entry.launch(layout, ["--version"]) - env = dict(_runtime_entry.os.environ) - - self.assertEqual(exit_code, 0) - load_shared_entrypoint.assert_called_once_with( - layout.shared_module, - layout.runtime_root / "lib", - preload_runtime_libraries=True, - ) - argc, c_argv = entrypoint.call_args.args - self.assertEqual( - [c_argv[i].decode("utf-8") for i in range(argc)], - [ - str(layout.wrapper), - "--tilelang-path", - str(layout.tileops_dir), - "--tilelang-pkg-path", - str(layout.python_root), - "--ptodsl-pkg-path", - str(layout.python_root), - "--version", - ], - ) - self.assertEqual(env["PTOAS_HOME"], str(layout.runtime_root)) - self.assertEqual(env["PTOAS_BIN"], str(layout.wrapper)) - self.assertEqual(env["PTOAS_TILEOPS_DIR"], str(layout.tileops_dir)) - self.assertEqual(env["PYTHONPATH"], str(layout.python_root) + os.pathsep + "/tmp/external-python") - self.assertEqual(env["LD_LIBRARY_PATH"], str(layout.runtime_root / "lib") + os.pathsep + "/tmp/external-lib") - self.assertEqual(env["DYLD_LIBRARY_PATH"], str(layout.runtime_root / "lib") + os.pathsep + "/tmp/external-dylib") - - def test_launch_prioritizes_runtime_environment_for_wheel_layout(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - wrapper = temp_root / "bin" / "ptoas" - runtime_root = temp_root / "runtime" - python_root = temp_root / "python" - tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" - shared_module = runtime_root / "lib" / "ptoas.so" - wrapper.parent.mkdir(parents=True, exist_ok=True) - runtime_root.mkdir(parents=True, exist_ok=True) - python_root.mkdir(parents=True, exist_ok=True) - tileops_dir.mkdir(parents=True, exist_ok=True) - shared_module.parent.mkdir(parents=True, exist_ok=True) - shared_module.write_text("fake shared module", encoding="utf-8") - - layout = _runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper, - runtime_root=runtime_root, - python_root=python_root, - shared_module=shared_module, - tileops_dir=tileops_dir, - isolated_env=True, - ) - entrypoint = mock.Mock(return_value=0) - - with mock.patch.dict( - _runtime_entry.os.environ, - { - "PYTHONPATH": "/tmp/external-python", - "LD_LIBRARY_PATH": "/tmp/external-lib", - "DYLD_LIBRARY_PATH": "/tmp/external-dylib", - }, - clear=True, - ), mock.patch.object( - _runtime_entry, - "_load_shared_entrypoint", - return_value=entrypoint, - ) as load_shared_entrypoint: - exit_code = _runtime_entry.launch(layout, ["--help"]) - env = dict(_runtime_entry.os.environ) - - self.assertEqual(exit_code, 0) - load_shared_entrypoint.assert_called_once_with( - layout.shared_module, - layout.runtime_root / "lib", - preload_runtime_libraries=False, - ) - self.assertEqual( - env["PYTHONPATH"], - str(layout.python_root) + os.pathsep + "/tmp/external-python", - ) - self.assertEqual( - env["LD_LIBRARY_PATH"], - str(layout.runtime_root / "lib") + os.pathsep + "/tmp/external-lib", - ) - self.assertEqual( - env["DYLD_LIBRARY_PATH"], - str(layout.runtime_root / "lib") + os.pathsep + "/tmp/external-dylib", - ) - - def test_load_shared_entrypoint_configures_in_process_ctypes_call(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - runtime_lib_dir = temp_root / "runtime" / "lib" - runtime_lib_dir.mkdir(parents=True, exist_ok=True) - dep = runtime_lib_dir / "libMLIRMlirOptMain.so.21.1" - dep.write_text("fake dep", encoding="utf-8") - shared_module = temp_root / "runtime" / "pto" / "ptoas.so" - shared_module.parent.mkdir(parents=True, exist_ok=True) - shared_module.write_text("fake shared module", encoding="utf-8") - - dep_library = mock.Mock() - shared_library = mock.Mock() - with mock.patch.object( - _runtime_entry.ctypes, "CDLL", side_effect=[dep_library, shared_library] - ) as load_library: - entrypoint = _runtime_entry._load_shared_entrypoint( - shared_module, - runtime_lib_dir, - preload_runtime_libraries=True, - ) - - self.assertEqual( - [call.args[0] for call in load_library.call_args_list], - [str(dep.resolve()), str(shared_module.resolve())], - ) - self.assertTrue( - all( - call.kwargs["mode"] == getattr(_runtime_entry.ctypes, "RTLD_GLOBAL", 0) - for call in load_library.call_args_list - ) - ) - self.assertIs(entrypoint, shared_library.ptoas_entrypoint) - self.assertEqual( - entrypoint.argtypes, - [_runtime_entry.ctypes.c_int, _runtime_entry.ctypes.POINTER(_runtime_entry.ctypes.c_char_p)], - ) - self.assertIs(entrypoint.restype, _runtime_entry.ctypes.c_int) - - def test_load_shared_entrypoint_can_skip_preloading_runtime_libraries(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - runtime_lib_dir = temp_root / "runtime" / "lib" - runtime_lib_dir.mkdir(parents=True, exist_ok=True) - dep = runtime_lib_dir / "libLLVMOption.so.21.1" - dep.write_text("fake dep", encoding="utf-8") - shared_module = runtime_lib_dir / "ptoas.so" - shared_module.write_text("fake shared module", encoding="utf-8") - - shared_library = mock.Mock() - with mock.patch.object(_runtime_entry.ctypes, "CDLL", return_value=shared_library) as load_library: - entrypoint = _runtime_entry._load_shared_entrypoint( - shared_module, - runtime_lib_dir, - preload_runtime_libraries=False, - ) - - load_library.assert_called_once_with( - str(shared_module), - mode=getattr(_runtime_entry.ctypes, "RTLD_GLOBAL", 0), - ) - self.assertIs(entrypoint, shared_library.ptoas_entrypoint) - - def test_preload_runtime_libraries_retries_until_dependencies_resolve(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - runtime_lib_dir = temp_root / "runtime" / "lib" - runtime_lib_dir.mkdir(parents=True, exist_ok=True) - dep_a = runtime_lib_dir / "libA.so.1" - dep_b = runtime_lib_dir / "libB.so.1" - dep_a.write_text("fake dep a", encoding="utf-8") - dep_b.write_text("fake dep b", encoding="utf-8") - shared_module = temp_root / "runtime" / "pto" / "ptoas.so" - shared_module.parent.mkdir(parents=True, exist_ok=True) - shared_module.write_text("fake shared module", encoding="utf-8") - - loaded: list[str] = [] - dep_b_attempts = 0 - - def fake_cdll(path: str, *, mode: int): - nonlocal dep_b_attempts - loaded.append(path) - if Path(path).resolve() == dep_b.resolve() and dep_b_attempts == 0: - dep_b_attempts += 1 - raise OSError("missing libA dependency") - return mock.Mock() - - with mock.patch.object(_runtime_entry.ctypes, "CDLL", side_effect=fake_cdll): - _runtime_entry._preload_runtime_libraries(shared_module, runtime_lib_dir) - - self.assertEqual( - loaded, - [ - str(dep_a.resolve()), - str(dep_b.resolve()), - str(dep_b.resolve()), - ], - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/ptodsl/tests/test_ptoas_tree_wrapper.py b/ptodsl/tests/test_ptoas_tree_wrapper.py index acf983e353..e289172a11 100644 --- a/ptodsl/tests/test_ptoas_tree_wrapper.py +++ b/ptodsl/tests/test_ptoas_tree_wrapper.py @@ -17,411 +17,136 @@ REPO_ROOT = Path(__file__).resolve().parents[2] WRAPPER_SOURCE = REPO_ROOT / "tools" / "ptoas" / "ptoas_wrapper.py" - -class TreeWrapperTests(unittest.TestCase): - def test_build_tree_wrapper_bootstraps_runtime_entry_and_delegates_shared_launcher(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - build_python_root = build_root / "python" - package_root = build_python_root / "ptoas" - package_root.mkdir(parents=True, exist_ok=True) - (package_root / "__init__.py").write_text("", encoding="utf-8") - (package_root / "_runtime_entry.py").write_text( - """ -from dataclasses import dataclass - +FAKE_CLI = """ calls = [] - -@dataclass(frozen=True) -class PTOASRuntimeLayout: - wrapper: object - runtime_root: object - python_root: object - shared_module: object - tileops_dir: object - isolated_env: bool - - -def launch(layout, user_args): - calls.append(("launch", layout, list(user_args))) +def launch(user_args, *, wrapper=None): + calls.append((list(user_args), wrapper)) return 17 -""".strip() - + "\n", - encoding="utf-8", - ) - - runtime_root = build_root / "runtime-staging" - (runtime_root / "lib").mkdir(parents=True, exist_ok=True) - (runtime_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (runtime_root / "lib" / "ptoas.so").write_text("fake shared module", encoding="utf-8") - install_root = temp_root / "install" - (install_root / "lib").mkdir(parents=True, exist_ok=True) - (install_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (install_root / "ptoas").mkdir(parents=True, exist_ok=True) - (install_root / "lib" / "ptoas.so").write_text("install shared module", encoding="utf-8") - (install_root / "ptoas" / "_runtime_entry.py").write_text("", encoding="utf-8") - wrapper_path = temp_root / "build" / "tools" / "ptoas" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") - - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) +""".lstrip() - wrapper_module.__file__ = str(wrapper_path) - saved_sys_path = list(sys.path) - saved_argv = list(sys.argv) - saved_ptoas = sys.modules.pop("ptoas", None) - saved_runtime_entry = sys.modules.pop("ptoas._runtime_entry", None) - try: - sys.path = [entry for entry in sys.path if entry != str(build_python_root)] - sys.argv = [str(wrapper_path), "--version"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertEqual(exc.exception.code, 17) - self.assertEqual(sys.path[0], str(build_python_root)) - - runtime_entry = sys.modules["ptoas._runtime_entry"] - self.assertEqual( - runtime_entry.calls, - [ - ( - "launch", - runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper_path.resolve(), - runtime_root=runtime_root.resolve(), - python_root=build_python_root.resolve(), - shared_module=(runtime_root / "lib" / "ptoas.so").resolve(), - tileops_dir=(runtime_root / "share" / "ptoas" / "TileOps").resolve(), - isolated_env=False, - ), - ["--version"], - ), - ], - ) - finally: - sys.path = saved_sys_path - sys.argv = saved_argv - sys.modules.pop("ptoas", None) - sys.modules.pop("ptoas._runtime_entry", None) - if saved_ptoas is not None: - sys.modules["ptoas"] = saved_ptoas - if saved_runtime_entry is not None: - sys.modules["ptoas._runtime_entry"] = saved_runtime_entry - - def test_install_tree_wrapper_bootstraps_install_prefix_and_delegates_shared_launcher(self): +class TreeWrapperTests(unittest.TestCase): + def _load_wrapper( + self, + wrapper_path: Path, + module_name: str, + *, + python_root_mode: str, + python_root: Path, + ): + spec = importlib.util.spec_from_file_location(module_name, WRAPPER_SOURCE) + self.assertIsNotNone(spec) + self.assertIsNotNone(spec.loader) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + module.__file__ = str(wrapper_path) + module._PYTHON_ROOT_MODE = python_root_mode + module._PYTHON_ROOT = python_root + return module + + def _run_wrapper(self, wrapper_module, python_root: Path, wrapper: Path): + saved_sys_path = list(sys.path) + saved_argv = list(sys.argv) + saved_modules = { + name: sys.modules.pop(name, None) + for name in ("ptoas", "ptoas._cli") + } + try: + sys.path = [entry for entry in sys.path if entry != str(python_root)] + sys.argv = [str(wrapper), "--version"] + with self.assertRaises(SystemExit) as exc: + wrapper_module.main() + self.assertEqual(exc.exception.code, 17) + return sys.modules["ptoas._cli"] + finally: + sys.path = saved_sys_path + sys.argv = saved_argv + for name in ("ptoas._cli", "ptoas"): + sys.modules.pop(name, None) + if saved_modules[name] is not None: + sys.modules[name] = saved_modules[name] + + def _make_package(self, python_root: Path) -> None: + package_root = python_root / "ptoas" + package_root.mkdir(parents=True) + (package_root / "__init__.py").write_text("", encoding="utf-8") + (package_root / "_cli.py").write_text(FAKE_CLI, encoding="utf-8") + + def test_build_tree_wrapper_delegates_to_cli_module(self): with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - build_python_root = build_root / "python" - (build_python_root / "ptoas").mkdir(parents=True, exist_ok=True) - (build_python_root / "ptoas" / "_runtime_entry.py").write_text("", encoding="utf-8") - (build_root / "runtime-staging" / "lib").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "lib" / "ptoas.so").write_text("build shared module", encoding="utf-8") - - install_root = temp_root / "install" - install_python_root = install_root - package_root = install_python_root / "ptoas" - package_root.mkdir(parents=True, exist_ok=True) - (package_root / "__init__.py").write_text("", encoding="utf-8") - (package_root / "_runtime_entry.py").write_text( - """ -from dataclasses import dataclass - -calls = [] - - -@dataclass(frozen=True) -class PTOASRuntimeLayout: - wrapper: object - runtime_root: object - python_root: object - shared_module: object - tileops_dir: object - isolated_env: bool - - -def launch(layout, user_args): - calls.append(("launch", layout, list(user_args))) - return 23 -""".strip() - + "\n", - encoding="utf-8", + build_root = Path(temp_dir) / "build" + python_root = build_root / "python" + wrapper = build_root / "tools" / "ptoas" / "ptoas" + self._make_package(python_root) + wrapper.parent.mkdir(parents=True) + wrapper.write_text("", encoding="utf-8") + + module = self._load_wrapper( + wrapper, + "test_ptoas_build_wrapper", + python_root_mode="absolute", + python_root=python_root, ) - (install_root / "lib").mkdir(parents=True, exist_ok=True) - (install_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (install_root / "lib" / "ptoas.so").write_text("install shared module", encoding="utf-8") - wrapper_path = install_root / "bin" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") - - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper_install", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) - - wrapper_module.__file__ = str(wrapper_path) - - saved_sys_path = list(sys.path) - saved_argv = list(sys.argv) - saved_ptoas = sys.modules.pop("ptoas", None) - saved_runtime_entry = sys.modules.pop("ptoas._runtime_entry", None) - try: - sys.path = [entry for entry in sys.path if entry != str(install_python_root)] - sys.argv = [str(wrapper_path), "--help"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertEqual(exc.exception.code, 23) - self.assertEqual(sys.path[0], str(install_python_root)) - - runtime_entry = sys.modules["ptoas._runtime_entry"] - self.assertEqual( - runtime_entry.calls, - [ - ( - "launch", - runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper_path.resolve(), - runtime_root=install_root.resolve(), - python_root=install_python_root.resolve(), - shared_module=(install_root / "lib" / "ptoas.so").resolve(), - tileops_dir=(install_root / "share" / "ptoas" / "TileOps").resolve(), - isolated_env=False, - ), - ["--help"], - ), - ], - ) - finally: - sys.path = saved_sys_path - sys.argv = saved_argv - sys.modules.pop("ptoas", None) - sys.modules.pop("ptoas._runtime_entry", None) - if saved_ptoas is not None: - sys.modules["ptoas"] = saved_ptoas - if saved_runtime_entry is not None: - sys.modules["ptoas._runtime_entry"] = saved_runtime_entry - - def test_build_tree_wrapper_does_not_fall_back_to_install_prefix_python_root(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - (build_root / "runtime-staging" / "lib").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "lib" / "ptoas.so").write_text("fake shared module", encoding="utf-8") + cli = self._run_wrapper(module, python_root, wrapper) - install_root = temp_root / "install" - (install_root / "lib").mkdir(parents=True, exist_ok=True) - (install_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (install_root / "ptoas").mkdir(parents=True, exist_ok=True) - (install_root / "lib" / "ptoas.so").write_text("install shared module", encoding="utf-8") - (install_root / "ptoas" / "_runtime_entry.py").write_text("", encoding="utf-8") - wrapper_path = temp_root / "build" / "tools" / "ptoas" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") + self.assertEqual(cli.calls, [(["--version"], wrapper.resolve())]) - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper_build_fallback", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) - wrapper_module.__file__ = str(wrapper_path) - - saved_sys_path = list(sys.path) - saved_argv = list(sys.argv) - try: - sys.path = [entry for entry in sys.path if entry != str(install_root)] - sys.argv = [str(wrapper_path), "--version"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertIn("build-tree ptoas Python package root", str(exc.exception)) - finally: - sys.path = saved_sys_path - sys.argv = saved_argv - - def test_build_tree_wrapper_fails_when_build_runtime_layout_is_missing(self): + def test_install_tree_wrapper_delegates_to_cli_module(self): with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - build_python_root = build_root / "python" - package_root = build_python_root / "ptoas" - package_root.mkdir(parents=True, exist_ok=True) - (package_root / "__init__.py").write_text("", encoding="utf-8") - (package_root / "_runtime_entry.py").write_text( - """ -from dataclasses import dataclass - - -@dataclass(frozen=True) -class PTOASRuntimeLayout: - wrapper: object - runtime_root: object - python_root: object - shared_module: object - tileops_dir: object - isolated_env: bool - - -def launch(layout, user_args): - raise AssertionError("missing runtime layout must fail before launch") -""".strip() - + "\n", - encoding="utf-8", + install_root = Path(temp_dir) / "install" + wrapper = install_root / "bin" / "ptoas" + self._make_package(install_root) + wrapper.parent.mkdir(parents=True) + wrapper.write_text("", encoding="utf-8") + + module = self._load_wrapper( + wrapper, + "test_ptoas_install_wrapper", + python_root_mode="wrapper-relative", + python_root=Path(".."), ) - install_root = temp_root / "install" - (install_root / "lib").mkdir(parents=True, exist_ok=True) - (install_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (install_root / "lib" / "ptoas.so").write_text("install shared module", encoding="utf-8") - wrapper_path = build_root / "tools" / "ptoas" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") - - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper_build_missing_runtime", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) - wrapper_module.__file__ = str(wrapper_path) + cli = self._run_wrapper(module, install_root, wrapper) - saved_sys_path = list(sys.path) - saved_argv = list(sys.argv) - saved_ptoas = sys.modules.pop("ptoas", None) - saved_runtime_entry = sys.modules.pop("ptoas._runtime_entry", None) - try: - sys.path = [entry for entry in sys.path if entry != str(build_python_root)] - sys.argv = [str(wrapper_path), "--version"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertIn("ptoas runtime tree", str(exc.exception)) - self.assertIn(str(build_root / "runtime-staging"), str(exc.exception)) - finally: - sys.path = saved_sys_path - sys.argv = saved_argv - sys.modules.pop("ptoas", None) - sys.modules.pop("ptoas._runtime_entry", None) - if saved_ptoas is not None: - sys.modules["ptoas"] = saved_ptoas - if saved_runtime_entry is not None: - sys.modules["ptoas._runtime_entry"] = saved_runtime_entry + self.assertEqual(cli.calls, [(["--version"], wrapper.resolve())]) - def test_install_tree_wrapper_does_not_fall_back_to_build_tree_python_root(self): + def test_wrapper_requires_cli_module(self): with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - build_python_root = build_root / "python" - (build_python_root / "ptoas").mkdir(parents=True, exist_ok=True) - (build_python_root / "ptoas" / "_runtime_entry.py").write_text("", encoding="utf-8") - (build_root / "runtime-staging" / "lib").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "lib" / "ptoas.so").write_text("build shared module", encoding="utf-8") - - install_root = temp_root / "install" - wrapper_path = install_root / "bin" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") - - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper_install_fallback", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) - wrapper_module.__file__ = str(wrapper_path) - - saved_sys_path = list(sys.path) - saved_argv = list(sys.argv) - try: - sys.path = [entry for entry in sys.path if entry != str(build_python_root)] - sys.argv = [str(wrapper_path), "--help"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertIn("install-tree ptoas Python package root", str(exc.exception)) - finally: - sys.path = saved_sys_path - sys.argv = saved_argv + python_root = Path(temp_dir) / "python" + python_root.mkdir() + module = self._load_wrapper( + Path(temp_dir) / "build" / "tools" / "ptoas" / "ptoas", + "test_ptoas_missing_cli", + python_root_mode="absolute", + python_root=python_root, + ) + with self.assertRaisesRegex(SystemExit, "ptoas/_cli.py"): + module._require_python_root(python_root, context="test") - def test_install_tree_wrapper_fails_when_install_runtime_layout_is_missing(self): + def test_archive_wrapper_rejects_a_different_python_minor(self): with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - build_root = temp_root / "build" - (build_root / "runtime-staging" / "lib").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (build_root / "runtime-staging" / "lib" / "ptoas.so").write_text("build shared module", encoding="utf-8") - - install_root = temp_root / "install" - package_root = install_root / "ptoas" - package_root.mkdir(parents=True, exist_ok=True) - (package_root / "__init__.py").write_text("", encoding="utf-8") - (package_root / "_runtime_entry.py").write_text( - """ -from dataclasses import dataclass - - -@dataclass(frozen=True) -class PTOASRuntimeLayout: - wrapper: object - runtime_root: object - python_root: object - shared_module: object - tileops_dir: object - isolated_env: bool - - -def launch(layout, user_args): - raise AssertionError("missing runtime layout must fail before launch") -""".strip() - + "\n", - encoding="utf-8", + python_root = Path(temp_dir) / "archive" + wrapper = python_root / "bin" / "ptoas" + self._make_package(python_root) + wrapper.parent.mkdir(parents=True) + wrapper.write_text("", encoding="utf-8") + (python_root / ".ptoas-python-version").write_text( + "0.0\n", encoding="utf-8" ) - wrapper_path = install_root / "bin" / "ptoas" - wrapper_path.parent.mkdir(parents=True, exist_ok=True) - wrapper_path.write_text("", encoding="utf-8") - spec = importlib.util.spec_from_file_location("test_ptoas_wrapper_install_missing_runtime", WRAPPER_SOURCE) - self.assertIsNotNone(spec) - self.assertIsNotNone(spec.loader) - wrapper_module = importlib.util.module_from_spec(spec) - spec.loader.exec_module(wrapper_module) - wrapper_module.__file__ = str(wrapper_path) - - saved_sys_path = list(sys.path) + module = self._load_wrapper( + wrapper, + "test_ptoas_archive_python_version", + python_root_mode="wrapper-relative", + python_root=Path(".."), + ) saved_argv = list(sys.argv) - saved_ptoas = sys.modules.pop("ptoas", None) - saved_runtime_entry = sys.modules.pop("ptoas._runtime_entry", None) try: - sys.path = [entry for entry in sys.path if entry != str(install_root)] - sys.argv = [str(wrapper_path), "--help"] - - with self.assertRaises(SystemExit) as exc: - wrapper_module.main() - - self.assertIn("ptoas runtime tree", str(exc.exception)) - self.assertIn(str(install_root), str(exc.exception)) + sys.argv = [str(wrapper)] + with self.assertRaisesRegex(SystemExit, "requires CPython 0.0"): + module.main() finally: - sys.path = saved_sys_path sys.argv = saved_argv - sys.modules.pop("ptoas", None) - sys.modules.pop("ptoas._runtime_entry", None) - if saved_ptoas is not None: - sys.modules["ptoas"] = saved_ptoas - if saved_runtime_entry is not None: - sys.modules["ptoas._runtime_entry"] = saved_runtime_entry if __name__ == "__main__": diff --git a/ptodsl/tests/test_ptoas_wheel_bootstrap.py b/ptodsl/tests/test_ptoas_wheel_bootstrap.py deleted file mode 100644 index cd04d23bff..0000000000 --- a/ptodsl/tests/test_ptoas_wheel_bootstrap.py +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import json -import os -import subprocess -import sys -import tempfile -import textwrap -import unittest -from dataclasses import dataclass -from pathlib import Path -from types import SimpleNamespace -from unittest import mock - -import ptoas_wheel_bootstrap as wheel_bootstrap - - -class WheelBootstrapTests(unittest.TestCase): - def _make_runtime_tree(self, temp_root: Path) -> tuple[Path, Path]: - python_root = temp_root / "site-packages" - package_root = python_root / "ptoas" - runtime_root = package_root / "_runtime" - package_root.mkdir(parents=True, exist_ok=True) - (package_root / "_runtime_entry.py").write_text("", encoding="utf-8") - (runtime_root / "lib").mkdir(parents=True, exist_ok=True) - (runtime_root / "share" / "ptoas" / "TileOps").mkdir(parents=True, exist_ok=True) - (runtime_root / "lib" / "ptoas.so").write_text("fake shared module", encoding="utf-8") - bootstrap = python_root / "ptoas_wheel_bootstrap.py" - bootstrap.write_text("", encoding="utf-8") - wrapper = temp_root / "bin" / "ptoas" - wrapper.parent.mkdir(parents=True, exist_ok=True) - wrapper.write_text("", encoding="utf-8") - return bootstrap, wrapper - - def test_stage1_reexecs_with_prioritized_python_and_library_paths(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - bootstrap, wrapper = self._make_runtime_tree(temp_root) - - with mock.patch.dict( - wheel_bootstrap.os.environ, - { - "PYTHONPATH": "/tmp/external-python", - "LD_LIBRARY_PATH": "/tmp/external-lib", - "DYLD_LIBRARY_PATH": "/tmp/external-dylib", - }, - clear=True, - ), mock.patch.object( - wheel_bootstrap, - "__file__", - str(bootstrap), - ), mock.patch.object( - wheel_bootstrap.sys, - "argv", - [str(wrapper), "--version"], - ), mock.patch.object( - wheel_bootstrap.os, - "execve", - side_effect=SystemExit(19), - ) as execve: - with self.assertRaises(SystemExit) as exc: - wheel_bootstrap.main() - - self.assertEqual(exc.exception.code, 19) - execve.assert_called_once() - invoked_path, invoked_argv, invoked_env = execve.call_args.args - self.assertEqual(invoked_path, str(wrapper.resolve())) - self.assertEqual(invoked_argv, [str(wrapper.resolve()), "--version"]) - self.assertEqual(invoked_env["PTOAS_WHEEL_STAGE2"], "1") - self.assertEqual( - invoked_env["PYTHONPATH"], - str(bootstrap.parent.resolve()) + os.pathsep + "/tmp/external-python", - ) - self.assertEqual( - invoked_env["LD_LIBRARY_PATH"], - str((bootstrap.parent / "ptoas" / "_runtime" / "lib").resolve()) - + os.pathsep - + "/tmp/external-lib", - ) - self.assertEqual( - invoked_env["DYLD_LIBRARY_PATH"], - str((bootstrap.parent / "ptoas" / "_runtime" / "lib").resolve()) - + os.pathsep - + "/tmp/external-dylib", - ) - - def test_stage2_loads_runtime_entry_without_reexec(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - bootstrap, wrapper = self._make_runtime_tree(temp_root) - @dataclass(frozen=True) - class FakeLayout: - wrapper: Path - runtime_root: Path - python_root: Path - shared_module: Path - tileops_dir: Path - isolated_env: bool - - runtime_entry = SimpleNamespace( - PTOASRuntimeLayout=FakeLayout, - launch=mock.Mock(return_value=7), - ) - - with mock.patch.dict( - wheel_bootstrap.os.environ, - {"PTOAS_WHEEL_STAGE2": "1"}, - clear=True, - ), mock.patch.object( - wheel_bootstrap, - "__file__", - str(bootstrap), - ), mock.patch.object( - wheel_bootstrap.sys, - "argv", - [str(wrapper), "--help"], - ), mock.patch.object( - wheel_bootstrap, - "_load_runtime_entry", - return_value=runtime_entry, - ) as load_runtime_entry, mock.patch.object( - wheel_bootstrap.os, - "execve", - ) as execve: - with self.assertRaises(SystemExit) as exc: - wheel_bootstrap.main() - - self.assertEqual(exc.exception.code, 7) - execve.assert_not_called() - load_runtime_entry.assert_called_once_with(bootstrap.parent.resolve(), (bootstrap.parent / "ptoas").resolve()) - runtime_entry.launch.assert_called_once_with( - FakeLayout( - wrapper=wrapper.resolve(), - runtime_root=(bootstrap.parent / "ptoas" / "_runtime").resolve(), - python_root=bootstrap.parent.resolve(), - shared_module=(bootstrap.parent / "ptoas" / "_runtime" / "lib" / "ptoas.so").resolve(), - tileops_dir=(bootstrap.parent / "ptoas" / "_runtime" / "share" / "ptoas" / "TileOps").resolve(), - isolated_env=True, - ), - ["--help"], - ) - - def test_resolve_wheel_python_root_prefers_installed_package_when_shadowed(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - bootstrap, wrapper = self._make_runtime_tree(temp_root) - package_root = bootstrap.parent / "ptoas" - shadow_launcher = temp_root / "shadow" / "ptoas" / "_launcher.py" - shadow_launcher.parent.mkdir(parents=True, exist_ok=True) - shadow_launcher.write_text("", encoding="utf-8") - - def fake_get_path(name: str) -> str: - if name in ("purelib", "platlib"): - return str(package_root.parent) - return "" - - with mock.patch.object( - wheel_bootstrap.sysconfig, - "get_path", - side_effect=fake_get_path, - ): - python_root, resolved_package_root = wheel_bootstrap._resolve_wheel_python_root( - wrapper, - str(shadow_launcher), - ) - - self.assertEqual(python_root, package_root.parent.resolve()) - self.assertEqual(resolved_package_root, package_root.resolve()) - - def test_console_entry_reexec_prioritizes_wheel_paths(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - wheel_root = temp_root / "wheel-site" - package_root = wheel_root / "ptoas" - runtime_root = package_root / "_runtime" - runtime_lib_dir = runtime_root / "lib" - tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" - result_path = temp_root / "launch-result.json" - wrapper = temp_root / "venv" / "bin" / "ptoas" - - package_root.mkdir(parents=True, exist_ok=True) - runtime_lib_dir.mkdir(parents=True, exist_ok=True) - tileops_dir.mkdir(parents=True, exist_ok=True) - (runtime_lib_dir / "ptoas.so").write_text("fake shared module", encoding="utf-8") - (wheel_root / "ptoas_wheel_bootstrap.py").write_text( - Path(wheel_bootstrap.__file__).read_text(encoding="utf-8"), - encoding="utf-8", - ) - (package_root / "_runtime_entry.py").write_text( - textwrap.dedent( - """ - import json - import os - from dataclasses import dataclass - from pathlib import Path - - @dataclass(frozen=True) - class PTOASRuntimeLayout: - wrapper: Path - runtime_root: Path - python_root: Path - shared_module: Path - tileops_dir: Path - isolated_env: bool - - def launch(layout, user_args): - result = { - "user_args": list(user_args), - "env": { - "PTOAS_WHEEL_STAGE2": os.environ.get("PTOAS_WHEEL_STAGE2"), - "PYTHONPATH": os.environ.get("PYTHONPATH"), - "LD_LIBRARY_PATH": os.environ.get("LD_LIBRARY_PATH"), - "DYLD_LIBRARY_PATH": os.environ.get("DYLD_LIBRARY_PATH"), - }, - "layout": { - "wrapper": str(layout.wrapper), - "runtime_root": str(layout.runtime_root), - "python_root": str(layout.python_root), - "shared_module": str(layout.shared_module), - "tileops_dir": str(layout.tileops_dir), - "isolated_env": layout.isolated_env, - }, - } - Path(os.environ["PTOAS_TEST_RESULT"]).write_text( - json.dumps(result, sort_keys=True), - encoding="utf-8", - ) - return 23 - """ - ).lstrip(), - encoding="utf-8", - ) - - shadow_root = temp_root / "shadow-site" - shadow_package = shadow_root / "ptoas" - shadow_package.mkdir(parents=True, exist_ok=True) - (shadow_package / "__init__.py").write_text( - "raise RuntimeError('shadow ptoas package must not be imported')\n", - encoding="utf-8", - ) - (shadow_package / "_runtime_entry.py").write_text( - "raise RuntimeError('shadow runtime entry must not be imported')\n", - encoding="utf-8", - ) - - wrapper.parent.mkdir(parents=True, exist_ok=True) - wrapper.write_text( - textwrap.dedent( - f""" - #!{sys.executable} - import sys - sys.path.insert(0, {str(wheel_root)!r}) - import ptoas_wheel_bootstrap - ptoas_wheel_bootstrap.main() - """ - ).lstrip(), - encoding="utf-8", - ) - wrapper.chmod(0o755) - - env = os.environ.copy() - env.pop("PTOAS_WHEEL_STAGE2", None) - env["PYTHONPATH"] = os.pathsep.join([str(shadow_root), str(wheel_root)]) - env["LD_LIBRARY_PATH"] = "/tmp/polluted-llvm" - env["DYLD_LIBRARY_PATH"] = "/tmp/polluted-dylib" - env["PTOAS_TEST_RESULT"] = str(result_path) - - completed = subprocess.run( - [str(wrapper), "--version"], - env=env, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - check=False, - ) - - self.assertEqual( - completed.returncode, - 23, - msg=f"stdout:\n{completed.stdout}\nstderr:\n{completed.stderr}", - ) - result = json.loads(result_path.read_text(encoding="utf-8")) - - self.assertEqual(result["user_args"], ["--version"]) - self.assertEqual(result["env"]["PTOAS_WHEEL_STAGE2"], "1") - self.assertEqual( - result["env"]["PYTHONPATH"], - str(wheel_root.resolve()) + os.pathsep + str(shadow_root), - ) - self.assertEqual( - result["env"]["LD_LIBRARY_PATH"], - str(runtime_lib_dir.resolve()) + os.pathsep + "/tmp/polluted-llvm", - ) - self.assertEqual( - result["env"]["DYLD_LIBRARY_PATH"], - str(runtime_lib_dir.resolve()) + os.pathsep + "/tmp/polluted-dylib", - ) - self.assertEqual( - result["layout"], - { - "wrapper": str(wrapper.resolve()), - "runtime_root": str(runtime_root.resolve()), - "python_root": str(wheel_root.resolve()), - "shared_module": str((runtime_lib_dir / "ptoas.so").resolve()), - "tileops_dir": str(tileops_dir.resolve()), - "isolated_env": True, - }, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/ptodsl/tests/test_runtime_toolchain.py b/ptodsl/tests/test_runtime_toolchain.py index bea4a0fcc3..f9c1797899 100644 --- a/ptodsl/tests/test_runtime_toolchain.py +++ b/ptodsl/tests/test_runtime_toolchain.py @@ -49,33 +49,41 @@ def test_native_launch_flags_use_target_arch(self): class ResolvePtoasBinaryTests(unittest.TestCase): - def test_env_override_wins_over_repo_default(self): + def test_env_override_wins_over_path(self): with tempfile.TemporaryDirectory() as temp_dir: temp_root = Path(temp_dir) env_ptoas = temp_root / "env-ptoas" env_ptoas.write_text("", encoding="utf-8") - repo_build_ptoas = temp_root / "build" / "tools" / "ptoas" / "ptoas" - repo_build_ptoas.parent.mkdir(parents=True, exist_ok=True) - repo_build_ptoas.write_text("", encoding="utf-8") + path_ptoas = temp_root / "path-ptoas" - fake_toolchain_file = ( - temp_root / "repo" / "ptodsl" / "ptodsl" / "_runtime" / "toolchain.py" - ) - fake_toolchain_file.parent.mkdir(parents=True, exist_ok=True) - fake_toolchain_file.write_text("", encoding="utf-8") - - with mock.patch.dict(os.environ, {"PTOAS_BIN": str(env_ptoas)}, clear=False), mock.patch.object( - toolchain, "__file__", str(fake_toolchain_file) - ): + with mock.patch.dict( + os.environ, {"PTOAS_BIN": str(env_ptoas)}, clear=True + ), mock.patch.object( + toolchain.shutil, "which", return_value=str(path_ptoas) + ) as which: resolved = toolchain.resolve_ptoas_binary() self.assertEqual(resolved, env_ptoas) + which.assert_not_called() + + def test_path_is_used_without_env_override(self): + with tempfile.TemporaryDirectory() as temp_dir: + path_ptoas = Path(temp_dir) / "path-ptoas" + with mock.patch.dict(os.environ, {}, clear=True), mock.patch.object( + toolchain.shutil, "which", return_value=str(path_ptoas) + ) as which: + resolved = toolchain.resolve_ptoas_binary() + + self.assertEqual(resolved, path_ptoas) + which.assert_called_once_with("ptoas") def test_invalid_env_override_raises(self): with tempfile.TemporaryDirectory() as temp_dir: missing = Path(temp_dir) / "missing-ptoas" - with mock.patch.dict(os.environ, {"PTOAS_BIN": str(missing)}, clear=False): + with mock.patch.dict( + os.environ, {"PTOAS_BIN": str(missing)}, clear=True + ), mock.patch.object(toolchain.shutil, "which", return_value=None): with self.assertRaises(FileNotFoundError): toolchain.resolve_ptoas_binary() diff --git a/ptodsl/tests/test_tileop.py b/ptodsl/tests/test_tileop.py index 0c55ddc671..1496439638 100644 --- a/ptodsl/tests/test_tileop.py +++ b/ptodsl/tests/test_tileop.py @@ -10,8 +10,8 @@ """Focused tracing coverage for the public ``@pto.tileop`` surface.""" from ptodsl import pto -from ptodsl._bootstrap import make_context -from mlir.ir import Module +from ptodsl._context import make_context +from ptoas.mlir.ir import Module @pto.simt(max_threads=64, ast_rewrite=False) diff --git a/ptodsl/tests/test_vector_cube_ops.py b/ptodsl/tests/test_vector_cube_ops.py index 71b975ab34..ddfa884d0a 100644 --- a/ptodsl/tests/test_vector_cube_ops.py +++ b/ptodsl/tests/test_vector_cube_ops.py @@ -13,9 +13,9 @@ import ptodsl._ops as _ops import ptodsl._pipe_namespace as _pipe_namespace -from ptodsl._bootstrap import make_context +from ptodsl._context import make_context from ptodsl import pto -from mlir.ir import F32Type +from ptoas.mlir.ir import F32Type def _identity(value): return value diff --git a/ptodsl/tests/test_vmi_vmull.py b/ptodsl/tests/test_vmi_vmull.py index 3fbf2972a4..fad01a208c 100644 --- a/ptodsl/tests/test_vmi_vmull.py +++ b/ptodsl/tests/test_vmi_vmull.py @@ -7,12 +7,6 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from pathlib import Path -import sys - - -sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "ptodsl")) - from ptodsl import pto diff --git a/ptodsl/tests/test_vmi_vshr_signedness.py b/ptodsl/tests/test_vmi_vshr_signedness.py index f4dfe09340..848ddec81a 100644 --- a/ptodsl/tests/test_vmi_vshr_signedness.py +++ b/ptodsl/tests/test_vmi_vshr_signedness.py @@ -7,12 +7,6 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from pathlib import Path -import sys - - -sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "ptodsl")) - from ptodsl import pto diff --git a/pyproject.toml b/pyproject.toml index b34908352a..beaed1b33b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,32 +1,26 @@ -# pyproject.toml - Project metadata -# -# Build flow (requires LLVM already built): -# pip install . -# -# This will: -# 1. CMake configure + Ninja build + install -# 2. Package Python bindings into a wheel via docker/create_wheel.sh -# -# Environment variables (all optional): -# LLVM_BUILD_DIR Path to LLVM build dir -# (default: /llvm-workspace/llvm-project/build-shared) -# PTO_BUILD_DIR Path to PTOAS build dir (default: /build) -# PTO_INSTALL_DIR Install prefix (default: /install) -# CMAKE_C_COMPILER Optional C compiler passed through to CMake -# CMAKE_CXX_COMPILER Optional C++ compiler passed through to CMake -# PTOAS_PYTHON_PACKAGE_VERSION Wheel version override +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +# Standard PEP 517 configuration for the `ptoas` distribution. Set +# LLVM_BUILD_DIR to an existing LLVM/MLIR build. Pass +# `--config-settings=build-dir=` when tests or development tools require +# a persistent CMake build tree. [build-system] -requires = ["setuptools>=68", "wheel"] -build-backend = "_ptoas_build_backend" -backend-path = ["."] +requires = ["scikit-build-core>=0.12.2,<2", "pybind11<3", "nanobind>=2.4"] +build-backend = "scikit_build_core.build" [project] name = "ptoas" -version = "0.51" +dynamic = ["version"] description = "PTO Assembler & Optimizer" readme = "README.md" -requires-python = ">=3.9" +requires-python = ">=3.10" license = "Apache-2.0" dependencies = [ "numpy", @@ -35,8 +29,31 @@ classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", ] + +[project.scripts] +ptoas = "ptoas._cli:main" + +[tool.scikit-build] +minimum-version = "build-system.requires" +cmake.version = "CMakeLists.txt" +ninja.version = ">=1.10" +build.verbose = false +editable.mode = "redirect" +install.components = ["PTOAS_Python"] + +[tool.scikit-build.wheel.packages] +ptodsl = "ptodsl/ptodsl" +ptoas = "ptodsl/ptoas" +tilelang_dsl = "tilelang-dsl/python/tilelang_dsl" + +[tool.scikit-build.cmake.define] +PTOAS_RELEASE_VERSION_OVERRIDE = { env = "PTOAS_RELEASE_VERSION_OVERRIDE", default = "" } + +[tool.scikit-build.metadata.version] +provider = "scikit_build_core.metadata.regex" +input = "CMakeLists.txt" +regex = 'project\s*\(\s*ptoas\s+VERSION\s+(?P[0-9]+\.[0-9]+)\s*\)' diff --git a/python/pto/dialects/pto.py b/python/pto/dialects/pto.py index 3e66f0bdb1..eb7731e7af 100644 --- a/python/pto/dialects/pto.py +++ b/python/pto/dialects/pto.py @@ -6,15 +6,10 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -import importlib -import importlib.util import functools -import os -from pathlib import Path -import sys from typing import Optional -from mlir import ir as _ods_ir +from ptoas.mlir import ir as _ods_ir from . import _pto_ops_gen as _pto_ops_gen from ._ods_common import ( @@ -22,77 +17,7 @@ get_op_result_or_value as _get_op_result_or_value, get_op_results_or_values as _get_op_results_or_values, ) - - -def _candidate_pto_ext_dirs(): - # Prefer the extension shipped next to the active wrapper so installed - # wheels stay self-consistent even if the caller also exported a developer - # PTO_INSTALL_DIR / PTO_PYTHON_ROOT in the environment. - candidates = [Path(__file__).resolve().parent.parent / "_mlir_libs"] - env_roots = ( - os.environ.get("PTO_PYTHON_BUILD_ROOT"), - os.environ.get("PTO_PYTHON_ROOT"), - os.environ.get("PTO_INSTALL_DIR"), - ) - for root in env_roots: - if not root: - continue - candidates.append(Path(root) / "mlir" / "_mlir_libs") - - seen = set() - ordered = [] - for candidate in candidates: - candidate = candidate.resolve() - candidate_text = str(candidate) - if candidate_text in seen: - continue - seen.add(candidate_text) - ordered.append(candidate) - return ordered - - -def _load_local_pto_ext(): - module_name = "mlir._mlir_libs._pto" - cached = sys.modules.get(module_name) - if cached is not None: - return cached - - candidates = [] - for lib_dir in _candidate_pto_ext_dirs(): - for suffix in ("*.so", "*.pyd", "*.dll", "*.dylib"): - candidates.extend(lib_dir.glob(f"_pto{suffix}")) - if not candidates: - raise FileNotFoundError("cannot locate local _pto extension in candidate _mlir_libs directories") - - first_error = None - for so_path in candidates: - try: - spec = importlib.util.spec_from_file_location( - module_name, so_path - ) - if spec and spec.loader: - mod = importlib.util.module_from_spec(spec) - previous = sys.modules.get(module_name) - sys.modules[module_name] = mod - try: - spec.loader.exec_module(mod) - except Exception: - if previous is None: - sys.modules.pop(module_name, None) - else: - sys.modules[module_name] = previous - raise - return mod - except ImportError as exc: - if first_error is None: - first_error = exc - raise ImportError("failed to load local _pto extension from candidate _mlir_libs directories") from first_error - - -try: - _pto_mod = _load_local_pto_ext() -except FileNotFoundError: - _pto_mod = importlib.import_module(".._mlir_libs._pto", __package__) +from ptoas import _core as _pto_mod def _export_generated_symbols(): @@ -126,6 +51,8 @@ def _export_optional_cext_symbol(name): AsyncEventType = _pto_mod.AsyncEventType PrefetchAsyncContextType = _export_optional_cext_symbol("PrefetchAsyncContextType") HiF8Type = _pto_mod.HiF8Type +HiF8x2Type = _pto_mod.HiF8x2Type +F8E8M0Type = _pto_mod.F8E8M0Type F4E1M2x2Type = _pto_mod.F4E1M2x2Type F4E2M1x2Type = _pto_mod.F4E2M1x2Type TensorViewType = _pto_mod.TensorViewType @@ -304,6 +231,8 @@ def fence_scope_attr_builder(value, context=None): "AsyncSessionType", "AsyncEventType", "HiF8Type", + "HiF8x2Type", + "F8E8M0Type", "F4E1M2x2Type", "F4E2M1x2Type", "TensorViewType", @@ -1213,9 +1142,9 @@ def _project_result(group, index, ty): def _load_standard_dialects(): try: - from mlir.dialects import arith as _mlir_arith # noqa: F401 - from mlir.dialects import func as _mlir_func # noqa: F401 - from mlir.dialects import scf as _mlir_scf # noqa: F401 + from ptoas.mlir.dialects import arith as _mlir_arith # noqa: F401 + from ptoas.mlir.dialects import func as _mlir_func # noqa: F401 + from ptoas.mlir.dialects import scf as _mlir_scf # noqa: F401 except ImportError as exc: raise RuntimeError("mlir standard dialect python bindings are required for vkernel parsing") from exc diff --git a/quick_install.sh b/quick_install.sh index 38509b61d5..253f5713ab 100755 --- a/quick_install.sh +++ b/quick_install.sh @@ -7,73 +7,37 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -# For quick development, build and install ptoas and its python bindings -# on top of Docker image https://github.com/learning-chip/agent_docker_npu/pull/8 -# assume MLIR is already installed to save time, takes <3min to finish the build of pto extension +# Build and install PTOAS in editable mode against an existing LLVM/MLIR +# build. The persistent build directory can subsequently be used with Ninja, +# for example: ninja -C build check-pto. # # Optional env: # LLVM_BUILD_DIR - default: ${LLVM_SOURCE_DIR:-/llvm-workspace/llvm-project}/build-shared -# PTO_INSTALL_DIR - default: /install +# PTO_BUILD_DIR - default: /build +# PYTHON_BIN - default: python set -euo pipefail PTO_SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PTO_INSTALL_DIR="${PTO_INSTALL_DIR:-${PTO_SOURCE_DIR}/install}" - LLVM_SOURCE_DIR="${LLVM_SOURCE_DIR:-/llvm-workspace/llvm-project}" LLVM_BUILD_DIR="${LLVM_BUILD_DIR:-${LLVM_SOURCE_DIR}/build-shared}" - -PY_ROOT="$(python -c 'import sys; print(sys.prefix)')" - -for d in "$LLVM_BUILD_DIR/lib/cmake/llvm" "$LLVM_BUILD_DIR/lib/cmake/mlir"; do - test -d "$d" || { echo "error: missing $d (set LLVM_BUILD_DIR?)" >&2; exit 1; } -done - -PYBIND11_DIR="$(python -m pybind11 --cmakedir)" -MLIR_PY_PKG="${LLVM_BUILD_DIR}/tools/mlir/python_packages/mlir_core" -test -d "$MLIR_PY_PKG" || { echo "error: MLIR python package dir missing: $MLIR_PY_PKG" >&2; exit 1; } - -PTOAS_VERSION="${PTOAS_VERSION:-$(python "${PTO_SOURCE_DIR}/.github/scripts/compute_ptoas_version.py" --cmake-file "${PTO_SOURCE_DIR}/CMakeLists.txt" --mode dev)}" - -cd "$PTO_SOURCE_DIR" - -cmake -C "${PTO_SOURCE_DIR}/cmake/LinuxHardeningCache.cmake" -G Ninja \ - -S . \ - -B build \ - -DLLVM_DIR="${LLVM_BUILD_DIR}/lib/cmake/llvm" \ - -DMLIR_DIR="${LLVM_BUILD_DIR}/lib/cmake/mlir" \ - -DPython3_ROOT_DIR="${PY_ROOT}" \ - -DPython3_EXECUTABLE=python \ - -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="${PYBIND11_DIR}" \ - -DMLIR_PYTHON_PACKAGE_DIR="${MLIR_PY_PKG}" \ - -DPTOAS_RELEASE_VERSION_OVERRIDE="${PTOAS_VERSION}" \ - -DCMAKE_INSTALL_PREFIX="${PTO_INSTALL_DIR}" - -ninja -C build -ninja -C build install - -export PTO_SOURCE_DIR PTO_INSTALL_DIR LLVM_BUILD_DIR -export PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_PYTHON_PACKAGE_VERSION:-${PTOAS_VERSION}}" -bash "${PTO_SOURCE_DIR}/docker/create_wheel.sh" - -shopt -s nullglob -wheels=("${MLIR_PY_PKG}/dist/ptoas-"*.whl) -shopt -u nullglob -((${#wheels[@]} > 0)) || { echo "error: no ptoas-*.whl under ${MLIR_PY_PKG}/dist" >&2; exit 1; } -pip install --force-reinstall "${wheels[0]}" - -export PATH="${PTO_SOURCE_DIR}/build/tools/ptoas:${PATH}" -export LD_LIBRARY_PATH="${LLVM_BUILD_DIR}/lib:${PTO_INSTALL_DIR}/lib:${LD_LIBRARY_PATH:-}" - -python -c "import mlir.ir" -python -c "from mlir.dialects import pto" - -which ptoas - -PTOAS_ENV_TMP="${PTO_SOURCE_DIR}/tmp/set_ptoas_env" -mkdir -p "${PTOAS_ENV_TMP}/MatMul" "${PTOAS_ENV_TMP}/Abs" -(cd "${PTO_SOURCE_DIR}/test/samples/MatMul" && python ./tmatmulk.py > "${PTOAS_ENV_TMP}/MatMul/tmatmulk.pto" && ptoas "${PTOAS_ENV_TMP}/MatMul/tmatmulk.pto" -o "${PTOAS_ENV_TMP}/MatMul/tmatmulk.cpp") -(cd "${PTO_SOURCE_DIR}/test/samples/Abs" && python ./abs.py > "${PTOAS_ENV_TMP}/Abs/abs.pto" && ptoas --enable-insert-sync "${PTOAS_ENV_TMP}/Abs/abs.pto" -o "${PTOAS_ENV_TMP}/Abs/abs.cpp") - -echo "quick_install.sh: OK" +PTO_BUILD_DIR="${PTO_BUILD_DIR:-${PTO_SOURCE_DIR}/build}" +PYTHON_BIN="${PYTHON_BIN:-python}" + +if command -v ccache >/dev/null 2>&1; then + export CMAKE_C_COMPILER_LAUNCHER="${CMAKE_C_COMPILER_LAUNCHER:-ccache}" + export CMAKE_CXX_COMPILER_LAUNCHER="${CMAKE_CXX_COMPILER_LAUNCHER:-ccache}" +fi + +"${PYTHON_BIN}" -m pip install \ + 'scikit-build-core>=0.12.2,<2' \ + 'pybind11<3' \ + 'nanobind>=2.4' + +LLVM_BUILD_DIR="${LLVM_BUILD_DIR}" \ + "${PYTHON_BIN}" -m pip install --editable "${PTO_SOURCE_DIR}" \ + --no-build-isolation \ + --config-settings="build-dir=${PTO_BUILD_DIR}" + +echo "PTOAS editable install complete." +echo "Build directory: ${PTO_BUILD_DIR}" diff --git a/scripts/batch_compile_output_cpp.sh b/scripts/batch_compile_output_cpp.sh index 8de0fb1141..093cf5bed7 100755 --- a/scripts/batch_compile_output_cpp.sh +++ b/scripts/batch_compile_output_cpp.sh @@ -64,8 +64,7 @@ print_usage() { --log-dir 编译日志目录,默认: /logs --help, -h 显示帮助 -推荐先执行: - source scripts/ptoas_env.sh +运行前请通过 CANN setenv 或显式参数准备 bisheng 和 PTO-ISA 路径。 默认编译参数来源: 由 test/npu_validation/scripts/generate_testcase.py 中 @@ -155,7 +154,7 @@ elif [[ "${COMPILER}" != */* ]] && command -v "${COMPILER}" >/dev/null 2>&1; the COMPILER="$(command -v "${COMPILER}")" fi -[[ -n "${COMPILER}" ]] || die "未找到编译器,请先 source scripts/ptoas_env.sh,或通过 --compiler/COMPILER 指定 bisheng 路径" +[[ -n "${COMPILER}" ]] || die "未找到编译器,请通过 CANN setenv、--compiler 或 COMPILER 指定 bisheng 路径" [[ -n "${PTO_ISA_PATH}" ]] || die "未找到 PTO-ISA 路径,请通过 --pto-isa-path、PTO_ISA_PATH 或 PTO_ISA_ROOT 指定" [[ -x "${COMPILER}" ]] || die "编译器不可执行: ${COMPILER}" [[ -d "${SRC_ROOT}" ]] || die "源码目录不存在: ${SRC_ROOT}" diff --git a/scripts/compile_pto_to_vpto_llvm.sh b/scripts/compile_pto_to_vpto_llvm.sh index 4b6c066c94..0dd0e123c2 100755 --- a/scripts/compile_pto_to_vpto_llvm.sh +++ b/scripts/compile_pto_to_vpto_llvm.sh @@ -15,12 +15,12 @@ ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" PTO_FILE="${1:-}" OUT_DIR_ARG="${2:-}" -PTOAS_BIN="${PTOAS_BIN:-${ROOT_DIR}/build/tools/ptoas/ptoas}" +PTOAS_BIN="${PTOAS_BIN:-}" PTOAS_FLAGS="${PTOAS_FLAGS:---pto-arch a5}" VPTO_FLAGS="${VPTO_FLAGS:---pto-backend=vpto --vpto-emit-hivm-llvm}" AICORE_ARCH="${AICORE_ARCH:-dav-c310-vec}" ASCEND_HOME_PATH="${ASCEND_HOME_PATH:-${HOME}/cann}" -BISHENG_BIN="" +BISHENG_BIN="${BISHENG_BIN:-}" BISHENG_FLAGS="${BISHENG_FLAGS:-}" LLVM_IR="" DEVICE_OBJ="" @@ -74,19 +74,21 @@ EOF [[ "${PTO_FILE}" == *.pto ]] || die "input must be a .pto file: ${PTO_FILE}" [[ -f "${PTO_FILE}" ]] || die "missing input file: ${PTO_FILE}" -set +u -source "${ROOT_DIR}/scripts/ptoas_env.sh" -set -u - if [[ -n "${ASCEND_HOME_PATH}" && -f "${ASCEND_HOME_PATH}/set_env.sh" ]]; then set +u source "${ASCEND_HOME_PATH}/set_env.sh" >/dev/null 2>&1 set -u fi +if [[ -z "${PTOAS_BIN}" ]]; then + PTOAS_BIN="$(command -v ptoas || true)" +elif [[ "${PTOAS_BIN}" != */* ]]; then + PTOAS_BIN="$(command -v "${PTOAS_BIN}" || true)" +fi BISHENG_BIN="${BISHENG_BIN:-${ASCEND_HOME_PATH}/bin/bisheng}" -[[ -x "${PTOAS_BIN}" ]] || die "PTOAS_BIN is not executable: ${PTOAS_BIN}" +[[ -n "${PTOAS_BIN}" && -x "${PTOAS_BIN}" ]] || \ + die "ptoas not found; run ./quick_install.sh or set PTOAS_BIN" command -v "${BISHENG_BIN}" >/dev/null 2>&1 || die "bisheng not found: ${BISHENG_BIN}" pto_abs="$(cd "$(dirname "${PTO_FILE}")" && pwd)/$(basename "${PTO_FILE}")" diff --git a/scripts/ptoas_env.sh b/scripts/ptoas_env.sh deleted file mode 100644 index b5e814ccda..0000000000 --- a/scripts/ptoas_env.sh +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -# PTOAS runtime environment bootstrap. -# Usage: -# source scripts/ptoas_env.sh -# -# Optional overrides before sourcing: -# export WORKSPACE_DIR=/path/to/workspace -# export LLVM_BUILD_DIR=/path/to/llvm-project/build-shared -# export PTO_SOURCE_DIR=/path/to/PTOAS -# export PTODSL_PYTHON_ROOT=/path/to/PTOAS/ptodsl -# export PTO_INSTALL_DIR=/path/to/PTOAS/install -# export PTO_PYTHON_BIN=/path/to/python3 -# export PTOAS_ENV_SKIP_SMOKE_TEST=1 # skip legacy MatMul/Abs sample checks -# CI shells skip the legacy smoke test by default. - -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - echo "This script must be sourced: source scripts/ptoas_env.sh" - exit 1 -fi - -_PTOAS_ENV_SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -_PTOAS_REPO_DIR="$(cd -- "${_PTOAS_ENV_SCRIPT_DIR}/.." && pwd)" - -# Default layout: -# / -# ├── PTOAS/ -# └── llvm-project/ -export PTO_SOURCE_DIR="${PTO_SOURCE_DIR:-${_PTOAS_REPO_DIR}}" -export WORKSPACE_DIR="${WORKSPACE_DIR:-$(cd -- "${PTO_SOURCE_DIR}/.." && pwd)}" -export LLVM_SOURCE_DIR="${LLVM_SOURCE_DIR:-${WORKSPACE_DIR}/llvm-project}" -export LLVM_BUILD_DIR="${LLVM_BUILD_DIR:-${LLVM_SOURCE_DIR}/build-shared}" -export PTO_INSTALL_DIR="${PTO_INSTALL_DIR:-${PTO_SOURCE_DIR}/install}" -export PTO_ISA_PATH="${PTO_ISA_PATH:-${WORKSPACE_DIR}/pto-isa}" -export ASCEND_HOME_PATH="${ASCEND_HOME_PATH:-${HOME}/cann}" - -export MLIR_PYTHON_ROOT="${MLIR_PYTHON_ROOT:-${LLVM_BUILD_DIR}/tools/mlir/python_packages/mlir_core}" -if [[ -z "${PTOAS_PYTHON_SITE:-}" ]]; then - PTOAS_PYTHON_SITE="$( - PTO_INSTALL_DIR="${PTO_INSTALL_DIR}" python3 - <<'PY' 2>/dev/null || true -import os -import sysconfig - -prefix = os.environ["PTO_INSTALL_DIR"] -print(sysconfig.get_path("purelib", vars={"base": prefix, "platbase": prefix})) -PY - )" -fi -export PTOAS_PYTHON_SITE -export PTO_PYTHON_ROOT="${PTO_PYTHON_ROOT:-${PTO_INSTALL_DIR}}" -export PTO_PYTHON_BUILD_ROOT="${PTO_PYTHON_BUILD_ROOT:-${PTO_SOURCE_DIR}/build/python}" -export PTODSL_PYTHON_ROOT="${PTODSL_PYTHON_ROOT:-${PTO_SOURCE_DIR}/ptodsl}" -export PYBIND11_CMAKE_DIR=$(python3 -m pybind11 --cmakedir) -export PTOAS_FLAGS="${PTOAS_FLAGS:-}" -export PTOAS_OUT_DIR="${PTOAS_OUT_DIR:-${PTO_SOURCE_DIR}/build/output}" - -_ptoas_prepend_path() { - local var_name="$1" - local value="$2" - local current="${!var_name:-}" - if [[ -z "${value}" ]]; then - return 0 - fi - if [[ ! -e "${value}" ]]; then - return 0 - fi - if [[ ":${current}:" == *":${value}:"* ]]; then - return 0 - fi - if [[ -z "${current}" ]]; then - printf -v "${var_name}" '%s' "${value}" - else - printf -v "${var_name}" '%s:%s' "${value}" "${current}" - fi - export "${var_name}" -} - -_ptoas_run_legacy_smoke_test() { - local python_bin="${PTO_PYTHON_BIN:-${PYTHON_BIN:-$(command -v python3 || command -v python || true)}}" - if [[ -z "${python_bin}" ]]; then - echo "error: unable to locate python3 or python for scripts/ptoas_env.sh" >&2 - return 1 - fi - - if ! command -v ptoas >/dev/null 2>&1; then - echo "error: ptoas is not on PATH after sourcing scripts/ptoas_env.sh" >&2 - return 1 - fi - - local tmp_root="${PTOAS_ENV_TMP:-${PTO_SOURCE_DIR}/tmp/set_ptoas_env}" - mkdir -p "${tmp_root}/MatMul" "${tmp_root}/Abs" - ( - cd "${PTO_SOURCE_DIR}/test/samples/MatMul" && - "${python_bin}" ./tmatmulk.py > "${tmp_root}/MatMul/tmatmulk.pto" && - ptoas "${tmp_root}/MatMul/tmatmulk.pto" -o "${tmp_root}/MatMul/tmatmulk.cpp" - ) - ( - cd "${PTO_SOURCE_DIR}/test/samples/Abs" && - "${python_bin}" ./abs.py > "${tmp_root}/Abs/abs.pto" && - ptoas --enable-insert-sync "${tmp_root}/Abs/abs.pto" -o "${tmp_root}/Abs/abs.cpp" - ) - - echo "test set_env: OK" -} - -# Prefer the in-tree PTO Python overlay plus LLVM's full MLIR package first. -# The install prefix may only contain the PTO overlay fragments, and when it is -# placed ahead of mlir_core it can shadow the real MLIR Python bindings. -_ptoas_prepend_path PYTHONPATH "${PTO_INSTALL_DIR}" -_ptoas_prepend_path PYTHONPATH "${PTO_PYTHON_ROOT}" -_ptoas_prepend_path PYTHONPATH "${PTOAS_PYTHON_SITE}" -_ptoas_prepend_path PYTHONPATH "${MLIR_PYTHON_ROOT}" -_ptoas_prepend_path PYTHONPATH "${PTO_PYTHON_BUILD_ROOT}" -_ptoas_prepend_path PYTHONPATH "${PTODSL_PYTHON_ROOT}" - -_ptoas_prepend_path LD_LIBRARY_PATH "${LLVM_BUILD_DIR}/lib" -_ptoas_prepend_path LD_LIBRARY_PATH "${PTO_INSTALL_DIR}/lib" -_ptoas_prepend_path LD_LIBRARY_PATH "${PTO_SOURCE_DIR}/build/lib" - -_ptoas_prepend_path PATH "${PTO_SOURCE_DIR}/build/tools/ptoas" - -if [[ -n "${PTO_PYTHON_BIN:-}" && -x "${PTO_PYTHON_BIN}" ]]; then - alias ptoas-python="${PTO_PYTHON_BIN}" -fi - -echo "[ptoas_env] PTO_SOURCE_DIR=${PTO_SOURCE_DIR}" -echo "[ptoas_env] LLVM_BUILD_DIR=${LLVM_BUILD_DIR}" -echo "[ptoas_env] PTO_INSTALL_DIR=${PTO_INSTALL_DIR}" -echo "[ptoas_env] PTO_ISA_PATH=${PTO_ISA_PATH}" -echo "[ptoas_env] ASCEND_HOME_PATH=${ASCEND_HOME_PATH}" -echo "[ptoas_env] PATH/LD_LIBRARY_PATH updated" - -_ptoas_env_skip_smoke="${PTOAS_ENV_SKIP_SMOKE_TEST:-0}" -if [[ -z "${PTOAS_ENV_SKIP_SMOKE_TEST:-}" && - ("${CI:-}" == "1" || "${CI:-}" == "true") ]]; then - _ptoas_env_skip_smoke=1 -fi - -if [[ "${_ptoas_env_skip_smoke}" != "1" ]]; then - _ptoas_run_legacy_smoke_test -fi - -unset -f _ptoas_prepend_path -unset -f _ptoas_run_legacy_smoke_test -unset _PTOAS_ENV_SCRIPT_DIR -unset _PTOAS_REPO_DIR -unset _ptoas_env_skip_smoke diff --git a/scripts/sim_dsl.sh b/scripts/sim_dsl.sh index 63dbf0b8ad..33d2cbec5e 100755 --- a/scripts/sim_dsl.sh +++ b/scripts/sim_dsl.sh @@ -129,7 +129,7 @@ print_msprof_log() { python_can_import_ptodsl() { local python_bin="$1" "${python_bin}" - <<'PY' >/dev/null 2>&1 -import mlir.ir # noqa: F401 +import ptoas.mlir.ir # noqa: F401 from ptodsl import pto # noqa: F401 PY } @@ -232,7 +232,7 @@ if [[ -n "${RESOLVED_PTOAS_BIN:-}" ]]; then export PTOAS_BIN="${RESOLVED_PTOAS_BIN}" fi if ! python_can_import_ptodsl "${RESOLVED_PYTHON_BIN}"; then - die "active Python environment cannot import ptodsl/mlir.ir; install the PTOAS wheel or use a preconfigured environment" + die "active Python environment cannot import ptodsl/ptoas.mlir.ir; install the PTOAS wheel or use a preconfigured environment" fi if ! command -v ptoas >/dev/null 2>&1; then die "ptoas is not available on PATH; install the PTOAS wheel or export PTOAS_BIN" diff --git a/test/dsl-st/README.md b/test/dsl-st/README.md index 94505052f5..442ba361d0 100644 --- a/test/dsl-st/README.md +++ b/test/dsl-st/README.md @@ -20,7 +20,6 @@ Python 环境,而不是在运行时自己修 `PYTHONPATH` 或 `sys.path`。 ```bash cd $PTOAS_REPO_ROOT pip install -e . --no-build-isolation -source scripts/ptoas_env.sh ``` 如果你在验证 release/CI wheel,也可以直接: diff --git a/test/dsl/abs.py b/test/dsl/abs.py index 1917a57250..807eca7d0c 100644 --- a/test/dsl/abs.py +++ b/test/dsl/abs.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -import mlir.dialects.pto as pto +import ptoas.mlir.dialects.pto as pto @pto.vkernel(target="a5", name="abs_kernel_2d") diff --git a/test/dsl/strict_vecscope.py b/test/dsl/strict_vecscope.py index 7badac2ae4..03bf99a801 100644 --- a/test/dsl/strict_vecscope.py +++ b/test/dsl/strict_vecscope.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -import mlir.dialects.pto as pto +import ptoas.mlir.dialects.pto as pto @pto.vkernel(target="a5", name="abs_strict_vecscope_kernel_2d") diff --git a/test/dsl/template_abs.py b/test/dsl/template_abs.py index dc674adee0..512ad54f08 100644 --- a/test/dsl/template_abs.py +++ b/test/dsl/template_abs.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -import mlir.dialects.pto as pto +import ptoas.mlir.dialects.pto as pto @pto.vkernel(target="a5", name="template_abs_kernel") diff --git a/test/lit/lit.cfg.py b/test/lit/lit.cfg.py index 94e6df594a..cb8d4a408b 100644 --- a/test/lit/lit.cfg.py +++ b/test/lit/lit.cfg.py @@ -54,6 +54,13 @@ 'ASCEND_HOME_PATH', 'ASCEND_OPP_PATH', 'ASCEND_AICPU_PATH', 'ASCEND_TOOLKIT_HOME', 'LD_LIBRARY_PATH', 'PYTHONPATH']) +# Keep build-tree lit tests self-contained. The PTOAS build stages the complete +# MLIR Python runtime together with generated PTO dialect modules and the PTO +# extension under one build-tree Python root. +if getattr(config, 'enable_bindings_python', False): + llvm_config.with_environment( + 'PYTHONPATH', [config.ptoas_python_dir], append_path=True) + llvm_config.use_default_substitutions() # excludes: A list of directories to exclude from the testsuite. The 'Inputs' diff --git a/test/lit/lit.site.cfg.py.in b/test/lit/lit.site.cfg.py.in index 47f7ccbc59..3972bbf620 100644 --- a/test/lit/lit.site.cfg.py.in +++ b/test/lit/lit.site.cfg.py.in @@ -19,7 +19,8 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.mlir_obj_dir = "@MLIR_BINARY_DIR@" config.mlir_lib_dir = "@MLIR_LIB_DIR@" config.python_executable = "@Python3_EXECUTABLE@" -# config.enable_bindings_python = @MLIR_ENABLE_BINDINGS_PYTHON@ +config.enable_bindings_python = "@PTO_ENABLE_PYTHON_BINDING@" == "ON" +config.ptoas_python_dir = path(r"@CMAKE_BINARY_DIR@/python") config.ptoir_src_root = "@CMAKE_SOURCE_DIR@" config.ptoir_obj_root = "@CMAKE_BINARY_DIR@" config.pto_enable_vfsim_costmodel = "@PTO_ENABLE_VFSIM_COSTMODEL@" == "ON" diff --git a/test/python/compact_tile_buf_asm.py b/test/python/compact_tile_buf_asm.py index 8c07e945ce..f73be451f5 100644 --- a/test/python/compact_tile_buf_asm.py +++ b/test/python/compact_tile_buf_asm.py @@ -1,7 +1,14 @@ #!/usr/bin/env python3 - -from mlir.ir import Context, F32Type, MLIRError, Module -from mlir.dialects import pto +# Copyright (c) 2026 Huawei Technologies Co., Ltd. +# This program is free software, you can redistribute it and/or modify it under the terms and conditions of +# CANN Open Software License Agreement Version 2.0 (the "License"). +# Please refer to the License for details. You may not use this file except in compliance with the License. +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +# See LICENSE in the root of the software repository for the full text of the License. + +from ptoas.mlir.ir import Context, F32Type, MLIRError, Module +from ptoas.mlir.dialects import pto def expect_equal(actual: str, expected: str, label: str) -> None: diff --git a/test/python/low_precision_types.py b/test/python/low_precision_types.py index dde603f191..38e9999de7 100644 --- a/test/python/low_precision_types.py +++ b/test/python/low_precision_types.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context -from mlir.dialects import pto +from ptoas.mlir.ir import Context +from ptoas.mlir.dialects import pto def assert_contains(text: str, needle: str) -> None: @@ -21,10 +21,14 @@ def main() -> None: pto.register_dialect(ctx) hif8 = pto.HiF8Type.get(ctx) + hif8x2 = pto.HiF8x2Type.get(ctx) + f8e8m0 = pto.F8E8M0Type.get(ctx) f4e1 = pto.F4E1M2x2Type.get(ctx) f4e2 = pto.F4E2M1x2Type.get(ctx) assert_contains(str(hif8), "hif8") + assert_contains(str(hif8x2), "hif8x2") + assert_contains(str(f8e8m0), "f8E8M0") assert_contains(str(f4e1), "f4E1M2x2") assert_contains(str(f4e2), "f4E2M1x2") diff --git a/test/python/memory_consistency_bindings.py b/test/python/memory_consistency_bindings.py index e52d26bae5..a227332d3b 100644 --- a/test/python/memory_consistency_bindings.py +++ b/test/python/memory_consistency_bindings.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module -from mlir.dialects import pto +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module +from ptoas.mlir.dialects import pto def assert_contains(text: str, needle: str) -> None: diff --git a/test/python/test_docker_runtime_packaging.py b/test/python/test_docker_runtime_packaging.py deleted file mode 100644 index 646d621db3..0000000000 --- a/test/python/test_docker_runtime_packaging.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import unittest -from pathlib import Path - - -REPO_ROOT = Path(__file__).resolve().parents[2] -DOCKERFILE = REPO_ROOT / "docker" / "Dockerfile" -COPY_DEPS_SCRIPT = REPO_ROOT / "docker" / "copy_ptoas_deps.sh" -COLLECT_DIST_SCRIPT = REPO_ROOT / "docker" / "collect_ptoas_dist.sh" -COLLECT_DIST_MAC_SCRIPT = REPO_ROOT / "docker" / "collect_ptoas_dist_mac.sh" -BUILD_WHEEL_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "build_wheel.yml" -BUILD_WHEEL_MAC_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "build_wheel_mac.yml" - - -class DockerRuntimePackagingTests(unittest.TestCase): - def test_runtime_image_uses_wheel_entrypoint_instead_of_copied_wrapper(self): - dockerfile = DOCKERFILE.read_text(encoding="utf-8") - - self.assertIn("COPY --from=builder /wheelhouse/ptoas*.whl /tmp/", dockerfile) - self.assertIn( - "RUN pip install --no-cache-dir /tmp/ptoas*.whl && rm /tmp/ptoas*.whl", - dockerfile, - ) - self.assertNotIn( - "COPY --from=builder /llvm-workspace/PTOAS/build-release/tools/ptoas/ptoas /usr/local/bin/ptoas", - dockerfile, - ) - self.assertNotIn("/usr/local/lib/ptoas", dockerfile) - - def test_dependency_collection_roots_at_shared_module(self): - script = COPY_DEPS_SCRIPT.read_text(encoding="utf-8") - - self.assertIn('PTOAS_SHARED_MODULE="${PTO_INSTALL_DIR}/lib/ptoas.so"', script) - self.assertIn('done < <(linux_runtime_dep_paths "$PTOAS_SHARED_MODULE")', script) - self.assertNotIn('PTOAS_BIN="${PTO_BUILD_DIR}/tools/ptoas/ptoas"', script) - self.assertNotIn('done < <(linux_runtime_dep_paths "$PTOAS_BIN")', script) - - def test_linux_dist_stages_install_tree_python_root(self): - script = COLLECT_DIST_SCRIPT.read_text(encoding="utf-8") - - self.assertIn('PTOAS_WRAPPER_PKG_SRC_DIR="${PTO_INSTALL_DIR}/ptoas"', script) - self.assertIn('PTOAS_WRAPPER_PKG_DIST_DIR="${PTOAS_DIST_DIR}/ptoas"', script) - self.assertIn('PTOAS_WHEEL_BOOTSTRAP_SRC="${PTO_INSTALL_DIR}/ptoas_wheel_bootstrap.py"', script) - self.assertIn('cp "${PTOAS_WHEEL_BOOTSTRAP_SRC}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}"', script) - self.assertIn('test -f "${PTOAS_WRAPPER_PKG_DIST_DIR}/_runtime_entry.py"', script) - self.assertIn('test -f "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}"', script) - self.assertIn('"${PTOAS_DIST_DIR}/bin/ptoas" --version', script) - self.assertNotIn("PTOAS_PYTHON_ROOT_DIST_DIR", script) - self.assertNotIn("export PTOAS_PYTHON_ROOT", script) - self.assertNotIn('cat > "${PTOAS_DIST_DIR}/ptoas"', script) - - def test_macos_dist_stages_install_tree_python_root(self): - script = COLLECT_DIST_MAC_SCRIPT.read_text(encoding="utf-8") - - self.assertIn('PTOAS_SHARED_MODULE="${PTO_INSTALL_DIR}/lib/ptoas.so"', script) - self.assertIn('PTOAS_WRAPPER_PKG_SRC_DIR="${PTO_INSTALL_DIR}/ptoas"', script) - self.assertIn('PTOAS_WRAPPER_PKG_DIST_DIR="${PTOAS_DIST_DIR}/ptoas"', script) - self.assertIn('PTOAS_WHEEL_BOOTSTRAP_SRC="${PTO_INSTALL_DIR}/ptoas_wheel_bootstrap.py"', script) - self.assertIn('cp "${PTOAS_WHEEL_BOOTSTRAP_SRC}" "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}"', script) - self.assertIn('collect_dylibs "${PTOAS_SHARED_MODULE_DIST_PATH}"', script) - self.assertIn('test -f "${PTOAS_WRAPPER_PKG_DIST_DIR}/_runtime_entry.py"', script) - self.assertIn('test -f "${PTOAS_WHEEL_BOOTSTRAP_DIST_PATH}"', script) - self.assertIn('"${PTOAS_DIST_DIR}/bin/ptoas" --version', script) - self.assertNotIn('cat > "${PTOAS_DIST_DIR}/ptoas"', script) - - def test_dist_archives_use_bin_entrypoint(self): - linux_workflow = BUILD_WHEEL_WORKFLOW.read_text(encoding="utf-8") - mac_workflow = BUILD_WHEEL_MAC_WORKFLOW.read_text(encoding="utf-8") - - self.assertIn('chmod +x "$GITHUB_WORKSPACE/ptoas-dist/bin/ptoas"', linux_workflow) - self.assertNotIn('chmod +x "$GITHUB_WORKSPACE/ptoas-dist/ptoas"', linux_workflow) - self.assertIn('chmod +x "$GITHUB_WORKSPACE/ptoas-dist/bin/ptoas"', mac_workflow) - self.assertNotIn('chmod +x "$GITHUB_WORKSPACE/ptoas-dist/ptoas"', mac_workflow) - self.assertIn('"$TEST_DIR/extracted/bin/ptoas" --version', mac_workflow) - self.assertNotIn('"$TEST_DIR/extracted/ptoas" --version', mac_workflow) - - def test_wheel_import_smoke_covers_polluted_ptoas_version(self): - script = (REPO_ROOT / "docker" / "test_wheel_imports.sh").read_text(encoding="utf-8") - - self.assertIn("Testing installed ptoas console entry under polluted Python and LLVM paths...", script) - self.assertIn("POLLUTED_ENV_DIR=\"${TEST_TMPDIR}/polluted-env\"", script) - self.assertIn('PYTHONPATH="${POLLUTED_ENV_DIR}"', script) - self.assertIn("POLLUTED_PTOAS_VERSION_OUTPUT", script) - self.assertIn('"/tmp/polluted-llvm"', script) - self.assertIn('"/tmp/polluted-dylib"', script) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/python/test_ptoas_build_backend.py b/test/python/test_ptoas_build_backend.py deleted file mode 100644 index 09ea739f14..0000000000 --- a/test/python/test_ptoas_build_backend.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import tempfile -import unittest -import zipfile -from pathlib import Path -from unittest import mock - -import _ptoas_build_backend as build_backend - - -class PtoasBuildBackendTests(unittest.TestCase): - def test_prepare_metadata_honors_package_name_override(self): - with tempfile.TemporaryDirectory() as temp_dir, mock.patch.dict( - build_backend.os.environ, - { - "PTOAS_PYTHON_PACKAGE_NAME": "ptoas-vmi", - "PTOAS_PYTHON_PACKAGE_VERSION": "0.1.0", - }, - clear=False, - ): - dist_info_name = build_backend.prepare_metadata_for_build_wheel(temp_dir) - - dist_info = Path(temp_dir) / dist_info_name - metadata = (dist_info / "METADATA").read_text(encoding="utf-8") - - self.assertEqual(dist_info_name, "ptoas_vmi-0.1.0.dist-info") - self.assertIn("Name: ptoas-vmi", metadata) - self.assertIn("Version: 0.1.0", metadata) - - def test_cmake_build_driver_is_used_for_build_and_install(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - repo = temp_root / "repo" - build_dir = temp_root / "build" - llvm_build = temp_root / "llvm-build" - install_dir = temp_root / "install" - (repo / "cmake").mkdir(parents=True) - (install_dir / "lib").mkdir(parents=True) - (install_dir / "lib" / "ptoas.so").write_bytes(b"fake shared module") - - check_call_args = [] - - def fake_check_call(args): - check_call_args.append(args) - - with mock.patch.object(build_backend, "_REPO", repo), mock.patch.object( - build_backend, "_BUILD_DIR", build_dir - ), mock.patch.object( - build_backend, "_LLVM_BUILD_DIR", llvm_build - ), mock.patch.object( - build_backend, "_PTO_INSTALL_DIR", install_dir - ), mock.patch.object( - build_backend, - "_should_use_linux_hardening_cache", - return_value=False, - ), mock.patch.object( - build_backend.subprocess, - "check_output", - return_value="/tmp/pybind11-cmake", - ), mock.patch.object( - build_backend.subprocess, - "check_call", - side_effect=fake_check_call, - ), mock.patch.object( - build_backend, - "_assert_installed_ptodsl_payload", - ): - build_backend._cmake_configure_and_build() - - self.assertEqual( - check_call_args[-2], - ["cmake", "--build", str(build_dir)], - ) - self.assertEqual( - check_call_args[-1], - ["cmake", "--build", str(build_dir), "--target", "install"], - ) - - def test_installed_shared_module_must_be_non_empty(self): - with tempfile.TemporaryDirectory() as temp_dir: - install_dir = Path(temp_dir) / "install" - shared_module = install_dir / "lib" / "ptoas.so" - shared_module.parent.mkdir(parents=True) - shared_module.write_bytes(b"") - - with mock.patch.object(build_backend, "_PTO_INSTALL_DIR", install_dir): - with self.assertRaisesRegex(RuntimeError, "missing or empty"): - build_backend._assert_installed_ptoas_shared_module() - - def test_build_editable_routes_console_entry_through_wheel_bootstrap(self): - with tempfile.TemporaryDirectory() as temp_dir, mock.patch.dict( - build_backend.os.environ, - { - "PTOAS_PYTHON_PACKAGE_NAME": "ptoas", - "PTOAS_PYTHON_PACKAGE_VERSION": "0.1.0", - }, - clear=False, - ), mock.patch.object( - build_backend, - "_cmake_configure_and_build", - ) as cmake_build: - wheel_dir = Path(temp_dir) / "wheel" - wheel_dir.mkdir(parents=True, exist_ok=True) - - wheel_name = build_backend.build_editable(str(wheel_dir)) - wheel_path = wheel_dir / wheel_name - - with zipfile.ZipFile(wheel_path) as zf: - entry_points = zf.read("ptoas-0.1.0.dist-info/entry_points.txt").decode("utf-8") - - cmake_build.assert_called_once_with(skip_install=True) - - self.assertIn("ptoas=ptoas_wheel_bootstrap:main", entry_points) - self.assertNotIn("ptoas._launcher", entry_points) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/python/test_release_version_scripts.py b/test/python/test_release_version_scripts.py deleted file mode 100644 index 235face241..0000000000 --- a/test/python/test_release_version_scripts.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import subprocess -import sys -import tempfile -from pathlib import Path -import unittest - - -REPO_ROOT = Path(__file__).resolve().parents[2] - - -class ReleaseVersionScriptTests(unittest.TestCase): - def test_ptoas_version_script_accepts_plain_v_tag(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text("project(ptoas VERSION 0.51)\n", encoding="utf-8") - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/compute_ptoas_version.py"), - "--cmake-file", - str(cmake_file), - "--check-tag", - "v0.51", - ], - check=True, - capture_output=True, - text=True, - ) - self.assertEqual(result.stdout.strip(), "0.51") - - def test_ptoas_version_script_accepts_ptoas_tag_prefix(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text("project(ptoas VERSION 0.51)\n", encoding="utf-8") - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/compute_ptoas_version.py"), - "--cmake-file", - str(cmake_file), - "--check-tag", - "ptoas-v0.51", - ], - check=True, - capture_output=True, - text=True, - ) - self.assertEqual(result.stdout.strip(), "0.51") - - def test_vmi_version_script_accepts_vmi_tag_prefix(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text( - 'project(ptoas VERSION 0.51)\nset(PTOAS_VMI_VERSION "0.1.0")\n', - encoding="utf-8", - ) - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/compute_vmi_version.py"), - "--cmake-file", - str(cmake_file), - "--check-tag", - "vmi-v0.1.0", - ], - check=True, - capture_output=True, - text=True, - ) - self.assertEqual(result.stdout.strip(), "0.1.0") - - def test_vmi_version_bump_updates_only_vmi_version(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text( - 'project(ptoas VERSION 0.51)\nset(PTOAS_VMI_VERSION "0.1.9")\n', - encoding="utf-8", - ) - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/update_vmi_version.py"), - "--cmake-file", - str(cmake_file), - "--version", - "vmi-v0.1.9", - "--next", - ], - check=True, - capture_output=True, - text=True, - ) - self.assertEqual(result.stdout.strip(), "0.1.10") - self.assertEqual( - cmake_file.read_text(encoding="utf-8"), - 'project(ptoas VERSION 0.51)\nset(PTOAS_VMI_VERSION "0.1.10")\n', - ) - - def test_vmi_version_bump_rejects_ptoas_tag(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text( - 'project(ptoas VERSION 0.51)\nset(PTOAS_VMI_VERSION "0.1.0")\n', - encoding="utf-8", - ) - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/update_vmi_version.py"), - "--cmake-file", - str(cmake_file), - "--version", - "v0.51", - "--next", - ], - capture_output=True, - text=True, - ) - self.assertNotEqual(result.returncode, 0) - - def test_ptoas_version_bump_rejects_vmi_tag(self): - with tempfile.TemporaryDirectory() as temp_dir: - temp_root = Path(temp_dir) - cmake_file = temp_root / "CMakeLists.txt" - cmake_file.write_text("project(ptoas VERSION 0.51)\n", encoding="utf-8") - result = subprocess.run( - [ - sys.executable, - str(REPO_ROOT / ".github/scripts/update_ptoas_base_version.py"), - "--cmake-file", - str(cmake_file), - "--version", - "vmi-v0.1.0", - ], - capture_output=True, - text=True, - ) - self.assertNotEqual(result.returncode, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/python/test_validate_wheel_payload.py b/test/python/test_validate_wheel_payload.py deleted file mode 100644 index 5b02a6e95e..0000000000 --- a/test/python/test_validate_wheel_payload.py +++ /dev/null @@ -1,261 +0,0 @@ -#!/usr/bin/env python3 -# Copyright (c) 2026 Huawei Technologies Co., Ltd. -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of -# CANN Open Software License Agreement Version 2.0 (the "License"). -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. - -import subprocess -import tempfile -import unittest -import zipfile -from pathlib import Path - - -REPO_ROOT = Path(__file__).resolve().parents[2] -VALIDATOR = REPO_ROOT / "docker" / "validate_wheel_payload.py" -CREATE_WHEEL = REPO_ROOT / "docker" / "create_wheel.sh" -LINUX_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "build_wheel.yml" -MAC_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "build_wheel_mac.yml" -WHEEL_IMPORTS = REPO_ROOT / "docker" / "test_wheel_imports.sh" -CI_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "ci.yml" -CI_SIM_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "ci_sim.yml" - - -class ValidateWheelPayloadTests(unittest.TestCase): - def _make_wheel( - self, - root: Path, - *, - include_runtime_so: bool, - include_runtime_entry: bool = True, - include_bootstrap: bool = True, - entry_points_text: str = "[console_scripts]\nptoas=ptoas_wheel_bootstrap:main\n", - wheel_stem: str = "ptoas", - dist_info_stem: str = "ptoas", - ) -> Path: - wheel = root / f"{wheel_stem}-1.2.3-cp311-cp311-linux_x86_64.whl" - with zipfile.ZipFile(wheel, "w") as zf: - if include_bootstrap: - zf.writestr("ptoas_wheel_bootstrap.py", "") - zf.writestr("ptoas/__init__.py", "") - zf.writestr("ptoas/_launcher.py", "") - if include_runtime_entry: - zf.writestr("ptoas/_runtime_entry.py", "") - if include_runtime_so: - zf.writestr("ptoas/_runtime/lib/ptoas.so", "fake") - zf.writestr( - f"{dist_info_stem}-1.2.3.dist-info/entry_points.txt", - entry_points_text, - ) - return wheel - - def test_validator_accepts_current_runtime_payload_layout(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel(Path(temp_dir), include_runtime_so=True) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertEqual(result.returncode, 0, result.stderr) - self.assertIn("validated wheel payload and launcher contract", result.stdout) - - def test_validator_rejects_missing_runtime_shared_module(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel(Path(temp_dir), include_runtime_so=False) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertNotEqual(result.returncode, 0) - self.assertIn("ptoas/_runtime/lib/ptoas.so", result.stderr) - - def test_validator_rejects_missing_runtime_entry_module(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel( - Path(temp_dir), - include_runtime_so=True, - include_runtime_entry=False, - ) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertNotEqual(result.returncode, 0) - self.assertIn("ptoas/_runtime_entry.py", result.stderr) - - def test_validator_rejects_missing_wheel_bootstrap_module(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel( - Path(temp_dir), - include_runtime_so=True, - include_bootstrap=False, - ) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertNotEqual(result.returncode, 0) - self.assertIn("ptoas_wheel_bootstrap.py", result.stderr) - - def test_validator_rejects_legacy_ptoas_launcher_entrypoint(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel( - Path(temp_dir), - include_runtime_so=True, - entry_points_text="[console_scripts]\nptoas=ptoas._launcher:main\n", - ) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertNotEqual(result.returncode, 0) - self.assertIn("ptoas_wheel_bootstrap:main", result.stderr) - - def test_validator_accepts_normalized_entrypoint_spacing(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel( - Path(temp_dir), - include_runtime_so=True, - entry_points_text="[console_scripts]\nptoas = ptoas_wheel_bootstrap:main\n", - ) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertEqual(result.returncode, 0, result.stderr) - - def test_validator_accepts_vmi_distribution_name(self): - with tempfile.TemporaryDirectory() as temp_dir: - wheel = self._make_wheel( - Path(temp_dir), - include_runtime_so=True, - wheel_stem="ptoas_vmi", - dist_info_stem="ptoas_vmi", - ) - result = subprocess.run( - ["python3", str(VALIDATOR), str(wheel)], - capture_output=True, - text=True, - check=False, - ) - - self.assertEqual(result.returncode, 0, result.stderr) - self.assertIn("validated wheel payload and launcher contract", result.stdout) - - def test_workflows_and_shell_probe_reuse_shared_validator(self): - validator_call = 'python "$PTO_SOURCE_DIR/docker/validate_wheel_payload.py" "$PTO_SOURCE_DIR/build/wheel-dist"' - self.assertIn( - validator_call, - LINUX_WORKFLOW.read_text(encoding="utf-8"), - ) - self.assertIn( - validator_call, - MAC_WORKFLOW.read_text(encoding="utf-8"), - ) - self.assertIn( - '"${PYTHON_BIN}" "${REPO_ROOT}/docker/validate_wheel_payload.py" "${TEST_WHEEL}"', - WHEEL_IMPORTS.read_text(encoding="utf-8"), - ) - - def test_release_workflows_separate_cli_and_wheel_versions(self): - linux_workflow = LINUX_WORKFLOW.read_text(encoding="utf-8") - mac_workflow = MAC_WORKFLOW.read_text(encoding="utf-8") - - self.assertIn("workflow_dispatch:", linux_workflow) - self.assertIn("release_kind:", linux_workflow) - self.assertIn('type: choice', linux_workflow) - self.assertIn('--mode release)', linux_workflow) - self.assertIn( - "if: github.event_name != 'release' || startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v')", - linux_workflow, - ) - self.assertIn( - "if: (github.event_name == 'release' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v'))) || github.event_name == 'schedule'", - linux_workflow, - ) - self.assertIn('PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}"', linux_workflow) - self.assertIn('PTOAS_RELEASE_VERSION_OVERRIDE="${PTOAS_CLI_VERSION}"', linux_workflow) - self.assertIn('export PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_VERSION}"', linux_workflow) - - self.assertIn("workflow_dispatch:", mac_workflow) - self.assertIn("release_kind:", mac_workflow) - self.assertIn('type: choice', mac_workflow) - self.assertIn('--mode release)', mac_workflow) - self.assertIn( - "if: github.event_name != 'release' || startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v')", - mac_workflow, - ) - self.assertIn( - "if: (github.event_name == 'release' && (startsWith(github.ref_name, 'v') || startsWith(github.ref_name, 'ptoas-v'))) || github.event_name == 'schedule'", - mac_workflow, - ) - self.assertIn('PTOAS_CLI_VERSION="vmi ${PTOAS_VERSION}"', mac_workflow) - self.assertIn('PTOAS_RELEASE_VERSION_OVERRIDE="${PTOAS_CLI_VERSION}"', mac_workflow) - self.assertIn('export PTOAS_PYTHON_PACKAGE_VERSION="${PTOAS_VERSION}"', mac_workflow) - - def test_create_wheel_script_validates_package_name(self): - script = CREATE_WHEEL.read_text(encoding="utf-8") - - self.assertIn( - "if [[ ! \"${PTOAS_PYTHON_PACKAGE_NAME}\" =~ ^[A-Za-z0-9]+([-_.][A-Za-z0-9]+)*$ ]]; then", - script, - ) - self.assertIn( - "Error: invalid PTOAS_PYTHON_PACKAGE_NAME", - script, - ) - - def test_wheel_imports_script_keeps_clean_env_ptoas_smoke(self): - script = WHEEL_IMPORTS.read_text(encoding="utf-8") - - self.assertIn('EXPECTED_PTOAS_CLI_VERSION="${PTOAS_CLI_VERSION:-${PTOAS_VERSION:-}}"', script) - self.assertIn('env -i \\', script) - self.assertIn('CLEAN_ENV_PTO="${CLEAN_ENV_PTO}" \\', script) - self.assertIn('CLEAN_ENV_LOG="${CLEAN_ENV_DIR}/wheel-clean-env-probe.log"', script) - self.assertIn('CLEAN_ENV_PTO_IR="${CLEAN_ENV_DIR}/wheel-clean-env-probe.pto.ir"', script) - self.assertIn('def wheel_clean_env_probe():', script) - self.assertIn('pto.alloc_tile(shape=[1, 16], dtype=pto.f32, addr=0)', script) - self.assertIn('pto.castptr(pto.const(0, dtype=pto.ui64), pto.ptr(pto.f32, "gm"))', script) - self.assertIn('pto.tile.load(a_view, a_tile)', script) - self.assertIn('pto.tile.store(o_tile, o_view)', script) - self.assertIn('--emit-pto-ir "${CLEAN_ENV_PTO}" -o "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('def wheel_clean_env_probe(', script) - self.assertIn('"${PTOAS_ENTRYPOINT}" --pto-arch=a5 --pto-backend=vpto --pto-level=level3 --enable-tile-op-expand --emit-pto-ir "${CLEAN_ENV_PTO}" -o "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('>"${CLEAN_ENV_LOG}" 2>&1', script) - self.assertIn('grep -q "wheel_clean_env_probe" "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('grep -q "pto.tload" "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('grep -q "pto.tstore" "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('grep -q "candidates = " "${CLEAN_ENV_PTO_IR}"', script) - self.assertIn('grep -q "TileLib daemon started successfully" "${CLEAN_ENV_LOG}"', script) - self.assertIn('grep -q "TileLib daemon stopped" "${CLEAN_ENV_LOG}"', script) - - def test_ci_workflows_accept_generic_ptoas_wheel_glob(self): - self.assertIn("name 'ptoas*.whl'", CI_WORKFLOW.read_text(encoding="utf-8")) - ci_sim_text = CI_SIM_WORKFLOW.read_text(encoding="utf-8") - self.assertIn("name 'ptoas*.whl'", ci_sim_text) - self.assertNotIn("name 'ptoas-*.whl'", ci_sim_text) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/samples/Abs/abs.py b/test/samples/Abs/abs.py index 5d01854e83..7e3a862254 100644 --- a/test/samples/Abs/abs.py +++ b/test/samples/Abs/abs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/AddPtr/addptr.py b/test/samples/AddPtr/addptr.py index 603162e98e..2a5cddd3bc 100644 --- a/test/samples/AddPtr/addptr.py +++ b/test/samples/AddPtr/addptr.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/AddPtr/addptr_chain.py b/test/samples/AddPtr/addptr_chain.py index cc9a3da26d..7d460cbe8e 100644 --- a/test/samples/AddPtr/addptr_chain.py +++ b/test/samples/AddPtr/addptr_chain.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/AddPtr/addptr_dynamic.py b/test/samples/AddPtr/addptr_dynamic.py index ce25d91178..a6c81e5e55 100644 --- a/test/samples/AddPtr/addptr_dynamic.py +++ b/test/samples/AddPtr/addptr_dynamic.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/AddPtr/addptr_f16.py b/test/samples/AddPtr/addptr_f16.py index 16ef95e3bc..0db5337049 100644 --- a/test/samples/AddPtr/addptr_f16.py +++ b/test/samples/AddPtr/addptr_f16.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, IndexType def build(): diff --git a/test/samples/Addc/addc.py b/test/samples/Addc/addc.py index 460e194c07..89209b44d8 100644 --- a/test/samples/Addc/addc.py +++ b/test/samples/Addc/addc.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Adds/adds.py b/test/samples/Adds/adds.py index 1a2c02b070..0cb7e53081 100644 --- a/test/samples/Adds/adds.py +++ b/test/samples/Adds/adds.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Addsc/addsc.py b/test/samples/Addsc/addsc.py index 1d96ed7dff..a15e6cc3eb 100644 --- a/test/samples/Addsc/addsc.py +++ b/test/samples/Addsc/addsc.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/AllocTile/alloc_tile_addr.py b/test/samples/AllocTile/alloc_tile_addr.py index 6072a6098c..452b408e63 100644 --- a/test/samples/AllocTile/alloc_tile_addr.py +++ b/test/samples/AllocTile/alloc_tile_addr.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IntegerType, IntegerAttr, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IntegerType, IntegerAttr, IndexType def build(): diff --git a/test/samples/And/and.py b/test/samples/And/and.py index 0bb8cb7a03..b138cc5041 100644 --- a/test/samples/And/and.py +++ b/test/samples/And/and.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Ands/ands.py b/test/samples/Ands/ands.py index a34372db67..1bdb4ef328 100644 --- a/test/samples/Ands/ands.py +++ b/test/samples/Ands/ands.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType, IntegerAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType, IntegerAttr def build(): diff --git a/test/samples/AsyncComm/async_comm.py b/test/samples/AsyncComm/async_comm.py index f8e4177f63..3efa0b39ce 100644 --- a/test/samples/AsyncComm/async_comm.py +++ b/test/samples/AsyncComm/async_comm.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, F32Type, IntegerType, IntegerAttr, IndexType, Operation, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, F32Type, IntegerType, IntegerAttr, IndexType, Operation, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def _build_async_session(scratch, workspace, i32, ctx, sync_id=0): diff --git a/test/samples/AsyncComm/tget_async_kernel_impl_like.py b/test/samples/AsyncComm/tget_async_kernel_impl_like.py index 691f1cb160..ca93990421 100644 --- a/test/samples/AsyncComm/tget_async_kernel_impl_like.py +++ b/test/samples/AsyncComm/tget_async_kernel_impl_like.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, F32Type, @@ -19,7 +19,7 @@ Operation, Type, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def _build_async_session(scratch, workspace, i32, ctx, sync_id=0): diff --git a/test/samples/AsyncComm/tput_async_kernel_impl_like.py b/test/samples/AsyncComm/tput_async_kernel_impl_like.py index 63551fb208..73a3af2e67 100644 --- a/test/samples/AsyncComm/tput_async_kernel_impl_like.py +++ b/test/samples/AsyncComm/tput_async_kernel_impl_like.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, F32Type, @@ -19,7 +19,7 @@ Operation, Type, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def _build_async_session(scratch, workspace, i32, ctx, sync_id=0): diff --git a/test/samples/Bf16/bf16_tile.py b/test/samples/Bf16/bf16_tile.py index 54b08ece08..f08e6fd68a 100644 --- a/test/samples/Bf16/bf16_tile.py +++ b/test/samples/Bf16/bf16_tile.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -15,7 +15,7 @@ BF16Type, StringAttr, ) -from mlir.dialects import func, arith, pto, builtin +from ptoas.mlir.dialects import func, arith, pto, builtin def _idx_const(v: int): diff --git a/test/samples/Ci/ci.py b/test/samples/Ci/ci.py index d7d374930c..ad5d337231 100644 --- a/test/samples/Ci/ci.py +++ b/test/samples/Ci/ci.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType, IntegerAttr, BoolAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType, IntegerAttr, BoolAttr def build(): diff --git a/test/samples/Cmp/cmp.py b/test/samples/Cmp/cmp.py index b71552638d..fbbada8478 100644 --- a/test/samples/Cmp/cmp.py +++ b/test/samples/Cmp/cmp.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Cmps/cmps.py b/test/samples/Cmps/cmps.py index 17eae6b9be..2b8f0bb7ff 100644 --- a/test/samples/Cmps/cmps.py +++ b/test/samples/Cmps/cmps.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Colexpand/colexpand.py b/test/samples/Colexpand/colexpand.py index 044dfcb225..e2f9deed8a 100644 --- a/test/samples/Colexpand/colexpand.py +++ b/test/samples/Colexpand/colexpand.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandadd/colexpandadd.py b/test/samples/Colexpandadd/colexpandadd.py index 94df4271b2..5043948b7d 100644 --- a/test/samples/Colexpandadd/colexpandadd.py +++ b/test/samples/Colexpandadd/colexpandadd.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpanddiv/colexpanddiv.py b/test/samples/Colexpanddiv/colexpanddiv.py index b3e6679608..f6faf69413 100644 --- a/test/samples/Colexpanddiv/colexpanddiv.py +++ b/test/samples/Colexpanddiv/colexpanddiv.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpanddiv/colexpanddiv_src1_vcol_mismatch_invalid.py b/test/samples/Colexpanddiv/colexpanddiv_src1_vcol_mismatch_invalid.py index aa2e612c1c..ea67e95bf3 100644 --- a/test/samples/Colexpanddiv/colexpanddiv_src1_vcol_mismatch_invalid.py +++ b/test/samples/Colexpanddiv/colexpanddiv_src1_vcol_mismatch_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Colexpandexpdif/colexpandexpdif.py b/test/samples/Colexpandexpdif/colexpandexpdif.py index 7ec49106fd..bb207c8ebc 100644 --- a/test/samples/Colexpandexpdif/colexpandexpdif.py +++ b/test/samples/Colexpandexpdif/colexpandexpdif.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandexpdif/colexpandexpdif_dtype_invalid.py b/test/samples/Colexpandexpdif/colexpandexpdif_dtype_invalid.py index d507da8518..429a2f8b50 100644 --- a/test/samples/Colexpandexpdif/colexpandexpdif_dtype_invalid.py +++ b/test/samples/Colexpandexpdif/colexpandexpdif_dtype_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import IntegerType def build(): diff --git a/test/samples/Colexpandmax/colexpandmax.py b/test/samples/Colexpandmax/colexpandmax.py index f7bbf72c69..681661c8f0 100644 --- a/test/samples/Colexpandmax/colexpandmax.py +++ b/test/samples/Colexpandmax/colexpandmax.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandmin/colexpandmin.py b/test/samples/Colexpandmin/colexpandmin.py index 8680dfc3b1..28b8deaf10 100644 --- a/test/samples/Colexpandmin/colexpandmin.py +++ b/test/samples/Colexpandmin/colexpandmin.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandmul/colexpandmul.py b/test/samples/Colexpandmul/colexpandmul.py index e8a02938c3..3e748fe3ae 100644 --- a/test/samples/Colexpandmul/colexpandmul.py +++ b/test/samples/Colexpandmul/colexpandmul.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandsub/colexpandsub.py b/test/samples/Colexpandsub/colexpandsub.py index dd1c3ef8ef..287bd35eab 100644 --- a/test/samples/Colexpandsub/colexpandsub.py +++ b/test/samples/Colexpandsub/colexpandsub.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colexpandsub/colexpandsub_src0_layout_invalid.py b/test/samples/Colexpandsub/colexpandsub_src0_layout_invalid.py index d811ca37f5..097a979265 100644 --- a/test/samples/Colexpandsub/colexpandsub_src0_layout_invalid.py +++ b/test/samples/Colexpandsub/colexpandsub_src0_layout_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Colmax/colmax.py b/test/samples/Colmax/colmax.py index fba23dfe26..250188a5b7 100644 --- a/test/samples/Colmax/colmax.py +++ b/test/samples/Colmax/colmax.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colmin/colmin.py b/test/samples/Colmin/colmin.py index acdea6e5de..f98683bc4f 100644 --- a/test/samples/Colmin/colmin.py +++ b/test/samples/Colmin/colmin.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colprod/colprod.py b/test/samples/Colprod/colprod.py index 5d946c5043..9e40d974cf 100644 --- a/test/samples/Colprod/colprod.py +++ b/test/samples/Colprod/colprod.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Colsum/colsum.py b/test/samples/Colsum/colsum.py index d5fca8ca96..0c3c32d044 100644 --- a/test/samples/Colsum/colsum.py +++ b/test/samples/Colsum/colsum.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, BoolAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, BoolAttr def build(): diff --git a/test/samples/CommSync/comm_collective.py b/test/samples/CommSync/comm_collective.py index d198c41df4..142bbf16bd 100644 --- a/test/samples/CommSync/comm_collective.py +++ b/test/samples/CommSync/comm_collective.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): with Context() as ctx: diff --git a/test/samples/CommSync/comm_collective_binding_variants.py b/test/samples/CommSync/comm_collective_binding_variants.py index 0c5ad90b77..f8350d6377 100644 --- a/test/samples/CommSync/comm_collective_binding_variants.py +++ b/test/samples/CommSync/comm_collective_binding_variants.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/CommSync/comm_p2p.py b/test/samples/CommSync/comm_p2p.py index a7325df7d2..e26a0f1f83 100644 --- a/test/samples/CommSync/comm_p2p.py +++ b/test/samples/CommSync/comm_p2p.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/CommSync/comm_p2p_binding_variants.py b/test/samples/CommSync/comm_p2p_binding_variants.py index 3df46d762b..a302ab2eb2 100644 --- a/test/samples/CommSync/comm_p2p_binding_variants.py +++ b/test/samples/CommSync/comm_p2p_binding_variants.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/CommSync/tbroadcast_root_binding.py b/test/samples/CommSync/tbroadcast_root_binding.py index 4ec5565004..b078b29463 100644 --- a/test/samples/CommSync/tbroadcast_root_binding.py +++ b/test/samples/CommSync/tbroadcast_root_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def _make_part(ptr, tv_ty, pv_ty, c0, c1, count): diff --git a/test/samples/CommSync/tgather_root_binding.py b/test/samples/CommSync/tgather_root_binding.py index b5e75c8ed9..51aeb7a1e9 100644 --- a/test/samples/CommSync/tgather_root_binding.py +++ b/test/samples/CommSync/tgather_root_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def _make_part(ptr, tv_ty, pv_ty, c0, c1, count): diff --git a/test/samples/CommSync/tnotify_atomic_add_binding.py b/test/samples/CommSync/tnotify_atomic_add_binding.py index bb93ab4193..c7d0655727 100644 --- a/test/samples/CommSync/tnotify_atomic_add_binding.py +++ b/test/samples/CommSync/tnotify_atomic_add_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/CommSync/treduce_root_binding.py b/test/samples/CommSync/treduce_root_binding.py index 780b36e0c8..00571c3041 100644 --- a/test/samples/CommSync/treduce_root_binding.py +++ b/test/samples/CommSync/treduce_root_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def _make_part(ptr, tv_ty, pv_ty, c0, c1, count): diff --git a/test/samples/CommSync/tscatter_root_binding.py b/test/samples/CommSync/tscatter_root_binding.py index bfd1b3d8bb..c9bdf71c5d 100644 --- a/test/samples/CommSync/tscatter_root_binding.py +++ b/test/samples/CommSync/tscatter_root_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def _make_part(ptr, tv_ty, pv_ty, c0, c1, count): diff --git a/test/samples/CommSync/twait_atomic_binding.py b/test/samples/CommSync/twait_atomic_binding.py index 639e2a1e32..bed112f013 100644 --- a/test/samples/CommSync/twait_atomic_binding.py +++ b/test/samples/CommSync/twait_atomic_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto, scf def build(): diff --git a/test/samples/Complex/cv_region.py b/test/samples/Complex/cv_region.py index 05d7ea37d0..b000ff7cef 100644 --- a/test/samples/Complex/cv_region.py +++ b/test/samples/Complex/cv_region.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IndexType, F32Type, UnitAttr -from mlir.dialects import func, arith, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IndexType, F32Type, UnitAttr +from ptoas.mlir.dialects import func, arith, pto def build_sections_test(): with Context() as ctx: diff --git a/test/samples/Complex/mix_kernel.py b/test/samples/Complex/mix_kernel.py index a5ed3312ea..a7f4e8f6ba 100644 --- a/test/samples/Complex/mix_kernel.py +++ b/test/samples/Complex/mix_kernel.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, Attribute, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, Attribute, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(M=32, N=32, K=32, TM=32, TN=32, TK=32): diff --git a/test/samples/Concat/concat.py b/test/samples/Concat/concat.py index 4cb4c5264f..c740481b70 100644 --- a/test/samples/Concat/concat.py +++ b/test/samples/Concat/concat.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Cvt/cvt_f32_f16.py b/test/samples/Cvt/cvt_f32_f16.py index fe00d1547f..7f68e6ed4a 100644 --- a/test/samples/Cvt/cvt_f32_f16.py +++ b/test/samples/Cvt/cvt_f32_f16.py @@ -16,8 +16,8 @@ make_tensor_view -> partition_view -> alloc_tile -> tload -> tcvt -> tstore """ -from mlir.ir import Attribute, Context, F16Type, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Attribute, Context, F16Type, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Cvt/cvt_f32_f32.py b/test/samples/Cvt/cvt_f32_f32.py index 2fa89a0df2..b8ebf0742d 100644 --- a/test/samples/Cvt/cvt_f32_f32.py +++ b/test/samples/Cvt/cvt_f32_f32.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, BoolAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, BoolAttr def build(): diff --git a/test/samples/Cvt/tcvt.py b/test/samples/Cvt/tcvt.py index 2ab189faef..b8a2a66c1b 100644 --- a/test/samples/Cvt/tcvt.py +++ b/test/samples/Cvt/tcvt.py @@ -17,7 +17,7 @@ make_tensor_view -> partition_view -> alloc_tile -> tload -> tcvt -> tstore """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, F32Type, @@ -28,7 +28,7 @@ Module, UnitAttr, ) -from mlir.dialects import arith, func, pto +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Dequant/dequant.py b/test/samples/Dequant/dequant.py index 3829aed870..93bc8375dd 100644 --- a/test/samples/Dequant/dequant.py +++ b/test/samples/Dequant/dequant.py @@ -23,7 +23,7 @@ f32 parameter tiles: Cols*4 >= 32 means Cols >= 8. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, Location, @@ -34,7 +34,7 @@ IntegerType, UnitAttr, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto # Tile shapes diff --git a/test/samples/Dequant/dequant_i8.py b/test/samples/Dequant/dequant_i8.py index a21672fdbf..134159dd90 100644 --- a/test/samples/Dequant/dequant_i8.py +++ b/test/samples/Dequant/dequant_i8.py @@ -23,7 +23,7 @@ f32 parameter tiles: Cols*4 >= 32 means Cols >= 8. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, Location, @@ -34,7 +34,7 @@ IntegerType, UnitAttr, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto # Tile shapes diff --git a/test/samples/Div/div.py b/test/samples/Div/div.py index eddd50b339..d36196e52d 100644 --- a/test/samples/Div/div.py +++ b/test/samples/Div/div.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IndexType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IndexType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Divs/divs.py b/test/samples/Divs/divs.py index e37ce94435..c285efc195 100644 --- a/test/samples/Divs/divs.py +++ b/test/samples/Divs/divs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Divs2/divs2.py b/test/samples/Divs2/divs2.py index 6d52e659dc..248e8aac71 100644 --- a/test/samples/Divs2/divs2.py +++ b/test/samples/Divs2/divs2.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/DynamicTailMatmul/dynamic_tail_matmul.py b/test/samples/DynamicTailMatmul/dynamic_tail_matmul.py index 762ac5b3ac..d86c136808 100644 --- a/test/samples/DynamicTailMatmul/dynamic_tail_matmul.py +++ b/test/samples/DynamicTailMatmul/dynamic_tail_matmul.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IndexType, IntegerType, F16Type, F32Type, UnitAttr -from mlir.dialects import func, arith, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IndexType, IntegerType, F16Type, F32Type, UnitAttr +from ptoas.mlir.dialects import func, arith, pto def build(): diff --git a/test/samples/Exp/exp.py b/test/samples/Exp/exp.py index aeddc984e0..979acdacd6 100644 --- a/test/samples/Exp/exp.py +++ b/test/samples/Exp/exp.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Expands/expand.py b/test/samples/Expands/expand.py index 77c30d59b2..f5f7e55efa 100644 --- a/test/samples/Expands/expand.py +++ b/test/samples/Expands/expand.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Extract/extract.py b/test/samples/Extract/extract.py index 2618f43f72..d649fe44ed 100644 --- a/test/samples/Extract/extract.py +++ b/test/samples/Extract/extract.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/Extract/extract_fp.py b/test/samples/Extract/extract_fp.py index 085db33f01..594e40c971 100644 --- a/test/samples/Extract/extract_fp.py +++ b/test/samples/Extract/extract_fp.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Fillpad/fillpad.py b/test/samples/Fillpad/fillpad.py index 07908652ae..e221c9accd 100644 --- a/test/samples/Fillpad/fillpad.py +++ b/test/samples/Fillpad/fillpad.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Fillpad/fillpad_expand.py b/test/samples/Fillpad/fillpad_expand.py index 5f06ab054a..1bfd10011e 100644 --- a/test/samples/Fillpad/fillpad_expand.py +++ b/test/samples/Fillpad/fillpad_expand.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Fillpad/fillpad_expand_invalid.py b/test/samples/Fillpad/fillpad_expand_invalid.py index 1cb14c144a..98fdf7206b 100644 --- a/test/samples/Fillpad/fillpad_expand_invalid.py +++ b/test/samples/Fillpad/fillpad_expand_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Fillpad/fillpad_expand_pad_null_invalid.py b/test/samples/Fillpad/fillpad_expand_pad_null_invalid.py index 8926dc905a..a3f250b95f 100644 --- a/test/samples/Fillpad/fillpad_expand_pad_null_invalid.py +++ b/test/samples/Fillpad/fillpad_expand_pad_null_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Fillpad/fillpad_inplace.py b/test/samples/Fillpad/fillpad_inplace.py index 25f16eddd7..b4159ef842 100644 --- a/test/samples/Fillpad/fillpad_inplace.py +++ b/test/samples/Fillpad/fillpad_inplace.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Fmod/fmod.py b/test/samples/Fmod/fmod.py index 87c58f33b7..32a1a79ff0 100644 --- a/test/samples/Fmod/fmod.py +++ b/test/samples/Fmod/fmod.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Fmods/fmods.py b/test/samples/Fmods/fmods.py index e852a67fe3..77c43e8193 100644 --- a/test/samples/Fmods/fmods.py +++ b/test/samples/Fmods/fmods.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Fmods/tfmods_scalar_type_invalid.py b/test/samples/Fmods/tfmods_scalar_type_invalid.py index f478435ae1..634ad763ae 100644 --- a/test/samples/Fmods/tfmods_scalar_type_invalid.py +++ b/test/samples/Fmods/tfmods_scalar_type_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IntegerType def build(): diff --git a/test/samples/Gather/gather.py b/test/samples/Gather/gather.py index bcb9c3dbf7..08ec15b6f8 100644 --- a/test/samples/Gather/gather.py +++ b/test/samples/Gather/gather.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto -from mlir.ir import IntegerType +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import IntegerType def build(): diff --git a/test/samples/Gather/gather_legacy.py b/test/samples/Gather/gather_legacy.py index eecfab05e0..dcf33bcdce 100644 --- a/test/samples/Gather/gather_legacy.py +++ b/test/samples/Gather/gather_legacy.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Gatherb/gatherb.py b/test/samples/Gatherb/gatherb.py index 4b1a0e435d..cf76034bbe 100644 --- a/test/samples/Gatherb/gatherb.py +++ b/test/samples/Gatherb/gatherb.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.dialects import arith, func, pto -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr def build(): diff --git a/test/samples/Gemv/gemv.py b/test/samples/Gemv/gemv.py index 416c2b0076..5870784948 100644 --- a/test/samples/Gemv/gemv.py +++ b/test/samples/Gemv/gemv.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/Gemv/gemvacc.py b/test/samples/Gemv/gemvacc.py index d70916cfeb..27c2b8c276 100644 --- a/test/samples/Gemv/gemvacc.py +++ b/test/samples/Gemv/gemvacc.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/Gemv/gemvbias.py b/test/samples/Gemv/gemvbias.py index 5beb088c7d..6ca847542e 100644 --- a/test/samples/Gemv/gemvbias.py +++ b/test/samples/Gemv/gemvbias.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/Gemvmx/gemvmx.py b/test/samples/Gemvmx/gemvmx.py index b667873a7b..c624a5d452 100644 --- a/test/samples/Gemvmx/gemvmx.py +++ b/test/samples/Gemvmx/gemvmx.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, Float8E4M3FNType, Float8E5M2Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, Float8E4M3FNType, Float8E5M2Type, IndexType def build(): diff --git a/test/samples/Layout/tensor_view_infer_layout_dn.py b/test/samples/Layout/tensor_view_infer_layout_dn.py index 05b29b8fd1..488cb3eb75 100644 --- a/test/samples/Layout/tensor_view_infer_layout_dn.py +++ b/test/samples/Layout/tensor_view_infer_layout_dn.py @@ -16,9 +16,9 @@ The expected emitted C++ should use `pto::Layout::DN` in GlobalTensor<>. """ -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Layout/tensor_view_layout_dn.py b/test/samples/Layout/tensor_view_layout_dn.py index 8d311920a4..984599cba1 100644 --- a/test/samples/Layout/tensor_view_layout_dn.py +++ b/test/samples/Layout/tensor_view_layout_dn.py @@ -15,8 +15,8 @@ - The generated C++ GlobalTensor uses pto::Layout::DN. """ -from mlir.ir import Context, Location, InsertionPoint, Module, IndexType -from mlir.dialects import arith, func, pto, builtin +from ptoas.mlir.ir import Context, Location, InsertionPoint, Module, IndexType +from ptoas.mlir.dialects import arith, func, pto, builtin def idx(val: int): diff --git a/test/samples/LayoutInference/layout_inference.py b/test/samples/LayoutInference/layout_inference.py index 8b72d15646..2944d3b969 100644 --- a/test/samples/LayoutInference/layout_inference.py +++ b/test/samples/LayoutInference/layout_inference.py @@ -20,7 +20,7 @@ on each make_tensor_view op. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Context, InsertionPoint, Location, @@ -29,7 +29,7 @@ IndexType, UnitAttr, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto from typing import Optional import sys diff --git a/test/samples/Log/log.py b/test/samples/Log/log.py index 0edf56293c..ac93b89b4d 100644 --- a/test/samples/Log/log.py +++ b/test/samples/Log/log.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Lrelu/lrelu.py b/test/samples/Lrelu/lrelu.py index 877a0a74ae..56e5736a99 100644 --- a/test/samples/Lrelu/lrelu.py +++ b/test/samples/Lrelu/lrelu.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/MatMul/tmatmulk.py b/test/samples/MatMul/tmatmulk.py index 1a75231e86..06bc905a4f 100644 --- a/test/samples/MatMul/tmatmulk.py +++ b/test/samples/MatMul/tmatmulk.py @@ -6,17 +6,17 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, InsertionPoint, IndexType, IntegerType, F16Type, F32Type, StringAttr ) -from mlir.dialects import func, arith, scf, pto, builtin -from mlir.dialects.pto import ( +from ptoas.mlir.dialects import func, arith, scf, pto, builtin +from ptoas.mlir.dialects.pto import ( TLOAD, TMOV_M2L, TMATMUL, TSTORE_ACC, EVENT_ID0 ) -from mlir.dialects.arith import CmpIPredicate +from ptoas.mlir.dialects.arith import CmpIPredicate def _idx_const(v: int): diff --git a/test/samples/MatmulMxLowPrecision/matmul_mx_low_precision.py b/test/samples/MatmulMxLowPrecision/matmul_mx_low_precision.py index 14a30dd803..3661b60692 100644 --- a/test/samples/MatmulMxLowPrecision/matmul_mx_low_precision.py +++ b/test/samples/MatmulMxLowPrecision/matmul_mx_low_precision.py @@ -7,7 +7,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, F16Type, @@ -20,7 +20,7 @@ StringAttr, UnitAttr, ) -from mlir.dialects import func, pto +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/Matmul_transpose/Matmul_transpose.py b/test/samples/Matmul_transpose/Matmul_transpose.py index 46b2ea916c..9e1f8d9aa4 100644 --- a/test/samples/Matmul_transpose/Matmul_transpose.py +++ b/test/samples/Matmul_transpose/Matmul_transpose.py @@ -15,9 +15,9 @@ - pto-as/test/samples/MatMul/tmatmulk.py """ -from mlir.ir import Context, Location, InsertionPoint, IndexType, IntegerType, F32Type, StringAttr, UnitAttr -from mlir.dialects import func, arith, scf, pto, builtin -from mlir.dialects.pto import TLOAD, TMOV_M2L, TMATMUL, TSTORE_ACC, EVENT_ID0 +from ptoas.mlir.ir import Context, Location, InsertionPoint, IndexType, IntegerType, F32Type, StringAttr, UnitAttr +from ptoas.mlir.dialects import func, arith, scf, pto, builtin +from ptoas.mlir.dialects.pto import TLOAD, TMOV_M2L, TMATMUL, TSTORE_ACC, EVENT_ID0 def _idx_const(v: int): diff --git a/test/samples/Max/max.py b/test/samples/Max/max.py index f6c74c3c1d..a62b1c7107 100644 --- a/test/samples/Max/max.py +++ b/test/samples/Max/max.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Maxs/maxs.py b/test/samples/Maxs/maxs.py index a51b0b3139..cd0e85cb6c 100644 --- a/test/samples/Maxs/maxs.py +++ b/test/samples/Maxs/maxs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Mgather/mgather.py b/test/samples/Mgather/mgather.py index 543d1211ae..9269e3072e 100644 --- a/test/samples/Mgather/mgather.py +++ b/test/samples/Mgather/mgather.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Attribute, Context, Location, Module, InsertionPoint, StringAttr, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IndexType, IntegerType +from ptoas.mlir.ir import Attribute, Context, Location, Module, InsertionPoint, StringAttr, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IndexType, IntegerType def build(): diff --git a/test/samples/Min/min.py b/test/samples/Min/min.py index 4b19f65e91..6ffe24fdb9 100644 --- a/test/samples/Min/min.py +++ b/test/samples/Min/min.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Mins/mins.py b/test/samples/Mins/mins.py index 86cfd556fa..928db3d38c 100644 --- a/test/samples/Mins/mins.py +++ b/test/samples/Mins/mins.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Movfp/movfp.py b/test/samples/Movfp/movfp.py index dda90fe81e..47e75e88ad 100644 --- a/test/samples/Movfp/movfp.py +++ b/test/samples/Movfp/movfp.py @@ -16,9 +16,9 @@ - src must be ACC tile; dst must be MAT tile. """ -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Mrgsort/mrgsort.py b/test/samples/Mrgsort/mrgsort.py index 4d58443f0b..4c5b000911 100644 --- a/test/samples/Mrgsort/mrgsort.py +++ b/test/samples/Mrgsort/mrgsort.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Mrgsort/mrgsort_a5.py b/test/samples/Mrgsort/mrgsort_a5.py index 40251dd2fb..b3d2ac9970 100644 --- a/test/samples/Mrgsort/mrgsort_a5.py +++ b/test/samples/Mrgsort/mrgsort_a5.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Mrgsort/mrgsort_format2.py b/test/samples/Mrgsort/mrgsort_format2.py index 4179f6e3eb..6c43018901 100644 --- a/test/samples/Mrgsort/mrgsort_format2.py +++ b/test/samples/Mrgsort/mrgsort_format2.py @@ -15,11 +15,11 @@ - This testcase covers all three forms in a single function entry so it fits the remote validation flow. """ -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType -from mlir.ir import VectorType +from ptoas.mlir.ir import VectorType def build(): diff --git a/test/samples/Mscatter/mscatter.py b/test/samples/Mscatter/mscatter.py index d3dca96d53..a314705e92 100644 --- a/test/samples/Mscatter/mscatter.py +++ b/test/samples/Mscatter/mscatter.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IndexType, IntegerType def build(): diff --git a/test/samples/Mul/mul.py b/test/samples/Mul/mul.py index 3b1be61534..05f80fdea8 100644 --- a/test/samples/Mul/mul.py +++ b/test/samples/Mul/mul.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Muls/muls.py b/test/samples/Muls/muls.py index dd1573dace..fa72991760 100644 --- a/test/samples/Muls/muls.py +++ b/test/samples/Muls/muls.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Neg/neg.py b/test/samples/Neg/neg.py index 5cb5f8f10b..a64a264947 100644 --- a/test/samples/Neg/neg.py +++ b/test/samples/Neg/neg.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Not/not.py b/test/samples/Not/not.py index 400fcbcedb..369481fddc 100644 --- a/test/samples/Not/not.py +++ b/test/samples/Not/not.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Or/or.py b/test/samples/Or/or.py index e958119129..76a1676669 100644 --- a/test/samples/Or/or.py +++ b/test/samples/Or/or.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Ors/ors.py b/test/samples/Ors/ors.py index 3ed43d47fd..afa0e8f8a4 100644 --- a/test/samples/Ors/ors.py +++ b/test/samples/Ors/ors.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType, IntegerAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType, IntegerAttr def build(): diff --git a/test/samples/Partadd/partadd.py b/test/samples/Partadd/partadd.py index 85cfe40adc..3a54a054af 100644 --- a/test/samples/Partadd/partadd.py +++ b/test/samples/Partadd/partadd.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Partarg/partarg.py b/test/samples/Partarg/partarg.py index 0c156e36a6..01b9459a91 100644 --- a/test/samples/Partarg/partarg.py +++ b/test/samples/Partarg/partarg.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.dialects import arith, func, pto -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr def build(): diff --git a/test/samples/Partition5D/partition5d.py b/test/samples/Partition5D/partition5d.py index 0e9d11c67e..25a684f34c 100644 --- a/test/samples/Partition5D/partition5d.py +++ b/test/samples/Partition5D/partition5d.py @@ -16,14 +16,14 @@ 4) tstore writes back to the destination tensor_view """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Context, Location, InsertionPoint, Module, IndexType, ) -from mlir.dialects import arith, func, pto, builtin +from ptoas.mlir.dialects import arith, func, pto, builtin def idx(val: int): diff --git a/test/samples/Partition5D/partition5d_a5.py b/test/samples/Partition5D/partition5d_a5.py index 91da2458e8..021693ee52 100644 --- a/test/samples/Partition5D/partition5d_a5.py +++ b/test/samples/Partition5D/partition5d_a5.py @@ -16,14 +16,14 @@ 4) tstore writes back to the destination tensor_view """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Context, Location, InsertionPoint, Module, IndexType, ) -from mlir.dialects import arith, func, pto, builtin +from ptoas.mlir.dialects import arith, func, pto, builtin def idx(val: int): diff --git a/test/samples/Partmax/partmax.py b/test/samples/Partmax/partmax.py index 9c91b5df56..b5a2a5e347 100644 --- a/test/samples/Partmax/partmax.py +++ b/test/samples/Partmax/partmax.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Partmin/partmin.py b/test/samples/Partmin/partmin.py index 32baa46d83..d4a6cd5a16 100644 --- a/test/samples/Partmin/partmin.py +++ b/test/samples/Partmin/partmin.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Partmul/partmul.py b/test/samples/Partmul/partmul.py index 0dcde4f4eb..d7dd68e626 100644 --- a/test/samples/Partmul/partmul.py +++ b/test/samples/Partmul/partmul.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Prelu/prelu.py b/test/samples/Prelu/prelu.py index e01f0fc94e..ec508cf027 100644 --- a/test/samples/Prelu/prelu.py +++ b/test/samples/Prelu/prelu.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Print/print.py b/test/samples/Print/print.py index 33f2942391..5fd0562496 100644 --- a/test/samples/Print/print.py +++ b/test/samples/Print/print.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): with Context() as ctx: diff --git a/test/samples/Print/print_scalar.py b/test/samples/Print/print_scalar.py index 8478319114..58c3013879 100644 --- a/test/samples/Print/print_scalar.py +++ b/test/samples/Print/print_scalar.py @@ -7,9 +7,9 @@ # See LICENSE in the root of the software repository for the full text of the License. """Test pto.print: format is string attribute, scalar is operand. Generates PRINTF("format", scalar) in C++.""" -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Quant/quant.py b/test/samples/Quant/quant.py index 7e802bbc6f..cdfa3d5952 100644 --- a/test/samples/Quant/quant.py +++ b/test/samples/Quant/quant.py @@ -17,7 +17,7 @@ (the NPU aligned-size). At 1 byte/element that means Cols >= 32. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, Location, @@ -28,7 +28,7 @@ IntegerType, UnitAttr, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto # Tile shape used throughout the sample. diff --git a/test/samples/Quant/quant_asym.py b/test/samples/Quant/quant_asym.py index 67490c96e7..aab8e02ed2 100644 --- a/test/samples/Quant/quant_asym.py +++ b/test/samples/Quant/quant_asym.py @@ -18,7 +18,7 @@ (the NPU aligned-size). At 1 byte/element that means Cols >= 32. """ -from mlir.ir import ( +from ptoas.mlir.ir import ( Attribute, Context, Location, @@ -29,7 +29,7 @@ IntegerType, UnitAttr, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto # Tile shape used throughout the sample. diff --git a/test/samples/Recip/recip.py b/test/samples/Recip/recip.py index 132295f5e2..410e8ab7f2 100644 --- a/test/samples/Recip/recip.py +++ b/test/samples/Recip/recip.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Relu/relu.py b/test/samples/Relu/relu.py index a4b6078f1f..073eb19393 100644 --- a/test/samples/Relu/relu.py +++ b/test/samples/Relu/relu.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rem/rem.py b/test/samples/Rem/rem.py index 7a8f50ef9d..245b16d73b 100644 --- a/test/samples/Rem/rem.py +++ b/test/samples/Rem/rem.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rems/rems.py b/test/samples/Rems/rems.py index 3f5b0cefd6..fd55edeba9 100644 --- a/test/samples/Rems/rems.py +++ b/test/samples/Rems/rems.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Reshape/bitcast_dtype_alias.py b/test/samples/Reshape/bitcast_dtype_alias.py index a107ecf1e2..ff2826d645 100644 --- a/test/samples/Reshape/bitcast_dtype_alias.py +++ b/test/samples/Reshape/bitcast_dtype_alias.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Reshape/bitcast_inplace_cvt.py b/test/samples/Reshape/bitcast_inplace_cvt.py index 7ba321e293..0f504f7590 100644 --- a/test/samples/Reshape/bitcast_inplace_cvt.py +++ b/test/samples/Reshape/bitcast_inplace_cvt.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/Reshape/bitcast_same_dtype_invalid.py b/test/samples/Reshape/bitcast_same_dtype_invalid.py index 44f3bd3c46..ea0271ffd5 100644 --- a/test/samples/Reshape/bitcast_same_dtype_invalid.py +++ b/test/samples/Reshape/bitcast_same_dtype_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Reshape/reshape.py b/test/samples/Reshape/reshape.py index 244b3a540d..ce265c0ccb 100644 --- a/test/samples/Reshape/reshape.py +++ b/test/samples/Reshape/reshape.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpand/rowexpand.py b/test/samples/Rowexpand/rowexpand.py index 6f0622cbec..54c62361dc 100644 --- a/test/samples/Rowexpand/rowexpand.py +++ b/test/samples/Rowexpand/rowexpand.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandadd/rowexpandadd.py b/test/samples/Rowexpandadd/rowexpandadd.py index cf4faa7f16..74d8414337 100644 --- a/test/samples/Rowexpandadd/rowexpandadd.py +++ b/test/samples/Rowexpandadd/rowexpandadd.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandadd/rowexpandadd_src1_width_invalid.py b/test/samples/Rowexpandadd/rowexpandadd_src1_width_invalid.py index a47feb3b80..19a68eeb5f 100644 --- a/test/samples/Rowexpandadd/rowexpandadd_src1_width_invalid.py +++ b/test/samples/Rowexpandadd/rowexpandadd_src1_width_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type def build(): diff --git a/test/samples/Rowexpanddiv/rowexpanddiv.py b/test/samples/Rowexpanddiv/rowexpanddiv.py index aa6c2e46fe..cff800754f 100644 --- a/test/samples/Rowexpanddiv/rowexpanddiv.py +++ b/test/samples/Rowexpanddiv/rowexpanddiv.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandexpdif/rowexpandexpdif.py b/test/samples/Rowexpandexpdif/rowexpandexpdif.py index 6955a0d411..ca0c22d032 100644 --- a/test/samples/Rowexpandexpdif/rowexpandexpdif.py +++ b/test/samples/Rowexpandexpdif/rowexpandexpdif.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandexpdif/rowexpandexpdif_dtype_invalid.py b/test/samples/Rowexpandexpdif/rowexpandexpdif_dtype_invalid.py index 7027715436..772b2d5cf5 100644 --- a/test/samples/Rowexpandexpdif/rowexpandexpdif_dtype_invalid.py +++ b/test/samples/Rowexpandexpdif/rowexpandexpdif_dtype_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import IntegerType def build(): diff --git a/test/samples/Rowexpandmax/rowexpandmax.py b/test/samples/Rowexpandmax/rowexpandmax.py index 26b2d5d2dd..fc6e695974 100644 --- a/test/samples/Rowexpandmax/rowexpandmax.py +++ b/test/samples/Rowexpandmax/rowexpandmax.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandmax/rowexpandmax_a5_tmp_invalid.py b/test/samples/Rowexpandmax/rowexpandmax_a5_tmp_invalid.py index 48d832a527..1c3ac39955 100644 --- a/test/samples/Rowexpandmax/rowexpandmax_a5_tmp_invalid.py +++ b/test/samples/Rowexpandmax/rowexpandmax_a5_tmp_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F32Type, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, StringAttr, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F32Type, IntegerType def build(): diff --git a/test/samples/Rowexpandmin/rowexpandmin.py b/test/samples/Rowexpandmin/rowexpandmin.py index b708716550..9ea8728d0a 100644 --- a/test/samples/Rowexpandmin/rowexpandmin.py +++ b/test/samples/Rowexpandmin/rowexpandmin.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandmul/rowexpandmul.py b/test/samples/Rowexpandmul/rowexpandmul.py index e90dfce604..066eb3817e 100644 --- a/test/samples/Rowexpandmul/rowexpandmul.py +++ b/test/samples/Rowexpandmul/rowexpandmul.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowexpandsub/rowexpandsub.py b/test/samples/Rowexpandsub/rowexpandsub.py index 15768203c6..04a84f89a9 100644 --- a/test/samples/Rowexpandsub/rowexpandsub.py +++ b/test/samples/Rowexpandsub/rowexpandsub.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowmax/rowmax.py b/test/samples/Rowmax/rowmax.py index 8e7798d8ac..30819eca8a 100644 --- a/test/samples/Rowmax/rowmax.py +++ b/test/samples/Rowmax/rowmax.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowmin/rowmin.py b/test/samples/Rowmin/rowmin.py index 4c7c3fde81..a51efdf81c 100644 --- a/test/samples/Rowmin/rowmin.py +++ b/test/samples/Rowmin/rowmin.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowprod/rowprod.py b/test/samples/Rowprod/rowprod.py index 7246a7407a..15e7c55734 100644 --- a/test/samples/Rowprod/rowprod.py +++ b/test/samples/Rowprod/rowprod.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rowsum/rowsum.py b/test/samples/Rowsum/rowsum.py index 452fb36c32..d7c5842f82 100644 --- a/test/samples/Rowsum/rowsum.py +++ b/test/samples/Rowsum/rowsum.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Rsqrt/rsqrt.py b/test/samples/Rsqrt/rsqrt.py index a43331cc41..bc04f8a13d 100644 --- a/test/samples/Rsqrt/rsqrt.py +++ b/test/samples/Rsqrt/rsqrt.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/ScalarPtr/scalar_ptr.py b/test/samples/ScalarPtr/scalar_ptr.py index baec3bd58c..f4f5e20bff 100644 --- a/test/samples/ScalarPtr/scalar_ptr.py +++ b/test/samples/ScalarPtr/scalar_ptr.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Scatter/scatter.py b/test/samples/Scatter/scatter.py index 569f612c82..6ef873b06d 100644 --- a/test/samples/Scatter/scatter.py +++ b/test/samples/Scatter/scatter.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.dialects import arith, func, pto -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr def build(): diff --git a/test/samples/Sel/sel.py b/test/samples/Sel/sel.py index ffbd047026..f4ae49b5ac 100644 --- a/test/samples/Sel/sel.py +++ b/test/samples/Sel/sel.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/Sels/sels.py b/test/samples/Sels/sels.py index 40411f708a..1e10484e6b 100644 --- a/test/samples/Sels/sels.py +++ b/test/samples/Sels/sels.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): with Context() as ctx: diff --git a/test/samples/SetValidShape/set_validshape.py b/test/samples/SetValidShape/set_validshape.py index 93a9edb7ee..dc003b07d2 100644 --- a/test/samples/SetValidShape/set_validshape.py +++ b/test/samples/SetValidShape/set_validshape.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Shl/shl.py b/test/samples/Shl/shl.py index 2c65bdab16..3a45069f6f 100644 --- a/test/samples/Shl/shl.py +++ b/test/samples/Shl/shl.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Shls/shls.py b/test/samples/Shls/shls.py index 3359f4f47e..19886789e0 100644 --- a/test/samples/Shls/shls.py +++ b/test/samples/Shls/shls.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IndexType, IntegerType def build(): diff --git a/test/samples/Shr/shr.py b/test/samples/Shr/shr.py index ca500102dd..5040781517 100644 --- a/test/samples/Shr/shr.py +++ b/test/samples/Shr/shr.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Shrs/shrs.py b/test/samples/Shrs/shrs.py index a1640c0e08..448d4049c1 100644 --- a/test/samples/Shrs/shrs.py +++ b/test/samples/Shrs/shrs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IndexType, IntegerType def build(): diff --git a/test/samples/Sort32/sort32.py b/test/samples/Sort32/sort32.py index 79c12c1c7d..d32567ea13 100644 --- a/test/samples/Sort32/sort32.py +++ b/test/samples/Sort32/sort32.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IntegerType, IndexType def build(): diff --git a/test/samples/Sqrt/sqrt.py b/test/samples/Sqrt/sqrt.py index d2f34653ab..fc9cfaa525 100644 --- a/test/samples/Sqrt/sqrt.py +++ b/test/samples/Sqrt/sqrt.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Storefp/storefp.py b/test/samples/Storefp/storefp.py index 0d8edd5dcb..a37f689366 100644 --- a/test/samples/Storefp/storefp.py +++ b/test/samples/Storefp/storefp.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IntegerType, IndexType def build(): with Context() as ctx: diff --git a/test/samples/Storefp/storefp_invalid.py b/test/samples/Storefp/storefp_invalid.py index 92906076ab..aeed23011e 100644 --- a/test/samples/Storefp/storefp_invalid.py +++ b/test/samples/Storefp/storefp_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, pto -from mlir.ir import F16Type, IntegerType, MemRefType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, pto +from ptoas.mlir.ir import F16Type, IntegerType, MemRefType def build(): diff --git a/test/samples/Sub/sub.py b/test/samples/Sub/sub.py index 4f199b1a16..375b9ded5c 100644 --- a/test/samples/Sub/sub.py +++ b/test/samples/Sub/sub.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/SubView/subview.py b/test/samples/SubView/subview.py index 7b33c74fa1..ecdc4cb940 100644 --- a/test/samples/SubView/subview.py +++ b/test/samples/SubView/subview.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/SubView/subview_boxed_dynamic.py b/test/samples/SubView/subview_boxed_dynamic.py index 57ce85d657..6a69817376 100644 --- a/test/samples/SubView/subview_boxed_dynamic.py +++ b/test/samples/SubView/subview_boxed_dynamic.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, IndexType def build(): diff --git a/test/samples/SubView/subview_boxed_invalid.py b/test/samples/SubView/subview_boxed_invalid.py index 6099705119..03a76ba229 100644 --- a/test/samples/SubView/subview_boxed_invalid.py +++ b/test/samples/SubView/subview_boxed_invalid.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, IndexType def build(): diff --git a/test/samples/SubView/subview_tsubs.py b/test/samples/SubView/subview_tsubs.py index 7081d0fb6f..60676aed00 100644 --- a/test/samples/SubView/subview_tsubs.py +++ b/test/samples/SubView/subview_tsubs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/SubView/vadd_pto_pingpong.py b/test/samples/SubView/vadd_pto_pingpong.py index f6e106c26d..7153f50ebe 100644 --- a/test/samples/SubView/vadd_pto_pingpong.py +++ b/test/samples/SubView/vadd_pto_pingpong.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build_pingpong(): with Context() as ctx: diff --git a/test/samples/Subc/subc.py b/test/samples/Subc/subc.py index d220f4c378..f06057ded5 100644 --- a/test/samples/Subc/subc.py +++ b/test/samples/Subc/subc.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Subs/subs.py b/test/samples/Subs/subs.py index e0e60988ac..a59742a8ac 100644 --- a/test/samples/Subs/subs.py +++ b/test/samples/Subs/subs.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Subsc/subsc.py b/test/samples/Subsc/subsc.py index 510d913f63..f0005a1b0a 100644 --- a/test/samples/Subsc/subsc.py +++ b/test/samples/Subsc/subsc.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Sync/sync.py b/test/samples/Sync/sync.py index 5b404f618a..b7b72e09e4 100644 --- a/test/samples/Sync/sync.py +++ b/test/samples/Sync/sync.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Sync/syncHigh.py b/test/samples/Sync/syncHigh.py index 61e797e15b..ff4dd26e65 100755 --- a/test/samples/Sync/syncHigh.py +++ b/test/samples/Sync/syncHigh.py @@ -7,9 +7,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Sync/test_a5_buf_sync.py b/test/samples/Sync/test_a5_buf_sync.py index 62be895521..9a5676c370 100644 --- a/test/samples/Sync/test_a5_buf_sync.py +++ b/test/samples/Sync/test_a5_buf_sync.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/Sync/test_inject_sync_if.py b/test/samples/Sync/test_inject_sync_if.py index c0ffd0ea81..29478d54b6 100644 --- a/test/samples/Sync/test_inject_sync_if.py +++ b/test/samples/Sync/test_inject_sync_if.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -16,7 +16,7 @@ IndexType, IntegerType, ) -from mlir.dialects import func, arith, scf, pto +from ptoas.mlir.dialects import func, arith, scf, pto def _idx_const(v: int): diff --git a/test/samples/Sync/test_inject_sync_if_else.py b/test/samples/Sync/test_inject_sync_if_else.py index 4dc1d20d0c..c175f15ed0 100644 --- a/test/samples/Sync/test_inject_sync_if_else.py +++ b/test/samples/Sync/test_inject_sync_if_else.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -16,7 +16,7 @@ IndexType, IntegerType, ) -from mlir.dialects import func, arith, scf, pto +from ptoas.mlir.dialects import func, arith, scf, pto def _idx_const(v: int): diff --git a/test/samples/Sync/test_inject_sync_intra_pipe_barrier.py b/test/samples/Sync/test_inject_sync_intra_pipe_barrier.py index 0f63d00657..60059ae3ef 100644 --- a/test/samples/Sync/test_inject_sync_intra_pipe_barrier.py +++ b/test/samples/Sync/test_inject_sync_intra_pipe_barrier.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.ir import F16Type -from mlir.dialects import func, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.ir import F16Type +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/Sync/test_inject_sync_loop.py b/test/samples/Sync/test_inject_sync_loop.py index 3b12958241..e2221dea8c 100644 --- a/test/samples/Sync/test_inject_sync_loop.py +++ b/test/samples/Sync/test_inject_sync_loop.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -15,8 +15,8 @@ F16Type, IndexType, ) -from mlir.dialects import func, arith, scf, pto -from mlir.dialects.arith import CmpIPredicate +from ptoas.mlir.dialects import func, arith, scf, pto +from ptoas.mlir.dialects.arith import CmpIPredicate def _idx_const(v: int): diff --git a/test/samples/Sync/test_inject_sync_loop_nest.py b/test/samples/Sync/test_inject_sync_loop_nest.py index 3e25acc909..b561f0846f 100644 --- a/test/samples/Sync/test_inject_sync_loop_nest.py +++ b/test/samples/Sync/test_inject_sync_loop_nest.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -15,8 +15,8 @@ F16Type, IndexType, ) -from mlir.dialects import func, arith, scf, pto -from mlir.dialects.arith import CmpIPredicate +from ptoas.mlir.dialects import func, arith, scf, pto +from ptoas.mlir.dialects.arith import CmpIPredicate def _idx_const(v: int): diff --git a/test/samples/Sync/test_inject_sync_two_event_id.py b/test/samples/Sync/test_inject_sync_two_event_id.py index 0b42083c95..e277fe5d95 100644 --- a/test/samples/Sync/test_inject_sync_two_event_id.py +++ b/test/samples/Sync/test_inject_sync_two_event_id.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -15,7 +15,7 @@ F16Type, IndexType, ) -from mlir.dialects import func, arith, pto +from ptoas.mlir.dialects import func, arith, pto def _idx_const(v: int): diff --git a/test/samples/Sync/test_intercore_sync_a3.py b/test/samples/Sync/test_intercore_sync_a3.py index 5ce20add1d..59fb54d326 100644 --- a/test/samples/Sync/test_intercore_sync_a3.py +++ b/test/samples/Sync/test_intercore_sync_a3.py @@ -7,7 +7,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, F32Type, @@ -18,7 +18,7 @@ MemRefType, Module, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def build(): diff --git a/test/samples/Sync/test_intercore_sync_a3_dyn.py b/test/samples/Sync/test_intercore_sync_a3_dyn.py index 302554847b..375929788f 100644 --- a/test/samples/Sync/test_intercore_sync_a3_dyn.py +++ b/test/samples/Sync/test_intercore_sync_a3_dyn.py @@ -7,7 +7,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, F32Type, @@ -18,7 +18,7 @@ MemRefType, Module, ) -from mlir.dialects import arith, func, pto, scf +from ptoas.mlir.dialects import arith, func, pto, scf def build(): diff --git a/test/samples/Sync/test_intercore_sync_a3_missing_setffts.py b/test/samples/Sync/test_intercore_sync_a3_missing_setffts.py index 847e29c9a9..223b4b421c 100644 --- a/test/samples/Sync/test_intercore_sync_a3_missing_setffts.py +++ b/test/samples/Sync/test_intercore_sync_a3_missing_setffts.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import func, pto +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/Sync/test_intercore_sync_a3_modes.py b/test/samples/Sync/test_intercore_sync_a3_modes.py index ff7614b488..f3c9d4c5e3 100644 --- a/test/samples/Sync/test_intercore_sync_a3_modes.py +++ b/test/samples/Sync/test_intercore_sync_a3_modes.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, MemRefType, Module, UnitAttr -from mlir.dialects import func, pto +from ptoas.mlir.ir import Context, IndexType, InsertionPoint, IntegerType, Location, MemRefType, Module, UnitAttr +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/Sync/test_intercore_sync_a5.py b/test/samples/Sync/test_intercore_sync_a5.py index c3f9607ed4..d7089fc697 100644 --- a/test/samples/Sync/test_intercore_sync_a5.py +++ b/test/samples/Sync/test_intercore_sync_a5.py @@ -7,7 +7,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, F32Type, @@ -16,7 +16,7 @@ Location, Module, ) -from mlir.dialects import arith, func, pto +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Sync/test_intercore_sync_a5_dyn.py b/test/samples/Sync/test_intercore_sync_a5_dyn.py index cc7b9d7535..b53e759143 100644 --- a/test/samples/Sync/test_intercore_sync_a5_dyn.py +++ b/test/samples/Sync/test_intercore_sync_a5_dyn.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Sync/test_intercore_sync_a5_functional.py b/test/samples/Sync/test_intercore_sync_a5_functional.py index 77d37495e5..4049393f51 100644 --- a/test/samples/Sync/test_intercore_sync_a5_functional.py +++ b/test/samples/Sync/test_intercore_sync_a5_functional.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Sync/test_intercore_sync_a5_ptoisa_vec.py b/test/samples/Sync/test_intercore_sync_a5_ptoisa_vec.py index 68919478f1..04beb6fe3a 100644 --- a/test/samples/Sync/test_intercore_sync_a5_ptoisa_vec.py +++ b/test/samples/Sync/test_intercore_sync_a5_ptoisa_vec.py @@ -7,8 +7,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/Sync/test_mem_inject_sync_basic.py b/test/samples/Sync/test_mem_inject_sync_basic.py index 01d29aa6dc..878523918f 100644 --- a/test/samples/Sync/test_mem_inject_sync_basic.py +++ b/test/samples/Sync/test_mem_inject_sync_basic.py @@ -6,7 +6,7 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, @@ -16,7 +16,7 @@ IndexType, IntegerType, ) -from mlir.dialects import func, arith, scf, pto +from ptoas.mlir.dialects import func, arith, scf, pto def _idx_const(v: int): diff --git a/test/samples/Sync/test_set_wait_unified_api.py b/test/samples/Sync/test_set_wait_unified_api.py index 1f3172ded7..5df69762d9 100644 --- a/test/samples/Sync/test_set_wait_unified_api.py +++ b/test/samples/Sync/test_set_wait_unified_api.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import arith, func, pto -from mlir.ir import IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import arith, func, pto +from ptoas.mlir.ir import IndexType def build(): diff --git a/test/samples/Sync/tmatmulk_autosync.py b/test/samples/Sync/tmatmulk_autosync.py index d89717c1fb..6a2f3756dd 100644 --- a/test/samples/Sync/tmatmulk_autosync.py +++ b/test/samples/Sync/tmatmulk_autosync.py @@ -6,13 +6,13 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, InsertionPoint, IndexType, IntegerType, F16Type, F32Type, StringAttr ) -from mlir.dialects import func, arith, scf, pto, builtin -from mlir.dialects.arith import CmpIPredicate +from ptoas.mlir.dialects import func, arith, scf, pto, builtin +from ptoas.mlir.dialects.arith import CmpIPredicate def _idx_const(v: int): diff --git a/test/samples/Sync/tmatmulk_autosync_a5.py b/test/samples/Sync/tmatmulk_autosync_a5.py index e3f3b012c9..106ebc34a5 100644 --- a/test/samples/Sync/tmatmulk_autosync_a5.py +++ b/test/samples/Sync/tmatmulk_autosync_a5.py @@ -6,13 +6,13 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import ( +from ptoas.mlir.ir import ( UnitAttr, Context, Location, InsertionPoint, IndexType, IntegerType, F16Type, F32Type, StringAttr ) -from mlir.dialects import func, arith, scf, pto, builtin -from mlir.dialects.arith import CmpIPredicate +from ptoas.mlir.dialects import func, arith, scf, pto, builtin +from ptoas.mlir.dialects.arith import CmpIPredicate def _idx_const(v: int): diff --git a/test/samples/SyncAll/syncall_binding.py b/test/samples/SyncAll/syncall_binding.py index 1ac3e1472b..578093c131 100644 --- a/test/samples/SyncAll/syncall_binding.py +++ b/test/samples/SyncAll/syncall_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Attribute, Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Attribute, Context, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def _mode(name): diff --git a/test/samples/TInsert/tinsert.py b/test/samples/TInsert/tinsert.py index 7180061e30..dbb367c0e4 100644 --- a/test/samples/TInsert/tinsert.py +++ b/test/samples/TInsert/tinsert.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F16Type, F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F16Type, F32Type, IndexType def build(): diff --git a/test/samples/TInsert/tinsert_fp.py b/test/samples/TInsert/tinsert_fp.py index dfc99bb116..470dbf7beb 100644 --- a/test/samples/TInsert/tinsert_fp.py +++ b/test/samples/TInsert/tinsert_fp.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType, IntegerType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType, IntegerType def build(): diff --git a/test/samples/TPrefetch/tprefetch.py b/test/samples/TPrefetch/tprefetch.py index f08919bdd0..9338203f02 100644 --- a/test/samples/TPrefetch/tprefetch.py +++ b/test/samples/TPrefetch/tprefetch.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, InsertionPoint, Location, Module, IndexType, F16Type, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, InsertionPoint, Location, Module, IndexType, F16Type, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/TPrefetchAsync/tprefetch_async_binding.py b/test/samples/TPrefetchAsync/tprefetch_async_binding.py index d28bcd212a..b21f50ff83 100644 --- a/test/samples/TPrefetchAsync/tprefetch_async_binding.py +++ b/test/samples/TPrefetchAsync/tprefetch_async_binding.py @@ -6,8 +6,8 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr -from mlir.dialects import arith, func, pto +from ptoas.mlir.ir import Context, F32Type, IndexType, InsertionPoint, IntegerType, Location, Module, UnitAttr +from ptoas.mlir.dialects import arith, func, pto def build(): diff --git a/test/samples/TTri/ttri.py b/test/samples/TTri/ttri.py index 7000b10645..401e288f17 100644 --- a/test/samples/TTri/ttri.py +++ b/test/samples/TTri/ttri.py @@ -12,8 +12,8 @@ stores them into a single output buffer as two consecutive 32x32 slices. """ -from mlir.ir import Context, Location, Module, InsertionPoint, IndexType, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IndexType, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto def build(): diff --git a/test/samples/TileSetGetValue/tileSetGetValue.py b/test/samples/TileSetGetValue/tileSetGetValue.py index 46ee475e89..49d5529f24 100644 --- a/test/samples/TileSetGetValue/tileSetGetValue.py +++ b/test/samples/TileSetGetValue/tileSetGetValue.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/TileSetGetValue/tile_getval_mat_invalid.py b/test/samples/TileSetGetValue/tile_getval_mat_invalid.py index 18065bd6e3..917f2c2376 100644 --- a/test/samples/TileSetGetValue/tile_getval_mat_invalid.py +++ b/test/samples/TileSetGetValue/tile_getval_mat_invalid.py @@ -10,9 +10,9 @@ Test that TGetValOp rejects MAT tile_buf (Ascend hardware does not support reading from MAT tile_buf to scalar). Verification must fail. """ -from mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, MLIRError, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Tpow/tpow.py b/test/samples/Tpow/tpow.py index e58442d06b..a648654461 100644 --- a/test/samples/Tpow/tpow.py +++ b/test/samples/Tpow/tpow.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Tpows/tpows.py b/test/samples/Tpows/tpows.py index 1c4ad7acc1..8bcc8cc00a 100644 --- a/test/samples/Tpows/tpows.py +++ b/test/samples/Tpows/tpows.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Trans/trans.py b/test/samples/Trans/trans.py index a7b6b2e5b8..9b17b31b1e 100644 --- a/test/samples/Trans/trans.py +++ b/test/samples/Trans/trans.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/Trap/trap.py b/test/samples/Trap/trap.py index b4376af13a..005b559f1d 100644 --- a/test/samples/Trap/trap.py +++ b/test/samples/Trap/trap.py @@ -7,8 +7,8 @@ # See LICENSE in the root of the software repository for the full text of the License. """Test pto.trap: generates TRAP() in C++.""" -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, pto +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, pto def build(): diff --git a/test/samples/VectorAddition/vadd_pto_ir.py b/test/samples/VectorAddition/vadd_pto_ir.py index c06bd018f9..4e43773bd8 100644 --- a/test/samples/VectorAddition/vadd_pto_ir.py +++ b/test/samples/VectorAddition/vadd_pto_ir.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): diff --git a/test/samples/VectorAddition/vadd_validshape.py b/test/samples/VectorAddition/vadd_validshape.py index 269c7604a1..3239998bb2 100644 --- a/test/samples/VectorAddition/vadd_validshape.py +++ b/test/samples/VectorAddition/vadd_validshape.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): with Context() as ctx: diff --git a/test/samples/VectorAddition/vadd_validshape_dynamic.py b/test/samples/VectorAddition/vadd_validshape_dynamic.py index 639716c890..01e6818fe8 100644 --- a/test/samples/VectorAddition/vadd_validshape_dynamic.py +++ b/test/samples/VectorAddition/vadd_validshape_dynamic.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build(): with Context() as ctx: diff --git a/test/samples/VectorAddition/vadd_validshape_hyper.py b/test/samples/VectorAddition/vadd_validshape_hyper.py index 45b1415de6..5172f5192a 100644 --- a/test/samples/VectorAddition/vadd_validshape_hyper.py +++ b/test/samples/VectorAddition/vadd_validshape_hyper.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import F32Type, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, IntegerType, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import F32Type, IndexType def build_mixed_shape(): with Context() as ctx: diff --git a/test/samples/Xor/xor.py b/test/samples/Xor/xor.py index 0d25112001..86acc61a46 100644 --- a/test/samples/Xor/xor.py +++ b/test/samples/Xor/xor.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType def build(): diff --git a/test/samples/Xors/xors.py b/test/samples/Xors/xors.py index 02f2c8c8e6..3ef70a27ea 100644 --- a/test/samples/Xors/xors.py +++ b/test/samples/Xors/xors.py @@ -6,9 +6,9 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -from mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr -from mlir.dialects import func, arith, pto -from mlir.ir import IntegerType, IndexType, IntegerAttr +from ptoas.mlir.ir import Context, Location, Module, InsertionPoint, UnitAttr +from ptoas.mlir.dialects import func, arith, pto +from ptoas.mlir.ir import IntegerType, IndexType, IntegerAttr def build(): diff --git a/test/samples/runop.sh b/test/samples/runop.sh index a529574a83..a9a632c9da 100755 --- a/test/samples/runop.sh +++ b/test/samples/runop.sh @@ -35,7 +35,7 @@ Env: PTOBC_BIN # path to ptobc executable (optional) PYTHON_BIN # python executable to run samples (optional) PTOAS_OUT_DIR # where generated *.mlir/*.cpp go (optional; defaults to a temp dir) - PTO_BUILD_DIR # build directory root that contains tools/ptoas and tools/ptobc (optional) + PTO_BUILD_DIR # build directory root that contains tools/ptobc (optional) PTOAS_FLAGS # extra flags passed to ptoas (e.g. --enable-insert-sync) PTOAS_ENABLE_INSERT_SYNC # 1 to append --enable-insert-sync to PTOAS_FLAGS (default: 1) PTO_PTO_DIRS # space-separated dirs to run .pto directly (default: Sync Qwen3DecodeA3 Qwen3DecodeA5 DeepseekV4DecodeA3 DeepseekV4DecodeA5 CommSync Prelu Rem Rems Gemvmx MatmulMxLowPrecision TquantMx Movfp) @@ -62,27 +62,16 @@ lcfirst() { resolve_ptoas_bin() { if [[ -n "${PTOAS_BIN}" ]]; then - echo "${PTOAS_BIN}" - return 0 + local override + override="$(command -v "${PTOAS_BIN}" 2>/dev/null || true)" + if [[ -n "${override}" && -x "${override}" ]]; then + echo "${override}" + return 0 + fi + return 1 fi - # Common locations: - # - installed wrapper in repo: PTOAS/install/bin/ptoas - # - out-of-tree build in repo: PTOAS/build/tools/ptoas/ptoas - # - legacy layout: build/bin/ptoas local cand - if [[ -n "${PTO_BUILD_DIR}" ]]; then - cand="${PTO_BUILD_DIR%/build}/install/bin/ptoas" - [[ -x "$cand" ]] && { echo "$cand"; return 0; } - cand="${PTO_BUILD_DIR}/tools/ptoas/ptoas" - [[ -x "$cand" ]] && { echo "$cand"; return 0; } - cand="${PTO_BUILD_DIR}/bin/ptoas" - [[ -x "$cand" ]] && { echo "$cand"; return 0; } - fi - cand="${BASE_DIR}/../../build/tools/ptoas/ptoas" - [[ -x "$cand" ]] && { echo "$cand"; return 0; } - cand="${BASE_DIR}/../../../../build/bin/ptoas" - [[ -x "$cand" ]] && { echo "$cand"; return 0; } cand="$(command -v ptoas 2>/dev/null || true)" [[ -n "$cand" && -x "$cand" ]] && { echo "$cand"; return 0; } @@ -240,7 +229,7 @@ process_one_dir() { fi if [[ -z "$ptoas" || ! -x "$ptoas" ]]; then - echo -e "${A}\tFAIL\tMissing executable: PTOAS_BIN (searched common paths)" + echo -e "${A}\tFAIL\tMissing ptoas command (install PTOAS or set PTOAS_BIN)" return 0 fi if [[ -z "$python" || ! -x "$python" ]]; then diff --git a/test/tilelang_st/script/run_all_st.py b/test/tilelang_st/script/run_all_st.py index 557482548d..34f55d27aa 100755 --- a/test/tilelang_st/script/run_all_st.py +++ b/test/tilelang_st/script/run_all_st.py @@ -101,6 +101,10 @@ def parse_args(): "-j", "--jobs", type=int, default=1, help="Number of testcases to run in parallel after the shared build (default: 1).", ) + parser.add_argument( + "--build-jobs", type=int, default=None, + help="Maximum parallel jobs for the shared CMake build (default: host CPU count).", + ) parser.add_argument( "--smoke", action="store_true", help="Run only a representative smoke subset of cases for each testcase.", @@ -168,6 +172,9 @@ def main(): if args.jobs < 1: print("[ERROR] --jobs must be >= 1", file=sys.stderr) sys.exit(1) + if args.build_jobs is not None and args.build_jobs < 1: + print("[ERROR] --build-jobs must be >= 1", file=sys.stderr) + sys.exit(1) batch_script_path = os.path.abspath(__file__) run_st_script_path = os.path.abspath(run_st.__file__) @@ -219,6 +226,7 @@ def main(): print(f"[INFO] selected_testcases={', '.join(selected_testcases)}") print(f"[INFO] smoke={args.smoke}") print(f"[INFO] jobs={args.jobs}") + print(f"[INFO] build_jobs={args.build_jobs or os.cpu_count() or 4}") original_dir = os.getcwd() failures = [] @@ -232,7 +240,13 @@ def main(): else: build_target = "all" print(f"[INFO] build requested for {build_target}") - run_st.build_project(args.run_mode, default_soc_version, build_target, ptoas_bin) + run_st.build_project( + args.run_mode, + default_soc_version, + build_target, + ptoas_bin, + args.build_jobs, + ) total = len(selected_testcases) if args.jobs == 1: diff --git a/test/tilelang_st/script/run_ci.sh b/test/tilelang_st/script/run_ci.sh index 385a7bda9f..f6a4fe5eb6 100755 --- a/test/tilelang_st/script/run_ci.sh +++ b/test/tilelang_st/script/run_ci.sh @@ -10,12 +10,6 @@ set -euo pipefail SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd -- "${SCRIPT_DIR}/../../.." && pwd)" - -if [[ -f "${REPO_ROOT}/scripts/ptoas_env.sh" ]]; then - # shellcheck source=/dev/null - source "${REPO_ROOT}/scripts/ptoas_env.sh" -fi export PYTHONUNBUFFERED=1 diff --git a/test/tilelang_st/script/run_ptodsl_st_parallel.py b/test/tilelang_st/script/run_ptodsl_st_parallel.py index f446992997..4c1e4a0ac7 100755 --- a/test/tilelang_st/script/run_ptodsl_st_parallel.py +++ b/test/tilelang_st/script/run_ptodsl_st_parallel.py @@ -83,6 +83,7 @@ def _run_build(args, default_soc_version, target_dir, log_dir, ptoas_bin): default_soc_version, "all", str(ptoas_bin), + args.jobs, ) finally: os.chdir(original_dir) diff --git a/test/tilelang_st/script/run_st.py b/test/tilelang_st/script/run_st.py index 45826a6929..db5fe52eff 100755 --- a/test/tilelang_st/script/run_st.py +++ b/test/tilelang_st/script/run_st.py @@ -49,21 +49,18 @@ def _normalize_case_filters(case_filters): def find_ptoas_bin(): - """Locate the ptoas binary by walking up from this script to the repo root.""" + """Locate the ptoas entry point from an override or the active environment.""" env_bin = os.environ.get("PTOAS_BIN") - if env_bin and os.path.isfile(env_bin): - return os.path.abspath(env_bin) + if env_bin: + resolved = shutil.which(env_bin) + if resolved: + return os.path.abspath(resolved) + if os.path.isfile(env_bin) and os.access(env_bin, os.X_OK): + return os.path.abspath(env_bin) + return None - search_dir = os.path.dirname(os.path.abspath(__file__)) - for _ in range(8): - candidate = os.path.join(search_dir, "build", "tools", "ptoas", "ptoas") - if os.path.isfile(candidate): - return os.path.abspath(candidate) - parent = os.path.dirname(search_dir) - if parent == search_dir: - break - search_dir = parent - return None + resolved = shutil.which("ptoas") + return os.path.abspath(resolved) if resolved else None def set_env_variables(run_mode, soc_version): @@ -118,7 +115,7 @@ def get_testcase_work_dir(testcase): return os.path.join("build", "testcase", testcase) -def build_project(run_mode, soc_version, testcase, ptoas_bin): +def build_project(run_mode, soc_version, testcase, ptoas_bin, build_jobs=None): build_dir = "build" if os.path.exists(build_dir): print(f"clean build: {build_dir}") @@ -143,8 +140,8 @@ def build_project(run_mode, soc_version, testcase, ptoas_bin): text=True, ) - cpu_count = os.cpu_count() or 4 - make_cmd = ["make", "VERBOSE=1", "-j", str(cpu_count)] + build_jobs = build_jobs or os.cpu_count() or 4 + make_cmd = ["make", "VERBOSE=1", "-j", str(build_jobs)] result = subprocess.run( make_cmd, cwd=build_dir, @@ -275,9 +272,14 @@ def main(): help="Skip build (requires prior build)") parser.add_argument("--target-dir", required=False, help="TileLang ST target directory. Defaults to npu//src/st.") + parser.add_argument("--build-jobs", type=int, default=None, + help="Maximum parallel jobs for the shared CMake build.") args = parser.parse_args() + if args.build_jobs is not None and args.build_jobs < 1: + parser.error("--build-jobs must be >= 1") + if args.soc_version == "a5": default_soc_version = "Ascend950PR_9599" else: @@ -315,7 +317,13 @@ def main(): set_env_variables(args.run_mode, default_soc_version) if not args.without_build: - build_project(args.run_mode, default_soc_version, testcase, ptoas_bin) + build_project( + args.run_mode, + default_soc_version, + testcase, + ptoas_bin, + args.build_jobs, + ) # gen golden → run binary → compare run_gen_data(testcase, args.case) diff --git a/test/tilelib-st/README.md b/test/tilelib-st/README.md index eb3aa26b34..51d4e63bd1 100644 --- a/test/tilelib-st/README.md +++ b/test/tilelib-st/README.md @@ -226,10 +226,8 @@ export PTOAS_REPO="$PWD" export PTOAS_BUILD="$PTOAS_REPO/build-sim" export ASCEND_HOME_PATH=/path/to/cann export LLVM_BUILD_DIR=/path/to/vpto-llvm/build -export MLIR_PYTHON_ROOT="$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core" export PYTHON_BIN=/path/to/python-with-torch-npu export PTO_PYTHON_BIN="$PYTHON_BIN" -export PTOAS_ENV_SKIP_SMOKE_TEST=1 export TORCH_DEVICE_BACKEND_AUTOLOAD=0 ``` @@ -246,7 +244,6 @@ Check the simulator, LLVM, and Python prerequisites: command -v msprof test -d "$LLVM_BUILD_DIR/lib/cmake/llvm" test -d "$LLVM_BUILD_DIR/lib/cmake/mlir" -test -d "$MLIR_PYTHON_ROOT" "$PYTHON_BIN" - <<'PY' import nanobind @@ -277,27 +274,20 @@ PTOAS Python bindings must have the same Python ABI as the runtime Python that will run the ST cases: ```bash -PYBIND11_CMAKE_DIR="$("$PYTHON_BIN" -m pybind11 --cmakedir)" -NANOBIND_CMAKE_DIR="$("$PYTHON_BIN" -m nanobind --cmake_dir)" - cmake -S "$PTOAS_REPO" -B "$PTOAS_BUILD" -G Ninja \ -DLLVM_DIR="$LLVM_BUILD_DIR/lib/cmake/llvm" \ -DMLIR_DIR="$LLVM_BUILD_DIR/lib/cmake/mlir" \ -DPython3_EXECUTABLE="$PYTHON_BIN" \ -DPython3_FIND_STRATEGY=LOCATION \ - -Dpybind11_DIR="$PYBIND11_CMAKE_DIR" \ - -Dnanobind_DIR="$NANOBIND_CMAKE_DIR" \ -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ - -DMLIR_PYTHON_PACKAGE_DIR="$MLIR_PYTHON_ROOT" \ -DPTO_ENABLE_PYTHON_BINDING=ON \ - -DPTOAS_ENABLE_WERROR=OFF \ -DBUILD_TESTING=ON ``` Build the compiler and PTO Python bindings: ```bash -ninja -C "$PTOAS_BUILD" ptoas PTOPythonModules +ninja -C "$PTOAS_BUILD" ptoas PTOAS_Python ``` Export the runtime lookup paths. `PTOAS_BIN` is useful, but PTODSL native build @@ -306,7 +296,7 @@ also resolves `ptoas` through `PATH`, so keep the freshly built binary first: ```bash export PTOAS_BIN="$PTOAS_BUILD/tools/ptoas/ptoas" export PATH="$PTOAS_BUILD/tools/ptoas:$PATH" -export PYTHONPATH="$PTOAS_BUILD/python:$PTOAS_REPO/ptodsl:$MLIR_PYTHON_ROOT:${PYTHONPATH:-}" +export PYTHONPATH="$PTOAS_BUILD/python:$PTOAS_REPO/ptodsl:${PYTHONPATH:-}" export LD_LIBRARY_PATH="$LLVM_BUILD_DIR/lib:$PTOAS_BUILD/lib:${LD_LIBRARY_PATH:-}" ``` @@ -316,7 +306,7 @@ build: ```bash "$PYTHON_BIN" - <<'PY' from ptodsl import pto # noqa: F401 -from mlir.dialects import pto as _pto # noqa: F401 +from ptoas.mlir.dialects import pto as _pto # noqa: F401 print("ptodsl imports ok") PY @@ -365,7 +355,6 @@ Example path layout: ```bash export ASCEND_HOME_PATH=/opt/ascend/cann export LLVM_BUILD_DIR=/opt/vpto-llvm/build -export MLIR_PYTHON_ROOT="$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core" export PYTHON_BIN=/opt/ptodsl-runtime/bin/python ``` @@ -379,5 +368,5 @@ Common failures: - `No TileLib ST cases discovered`: pass the case root through `scripts/sim_dsl.sh ... run_tilelib_st.py -- test/tilelib-st/a5`, keeping the `--` separator. -- Stale compiler behavior: rebuild `ptoas PTOPythonModules`, put +- Stale compiler behavior: rebuild `ptoas PTOAS_Python`, put `$PTOAS_BUILD/tools/ptoas` first in `PATH`, and verify `$PTOAS_BIN --version`. diff --git a/tilelang-dsl/CMakeLists.txt b/tilelang-dsl/CMakeLists.txt index 2bbca7c3dc..3c00670513 100644 --- a/tilelang-dsl/CMakeLists.txt +++ b/tilelang-dsl/CMakeLists.txt @@ -12,24 +12,24 @@ set(TILELANG_DSL_PACKAGE_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/python/tilelang_dsl") -set(TILELANG_DSL_BUILD_ROOT "${CMAKE_BINARY_DIR}/python") set(TILELANG_DSL_BUILD_PACKAGE_DIR - "${TILELANG_DSL_BUILD_ROOT}/tilelang_dsl") + "${CMAKE_BINARY_DIR}/python/tilelang_dsl") -add_custom_target(TileLangDSLPackage ALL - COMMAND ${CMAKE_COMMAND} -E make_directory "${TILELANG_DSL_BUILD_ROOT}" - COMMAND ${CMAKE_COMMAND} -E remove_directory "${TILELANG_DSL_BUILD_PACKAGE_DIR}" - COMMAND ${CMAKE_COMMAND} -E copy_directory - "${TILELANG_DSL_PACKAGE_SRC_DIR}" - "${TILELANG_DSL_BUILD_PACKAGE_DIR}" - COMMENT "Staging tilelang_dsl package into build/python" - VERBATIM +declare_mlir_python_sources(TileLangDSLPythonSources + ROOT_DIR "${TILELANG_DSL_PACKAGE_SRC_DIR}" + SOURCES_GLOB "*.py" ) +add_mlir_python_sources_target(TileLangDSLPackageStage + OUTPUT_DIRECTORY "${TILELANG_DSL_BUILD_PACKAGE_DIR}" + SOURCES_TARGETS TileLangDSLPythonSources +) +add_custom_target(TileLangDSLPackage ALL) +add_dependencies(TileLangDSLPackage TileLangDSLPackageStage) install( DIRECTORY "${TILELANG_DSL_PACKAGE_SRC_DIR}" DESTINATION "." - COMPONENT PTOAS_Runtime + COMPONENT PTOAS_CompilerArchive PATTERN "__pycache__" EXCLUDE PATTERN "*.pyc" EXCLUDE ) @@ -37,7 +37,7 @@ install( install( DIRECTORY "${CMAKE_SOURCE_DIR}/lib/TileOps" DESTINATION "share/ptoas" - COMPONENT PTOAS_Runtime + COMPONENT PTOAS_CompilerArchive PATTERN "__pycache__" EXCLUDE PATTERN "*.pyc" EXCLUDE ) diff --git a/tilelang-dsl/README.md b/tilelang-dsl/README.md index 37d13f0158..38095a856c 100644 --- a/tilelang-dsl/README.md +++ b/tilelang-dsl/README.md @@ -111,9 +111,9 @@ To check that the generated MLIR passes the current repo VPTO authoring-stage legality path: ```bash -source scripts/ptoas_env.sh +LLVM_BUILD_DIR=/path/to/llvm/build ./quick_install.sh PYTHONPATH=$PWD/tilelang-dsl/python python3 tilelang-dsl/examples/v1_verify_smoke.py /tmp/tilelang_v1_verify.mlir -build/tools/ptoas/ptoas --pto-arch a5 --pto-backend=vpto --emit-vpto \ +ptoas --pto-arch a5 --pto-backend=vpto --emit-vpto \ /tmp/tilelang_v1_verify.mlir -o /tmp/tilelang_v1_verify.checked.mlir ``` diff --git a/tilelang-dsl/docs/v1-lowering.md b/tilelang-dsl/docs/v1-lowering.md index 8568fbc4ae..0355e9e19b 100644 --- a/tilelang-dsl/docs/v1-lowering.md +++ b/tilelang-dsl/docs/v1-lowering.md @@ -164,7 +164,7 @@ PYTHONPATH=$PWD/tilelang-dsl/python \ PYTHONPATH=$PWD/tilelang-dsl/python \ python3 tilelang-dsl/examples/v1_verify_smoke.py /tmp/tilelang_v1_verify.mlir -build/tools/ptoas/ptoas --pto-arch a5 --pto-backend=vpto --emit-vpto \ +ptoas --pto-arch a5 --pto-backend=vpto --emit-vpto \ /tmp/tilelang_v1_verify.mlir -o /tmp/tilelang_v1_verify.checked.mlir ``` diff --git a/tilelang-dsl/python/tilelang_dsl/env_config.py b/tilelang-dsl/python/tilelang_dsl/env_config.py index 00dc0e66e5..f45b256b94 100644 --- a/tilelang-dsl/python/tilelang_dsl/env_config.py +++ b/tilelang-dsl/python/tilelang_dsl/env_config.py @@ -24,7 +24,7 @@ def check_mlir_bindings_available() -> bool: True if mlir.ir module can be imported, False otherwise. """ try: - from mlir import ir + from ptoas.mlir import ir return True except ImportError: return False @@ -34,10 +34,10 @@ def check_pto_dialect_available() -> bool: """Check if PTO dialect bindings are available. Returns: - True if pto.dialects.pto module can be imported, False otherwise. + True if mlir.dialects.pto can be imported, False otherwise. """ try: - from pto.dialects import pto + from ptoas.mlir.dialects import pto return True except ImportError: return False @@ -64,32 +64,30 @@ def print_environment_help() -> None: print("PybindBackend Environment Configuration Guide") print("=" * 60) print() - print("PybindBackend requires MLIR Python bindings from LLVM build.") + print("PybindBackend requires the MLIR Python package built by PTOAS.") print() print("To set up the environment, add the following to PYTHONPATH:") print() - print("1. LLVM MLIR Python package:") - print(" $LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core") - print() - print("2. PTO dialect bindings (optional, for PTO ops):") - print(" $PTOAS_BUILD_DIR/python/mlir") + print("1. PTOAS build-tree Python package:") + print(" $PTOAS_BUILD_DIR/python") print(" OR") - print(" $PTO_INSTALL_DIR/mlir") + print("2. PTOAS install tree:") + print(" $PTO_INSTALL_DIR") print() print("Example setup:") print() - print(" # Assuming LLVM is built at ~/llvm-workspace/llvm-project/build-shared") - print(" export LLVM_BUILD_DIR=~/llvm-workspace/llvm-project/build-shared") - print() print(" # Assuming PTOAS is at ~/llvm-workspace/pto-as") print(" export PTOAS_BUILD_DIR=~/llvm-workspace/pto-as/build") print() print(" # Set PYTHONPATH") - print(" export PYTHONPATH=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core:$PTOAS_BUILD_DIR/python") + print(" export PYTHONPATH=$PTOAS_BUILD_DIR/python") print() print("After setup, verify with:") - print(" python3 -c 'from mlir import ir; print(\"MLIR bindings OK\")'") - print(" python3 -c 'from pto.dialects import pto; print(\"PTO dialect OK\")'") + print(" python3 -c 'from ptoas.mlir import ir; print(\"MLIR bindings OK\")'") + print( + " python3 -c 'from ptoas.mlir.dialects import pto; " + "print(\"PTO dialect OK\")'" + ) print() print("=" * 60) @@ -128,4 +126,4 @@ def verify_environment() -> bool: "get_environment_status", "print_environment_help", "verify_environment", -] \ No newline at end of file +] diff --git a/tilelang-dsl/python/tilelang_dsl/lowering_backend.py b/tilelang-dsl/python/tilelang_dsl/lowering_backend.py index 80bdb4e972..ed13f9a120 100644 --- a/tilelang-dsl/python/tilelang_dsl/lowering_backend.py +++ b/tilelang-dsl/python/tilelang_dsl/lowering_backend.py @@ -24,7 +24,7 @@ if TYPE_CHECKING: from .semantic import SemanticKernel - from mlir import ir as _ods_ir + from ptoas.mlir import ir as _ods_ir @dataclass(frozen=True) @@ -68,18 +68,13 @@ def _parse_text_to_module( ) -> "_ods_ir.Module": """Parse MLIR text into a structured Module. - Registers all required dialects (func, arith, scf, pto) before parsing. + The PTOAS MLIR site initializer registers the bundled upstream dialects. + Register the project-owned PTO dialect explicitly before parsing. """ - from mlir import ir as _ods_ir - from mlir.dialects import func as _func_dialect - from mlir.dialects import arith as _arith_dialect - from mlir.dialects import scf as _scf_dialect - from pto.dialects import pto as _pto_dialect + from ptoas.mlir import ir as _ods_ir + from ptoas.mlir.dialects import pto as _pto_dialect ctx = context if context is not None else _ods_ir.Context() - _func_dialect.register_dialect(ctx) - _arith_dialect.register_dialect(ctx) - _scf_dialect.register_dialect(ctx) _pto_dialect.register_dialect(ctx, load=True) return _ods_ir.Module.parse(text, ctx) @@ -180,7 +175,7 @@ def _check_mlir_available(self) -> bool: return self._mlir_available try: - from mlir import ir + from ptoas.mlir import ir self._mlir_available = True except ImportError: self._mlir_available = False @@ -278,4 +273,4 @@ def lower_with_backend( "PybindBackend", "get_backend", "lower_with_backend", -] \ No newline at end of file +] diff --git a/tilelang-dsl/python/tilelang_dsl/pybind_renderer.py b/tilelang-dsl/python/tilelang_dsl/pybind_renderer.py index 8b9ad249c0..b0962408af 100644 --- a/tilelang-dsl/python/tilelang_dsl/pybind_renderer.py +++ b/tilelang-dsl/python/tilelang_dsl/pybind_renderer.py @@ -14,16 +14,15 @@ Phase 2 implementation: core framework with basic stmt/expr rendering. Dependencies: - - mlir.ir: MLIR Python bindings from LLVM build - - mlir.dialects.func, arith, scf: Standard MLIR dialects - - mlir.dialects.pto: PTO dialect bindings from PTOAS build + - ptoas.mlir.ir: MLIR Python bindings assembled by the PTOAS build + - ptoas.mlir.dialects.func, arith, scf: Standard MLIR dialects + - ptoas.mlir.dialects.pto: PTO dialect bindings from PTOAS build -To use this module, ensure PYTHONPATH includes: - 1. LLVM MLIR Python package: $LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core - 2. PTOAS Python bindings: $PTOAS_BUILD_DIR/python +To use this module from a build tree, ensure PYTHONPATH includes: + $PTOAS_BUILD_DIR/python Example: - export PYTHONPATH="$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core:$PTOAS_BUILD_DIR/python" + export PYTHONPATH="$PTOAS_BUILD_DIR/python" """ from __future__ import annotations @@ -32,7 +31,7 @@ from typing import Any, TYPE_CHECKING if TYPE_CHECKING: - from mlir import ir as _ods_ir + from ptoas.mlir import ir as _ods_ir # Lazy imports - only load when actually needed _mlir_ir: Any = None @@ -55,10 +54,10 @@ def _ensure_mlir_bindings() -> None: return # Already loaded try: - from mlir import ir as mlir_ir - from mlir.dialects import func as func_dialect - from mlir.dialects import arith as arith_dialect - from mlir.dialects import scf as scf_dialect + from ptoas.mlir import ir as mlir_ir + from ptoas.mlir.dialects import func as func_dialect + from ptoas.mlir.dialects import arith as arith_dialect + from ptoas.mlir.dialects import scf as scf_dialect _mlir_ir = mlir_ir _func_dialect = func_dialect @@ -67,13 +66,13 @@ def _ensure_mlir_bindings() -> None: except ImportError as exc: raise ImportError( "MLIR Python bindings not found. Please ensure PYTHONPATH includes " - "the MLIR Python package from your LLVM build. " - "Example: export PYTHONPATH=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core " + "the Python package assembled by your PTOAS build. " + "Example: export PYTHONPATH=$PTOAS_BUILD_DIR/python " "See README.md for build instructions." ) from exc try: - from mlir.dialects import pto as pto_dialect + from ptoas.mlir.dialects import pto as pto_dialect _pto_dialect = pto_dialect except ImportError: # PTO dialect is optional for some operations diff --git a/tilelang-dsl/tests/backend/test_e2e_pybind_backend.py b/tilelang-dsl/tests/backend/test_e2e_pybind_backend.py index c660cb64ee..5ca6630957 100644 --- a/tilelang-dsl/tests/backend/test_e2e_pybind_backend.py +++ b/tilelang-dsl/tests/backend/test_e2e_pybind_backend.py @@ -18,7 +18,7 @@ python3 tests/backend/test_e2e_pybind_backend.py Environment setup (optional for PybindBackend): - export PYTHONPATH=$LLVM_BUILD_DIR/tools/mlir/python_packages/mlir_core:$PTOAS_BUILD_DIR/python + export PYTHONPATH=$PTOAS_BUILD_DIR/python """ import sys @@ -46,7 +46,7 @@ def _check_pto_dialect_available(): """Check if PTO dialect bindings are available.""" try: - from mlir.dialects import pto + from ptoas.mlir.dialects import pto return True except ImportError: return False @@ -309,4 +309,4 @@ def main(): if __name__ == "__main__": success = main() - sys.exit(0 if success else 1) \ No newline at end of file + sys.exit(0 if success else 1) diff --git a/python/CMakeLists.txt b/tilelang-dsl/tests/test_lowering_backend_conversion.py similarity index 51% rename from python/CMakeLists.txt rename to tilelang-dsl/tests/test_lowering_backend_conversion.py index a044a0049b..35d724b84d 100644 --- a/python/CMakeLists.txt +++ b/tilelang-dsl/tests/test_lowering_backend_conversion.py @@ -6,22 +6,18 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -# ========================================================= -# Python Package Configuration -# ========================================================= +import unittest -add_custom_target(PTOPythonModules) +from ptoas.mlir import ir +from tilelang_dsl.lowering_backend import LoweringResult -# [修改] 依赖必须指向 lib/Bindings/Python 中定义的 Target (_pto) -add_dependencies(PTOPythonModules _pto) -# 生成 TableGen 绑定代码 -set(LLVM_TARGET_DEFINITIONS pto/dialects/PTOOps.td) -mlir_tablegen(pto/dialects/_pto_ops_gen.py - -gen-python-op-bindings - -bind-dialect=pto - -I${PROJECT_SOURCE_DIR}/include -) -add_public_tablegen_target(PTOOpsPyGen) +class LoweringBackendConversionTests(unittest.TestCase): + def test_text_result_parses_with_namespaced_pto_dialect(self): + module = LoweringResult(text="module {}").as_module() -add_dependencies(PTOPythonModules PTOOpsPyGen) + self.assertIsInstance(module, ir.Module) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/ptoas/CMakeLists.txt b/tools/ptoas/CMakeLists.txt index 1e2918bd5a..7a8575f854 100644 --- a/tools/ptoas/CMakeLists.txt +++ b/tools/ptoas/CMakeLists.txt @@ -6,10 +6,10 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -# Please refer to the License for details. You may not use this file except in compliance with the License. -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. -# See LICENSE in the root of the software repository for the full text of the License. +# Do not carry toolchain-injected paths, such as a Conda compiler RPATH, into +# installed Python modules. Distribution builds keep only package-relative +# RPATHs; editable builds add the external LLVM directory explicitly below. +set(CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH ON) set(PTOAS_RUNTIME_SOURCES ptoas.cpp @@ -21,19 +21,38 @@ set(PTOAS_RUNTIME_SOURCES set(PTOAS_WRAPPER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/ptoas_wrapper.py") set(PTOAS_WRAPPER_BINARY "${CMAKE_CURRENT_BINARY_DIR}/ptoas") +set(PTOAS_INSTALL_WRAPPER_BINARY "${CMAKE_CURRENT_BINARY_DIR}/ptoas-install") +set(PTOAS_WRAPPER_PYTHON_ROOT_MODE "absolute") +set(PTOAS_WRAPPER_PYTHON_ROOT "${CMAKE_BINARY_DIR}/python") configure_file( "${PTOAS_WRAPPER_SOURCE}" "${PTOAS_WRAPPER_BINARY}" @ONLY ) -file(CHMOD "${PTOAS_WRAPPER_BINARY}" - PERMISSIONS - OWNER_READ OWNER_WRITE OWNER_EXECUTE - GROUP_READ GROUP_EXECUTE - WORLD_READ WORLD_EXECUTE + +# CMake install prefixes may be overridden at install time. Resolve the +# installed package relative to bin/ptoas instead of baking in the configure +# prefix. +set(PTOAS_WRAPPER_PYTHON_ROOT_MODE "wrapper-relative") +set(PTOAS_WRAPPER_PYTHON_ROOT "..") +configure_file( + "${PTOAS_WRAPPER_SOURCE}" + "${PTOAS_INSTALL_WRAPPER_BINARY}" + @ONLY ) +foreach(_ptoas_wrapper IN ITEMS + "${PTOAS_WRAPPER_BINARY}" + "${PTOAS_INSTALL_WRAPPER_BINARY}") + file(CHMOD "${_ptoas_wrapper}" + PERMISSIONS + OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE + ) +endforeach() + function(ptoas_configure_runtime_target target_name) target_compile_definitions(${target_name} PRIVATE PTOAS_RELEASE_VERSION="${PTOAS_CLI_VERSION}" @@ -45,18 +64,12 @@ function(ptoas_configure_runtime_target target_name) PTOAS_DEFAULT_TILELANG_PATH="${CMAKE_SOURCE_DIR}/lib/TileOps" PTOAS_DEFAULT_TILELANG_PKG_PATH="${CMAKE_SOURCE_DIR}/tilelang-dsl/python" PTOAS_DEFAULT_PTODSL_PKG_PATH="${CMAKE_SOURCE_DIR}/ptodsl" - ${ARGN} ) - target_link_libraries(${target_name} PRIVATE - # === 你的本地库 (请确认 lib/PTO/*/CMakeLists.txt 里的定义名) === - PTOIR # 替代 MLIRPTODialect - PTOTransforms # 替代 MLIRPTOTransforms + target_link_libraries(${target_name} PUBLIC + PTOIR + PTOTransforms ptobc_lib - - # === MLIR 基础设施 === - MLIRMlirOptMain # [重要] 包含了 main 函数入口逻辑,通常必须链接 - - # === MLIR 标准库 === + MLIRMlirOptMain MLIRBufferizationTransforms MLIRArithTransforms MLIRTensorTransforms @@ -86,53 +99,121 @@ function(ptoas_configure_runtime_target target_name) ) endfunction() -add_library(ptoas_runtime SHARED ${PTOAS_RUNTIME_SOURCES}) -# Keep the shared runtime's compile mode aligned with LLVM/MLIR so RTTI, -# exceptions, and visibility expectations match the libraries it links to. -llvm_update_compile_flags(ptoas_runtime) -set_target_properties(ptoas_runtime PROPERTIES - OUTPUT_NAME "ptoas" - PREFIX "" -) -ptoas_configure_runtime_target(ptoas_runtime - PTOAS_BUILD_SHARED_LIBRARY=1 -) - -set(PTOAS_BUILD_RUNTIME_STAGING_DIR "${CMAKE_BINARY_DIR}/runtime-staging") -add_custom_target(ptoas_runtime_staging ALL - COMMAND ${CMAKE_COMMAND} -E make_directory - "${PTOAS_BUILD_RUNTIME_STAGING_DIR}/lib" - "${PTOAS_BUILD_RUNTIME_STAGING_DIR}/share/ptoas" - COMMAND ${CMAKE_COMMAND} -E copy_if_different - "$" - "${PTOAS_BUILD_RUNTIME_STAGING_DIR}/lib/ptoas.so" - COMMAND ${CMAKE_COMMAND} -E remove_directory - "${PTOAS_BUILD_RUNTIME_STAGING_DIR}/share/ptoas/TileOps" - COMMAND ${CMAKE_COMMAND} -E copy_directory - "${CMAKE_SOURCE_DIR}/lib/TileOps" - "${PTOAS_BUILD_RUNTIME_STAGING_DIR}/share/ptoas/TileOps" - DEPENDS ptoas_runtime - COMMENT "Staging ptoas runtime into build/runtime-staging" - VERBATIM +# Keep the LLVM-based driver sources under LLVM's RTTI/exception compile mode. +# The pybind11 translation unit must retain the Python extension's normal RTTI +# and exception mode, so it is compiled by the module target separately. +add_library(ptoas_runtime_objects OBJECT ${PTOAS_RUNTIME_SOURCES}) +llvm_update_compile_flags(ptoas_runtime_objects) +ptoas_configure_runtime_target(ptoas_runtime_objects) + +# Build the single PTOAS-owned Python extension. It contains both the compiler +# driver and PTO dialect bindings, while linking MLIR's shared common CAPI so +# Python-created MLIR objects and the compiler use the same MLIR runtime. +set(PTOAS_BUILD_PYTHON_PACKAGE_DIR "${CMAKE_BINARY_DIR}/python/ptoas") +add_mlir_python_extension(PTOASPythonCore _core + INSTALL_COMPONENT PTOAS_Python + INSTALL_DIR ptoas + OUTPUT_DIRECTORY "${PTOAS_BUILD_PYTHON_PACKAGE_DIR}" + PYTHON_BINDINGS_LIBRARY pybind11 + SOURCES + NativeModule.cpp + "${CMAKE_SOURCE_DIR}/lib/Bindings/Python/PTOModule.cpp" + LINK_LIBS + ptoas_runtime_objects + PTOCAPI + PTOASPythonCAPI ) +target_compile_definitions(PTOASPythonCore PRIVATE + "MLIR_PYTHON_PACKAGE_PREFIX=ptoas.mlir." +) +target_include_directories(PTOASPythonCore PRIVATE + "${CMAKE_SOURCE_DIR}/lib/Bindings/Python" +) +mlir_python_setup_extension_rpath(PTOASPythonCore) + +if(APPLE) + set_property(TARGET PTOASPythonCore PROPERTY INSTALL_RPATH + "@loader_path;@loader_path/mlir/_mlir_libs") +elseif(UNIX) + set_property(TARGET PTOASPythonCore PROPERTY INSTALL_RPATH + "$ORIGIN;$ORIGIN/mlir/_mlir_libs") +endif() +ptoas_append_editable_llvm_rpath(PTOASPythonCore) +declare_mlir_python_sources(PTOASRuntimePythonSources + ROOT_DIR "${CMAKE_SOURCE_DIR}/ptodsl/ptoas" + SOURCES_GLOB "*.py" +) +add_mlir_python_sources_target(PTOASRuntimePythonSourcesStage + OUTPUT_DIRECTORY "${PTOAS_BUILD_PYTHON_PACKAGE_DIR}" + SOURCES_TARGETS PTOASRuntimePythonSources +) + +declare_mlir_python_sources(PTOASTileOpsPythonSources + ROOT_DIR "${CMAKE_SOURCE_DIR}/lib/TileOps" + SOURCES_GLOB "*.py" +) +add_mlir_python_sources_target(PTOASTileOpsPythonSourcesStage + OUTPUT_DIRECTORY + "${PTOAS_BUILD_PYTHON_PACKAGE_DIR}/_runtime/share/ptoas/TileOps" + SOURCES_TARGETS PTOASTileOpsPythonSources +) + +add_custom_target(PTOASPythonPackage ALL) +add_dependencies(PTOASPythonPackage + PTOASPythonCore + PTOAS_Python + PTOASRuntimePythonSourcesStage + PTOASTileOpsPythonSourcesStage +) if(TARGET PTODSLPackage) - # The build-tree launcher imports ptoas._runtime_entry from build/python. - # Keep that package staging coupled to every runtime staging entrypoint, - # including partial builds such as tools/ptoas/all. - add_dependencies(ptoas_runtime_staging PTODSLPackage) + add_dependencies(PTOASPythonPackage PTODSLPackage) +endif() +if(TARGET TileLangDSLPackage) + add_dependencies(PTOASPythonPackage TileLangDSLPackage) endif() if(TARGET ptoas_runtime_deps) - add_dependencies(ptoas_runtime_deps ptoas_runtime_staging) + add_dependencies(ptoas_runtime_deps PTOASPythonPackage) endif() -install(PROGRAMS "${PTOAS_WRAPPER_BINARY}" +install(PROGRAMS "${PTOAS_INSTALL_WRAPPER_BINARY}" DESTINATION bin - COMPONENT PTOAS_Runtime + RENAME ptoas + COMPONENT PTOAS_CompilerArchive +) + +set(PTOAS_ARCHIVE_PYTHON_VERSION_FILE + "${CMAKE_CURRENT_BINARY_DIR}/.ptoas-python-version") +file(WRITE "${PTOAS_ARCHIVE_PYTHON_VERSION_FILE}" + "${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR}\n") +install(FILES "${PTOAS_ARCHIVE_PYTHON_VERSION_FILE}" + DESTINATION "." + COMPONENT PTOAS_CompilerArchive +) + +# The standalone compiler archive is staged by installing PTOAS_Python first +# and PTOAS_CompilerArchive second into the same prefix. Generate the deploy +# script so known native entry points come from CMake targets; the script scans +# only AddMLIRPython's generated extension directory for the remaining modules. +configure_file( + "${CMAKE_SOURCE_DIR}/cmake/RelocatePTOASCompilerArchive.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/RelocatePTOASCompilerArchive.cmake.in" + @ONLY +) +file(GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/RelocatePTOASCompilerArchive.cmake" + INPUT "${CMAKE_CURRENT_BINARY_DIR}/RelocatePTOASCompilerArchive.cmake.in" +) +install(SCRIPT + "${CMAKE_CURRENT_BINARY_DIR}/RelocatePTOASCompilerArchive.cmake" + COMPONENT PTOAS_CompilerArchive ) -install(TARGETS ptoas_runtime - LIBRARY DESTINATION lib - COMPONENT PTOAS_Runtime +install( + DIRECTORY "${CMAKE_SOURCE_DIR}/lib/TileOps" + DESTINATION "ptoas/_runtime/share/ptoas" + COMPONENT PTOAS_Python + PATTERN "__pycache__" EXCLUDE + PATTERN "*.pyc" EXCLUDE ) diff --git a/tools/ptoas/NativeModule.cpp b/tools/ptoas/NativeModule.cpp new file mode 100644 index 0000000000..5a474cbd27 --- /dev/null +++ b/tools/ptoas/NativeModule.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2026 Huawei Technologies Co., Ltd. +// This program is free software, you can redistribute it and/or modify it under the terms and conditions of +// CANN Open Software License Agreement Version 2.0 (the "License"). +// Please refer to the License for details. You may not use this file except in compliance with the License. +// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// See LICENSE in the root of the software repository for the full text of the License. + +#include "ptoas.h" + +#include "PTOModule.h" + +#include "pybind11/pybind11.h" +#include "pybind11/stl.h" + +#include +#include + +namespace py = pybind11; + +namespace { + +int runPTOASFromPython(const std::vector &arguments) { + std::vector storage = arguments; + std::vector argv; + argv.reserve(storage.size()); + for (std::string &argument : storage) + argv.push_back(argument.data()); + + py::gil_scoped_release release; + return mlir::pto::runPTOAS(static_cast(argv.size()), argv.data()); +} + +} // namespace + +PYBIND11_MODULE(_core, module) { + module.doc() = "PTOAS compiler and PTO dialect native bindings"; + py::module_::import("ptoas.mlir.ir"); + mlir::pto::python::populatePTODialectBindings(module); + module.def("main", &runPTOASFromPython, py::arg("argv")); +} diff --git a/tools/ptoas/driver.cpp b/tools/ptoas/driver.cpp index 6caa23ce33..5c6e81b79e 100644 --- a/tools/ptoas/driver.cpp +++ b/tools/ptoas/driver.cpp @@ -1284,12 +1284,6 @@ static int runPTOASDriver(int argc, char **argv) { return 1; } -extern "C" int ptoas_entrypoint(int argc, char **argv) { +int mlir::pto::runPTOAS(int argc, char **argv) { return runPTOASDriver(argc, argv); } - -#ifndef PTOAS_BUILD_SHARED_LIBRARY -int main(int argc, char **argv) { - return runPTOASDriver(argc, argv); -} -#endif diff --git a/tools/ptoas/ptoas.h b/tools/ptoas/ptoas.h index 92ce03ecee..ba422628a8 100644 --- a/tools/ptoas/ptoas.h +++ b/tools/ptoas/ptoas.h @@ -125,8 +125,8 @@ void registerPTOASDialects(DialectRegistry ®istry); void registerPTOASPassesAndCLOptions(); void loadPTOASDialects(MLIRContext &context); -// Shared-library entrypoint for wheel-installed in-process launching. -extern "C" int ptoas_entrypoint(int argc, char **argv); +// Reusable driver entry shared by the Python extension and standalone CLI. +int runPTOAS(int argc, char **argv); // Attach textual-.pto SSA name hints (function args, block args, op results) // to the parsed module's Locations as debug metadata. Called by the driver diff --git a/tools/ptoas/ptoas_wrapper.py b/tools/ptoas/ptoas_wrapper.py index 3dadc46d16..0328d9733f 100644 --- a/tools/ptoas/ptoas_wrapper.py +++ b/tools/ptoas/ptoas_wrapper.py @@ -7,142 +7,75 @@ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. # See LICENSE in the root of the software repository for the full text of the License. -"""Build/install-tree wrapper for the `ptoas` entrypoint. - -This script is configured into the build tree and installed as `bin/ptoas`. -It bootstraps the Python package root for tree layouts, then delegates to the -shared in-process runtime entry contract in `ptoas._runtime_entry`. -""" +"""Run the regular PTOAS CLI from a configured CMake package tree.""" from __future__ import annotations -import shutil import sys from pathlib import Path +_PYTHON_ROOT_MODE = "@PTOAS_WRAPPER_PYTHON_ROOT_MODE@" +_PYTHON_ROOT = Path(r"@PTOAS_WRAPPER_PYTHON_ROOT@") +_ARCHIVE_PYTHON_REQUIREMENT_FILE = ".ptoas-python-version" + + def _resolve_wrapper_path(argv0: str | None = None) -> Path: candidate = argv0 if argv0 is not None else sys.argv[0] wrapper = Path(candidate) if wrapper.exists(): return wrapper.resolve() - found = shutil.which(wrapper.name or "ptoas") - if found: - return Path(found).resolve() - - raise SystemExit(f"unable to locate the installed ptoas wrapper: {candidate}") - - -def _build_tree_root(wrapper: Path) -> Path | None: - if len(wrapper.parents) < 3: - return None - return wrapper.parents[2] - - -def _install_tree_root(wrapper: Path) -> Path | None: - if len(wrapper.parents) < 2: - return None - return wrapper.parents[1] - - -def _is_build_tree_wrapper(wrapper: Path) -> bool: - return len(wrapper.parents) >= 2 and wrapper.parents[1].name == "tools" + raise SystemExit(f"unable to locate the ptoas tree wrapper: {candidate}") def _require_python_root(python_root: Path, *, context: str) -> Path: - helper = python_root / "ptoas" / "_runtime_entry.py" + helper = python_root / "ptoas" / "_cli.py" if helper.is_file(): return python_root.resolve() raise SystemExit( f"unable to locate the {context} ptoas Python package root: " - f"expected {python_root}/ptoas/_runtime_entry.py" - ) - - -def _require_runtime_root(runtime_root: Path) -> Path: - shared_module = runtime_root / "lib" / "ptoas.so" - tileops_dir = runtime_root / "share" / "ptoas" / "TileOps" - if shared_module.is_file() and shared_module.stat().st_size > 0 and tileops_dir.is_dir(): - return runtime_root.resolve() - raise SystemExit( - "unable to locate the ptoas runtime tree: expected " - f"{runtime_root}/lib/ptoas.so and {runtime_root}/share/ptoas/TileOps" + f"expected {python_root}/ptoas/_cli.py" ) -def _resolve_build_tree_layout(wrapper: Path): - from ptoas import _runtime_entry +def _configured_python_root(wrapper: Path) -> Path: + if _PYTHON_ROOT_MODE == "absolute": + return _PYTHON_ROOT + if _PYTHON_ROOT_MODE == "wrapper-relative": + return wrapper.parent / _PYTHON_ROOT + raise SystemExit(f"unsupported PTOAS wrapper mode: {_PYTHON_ROOT_MODE}") - build_root = _build_tree_root(wrapper) - if build_root is None: - raise SystemExit("unable to locate the build-tree layout for ptoas") - python_root = _require_python_root(build_root / "python", context="build-tree") - runtime_root = _require_runtime_root(build_root / "runtime-staging") - - return _runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper, - runtime_root=runtime_root, - python_root=python_root, - shared_module=(runtime_root / "lib" / "ptoas.so").resolve(), - tileops_dir=(runtime_root / "share" / "ptoas" / "TileOps").resolve(), - isolated_env=False, +def _add_configured_python_root(wrapper: Path) -> Path: + python_root = _require_python_root( + _configured_python_root(wrapper), context="configured" ) - -def _resolve_install_tree_layout(wrapper: Path): - from ptoas import _runtime_entry - - install_root = _install_tree_root(wrapper) - if install_root is None: - raise SystemExit("unable to locate the install-tree layout for ptoas") - - python_root = _require_python_root(install_root, context="install-tree") - runtime_root = _require_runtime_root(install_root) - - return _runtime_entry.PTOASRuntimeLayout( - wrapper=wrapper, - runtime_root=runtime_root, - python_root=python_root, - shared_module=(runtime_root / "lib" / "ptoas.so").resolve(), - tileops_dir=(runtime_root / "share" / "ptoas" / "TileOps").resolve(), - isolated_env=False, - ) - - -def _bootstrap_python_path(wrapper: Path) -> None: - if _is_build_tree_wrapper(wrapper): - build_root = _build_tree_root(wrapper) - if build_root is not None: - root = build_root / "python" - _require_python_root(root, context="build-tree") - root_text = str(root) - if root_text not in sys.path: - sys.path.insert(0, root_text) - return - raise SystemExit("unable to locate the build-tree layout for ptoas") - - install_root = _install_tree_root(wrapper) - if install_root is not None: - _require_python_root(install_root, context="install-tree") - root_text = str(install_root) - if root_text not in sys.path: - sys.path.insert(0, root_text) - return - raise SystemExit("unable to locate the ptoas Python package root for the build/install-tree wrapper") + python_root_text = str(python_root) + if python_root_text not in sys.path: + sys.path.insert(0, python_root_text) + return python_root def main() -> None: wrapper = _resolve_wrapper_path() - _bootstrap_python_path(wrapper) - from ptoas import _runtime_entry - - if _is_build_tree_wrapper(wrapper): - layout = _resolve_build_tree_layout(wrapper) - else: - layout = _resolve_install_tree_layout(wrapper) - raise SystemExit(_runtime_entry.launch(layout, sys.argv[1:])) + requirement_file = wrapper.parent.parent / _ARCHIVE_PYTHON_REQUIREMENT_FILE + if requirement_file.is_file(): + required_python_major_minor = requirement_file.read_text( + encoding="utf-8" + ).strip() + actual = f"{sys.version_info.major}.{sys.version_info.minor}" + if actual != required_python_major_minor: + raise SystemExit( + "this ptoas compiler archive requires CPython " + f"{required_python_major_minor}, but the active interpreter is " + f"{actual} ({sys.executable})" + ) + _add_configured_python_root(wrapper) + from ptoas import _cli + + raise SystemExit(_cli.launch(sys.argv[1:], wrapper=wrapper)) if __name__ == "__main__":