#ifdef MNN_SUPPORT_TRANSFORMER_FUSE #ifndef VulkanAttention_hpp #define VulkanAttention_hpp #include "VulkanBasicExecution.hpp" #include "core/OpCommonUtils.hpp" namespace MNN { class VulkanAttention : public VulkanBasicExecution { public: VulkanAttention(const Op* op, Backend* bn); ~VulkanAttention() override; ErrorCode onEncode(const std::vector& inputs, const std::vector& outputs, const VulkanCommandPool::Buffer* cmdBuffer) override; ErrorCode onBeforeExecute(const std::vector& inputs, const std::vector& outputs) override; bool onClone(Backend* bn, const Op* op, VulkanBasicExecution** dst) override; private: struct GpuParam { ivec4 s0; // qLen, kLen, headNum, kvHeadNum ivec4 s1; // headDim, group, pastLen, totalLen ivec4 s2; // maskQlen, maskKvlen, maskMode(0:none,1:additive,2:causal), cacheMaxLen vec4 f0; // scale, 0, 0, 0 }; struct KVCache { int maxLen = 0; int kvHeadNum = 0; int headDim = 0; int expandChunk = 64; bool fp16 = false; std::shared_ptr key; std::shared_ptr value; void reset(); void ensureCapacity(VulkanBackend* vkBn, int requiredLen, int kvH, int d, bool useFP16); }; const Op* mOp = nullptr; bool mNeedKvCache = false; bool mUseFP16 = false; KVMeta* mMeta = nullptr; int mQueryLen = 0; int mKeyLen = 0; int mHeadNum = 0; int mKvHeadNum = 0; int mHeadDim = 0; std::shared_ptr mKVCache; std::shared_ptr mParam; const VulkanPipeline* mAttentionPipeline = nullptr; const VulkanPipeline* mAttentionLegacyPipeline = nullptr; const VulkanPipeline* mDecodeQ1SubgroupPipeline = nullptr; const VulkanPipeline* mDecodeQ1SubgroupHD128Pipeline = nullptr; const VulkanPipeline* mUpdatePipeline = nullptr; std::shared_ptr mAttentionSet; std::shared_ptr mAttentionLegacySet; std::shared_ptr mDecodeQ1SubgroupSet; std::shared_ptr mDecodeQ1SubgroupHD128Set; std::shared_ptr mUpdateSet; bool mUsePrefill = false; int mPrefillTotalLen = 0; // encoded totalLen for prefill multi-pass int mQueryLen4 = 0; // padded qLen for rearranged Qtmp (multiple of 4) std::shared_ptr mTempQuery; // Prefill K-block mode temporaries (avoid O(qLen*totalLen) intermediates). std::shared_ptr mTempQKBlock; std::shared_ptr mTempWBlock; std::shared_ptr mTempM; std::shared_ptr mTempL; std::shared_ptr mTempAlpha; std::shared_ptr mTempOAcc; const VulkanPipeline* mRearrangeQPipeline = nullptr; std::shared_ptr mRearrangeQSet; const VulkanPipeline* mInitStatePipeline = nullptr; const VulkanPipeline* mQKBlockFullPipeline = nullptr; const VulkanPipeline* mQKBlockPipeline = nullptr; const VulkanPipeline* mSoftmaxOnlinePipeline = nullptr; const VulkanPipeline* mQKVAccFullPipeline = nullptr; const VulkanPipeline* mQKVAccPipeline = nullptr; const VulkanPipeline* mFinalizePipeline = nullptr; std::shared_ptr mInitStateSet; std::shared_ptr mQKBlockFullSet; std::shared_ptr mQKBlockSet; std::shared_ptr mSoftmaxOnlineSet; std::shared_ptr mQKVAccFullSet; std::shared_ptr mQKVAccSet; std::shared_ptr mFinalizeSet; uint32_t mSoftmaxOnlineLocalSize = 0; uint32_t mDecodeQ1SubgroupLocalSize = 0; }; } // namespace MNN #endif // VulkanAttention_hpp #endif // MNN_SUPPORT_TRANSFORMER_FUSE