Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions .github/workflows/_packaging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,22 @@ jobs:
if: inputs.setup_variant == 'github'
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y cmake ninja-build g++
missing_packages=()
command -v ninja >/dev/null 2>&1 || missing_packages+=(ninja-build)
command -v ccache >/dev/null 2>&1 || missing_packages+=(ccache)
if ! command -v gcc >/dev/null 2>&1 || ! command -v g++ >/dev/null 2>&1; then
missing_packages+=(g++)
fi
if (( ${#missing_packages[@]} )); then
sudo apt-get update
sudo apt-get install -y "${missing_packages[@]}"
fi
else
brew install ninja cmake
brew install gcc@15 || brew install gcc
command -v ninja >/dev/null 2>&1 || brew install ninja
command -v ccache >/dev/null 2>&1 || brew install ccache
if ! command -v gcc-15 >/dev/null 2>&1 || ! command -v g++-15 >/dev/null 2>&1; then
brew install gcc@15 || brew install gcc
fi
fi

- name: Set up Python ${{ inputs.python_version }}
Expand All @@ -61,9 +72,28 @@ jobs:
- name: Install build + runtime deps in venv
uses: ./.github/actions/setup-venv
with:
packages: "scikit-build-core nanobind cmake>=3.15 pytest"
packages: "scikit-build-core>=0.10.0 nanobind>=2.0.0 cmake>=3.15 pytest>=6.0"

- name: Run packaging matrix
run: |
. .venv/bin/activate
if [[ "${{ runner.os }}" == "macOS" ]]; then
export MACOSX_DEPLOYMENT_TARGET
MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -d. -f1,2)"
fi
if command -v ccache >/dev/null 2>&1; then
export CCACHE_DIR="$RUNNER_TEMP/simpler-packaging-ccache"
# Keep one cold build per job while reusing identical objects
# across the remaining clean-install modes.
if ccache --clear && ccache --max-size=1G && ccache --zero-stats; then
export CMAKE_C_COMPILER_LAUNCHER=ccache
export CMAKE_CXX_COMPILER_LAUNCHER=ccache
trap 'ccache --show-stats || true' EXIT
else
unset CCACHE_DIR
echo "::warning::ccache initialization failed; running without compiler cache"
fi
else
echo "::notice::ccache not found; running packaging matrix without compiler cache"
fi
bash tools/verify_packaging.sh
32 changes: 17 additions & 15 deletions .github/workflows/_profiling-flags-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,26 @@ jobs:
- name: Run all profiling flag combos x 2 arches
run: |
COMBO_NAMES=(dfx-off orch orch-tensormap sched orch-sched all-on)
COMBO_DEFS=(
"-DSIMPLER_DFX=0"
"-DSIMPLER_ORCH_PROFILING=1"
"-DSIMPLER_ORCH_PROFILING=1 -DSIMPLER_TENSORMAP_PROFILING=1"
"-DSIMPLER_SCHED_PROFILING=1"
"-DSIMPLER_ORCH_PROFILING=1 -DSIMPLER_SCHED_PROFILING=1"
"-DSIMPLER_ORCH_PROFILING=1 -DSIMPLER_SCHED_PROFILING=1 -DSIMPLER_TENSORMAP_PROFILING=1"
)
COMBO_DFX=(0 1 1 1 1 1)
COMBO_ORCH=(0 1 1 0 1 1)
COMBO_SCHED=(0 0 0 1 1 1)
COMBO_TENSORMAP=(0 0 1 0 0 1)
ARCHES=(a2a3sim a5sim)
FAIL=()

for ARCH in "${ARCHES[@]}"; do
ARCH_DIR=${ARCH%sim}
for i in "${!COMBO_NAMES[@]}"; do
NAME=${COMBO_NAMES[$i]}
DEFS=${COMBO_DEFS[$i]}
echo "::group::$ARCH / $NAME - CXX defines: $DEFS"
if ! CXX="g++ $DEFS" .venv/bin/python simpler_setup/build_runtimes.py --platforms "$ARCH"; then
# Each architecture keeps one persistent CMake tree. Updating the
# generated config header rebuilds only objects that include it.
for i in "${!COMBO_NAMES[@]}"; do
NAME=${COMBO_NAMES[$i]}
for ARCH in "${ARCHES[@]}"; do
ARCH_DIR=${ARCH%sim}
echo "::group::$ARCH / $NAME"
if ! .venv/bin/python simpler_setup/build_runtimes.py \
--platforms "$ARCH" \
--profiling-dfx "${COMBO_DFX[$i]}" \
--profiling-orch "${COMBO_ORCH[$i]}" \
--profiling-sched "${COMBO_SCHED[$i]}" \
--profiling-tensormap "${COMBO_TENSORMAP[$i]}"; then
echo "::error::Build failed: $ARCH / $NAME"
FAIL+=("$ARCH/$NAME (build)")
echo "::endgroup::"
Expand Down
7 changes: 2 additions & 5 deletions .github/workflows/_st-pod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,10 @@ jobs:
if: always()
uses: ./.github/actions/pod-teardown

# Both sides' device logs and each daemon's output land under the run
# directory and stay on the runner otherwise. A device-side failure — a
# scheduler timeout on the peer, say — names its sub-class only there, so
# without this the run page shows the host traceback and nothing that
# explains it.
# Artifact service availability must not override the POD test result.
- name: Upload pod logs
if: always()
continue-on-error: true
uses: actions/upload-artifact@v4
with:
name: pod-ci-${{ github.run_id }}-${{ github.run_attempt }}
Expand Down
11 changes: 5 additions & 6 deletions .github/workflows/_ut-no-hardware.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,7 @@ jobs:
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y cmake libgtest-dev
cd /usr/src/googletest
sudo cmake -B build
sudo cmake --build build
sudo cmake --install build
sudo apt-get install -y libgtest-dev
else
brew install googletest
fi
Expand All @@ -65,7 +61,10 @@ jobs:
if: inputs.setup_variant == 'github'
run: |
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install '.[test]'
pip install 'scikit-build-core>=0.10.0' 'nanobind>=2.0.0' 'cmake>=3.15'
# Worker integration tests exercise both a2a3sim and a5sim.
pip install --no-build-isolation \
--config-settings=build.targets=build_package_sim -e '.[test]'

- name: venv + deps
if: inputs.setup_variant == 'self-cpu'
Expand Down
17 changes: 6 additions & 11 deletions .github/workflows/_ut-npu-a2a3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,19 @@ jobs:
system-site-packages: "true"
source-cann: "true"

- name: Run Python hardware unit tests (a2a3)
- name: Build C++ hardware unit tests (a2a3)
run: |
source /usr/local/Ascend/cann/set_env.sh
source .venv/bin/activate
if [ "$(uname -m)" = "x86_64" ]; then
python -m pytest tests/ut -m requires_hardware --platform a2a3 --device ${DEVICE_RANGE} -v
else
task-submit --timeout 1800 --max-time 1800 --device auto --device-num "$DEVICE_NUM" \
--run "python -m pytest tests/ut -m requires_hardware --platform a2a3 --device \$TASK_DEVICE -v"
fi
cmake -B tests/ut/cpp/build -S tests/ut/cpp -DSIMPLER_ENABLE_HARDWARE_TESTS=ON
cmake --build tests/ut/cpp/build --target test_comm_lifecycle

- name: Build and run C++ hardware unit tests (a2a3)
- name: Run Python and C++ hardware unit tests (a2a3)
run: |
source /usr/local/Ascend/cann/set_env.sh
source .venv/bin/activate
cmake -B tests/ut/cpp/build -S tests/ut/cpp -DSIMPLER_ENABLE_HARDWARE_TESTS=ON
cmake --build tests/ut/cpp/build --target test_comm_lifecycle
if [ "$(uname -m)" = "x86_64" ]; then
python -m pytest tests/ut -m requires_hardware --platform a2a3 --device ${DEVICE_RANGE} -v
python3 -c "
import json, os
p = os.environ['DEVICE_RANGE'].split('-'); s, e = p[0], p[-1]
Expand All @@ -74,7 +69,7 @@ jobs:
ctest --test-dir tests/ut/cpp/build -L '^requires_hardware(_a2a3)?$' --resource-spec-file $PWD/tests/ut/cpp/build/resources.json -j$(nproc) --output-on-failure
else
task-submit --timeout 1800 --max-time 1800 --device auto --device-num "$DEVICE_NUM" \
--run "python3 -c \"import json,os; ids=os.environ['TASK_DEVICE'].split(','); json.dump({'version':{'major':1,'minor':0},'local':[{'npus':[{'id':i,'slots':1} for i in ids]}]}, open('tests/ut/cpp/build/resources.json','w'))\" && ctest --test-dir tests/ut/cpp/build -L '^requires_hardware(_a2a3)?\$' --resource-spec-file $PWD/tests/ut/cpp/build/resources.json -j$(nproc) --output-on-failure"
--run "python -m pytest tests/ut -m requires_hardware --platform a2a3 --device \$TASK_DEVICE -v && python3 -c \"import json,os; ids=os.environ['TASK_DEVICE'].split(','); json.dump({'version':{'major':1,'minor':0},'local':[{'npus':[{'id':i,'slots':1} for i in ids]}]}, open('tests/ut/cpp/build/resources.json','w'))\" && ctest --test-dir tests/ut/cpp/build -L '^requires_hardware(_a2a3)?\$' --resource-spec-file $PWD/tests/ut/cpp/build/resources.json -j$(nproc) --output-on-failure"
fi

- name: Build cann-examples/query
Expand Down
18 changes: 18 additions & 0 deletions cmake/profiling_build_config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* Generated by CMake. Do not edit. */
#ifndef SIMPLER_PROFILING_BUILD_CONFIG_H_
#define SIMPLER_PROFILING_BUILD_CONFIG_H_

#ifndef SIMPLER_DFX
#define SIMPLER_DFX @SIMPLER_DFX@
#endif
#ifndef SIMPLER_ORCH_PROFILING
#define SIMPLER_ORCH_PROFILING @SIMPLER_ORCH_PROFILING@
#endif
#ifndef SIMPLER_SCHED_PROFILING
#define SIMPLER_SCHED_PROFILING @SIMPLER_SCHED_PROFILING@
#endif
#ifndef SIMPLER_TENSORMAP_PROFILING
#define SIMPLER_TENSORMAP_PROFILING @SIMPLER_TENSORMAP_PROFILING@
#endif

#endif // SIMPLER_PROFILING_BUILD_CONFIG_H_
54 changes: 54 additions & 0 deletions cmake/profiling_config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright (c) PyPTO Contributors.
# 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(_SIMPLER_PROFILING_CONFIG_DIR "${CMAKE_CURRENT_LIST_DIR}")

function(simpler_configure_profiling target)
foreach(name IN ITEMS
SIMPLER_DFX
SIMPLER_ORCH_PROFILING
SIMPLER_SCHED_PROFILING
SIMPLER_TENSORMAP_PROFILING)
if(DEFINED ${name} AND NOT "${${name}}" MATCHES "^[01]$")
message(FATAL_ERROR "${name} must be 0 or 1")
endif()
endforeach()

if(NOT DEFINED SIMPLER_DFX)
set(SIMPLER_DFX 1)
endif()
if(NOT DEFINED SIMPLER_ORCH_PROFILING)
set(SIMPLER_ORCH_PROFILING 0)
endif()
if(NOT DEFINED SIMPLER_SCHED_PROFILING)
set(SIMPLER_SCHED_PROFILING 0)
endif()
if(NOT DEFINED SIMPLER_TENSORMAP_PROFILING)
set(SIMPLER_TENSORMAP_PROFILING 0)
endif()

if(SIMPLER_ORCH_PROFILING AND NOT SIMPLER_DFX)
message(FATAL_ERROR "SIMPLER_ORCH_PROFILING requires SIMPLER_DFX=1")
endif()
if(SIMPLER_SCHED_PROFILING AND NOT SIMPLER_DFX)
message(FATAL_ERROR "SIMPLER_SCHED_PROFILING requires SIMPLER_DFX=1")
endif()
if(SIMPLER_TENSORMAP_PROFILING AND NOT SIMPLER_ORCH_PROFILING)
message(FATAL_ERROR "SIMPLER_TENSORMAP_PROFILING requires SIMPLER_ORCH_PROFILING=1")
endif()

set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
file(MAKE_DIRECTORY "${generated_dir}")
configure_file(
"${_SIMPLER_PROFILING_CONFIG_DIR}/profiling_build_config.h.in"
"${generated_dir}/simpler_profiling_build_config.h"
@ONLY
)
target_include_directories(${target} PRIVATE "${generated_dir}")
endfunction()
12 changes: 6 additions & 6 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ means adding a `test_*.py` wrapper with `@scene_level(SceneTestLevel.POD)`, not
editing `_st-pod.yml`. `pod_remote_device_count` stays as the peer-resource
declaration; `pod` is the runner topology, not a pytest selection marker.

Pod logs go to `output/pod-ci-<run>-<attempt>/pytest/` and the whole directory
is uploaded as one artifact. Parent-side `ASCEND_PROCESS_LOG_PATH` is split per
pytest nodeid by `st_pod_logs`; peer-side daemon/device logs are grouped for the
pytest session. Reach for the artifact first on a device-side failure: the host
traceback only says the peer's scheduler gave up, and the sub-class saying why
is printed on the device.
Pod logs go to `output/pod-ci-<run>-<attempt>/pytest/` while the job is running.
Parent-side `ASCEND_PROCESS_LOG_PATH` is split per pytest nodeid by
`st_pod_logs`; peer-side daemon/device logs are grouped for the pytest session.
The directory is uploaded on a best-effort basis: artifact-service failures are
ignored so they cannot override the POD test result. Preserve relevant
diagnostics in the inline job log as well when investigating a failure.

Writing an example — the files, the entry module, the `run(...)` entry point,
the `test_*.py` pod wrapper, and the manual `run_parent.sh` — is covered in
Expand Down
5 changes: 3 additions & 2 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,15 +107,16 @@ All workflows assume an activated project-local venv (see [`.claude/rules/venv-i
```bash
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install --no-build-isolation scikit-build-core nanobind 'cmake>=3.15' pytest torch
pip install --no-build-isolation \
'scikit-build-core>=0.10.0' 'nanobind>=2.0.0' 'cmake>=3.15' 'pytest>=6.0' 'torch>=2.3'
pip install --no-build-isolation -e .
```

Editing Python is instant (editable install). Editing C++ requires re-running `pip install --no-build-isolation -e .` (scikit-build-core's auto-rebuild is disabled because it interacts badly with pip's ephemeral build env — see `docs/python-packaging.md`).

**Other supported paths:** `pip install .` (non-editable), `pip install --no-build-isolation .`, `pip install -e .`, and `cmake + PYTHONPATH` (no pip). Full comparison of all 5 paths — what lands where, which entry points work under each, trade-offs — lives in [`docs/python-packaging.md`](python-packaging.md).

**Verifying an install:** the single source of truth is `tools/verify_packaging.sh`, which exercises all 5 install paths × 4 entry points from a fully clean state. CI runs the same script on macOS + Ubuntu (see the `packaging-matrix` job in `.github/workflows/ci.yml`).
**Verifying an install:** the single source of truth is `tools/verify_packaging.sh`, which exercises all 5 install paths × 2 entry points from a fully clean state. CI runs the same script on macOS + Ubuntu (see the `packaging-matrix` job in `.github/workflows/ci.yml`).

## Build Process

Expand Down
6 changes: 3 additions & 3 deletions docs/python-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ For developers who don't want to use pip at all:

```bash
. .venv/bin/activate
pip install scikit-build-core nanobind 'cmake>=3.15' pytest torch # one-time
pip install 'scikit-build-core>=0.10.0' 'nanobind>=2.0.0' 'cmake>=3.15' 'pytest>=6.0' 'torch>=2.3' # one-time
cmake -S . -B build/cmake_only -Dnanobind_DIR=$(python -c 'import nanobind; print(nanobind.cmake_dir())')
cmake --build build/cmake_only
export PYTHONPATH=$(pwd):$(pwd)/python
Expand Down Expand Up @@ -158,11 +158,11 @@ Any change that touches:
```bash
# Locally — same script CI runs.
source .venv/bin/activate
pip install scikit-build-core nanobind 'cmake>=3.15' pytest torch # one-time
pip install 'scikit-build-core>=0.10.0' 'nanobind>=2.0.0' 'cmake>=3.15' 'pytest>=6.0' 'torch>=2.3' # one-time
bash tools/verify_packaging.sh
```

The script wipes `build/`, uninstalls `simpler`, and re-runs the install + smoke check from scratch for every mode, so a previous mode's cached binaries cannot mask a regression in the next. Slow (~25–45 min for all 5 modes) but reliable. Both CI and the local invocation use the same script — there's no second source of truth that can drift.
The script wipes `build/`, uninstalls `simpler`, and re-runs the install + smoke check from scratch for every mode, so a previous mode's cached binaries cannot mask a regression in the next. Smoke checks run from a temporary directory outside the repository, preventing source files from shadowing an incomplete wheel install. Slow (~25–45 min for all 5 modes) but reliable. Both CI and the local invocation use the same script — there's no second source of truth that can drift.

The smoke check itself only verifies imports and each entry point's `--help`. Functional tests (real runtime compilation, scene tests) live in `ut-py`, `ut-cpp`, `st-sim-*`, and the hardware self-hosted jobs.

Expand Down
Loading
Loading