* 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.
*/
#include "fused_floyd_attention_grad_tiling_s1s2_bn2gs1s2.h"
#include "op_host/tiling_type.h"
#include "op_host/tiling_templates_registry.h"
#include "err/ops_err.h"
#include "op_host/tiling_base.h"
using namespace Ops::Transformer::OpTiling;
namespace optiling {
namespace FFAG {
constexpr uint32_t INITIAL_S1_SPLIT_NUM = 128;
constexpr uint32_t INITIAL_S2_SPLIT_NUM = 64;
constexpr uint32_t MUL_CORE_SYNC_BUFFER = 16 * 1024;
constexpr uint32_t EMPTY_TENSOR = 0;
constexpr uint32_t NORMAL_TENSOR = 1;
constexpr uint32_t MAX_BASIC_BLOCK_SIZE = 1024;
constexpr uint32_t TEMP_BUFFER_REMAIN_SIZE = 1024 * 2;
constexpr uint32_t INPUT_FORMAT_BN2GS2D = 0;
constexpr uint32_t CORE_INIT_NUM = 40;
constexpr uint32_t MATMUL_SIZE = 8 * 1024;
constexpr uint32_t INPUT_ALIGN = 16;
constexpr uint32_t WORKSPACE_NUM_ALIGN = 256;
constexpr int64_t GM_ALIGN = 512;
constexpr uint32_t SOFTMAX_PERF = 64;
constexpr uint32_t TOTAL_BLOCK_DIMENSION = 2;
constexpr uint32_t CALCULATED_BLOCK_DIMENSION = 4;
constexpr uint32_t BEGIN_IDX = 0;
constexpr uint32_t END_IDX = 1;
constexpr uint32_t SUM_S1S2 = 2;
constexpr uint32_t SUM_ALL = 3;
constexpr uint32_t LENGTH_IDX = 2;
constexpr uint32_t BASIC_BLOCK_MULTIPLE = 15;
constexpr uint32_t POST_NZ_COEX_NODE = 10;
constexpr uint32_t POST_COEX_NODE = 3;
constexpr uint32_t BUFFER_NUM = 1;
constexpr uint32_t POST_NZ_RESERVED_N = 4;
constexpr uint32_t FP16_BYTES = 2;
constexpr uint32_t FP16_BLOCK_NUMS = 16;
constexpr uint32_t FP32_BYTES = 4;
constexpr uint32_t FP32_BLOCK_NUMS = 8;
constexpr uint32_t SHAPE_INFO = 32;
constexpr uint32_t C0_SIZE = 16;
constexpr uint32_t BLOCK_SIZE = 32;
constexpr uint32_t MATMAL_INPUT_NUMS = 2;
constexpr uint32_t S1CV_RATIO_DEFAULT = 1;
constexpr uint32_t S2CV_RATIO_DEFAULT = 8;
constexpr uint32_t CV_RATIO_2 = 2;
constexpr uint32_t CV_RATIO_4 = 4;
constexpr uint32_t CV_RATIO_16 = 16;
constexpr uint32_t WORKSPACE_BUFFER = 20 * 1024 * 1024;
constexpr uint32_t PSE_ALIBI_S2_LIMIT_SIZE = 1024;
constexpr uint32_t BIT_NUMS = 8;
constexpr uint32_t S2_NZ_SIZE = 128;
constexpr uint32_t MM12_ND2NZ_SIZE = 5000;
constexpr uint32_t ASCENDC_API_TEMP_BUFFER = 32 * 1024 + 1024;
constexpr uint32_t API_BOOL_ALIGN = 32;
constexpr uint32_t SYNC_GLOBAL_WORKSPACE_SIZE = 16 * 1024;
constexpr uint32_t ADDR_ALIGN_SIZE = 512;
constexpr uint32_t FIX_BASEMN_128 = 128;
constexpr uint32_t FIX_BASEMN_256 = 256;
constexpr uint32_t EVERY_BLOCK_INFO_DIM = 4;
constexpr uint32_t S1OUTER_IDX = 0;
constexpr uint32_t S2OUTER_IDX = 1;
constexpr uint32_t S1TAIL_IDX = 2;
constexpr uint32_t S2TAIL_IDX = 3;
constexpr uint32_t SFMG_DB_CLC1_UBSIZE = 18 * 1024;
bool FusedFloydAttentionGradTilingS1s2Bn2gs1s2::IsCapable()
{
return true;
}
uint64_t FusedFloydAttentionGradTilingS1s2Bn2gs1s2::GetTilingKey() const
{
auto dtypeValue = DtypeEnum::FLOAT32;
if (fBaseParams.mode == BF16) {
dtypeValue = DtypeEnum::BFLOAT16;
} else if (fBaseParams.mode == FP32) {
dtypeValue = DtypeEnum::FLOAT32;
} else {
dtypeValue = DtypeEnum::FLOAT16_PRECISION;
}
auto attenMaskCfg = fBaseParams.attenMaskOptional == EMPTY_TENSOR ? OptionEnum::DISABLE : OptionEnum::ENABLE;
LayoutEnum inputLayout = LayoutEnum::BNSD;
auto pseValue = fBaseParams.pseOptional == NORMAL_TENSOR ? OptionEnum::ENABLE : OptionEnum::DISABLE;
auto dropValue = fBaseParams.keepProb < 1 ? OptionEnum::ENABLE : OptionEnum::DISABLE;
auto mm1IsNZOut = fBaseParams.mm1IsNZOut ? OptionEnum::ENABLE : OptionEnum::DISABLE;
auto mm2IsNZOut = fBaseParams.mm2IsNZOut ? OptionEnum::ENABLE : OptionEnum::DISABLE;
auto tndS1Pingpong = OptionEnum::DISABLE;
uint64_t tilingKey = GET_TILINGKEY(AxisEnum::S2, AxisEnum::S1, AxisEnum::S2, dtypeValue, inputLayout,
SparseEnum::ALL, dropValue, pseValue, attenMaskCfg, mm1IsNZOut, mm2IsNZOut,
OptionEnum::DISABLE, OptionEnum::DISABLE, tndS1Pingpong);
OP_LOGI(context_, "FAGTiling S1s2Bn2gs1s2 DoTiling success, tiling is %lu.", tilingKey);
return tilingKey;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::GetPlatformInfo()
{
uint32_t coreNum = CORE_INIT_NUM;
auto platformInfoPtr = context_->GetPlatformInfo();
if (platformInfoPtr == nullptr) {
auto compileInfoPtr = reinterpret_cast<const FlashAttentionScoreGradCompileInfo *>(context_->GetCompileInfo());
OP_CHECK_IF(compileInfoPtr == nullptr, OP_LOGE(context_, "compile_info is null"),
return ge::GRAPH_FAILED);
fBaseParams.coreNum = compileInfoPtr->aivNum;
fBaseParams.aicNum = compileInfoPtr->aicNum;
fBaseParams.ubSize = compileInfoPtr->ubSize;
fBaseParams.l1Size = compileInfoPtr->l1Size;
fBaseParams.l0aSize = compileInfoPtr->l0aSize;
fBaseParams.l0cSize = compileInfoPtr->l0cSize;
} else {
auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfoPtr);
coreNum = ascendcPlatform.GetCoreNumAiv();
fBaseParams.coreNum = coreNum;
fBaseParams.aicNum = ascendcPlatform.GetCoreNumAic();
ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, fBaseParams.ubSize);
ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::L1, fBaseParams.l1Size);
ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::L0_A, fBaseParams.l0aSize);
ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::L0_C, fBaseParams.l0cSize);
}
OP_CHECK_IF((fBaseParams.coreNum == 0) || (fBaseParams.aicNum == 0),
OP_LOGE(context_, "num of coreNum(aivNum) is %ld, num of aicNum is %ld.",
fBaseParams.coreNum, fBaseParams.aicNum),
return ge::GRAPH_FAILED);
fBaseParams.ubSize -= MATMUL_SIZE;
OP_CHECK_IF(fBaseParams.ubSize <= 0,
OP_LOGE(context_, "ubSize is invalid."),
return ge::GRAPH_FAILED);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::GetBaseShapeInfo() {
const gert::StorageShape *queryShape = context_->GetInputShape(QUERY);
const gert::StorageShape *keyShape = context_->GetInputShape(KEY_1);
const char *inputLayout = "BNSD";
OP_CHECK_IF(queryShape == nullptr,
OP_LOGE(context_, "queryShape is nullptr."),
return ge::GRAPH_FAILED);
OP_CHECK_IF(keyShape == nullptr,
OP_LOGE(context_, "keyShape is nullptr."),
return ge::GRAPH_FAILED);
if (strcmp(inputLayout, "BNSD") == 0) {
OP_LOGD(context_, "inputLayout == BNSD queryShape");
fBaseParams.layoutType = INPUT_FORMAT_BN2GS2D;
fBaseParams.b = queryShape->GetStorageShape().GetDim(0);
fBaseParams.n2 = keyShape->GetStorageShape().GetDim(1);
fBaseParams.g = keyShape->GetStorageShape().GetDim(2);
fBaseParams.s1 = queryShape->GetStorageShape().GetDim(3);
fBaseParams.d = queryShape->GetStorageShape().GetDim(4);
fBaseParams.s2 = keyShape->GetStorageShape().GetDim(3);
OP_LOGD(context_, "inputLayout == BNSD queryShape", "%ld, %ld, %ld, %ld,",
queryShape->GetStorageShape().GetDim(DIM_0), queryShape->GetStorageShape().GetDim(DIM_1),
queryShape->GetStorageShape().GetDim(DIM_2), queryShape->GetStorageShape().GetDim(DIM_3));
} else {
OP_LOGE(context_, "FAG inputLayout is invalid");
return ge::GRAPH_FAILED;
}
OP_CHECK_IF(fBaseParams.n2 == 0,
OP_LOGE(context_, "n2 is 0."),
return ge::GRAPH_FAILED);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::GetShapeAttrsInfo()
{
OP_CHECK_IF(context_ == nullptr,
OP_LOGE(context_, "context is nullptr."),
return ge::GRAPH_FAILED);
OP_CHECK_IF(context_->GetAttrs() == nullptr,
OP_LOGE(context_, "GetAttrs is nullptr."),
return ge::GRAPH_FAILED);
auto ret = GetBaseShapeInfo();
if (ret != ge::GRAPH_SUCCESS) {
return ret;
}
fBaseParams.n1 = fBaseParams.n2 * fBaseParams.g;
fBaseParams.s1Align = (fBaseParams.s1 + INPUT_ALIGN - 1) / INPUT_ALIGN * INPUT_ALIGN;
fBaseParams.s2Align = (fBaseParams.s2 + INPUT_ALIGN - 1) / INPUT_ALIGN * INPUT_ALIGN;
fBaseParams.qSize = fBaseParams.b * fBaseParams.n2 * fBaseParams.g * fBaseParams.s1 * fBaseParams.d;
fBaseParams.kvSize = fBaseParams.b * fBaseParams.n2 * fBaseParams.g * fBaseParams.s2 * fBaseParams.d;
fBaseParams.k1v1Size = fBaseParams.b * fBaseParams.n2 * fBaseParams.s2 * fBaseParams.s1 * fBaseParams.d;
fBaseParams.dropMaskSize = fBaseParams.b * fBaseParams.n2 * fBaseParams.g * fBaseParams.s2 * fBaseParams.s1;
OP_CHECK_IF(context_->GetInputDesc(QUERY) == nullptr,
OP_LOGE(context_, "InputDesc of query is nullptr."),
return ge::GRAPH_FAILED);
auto queryType = context_->GetInputDesc(QUERY)->GetDataType();
fBaseParams.queryType = queryType;
fBaseParams.isBf16 = queryType == ge::DT_BF16 ? true : false;
if (queryType == ge::DT_FLOAT) {
fBaseParams.dataTypeSize = FP32_BYTES;
fBaseParams.dataBlockNum = FP32_BLOCK_NUMS;
fBaseParams.calTypeSize = FP32_BYTES;
fBaseParams.calBlockNum = FP32_BLOCK_NUMS;
} else {
fBaseParams.dataTypeSize = FP16_BYTES;
fBaseParams.dataBlockNum = FP16_BLOCK_NUMS;
fBaseParams.calTypeSize = FP32_BYTES;
fBaseParams.calBlockNum = FP32_BLOCK_NUMS;
}
fBaseParams.mm1IsNZOut = false;
fBaseParams.mm2IsNZOut = false;
fBaseParams.dataBlockNum = BYTE_BLOCK / fBaseParams.dataTypeSize;
fBaseParams.calBlockNum = BYTE_BLOCK / fBaseParams.calTypeSize;
int64_t qSizeAlign = fBaseParams.qSize;
int64_t kvSizeAlign = fBaseParams.kvSize;
int64_t k1v1SizeAlign = fBaseParams.k1v1Size;
if (fBaseParams.mm2IsNZOut) {
int64_t dAlign = (fBaseParams.d + C0_SIZE - 1) / C0_SIZE * C0_SIZE;
qSizeAlign = (fBaseParams.qSize / fBaseParams.d) * dAlign;
kvSizeAlign = (fBaseParams.kvSize / fBaseParams.d) * dAlign;
}
fBaseParams.qSizeAlign = qSizeAlign;
fBaseParams.kvSizeAlign = kvSizeAlign;
fBaseParams.k1v1SizeAlign = k1v1SizeAlign;
fBaseParams.scaleValue = *(context_->GetAttrs()->GetAttrPointer<float>(0));
fBaseParams.keepProb = 1;
OP_CHECK_IF((fBaseParams.keepProb <= 0 || fBaseParams.keepProb > 1),
OP_LOGE(context_, "keepProb is illegal."),
return ge::GRAPH_FAILED);
fBaseParams.dropoutIsDivisibleBy8 = 1;
fBaseParams.s1Token = 65536;
fBaseParams.s2Token = 65536;
fBaseParams.sparseMode = NO_MASK;
fBaseParams.attenMaskOptional = EMPTY_TENSOR;
auto attenMask = context_->GetOptionalInputDesc(ATTEN_MASK);
if (attenMask != nullptr) {
fBaseParams.attenMaskOptional = NORMAL_TENSOR;
auto attenMaskType = attenMask->GetDataType();
OP_CHECK_IF(attenMaskType != ge::DT_BOOL && attenMaskType != ge::DT_UINT8,
OP_LOGE(context_, "invalid attenMask dtype[%s], only support bool or uint8.",
ge::TypeUtils::DataTypeToSerialString(attenMaskType).c_str()),
return ge::GRAPH_FAILED);
fBaseParams.attenMaskDtype = ATTEN_MASK_TYPE_U8_BOOL;
}
fBaseParams.isSparse = false;
OP_LOGD(context_, "FAG S1s2Bn2gs1s2 sparse mode = %u, sparse %s.", fBaseParams.sparseMode,
fBaseParams.isSparse ? "enable" : "disable");
return CheckInputShapeValid(context_, fBaseParams.b, fBaseParams.n2, fBaseParams.g, fBaseParams.s1, fBaseParams.s2, fBaseParams.d);
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoOpTiling()
{
auto ret = DoSplit();
OP_CHECK_IF(ret != ge::GRAPH_SUCCESS,
OP_LOGW(context_, "get DoSplit fail."),
return ret);
ret = DoSparse();
OP_CHECK_IF(ret != ge::GRAPH_SUCCESS,
OP_LOGW(context_, "get DoSparse fail."),
return ret);
ret = DoPreTiling();
OP_CHECK_IF(ret != ge::GRAPH_SUCCESS,
OP_LOGW(context_, "get DoPreTiling fail."),
return ret);
ret = DoPostTiling();
OP_CHECK_IF(ret != ge::GRAPH_SUCCESS,
OP_LOGW(context_, "get DoPostTiling fail."),
return ret);
DetermineMode();
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoSplit()
{
fBaseParams.s1CvRatio = 1;
fBaseParams.s2CvRatio = 1;
if (fBaseParams.d == 64) {
fBaseParams.s2CvRatio = CV_RATIO_16;
if (fBaseParams.s1 >= 256) {
if (fBaseParams.s2 <= 128) {
fBaseParams.s1CvRatio = CV_RATIO_4;
fBaseParams.s2CvRatio = CV_RATIO_2;
}
}
}
fBaseParams.s1CvRatio = 1;
fBaseParams.s2CvRatio = 1;
uint32_t s1Inner = 64;
uint32_t s2Inner = 128;
fBaseParams.gInner = 16;
fBaseParams.bmmS1base = 8;
if (fBaseParams.d == 32) {
fBaseParams.bmmS1base = 16;
}
uint32_t tmpBufferSize =
(fBaseParams.ubSize - s1Inner * s2Inner * BASIC_BLOCK_MULTIPLE - s1Inner * SHAPE_INFO * fBaseParams.calTypeSize) /
BYTE_BLOCK * BYTE_BLOCK;
if (fBaseParams.mm1IsNZOut) {
tmpBufferSize = tmpBufferSize - TEMP_BUFFER_REMAIN_SIZE;
}
fBaseParams.tmpBufferSize = tmpBufferSize;
uint32_t s1CvInner = s1Inner * fBaseParams.s1CvRatio;
OP_CHECK_IF(s1CvInner == 0,
OP_LOGE(context_, "divisor s1CvInner is 0."),
return ge::GRAPH_FAILED);
int64_t s1Outer = (fBaseParams.s1 + s1CvInner - 1) / s1CvInner;
uint32_t s1TailTmp = fBaseParams.s1 % s1Inner;
uint32_t s1CvTailTmp = fBaseParams.s1 % s1CvInner;
fBaseParams.s1Tail = s1TailTmp == 0 ? s1Inner : s1TailTmp;
fBaseParams.s1CvTail = s1CvTailTmp == 0 ? s1CvInner : s1CvTailTmp;
fBaseParams.s1Inner = s1Inner;
fBaseParams.s1CvInner = s1CvInner;
fBaseParams.s1Outer = s1Outer;
uint32_t cvS2Inner = s2Inner * fBaseParams.s2CvRatio;
OP_CHECK_IF(cvS2Inner == 0,
OP_LOGE(context_, "divisor cvS2Inner is 0."),
return ge::GRAPH_FAILED);
int64_t s2Outer = (fBaseParams.s2 + cvS2Inner - 1) / cvS2Inner;
uint32_t s2TailTmp = fBaseParams.s2 % s2Inner;
uint32_t s2CvTailTmp = fBaseParams.s2 % cvS2Inner;
fBaseParams.s2Tail = s2TailTmp == 0 ? s2Inner : s2TailTmp;
fBaseParams.s2CvTail = s2CvTailTmp == 0 ? cvS2Inner : s2CvTailTmp;
fBaseParams.s2Outer = s2Outer;
fBaseParams.cvS2Inner = cvS2Inner;
fBaseParams.s2Inner = s2Inner;
fBaseParams.gOuter = (fBaseParams.g + fBaseParams.gInner - 1) / fBaseParams.gInner;
fBaseParams.gTail = fBaseParams.g - (fBaseParams.gOuter - 1) * fBaseParams.gInner;
fBaseParams.baseMN = fBaseParams.gInner * s1Inner * s2Inner;
OP_CHECK_IF(
(fBaseParams.baseMN == 0 || fBaseParams.s2Outer == 0 || fBaseParams.s1Outer == 0),
OP_LOGE(context_, "baseMN or s2Outer or s1Outer is 0."),
return ge::GRAPH_FAILED);
uint32_t sfmgdInner = 128;
OP_CHECK_IF(sfmgdInner == 0,
OP_LOGE(context_, "divisor sfmgdInner is 0."),
return ge::GRAPH_FAILED);
uint32_t sfmgdOuter = (fBaseParams.d + sfmgdInner - 1) / sfmgdInner;
uint32_t sfmgdTailTmp = fBaseParams.d % sfmgdInner;
uint32_t sfmgdTail = sfmgdTailTmp == 0 ? sfmgdInner : sfmgdTailTmp;
fBaseParams.sfmgdOuter = sfmgdOuter;
fBaseParams.sfmgdInner = sfmgdInner;
fBaseParams.sfmgdTail = sfmgdTail;
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoSparse()
{
int64_t blockStarts[CORE_LIST_NUM];
int64_t blockEnds[CORE_LIST_NUM];
int64_t fusedOuter = static_cast<int64_t>(fBaseParams.b) * fBaseParams.n2 * fBaseParams.gOuter *
fBaseParams.s1Outer * fBaseParams.s2Outer;
int64_t blockFactor = (fusedOuter + fBaseParams.coreNum - 1) / fBaseParams.coreNum;
OP_CHECK_IF(blockFactor == 0,
OP_LOGE(context_, "divisor blockFactor is 0."),
return ge::GRAPH_FAILED);
int64_t blockOuter = (fusedOuter + blockFactor - 1) / blockFactor;
OP_CHECK_IF(blockOuter > CORE_LIST_NUM,
OP_LOGE(context_, "blockStarts and blockEnds array bound."),
return ge::GRAPH_FAILED);
fBaseParams.blockOuter = blockOuter;
fBaseParams.blockFactor = blockFactor;
for (int64_t i = 0; i < blockOuter; i++) {
blockStarts[i] = blockFactor * i;
blockEnds[i] = std::min(blockFactor * (i + 1), fusedOuter);
}
for (int64_t i = blockOuter; i < CORE_LIST_NUM; i++) {
blockStarts[i] = 0;
blockEnds[i] = 0;
}
std::copy(std::begin(blockStarts), std::end(blockStarts), std::begin(fBaseParams.blockStarts));
std::copy(std::begin(blockEnds), std::end(blockEnds), std::begin(fBaseParams.blockEnds));
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoLibApiTiling()
{
matmul_tiling::MatmulApiTiling mm1;
matmul_tiling::MatmulApiTiling mm2;
matmul_tiling::MatmulApiTiling mm3;
matmul_tiling::DataType inputAType = matmul_tiling::DataType::DT_FLOAT;
if(fBaseParams.mode == FP32) {
inputAType = matmul_tiling::DataType::DT_FLOAT;
} else {
inputAType = matmul_tiling::DataType::DT_BFLOAT16;
}
mm1.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, false);
mm1.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, true);
mm1.SetCType(matmul_tiling::TPosition::VECCALC, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT);
int64_t mmS1 = fBaseParams.s1;
if (fBaseParams.mm1IsNZOut) {
mmS1 = fBaseParams.s1Inner * fBaseParams.s1CvRatio;
}
mm1.SetOrgShape(mmS1, fBaseParams.s2, fBaseParams.d);
mm1.SetShape(fBaseParams.s1Inner * fBaseParams.s1CvRatio, fBaseParams.s2Inner * fBaseParams.s2CvRatio, fBaseParams.d);
mm1.SetBias(false);
if (fBaseParams.cvS2Inner > 128) {
if (fBaseParams.d > 64) {
uint32_t minBaseM = std::min(fBaseParams.s1CvInner, FIX_BASEMN_256);
mm1.SetFixSplit(minBaseM, FIX_BASEMN_128, -1);
} else {
uint32_t minBaseM = std::min(fBaseParams.s1CvInner, FIX_BASEMN_128);
mm1.SetFixSplit(minBaseM, FIX_BASEMN_256, -1);
}
} else {
mm1.SetFixSplit(-1, -1, -1);
}
OP_CHECK_IF(mm1.GetTiling(tilingData.mm1TilingData) != 0,
OP_LOGE(context_, "matmul1 tilingData get fail."),
return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.mm1TilingData);
matmul_tiling::MatmulApiTiling bmm1k1;
SetBmm1k1TilingInput(bmm1k1, inputAType);
OP_CHECK_IF(bmm1k1.GetTiling(tilingData.bmm1TilingData) != 0,
OP_LOGE(context_, "bmm1k1 tilingData get fail."), return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.bmm1TilingData);
matmul_tiling::MatmulApiTiling bmm2k1;
SetBmm2k1TilingInput(bmm2k1, inputAType);
OP_CHECK_IF(bmm2k1.GetTiling(tilingData.bmm2TilingData) != 0,
OP_LOGE(context_, "bmm2k1 tilingData get fail."), return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.bmm2TilingData);
matmul_tiling::MatmulApiTiling bmm3k1v1;
SetBmm3k1V1TilingInput(bmm3k1v1, inputAType);
OP_CHECK_IF(bmm3k1v1.GetTiling(tilingData.bmm3TilingData) != 0,
OP_LOGE(context_, "bmm3k1v1 tilingData get fail."), return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.bmm3TilingData);
mm2.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType,
true);
mm2.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType,
false);
auto outFormat = fBaseParams.mm2IsNZOut ? matmul_tiling::CubeFormat::NZ : matmul_tiling::CubeFormat::ND;
mm2.SetCType(matmul_tiling::TPosition::GM, outFormat, matmul_tiling::DataType::DT_FLOAT);
mm2.SetOrgShape(fBaseParams.s2, fBaseParams.d, fBaseParams.s1);
mm2.SetShape(fBaseParams.s2Inner * fBaseParams.s2CvRatio, fBaseParams.d,
fBaseParams.s1Inner * fBaseParams.s1CvRatio);
mm2.SetBias(false);
mm2.SetFixSplit(-1, -1, -1);
OP_CHECK_IF(mm2.GetTiling(tilingData.mm2TilingData) != 0,
OP_LOGE(context_, "matmul2 tilingData get fail."),
return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.mm2TilingData);
mm3.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType,
false);
mm3.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType,
false);
mm3.SetCType(matmul_tiling::TPosition::GM, outFormat, matmul_tiling::DataType::DT_FLOAT);
mm3.SetOrgShape(fBaseParams.s1, fBaseParams.d, fBaseParams.s2);
mm3.SetShape(fBaseParams.s1Inner * fBaseParams.s1CvRatio, fBaseParams.d,
fBaseParams.s2Inner * fBaseParams.s2CvRatio);
mm3.SetBias(false);
if (fBaseParams.mm1IsNZOut && fBaseParams.mm2IsNZOut) {
int64_t dAlign = (fBaseParams.d + FP16_BLOCK_NUMS - 1) / FP16_BLOCK_NUMS * FP16_BLOCK_NUMS;
uint32_t minBaseN = std::min(static_cast<uint32_t>(dAlign), FIX_BASEMN_256);
mm3.SetFixSplit(-1, minBaseN, -1);
} else {
mm3.SetFixSplit(-1, -1, -1);
}
OP_CHECK_IF(mm3.GetTiling(tilingData.mm3TilingData) != 0,
OP_LOGE(context_, "matmul3 tilingData get fail."),
return ge::GRAPH_FAILED);
SetMatmulTilingBufferInfo(tilingData.mm3TilingData);
uint32_t cvS2Inner = fBaseParams.s2Inner * fBaseParams.s2CvRatio;
uint32_t s2VSize = cvS2Inner > 256 ? 256 : cvS2Inner;
uint32_t s1VecSize =
std::min(((INITIAL_S1_SPLIT_NUM * INITIAL_S2_SPLIT_NUM + s2VSize - 1) / s2VSize), fBaseParams.s1Inner);
auto softmaxShape = ge::Shape({s1VecSize, s2VSize});
AscendC::SoftMaxTilingFunc(softmaxShape, fBaseParams.calTypeSize, fBaseParams.tmpBufferSize,
tilingData.softmaxTilingData);
AscendC::SoftMaxGradTilingFunc(softmaxShape, fBaseParams.calTypeSize, fBaseParams.tmpBufferSize,
tilingData.softmaxGradTilingData, true);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::SetBmm1k1TilingInput(
matmul_tiling::MatmulApiTiling &bmm1k1, matmul_tiling::DataType inputAType)
{
bmm1k1.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, false);
bmm1k1.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, true);
bmm1k1.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT);
bmm1k1.SetShape(fBaseParams.gInner, fBaseParams.cvS2Inner, fBaseParams.d);
bmm1k1.SetOrgShape(fBaseParams.g, fBaseParams.s2, fBaseParams.d);
bmm1k1.SetBias(false);
bmm1k1.SetBufferSpace(-1, -1, -1);
bmm1k1.SetALayout(1, fBaseParams.g, 1, fBaseParams.s1, fBaseParams.d);
bmm1k1.SetBLayout(1, fBaseParams.s2, 1, fBaseParams.s1, fBaseParams.d);
bmm1k1.SetCLayout(1, fBaseParams.gInner, 1, fBaseParams.s1CvInner, fBaseParams.cvS2Inner);
bmm1k1.SetBatchNum(fBaseParams.bmmS1base);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::SetBmm2k1TilingInput(
matmul_tiling::MatmulApiTiling &bmm2k1, matmul_tiling::DataType inputAType)
{
bmm2k1.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, false);
bmm2k1.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, false);
bmm2k1.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT);
bmm2k1.SetShape(fBaseParams.gInner, fBaseParams.d, fBaseParams.cvS2Inner);
bmm2k1.SetOrgShape(fBaseParams.g, fBaseParams.d, fBaseParams.s2);
bmm2k1.SetBias(false);
bmm2k1.SetBufferSpace(-1, -1, -1);
bmm2k1.SetALayout(1, fBaseParams.gInner, 1, fBaseParams.s1CvInner, fBaseParams.cvS2Inner);
bmm2k1.SetBLayout(1, fBaseParams.s2, 1, fBaseParams.s1, fBaseParams.d);
bmm2k1.SetCLayout(1, fBaseParams.g, 1, fBaseParams.s1, fBaseParams.d);
bmm2k1.SetBatchNum(fBaseParams.bmmS1base);
return true;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::SetBmm3k1V1TilingInput(
matmul_tiling::MatmulApiTiling &bmm3k1v1, matmul_tiling::DataType inputAType)
{
bmm3k1v1.SetAType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, true);
bmm3k1v1.SetBType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, inputAType, false);
bmm3k1v1.SetCType(matmul_tiling::TPosition::GM, matmul_tiling::CubeFormat::ND, matmul_tiling::DataType::DT_FLOAT);
bmm3k1v1.SetShape(fBaseParams.cvS2Inner, fBaseParams.d, fBaseParams.gInner);
bmm3k1v1.SetOrgShape(fBaseParams.s2, fBaseParams.d, fBaseParams.g);
bmm3k1v1.SetBias(false);
bmm3k1v1.SetBufferSpace(-1, -1, -1);
bmm3k1v1.SetALayout(1, fBaseParams.gInner, 1, fBaseParams.s1CvInner, fBaseParams.cvS2Inner);
bmm3k1v1.SetBLayout(1, fBaseParams.g, 1, fBaseParams.s1, fBaseParams.d);
bmm3k1v1.SetCLayout(1, fBaseParams.s2, 1, fBaseParams.s1, fBaseParams.d);
bmm3k1v1.SetBatchNum(fBaseParams.bmmS1base);
return true;
}
void FusedFloydAttentionGradTilingS1s2Bn2gs1s2::SetMatmulTilingBufferInfo(TCubeTiling &mmTiling)
{
mmTiling.set_shareMode(0);
mmTiling.set_shareL1Size(fBaseParams.l1Size);
mmTiling.set_shareL0CSize(fBaseParams.l0cSize);
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::GetWorkspaceSize()
{
size_t *workspaces = context_->GetWorkspaceSizes(1);
size_t workspaceSize = MUL_CORE_SYNC_BUFFER;
uint32_t s1Inner = std::min(INITIAL_S1_SPLIT_NUM, fBaseParams.s1Align);
OP_CHECK_IF(s1Inner <= 0,
OP_LOGE(context_,
"s1Inner is less than or equal to 0, s1Inner is %u.", s1Inner),
return ge::GRAPH_FAILED);
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.qSizeAlign) * FP32_BYTES + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.kvSizeAlign) * FP32_BYTES + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.kvSizeAlign) * FP32_BYTES + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.k1v1SizeAlign) * FP32_BYTES + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.k1v1SizeAlign) * FP32_BYTES + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
if (fBaseParams.dropoutIsDivisibleBy8 == 0) {
workspaceSize =
(workspaceSize + static_cast<size_t>(fBaseParams.dropMaskSize) + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
}
size_t vectorCoreNum = fBaseParams.coreNum;
workspaceSize = (workspaceSize +
vectorCoreNum * fBaseParams.gInner * fBaseParams.s1CvRatio * fBaseParams.s2CvRatio * fBaseParams.baseMN * FP32_BYTES *
MATMAL_INPUT_NUMS +
GM_ALIGN) /
GM_ALIGN * GM_ALIGN;
workspaceSize = (workspaceSize +
vectorCoreNum * fBaseParams.gInner * fBaseParams.s1CvRatio * fBaseParams.s2CvRatio * fBaseParams.baseMN *
fBaseParams.dataTypeSize *
2
+ GM_ALIGN) /
GM_ALIGN * GM_ALIGN;
workspaceSize = (workspaceSize +
vectorCoreNum * fBaseParams.gInner * fBaseParams.s1CvRatio * fBaseParams.s2CvRatio * fBaseParams.baseMN *
fBaseParams.dataTypeSize *
2
+ GM_ALIGN) /
GM_ALIGN * GM_ALIGN;
workspaceSize += WORKSPACE_BUFFER;
workspaces[0] = workspaceSize;
if (fBaseParams.pseType == PSE_INNER_MUL_ADD_TYPE ||
fBaseParams.pseType == PSE_INNER_MUL_ADD_SQRT_TYPE) {
fBaseParams.pseAlibiBaseS2 = PSE_ALIBI_S2_LIMIT_SIZE;
int64_t s2Tail = fBaseParams.s2 % PSE_ALIBI_S2_LIMIT_SIZE;
if (s2Tail != 0) {
fBaseParams.pseAlibiBaseS1 = std::min(static_cast<int64_t>(s1Inner),
UB_BASIC_LIMIT_SIZE / AlignUp(s2Tail, FRACTAL_NUM));
} else {
fBaseParams.pseAlibiBaseS1 = std::min(static_cast<int64_t>(s1Inner),
UB_BASIC_LIMIT_SIZE / fBaseParams.pseAlibiBaseS2);
}
fBaseParams.pseAlibiBaseS1 = std::max(fBaseParams.pseAlibiBaseS1, UB_BASIC_LIMIT_SIZE / s1Inner);
int64_t pseAlibiBytes = AlignUp(fBaseParams.pseAlibiBaseS2 * fBaseParams.pseAlibiBaseS1 * 2, GM_ALIGN) * fBaseParams.coreNum;
workspaces[0] += pseAlibiBytes;
}
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::PostTiling()
{
SaveToTilingData();
auto blockdim = CalcTschBlockDim(tilingData.s1s2BNGS1S2SplitCoreParams.get_blockOuter(), fBaseParams.aicNum,
fBaseParams.coreNum);
OP_CHECK_IF(blockdim == 0,
OP_LOGE(context_,
"blockdim is 0, aicNum is %ld, aivNum is %ld.", fBaseParams.aicNum,
fBaseParams.coreNum),
return ge::GRAPH_FAILED);
context_->SetBlockDim(blockdim);
context_->SetScheduleMode(1);
tilingData.SaveToBuffer(context_->GetRawTilingData()->GetData(), context_->GetRawTilingData()->GetCapacity());
context_->GetRawTilingData()->SetDataSize(tilingData.GetDataSize());
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::SaveToTilingData()
{
tilingData.s1s2BNGS1S2BaseParams.set_coreNum(fBaseParams.coreNum);
tilingData.s1s2BNGS1S2BaseParams.set_b(fBaseParams.b);
tilingData.s1s2BNGS1S2BaseParams.set_n2(fBaseParams.n2);
tilingData.s1s2BNGS1S2BaseParams.set_g(fBaseParams.g);
tilingData.s1s2BNGS1S2BaseParams.set_s1(fBaseParams.s1);
tilingData.s1s2BNGS1S2BaseParams.set_d(fBaseParams.d);
tilingData.s1s2BNGS1S2BaseParams.set_s2(fBaseParams.s2);
tilingData.s1s2BNGS1S2BaseParams.set_pseOptional(fBaseParams.pseOptional);
tilingData.s1s2BNGS1S2BaseParams.set_pseType(fBaseParams.pseType);
tilingData.s1s2BNGS1S2BaseParams.set_pseShapeType(fBaseParams.pseShapeType);
tilingData.s1s2BNGS1S2BaseParams.set_pseDtype(fBaseParams.pseDtype);
tilingData.s1s2BNGS1S2BaseParams.set_attenMaskOptional(fBaseParams.attenMaskOptional);
tilingData.s1s2BNGS1S2BaseParams.set_attenMaskShapeType(fBaseParams.attenMaskShapeType);
tilingData.s1s2BNGS1S2BaseParams.set_attenMaskDtype(fBaseParams.attenMaskDtype);
tilingData.s1s2BNGS1S2BaseParams.set_scaleValue(fBaseParams.scaleValue);
tilingData.s1s2BNGS1S2BaseParams.set_keepProb(fBaseParams.keepProb);
tilingData.s1s2BNGS1S2BaseParams.set_s1Token(fBaseParams.s1Token > INT32_MAX ? INT32_MAX : fBaseParams.s1Token);
tilingData.s1s2BNGS1S2BaseParams.set_s2Token(fBaseParams.s2Token > INT32_MAX ? INT32_MAX : fBaseParams.s2Token);
tilingData.s1s2BNGS1S2BaseParams.set_sparseMode(fBaseParams.sparseMode);
tilingData.s1s2BNGS1S2BaseParams.set_isSparse(fBaseParams.isSparse);
tilingData.s1s2BNGS1S2BaseParams.set_attenMaskS2Size(fBaseParams.attenMaskS2Size);
tilingData.s1s2BNGS1S2BaseParams.set_attenMaskCompressMode(fBaseParams.attenMaskCompressMode);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1CvRatio(fBaseParams.s1CvRatio);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1Outer(fBaseParams.s1Outer);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1Inner(fBaseParams.s1Inner);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1CvInner(fBaseParams.s1CvInner);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1Tail(fBaseParams.s1Tail);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s1CvTail(fBaseParams.s1CvTail);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s2Outer(fBaseParams.s2Outer);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s2CvRatio(fBaseParams.s2CvRatio);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s2Inner(fBaseParams.s2Inner);
tilingData.s1s2BNGS1S2SplitCoreParams.set_s2Tail(fBaseParams.s2Tail);
tilingData.s1s2BNGS1S2SplitCoreParams.set_sfmgdOuter(fBaseParams.sfmgdOuter);
tilingData.s1s2BNGS1S2SplitCoreParams.set_sfmgdFactor(fBaseParams.sfmgdInner);
tilingData.s1s2BNGS1S2SplitCoreParams.set_sfmgdTail(fBaseParams.sfmgdTail);
tilingData.s1s2BNGS1S2SplitCoreParams.set_gInner(fBaseParams.gInner);
tilingData.s1s2BNGS1S2SplitCoreParams.set_gTail(fBaseParams.gTail);
tilingData.s1s2BNGS1S2SplitCoreParams.set_gOuter(fBaseParams.gOuter);
tilingData.s1s2BNGS1S2SplitCoreParams.set_bmmS1base(fBaseParams.bmmS1base);
tilingData.s1s2BNGS1S2SplitCoreParams.set_baseMN(fBaseParams.baseMN);
tilingData.s1s2BNGS1S2SplitCoreParams.set_bandIdx(fBaseParams.bandIdx);
tilingData.s1s2BNGS1S2BlockNumList.set_blockStarts(fBaseParams.blockStarts);
tilingData.s1s2BNGS1S2BlockNumList.set_blockEnds(fBaseParams.blockEnds);
tilingData.s1s2BNGS1S2SplitCoreParams.set_blockOuter(fBaseParams.blockOuter);
if (fBaseParams.pseType == PSE_INNER_MUL_ADD_TYPE ||
fBaseParams.pseType == PSE_INNER_MUL_ADD_SQRT_TYPE) {
tilingData.s1s2BNGS1S2BaseParams.set_pseAlibiBaseS1(fBaseParams.pseAlibiBaseS1);
tilingData.s1s2BNGS1S2BaseParams.set_pseAlibiBaseS2(fBaseParams.pseAlibiBaseS2);
}
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoPreTiling()
{
uint32_t castBufferLen = 60 * 1024;
uint32_t outputBufferLen = 30 * 1024;
uint32_t inputBufferLen = 4 * 1024;
int64_t singleUBProcessNum = castBufferLen / 2;
int64_t maskSize = AlignTo(fBaseParams.dropMaskSize, static_cast<int64_t>(BOOL_BLOCK_NUMS));
int64_t singleCoreNum = AlignTo(CeilCommon(maskSize, static_cast<int64_t>(fBaseParams.blockOuter)),
static_cast<int64_t>(BOOL_BLOCK_NUMS));
int64_t maskUsedCoreNum = static_cast<int64_t>(CeilCommon(maskSize, singleCoreNum));
int64_t tailCoreNum = maskSize - (maskUsedCoreNum - 1) * singleCoreNum;
tailCoreNum = AlignTo(tailCoreNum, static_cast<int64_t>(BOOL_BLOCK_NUMS));
int64_t singleCoreUBLoop = static_cast<int64_t>(CeilCommon(singleCoreNum, singleUBProcessNum));
int64_t tailCoreUBLoop = static_cast<int64_t>(CeilCommon(tailCoreNum, singleUBProcessNum));
int64_t singleCoreUBLastLoopNum = static_cast<int64_t>(singleCoreNum - (singleCoreUBLoop - 1) * singleUBProcessNum);
int64_t tailCoreUBLastLoopNum = static_cast<int64_t>(tailCoreNum - (tailCoreUBLoop - 1) * singleUBProcessNum);
tilingData.preTilingData.set_maskCoreNum(maskUsedCoreNum);
tilingData.preTilingData.set_castBufferLen(castBufferLen);
tilingData.preTilingData.set_outputBufferLen(outputBufferLen);
tilingData.preTilingData.set_inputBufferLen(inputBufferLen);
tilingData.preTilingData.set_singleUBProcessNum(static_cast<int64_t>(singleUBProcessNum));
tilingData.preTilingData.set_maskSingleCoreNum(singleCoreNum);
tilingData.preTilingData.set_maskSingleCoreLoop(singleCoreUBLoop);
tilingData.preTilingData.set_maskLastLoopNum(singleCoreUBLastLoopNum);
tilingData.preTilingData.set_maskTailCoreLoop(tailCoreUBLoop);
tilingData.preTilingData.set_maskTailCoreLastLoopNum(tailCoreUBLastLoopNum);
OP_CHECK_IF(maskUsedCoreNum == 0,
OP_LOGE(context_, "divisor maskUsedCoreNum is 0."),
return ge::GRAPH_FAILED);
int64_t qPreBlockFactor = (fBaseParams.qSizeAlign + maskUsedCoreNum - 1) / maskUsedCoreNum;
OP_CHECK_IF(qPreBlockFactor == 0,
OP_LOGE(context_, "divisor qPreBlockFactor is 0."),
return ge::GRAPH_FAILED);
int64_t qPreBlockTotal = (fBaseParams.qSizeAlign + qPreBlockFactor - 1) / qPreBlockFactor;
int64_t qPreTailNumTmp = fBaseParams.qSizeAlign % qPreBlockFactor;
int64_t qPreTailNum = qPreTailNumTmp == 0 ? qPreBlockFactor : qPreTailNumTmp;
int64_t kvPreBlockFactor = (fBaseParams.kvSizeAlign + maskUsedCoreNum - 1) / maskUsedCoreNum;
OP_CHECK_IF(kvPreBlockFactor == 0,
OP_LOGE(context_, "divisor kvPreBlockFactor is 0."),
return ge::GRAPH_FAILED);
int64_t kvPreBlockTotal = (fBaseParams.kvSizeAlign + kvPreBlockFactor - 1) / kvPreBlockFactor;
int64_t kvPreTailNumTmp = fBaseParams.kvSizeAlign % kvPreBlockFactor;
int64_t kvPreTailNum = kvPreTailNumTmp == 0 ? kvPreBlockFactor : kvPreTailNumTmp;
int64_t k1v1PreBlockFactor = (fBaseParams.k1v1SizeAlign + maskUsedCoreNum - 1) / maskUsedCoreNum;
OP_CHECK_IF(k1v1PreBlockFactor == 0,
OP_LOGE(context_, "divisor k1v1PreBlockFactor is 0."),
return ge::GRAPH_FAILED);
int64_t k1v1PreBlockTotal = (fBaseParams.k1v1SizeAlign + k1v1PreBlockFactor - 1) / k1v1PreBlockFactor;
int64_t k1v1PreTailNumTmp = fBaseParams.k1v1SizeAlign % k1v1PreBlockFactor;
int64_t k1v1PreTailNum = k1v1PreTailNumTmp == 0 ? k1v1PreBlockFactor : k1v1PreTailNumTmp;
int64_t maskPreBlockTotal = (fBaseParams.dropMaskSize);
tilingData.preTilingData.set_qPreBlockFactor(qPreBlockFactor);
tilingData.preTilingData.set_qPreBlockTotal(qPreBlockTotal);
tilingData.preTilingData.set_qPreBlockTail(qPreTailNum);
tilingData.preTilingData.set_kvPreBlockFactor(kvPreBlockFactor);
tilingData.preTilingData.set_kvPreBlockTotal(kvPreBlockTotal);
tilingData.preTilingData.set_kvPreBlockTail(kvPreTailNum);
tilingData.preTilingData.set_k1v1PreBlockFactor(k1v1PreBlockFactor);
tilingData.preTilingData.set_k1v1PreBlockTotal(k1v1PreBlockTotal);
tilingData.preTilingData.set_k1v1PreBlockTail(k1v1PreTailNum);
tilingData.preTilingData.set_dropoutIsDivisibleBy8(fBaseParams.dropoutIsDivisibleBy8);
tilingData.preTilingData.set_maskPreBlockTotal(maskPreBlockTotal);
int64_t dropBeginAddr = SYNC_GLOBAL_WORKSPACE_SIZE;
dropBeginAddr =
(dropBeginAddr + (fBaseParams.qSize) * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;
dropBeginAddr =
(dropBeginAddr + (fBaseParams.kvSize) * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;
dropBeginAddr =
(dropBeginAddr + (fBaseParams.kvSize) * sizeof(float) + ADDR_ALIGN_SIZE) / ADDR_ALIGN_SIZE * ADDR_ALIGN_SIZE;
tilingData.preTilingData.set_dropBeginAddr(dropBeginAddr);
return ge::GRAPH_SUCCESS;
}
ge::graphStatus FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DoPostTiling()
{
int64_t dAlign = (fBaseParams.d + FP16_BLOCK_NUMS - 1) / FP16_BLOCK_NUMS * FP16_BLOCK_NUMS;
int64_t curPostCoexNode = fBaseParams.mm2IsNZOut ? POST_NZ_COEX_NODE : POST_COEX_NODE;
int64_t nzReservedSize = fBaseParams.mm2IsNZOut ? dAlign / C0_SIZE * BLOCK_SIZE * POST_NZ_RESERVED_N : 0;
int64_t postUbBaseSize = (fBaseParams.ubSize - 2 * nzReservedSize) / curPostCoexNode / BUFFER_NUM /
WORKSPACE_NUM_ALIGN * WORKSPACE_NUM_ALIGN;
int64_t qPostBaseNum =
fBaseParams.mm2IsNZOut ? (postUbBaseSize / fBaseParams.dataTypeSize / dAlign * fBaseParams.d)
: (postUbBaseSize / fBaseParams.dataTypeSize);
OP_CHECK_IF(qPostBaseNum == 0,
OP_LOGE(context_, "divisor qPostBaseNum is 0."),
return ge::GRAPH_FAILED);
OP_CHECK_IF(fBaseParams.blockOuter == 0,
OP_LOGE(context_, "divisor fBaseParams.blockOuter is 0."),
return ge::GRAPH_FAILED);
int64_t qPostBlockTotal = fBaseParams.qSize;
int64_t qPostTailNumTmp = qPostBlockTotal % qPostBaseNum;
int64_t qPostTailNum = qPostTailNumTmp == 0 ? qPostBaseNum : qPostTailNumTmp;
int64_t qPostBlockOuterTotal = (qPostBlockTotal + qPostBaseNum - 1) / qPostBaseNum;
int64_t qPostBlockFactor = (qPostBlockOuterTotal + fBaseParams.blockOuter - 1) / fBaseParams.blockOuter;
int64_t kvPostBaseNum = qPostBaseNum;
OP_CHECK_IF(kvPostBaseNum == 0,
OP_LOGE(context_, "divisor kvPostBaseNum is 0."),
return ge::GRAPH_FAILED);
int64_t kvPostBlockTotal = fBaseParams.kvSize;
int64_t kvPostTailNumTmp = kvPostBlockTotal % kvPostBaseNum;
int64_t kvPostTailNum = kvPostTailNumTmp == 0 ? kvPostBaseNum : kvPostTailNumTmp;
int64_t kvPostBlockOuterTotal = (kvPostBlockTotal + kvPostBaseNum - 1) / kvPostBaseNum;
int64_t kvPostBlockFactor = (kvPostBlockOuterTotal + fBaseParams.blockOuter - 1) / fBaseParams.blockOuter;
int64_t k1v1PostBaseNum = qPostBaseNum;
OP_CHECK_IF(k1v1PostBaseNum == 0,
OP_LOGE(context_, "divisor k1v1PostBaseNum is 0."),
return ge::GRAPH_FAILED);
int64_t k1v1PostBlockTotal = fBaseParams.k1v1Size;
int64_t k1v1PostTailNumTmp = k1v1PostBlockTotal % k1v1PostBaseNum;
int64_t k1v1PostTailNum = k1v1PostTailNumTmp == 0 ? k1v1PostBaseNum : k1v1PostTailNumTmp;
int64_t k1v1PostBlockOuterTotal = (k1v1PostBlockTotal + k1v1PostBaseNum - 1) / k1v1PostBaseNum;
int64_t k1v1PostBlockFactor = (k1v1PostBlockOuterTotal + fBaseParams.blockOuter - 1) / fBaseParams.blockOuter;
tilingData.postTilingData.set_scaleValue(fBaseParams.scaleValue);
tilingData.postTilingData.set_coreNum(fBaseParams.coreNum);
tilingData.postTilingData.set_postUbBaseSize(postUbBaseSize);
tilingData.postTilingData.set_nzReservedSize(nzReservedSize);
tilingData.postTilingData.set_qPostBlockFactor(qPostBlockFactor);
tilingData.postTilingData.set_qPostBlockTotal(qPostBlockTotal);
tilingData.postTilingData.set_qPostBaseNum(qPostBaseNum);
tilingData.postTilingData.set_qPostTailNum(qPostTailNum);
tilingData.postTilingData.set_qSizeAlign(fBaseParams.qSizeAlign);
tilingData.postTilingData.set_kvPostBlockFactor(kvPostBlockFactor);
tilingData.postTilingData.set_kvPostBlockTotal(kvPostBlockTotal);
tilingData.postTilingData.set_kvPostBaseNum(kvPostBaseNum);
tilingData.postTilingData.set_kvPostTailNum(kvPostTailNum);
tilingData.postTilingData.set_kvSizeAlign(fBaseParams.kvSizeAlign);
tilingData.postTilingData.set_k1v1PostBlockFactor(k1v1PostBlockFactor);
tilingData.postTilingData.set_k1v1PostBlockTotal(k1v1PostBlockTotal);
tilingData.postTilingData.set_k1v1PostBaseNum(k1v1PostBaseNum);
tilingData.postTilingData.set_k1v1PostTailNum(k1v1PostTailNum);
tilingData.postTilingData.set_k1v1SizeAlign(fBaseParams.k1v1SizeAlign);
int64_t workspaceOffsets = MUL_CORE_SYNC_BUFFER;
tilingData.postTilingData.set_dqWorkSpaceOffset(workspaceOffsets);
workspaceOffsets = (workspaceOffsets + fBaseParams.qSizeAlign * sizeof(float) + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
tilingData.postTilingData.set_dkWorkSpaceOffset(workspaceOffsets);
workspaceOffsets = (workspaceOffsets + fBaseParams.kvSizeAlign * sizeof(float) + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
tilingData.postTilingData.set_dvWorkSpaceOffset(workspaceOffsets);
workspaceOffsets = (workspaceOffsets + fBaseParams.kvSizeAlign * sizeof(float) + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
tilingData.postTilingData.set_dk1WorkSpaceOffset(workspaceOffsets);
workspaceOffsets = (workspaceOffsets + fBaseParams.k1v1SizeAlign * sizeof(float) + GM_ALIGN) / GM_ALIGN * GM_ALIGN;
tilingData.postTilingData.set_dv1WorkSpaceOffset(workspaceOffsets);
tilingData.postTilingData.set_b(fBaseParams.b);
tilingData.postTilingData.set_n2(fBaseParams.n2);
tilingData.postTilingData.set_g(fBaseParams.g);
tilingData.postTilingData.set_s1(fBaseParams.s1);
tilingData.postTilingData.set_s2(fBaseParams.s2);
tilingData.postTilingData.set_d(fBaseParams.d);
return ge::GRAPH_SUCCESS;
}
void FusedFloydAttentionGradTilingS1s2Bn2gs1s2::DetermineMode()
{
if (fBaseParams.queryType == ge::DT_FLOAT) {
fBaseParams.mode = FP32;
} else if (fBaseParams.queryType == ge::DT_BF16) {
fBaseParams.mode = BF16;
} else if (fBaseParams.queryType == ge::DT_FLOAT16) {
fBaseParams.mode = INHP;
} else {
fBaseParams.mode = FP16;
}
}
REGISTER_OPS_TILING_TEMPLATE(FusedFloydAttentionGrad, FusedFloydAttentionGradTilingS1s2Bn2gs1s2, 16000);
}
}