已合并
fix cleancode include:assign,mem_set,split_v,tensor_move,adds,power #5264
csz创建于 18 天前
fix cleancode include:assign,mem_set,split_v,tensor_move,adds,power #5264
已合并
共 7 个文件变更+114-201
| @@ -185,7 +185,7 @@ static ge::graphStatus AssignTilingForAscendC(gert::TilingContext* context) | |||
| 185 | OP_CHECK_IF(CheckShapeForAssign(context, tilingParam) != ge::GRAPH_SUCCESS, | 185 | OP_CHECK_IF(CheckShapeForAssign(context, tilingParam) != ge::GRAPH_SUCCESS, |
| 186 | OP_LOGE(context->GetNodeName(), "The shape check failed."), return ge::GRAPH_FAILED); | 186 | OP_LOGE(context->GetNodeName(), "The shape check failed."), return ge::GRAPH_FAILED); |
| 187 | 187 | ||
| 188 | - auto compileInfo = reinterpret_cast<const AssignCompileInfo*>(context->GetCompileInfo()); | 188 | + auto compileInfo = context->GetCompileInfo<AssignCompileInfo>(); |
| 189 | OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo); | 189 | OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo); |
| 190 | 190 | ||
| 191 | tilingParam.totalCoreNum = compileInfo->coreNum; | 191 | tilingParam.totalCoreNum = compileInfo->coreNum; |
| @@ -29,6 +29,9 @@ std::set<ge::DataType> SUPPORT_TYPE_LIST = {ge::DT_INT8, ge::DT_INT32, ge::DT_ | |||
| 29 | std::set<ge::DataType> SUPPORT_TYPE_INT_LIST = {ge::DT_INT8, ge::DT_INT32, ge::DT_UINT8, ge::DT_INT16, | 29 | std::set<ge::DataType> SUPPORT_TYPE_INT_LIST = {ge::DT_INT8, ge::DT_INT32, ge::DT_UINT8, ge::DT_INT16, |
| 30 | ge::DT_UINT16, ge::DT_UINT32, ge::DT_INT64, ge::DT_UINT64}; | 30 | ge::DT_UINT16, ge::DT_UINT32, ge::DT_INT64, ge::DT_UINT64}; |
| 31 | constexpr uint64_t BLOCK_SIZE = 512; | 31 | constexpr uint64_t BLOCK_SIZE = 512; |
| 32 | +constexpr int TILING_COUNTS[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64, 128, 192, 256}; | ||
| 33 | +constexpr size_t TILING_COUNTS_NUM = sizeof(TILING_COUNTS) / sizeof(TILING_COUNTS[0]); | ||
| 34 | +constexpr int MAX_TILING_COUNT = TILING_COUNTS[TILING_COUNTS_NUM - 1]; | ||
| 32 | 35 | ||
| 33 | template <uint16_t Count> | 36 | template <uint16_t Count> |
| 34 | void MemSetTilingClass::CheckTilingData(MemSetTilingData<Count>* tilingDataPostAtr) | 37 | void MemSetTilingClass::CheckTilingData(MemSetTilingData<Count>* tilingDataPostAtr) |
| @@ -69,82 +72,28 @@ void MemSetTilingClass::PostDo() | |||
| 69 | CheckTilingData<Count>(tilingDataPostAtr); | 72 | CheckTilingData<Count>(tilingDataPostAtr); |
| 70 | } | 73 | } |
| 71 | 74 | ||
| 75 | +template <size_t Idx> | ||
| 76 | +void MemSetTilingClass::DispatchPostDo(size_t targetIdx) | ||
| 77 | +{ | ||
| 78 | + if (targetIdx == Idx) { | ||
| 79 | + PostDo<static_cast<uint16_t>(TILING_COUNTS[Idx])>(); | ||
| 80 | + return; | ||
| 81 | + } | ||
| 82 | + if constexpr (Idx + 1 < TILING_COUNTS_NUM) { | ||
| 83 | + DispatchPostDo<Idx + 1>(targetIdx); | ||
| 84 | + } | ||
| 85 | +} | ||
| 86 | + | ||
| 72 | ge::graphStatus MemSetTilingClass::PostTiling() | 87 | ge::graphStatus MemSetTilingClass::PostTiling() |
| 73 | { | 88 | { |
| 74 | - // Different sizes of tiling data templates | 89 | + if (inputCount_ > MAX_TILING_COUNT) { |
| 75 | - const std::vector<int> validNums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64, 128, 192, 256}; | ||
| 76 | - if (inputCount_ > validNums.back()) { | ||
| 77 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context_->GetNodeName(), "TensorNum", std::to_string(inputCount_).c_str(), | 90 | OP_LOGE_FOR_INVALID_VALUE_WITH_REASON(context_->GetNodeName(), "TensorNum", std::to_string(inputCount_).c_str(), |
| 78 | "The value of TensorNum must be within the range [1, 256]."); | 91 | "The value of TensorNum must be within the range [1, 256]."); |
| 79 | return ge::GRAPH_FAILED; | 92 | return ge::GRAPH_FAILED; |
| 80 | } | 93 | } |
| 81 | - auto it = std::lower_bound(validNums.begin(), validNums.end(), inputCount_); | 94 | + auto it = std::lower_bound(TILING_COUNTS, TILING_COUNTS + TILING_COUNTS_NUM, static_cast<int>(inputCount_)); |
| 82 | - int targetNum = *it; | 95 | + size_t targetIdx = static_cast<size_t>(std::distance(TILING_COUNTS, it)); |
| 83 | - switch (targetNum) { | 96 | + DispatchPostDo<0>(targetIdx); |
| 84 | - case 1: | ||
| 85 | - PostDo<1>(); | ||
| 86 | - break; | ||
| 87 | - case 2: | ||
| 88 | - PostDo<2>(); | ||
| 89 | - break; | ||
| 90 | - case 3: | ||
| 91 | - PostDo<3>(); | ||
| 92 | - break; | ||
| 93 | - case 4: | ||
| 94 | - PostDo<4>(); | ||
| 95 | - break; | ||
| 96 | - case 5: | ||
| 97 | - PostDo<5>(); | ||
| 98 | - break; | ||
| 99 | - case 6: | ||
| 100 | - PostDo<6>(); | ||
| 101 | - break; | ||
| 102 | - case 7: | ||
| 103 | - PostDo<7>(); | ||
| 104 | - break; | ||
| 105 | - case 8: | ||
| 106 | - PostDo<8>(); | ||
| 107 | - break; | ||
| 108 | - case 9: | ||
| 109 | - PostDo<9>(); | ||
| 110 | - break; | ||
| 111 | - case 10: | ||
| 112 | - PostDo<10>(); | ||
| 113 | - break; | ||
| 114 | - case 11: | ||
| 115 | - PostDo<11>(); | ||
| 116 | - break; | ||
| 117 | - case 12: | ||
| 118 | - PostDo<12>(); | ||
| 119 | - break; | ||
| 120 | - case 13: | ||
| 121 | - PostDo<13>(); | ||
| 122 | - break; | ||
| 123 | - case 14: | ||
| 124 | - PostDo<14>(); | ||
| 125 | - break; | ||
| 126 | - case 15: | ||
| 127 | - PostDo<15>(); | ||
| 128 | - break; | ||
| 129 | - case 16: | ||
| 130 | - PostDo<16>(); | ||
| 131 | - break; | ||
| 132 | - case 32: | ||
| 133 | - PostDo<32>(); | ||
| 134 | - break; | ||
| 135 | - case 64: | ||
| 136 | - PostDo<64>(); | ||
| 137 | - break; | ||
| 138 | - case 128: | ||
| 139 | - PostDo<128>(); | ||
| 140 | - break; | ||
| 141 | - case 196: | ||
| 142 | - PostDo<196>(); | ||
| 143 | - break; | ||
| 144 | - case 256: | ||
| 145 | - PostDo<256>(); | ||
| 146 | - break; | ||
| 147 | - } | ||
| 148 | context_->SetBlockDim(aicoreParams_.numBlocks); | 97 | context_->SetBlockDim(aicoreParams_.numBlocks); |
| 149 | return ge::GRAPH_SUCCESS; | 98 | return ge::GRAPH_SUCCESS; |
| 150 | } | 99 | } |
| @@ -22,7 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | - | ||
| 26 | namespace optiling { | 25 | namespace optiling { |
| 27 | 26 | ||
| 28 | struct MemSetCompileInfoArch35 { | 27 | struct MemSetCompileInfoArch35 { |
| @@ -32,26 +31,16 @@ struct MemSetCompileInfoArch35 { | |||
| 32 | 31 | ||
| 33 | class MemSetTilingClass : public Ops::Base::TilingBaseClass { | 32 | class MemSetTilingClass : public Ops::Base::TilingBaseClass { |
| 34 | public: | 33 | public: |
| 35 | - explicit MemSetTilingClass(gert::TilingContext* context) : Ops::Base::TilingBaseClass(context) | 34 | + explicit MemSetTilingClass(gert::TilingContext* context) : Ops::Base::TilingBaseClass(context) {} |
| 36 | - {} | ||
| 37 | 35 | ||
| 38 | - void Reset(gert::TilingContext* context) override | 36 | + void Reset(gert::TilingContext* context) override { Ops::Base::TilingBaseClass::Reset(context); } |
| 39 | - { | ||
| 40 | - Ops::Base::TilingBaseClass::Reset(context); | ||
| 41 | - } | ||
| 42 | 37 | ||
| 43 | protected: | 38 | protected: |
| 44 | ge::graphStatus GetShapeAttrsInfo() override; | 39 | ge::graphStatus GetShapeAttrsInfo() override; |
| 45 | ge::graphStatus GetPlatformInfo() override; | 40 | ge::graphStatus GetPlatformInfo() override; |
| 46 | - bool IsCapable() override | 41 | + bool IsCapable() override { return true; } |
| 47 | - { | ||
| 48 | - return true; | ||
| 49 | - } | ||
| 50 | ge::graphStatus DoOpTiling() override; | 42 | ge::graphStatus DoOpTiling() override; |
| 51 | - ge::graphStatus DoLibApiTiling() override | 43 | + ge::graphStatus DoLibApiTiling() override { return ge::GRAPH_SUCCESS; } |
| 52 | - { | ||
| 53 | - return ge::GRAPH_SUCCESS; | ||
| 54 | - } | ||
| 55 | ge::graphStatus GetWorkspaceSize() override; | 44 | ge::graphStatus GetWorkspaceSize() override; |
| 56 | ge::graphStatus PostTiling() override; | 45 | ge::graphStatus PostTiling() override; |
| 57 | uint64_t GetTilingKey() const override; | 46 | uint64_t GetTilingKey() const override; |
| @@ -63,22 +52,24 @@ private: | |||
| 63 | void PostDo(); | 52 | void PostDo(); |
| 64 | template <uint16_t Count> | 53 | template <uint16_t Count> |
| 65 | void CheckTilingData(MemSetTilingData<Count>* tilingDataPostAtr); | 54 | void CheckTilingData(MemSetTilingData<Count>* tilingDataPostAtr); |
| 55 | + template <size_t Idx> | ||
| 56 | + void DispatchPostDo(size_t targetIdx); | ||
| 66 | 57 | ||
| 67 | -private: | 58 | +private: |
| 68 | - void* tilingDataPostAtr_ = nullptr; | 59 | + void* tilingDataPostAtr_ = nullptr; |
| 69 | - std::vector<int64_t> perCoreSizes_; | 60 | + std::vector<int64_t> perCoreSizes_; |
| 70 | - std::vector<int64_t> lastCoreSizes_; | 61 | + std::vector<int64_t> lastCoreSizes_; |
| 71 | - std::vector<int64_t> intValue_; | 62 | + std::vector<int64_t> intValue_; |
| 72 | - std::vector<float> floatValue_; | 63 | + std::vector<float> floatValue_; |
| 73 | - std::vector<int16_t> listType_; | 64 | + std::vector<int16_t> listType_; |
| 74 | - std::vector<int16_t> useCore_; | 65 | + std::vector<int16_t> useCore_; |
| 75 | - std::vector<int64_t> sizes_; | 66 | + std::vector<int64_t> sizes_; |
| 76 | - uint16_t cacheLineSize_ = 0; | 67 | + uint16_t cacheLineSize_ = 0; |
| 77 | - uint16_t needCore_ = 0; | 68 | + uint16_t needCore_ = 0; |
| 78 | - int halfUbSize_ = 0; | 69 | + int halfUbSize_ = 0; |
| 79 | - uint16_t inputCount_ = 0; | 70 | + uint16_t inputCount_ = 0; |
| 80 | - uint16_t TilingKey_ = 0; | 71 | + uint16_t TilingKey_ = 0; |
| 81 | - bool isDynamic_ = false; | 72 | + bool isDynamic_ = false; |
| 82 | }; | 73 | }; |
| 83 | 74 | ||
| 84 | } // namespace optiling | 75 | } // namespace optiling |
| @@ -90,22 +81,16 @@ public: | |||
| 90 | * Get workspaceSize list | 81 | * Get workspaceSize list |
| 91 | * @return workspaceSize list | 82 | * @return workspaceSize list |
| 92 | */ | 83 | */ |
| 93 | - const gert::ContinuousVector* GetCleanWorkspaceSizes() const | 84 | + const gert::ContinuousVector* GetCleanWorkspaceSizes() const { return GetInputPointer<gert::ContinuousVector>(0); } |
| 94 | - { | ||
| 95 | - return GetInputPointer<gert::ContinuousVector>(0); | ||
| 96 | - } | ||
| 97 | 85 | ||
| 98 | /** | 86 | /** |
| 99 | * Get the size of the output memory to be cleared by the output index | 87 | * Get the size of the output memory to be cleared by the output index |
| 100 | * @param index output index | 88 | * @param index output index |
| 101 | * @return Size of output memory to be cleaned | 89 | * @return Size of output memory to be cleaned |
| 102 | */ | 90 | */ |
| 103 | - uint64_t GetCleanOutputSize(size_t index) const | 91 | + uint64_t GetCleanOutputSize(size_t index) const { return GetInputValue<uint64_t>(index + 1U); } |
| 104 | - { | ||
| 105 | - return GetInputValue<uint64_t>(index + 1U); | ||
| 106 | - } | ||
| 107 | }; | 92 | }; |
| 108 | -static_assert( | 93 | +static_assert(std::is_standard_layout<AtomicCleanTilingContext>::value, |
| 109 | - std::is_standard_layout<AtomicCleanTilingContext>::value, "The class AtomicCleanTilingContext must be a POD"); | 94 | + "The class AtomicCleanTilingContext must be a POD"); |
| 110 | } // namespace ops | 95 | } // namespace ops |
| 111 | -#endif | 96 | +#endif |
| @@ -74,6 +74,14 @@ constexpr int64_t SIMT_CHUNK_TOTAL_ELEM_THRESHOLD = 131072; // 1024 block * 128 | |||
| 74 | constexpr int64_t SIMT_REJECT_RELATIVE_SKEW_UPPER = 16; // SIMT拒绝后回退Chunk的相对偏差上界 | 74 | constexpr int64_t SIMT_REJECT_RELATIVE_SKEW_UPPER = 16; // SIMT拒绝后回退Chunk的相对偏差上界 |
| 75 | constexpr int64_t SIMT_REJECT_ABSOLUTE_SKEW_UPPER = 2048; // SIMT拒绝后回退Chunk的绝对偏差上界 | 75 | constexpr int64_t SIMT_REJECT_ABSOLUTE_SKEW_UPPER = 2048; // SIMT拒绝后回退Chunk的绝对偏差上界 |
| 76 | 76 | ||
| 77 | +// IsDoSplitVSIMT 强制走 SIMT 的特定输入 shape [256, 16] 及 numSplit 上限 | ||
| 78 | +constexpr size_t SIMT_FORCE_INPUT_DIM_NUM = 2; | ||
| 79 | +constexpr int64_t SIMT_FORCE_INPUT_DIM0 = 256; | ||
| 80 | +constexpr int64_t SIMT_FORCE_INPUT_DIM1 = 16; | ||
| 81 | +constexpr int64_t SIMT_FORCE_MAX_NUM_SPLIT = 16; | ||
| 82 | +// host 侧 uint64 fast-div 计算中的 uint64 位宽 | ||
| 83 | +constexpr int64_t UINT64_BIT_WIDTH = 64; | ||
| 84 | + | ||
| 77 | template <typename T> | 85 | template <typename T> |
| 78 | std::string SplitVTiling::ArrayToString(const T* vec, size_t num) const | 86 | std::string SplitVTiling::ArrayToString(const T* vec, size_t num) const |
| 79 | { | 87 | { |
| @@ -893,8 +901,8 @@ bool SplitVTiling::IsDoSplitVSIMT(int32_t maxCoreNum) | |||
| 893 | if (isSameLenMode_) { | 901 | if (isSameLenMode_) { |
| 894 | return false; | 902 | return false; |
| 895 | } | 903 | } |
| 896 | - if (inputShape_.GetDimNum() == 2 && inputShape_.GetDim(0) == 256 && inputShape_.GetDim(1) == 16 && splitDim_ == 1 && | 904 | + if (inputShape_.GetDimNum() == SIMT_FORCE_INPUT_DIM_NUM && inputShape_.GetDim(0) == SIMT_FORCE_INPUT_DIM0 && |
| 897 | - numSplit_ <= 16) { | 905 | + inputShape_.GetDim(1) == SIMT_FORCE_INPUT_DIM1 && splitDim_ == 1 && numSplit_ <= SIMT_FORCE_MAX_NUM_SPLIT) { |
| 898 | CalInputDataSize(); | 906 | CalInputDataSize(); |
| 899 | OP_LOGI(context_->GetNodeName(), "Force SIMT for shape [256, 16]"); | 907 | OP_LOGI(context_->GetNodeName(), "Force SIMT for shape [256, 16]"); |
| 900 | return true; | 908 | return true; |
| @@ -1034,19 +1042,19 @@ static inline void HostGetUintDivMagicAndShift64(uint64_t& magic, uint32_t& shif | |||
| 1034 | shift = 0; | 1042 | shift = 0; |
| 1035 | return; | 1043 | return; |
| 1036 | } | 1044 | } |
| 1037 | - // pos = 64 - clz(divisor) = floor(log2(divisor)) + 1 | 1045 | + // pos = UINT64_BIT_WIDTH - clz(divisor) = floor(log2(divisor)) + 1 |
| 1038 | - int64_t pos = 64 - static_cast<int64_t>(__builtin_clzll(divisor)); | 1046 | + int64_t pos = UINT64_BIT_WIDTH - static_cast<int64_t>(__builtin_clzll(divisor)); |
| 1039 | int64_t cnt1 = static_cast<int64_t>(__builtin_popcountll(divisor)); | 1047 | int64_t cnt1 = static_cast<int64_t>(__builtin_popcountll(divisor)); |
| 1040 | shift = (cnt1 == 1) ? static_cast<uint32_t>(pos - 1) : static_cast<uint32_t>(pos); | 1048 | shift = (cnt1 == 1) ? static_cast<uint32_t>(pos - 1) : static_cast<uint32_t>(pos); |
| 1041 | uint64_t dividend = 0; | 1049 | uint64_t dividend = 0; |
| 1042 | - if (shift < 64) { | 1050 | + if (shift < UINT64_BIT_WIDTH) { |
| 1043 | dividend = (1ULL << shift) - divisor; | 1051 | dividend = (1ULL << shift) - divisor; |
| 1044 | } else { | 1052 | } else { |
| 1045 | - // shift == 64, 2^64 - divisor | 1053 | + // shift == UINT64_BIT_WIDTH, 2^64 - divisor |
| 1046 | dividend = 0xFFFFFFFFFFFFFFFFULL - divisor + 1; | 1054 | dividend = 0xFFFFFFFFFFFFFFFFULL - divisor + 1; |
| 1047 | } | 1055 | } |
| 1048 | // magic = floor(2^64 * dividend / divisor) + 1 | 1056 | // magic = floor(2^64 * dividend / divisor) + 1 |
| 1049 | - __uint128_t num = (static_cast<__uint128_t>(dividend) << 64); | 1057 | + __uint128_t num = (static_cast<__uint128_t>(dividend) << UINT64_BIT_WIDTH); |
| 1050 | magic = static_cast<uint64_t>(num / divisor) + 1; | 1058 | magic = static_cast<uint64_t>(num / divisor) + 1; |
| 1051 | } | 1059 | } |
| 1052 | 1060 | ||
| @@ -1103,12 +1111,9 @@ void SplitVTiling::DoSplitVSIMTChunkPreTiling(int32_t maxCoreNum) | |||
| 1103 | // diff >= 0 (欠分配): 差值全部补到拷贝量最大的 output | 1111 | // diff >= 0 (欠分配): 差值全部补到拷贝量最大的 output |
| 1104 | // diff < 0 (超分配): 按拷贝量降序逐个扣减, 每个非空 output 保留至少 1 块, 避免下游 q=total/blkCnt 除零 | 1112 | // diff < 0 (超分配): 按拷贝量降序逐个扣减, 每个非空 output 保留至少 1 块, 避免下游 q=total/blkCnt 除零 |
| 1105 | if (maxCopyIdx >= 0) { | 1113 | if (maxCopyIdx >= 0) { |
| 1106 | - // int32_t diff = logicBlockNum_ - blkSum; | ||
| 1107 | int32_t diff = maxLogicBlockByCore - blkSum; | 1114 | int32_t diff = maxLogicBlockByCore - blkSum; |
| 1108 | if (diff >= 0) { | 1115 | if (diff >= 0) { |
| 1109 | - // blockPrefixBuf_[maxCopyIdx] = static_cast<uint32_t>(static_cast<int32_t>(blockPrefixBuf_[maxCopyIdx]) + | 1116 | + realCoreNum_ = CeilDiv(blkSum, LOGIC_BLOCK_PER_CORE); |
| 1110 | - // diff); | ||
| 1111 | - realCoreNum_ = CeilDiv(blkSum, 16); | ||
| 1112 | } else { | 1117 | } else { |
| 1113 | int32_t need = -diff; | 1118 | int32_t need = -diff; |
| 1114 | // 收集可扣减的输出(blk > 1), 按拷贝量 M*wi 降序排序后贪心扣减 | 1119 | // 收集可扣减的输出(blk > 1), 按拷贝量 M*wi 降序排序后贪心扣减 |
| @@ -1175,7 +1180,6 @@ void SplitVTiling::DoSplitVSIMTChunkPreTiling(int32_t maxCoreNum) | |||
| 1175 | } | 1180 | } |
| 1176 | 1181 | ||
| 1177 | // 5) 1024 逻辑 block = 64 核 * 16 | 1182 | // 5) 1024 逻辑 block = 64 核 * 16 |
| 1178 | - // realCoreNum_ = std::min(maxCoreNum, SIMT_VECTOR_CORE_NUM); | ||
| 1179 | blockDim_ = realCoreNum_; | 1183 | blockDim_ = realCoreNum_; |
| 1180 | tilingKey_ = SIMT_CHUNK_KEY; | 1184 | tilingKey_ = SIMT_CHUNK_KEY; |
| 1181 | 1185 | ||
| @@ -1226,11 +1230,6 @@ ge::graphStatus SplitVTiling::DoSplitVTiling(int32_t maxCoreNum, uint32_t ubSize | |||
| 1226 | if (IsDoSplitVSIMT(maxCoreNum)) { | 1230 | if (IsDoSplitVSIMT(maxCoreNum)) { |
| 1227 | return DoSplitVSIMTTiling(maxCoreNum); | 1231 | return DoSplitVSIMTTiling(maxCoreNum); |
| 1228 | } | 1232 | } |
| 1229 | - // if (IsFallbackToChunk()) { | ||
| 1230 | - // DoSplitVSIMTChunkPreTiling(maxCoreNum); | ||
| 1231 | - // // DoSplitVSIMTChunkTiling(maxCoreNum); | ||
| 1232 | - // return ge::GRAPH_SUCCESS; | ||
| 1233 | - // } | ||
| 1234 | if (numSplit_ != 0 && numSplit_ != 1 && isSameLenMode_) { | 1233 | if (numSplit_ != 0 && numSplit_ != 1 && isSameLenMode_) { |
| 1235 | // SamLenMode fuse to [M G N] | 1234 | // SamLenMode fuse to [M G N] |
| 1236 | FuseInputShapeSameLen(); | 1235 | FuseInputShapeSameLen(); |
| @@ -1476,7 +1475,6 @@ void SplitVTiling::CalcSameLenSplitTilingInfo(int64_t halfUbEleNum, int64_t bloc | |||
| 1476 | int64_t newGBF = 0, newGBCount = 0, newGBFT = 0; | 1475 | int64_t newGBF = 0, newGBCount = 0, newGBFT = 0; |
| 1477 | int64_t newTiles = 0; | 1476 | int64_t newTiles = 0; |
| 1478 | bool smallGAvail = FloorAlign(factorTmp, blockEleNum) >= numSplit_; | 1477 | bool smallGAvail = FloorAlign(factorTmp, blockEleNum) >= numSplit_; |
| 1479 | - | ||
| 1480 | if (smallGAvail) { | 1478 | if (smallGAvail) { |
| 1481 | newGBF = numSplit_; | 1479 | newGBF = numSplit_; |
| 1482 | int64_t tmp = FloorAlign(halfUbEleNum / fusedShape_[1] / newGBF, blockEleNum); | 1480 | int64_t tmp = FloorAlign(halfUbEleNum / fusedShape_[1] / newGBF, blockEleNum); |
| @@ -186,7 +186,7 @@ static ge::graphStatus Tiling4TensorMove(gert::TilingContext* context) | |||
| 186 | OP_CHECK_IF(CheckTensorMoveShape(context) != ge::GRAPH_SUCCESS, | 186 | OP_CHECK_IF(CheckTensorMoveShape(context) != ge::GRAPH_SUCCESS, |
| 187 | OP_LOGE(context->GetNodeName(), "The shape check failed."), return ge::GRAPH_FAILED); | 187 | OP_LOGE(context->GetNodeName(), "The shape check failed."), return ge::GRAPH_FAILED); |
| 188 | 188 | ||
| 189 | - auto compileInfo = reinterpret_cast<const TensorMoveCompileInfo*>(context->GetCompileInfo()); | 189 | + auto compileInfo = context->GetCompileInfo<TensorMoveCompileInfo>(); |
| 190 | OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo); | 190 | OP_CHECK_NULL_WITH_CONTEXT(context, compileInfo); |
| 191 | 191 | ||
| 192 | TensorMoveTilingParam tilingParam; | 192 | TensorMoveTilingParam tilingParam; |
| @@ -16,32 +16,25 @@ | |||
| 16 | * | 16 | * |
| 17 | * 数据流(bf16/fp16/int16/int32/int64): | 17 | * 数据流(bf16/fp16/int16/int32/int64): |
| 18 | * input (GM) -> CopyIn<T> -> Cast<T,float> -> Adds<float,scalar> -> Cast<float,T> -> CopyOut<T> -> output (GM) | 18 | * input (GM) -> CopyIn<T> -> Cast<T,float> -> Adds<float,scalar> -> Cast<float,T> -> CopyOut<T> -> output (GM) |
| 19 | - * | 19 | + * |
| 20 | * 数据流(fp32): | 20 | * 数据流(fp32): |
| 21 | * input (GM) -> CopyIn<float> -> Adds<float,scalar> -> CopyOut<float> -> output (GM) | 21 | * input (GM) -> CopyIn<float> -> Adds<float,scalar> -> CopyOut<float> -> output (GM) |
| 22 | * (Cast fp32→fp32会被模板优化掉) | 22 | * (Cast fp32→fp32会被模板优化掉) |
| 23 | - * | 23 | + * |
| 24 | * 标量参数通过 Placeholder::Var<float, 0> 占位,Kernel 入口通过 SetVar<float, 0>(value) 注入 | 24 | * 标量参数通过 Placeholder::Var<float, 0> 占位,Kernel 入口通过 SetVar<float, 0>(value) 注入 |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | -// Host 编译时 mock __aicore__(Kernel 编译器已内置定义) | ||
| 31 | - | ||
| 32 | - | ||
| 33 | - | ||
| 34 | - | ||
| 35 | - | ||
| 36 | - | ||
| 37 | 30 | ||
| 38 | 31 | ||
| 39 | 32 | ||
| 40 | 33 | ||
| 41 | -using namespace Ops::Base; | ||
| 42 | - | ||
| 43 | namespace NsAdds { | 34 | namespace NsAdds { |
| 44 | 35 | ||
| 36 | +using namespace Ops::Base; | ||
| 37 | + | ||
| 45 | constexpr int CAST_MODE_NONE = 0; | 38 | constexpr int CAST_MODE_NONE = 0; |
| 46 | constexpr int CAST_MODE_RINT = 1; | 39 | constexpr int CAST_MODE_RINT = 1; |
| 47 | constexpr int CAST_MODE_ROUND = 4; | 40 | constexpr int CAST_MODE_ROUND = 4; |
| @@ -88,4 +81,4 @@ struct AddsOp { | |||
| 88 | 81 | ||
| 89 | } // namespace NsAdds | 82 | } // namespace NsAdds |
| 90 | 83 | ||
| 91 | -#endif // ADDS_DAG_H | 84 | +#endif // ADDS_DAG_H |
| @@ -38,6 +38,8 @@ static const size_t POWER_ASCEND_WORKSPACE = 16 * 1024 * 1024; | |||
| 38 | // isclose 判等使用的绝对/相对容差,与 math/is_close 默认参数对齐。 | 38 | // isclose 判等使用的绝对/相对容差,与 math/is_close 默认参数对齐。 |
| 39 | static constexpr float POWER_ISCLOSE_ATOL = 1e-8f; | 39 | static constexpr float POWER_ISCLOSE_ATOL = 1e-8f; |
| 40 | static constexpr float POWER_ISCLOSE_RTOL = 1e-5f; | 40 | static constexpr float POWER_ISCLOSE_RTOL = 1e-5f; |
| 41 | +// 整数幂奇偶性判断的模数: intPow % 2 决定 (-1)^intPow 的符号 | ||
| 42 | +static constexpr int POWER_PARITY_MODULUS = 2; | ||
| 41 | 43 | ||
| 42 | // 浮点近似相等:|a - b| <= atol + rtol * |b|。 | 44 | // 浮点近似相等:|a - b| <= atol + rtol * |b|。 |
| 43 | // 用于在 host 端容忍浮点误差地判断 power/scale/shift 是否落到 0/1/2/3 等关键点。 | 45 | // 用于在 host 端容忍浮点误差地判断 power/scale/shift 是否落到 0/1/2/3 等关键点。 |
| @@ -65,9 +67,7 @@ ge::graphStatus PowerTiling::CalcInputDtype() | |||
| 65 | OP_CHECK_IF( | 67 | OP_CHECK_IF( |
| 66 | this->inputDtype != ge::DT_FLOAT16 && this->inputDtype != ge::DT_BF16 && this->inputDtype != ge::DT_FLOAT, | 68 | this->inputDtype != ge::DT_FLOAT16 && this->inputDtype != ge::DT_BF16 && this->inputDtype != ge::DT_FLOAT, |
| 67 | OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON( | 69 | OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON( |
| 68 | - tilingContext->GetNodeName(), | 70 | + tilingContext->GetNodeName(), "x", Ops::Base::ToString(this->inputDtype).c_str(), |
| 69 | - "x", | ||
| 70 | - Ops::Base::ToString(this->inputDtype).c_str(), | ||
| 71 | "The dtype of x must be within the range [DT_FLOAT16, DT_BF16, DT_FLOAT]."), | 71 | "The dtype of x must be within the range [DT_FLOAT16, DT_BF16, DT_FLOAT]."), |
| 72 | return ge::GRAPH_FAILED); | 72 | return ge::GRAPH_FAILED); |
| 73 | return ge::GRAPH_SUCCESS; | 73 | return ge::GRAPH_SUCCESS; |
| @@ -79,14 +79,12 @@ ge::graphStatus PowerTiling::CalcOutputDtype() | |||
| 79 | auto outputDesc = tilingContext->GetOutputDesc(0); | 79 | auto outputDesc = tilingContext->GetOutputDesc(0); |
| 80 | OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outputDesc); | 80 | OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outputDesc); |
| 81 | this->outputDtype = outputDesc->GetDataType(); | 81 | this->outputDtype = outputDesc->GetDataType(); |
| 82 | - OP_CHECK_IF( | 82 | + OP_CHECK_IF(this->outputDtype != this->inputDtype, |
| 83 | - this->outputDtype != this->inputDtype, | 83 | + OP_LOGE_FOR_INVALID_DTYPES_WITH_REASON( |
| 84 | - OP_LOGE_FOR_INVALID_DTYPES_WITH_REASON( | 84 | + tilingContext->GetNodeName(), "x, y", |
| 85 | - tilingContext->GetNodeName(), | 85 | + (Ops::Base::ToString(this->inputDtype) + ", " + Ops::Base::ToString(this->outputDtype)).c_str(), |
| 86 | - "x, y", | 86 | + "The dtypes of x and y must be the same."), |
| 87 | - (Ops::Base::ToString(this->inputDtype) + ", " + Ops::Base::ToString(this->outputDtype)).c_str(), | 87 | + return ge::GRAPH_FAILED); |
| 88 | - "The dtypes of x and y must be the same."), | ||
| 89 | - return ge::GRAPH_FAILED); | ||
| 90 | return ge::GRAPH_SUCCESS; | 88 | return ge::GRAPH_SUCCESS; |
| 91 | } | 89 | } |
| 92 | 90 | ||
| @@ -102,14 +100,12 @@ ge::graphStatus PowerTiling::CheckShape() | |||
| 102 | OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outputStorageShape); | 100 | OP_CHECK_NULL_WITH_CONTEXT(tilingContext, outputStorageShape); |
| 103 | const gert::Shape& yShape = Ops::Base::EnsureNotScalar(outputStorageShape->GetStorageShape()); | 101 | const gert::Shape& yShape = Ops::Base::EnsureNotScalar(outputStorageShape->GetStorageShape()); |
| 104 | 102 | ||
| 105 | - OP_CHECK_IF( | 103 | + OP_CHECK_IF(xShape != yShape, |
| 106 | - xShape != yShape, | 104 | + OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( |
| 107 | - OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | 105 | + tilingContext->GetNodeName(), "x, y", |
| 108 | - tilingContext->GetNodeName(), | 106 | + (Ops::Base::ToString(xShape) + ", " + Ops::Base::ToString(yShape)).c_str(), |
| 109 | - "x, y", | 107 | + "The shapes of x and y must be the same."), |
| 110 | - (Ops::Base::ToString(xShape) + ", " + Ops::Base::ToString(yShape)).c_str(), | 108 | + return ge::GRAPH_FAILED); |
| 111 | - "The shapes of x and y must be the same."), | ||
| 112 | - return ge::GRAPH_FAILED); | ||
| 113 | return ge::GRAPH_SUCCESS; | 109 | return ge::GRAPH_SUCCESS; |
| 114 | } | 110 | } |
| 115 | 111 | ||
| @@ -129,18 +125,17 @@ ge::graphStatus PowerTiling::SetAttr() | |||
| 129 | const float* shiftPtr = attrs->GetAttrPointer<float>(2); | 125 | const float* shiftPtr = attrs->GetAttrPointer<float>(2); |
| 130 | this->attrShift = shiftPtr != nullptr ? *shiftPtr : 0.0f; | 126 | this->attrShift = shiftPtr != nullptr ? *shiftPtr : 0.0f; |
| 131 | 127 | ||
| 132 | - OP_LOGD( | 128 | + OP_LOGD(tilingContext->GetNodeName(), "Power attrs: power=%f, scale=%f, shift=%f", this->attrPower, this->attrScale, |
| 133 | - tilingContext->GetNodeName(), "Power attrs: power=%f, scale=%f, shift=%f", | 129 | + this->attrShift); |
| 134 | - this->attrPower, this->attrScale, this->attrShift); | ||
| 135 | return ge::GRAPH_SUCCESS; | 130 | return ge::GRAPH_SUCCESS; |
| 136 | } | 131 | } |
| 137 | 132 | ||
| 138 | // ----------------------------------------------------------------------------- | 133 | // ----------------------------------------------------------------------------- |
| 139 | // 模板辅助函数:根据 dtype 分发 DoTiling 调用(单模板参数 DAG)。 | 134 | // 模板辅助函数:根据 dtype 分发 DoTiling 调用(单模板参数 DAG)。 |
| 140 | // ----------------------------------------------------------------------------- | 135 | // ----------------------------------------------------------------------------- |
| 141 | -template<template<typename> class DagT> | 136 | +template <template <typename> class DagT> |
| 142 | -ge::graphStatus DispatchTilingByDtype( | 137 | +ge::graphStatus DispatchTilingByDtype(ElewiseBaseTiling& tiling, ge::DataType dtype, |
| 143 | - ElewiseBaseTiling& tiling, ge::DataType dtype, Ops::Base::EleBaseTilingData& baseTiling) | 138 | + Ops::Base::EleBaseTilingData& baseTiling) |
| 144 | { | 139 | { |
| 145 | if (dtype == ge::DT_FLOAT16) { | 140 | if (dtype == ge::DT_FLOAT16) { |
| 146 | return tiling.DoTiling<typename DagT<half>::OpDag>(baseTiling); | 141 | return tiling.DoTiling<typename DagT<half>::OpDag>(baseTiling); |
| @@ -154,9 +149,9 @@ ge::graphStatus DispatchTilingByDtype( | |||
| 154 | // ----------------------------------------------------------------------------- | 149 | // ----------------------------------------------------------------------------- |
| 155 | // 模板辅助函数:根据 dtype 分发 DoTiling 调用(双模板参数 DAG,用于 GENERIC_POW)。 | 150 | // 模板辅助函数:根据 dtype 分发 DoTiling 调用(双模板参数 DAG,用于 GENERIC_POW)。 |
| 156 | // ----------------------------------------------------------------------------- | 151 | // ----------------------------------------------------------------------------- |
| 157 | -template<template<typename, int> class DagT, int PowSign> | 152 | +template <template <typename, int> class DagT, int PowSign> |
| 158 | -ge::graphStatus DispatchTilingByDtypeGeneric( | 153 | +ge::graphStatus DispatchTilingByDtypeGeneric(ElewiseBaseTiling& tiling, ge::DataType dtype, |
| 159 | - ElewiseBaseTiling& tiling, ge::DataType dtype, Ops::Base::EleBaseTilingData& baseTiling) | 154 | + Ops::Base::EleBaseTilingData& baseTiling) |
| 160 | { | 155 | { |
| 161 | if (dtype == ge::DT_FLOAT16) { | 156 | if (dtype == ge::DT_FLOAT16) { |
| 162 | return tiling.DoTiling<typename DagT<half, PowSign>::OpDag>(baseTiling); | 157 | return tiling.DoTiling<typename DagT<half, PowSign>::OpDag>(baseTiling); |
| @@ -225,9 +220,11 @@ bool PowerTiling::DecideCulType() | |||
| 225 | } | 220 | } |
| 226 | 221 | ||
| 227 | // 分支2:优化整数幂 1/2/3,避免 exp/log 开销 | 222 | // 分支2:优化整数幂 1/2/3,避免 exp/log 开销 |
| 228 | - if (IsCloseScalar(this->attrPower, 1.0f) || IsCloseScalar(this->attrPower, 2.0f) || IsCloseScalar(this->attrPower, 3.0f)) { | 223 | + if (IsCloseScalar(this->attrPower, 1.0f) || IsCloseScalar(this->attrPower, 2.0f) || |
| 224 | + IsCloseScalar(this->attrPower, 3.0f)) { | ||
| 229 | culType = IsCloseScalar(this->attrPower, 1.0f) ? CulTypeEnum::LINEAR : | 225 | culType = IsCloseScalar(this->attrPower, 1.0f) ? CulTypeEnum::LINEAR : |
| 230 | - IsCloseScalar(this->attrPower, 2.0f) ? CulTypeEnum::SQUARE : CulTypeEnum::CUBE; | 226 | + IsCloseScalar(this->attrPower, 2.0f) ? CulTypeEnum::SQUARE : |
| 227 | + CulTypeEnum::CUBE; | ||
| 231 | scalar0 = this->attrScale; | 228 | scalar0 = this->attrScale; |
| 232 | scalar1 = this->attrShift; | 229 | scalar1 = this->attrShift; |
| 233 | return true; | 230 | return true; |
| @@ -239,7 +236,7 @@ bool PowerTiling::DecideCulType() | |||
| 239 | scalar1 = this->attrShift; | 236 | scalar1 = this->attrShift; |
| 240 | scalar2 = this->attrPower; | 237 | scalar2 = this->attrPower; |
| 241 | long long intPow = static_cast<long long>(std::llround(this->attrPower)); | 238 | long long intPow = static_cast<long long>(std::llround(this->attrPower)); |
| 242 | - scalar3 = powerIsInt ? ((std::llabs(intPow) % 2 == 0) ? 1.0f : -1.0f) : kNaN; | 239 | + scalar3 = powerIsInt ? ((std::llabs(intPow) % POWER_PARITY_MODULUS == 0) ? 1.0f : -1.0f) : kNaN; |
| 243 | return true; | 240 | return true; |
| 244 | } | 241 | } |
| 245 | 242 | ||
| @@ -251,20 +248,16 @@ bool PowerTiling::DecideCulType() | |||
| 251 | // ----------------------------------------------------------------------------- | 248 | // ----------------------------------------------------------------------------- |
| 252 | ge::graphStatus PowerTiling::PerformValidationChecks() | 249 | ge::graphStatus PowerTiling::PerformValidationChecks() |
| 253 | { | 250 | { |
| 254 | - OP_CHECK_IF( | 251 | + OP_CHECK_IF(CalcInputDtype() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "get input dtype failed"), |
| 255 | - CalcInputDtype() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "get input dtype failed"), | 252 | + return ge::GRAPH_FAILED); |
| 256 | - return ge::GRAPH_FAILED); | 253 | + OP_CHECK_IF(CalcOutputDtype() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "get output dtype failed"), |
| 257 | - OP_CHECK_IF( | 254 | + return ge::GRAPH_FAILED); |
| 258 | - CalcOutputDtype() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "get output dtype failed"), | 255 | + OP_CHECK_IF(CheckShape() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "check shape failed"), |
| 259 | - return ge::GRAPH_FAILED); | 256 | + return ge::GRAPH_FAILED); |
| 260 | - OP_CHECK_IF( | 257 | + OP_CHECK_IF(SetAttr() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "set attrs failed"), |
| 261 | - CheckShape() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "check shape failed"), | 258 | + return ge::GRAPH_FAILED); |
| 262 | - return ge::GRAPH_FAILED); | 259 | + OP_CHECK_IF(!DecideCulType(), OP_LOGE(tilingContext->GetNodeName(), "DecideCulType failed"), |
| 263 | - OP_CHECK_IF( | 260 | + return ge::GRAPH_FAILED); |
| 264 | - SetAttr() == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "set attrs failed"), | ||
| 265 | - return ge::GRAPH_FAILED); | ||
| 266 | - OP_CHECK_IF( | ||
| 267 | - !DecideCulType(), OP_LOGE(tilingContext->GetNodeName(), "DecideCulType failed"), return ge::GRAPH_FAILED); | ||
| 268 | return ge::GRAPH_SUCCESS; | 261 | return ge::GRAPH_SUCCESS; |
| 269 | } | 262 | } |
| 270 | 263 | ||
| @@ -278,9 +271,7 @@ ge::graphStatus PowerTiling::MapOutputDtypeToTplKey() | |||
| 278 | dType = POWER_TPL_DTYPE_FP32; | 271 | dType = POWER_TPL_DTYPE_FP32; |
| 279 | } else { | 272 | } else { |
| 280 | OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON( | 273 | OP_LOGE_FOR_INVALID_DTYPE_WITH_REASON( |
| 281 | - tilingContext->GetNodeName(), | 274 | + tilingContext->GetNodeName(), "y", Ops::Base::ToString(this->outputDtype).c_str(), |
| 282 | - "y", | ||
| 283 | - Ops::Base::ToString(this->outputDtype).c_str(), | ||
| 284 | "The dtype of y must be within the range [DT_FLOAT16, DT_BF16, DT_FLOAT]."); | 275 | "The dtype of y must be within the range [DT_FLOAT16, DT_BF16, DT_FLOAT]."); |
| 285 | return ge::GRAPH_FAILED; | 276 | return ge::GRAPH_FAILED; |
| 286 | } | 277 | } |
| @@ -289,9 +280,9 @@ ge::graphStatus PowerTiling::MapOutputDtypeToTplKey() | |||
| 289 | 280 | ||
| 290 | ge::graphStatus PowerTiling::SetTilingResults(PowerOp::PowerTilingData* powerTilingData) | 281 | ge::graphStatus PowerTiling::SetTilingResults(PowerOp::PowerTilingData* powerTilingData) |
| 291 | { | 282 | { |
| 292 | - powerTilingData->scale = scalar0; | 283 | + powerTilingData->scale = scalar0; |
| 293 | - powerTilingData->shift = scalar1; | 284 | + powerTilingData->shift = scalar1; |
| 294 | - powerTilingData->power = scalar2; | 285 | + powerTilingData->power = scalar2; |
| 295 | powerTilingData->negScalar = scalar3; | 286 | powerTilingData->negScalar = scalar3; |
| 296 | 287 | ||
| 297 | size_t* currentWorkspace = tilingContext->GetWorkspaceSizes(1); | 288 | size_t* currentWorkspace = tilingContext->GetWorkspaceSizes(1); |
| @@ -318,19 +309,16 @@ ge::graphStatus PowerTiling::RunTiling() | |||
| 318 | } | 309 | } |
| 319 | 310 | ||
| 320 | culTypeKey = static_cast<uint64_t>(culType); | 311 | culTypeKey = static_cast<uint64_t>(culType); |
| 321 | - OP_LOGD( | 312 | + OP_LOGD(tilingContext->GetNodeName(), "Power culType=%lu (scalar0=%f, scalar1=%f, scalar2=%f, scalar3=%f)", |
| 322 | - tilingContext->GetNodeName(), | 313 | + culTypeKey, scalar0, scalar1, scalar2, scalar3); |
| 323 | - "Power culType=%lu (scalar0=%f, scalar1=%f, scalar2=%f, scalar3=%f)", | ||
| 324 | - culTypeKey, scalar0, scalar1, scalar2, scalar3); | ||
| 325 | 314 | ||
| 326 | if (MapOutputDtypeToTplKey() != ge::GRAPH_SUCCESS) { | 315 | if (MapOutputDtypeToTplKey() != ge::GRAPH_SUCCESS) { |
| 327 | return ge::GRAPH_FAILED; | 316 | return ge::GRAPH_FAILED; |
| 328 | } | 317 | } |
| 329 | 318 | ||
| 330 | ge::graphStatus baseTilingResult = DispatchTilingByCulType(elewiseBaseTiling, powerTilingData); | 319 | ge::graphStatus baseTilingResult = DispatchTilingByCulType(elewiseBaseTiling, powerTilingData); |
| 331 | - OP_CHECK_IF( | 320 | + OP_CHECK_IF(baseTilingResult == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "elewiseBaseTiling failed"), |
| 332 | - baseTilingResult == ge::GRAPH_FAILED, OP_LOGE(tilingContext->GetNodeName(), "elewiseBaseTiling failed"), | 321 | + return ge::GRAPH_FAILED); |
| 333 | - return ge::GRAPH_FAILED); | ||
| 334 | 322 | ||
| 335 | return SetTilingResults(powerTilingData); | 323 | return SetTilingResults(powerTilingData); |
| 336 | } | 324 | } |