Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include <iostream>
12 : #include <graph/utils/type_utils.h>
13 : #include "log/log.h"
14 : #include "platform/platform_ascendc.h"
15 : #include "register/op_def_registry.h"
16 : #include "register/tilingdata_base.h"
17 : #include "activation/fast_gelu/op_kernel/arch35/fast_gelu_dag.h"
18 : #include "activation/fast_gelu/op_kernel/arch35/fast_gelu_struct.h"
19 : #include "atvoss/elewise/elewise_tiling.h"
20 : #include "atvoss/broadcast/broadcast_tiling.h"
21 : #include "fast_gelu_tiling_arch35.h"
22 :
23 : using namespace FastGeluOp;
24 :
25 : namespace optiling {
26 : const int64_t SYSWORKSPACE = 16777216; // 16 * 1024 * 1024
27 :
28 : ge::graphStatus FastGeluTiling::CalcInputDtype()
29 : {
30 : auto inputDesc = tilingContext->GetInputDesc(0);
31 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, inputDesc);
32 : this->inputDtype = inputDesc->GetDataType();
33 : OP_CHECK_IF(
34 : this->inputDtype != ge::DT_FLOAT16 && this->inputDtype != ge::DT_BF16 && this->inputDtype != ge::DT_FLOAT,
35 : OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(
36 : tilingContext->GetNodeName(), "x",
37 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->inputDtype)),
38 : "The dtype of x must be DT_FLOAT16, DT_BF16, or DT_FLOAT"),
39 : return ge::GRAPH_FAILED);
40 : return ge::GRAPH_SUCCESS;
41 : }
42 :
43 : ge::graphStatus FastGeluTiling::CalcOutputDtype()
44 : {
45 : auto outputDesc = tilingContext->GetOutputDesc(0);
46 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outputDesc);
47 : this->outputDtype = outputDesc->GetDataType();
48 : OP_CHECK_IF(
49 : this->outputDtype != ge::DT_FLOAT16 && this->outputDtype != ge::DT_BF16 && this->outputDtype != ge::DT_FLOAT,
50 : OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(
51 : tilingContext->GetNodeName(), "y",
52 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->outputDtype)),
53 : "The dtype of y must be DT_FLOAT16, DT_BF16, or DT_FLOAT"),
54 : return ge::GRAPH_FAILED);
55 : OP_CHECK_IF(this->outputDtype != this->inputDtype,
56 : OP_LOGE_FOR_INVALID_DTYPES_WITH_REASON(
57 : tilingContext->GetNodeName(), "x, y",
58 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->inputDtype)) + ", " +
59 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->outputDtype)),
60 : "The dtypes of x and y must be the same"),
61 : return ge::GRAPH_FAILED);
62 : return ge::GRAPH_SUCCESS;
63 : }
64 :
65 : ge::graphStatus FastGeluTiling::CheckShape()
66 : {
67 : auto selfStorageShape = tilingContext->GetInputShape(0);
68 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, selfStorageShape);
69 : const gert::Shape& inputShape = Ops::Base::EnsureNotScalar(selfStorageShape->GetStorageShape());
70 :
71 : auto outStorageShape = tilingContext->GetOutputShape(0);
72 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outStorageShape);
73 : const gert::Shape& outputShape = Ops::Base::EnsureNotScalar(outStorageShape->GetStorageShape());
74 :
75 : OP_CHECK_IF(inputShape != outputShape,
76 : OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON(
77 : tilingContext->GetNodeName(), "x, y",
78 : Ops::Base::ToString(inputShape) + ", " + Ops::Base::ToString(outputShape),
79 : "The shapes of x and y must be the same"),
80 : return ge::GRAPH_FAILED);
81 : return ge::GRAPH_SUCCESS;
82 : }
83 :
84 : std::string FastGeluTiling::DataTypeToSerialString(const ge::DataType type) const
85 : {
86 : const auto it = DATATYPE_TO_STRING_MAP.find(type);
87 : if (it != DATATYPE_TO_STRING_MAP.end()) {
88 : return it->second;
89 : } else {
90 : OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(tilingContext->GetNodeName(), "x",
91 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(type)),
92 : "The dtype of x must be DT_FLOAT16, DT_BF16, or DT_FLOAT");
93 : return "UNDEFINED";
94 : }
95 : }
96 :
97 : ge::graphStatus FastGeluTiling::RunTiling()
98 : {
99 : ElewiseBaseTiling elewiseBaseTiling(tilingContext);
100 : // 获取tiling计算所需的参数
101 : ge::graphStatus status = ge::GRAPH_FAILED;
102 : status = CalcInputDtype();
103 : OP_CHECK_IF(status == ge::GRAPH_FAILED, OP_LOGE(tilingContext, "get input dtype failed"), return ge::GRAPH_FAILED);
104 : status = CalcOutputDtype();
105 : OP_CHECK_IF(status == ge::GRAPH_FAILED, OP_LOGE(tilingContext, "get output dtype failed"), return ge::GRAPH_FAILED);
106 : status = CheckShape();
107 : OP_CHECK_IF(status == ge::GRAPH_FAILED, OP_LOGE(tilingContext, "check shape failed"), return ge::GRAPH_FAILED);
108 :
109 : auto tiling = tilingContext->GetTilingData<EleBaseTilingDataV2>();
110 : OP_CHECK_IF((tiling == nullptr), OP_LOGE(tilingContext->GetNodeName(), "Get FastGeluTiling from GE context failed"),
111 : return ge::GRAPH_FAILED);
112 : if (this->outputDtype == ge::DT_FLOAT16) {
113 : dType = TPL_FP16;
114 : status = elewiseBaseTiling.DoTiling<FastGeluDag::FastGeluNeedCast<half>::OpDag>(*tiling);
115 : } else if (this->outputDtype == ge::DT_BF16) {
116 : dType = TPL_BF16;
117 : status = elewiseBaseTiling.DoTiling<FastGeluDag::FastGeluNeedCast<bfloat16_t>::OpDag>(*tiling);
118 : } else if (this->outputDtype == ge::DT_FLOAT) {
119 : dType = TPL_FP32;
120 : status = elewiseBaseTiling.DoTiling<FastGeluDag::FastGeluNoCast<float>::OpDag>(*tiling);
121 : } else {
122 : OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON(
123 : tilingContext->GetNodeName(), "y",
124 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->outputDtype)),
125 : "The dtype of y must be DT_FLOAT16, DT_BF16, or DT_FLOAT");
126 : return ge::GRAPH_FAILED;
127 : }
128 7 : OP_CHECK_IF(status == ge::GRAPH_FAILED,
129 : OP_LOGE(tilingContext->GetNodeName(), "elewiseBaseTiling failed, output dtype: %s.",
130 : ge::TypeUtils::DataTypeToSerialString(static_cast<ge::DataType>(this->outputDtype)).c_str()),
131 : return ge::GRAPH_FAILED);
132 : const uint64_t tilingKey = GET_TPL_TILING_KEY(tiling->scheMode, dType);
133 : OP_LOGD(tilingContext->GetNodeName(), "[TilingData] : tilingKey=%ld.", tilingKey);
134 : tilingContext->SetTilingKey(tilingKey);
135 : tilingContext->SetBlockDim(tiling->blockNum);
136 : size_t usrWorkspaceSize = 0;
137 : size_t sysWorkspaceSize = SYSWORKSPACE;
138 : size_t* currentWorkspace = tilingContext->GetWorkspaceSizes(1);
139 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, currentWorkspace);
140 : currentWorkspace[0] = sysWorkspaceSize + usrWorkspaceSize;
141 : return ge::GRAPH_SUCCESS;
142 : }
143 :
144 : static ge::graphStatus TilingFuncFastGelu(gert::TilingContext* tilingContext)
145 : {
146 : auto compileInfo = tilingContext->GetCompileInfo<ElewiseCompileInfo>();
147 : OP_CHECK_NULL_WITH_CONTEXT(tilingContext, compileInfo);
148 :
149 : OP_LOGD(tilingContext->GetNodeName(), "START FastGelu AscendC Tiling \n");
150 : FastGeluTiling FastGeluTiling(tilingContext);
151 : return FastGeluTiling.RunTiling();
152 : }
153 :
154 : ge::graphStatus TilingPrepareForFastGelu([[maybe_unused]] gert::TilingParseContext* context)
155 : {
156 : return ge::GRAPH_SUCCESS;
157 : }
158 :
159 : IMPL_OP_OPTILING(FastGelu).Tiling(TilingFuncFastGelu).TilingParse<ElewiseCompileInfo>(TilingPrepareForFastGelu);
160 : } // namespace optiling
|