diff --git a/cplusplus/level1_single_api/3_ir/IRBuild/CMakeLists.txt b/cplusplus/level1_single_api/3_ir/IRBuild/CMakeLists.txt index 8c42b7ac36ab761316cb4ae7567ba341e856e998..3ad5c2656ad7556d7766a7eec94a55ca7d138768 100644 --- a/cplusplus/level1_single_api/3_ir/IRBuild/CMakeLists.txt +++ b/cplusplus/level1_single_api/3_ir/IRBuild/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE) if (DEFINED ENV{ASCEND_INSTALL_PATH}) set(ASCEND_PATH $ENV{ASCEND_INSTALL_PATH}) else () - set(ASCEND_PATH /usr/local/Ascend) + set(ASCEND_PATH /usr/local/Ascend/latest) endif() set(ATC_INCLUDE_DIR ${ASCEND_PATH}/compiler/include) diff --git a/cplusplus/level1_single_api/3_ir/IRBuild/Makefile b/cplusplus/level1_single_api/3_ir/IRBuild/Makefile index 54dfb409b61485419feacca0f85a76283eb5bc80..9acb81dbf42cc85914ba7642edd0ca4ab0334311 100644 --- a/cplusplus/level1_single_api/3_ir/IRBuild/Makefile +++ b/cplusplus/level1_single_api/3_ir/IRBuild/Makefile @@ -1,5 +1,5 @@ ifeq (${ASCEND_INSTALL_PATH},) - ASCEND_PATH := /usr/local/Ascend + ASCEND_PATH := /usr/local/Ascend/latest else ASCEND_PATH := ${ASCEND_INSTALL_PATH} endif @@ -16,13 +16,13 @@ CC := g++ CFLAGS := -std=c++11 -g -Wall -D_GLIBCXX_USE_CXX11_ABI=0 SRCS := $(wildcard $(LOCAL_DIR)/src/main.cpp) -INCLUDES := -I $(ASCEND_PATH)/opp/op_proto/built-in/inc \ +INCLUDES := -I $(ASCEND_PATH)/opp/built-in/op_proto/inc \ -I $(ATC_INCLUDE_DIR)/graph \ -I $(ATC_INCLUDE_DIR)/ge \ -I $(ATC_INCLUDE_DIR)/parser \ -I $(ASCEND_PATH)/compiler/include \ -FWK_INCLUDES := -I $(ASCEND_PATH)/opp/op_proto/built-in/inc \ +FWK_INCLUDES := -I $(ASCEND_PATH)/opp/built-in/op_proto/inc \ -I $(FWK_INCLUDE_DIR)/graph \ -I $(FWK_INCLUDE_DIR)/ge \ -I $(FWK_INCLUDE_DIR)/parser \ diff --git a/cplusplus/level1_single_api/3_ir/IRBuild/readme.md b/cplusplus/level1_single_api/3_ir/IRBuild/readme.md index 7ce49b37f985ea1bf2302372500b9a6de4e88534..04b4684722b8217b74fac2df874efbcffc5cc234 100644 --- a/cplusplus/level1_single_api/3_ir/IRBuild/readme.md +++ b/cplusplus/level1_single_api/3_ir/IRBuild/readme.md @@ -52,7 +52,7 @@ 1. 根据实际情况修改**Makefile**文件中的如下信息。 - - ASCEND_PATH:指定到ATC或FwkACLlib的安装目录,例如/home/HwHiAiUser/Ascend/ascend-toolkit/latest + - ASCEND_INSTALL_PATH:指定到ATC或FwkACLlib的安装目录,例如/home/HwHiAiUser/Ascend/ascend-toolkit/latest - INCLUDES:需要包含的头文件,对于本示例,无需修改。如果是用户自行开发的代码,当需要添加头文件时,在示例下方直接增加行即可,注意不要删除原有项目。如果网络中有自定义算子,请增加自定义算子的原型定义头文文件。 diff --git a/cplusplus/level1_single_api/3_ir/IRBuild/src/main.cpp b/cplusplus/level1_single_api/3_ir/IRBuild/src/main.cpp index d1cbaf5656a897088ac42330bd98c48a1aa287f5..112898926bd97e38743984afd66209b7d278a0df 100644 --- a/cplusplus/level1_single_api/3_ir/IRBuild/src/main.cpp +++ b/cplusplus/level1_single_api/3_ir/IRBuild/src/main.cpp @@ -14,22 +14,21 @@ * limitations under the License. */ -#include -#include #include +#include +#include +#include #include -#include "tensorflow_parser.h" -#include "caffe_parser.h" -#include "graph.h" -#include "types.h" -#include "tensor.h" +#include + +#include "all_ops.h" #include "attr_value.h" -#include "ge_error_codes.h" #include "ge_api_types.h" +#include "ge_error_codes.h" #include "ge_ir_build.h" -#include "all_ops.h" -#include -#include +#include "graph.h" +#include "tensor.h" +#include "types.h" //#include "add.h" // custom op ,if you have one new or different op defination with frame's,please // add head file here.If same with frame , no need to add head file here @@ -38,20 +37,20 @@ using namespace ge; using ge::Operator; namespace { -static const int kArgsNum = 3; +static const int kArgsNum = 6; static const int kSocVersion = 1; -static const int kGenGraphOpt = 2; -static const std::string kPath = "../data/"; +static const int kEmbeddingDim = 2; +static const int kTh1 = 3; +static const int kTh2 = 4; +static const int kNormScale = 5; +static const std::string kDataPath = "../data/weight_at_v.bin"; +static const float clip_min = 1e-30; +static const float clip_max = 1; +static const char_t *const allow_fp32_to_fp16 = "allow_fp32_to_fp16"; } // namespace void PrepareOptions(std::map& options) { -} - -bool CheckIsLHisi(string soc_version) { - if (soc_version == "Hi3796CV300ES" || soc_version == "Hi3796CV300CS") { - return true; - } - return false; + options.insert({ge::ir_option::PRECISION_MODE, AscendString(allow_fp32_to_fp16)}); } bool GetConstTensorFromBin(string path, Tensor &weight, uint32_t len) { @@ -65,13 +64,13 @@ bool GetConstTensorFromBin(string path, Tensor &weight, uint32_t len) { in_file.seekg(0, ios_base::beg); if (len != file_size) { - cout << "Invalid Param.len:" << len << " is not equal with binary size(" << file_size << ")\n"; + cout << "Invalid Param.len:" << len << " is not equal with binary size(" << file_size << ")\n"; in_file.close(); return false; } char* pdata = new(std::nothrow) char[len]; if (pdata == nullptr) { - cout << "Invalid Param.len:" << len << " is not equal with binary size(" << file_size << ")\n"; + cout << "Invalid Param.len:" << len << " is not equal with binary size(" << file_size << ")\n"; in_file.close(); return false; } @@ -86,189 +85,110 @@ bool GetConstTensorFromBin(string path, Tensor &weight, uint32_t len) { in_file.close(); return true; } -bool GenGraph(Graph& graph) +bool GenGraph(Graph& graph, int64_t embedding_dim, float th1, float th2, float mocha_norm_scale) { - auto shape_data = vector({ 1,1,28,28 }); - TensorDesc desc_data(ge::Shape(shape_data), FORMAT_ND, DT_FLOAT16); + auto shape_tsd = vector({-1, -1, embedding_dim}); + auto shape_sd = vector({-1, embedding_dim}); + auto shape_st = vector({-1, -1}); + TensorDesc desc_enc_try_data(ge::Shape(shape_tsd), FORMAT_ND, DT_FLOAT); + TensorDesc desc_dec_try_data(ge::Shape(shape_sd), FORMAT_ND, DT_FLOAT); + TensorDesc at_alpha_t_1_data(ge::Shape(shape_st), FORMAT_ND, DT_FLOAT); // data op - auto data = op::Data("data"); - data.update_input_desc_x(desc_data); - data.update_output_desc_y(desc_data); + auto data_enc_try = op::Data("data_enc_try"); + auto data_dec_try = op::Data("data_dec_try"); + auto at_alpha_t_1 = op::Data("at_alpha_t_1"); + data_enc_try.update_input_desc_x(desc_enc_try_data); + data_enc_try.update_output_desc_y(desc_enc_try_data); + data_dec_try.update_input_desc_x(desc_dec_try_data); + data_dec_try.update_output_desc_y(desc_dec_try_data); + at_alpha_t_1.update_input_desc_x(at_alpha_t_1_data); + at_alpha_t_1.update_output_desc_y(at_alpha_t_1_data); // custom op ,using method is the same with frame internal op // [Notice]: if you want to use custom self-define op, please prepare custom op according to custum op define user guides auto add = op::Add("add") - .set_input_x1(data) - .set_input_x2(data); - // AscendQuant - auto quant = op::AscendQuant("quant") - .set_input_x(data) - .set_attr_scale(1.0) - .set_attr_offset(0.0); + .set_input_x1(data_enc_try) + .set_input_x2(data_dec_try); + // Tanh + auto tanh = op::Tanh("tanh") + .set_input_x(add); - // const op: conv2d weight - auto weight_shape = ge::Shape({ 2,2,1,1 }); - TensorDesc desc_weight_1(weight_shape, FORMAT_ND, DT_INT8); - Tensor weight_tensor(desc_weight_1); - uint32_t weight_1_len = weight_shape.GetShapeSize() * sizeof(int8_t); - bool res = GetConstTensorFromBin(kPath+"Conv2D_kernel_quant.bin", weight_tensor, weight_1_len); + // MatMul weight + auto matmul_weight_shape = ge::Shape({embedding_dim, 1}); + TensorDesc desc_matmul_weight(matmul_weight_shape, FORMAT_ND, DT_FLOAT); + Tensor matmul_weight_tensor(desc_matmul_weight); + uint32_t matmul_weight_len = matmul_weight_shape.GetShapeSize() * sizeof(float); + bool res = GetConstTensorFromBin(kDataPath, matmul_weight_tensor, matmul_weight_len); if (!res) { cout << __LINE__ << "GetConstTensorFromBin Failed!" << endl; return -1; } - auto conv_weight = op::Const("Conv2D/weight") - .set_attr_value(weight_tensor); - - // conv2d op - auto conv2d = op::Conv2D("Conv2d1") - .set_input_x(quant) - .set_input_filter(conv_weight) - .set_attr_strides({ 1, 1, 1, 1 }) - .set_attr_pads({ 0, 1, 0, 1 }) - .set_attr_dilations({ 1, 1, 1, 1 }); - - TensorDesc conv2d_input_desc_x(ge::Shape(), FORMAT_NCHW, DT_INT8); - TensorDesc conv2d_input_desc_filter(ge::Shape(), FORMAT_HWCN, DT_INT8); - TensorDesc conv2d_output_desc_y(ge::Shape(), FORMAT_NCHW, DT_INT8); - conv2d.update_input_desc_x(conv2d_input_desc_x); - conv2d.update_input_desc_filter(conv2d_input_desc_filter); - conv2d.update_output_desc_y(conv2d_output_desc_y); - // dequant scale - TensorDesc desc_dequant_shape(ge::Shape({ 1 }), FORMAT_ND, DT_UINT64); - Tensor dequant_tensor(desc_dequant_shape); - uint64_t dequant_scale_val = 1; - auto status = dequant_tensor.SetData(reinterpret_cast(&dequant_scale_val), sizeof(uint64_t)); + auto matmul_weight_const = op::Const("weight_at_v") + .set_attr_value(matmul_weight_tensor); + // MatMul + auto matmul = op::BatchMatMul("matmul") + .set_input_x1(tanh) + .set_input_x2(matmul_weight_const); + // Sigmoid + auto sigmoid = op::Sigmoid("sigmoid") + .set_input_x(matmul); + + // Clip + float *clip_min_data = new float[1]{clip_min}; + float *clip_max_data = new float[1]{clip_max}; + TensorDesc clip_desc(ge::Shape({1}), FORMAT_ND, DT_FLOAT); + Tensor clip_min_tensor(clip_desc); + Tensor clip_max_tensor(clip_desc); + auto status = clip_min_tensor.SetData((uint8_t *)clip_min_data, sizeof(float)); if (status != ge::GRAPH_SUCCESS) { cout << __LINE__ << "Set Tensor Data Failed" << "\n"; return false; } - auto dequant_scale = op::Const("dequant_scale") - .set_attr_value(dequant_tensor); - - // AscendDequant - auto dequant = op::AscendDequant("dequant") - .set_input_x(conv2d) - .set_input_deq_scale(dequant_scale); - - // const op: BiasAdd weight - auto weight_bias_add_shape_1 = ge::Shape({ 1 }); - TensorDesc desc_weight_bias_add_1(weight_bias_add_shape_1, FORMAT_ND, DT_FLOAT); - Tensor weight_bias_add_tensor_1(desc_weight_bias_add_1); - uint32_t weight_bias_add_len_1 = weight_bias_add_shape_1.GetShapeSize() * sizeof(float); - float weight_bias_add_value = 0.006448820233345032; - status = weight_bias_add_tensor_1.SetData(reinterpret_cast(&weight_bias_add_value), weight_bias_add_len_1); + status = clip_max_tensor.SetData((uint8_t *)clip_max_data, sizeof(float)); if (status != ge::GRAPH_SUCCESS) { cout << __LINE__ << "Set Tensor Data Failed" << "\n"; return false; } - auto bias_weight_1 = op::Const("Bias/weight_1") - .set_attr_value(weight_bias_add_tensor_1); - // BiasAdd 1 - auto bias_add_1 = op::BiasAdd("bias_add_1") - .set_input_x(dequant) - .set_input_bias(bias_weight_1) - .set_attr_data_format("NCHW"); + delete[] clip_min_data; + delete[] clip_max_data; + auto clip_min_const = op::Const("min_const").set_attr_value(clip_min_tensor); + auto clip_max_const = op::Const("max_const").set_attr_value(clip_max_tensor); + // Sub + auto sub = op::Sub("sub") + .set_input_x1(clip_max_const) + .set_input_x2(sigmoid); - // const - int32_t value[2] = {1,-1}; - - auto value_shape = ge::Shape({ 2 }); - TensorDesc desc_dynamic_const(value_shape, FORMAT_ND, DT_INT32); - Tensor dynamic_const_tensor(desc_dynamic_const); - uint32_t dynamic_const_len = value_shape.GetShapeSize() * sizeof(int32_t); - status = dynamic_const_tensor.SetData(reinterpret_cast(&(value[0])), dynamic_const_len); + auto clip = op::ClipByValue("clip") + .set_input_x(sub) + .set_input_clip_value_min(clip_min_const) + .set_input_clip_value_max(clip_max_const); + // Log + auto log = op::Log("log") + .set_input_x(clip); + // Cumsum + TensorDesc axis_shape(ge::Shape({1}), FORMAT_ND, DT_INT64); + Tensor axis_tensor(axis_shape); + int64_t axis_value = 0; + status = axis_tensor.SetData(reinterpret_cast(&axis_value), sizeof(int64_t)); if (status != ge::GRAPH_SUCCESS) { cout << __LINE__ << "Set Tensor Data Failed" << "\n"; return false; } - auto dynamic_const = op::Const("dynamic_const").set_attr_value(dynamic_const_tensor); - - // ReShape op - auto reshape = op::Reshape("Reshape") - .set_input_x(bias_add_1) - .set_input_shape(dynamic_const); - // MatMul + BiasAdd - // MatMul weight 1 - auto matmul_weight_shape_1 = ge::Shape({784,512}); - TensorDesc desc_matmul_weight_1(matmul_weight_shape_1, FORMAT_ND, DT_FLOAT); - Tensor matmul_weight_tensor_1(desc_matmul_weight_1); - uint32_t matmul_weight_1_len = matmul_weight_shape_1.GetShapeSize() * sizeof(float); - res = GetConstTensorFromBin(kPath + "dense_kernel.bin", matmul_weight_tensor_1, matmul_weight_1_len); - if (!res) { - cout << __LINE__ << "GetConstTensorFromBin Failed!" << endl; - return -1; - } - auto matmul_weight_1 = op::Const("dense/kernel") - .set_attr_value(matmul_weight_tensor_1); - // MatMul1 - auto matmul_1 = op::MatMul("MatMul_1") - .set_input_x1(reshape) - .set_input_x2(matmul_weight_1); - // BiasAdd const 2 - auto bias_add_shape_2 = ge::Shape({ 512 }); - TensorDesc desc_bias_add_const_1(bias_add_shape_2, FORMAT_ND, DT_FLOAT); - Tensor bias_add_const_tensor_1(desc_bias_add_const_1); - uint32_t bias_add_const_len_1 = bias_add_shape_2.GetShapeSize() * sizeof(float); - res = GetConstTensorFromBin(kPath + "dense_bias.bin", bias_add_const_tensor_1, bias_add_const_len_1); - if (!res) { - cout << __LINE__ << "GetConstTensorFromBin Failed!" << endl; - return -1; - } - auto bias_add_const_1 = op::Const("dense/bias") - .set_attr_value(bias_add_const_tensor_1); - // BiasAdd 2 - auto bias_add_2 = op::BiasAdd("bias_add_2") - .set_input_x(matmul_1) - .set_input_bias(bias_add_const_1) - .set_attr_data_format("NCHW"); - // Relu6 - auto relu6 = op::Relu6("relu6") - .set_input_x(bias_add_2); - // MatMul weight 2 - auto matmul_weight_shape_2 = ge::Shape({ 512, 10 }); - TensorDesc desc_matmul_weight_2(matmul_weight_shape_2, FORMAT_ND, DT_FLOAT); - Tensor matmul_weight_tensor_2(desc_matmul_weight_2); - uint32_t matmul_weight_2_len = matmul_weight_shape_2.GetShapeSize() * sizeof(float); - res = GetConstTensorFromBin(kPath + "OutputLayer_kernel.bin", matmul_weight_tensor_2, matmul_weight_2_len); - if (!res) { - cout << __LINE__ << "GetConstTensorFromBin Failed!" << endl; - return -1; - } - auto matmul_weight_2 = op::Const("OutputLayer/kernel") - .set_attr_value(matmul_weight_tensor_2); - // MatMul 2 - auto matmul_2 = op::MatMul("MatMul_2") - .set_input_x1(relu6) - .set_input_x2(matmul_weight_2); - // BiasAdd const 3 - auto bias_add_shape_3 = ge::Shape({ 10 }); - TensorDesc desc_bias_add_const_3(bias_add_shape_3, FORMAT_ND, DT_FLOAT); - Tensor bias_add_const_tensor_3(desc_bias_add_const_3); - uint32_t bias_add_const_len_3 = bias_add_shape_3.GetShapeSize() * sizeof(float); - res = GetConstTensorFromBin(kPath + "OutputLayer_bias.bin", bias_add_const_tensor_3, bias_add_const_len_3); - if (!res) { - cout << __LINE__ << "GetConstTensorFromBin Failed!" << endl; - return -1; - } - auto bias_add_const_3 = op::Const("OutputLayer/bias") - .set_attr_value(bias_add_const_tensor_3); - // BiasAdd 3 - /* - * When set input for some node, there are two methodes for you. - * Method 1: operator level method. Frame will auto connect the node's output edge to netoutput nodes for user - * we recommend this method when some node own only one out node - * Method 2: edge of operator level. Frame will find the edge according to the output edge name - * we recommend this method when some node own multi out nodes and only one out edge data wanted back - */ - auto bias_add_3 = op::BiasAdd("bias_add_3") - .set_input_x(matmul_2, "y") - .set_input_bias(bias_add_const_3, "y") - .set_attr_data_format("NCHW"); - // Softmax op - auto softmax = op::SoftmaxV2("Softmax") - .set_input_x(bias_add_3, "y"); + auto axis_const = op::Const("axis_const") + .set_attr_value(axis_tensor); + auto cumsum = op::Cumsum("cumsum") + .set_input_x(log) + .set_input_axis(axis_const); + // CumsumHardAttention + auto c_hard_attention = op::CumsumHardAttention("c_hard_attention") + .set_input_pt(sigmoid) + .set_input_pt_1(at_alpha_t_1) + .set_input_log_t(cumsum) + .set_attr_th1(th1) + .set_attr_th2(th2) + .set_attr_mocha_norm_scale(mocha_norm_scale); - std::vector inputs{ data }; + std::vector inputs{data_enc_try, data_dec_try, at_alpha_t_1}; /* * The same as set input, when point net output ,Davince framework alos support multi method to set outputs info * Method 1: operator level method. Frame will auto connect the node's output edge to netoutput nodes for user @@ -277,152 +197,54 @@ bool GenGraph(Graph& graph) * we recommend this method when some node own multi out nodes and only one out edge data wanted back * Using method is like follows: */ - std::vector outputs{ softmax, add }; - std::vector> outputs_with_name = {{softmax, "y"}}; + std::vector outputs{c_hard_attention}; + std::vector> outputs_with_name = {{c_hard_attention, "y"}}; graph.SetInputs(inputs).SetOutputs(outputs); return true; } -// |o>------------------------- -// |o> data -// |o> | -// |o> data abs const -// |o> | | / -// |o> abs add -// |o> \ / -// |o> add -// modify tf graph -bool ModifyGraph(Graph &graph) { - /* First, you need to know where to insert new node , and find src node and dest node of new node - * by Node name from all nodes of graph; - * Second, remove edge between src node and dest node(data or control edge). - * Third, create new node by operator. - * Last, add edge(data or control) between src node and new node. - * add edge between new node and dest node. - * Here, we will insert Abs between Add and Const. - */ - // Option: If you need to know shape and type info of node, you can call infer shape interface: - // aclgrphInferShapeAndType ,then view this info by graph file which generated by dump graph - // interface: aclgrphDumpGraph. - std::cout<<"Modify Graph Start."< nodes = graph.GetAllNodes(); - graphStatus ret = GRAPH_FAILED; - for (auto &node : nodes) { - ge::AscendString name; - ret = node.GetName(name); - if (ret != GRAPH_SUCCESS) { - std::cout<<"Get node name failed."< parser_options = { - {AscendString(ge::ir_option::INPUT_FP16_NODES), AscendString("input1;input2")} - }; - tfStatus = ge::aclgrphParseTensorFlow(tfPath.c_str(), parser_options, graph1); - } else { - tfStatus = ge::aclgrphParseTensorFlow(tfPath.c_str(), graph1); - } - if (tfStatus != GRAPH_SUCCESS) { - cout << "========== Generate graph from tensorflow origin model failed.========== " << endl; - return 0; - } - cout << "========== Generate graph from tensorflow origin model success.========== " << endl; - if (ModifyGraph(graph1)) { - cout << "========== Modify tensorflow origin graph success.========== " << endl; - } - } else if (string(argv[kGenGraphOpt]) == "caffe") { - std::string caffePath = "../data/caffe_test.prototxt"; - std::string weigtht = "../data/caffe_test.caffemodel"; - graphStatus caffeStatus = GRAPH_SUCCESS; - if (CheckIsLHisi(string(argv[kSocVersion]))) { - std::map parser_options = { - {AscendString(ge::ir_option::INPUT_FP16_NODES), AscendString("data")} - }; - caffeStatus = ge::aclgrphParseCaffe(caffePath.c_str(), weigtht.c_str(), parser_options, graph1); - } else { - caffeStatus = ge::aclgrphParseCaffe(caffePath.c_str(), weigtht.c_str(), graph1); - } - if (caffeStatus != GRAPH_SUCCESS) { - cout << "========== Generate graph from caffe origin model failed.========== " << endl; - return 0; - } - cout << "========== Generate graph from caffe origin model success.========== " << endl; + ret = GenGraph(graph1, embedding_dim, th1, th2, mocha_norm_scale); + if (!ret) { + cout << "========== Generate Graph1 Failed! ==========" << endl; + return -1; + } + else { + cout << "========== Generate Graph1 Success! ==========" << endl; } - // 2. system init std::map global_options = { - {AscendString(ge::ir_option::SOC_VERSION), AscendString(argv[kSocVersion])} , + {AscendString(ge::ir_option::SOC_VERSION), AscendString(argv[kSocVersion])}, + {ge::ir_option::PRECISION_MODE, AscendString(allow_fp32_to_fp16)} }; auto status = aclgrphBuildInitialize(global_options); // 3. Build Ir Model1