@@ -262,8 +262,70 @@ if(WITH_ASCEND)
262262 list (APPEND DEVICE_LIST "ascend" )
263263
264264 # Custom `AscendC` kernels (PyTorch extension, requires `torch_npu`).
265- if (BUILD_CUSTOM_KERNEL)
266- add_subdirectory (native/ascend/custom )
265+ if (BUILD_ASCEND_CUSTOM)
266+ # In-tree `ascendc_library()` trips the `CANN` `extract_host_stub.py`
267+ # path-handling bug under `scikit-build-core`'s temp-dir builds
268+ # (`KeyError` on `/./workspace/...` paths in `$<TARGET_OBJECTS>`).
269+ # Work around it by driving the standalone `src/native/ascend/custom/build.sh`;
270+ # that script invokes a separate `cmake` with
271+ # `src/native/ascend/custom/` as its `SOURCE_DIR`, avoiding the buggy
272+ # path shape. The produced `.a` is imported and linked into
273+ # `ops` with `--whole-archive`.
274+ set (_custom_build_dir "${CMAKE_SOURCE_DIR} /build/build_ascend_custom" )
275+ set (_custom_lib "${_custom_build_dir} /lib/libno_workspace_kernel.a" )
276+ set (_custom_source_dir "${CMAKE_CURRENT_BINARY_DIR} /ascend_custom_source" )
277+
278+ if (NOT DEFINED SOC_VERSION OR "${SOC_VERSION} " STREQUAL "" )
279+ include (${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom/cmake/detect_soc.cmake )
280+ infiniops_detect_soc (SOC_VERSION )
281+ endif ()
282+
283+ # Drive `build.sh` as a build-phase target with explicit source
284+ # dependencies so that editing any `op_host/` or `op_kernel/`
285+ # source re-triggers the build (plain `execute_process` at
286+ # configure time would only gate on file existence and leave
287+ # stale `.a` files in place).
288+ file (GLOB_RECURSE _custom_srcs CONFIGURE_DEPENDS
289+ "${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom/*.cpp"
290+ "${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom/*.h"
291+ "${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom/build.sh" )
292+
293+ # Scrub env inherited from the outer `scikit-build-core` invocation
294+ # before handing control to `build.sh`: `CMAKE_GENERATOR` /
295+ # `CMAKE_EXPORT_COMPILE_COMMANDS` leaking into the inner `cmake`
296+ # change the path format passed to `ninja`'s `_host_cpp` rule and
297+ # re-trigger the `CANN` `extract_host_stub.py` `KeyError`
298+ # (`/./workspace/...`) that standalone `build.sh` avoids.
299+ #
300+ # `pip install` MUST be invoked with `--no-build-isolation` on
301+ # Ascend; otherwise pip's build-isolation overlay shadows system
302+ # `torch` (via `PYTHONPATH`) and the inner `cmake`'s
303+ # `import torch` in `config_envs.cmake` fails with
304+ # `ModuleNotFoundError`.
305+ add_custom_command (
306+ OUTPUT ${_custom_lib}
307+ COMMAND ${CMAKE_COMMAND} -E rm -f "${_custom_source_dir} "
308+ COMMAND ${CMAKE_COMMAND} -E create_symlink
309+ "${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom"
310+ "${_custom_source_dir} "
311+ COMMAND ${CMAKE_COMMAND} -E env
312+ --unset=CMAKE_GENERATOR
313+ --unset=CMAKE_EXPORT_COMPILE_COMMANDS
314+ --unset=CMAKE_BUILD_PARALLEL_LEVEL
315+ "BUILD_DIR=${_custom_build_dir} "
316+ "MAIN_SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} "
317+ bash ${_custom_source_dir} /build.sh ${SOC_VERSION}
318+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} /native/ascend/custom
319+ DEPENDS ${_custom_srcs}
320+ COMMENT "Building custom AscendC kernels (SOC_VERSION=${SOC_VERSION} )"
321+ VERBATIM )
322+
323+ add_custom_target (no_workspace_kernel_build ALL DEPENDS ${_custom_lib} )
324+
325+ add_library (no_workspace_kernel STATIC IMPORTED GLOBAL )
326+ set_target_properties (no_workspace_kernel PROPERTIES
327+ IMPORTED_LOCATION "${_custom_lib} " )
328+ add_dependencies (no_workspace_kernel no_workspace_kernel_build )
267329
268330 # Link the compiled `AscendC` kernel objects into `infiniops` so that
269331 # custom kernel implementations (e.g. `RmsNorm` index 1) can call
@@ -651,9 +713,17 @@ if(GENERATE_PYTHON_BINDINGS)
651713 # The `Operator<..., 1>` template instantiations that call
652714 # `aclrtlaunch_*` live in `ops.cc`, so link here with
653715 # `--whole-archive` to ensure all launch functions are available.
654- if (BUILD_CUSTOM_KERNEL)
716+ # `$<TARGET_FILE>` works for both real `ascendc_library()` targets and
717+ # `IMPORTED` targets pointing at a pre-built `.a`. The
718+ # `no_workspace_kernel` target is only created inside the
719+ # `WITH_ASCEND` block above, so this branch must mirror that gate;
720+ # otherwise non-Ascend builds error out with "No target
721+ # no_workspace_kernel".
722+ if (WITH_ASCEND AND BUILD_ASCEND_CUSTOM)
655723 target_link_libraries (ops PRIVATE
656- -Wl,--whole-archive no_workspace_kernel -Wl,--no-whole-archive )
724+ -Wl,--whole-archive $<TARGET_FILE :no_workspace_kernel > -Wl,--no-whole-archive )
725+ # `ops` link step must wait for `build.sh` to produce the `.a`.
726+ add_dependencies (ops no_workspace_kernel_build )
657727 endif ()
658728 set (_INFINIOPS_INSTALL_RPATH "$ORIGIN" )
659729 if (WITH_TORCH)
0 commit comments