Files
enginex-ascend-910-vllm/csrc/attention/common/op_kernel/buffer.h
Sun Ruoxi 7f8a1b1f7a init v0.23.0
Signed-off-by: Sun Ruoxi <sunruoxi@4paradigm.com>
2026-08-27 15:11:51 +08:00

292 lines
12 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
 * CANN Open Software License Agreement Version 2.0 (the "License").
 * Please refer to the License for details. You may not use this file except in compliance with the License.
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
 * See LICENSE in the root of the software repository for the full text of the License.
 */
/*!
* \file buffer.h
* \brief同步管理
*/
#ifndef BUFFER_H
#define BUFFER_H
#include<type_traits>
#include"lib/matmul_intf.h"
#if ASC_DEVKIT_MAJOR >= 9
#include "kernel_basic_intf.h"
#else
#include "kernel_operator.h"
#endif
using namespace AscendC;
namespace fa_base_matmul {
__BLOCK_LOCAL__ __inline__ uint32_t idCounterNum;
#define MAKE_ID ((++idCounterNum) % 11)
// 核间同步中AIC(flagId 0-10)对应AIV0(flagId 0-10)对应AIV1(flagId 16-26)
#define AIV0_AIV1_OFFSET 16
enum class BufferType {
L1 = 0,
L0A = 1,
L0B = 2,
L0C = 3,
UB = 4,
GM = 5,
C2 = 6,
};
enum class SyncType {
NO_SYNC,
INNER_CORE_SYNC,
CROSS_CORE_SYNC_FORWARD,
CROSS_CORE_SYNC_BOTH,
CROSS_CORE_SYNC_BACKWARD,
};
constexpr uint32_t INVALID_CROSS_CORE_EVENT_ID = 16;
static constexpr uint64_t CROSS_CORE_SYNC_MODE = 4;
template<BufferType Type>
struct BufferInfo{
// Cons 消费者Prod 生产者
__aicore__ const static constexpr HardEvent ConsWaitProdStatus() {
if constexpr (Type == BufferType::L1) {
return HardEvent::MTE2_MTE1;
} else if constexpr (Type == BufferType::L0A) {
return HardEvent::MTE1_M;
} else if constexpr (Type == BufferType::L0B) {
return HardEvent::MTE1_M;
} else if constexpr (Type == BufferType::L0C) {
return HardEvent::M_FIX;
} else if constexpr (Type == BufferType::C2) {
return HardEvent::MTE1_M;
}
}
__aicore__ const static constexpr HardEvent ProdWaitConsStatus() {
if constexpr (Type == BufferType::L1) {
return HardEvent::MTE1_MTE2;
} else if constexpr (Type == BufferType::L0A) {
return HardEvent::M_MTE1;
} else if constexpr (Type == BufferType::L0B) {
return HardEvent::M_MTE1;
} else if constexpr (Type == BufferType::L0C) {
return HardEvent::FIX_M;
} else if constexpr (Type == BufferType::C2) {
return HardEvent::M_MTE1;
}
}
__aicore__ const static constexpr TPosition GetTPosition() {
if constexpr (Type == BufferType::L1) {
return TPosition::A1;
} else if constexpr (Type == BufferType::L0A) {
return TPosition::A2;
} else if constexpr (Type == BufferType::L0B) {
return TPosition::B2;
} else if constexpr (Type == BufferType::L0C) {
return TPosition::CO1;
} else if constexpr (Type == BufferType::UB) {
return TPosition::VECIN;
} else if constexpr (Type == BufferType::GM) {
return TPosition::GM;
} else if constexpr (Type == BufferType::C2) {
return TPosition::C2;
}
}
static constexpr HardEvent EventP2C = ConsWaitProdStatus(); // 生产者到消费者方向的HardEvent消费者等生产者提供/生产者通知消费者已生成
static constexpr HardEvent EventC2P = ProdWaitConsStatus(); // 消费者到生产者方向的HardEvent生产者等消费者消耗/消费者通知生产者已消耗’
static constexpr TPosition Position = GetTPosition();
};
// buffer绑定生产者、消费者关系
// L1 buffer的生产者为MTE2或者MTE3消费者为MTE1
// L0A buffer的生产者为MTE1消费者为M
// L0B buffer的生产者为MTE1消费者为M
// L0C buffer的生产者为M消费者为FIX
template<BufferType bufferType, SyncType syncType = SyncType::INNER_CORE_SYNC>
class Buffer {
using TensorType = std::conditional_t<bufferType == BufferType::GM, GlobalTensor<uint8_t>, LocalTensor<uint8_t>>;
template <typename T>
using TargetTensorType = std::conditional_t<bufferType == BufferType::GM, GlobalTensor<T>, LocalTensor<T>>;
public:
__aicore__ inline Buffer() {}
__aicore__ inline Buffer(TensorType tensor, uint32_t size) {
tensor_ = tensor;
size_ = size;
if constexpr (syncType == SyncType::CROSS_CORE_SYNC_FORWARD) {
id0_ = MAKE_ID;
id1_ = INVALID_CROSS_CORE_EVENT_ID;
} else if constexpr (syncType == SyncType::CROSS_CORE_SYNC_BACKWARD) {
id0_ = INVALID_CROSS_CORE_EVENT_ID;
id1_ = MAKE_ID;
} else if constexpr (syncType == SyncType::CROSS_CORE_SYNC_BOTH) {
id0_ = MAKE_ID;
id1_ = MAKE_ID;
} else {
id0_ = INVALID_CROSS_CORE_EVENT_ID;
id1_ = INVALID_CROSS_CORE_EVENT_ID;
}
}
__aicore__ inline void Init() {
if ASCEND_IS_AIC {
if constexpr (syncType == SyncType::INNER_CORE_SYNC) {
p2cEventId_ = GetTPipePtr()->AllocEventID<BufferInfo<bufferType>::EventP2C>(); // 确保只能被调用一次
c2pEventId_ = GetTPipePtr()->AllocEventID<BufferInfo<bufferType>::EventC2P>();
SetFlag<BufferInfo<bufferType>::EventC2P>(c2pEventId_);
}
}
}
__aicore__ inline void UnInit() {
if ASCEND_IS_AIC {
if constexpr (syncType == SyncType::INNER_CORE_SYNC) {
WaitFlag<BufferInfo<bufferType>::EventC2P>(c2pEventId_);
GetTPipePtr()->ReleaseEventID<BufferInfo<bufferType>::EventP2C>(p2cEventId_); // 确保只能被调用一次
GetTPipePtr()->ReleaseEventID<BufferInfo<bufferType>::EventC2P>(c2pEventId_);
}
}
}
template<HardEvent EventType>
__aicore__ inline void Wait() {
if ASCEND_IS_AIC {
if constexpr (syncType == SyncType::INNER_CORE_SYNC) {
if constexpr (EventType == BufferInfo<bufferType>::EventP2C) {
WaitFlag<BufferInfo<bufferType>::EventP2C>(p2cEventId_); // 消费者等待生产者完成生产
} else {
WaitFlag<BufferInfo<bufferType>::EventC2P>(c2pEventId_); // 生产者等待消费者完成消费
}
}
}
}
template<HardEvent EventType>
__aicore__ inline void Set() {
if ASCEND_IS_AIC {
if constexpr (syncType == SyncType::INNER_CORE_SYNC) {
if constexpr (EventType == BufferInfo<bufferType>::EventP2C) {
SetFlag<BufferInfo<bufferType>::EventP2C>(p2cEventId_); // 生产者通知消费者已完成生产
} else {
SetFlag<BufferInfo<bufferType>::EventC2P>(c2pEventId_); // 消费者通知生产者已完成消费
}
}
}
}
__aicore__ inline void SetEventID() {
if ASCEND_IS_AIC {
p2cEventId_ = GetTPipePtr()->AllocEventID<BufferInfo<bufferType>::EventP2C>(); // 确保只能被调用一次
c2pEventId_ = GetTPipePtr()->AllocEventID<BufferInfo<bufferType>::EventC2P>();
}
}
template<HardEvent EventType>
__aicore__ inline TEventID GetEventID() {
if ASCEND_IS_AIC {
if constexpr (EventType == BufferInfo<bufferType>::EventP2C) {
return p2cEventId_; // 生产者通知消费者已完成生产
} else {
return c2pEventId_; // 消费者通知生产者已完成消费
}
}
}
template<bool isReuse = false>
__aicore__ inline void WaitCrossCore() {
if constexpr (bufferType == BufferType::GM && syncType == SyncType::CROSS_CORE_SYNC_BACKWARD) {
// AIC属于消费者AIV属于生产者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE2>(id1_);
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE2>(id1_ + AIV0_AIV1_OFFSET);
} else {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE2>(id0_);
}
} else if constexpr (bufferType == BufferType::UB || bufferType == BufferType::GM) {
// AIC属于生产者AIV属于消费者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id1_);
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id1_ + AIV0_AIV1_OFFSET);
} else {
if constexpr (isReuse) {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE3>(id0_);
} else {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_V>(id0_);
}
}
} else if constexpr (bufferType == BufferType::L1) {
// AIC属于消费者AIV属于生产者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE1>(id0_);
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE1>(id0_ + AIV0_AIV1_OFFSET);
} else {
if constexpr (syncType == SyncType::CROSS_CORE_SYNC_BOTH) {
CrossCoreWaitFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE3>(id1_);
}
}
}
}
template<bool isReuse = false>
__aicore__ inline void SetCrossCore() {
if constexpr (bufferType == BufferType::GM && syncType == SyncType::CROSS_CORE_SYNC_BACKWARD) {
// AIC属于消费者AIV属于生产者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id0_);
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id0_ + AIV0_AIV1_OFFSET);
} else {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE3>(id1_);
}
} else if constexpr (bufferType == BufferType::UB || bufferType == BufferType::GM) {
// AIC属于生产者AIV属于消费者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id0_);
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_FIX>(id0_ + AIV0_AIV1_OFFSET);
} else {
if constexpr (isReuse) {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE3>(id1_);
} else {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_V>(id1_);
}
}
} else if constexpr (bufferType == BufferType::L1) {
// AIC属于消费者AIV属于生产者且一个AIC对应两个AIV
if ASCEND_IS_AIC {
if constexpr (syncType == SyncType::CROSS_CORE_SYNC_BOTH) {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE1>(id1_);
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE1>(id1_ + AIV0_AIV1_OFFSET);
}
} else {
CrossCoreSetFlag<CROSS_CORE_SYNC_MODE, PIPE_MTE3>(id0_);
}
}
}
template<typename T>
__aicore__ inline TargetTensorType<T> GetTensor() {
return tensor_.template ReinterpretCast<T>();
}
template<typename T>
__aicore__ inline TargetTensorType<T> GetTensor(uint64_t startindex) {
TargetTensorType<T> tmpTensor = tensor_.template ReinterpretCast<T>();
return tmpTensor[startindex];
}
private:
TensorType tensor_;
uint32_t size_;
TEventID p2cEventId_;
TEventID c2pEventId_;
uint32_t id0_; // 用作正向同步:生产者通知消费者,或者消费者等待生产者;
uint32_t id1_; // 用作反向同步:消费者通知生产者,或者生产者等待消费者;
};
}
#endif