在静态图模式下,可以通过整图下沉优化调度性能。将完整的计算图一次性下发至Device侧,后续执行则无需Host参与,由Device自主完成计算,从而减少Host-Device交互开销,提升执行效率。部分算子的Tiling计算依赖运行时输入的具体数值(Tiling值依赖),需在执行时动态计算Tiling参数。针对该场景,可采用Tiling下沉优化方案:将Tiling计算下沉至Device侧的AI CPU上执行,从而实现计算全程在Device侧高效完成。
Tiling下沉场景下,算子工程的op_host目录结构如下,将Tiling实现文件单独放在在一个cpp文件中,示例中为add_custom_tiling.cpp。
├── op_host │ ├── add_custom.cpp // 算子原型定义、InferShape、InferDataType实现 │ ├── add_custom_tiling.cpp // Tiling函数实现 │ ├── add_custom_tiling.h // TilingData结构体定义、Tiling函数声明 │ └── CMakeLists.txt
以AddCustom算子为例,讲解关键代码文件的具体实现方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#ifndef ADD_CUSTOM_TILING_H #define ADD_CUSTOM_TILING_H #include "register/tilingdata_base.h" #include "register/op_def_registry.h" namespace optiling { BEGIN_TILING_DATA_DEF(TilingData) TILING_DATA_FIELD_DEF(uint32_t, totalLength); TILING_DATA_FIELD_DEF(uint32_t, tileNum); END_TILING_DATA_DEF; REGISTER_TILING_DATA_CLASS(AddCustom, TilingData) // Tiling结构体定义 } // namespace optiling namespace optiling { ge::graphStatus TilingFunc(gert::TilingContext* context); // Tiling函数声明 } #endif // ADD_CUSTOM_TILING_H |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include "register/device_op_impl_registry.h" // 包含头文件 #include "add_custom_tiling.h" namespace optiling { const uint32_t BLOCK_DIM = 8; const uint32_t TILE_NUM = 8; ge::graphStatus TilingFunc(gert::TilingContext *context) { TilingData tiling; uint32_t totalLength = context->GetInputShape(0)->GetOriginShape().GetShapeSize(); context->SetBlockDim(BLOCK_DIM); tiling.set_totalLength(totalLength); tiling.set_tileNum(TILE_NUM); tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity()); context->GetRawTilingData()->SetDataSize(tiling.GetDataSize()); // 设置值依赖后,可以通过TilingContext::GetOptionalInputTensor获取到tensor数据 auto tensor = context->GetOptionalInputTensor(0)->GetData<float>(); if (tensor != nullptr) { printf("tensor[0] = %f \n", tensor[0]); } context->SetTilingKey(0); size_t *currentWorkspace = context->GetWorkspaceSizes(1); currentWorkspace[0] = 0; return ge::GRAPH_SUCCESS; } } // namespace optiling DEVICE_IMPL_OP_OPTILING(AddCustom).Tiling(optiling::TilingFunc); // 将Tiling函数以及其OpType注册到Tiling下沉 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#include "add_custom_tiling.h" // 包含头文件 // ... namespace ops { class AddCustom : public OpDef { public: AddCustom(const char* name) : OpDef(name) { this->Input("x") .ParamType(REQUIRED) .DataType({ge::DT_FLOAT}) .Format({ge::FORMAT_ND}) .ValueDepend(OPTIONAL, DependScope::TILING); // 表示输入x为Tiling值依赖 this->Input("y") .ParamType(REQUIRED) .DataType({ge::DT_FLOAT}) .Format({ge::FORMAT_ND}); this->Output("z") .ParamType(REQUIRED) .DataType({ge::DT_FLOAT}) .Format({ge::FORMAT_ND}); // 如下的shape/datatype推导函数仅在算子入图场景使用 this->SetInferShape(ge::InferShape); this->SetInferDataType(ge::InferDataType); this->AICore() .SetTiling(optiling::TilingFunc); // Tiling函数和算子原型定义的关联 // 请替换为实际的昇腾AI处理器型号 this->AICore().AddConfig("ascendxxx"); } }; OP_ADD(AddCustom); } // namespace ops |
# 通过ascendc_device_library添加Tiling下沉编译任务 ascendc_device_library( TARGET cust_opmaster # 任务名称,固定为cust_opmaster OPTION SHARED # 动态库(当前仅支持动态库入图下沉) SRC ${CMAKE_CURRENT_SOURCE_DIR}/add_custom_tiling.cpp ) # Tiling函数实现代码源文件