Summary
Use dnnl::lstm_forward primitive on XPU for LSTM inference, replacing the per-timestep fused cell approach. The oneDNN primitive processes the entire sequence internally, eliminating O(T) kernel launches.
Changes
- New file
aten/src/ATen/native/mkldnn/xpu/RNN.cpp: Implementslstm_onednn_xpuusingdnnl::lstm_forward, registered viaREGISTER_XPU_DISPATCH(lstm_mkldnn_stub, ...). Handles weight layout transformation (PyTorch[4*H, I]→ oneDNNldgoi), weight reorder, and scratchpad management. aten/src/ATen/native/RNN.cpp:
- Extended
use_mkldnn()to return true for XPU in inference mode (float/bf16/fp16) - Added packed sequence unwrap: when
batch_sizesare uniform (common in batch=1 inference), reshape to regular 3D tensor and route to oneDNN - Added XPU-specific
LSTMCellpath with pre-computed input gates as fallback for training
- Extended
Correctness
- oneDNN and PyTorch use identical gate order:
i, f, c̃, o - oneDNN formula:
gates = W·x + U·h + BwhereB = b_ih + b_hh(we sum before passing) - Verified max diff < 1e-6 vs CPU reference across multiple configurations
Performance (Intel PVC, Kokoro TTS, bidirectional LSTM, hidden=256)
| Path | LSTM latency | E2E Kokoro |
|---|---|---|
| Original (per-step mm + fused cell) | ~34 ms | 1.06s |
| oneDNN LSTM primitive | ~5 ms | 0.635s (-40%) |
Dependencies
- Depends on intel/torch-xpu-ops#3770 for the fused cell fallback path (bias fix)
- Only affects XPU. CUDA and CPU paths unchanged.
Pull Request resolved: #185531
Approved by: https://github.com/EikanWang, https://github.com/guangyey, https://github.com/atalman