Skip to content
Open
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
19 changes: 19 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,27 @@ project(tilexr LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
option(TILEXR_BUILD_COLLECTIVES "Build optional TileXR collectives library" OFF)
option(TILEXR_BUILD_EP "Build TileXR EP communication library" OFF)
option(TILEXR_EP_BUILD_URMA_COMBINE "Build the Ascend950 URMA EP combine operator" OFF)
option(TILEXR_BUILD_TESTS "Build TileXR tests" OFF)
option(TILEXR_BUILD_CHECKER "Build TileXR no-NPU checker" OFF)
set(TILEXR_UDMA_QP_COUNT "1" CACHE STRING "Base UDMA queue-pair count per EID")
set(TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT "22" CACHE STRING
"Send AIV count for the Ascend950 URMA EP combine operator")

if(NOT TILEXR_UDMA_QP_COUNT MATCHES "^[1-9][0-9]*$")
message(FATAL_ERROR "TILEXR_UDMA_QP_COUNT must be a positive integer")
endif()
if(NOT TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT MATCHES "^[1-9][0-9]*$" OR
TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT GREATER_EQUAL 64)
message(FATAL_ERROR
"TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT must be an integer in [1, 63]")
endif()

set(TILEXR_UDMA_EFFECTIVE_QP_COUNT "${TILEXR_UDMA_QP_COUNT}")
if(TILEXR_BUILD_EP AND TILEXR_EP_BUILD_URMA_COMBINE AND
TILEXR_UDMA_EFFECTIVE_QP_COUNT LESS TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT)
set(TILEXR_UDMA_EFFECTIVE_QP_COUNT "${TILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT}")
endif()
include(CTest)
if(BUILD_TESTING OR TILEXR_BUILD_TESTS)
enable_testing()
Expand Down
79 changes: 79 additions & 0 deletions docs/EP_URMA_COMBINE_S22.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# EP URMA Combine for Ascend 950

This change adds a TileXR-native Mixture-of-Experts combine operator backed by
URMA/UDMA. The production implementation is fixed to the validated S22 layout:

- 42 Pack/Receive AIVs and 22 Send AIVs;
- 22 independent UDMA queue pairs;
- one WQE per doorbell;
- QDC-v3 quant/dequant;
- round-robin receive scheduling with sticky ready state;
- parallel release publication and deferred same-parity credit checks;
- first-launch start gate after a stream synchronization;
- BiSheng `-O2`, with profiling disabled by default.

The fixed configuration avoids carrying experiment-only variant switches into
the production build. The kernel contains no experiment-selection macros or
alternate protocol branches; only the Send AIV count and the explicit
profiling build remain configurable.

## Build

Configure and build through CMake. No variant or wrapper script is required.

```bash
cmake -S . -B build-s22 \
-DTILEXR_BUILD_EP=ON \
-DTILEXR_EP_BUILD_URMA_COMBINE=ON \
-DTILEXR_EP_SOC_TYPE=ascend950 \
-DBUILD_TESTING=OFF \
-DCMAKE_INSTALL_PREFIX="$PWD/install-s22"
cmake --build build-s22 -j --target tilexr-ep
cmake --install build-s22
```

`ASCEND_HOME_PATH` and `ASCEND_DRIVER_PATH` must point to the active CANN
toolkit and driver before configuration. A profiling build is available only
when explicitly requested with `-DTILEXR_EP_ENABLE_PROFILING=ON`; it is not the
production default.

The URMA Combine target is opt-in. A Dispatch-only EP build leaves
`TILEXR_EP_BUILD_URMA_COMBINE=OFF` and uses the generic UDMA default of one QP
per EID. When URMA Combine is enabled, CMake raises the effective QP count to
the configured Send AIV count; `comm/udma` does not contain an Ascend950- or
operator-specific QP constant. The validated default is 22 Send AIVs and can
be changed with `-DTILEXR_EP_URMA_COMBINE_SEND_CORE_COUNT=<count>`.

## API

The public header `src/include/tilexr_ep.h` provides:

- `TileXRMoeEpCombineUrmaGetWorkspaceSize` for the registered workspace size;
- `TileXRMoeEpCombineUrma` for the production launch;
- `TileXRMoeEpCombineUrmaProfile` for an explicitly profiled launch.

The workspace must be aligned and registered with TileXR UDMA before launch.
The operator supports an eight-rank Ascend 950 deployment and uses the existing
TileXR communicator for rank information and registered-memory exchange.

## Performance Evidence

The production comparison metric is profiling-free `strictKernelCycles`,
aggregated as max core per rank, max rank per launch, then median across 100
launches. For BS128, H=5120, top-k=6, rank-size=8 and enqueue-window=1, S22
measured 88,343.5 cycles (88.3435 us using 1000 cycles/us). The paired baseline
was 88,602.5 cycles, a 0.29% reduction. BS32 improved from 39,753 to 38,541
cycles (3.05%).

The single retained detailed report is
[BS128 S22 profile](performance/tilexr_ep_urma_combine_s22_bs128.html). Its
charts, stage maxima, heatmaps and kernel KPIs exclude the first-launch start
gate and rebase the axis to steady-state device work. The raw embedded capture
retains the gate samples only for provenance.

This boundary explains the large host/device timing difference. The host round
starts before launch and ends after stream synchronization, so it includes the
start-gate wait, API launch/synchronization overhead and cross-rank scheduling
skew. Device `kernel_total` begins after the gate releases. The values therefore
describe different intervals and must not be subtracted to infer kernel work;
production comparisons use steady-state `strictKernelCycles`.
71 changes: 71 additions & 0 deletions docs/performance/tilexr_ep_urma_combine_s22_bs128.html

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/comm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ set(TILEXR_SOURCE_FILE tilexr_comm.cpp

add_library(tile-comm SHARED ${TILEXR_SOURCE_FILE})

target_compile_definitions(tile-comm PRIVATE
TILEXR_UDMA_QP_COUNT_VALUE=${TILEXR_UDMA_EFFECTIVE_QP_COUNT})

if(TILEXR_HAVE_PTO_SDMA)
target_compile_definitions(tile-comm PRIVATE TILEXR_HAVE_PTO_SDMA=1)
else()
Expand Down
25 changes: 19 additions & 6 deletions src/comm/udma/tilexr_udma_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
namespace TileXR {
namespace {

constexpr uint32_t TILEXR_UDMA_QP_NUM = 1;

template <typename T>
void CopyVector(std::vector<uint8_t>& dst, size_t offset, const std::vector<T>& src)
{
Expand All @@ -32,9 +30,24 @@ int BuildUDMAInfoImage(
UDMAInfo& info,
std::vector<uint8_t>& bytes)
{
const size_t rankCount = sq.size();
if (rankCount == 0 || rq.size() != rankCount || scq.size() != rankCount ||
rcq.size() != rankCount || mem.size() != rankCount) {
return BuildUDMAInfoImage(deviceBase, 1, sq, rq, scq, rcq, mem, info, bytes);
}

int BuildUDMAInfoImage(
uintptr_t deviceBase,
uint32_t qpCount,
const std::vector<UDMAWQCtx>& sq,
const std::vector<UDMAWQCtx>& rq,
const std::vector<UDMACQCtx>& scq,
const std::vector<UDMACQCtx>& rcq,
const std::vector<UDMAMemInfo>& mem,
UDMAInfo& info,
std::vector<uint8_t>& bytes)
{
const size_t queueEntryCount = sq.size();
if (qpCount == 0 || queueEntryCount == 0 || queueEntryCount % qpCount != 0 ||
rq.size() != queueEntryCount || scq.size() != queueEntryCount ||
rcq.size() != queueEntryCount || mem.size() != queueEntryCount) {
return TILEXR_UDMA_LAYOUT_INVALID;
}

Expand All @@ -46,7 +59,7 @@ int BuildUDMAInfoImage(
const size_t totalBytes = memOffset + mem.size() * sizeof(UDMAMemInfo);

info = {};
info.qpNum = TILEXR_UDMA_QP_NUM;
info.qpNum = qpCount;
info.sqPtr = deviceBase + sqOffset;
info.rqPtr = deviceBase + rqOffset;
info.scqPtr = deviceBase + scqOffset;
Expand Down
11 changes: 11 additions & 0 deletions src/comm/udma/tilexr_udma_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ int BuildUDMAInfoImage(
UDMAInfo& info,
std::vector<uint8_t>& bytes);

int BuildUDMAInfoImage(
uintptr_t deviceBase,
uint32_t qpCount,
const std::vector<UDMAWQCtx>& sq,
const std::vector<UDMAWQCtx>& rq,
const std::vector<UDMACQCtx>& scq,
const std::vector<UDMACQCtx>& rcq,
const std::vector<UDMAMemInfo>& mem,
UDMAInfo& info,
std::vector<uint8_t>& bytes);

} // namespace TileXR

#endif // TILEXR_UDMA_LAYOUT_H
Loading