* Copyright (c) Huawei Technologies Co., Ltd. 2026-2026. All rights reserved.
* MindIE is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* 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 FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
* \file offset_calculator_v2.h
* \brief
*/
#ifndef OFFSET_CALCULATOR_V2_H
#define OFFSET_CALCULATOR_V2_H
#include "gm_layout.h"
#include "parser.h"
using AscendC::GlobalTensor;
enum class FormatCategory {
GM_Q_OUT_BNGSD = 0,
GM_Q_OUT_TND = 1,
GM_KV_BNSD = 2,
GM_KV_TND = 3,
GM_KV_PA_BNBD = 4,
GM_KV_PA_NZ = 5,
GM_POST_QUANT_NGD = 6,
GM_ANTIQ_ND = 7,
GM_ANTIQ_BS = 8,
GM_ANTIQ_BNS = 9,
GM_ANTIQ_BnBs = 10,
GM_ANTIQ_BnNBs = 11,
GM_PSE_BN2GS1S2 = 12,
GM_V_SCALE_TND = 13,
GM_K_SCALE_PA_NZ = 14,
};
template <GmFormat FORMAT> struct GmLayoutParams {};
template <> struct GmLayoutParams<GmFormat::BSNGD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_BNGSD;
};
template <> struct GmLayoutParams<GmFormat::BNGSD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_BNGSD;
};
template <> struct GmLayoutParams<GmFormat::NGBSD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_BNGSD;
};
template <> struct GmLayoutParams<GmFormat::TNGD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_TND;
};
template <> struct GmLayoutParams<GmFormat::NGTD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_TND;
};
template <> struct GmLayoutParams<GmFormat::NTGD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_TND;
};
template <> struct GmLayoutParams<GmFormat::BSND> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_BNSD;
};
template <> struct GmLayoutParams<GmFormat::BNSD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_BNSD;
};
template <> struct GmLayoutParams<GmFormat::TND> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_TND;
};
template <> struct GmLayoutParams<GmFormat::NTD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_TND;
};
template <> struct GmLayoutParams<GmFormat::TND2> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_V_SCALE_TND;
};
template <> struct GmLayoutParams<GmFormat::PA_BnBsND> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_PA_BNBD;
};
template <> struct GmLayoutParams<GmFormat::PA_BnNBsD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_PA_BNBD;
};
template <> struct GmLayoutParams<GmFormat::PA_NZ> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_PA_NZ;
};
template <> struct GmLayoutParams<GmFormat::PA_NZ_K_SCALE> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_K_SCALE_PA_NZ;
};
template <> struct GmLayoutParams<GmFormat::SBNGD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_Q_OUT_BNGSD;
};
template <> struct GmLayoutParams<GmFormat::SBND> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_KV_BNSD;
};
template <> struct GmLayoutParams<GmFormat::NGD> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_POST_QUANT_NGD;
};
template <> struct GmLayoutParams<GmFormat::ND> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_ANTIQ_ND;
};
template <> struct GmLayoutParams<GmFormat::BS2> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_ANTIQ_BS;
};
template <> struct GmLayoutParams<GmFormat::BNS2> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_ANTIQ_BNS;
};
template <> struct GmLayoutParams<GmFormat::PA_BnBs> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_ANTIQ_BnBs;
};
template <> struct GmLayoutParams<GmFormat::PA_BnNBs> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_ANTIQ_BnNBs;
};
template <> struct GmLayoutParams<GmFormat::BN2GS1S2> {
static constexpr FormatCategory CATEGORY = FormatCategory::GM_PSE_BN2GS1S2;
};
template <GmFormat FORMAT, FormatCategory CATEGORY, typename ACTLEN_T, bool WITH_ZERO_HEAD = false>
struct OffsetCalculatorImpl {};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_Q_OUT_BNGSD, ACTLEN_T, false> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> actualSeqLensQParser;
bool isQPaddingFlag = false;
uint64_t qPaddingSize = 0;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t g, uint32_t s1, uint32_t d) {
gmLayout.MakeLayout(b, n2, g, s1, d);
}
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t g, uint32_t s1, uint32_t d,
GlobalTensor<ACTLEN_T> actualSeqLengthsGmQ, uint32_t actualLenQDims, bool isQPaddingFlag = false,
uint64_t qPaddingSize = 0) {
this->isQPaddingFlag = isQPaddingFlag;
this->qPaddingSize = qPaddingSize;
if (actualLenQDims != 0) {
actualSeqLensQParser.Init(actualSeqLengthsGmQ, actualLenQDims, 0);
}
gmLayout.MakeLayout(b, n2, g, s1, d);
}
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t g, uint32_t s1, uint32_t d,
const ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> &actualSeqLensQParser) {
this->actualSeqLensQParser = actualSeqLensQParser;
gmLayout.MakeLayout(b, n2, g, s1, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t gIdx, uint32_t s1Idx, uint32_t dIdx) {
if (isQPaddingFlag) {
s1Idx += GetDimS1() - qPaddingSize - actualSeqLensQParser.GetActualSeqLength(bIdx);
}
uint64_t offset = bIdx * GetStrideB() + n2Idx * GetStrideN2() + gIdx * GetStrideG() + s1Idx * GetStrideS1() +
dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideB() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideG() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS1() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<4>(gmLayout.stride);
}
__aicore__ inline uint64_t GetDimB() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimG() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint64_t GetDimS1() {
return AscendC::Std::get<3>(gmLayout.shape);
}
__aicore__ inline uint64_t GetDimD() {
return AscendC::Std::get<4>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T, bool WITH_ZERO_HEAD>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_Q_OUT_TND, ACTLEN_T, WITH_ZERO_HEAD> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> actualSeqLensQParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(
uint32_t n2, uint32_t g, uint32_t d, GlobalTensor<ACTLEN_T> actualSeqLengthsGmQ, uint32_t actualLenQDims) {
actualSeqLensQParser.Init(actualSeqLengthsGmQ, actualLenQDims);
gmLayout.MakeLayout(actualSeqLensQParser.GetTSize(), n2, g, d);
}
__aicore__ inline void Init(uint32_t n2, uint32_t g, uint32_t d,
const ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> &actualSeqLensQParser) {
this->actualSeqLensQParser = actualSeqLensQParser;
gmLayout.MakeLayout(actualSeqLensQParser.GetTSize(), n2, g, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t gIdx, uint32_t s1Idx, uint32_t dIdx) {
uint64_t tIdx = actualSeqLensQParser.GetTBase(bIdx) + s1Idx;
uint64_t offset = tIdx * GetStrideT() + n2Idx * GetStrideN2() + gIdx * GetStrideG() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideT() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideG() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS1() { return GetStrideT(); }
__aicore__ inline uint64_t GetDimT() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimG() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint64_t GetDimD() {
return AscendC::Std::get<3>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_KV_BNSD, ACTLEN_T, false> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> actualSeqLensKVParser;
bool isKvPaddingFlag = false;
uint64_t kvPaddingSize = 0;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t s2, uint32_t d) { gmLayout.MakeLayout(b, n2, s2, d); }
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t s2, uint32_t d,
GlobalTensor<ACTLEN_T> actualSeqLengthsGm, uint32_t actualLenKvDims, bool isKvPaddingFlag = false,
uint64_t kvPaddingSize = 0) {
this->isKvPaddingFlag = isKvPaddingFlag;
this->kvPaddingSize = kvPaddingSize;
if (actualLenKvDims != 0) {
actualSeqLensKVParser.Init(actualSeqLengthsGm, actualLenKvDims, 0);
}
gmLayout.MakeLayout(b, n2, s2, d);
}
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t s2, uint32_t d,
const ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> &actualSeqLensKVParser) {
this->actualSeqLensKVParser = actualSeqLensKVParser;
gmLayout.MakeLayout(b, n2, s2, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
if (isKvPaddingFlag) {
s2Idx += GetDimS2() - kvPaddingSize - actualSeqLensKVParser.GetActualSeqLength(bIdx);
}
uint64_t offset = bIdx * GetStrideB() + n2Idx * GetStrideN2() + s2Idx * GetStrideS2() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideB() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideS2() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetDimB() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimS2() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint64_t GetDimD() {
return AscendC::Std::get<3>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T, bool WITH_ZERO_HEAD>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_KV_TND, ACTLEN_T, WITH_ZERO_HEAD> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> actualSeqLensKVParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(
uint32_t n2, uint32_t d, GlobalTensor<ACTLEN_T> actualSeqLengthsGmKV, uint32_t actualLenKVDims) {
actualSeqLensKVParser.Init(actualSeqLengthsGmKV, actualLenKVDims);
gmLayout.MakeLayout(actualSeqLensKVParser.GetTSize(), n2, d);
}
__aicore__ inline void Init(uint32_t n2, uint32_t d,
const ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> &actualSeqLensKVParser) {
this->actualSeqLensKVParser = actualSeqLensKVParser;
gmLayout.MakeLayout(actualSeqLensKVParser.GetTSize(), n2, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t tIdx = actualSeqLensKVParser.GetTBase(bIdx) + s2Idx;
uint64_t offset = tIdx * GetStrideT() + n2Idx * GetStrideN2() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideT() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS2() { return GetStrideT(); }
__aicore__ inline uint64_t GetDimT() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimD() {
return AscendC::Std::get<2>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T, bool WITH_ZERO_HEAD>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_V_SCALE_TND, ACTLEN_T, WITH_ZERO_HEAD> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> actualSeqLensKVParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(
uint32_t n2, uint32_t d, GlobalTensor<ACTLEN_T> actualSeqLengthsGmKV, uint32_t actualLenKVDims) {
actualSeqLensKVParser.Init(actualSeqLengthsGmKV, actualLenKVDims);
gmLayout.MakeLayout(actualSeqLensKVParser.GetTSize(), n2, d);
}
__aicore__ inline void Init(uint32_t n2, uint32_t d,
const ActualSeqLensParser<ActualSeqLensMode::ACCUM, ACTLEN_T, WITH_ZERO_HEAD> &actualSeqLensKVParser) {
this->actualSeqLensKVParser = actualSeqLensKVParser;
gmLayout.MakeLayout(actualSeqLensKVParser.GetTSize(), n2, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t tBase = 0;
for (uint32_t idx = 0; idx < bIdx; idx++) {
tBase += ((actualSeqLensKVParser.GetActualSeqLength(idx) + 63U) >> 6U);
}
uint64_t tIdx = tBase + s2Idx;
uint64_t offset = tIdx * GetStrideT() + n2Idx * GetStrideN2() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideT() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS2() { return GetStrideT(); }
__aicore__ inline uint64_t GetDimT() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetDimD() {
return AscendC::Std::get<2>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_KV_PA_BNBD, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
BlockTableParser blockTableParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(
uint32_t n2, uint32_t blockSize, uint32_t d, GlobalTensor<int32_t> blockTableGm, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGm, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d);
}
__aicore__ inline void Init(
uint32_t n2, uint32_t blockSize, uint32_t d, __gm__ uint8_t *blockTableGmAddr, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGmAddr, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t blockIdxInBatch = s2Idx / GetBlockSize();
uint64_t bsIdx = s2Idx % GetBlockSize();
int32_t blockIdx = blockTableParser.GetBlockIdx(bIdx, blockIdxInBatch);
uint64_t offset =
blockIdx * GetStrideBlockNum() + n2Idx * GetStrideN2() + bsIdx * GetStrideBlockSize() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideBlockNum() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideBlockSize() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetN2() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetBlockSize() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetD() {
return AscendC::Std::get<2>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_KV_PA_NZ, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
BlockTableParser blockTableParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t n2, uint32_t blockSize, uint32_t d1, uint32_t d0,
GlobalTensor<int32_t> blockTableGm, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGm, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d1, d0);
}
__aicore__ inline void Init(uint32_t n2, uint32_t blockSize, uint32_t d1, uint32_t d0,
__gm__ uint8_t *blockTableGmAddr, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGmAddr, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d1, d0);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t blockIdxInBatch = s2Idx / GetBlockSize();
uint64_t bsIdx = s2Idx % GetBlockSize();
int32_t blockIdx = blockTableParser.GetBlockIdx(bIdx, blockIdxInBatch);
uint32_t d1Idx = dIdx / GetD0();
uint32_t d0Idx = dIdx % GetD0();
uint64_t offset = blockIdx * GetStrideBlockNum() + n2Idx * GetStrideN2() + d1Idx * GetStrideD1() +
bsIdx * GetStrideBlockSize() + d0Idx * GetStrideD0();
return offset;
}
__aicore__ inline uint64_t GetStrideBlockNum() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideD1() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideBlockSize() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD0() {
return AscendC::Std::get<4>(gmLayout.stride);
}
__aicore__ inline uint64_t GetN2() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetD1() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetBlockSize() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint64_t GetD0() {
return AscendC::Std::get<3>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_K_SCALE_PA_NZ, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
BlockTableParser blockTableParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t n2, uint32_t blockSize, uint32_t d1, uint32_t d0,
GlobalTensor<int32_t> blockTableGm, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGm, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d1, d0);
}
__aicore__ inline void Init(uint32_t n2, uint32_t blockSize, uint32_t d1, uint32_t d0,
__gm__ uint8_t *blockTableGmAddr, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGmAddr, maxblockNumPerBatch);
gmLayout.MakeLayout(n2, blockSize, d1, d0);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t blockIdxInBatch = s2Idx / GetBlockSize();
uint64_t bsIdx = s2Idx % GetBlockSize();
int32_t blockIdx = blockTableParser.GetBlockIdx(bIdx, blockIdxInBatch);
constexpr uint32_t bs0 = 16;
uint32_t bs1Idx = bsIdx / bs0;
uint32_t bs0Idx = bsIdx % bs0;
uint64_t offset = blockIdx * GetStrideBlockNum() + n2Idx * GetStrideN2() + bs1Idx * GetStrideBlockSize1() +
dIdx * GetStrideD() + bs0Idx * GetStrideBlockSize0();
return offset;
}
__aicore__ inline uint64_t GetStrideBlockNum() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideBlockSize1() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideBlockSize0() {
return AscendC::Std::get<4>(gmLayout.stride);
}
__aicore__ inline uint64_t GetN2() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint64_t GetBlockSize1() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint64_t GetD() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint64_t GetBlockSize0() {
return AscendC::Std::get<3>(gmLayout.shape);
}
__aicore__ inline uint64_t GetBlockSize() { return GetBlockSize1() * 16; }
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_POST_QUANT_NGD, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t n2, uint32_t g, uint32_t d) { gmLayout.MakeLayout(n2, g, d); }
__aicore__ inline uint64_t GetOffset(uint32_t n2Idx, uint32_t gIdx, uint32_t dIdx) {
uint64_t offset = n2Idx * GetStrideN2() + gIdx * GetStrideG() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideG() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideD() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint32_t GetDimN2() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimG() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimD() {
return AscendC::Std::get<2>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_ANTIQ_ND, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t n2, uint32_t d) { gmLayout.MakeLayout(n2, d); }
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t offset = n2Idx * GetStrideN2() + dIdx * GetStrideD();
return offset;
}
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideD() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint32_t GetDimN2() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimD() { return AscendC::Std::get<1>(gmLayout.shape); }
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_ANTIQ_BS, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t b, uint32_t s2) { gmLayout.MakeLayout(b, s2); }
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t offset = bIdx * GetStrideB() + s2Idx * GetStrideS2();
return offset;
}
__aicore__ inline uint64_t GetStrideB() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideS2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint32_t GetDimB() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimS2() { return AscendC::Std::get<1>(gmLayout.shape); }
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_ANTIQ_BNS, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t s2) { gmLayout.MakeLayout(b, n2, s2); }
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t s2Idx, uint32_t dIdx) {
uint64_t offset = bIdx * GetStrideB() + n2Idx * GetStrideN2() + s2Idx * GetStrideS2();
return offset;
}
__aicore__ inline uint64_t GetStrideB() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideS2() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint32_t GetDimB() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimS2() {
return AscendC::Std::get<2>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_ANTIQ_BnBs, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
BlockTableParser blockTableParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t blockSize, GlobalTensor<int32_t> blockTableGm, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGm, maxblockNumPerBatch);
gmLayout.MakeLayout(blockSize);
}
__aicore__ inline void Init(uint32_t blockSize, __gm__ uint8_t *blockTableGmAddr, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGmAddr, maxblockNumPerBatch);
gmLayout.MakeLayout(blockSize);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t nIdx, uint32_t sIdx) {
uint64_t blockIdxInBatch = sIdx / GetStrideBlockSize();
uint64_t bsIdx = sIdx % GetStrideBlockSize();
int32_t blockIdx = blockTableParser.GetBlockIdx(bIdx, blockIdxInBatch);
uint64_t offset = blockIdx * GetStrideBlockNum() + bsIdx * GetStrideBlockSize();
return offset;
}
__aicore__ inline uint64_t GetStrideBlockNum() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideBlockSize() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint32_t GetDimBlockSize() { return AscendC::Std::get<0>(gmLayout.shape); }
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_ANTIQ_BnNBs, ACTLEN_T> {
GmLayout<FORMAT> gmLayout;
BlockTableParser blockTableParser;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(
uint32_t n, uint32_t blockSize, GlobalTensor<int32_t> blockTableGm, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGm, maxblockNumPerBatch);
gmLayout.MakeLayout(n, blockSize);
}
__aicore__ inline void Init(
uint32_t n, uint32_t blockSize, __gm__ uint8_t *blockTableGmAddr, uint32_t maxblockNumPerBatch) {
blockTableParser.Init(blockTableGmAddr, maxblockNumPerBatch);
gmLayout.MakeLayout(n, blockSize);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t nIdx, uint32_t sIdx) {
uint64_t blockIdxInBatch = sIdx / GetStrideBlockSize();
uint64_t bsIdx = sIdx % GetStrideBlockSize();
int32_t blockIdx = blockTableParser.GetBlockIdx(bIdx, blockIdxInBatch);
uint64_t offset = blockIdx * GetStrideBlockNum() + nIdx * GetStrideN() + bsIdx * GetStrideBlockSize();
return offset;
}
__aicore__ inline uint64_t GetStrideBlockNum() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideBlockSize() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint32_t GetDimN() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimBlockSize() { return AscendC::Std::get<1>(gmLayout.shape); }
};
template <GmFormat FORMAT, typename ACTLEN_T>
struct OffsetCalculatorImpl<FORMAT, FormatCategory::GM_PSE_BN2GS1S2, ACTLEN_T, false> {
GmLayout<FORMAT> gmLayout;
ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> actualSeqLensQParser;
bool isQPaddingFlag = false;
uint64_t qPaddingSize = 0;
__aicore__ inline OffsetCalculatorImpl() = default;
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t g, uint32_t s1, uint32_t s2,
GlobalTensor<ACTLEN_T> actualSeqLengthsGmQ, uint32_t actualLenQDims, bool isQPaddingFlag = false,
uint64_t qPaddingSize = 0) {
this->isQPaddingFlag = isQPaddingFlag;
this->qPaddingSize = qPaddingSize;
if (actualLenQDims != 0) {
actualSeqLensQParser.Init(actualSeqLengthsGmQ, actualLenQDims, 0);
}
gmLayout.MakeLayout(b, n2, g, s1, s2);
}
__aicore__ inline void Init(uint32_t b, uint32_t n2, uint32_t g, uint32_t s1, uint32_t s2,
const ActualSeqLensParser<ActualSeqLensMode::BY_BATCH, ACTLEN_T> &actualSeqLensQParser) {
this->actualSeqLensQParser = actualSeqLensQParser;
gmLayout.MakeLayout(b, n2, g, s1, s2);
}
__aicore__ inline uint64_t GetOffset(uint32_t bIdx, uint32_t n2Idx, uint32_t gIdx, uint32_t s1Idx, uint32_t s2Idx) {
if (isQPaddingFlag) {
s1Idx += GetDimS1() - qPaddingSize - actualSeqLensQParser.GetActualSeqLength(bIdx);
}
uint64_t offset = bIdx * GetStrideB() + n2Idx * GetStrideN2() + gIdx * GetStrideG() + s1Idx * GetStrideS1() +
s2Idx * GetStrideS2();
return offset;
}
__aicore__ inline uint64_t GetStrideB() { return AscendC::Std::get<0>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideN2() { return AscendC::Std::get<1>(gmLayout.stride); }
__aicore__ inline uint64_t GetStrideG() {
return AscendC::Std::get<2>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS1() {
return AscendC::Std::get<3>(gmLayout.stride);
}
__aicore__ inline uint64_t GetStrideS2() {
return AscendC::Std::get<4>(gmLayout.stride);
}
__aicore__ inline uint32_t GetDimB() { return AscendC::Std::get<0>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimN2() { return AscendC::Std::get<1>(gmLayout.shape); }
__aicore__ inline uint32_t GetDimG() {
return AscendC::Std::get<2>(gmLayout.shape);
}
__aicore__ inline uint32_t GetDimS1() {
return AscendC::Std::get<3>(gmLayout.shape);
}
__aicore__ inline uint32_t GetDimS2() {
return AscendC::Std::get<4>(gmLayout.shape);
}
};
template <GmFormat FORMAT, typename ACTLEN_T = uint64_t, bool WITH_ZERO_HEAD = false>
struct OffsetCalculator
: public OffsetCalculatorImpl<FORMAT, GmLayoutParams<FORMAT>::CATEGORY, ACTLEN_T, WITH_ZERO_HEAD> {};
#endif