已合并
fix: build.sh 无参数默认打包,修复 compile_acc 裸调用失败 #28
fix: build.sh 无参数默认打包,修复 compile_acc 裸调用失败 #28
已合并
newbgirl创建于 9月21日
共 6 个文件变更+77-25
@@ -47,8 +47,12 @@ output/
47在本目录执行:47在本目录执行:
48 48 
49```bash49```bash
50-# 编译并打包 OPP .run(默认 SOC=Ascend910B1,默认全部算子)50+# 编译 OPP .run 与 Python whl,不安装(无参数默认)
51# → <repo>/output/Ascend910B1/oil_gas_ops_prospect_opp_<os>_<arch>.run51# → <repo>/output/Ascend910B1/oil_gas_ops_prospect_opp_<os>_<arch>.run
52+# <repo>/output/wheels/oil_gas_ops_prospect-*.whl
53+bash build.sh
54+ 
55+# 只编译并打包 OPP .run(默认 SOC=Ascend910B1,默认全部算子)
52bash build.sh --pkg56bash build.sh --pkg
53 57 
54# 运行 ophost 侧单元测试(googletest)58# 运行 ophost 侧单元测试(googletest)
@@ -25,6 +25,8 @@
25set -euo pipefail25set -euo pipefail
26 26 
27SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"27SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
28+REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
29+OUTPUT_DIR="${REPO_ROOT}/output"
28BUILD_PY="${SCRIPT_DIR}/build.py"30BUILD_PY="${SCRIPT_DIR}/build.py"
29DEFAULT_SOC="Ascend910B1"31DEFAULT_SOC="Ascend910B1"
30 32 
@@ -36,7 +38,8 @@ FORWARD_ARGS=()
36usage() {38usage() {
37 cat <<'EOF'39 cat <<'EOF'
38Usage:40Usage:
39- bash build.sh --pkg [options] Build and package OPP .run41+ bash build.sh Build OPP .run and Python whl, no install (default)
42+ bash build.sh --pkg [options] Build and package OPP .run only
40 bash build.sh -u --ophost [options] Build and run ophost unit tests43 bash build.sh -u --ophost [options] Build and run ophost unit tests
41 bash build.sh clean Clean ascendc/_work/ and <repo>/output/44 bash build.sh clean Clean ascendc/_work/ and <repo>/output/
42 bash build.sh list-ops List operators in manifest45 bash build.sh list-ops List operators in manifest
@@ -97,7 +100,20 @@ run_pkg() {
97 args+=("${FORWARD_ARGS[@]}")100 args+=("${FORWARD_ARGS[@]}")
98 fi101 fi
99 echo "[build.sh] packaging via: python3 build.py ${args[*]}"102 echo "[build.sh] packaging via: python3 build.py ${args[*]}"
100- exec python3 "${BUILD_PY}" "${args[@]}"103+ python3 "${BUILD_PY}" "${args[@]}"
104+}
105+ 
106+build_wheel() {
107+ # 与根目录 build.sh 的 build_python_wheel 一致:whl 落 <repo>/output/wheels/
108+ local repo_root wheel_dir
109+ repo_root="$(cd "${SCRIPT_DIR}/.." && pwd)"
110+ wheel_dir="${repo_root}/output/wheels"
111+ echo "[build.sh] building wheel via: python3 setup.py bdist_wheel --dist-dir ${wheel_dir}"
112+ (
113+ cd "${repo_root}"
114+ python3 setup.py bdist_wheel --dist-dir "${wheel_dir}"
115+ rm -rf build ./*.egg-info
116+ )
101}117}
102 118 
103run_ut() {119run_ut() {
@@ -127,12 +143,9 @@ case "${MODE}" in
127 run_ut143 run_ut
128 ;;144 ;;
129 "")145 "")
130- # Legacy: bash build.sh -v Ascend910B1 --ops ...146+ # 无参数 = 编译 .run 与 whl,不安装
131- if [[ "${HAS_SOC}" -eq 1 || ${#FORWARD_ARGS[@]} -gt 0 ]]; then147+ run_pkg
132- run_pkg148+ build_wheel
133- fi
134- usage >&2
135- exit 2
136 ;;149 ;;
137 *)150 *)
138 echo "未知模式: ${MODE}" >&2151 echo "未知模式: ${MODE}" >&2
@@ -24,8 +24,12 @@
24 - 仓库根 `setup.py`:把扩展打进 `oil_gas_ops_prospect` whl;24 - 仓库根 `setup.py`:把扩展打进 `oil_gas_ops_prospect` whl;
25 - `ascendc/pybind_setup.py`:就地编译,供 NPU 测试直接 import。25 - `ascendc/pybind_setup.py`:就地编译,供 NPU 测试直接 import。
26 26 
27-前置条件:OPP 包已安装到 CANN(`opp/vendors/customize/op_api/lib/libcust_opapi.so`27+aclnn 头与 ``libcust_opapi.so`` 的取用顺序(见 ``_vendor_opapi``):
28-存在),因为扩展直接链接 msopgen 生成的 aclnn 接口。28+ 
29+1. msopgen 构建工作区产物(``ascendc/_work/CustomOp_*/build_out/``)——
30+ 构建流程内无需安装 OPP 即可编扩展,且与刚构建的 `.run` 严格同源;
31+2. 已安装的 CANN vendor 目录(``opp/vendors/customize/op_api/``,两种
32+ 历史布局)—— 适合 `pybind_setup.py` 就地编译等仅有安装件的环境。
29"""33"""
30# pyright: reportMissingImports=false34# pyright: reportMissingImports=false
31 35 
@@ -56,16 +60,27 @@ def _torch_npu_include_root() -> Path:
56 return Path(torch.__file__).parent / ".." / "torch_npu"60 return Path(torch.__file__).parent / ".." / "torch_npu"
57 61 
58 62 
59-def _vendor_opapi() -> Path:63+def _vendor_opapi() -> tuple[Path, Path]:
60- """自定义算子包的 vendor 目录(不同 CANN 版本布局略有差异)。"""64+ """返回 (aclnn 头目录, libcust_opapi 库目录)。
65+ 
66+ 优先 msopgen 构建工作区(``_work`` 会随 ``build.sh clean`` 清理,
67+ 每次打包重新生成,与刚构建的 `.run` 同源);回退已安装 vendor 目录
68+ (不同 CANN 版本布局略有差异);均不存在时返回安装布局的默认路径,
69+ 让编译以缺头文件的明确报错终止。
70+ """
71+ for custom_op in sorted((ASCENDC_DIR / "_work").glob("CustomOp_*")):
72+ build_out = custom_op / "build_out"
73+ headers, libdir = build_out / "autogen", build_out / "op_host"
74+ if (libdir / "libcust_opapi.so").is_file() and any(headers.glob("aclnn_*.h")):
75+ return headers, libdir
61 candidates = [76 candidates = [
62 Path(ASCEND_DIR) / "opp" / "vendors" / "customize" / "op_api",77 Path(ASCEND_DIR) / "opp" / "vendors" / "customize" / "op_api",
63 Path(ASCEND_DIR) / "vendors" / "customize" / "op_api",78 Path(ASCEND_DIR) / "vendors" / "customize" / "op_api",
64 ]79 ]
65- return next(80+ for p in candidates:
66- (p for p in candidates if (p / "lib" / "libcust_opapi.so").is_file()),81+ if (p / "lib" / "libcust_opapi.so").is_file():
67- candidates[0],82+ return p / "include", p / "lib"
68- )83+ return candidates[0] / "include", candidates[0] / "lib"
69 84 
70 85 
71def discover() -> list[Path]:86def discover() -> list[Path]:
@@ -90,7 +105,7 @@ def build_extensions(relative_to: Path | None = None) -> list[CppExtension]:
90 105 
91 base = Path(relative_to).resolve() if relative_to is not None else PYBIND_DIR106 base = Path(relative_to).resolve() if relative_to is not None else PYBIND_DIR
92 torch_npu_root = _torch_npu_include_root()107 torch_npu_root = _torch_npu_include_root()
93- vendor_opapi = _vendor_opapi()108+ opapi_include, opapi_lib = _vendor_opapi()
94 109 
95 include_dirs = [110 include_dirs = [
96 str(CSRC_DIR / "_common"),111 str(CSRC_DIR / "_common"),
@@ -98,11 +113,11 @@ def build_extensions(relative_to: Path | None = None) -> list[CppExtension]:
98 str(torch_npu_root / "include" / "third_party" / "acl" / "inc"),113 str(torch_npu_root / "include" / "third_party" / "acl" / "inc"),
99 str(torch_npu_root / "include" / "third_party" / "op-plugin"),114 str(torch_npu_root / "include" / "third_party" / "op-plugin"),
100 f"{ASCEND_DIR}/include",115 f"{ASCEND_DIR}/include",
101- str(vendor_opapi / "include"),116+ str(opapi_include),
102 ]117 ]
103 library_dirs = [118 library_dirs = [
104 f"{ASCEND_DIR}/lib64",119 f"{ASCEND_DIR}/lib64",
105- str(vendor_opapi / "lib"),120+ str(opapi_lib),
106 str(torch_npu_root / "lib"),121 str(torch_npu_root / "lib"),
107 ]122 ]
108 libraries = ["cust_opapi", "ascendcl", "nnopbase", "opapi", "torch_npu"]123 libraries = ["cust_opapi", "ascendcl", "nnopbase", "opapi", "torch_npu"]
@@ -1,14 +1,16 @@
1[build-system]1[build-system]
2-# setuptools>=77 for the PEP 639 SPDX ``license`` / ``license-files`` keys.2+# ``project.license`` 采用 PEP 621 表格形式(非 PEP 639 SPDX 字符串):
3-requires = ["setuptools>=77", "wheel"]3+# CI 编译镜像为 python 3.10 + 旧版 setuptools(<77),SPDX 字符串形式会
4+# 校验失败;表格形式新旧 setuptools 均可构建(新版仅弃用告警)。
5+# LICENSE 文件由 setuptools 自动识别并随 whl 分发,无需 license-files。
6+requires = ["setuptools>=61", "wheel"]
4build-backend = "setuptools.build_meta"7build-backend = "setuptools.build_meta"
5 8 
6[project]9[project]
7name = "oil-gas-ops-prospect"10name = "oil-gas-ops-prospect"
8version = "0.1.0"11version = "0.1.0"
9description = "AscendC and Triton-Ascend custom operators for oil & gas exploration"12description = "AscendC and Triton-Ascend custom operators for oil & gas exploration"
10-license = "Apache-2.0"13+license = {text = "Apache-2.0"}
11-license-files = ["LICENSE"]
12requires-python = ">=3.10"14requires-python = ">=3.10"
13dependencies = [15dependencies = [
14 "torch",16 "torch",
@@ -107,7 +107,23 @@ def _composite_mapping(composite_root: Path) -> dict[str, Path]:
107 107 
108 108 
109def activate(repo_root: Path | None = None) -> bool:109def activate(repo_root: Path | None = None) -> bool:
110- """把源码树挂到 ``oil_gas_ops_prospect`` 导入名下。已激活则直接返回 True。"""110+ """把源码树挂到 ``oil_gas_ops_prospect`` 导入名下。已激活则直接返回 True。
111+ 
112+ 同时处理 torch 的设备后端自动加载(``TORCH_DEVICE_BACKEND_AUTOLOAD``):
113+ LLT 等无卡镜像可能装有 torch_npu 但缺 CANN 运行环境,torch 2.7+ 默认开启的
114+ 自动加载会在 ``import torch`` / 访问 ``torch.npu`` 时抛
115+ ``RuntimeError: Failed to load the backend extension: torch_npu``。因此先
116+ 关闭自动加载(显式置 ``1`` 可覆盖,setdefault 语义),再**显式尽早**导入
117+ torch_npu:NPU 环境下 autograd 引擎按首次执行时已注册的设备初始化 ready
118+ queues,torch_npu 晚于首次 autograd 注册会触发 ``device_ready_queues_``
119+ 内部断言;导入失败(无卡 / 缺 CANN)则静默跳过,CPU 用例照常运行。
120+ whl 验证路径同样受益。
121+ """
122+ os.environ.setdefault("TORCH_DEVICE_BACKEND_AUTOLOAD", "0")
123+ try:
124+ import torch_npu # noqa: F401 尽早注册 NPU 设备(见上)
125+ except Exception:
126+ pass
111 if os.environ.get("OIL_GAS_OPS_WHL_TEST") == "1":127 if os.environ.get("OIL_GAS_OPS_WHL_TEST") == "1":
112 return False128 return False
113 129 
@@ -65,6 +65,8 @@ for _p in (TRITON_ROOT / "real_fft",):
65DEFAULT_ARCH = "Ascend910B1"65DEFAULT_ARCH = "Ascend910B1"
66os.environ.setdefault("TRITON_ASCEND_ARCH", DEFAULT_ARCH)66os.environ.setdefault("TRITON_ASCEND_ARCH", DEFAULT_ARCH)
67os.environ.setdefault("TRITON_CACHE_DIR", "/tmp/triton_cache_aot")67os.environ.setdefault("TRITON_CACHE_DIR", "/tmp/triton_cache_aot")
68+# 无卡镜像可能装有 torch_npu 但缺 CANN 运行环境,torch 后端自动加载会抛错
69+os.environ.setdefault("TORCH_DEVICE_BACKEND_AUTOLOAD", "0")
68ARCH = os.environ["TRITON_ASCEND_ARCH"]70ARCH = os.environ["TRITON_ASCEND_ARCH"]
69 71 
70 72