// // LinearAttentionBufExecution.hpp // MNN // // Created by MNN on 2026/02/12. // Copyright © 2018, Alibaba Group Holding Limited // #ifdef MNN_SUPPORT_TRANSFORMER_FUSE #ifndef LinearAttentionBufExecution_hpp #define LinearAttentionBufExecution_hpp #include "backend/opencl/execution/image/CommonExecution.hpp" #include "core/OpCommonUtils.hpp" #include "core/KVMeta.hpp" namespace MNN { namespace OpenCL { struct OpenCLStateCache { std::shared_ptr mConvState; // Conv1D padding state: [B, D, kernel_size - 1] std::shared_ptr mRecurrentState; // Gated Delta Rule recurrent state S: [B, H, d_k, d_v] std::shared_ptr mRecurrentStateTune; // Gated Delta Rule recurrent state S: [B, H, d_k, d_v] }; class LinearAttentionBufExecution : public CommonExecution { public: LinearAttentionBufExecution(const MNN::Op *op, Backend *backend); virtual ~LinearAttentionBufExecution() = default; virtual ErrorCode onResize(const std::vector &inputs, const std::vector &outputs) override; virtual ErrorCode onExecute(const std::vector &inputs, const std::vector &outputs) override; virtual bool onClone(Backend* bn, const Op* op, Execution** dst) override; // Chunked prefill: fully independent branch (called from onResize/onExecute when seqLen > 1) ErrorCode onResizeChunkedPrefill(const std::vector &inputs, const std::vector &outputs); ErrorCode onExecuteChunkedPrefill(const std::vector &inputs, const std::vector &outputs); private: std::string mAttentionType; int mNumKHeads; int mNumVHeads; int mHeadKDim; int mHeadVDim; bool mUseQKL2Norm; OpenCLBackend *mOpenCLBackend; // Persistent state buffers shared between prefill and decode via onClone std::shared_ptr mStateCache; KVMeta* mMeta = nullptr; // Temporary conv output: [B * D * L] std::shared_ptr mConvOut; // Kernels std::shared_ptr mKernelConvSilu; std::shared_ptr mKernelConvStateUpdate; std::shared_ptr mKernell2Norm; std::shared_ptr mKernelGatedDeltaRule; // Work sizes std::vector mGWSConvSilu; std::vector mLWSConvSilu; std::vector mGWSConvStateUpdate; std::vector mLWSConvStateUpdate; std::vector mGWSl2Norm; std::vector mLWSl2Norm; std::vector mGWSGatedDeltaRule; std::vector mLWSGatedDeltaRule; // ─── Chunked prefill ─── bool mUseChunkedPrefill = false; int mChunkSize = 16; int mNumChunks = 0; // Chunked prefill common kernels (independent copies) std::shared_ptr mConvOutPrefill; std::shared_ptr mKernelConvSiluPrefill; std::shared_ptr mKernelConvStateUpdatePrefill; std::shared_ptr mKernell2NormPrefill; std::vector mGWSConvSiluPrefill, mLWSConvSiluPrefill; std::vector mGWSConvStateUpdatePrefill, mLWSConvStateUpdatePrefill; std::vector mGWSl2NormPrefill, mLWSl2NormPrefill; // Chunked prefill kernels std::shared_ptr mKernelChunkGCumsum; std::shared_ptr mKernelChunkNeumannAttn0; std::shared_ptr mKernelChunkNeumannAttn1; std::shared_ptr mKernelChunkCorrectV; std::shared_ptr mKernelChunkQKAttn; std::shared_ptr mKernelChunkVnew; std::shared_ptr mKernelChunkOutput; std::shared_ptr mKernelChunkOutputUpdate; // Chunked prefill work sizes std::vector mGWSChunkGCumsum, mLWSChunkGCumsum; std::vector mGWSChunkNeumannAttn0, mLWSChunkNeumannAttn0; std::vector mGWSChunkNeumannAttn1, mLWSChunkNeumannAttn1; std::vector mGWSChunkCorrectV, mLWSChunkCorrectV; std::vector mGWSChunkQKAttn, mLWSChunkQKAttn; std::vector mGWSChunkVnew, mLWSChunkVnew; std::vector mGWSChunkOutput, mLWSChunkOutput; std::vector mGWSChunkOutputUpdate, mLWSChunkOutputUpdate; // Chunked prefill intermediate buffers (float32) std::shared_ptr mGCumsumBuf; std::shared_ptr mAttnMatrixBuf; // shared for Neumann attn and QK attn std::shared_ptr mVCorrectedBuf; std::shared_ptr mKCumdecayBuf; std::shared_ptr mVNewBuf; // single chunk only }; } // namespace OpenCL } // namespace MNN #endif /* LinearAttentionBufExecution_hpp */ #endif /* MNN_SUPPORT_TRANSFORMER_FUSE */