Skip to content

Commit f15a41a

Browse files
authored
Fix CI breaks from the off-graph KV stack (ROCm build, muse-glimmer offgraph e2e) (pytorch#23304)
Fixes CI breaks introduced by the off-graph KV stack (pytorch#23292–pytorch#23297). ### 1. ROCm build (`unittest-rocm-gfx950-rocm7.2`, `test-voxtral-realtime-rocm-gfx950-rocm7.2`) pytorch#23293 added `backends/cuda/runtime/cuda_kv_cache.h`, which includes `<cuda_runtime.h>` directly. The ROCm build compiles `aoti_cuda_backend` with `EXECUTORCH_USE_HIP` and no CUDA toolkit: ``` backends/cuda/runtime/cuda_kv_cache.h:14:10: fatal error: cuda_runtime.h: No such file or directory ``` - Include `executorch/extension/cuda/runtime_api.h` (the CUDA/HIP shim used by the rest of the runtime) instead. - Add HIP shims for the event APIs the KV cache uses: `cudaEvent_t`, `cudaEventCreateWithFlags`, `cudaEventDisableTiming`, `cudaEventDestroy`, `cudaEventRecord`, `cudaStreamWaitEvent`. ### 2. `test-muse-glimmer-cuda-e2e-kquant-17gb-solo-text-offgraph` pytorch#23296 added this job and the `solo-text-offgraph` export branch, but the early mode validation in `.ci/scripts/export_model_artifact.sh` still only allowed `solo-text`/`dflash-image`: ``` Error: Muse Glimmer requires mode 'solo-text' or 'dflash-image' ``` Allow `solo-text-offgraph` there. ### 3. Off-graph export fails in AOTI lowering Once past the mode check, the same job fails in export: ``` InductorError: RuntimeError: When autotune_at_compile_time is False, AOTInductor generates both JIT code and AOT code. The JIT code failed to run. ``` pytorch#23295 forced `autotune_at_compile_time=OFF` for the off-graph export. With it off, AOTI tunes by running a JIT build of the wrapper on the real constants. `LowerOffGraphKVPass` declares the KV storage constants with zero-byte storage, because the runtime supplies the storage, so nothing can run on them. The CUDA unit test only works because it swaps them for real zero tensors first. This drops the override so AOTI keeps its default compile-time autotune on generated inputs, which is the mode the pass's `kv_len` derivation is written for. Test plan: ROCm + CUDA CI on this PR.
1 parent 8a03574 commit f15a41a

5 files changed

Lines changed: 28 additions & 5 deletions

File tree

‎.ci/scripts/export_model_artifact.sh‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ if [ "$MODEL_NAME" = "muse_glimmer" ]; then
289289
echo "Error: Muse Glimmer requires quantization 'kquant-17gb' or 'kquant-dynamic'"
290290
exit 1
291291
fi
292-
if [ "$MODE" != "solo-text" ] && [ "$MODE" != "dflash-image" ]; then
293-
echo "Error: Muse Glimmer requires mode 'solo-text' or 'dflash-image'"
292+
if [ "$MODE" != "solo-text" ] && [ "$MODE" != "solo-text-offgraph" ] && [ "$MODE" != "dflash-image" ]; then
293+
echo "Error: Muse Glimmer requires mode 'solo-text', 'solo-text-offgraph' or 'dflash-image'"
294294
exit 1
295295
fi
296296
fi

‎backends/cuda/passes/lower_offgraph_kv.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ def __init__(self, manifest: dict[str, Any]) -> None:
308308
def _compile_storage(shape, dtype: torch.dtype, device):
309309
storage = torch.empty(shape, dtype=dtype, device=device)
310310
# AOTI needs the logical metadata, while the runtime supplies storage.
311+
# Nothing can run on it, so lowering must keep AOTI's compile-time
312+
# autotune (generated inputs) rather than the JIT pass on real constants.
311313
storage.untyped_storage().resize_(0)
312314
return storage
313315

‎backends/cuda/runtime/cuda_kv_cache.h‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@
1313
#include <optional>
1414
#include <string_view>
1515

16-
#include <cuda_runtime.h>
17-
1816
#include <executorch/backends/cuda/runtime/backend_options.h>
1917
#include <executorch/backends/cuda/runtime/cuda_delegate_handle.h>
18+
#include <executorch/extension/cuda/runtime_api.h>
2019
#include <executorch/extension/llm/cache/cache.h>
2120
#include <executorch/runtime/core/error.h>
2221
#include <executorch/runtime/core/evalue.h>

‎examples/models/muse-glimmer/export/export_solo.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,6 @@ def _partitioner_for(name: str) -> "CudaPartitioner":
316316
# the runtime cannot recover the width from the graph; every
317317
# method here takes input_pos second, shaped [T].
318318
CompileSpec(OFFGRAPH_KV_STEP_WIDTH_COMPILE_SPEC, b"1:0"),
319-
CompileSpec("autotune_at_compile_time", b"OFF"),
320319
)
321320
)
322321
return CudaPartitioner(compile_specs)

‎extension/cuda/runtime_api.h‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <hip/hip_runtime.h>
1616

1717
using cudaError_t = hipError_t;
18+
using cudaEvent_t = hipEvent_t;
1819
using cudaGraph_t = hipGraph_t;
1920
using cudaGraphExec_t = hipGraphExec_t;
2021
using cudaMemcpyKind = hipMemcpyKind;
@@ -23,6 +24,7 @@ using cudaStreamCaptureMode = hipStreamCaptureMode;
2324
using cudaStream_t = hipStream_t;
2425

2526
inline constexpr cudaError_t cudaSuccess = hipSuccess;
27+
inline constexpr unsigned int cudaEventDisableTiming = hipEventDisableTiming;
2628
inline constexpr cudaMemcpyKind cudaMemcpyDeviceToDevice =
2729
hipMemcpyDeviceToDevice;
2830
inline constexpr cudaMemcpyKind cudaMemcpyDeviceToHost = hipMemcpyDeviceToHost;
@@ -50,6 +52,20 @@ inline cudaError_t cudaDeviceSynchronize() {
5052
return hipDeviceSynchronize();
5153
}
5254

55+
inline cudaError_t cudaEventCreateWithFlags(
56+
cudaEvent_t* event,
57+
unsigned int flags) {
58+
return hipEventCreateWithFlags(event, flags);
59+
}
60+
61+
inline cudaError_t cudaEventDestroy(cudaEvent_t event) {
62+
return hipEventDestroy(event);
63+
}
64+
65+
inline cudaError_t cudaEventRecord(cudaEvent_t event, cudaStream_t stream) {
66+
return hipEventRecord(event, stream);
67+
}
68+
5369
inline cudaError_t cudaFree(void* ptr) {
5470
return hipFree(ptr);
5571
}
@@ -167,6 +183,13 @@ inline cudaError_t cudaStreamSynchronize(cudaStream_t stream) {
167183
return hipStreamSynchronize(stream);
168184
}
169185

186+
inline cudaError_t cudaStreamWaitEvent(
187+
cudaStream_t stream,
188+
cudaEvent_t event,
189+
unsigned int flags) {
190+
return hipStreamWaitEvent(stream, event, flags);
191+
}
192+
170193
#else
171194

172195
#include <cuda_runtime.h>

0 commit comments

Comments
 (0)