|
|
|
@ -15,15 +15,12 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "kernel/tbe/tbe_kernel_build.h"
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <unordered_set>
|
|
|
|
|
|
|
|
|
|
#include "operator/ops.h"
|
|
|
|
|
#include "parallel/ops_info/ops_utils.h"
|
|
|
|
|
#include "session/anf_runtime_algorithm.h"
|
|
|
|
|
#include "kernel/tbe/tbe_kernel_mod.h"
|
|
|
|
|
#include "kernel/tbe/tbe_adapter.h"
|
|
|
|
|
#include "kernel/tbe/tbe_python_funcs.h"
|
|
|
|
|
#include "kernel/tbe/tbe_convert_utils.h"
|
|
|
|
@ -37,6 +34,42 @@ constexpr auto kFusionOpList = "op_list";
|
|
|
|
|
constexpr auto kFusionKernelNamePrfix = "te_fusion";
|
|
|
|
|
constexpr auto kOptional = "optional_";
|
|
|
|
|
constexpr auto kOpFormat_FRACTAL_Z = "FRACTAL_Z";
|
|
|
|
|
constexpr auto kPlatform = "platform";
|
|
|
|
|
constexpr auto kPlatTBE = "TBE";
|
|
|
|
|
constexpr auto kGenModel = "gen_model";
|
|
|
|
|
constexpr auto kSingle = "single";
|
|
|
|
|
constexpr auto kImplPath = "impl_path";
|
|
|
|
|
constexpr auto kJInputs = "inputs";
|
|
|
|
|
constexpr auto kJOutputs = "outputs";
|
|
|
|
|
constexpr auto kJAttrs = "attrs";
|
|
|
|
|
constexpr auto kJKernelName = "kernel_name";
|
|
|
|
|
constexpr auto kJOpInfo = "op_info";
|
|
|
|
|
constexpr auto kJDtype = "dtype";
|
|
|
|
|
constexpr auto kJtype = "type";
|
|
|
|
|
constexpr auto kJName = "name";
|
|
|
|
|
constexpr auto kJOriShape = "ori_shape";
|
|
|
|
|
constexpr auto kJOriFormat = "ori_format";
|
|
|
|
|
constexpr auto kJShape = "shape";
|
|
|
|
|
constexpr auto kJFormat = "format";
|
|
|
|
|
constexpr auto kJValid = "valid";
|
|
|
|
|
constexpr auto kJParamType = "param_type";
|
|
|
|
|
constexpr auto kParamDynamic = "dynamic";
|
|
|
|
|
constexpr auto kParamRequred = "required";
|
|
|
|
|
constexpr auto kJDataType = "data_type";
|
|
|
|
|
constexpr auto kJOutputIndex = "output_index";
|
|
|
|
|
constexpr auto kJOutputDesc = "output_desc";
|
|
|
|
|
constexpr auto kJInputDesc = "input_desc";
|
|
|
|
|
constexpr auto kVTypeInt = "int";
|
|
|
|
|
constexpr auto kVTypeStr = "str";
|
|
|
|
|
constexpr auto kVTypeBool = "bool";
|
|
|
|
|
constexpr auto kVTypeFloat = "float";
|
|
|
|
|
constexpr auto kVTypeListInt = "listInt";
|
|
|
|
|
constexpr auto kVTypeInt32 = "Int32";
|
|
|
|
|
constexpr auto kVTypeListFloat = "listFloat";
|
|
|
|
|
constexpr auto kVTypeListListInt = "listListInt";
|
|
|
|
|
constexpr auto kJValue = "value";
|
|
|
|
|
constexpr auto kJDynIndex = "dyn_index";
|
|
|
|
|
constexpr auto kJFuncName = "func_name";
|
|
|
|
|
|
|
|
|
|
std::string NormalizeFullScopeName(const string &full_scope_name) {
|
|
|
|
|
// exp:Default/ReLU-op0 -->Default_ReLU_op0
|
|
|
|
@ -46,51 +79,51 @@ std::string NormalizeFullScopeName(const string &full_scope_name) {
|
|
|
|
|
return normal_ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelJsonCreator::GenTbeSingleKernelJson(const shared_ptr<mindspore::AnfNode> &anf_node,
|
|
|
|
|
bool TbeKernelJsonCreator::GenTbeSingleKernelJson(const std::shared_ptr<mindspore::AnfNode> &anf_node,
|
|
|
|
|
nlohmann::json *kernel_json) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(kernel_json);
|
|
|
|
|
std::string op_name = AnfAlgo::GetCNodeName(anf_node);
|
|
|
|
|
auto op_info_ptr = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kTBE);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(op_info_ptr);
|
|
|
|
|
(*kernel_json)["platform"] = "TBE";
|
|
|
|
|
(*kernel_json)["gen_model"] = "single";
|
|
|
|
|
(*kernel_json)["impl_path"] = op_info_ptr->impl_path();
|
|
|
|
|
(*kernel_json)[kPlatform] = kPlatTBE;
|
|
|
|
|
(*kernel_json)[kGenModel] = kSingle;
|
|
|
|
|
(*kernel_json)[kImplPath] = op_info_ptr->impl_path();
|
|
|
|
|
nlohmann::json op_info_json;
|
|
|
|
|
if (op_info_ptr->impl_path().empty()) {
|
|
|
|
|
tbe::TbeAdapter::NormalizeFuncName(&op_name);
|
|
|
|
|
} else {
|
|
|
|
|
op_name = op_info_ptr->kernel_name();
|
|
|
|
|
}
|
|
|
|
|
op_info_json["name"] = op_name;
|
|
|
|
|
op_info_json[kJName] = op_name;
|
|
|
|
|
// generate inputs json
|
|
|
|
|
nlohmann::json inputs_json;
|
|
|
|
|
if (!GenTbeInputsJson(anf_node, op_info_ptr, &inputs_json)) {
|
|
|
|
|
MS_LOG(ERROR) << "Anf Node [" << op_name << "] generate inputs json failed";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
op_info_json["inputs"] = inputs_json;
|
|
|
|
|
op_info_json[kJInputs] = inputs_json;
|
|
|
|
|
// generate outputs json
|
|
|
|
|
nlohmann::json outputs_json;
|
|
|
|
|
if (!GenTbeOutputsJson(anf_node, op_info_ptr, &outputs_json)) {
|
|
|
|
|
MS_LOG(ERROR) << "Anf Node [" << op_name << "] generate outputs json failed";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
op_info_json["outputs"] = outputs_json;
|
|
|
|
|
op_info_json[kJOutputs] = outputs_json;
|
|
|
|
|
// generate attrs json
|
|
|
|
|
nlohmann::json attrs_json;
|
|
|
|
|
(void)GenTbeAttrJson(anf_node, op_info_ptr, &attrs_json);
|
|
|
|
|
op_info_json["attrs"] = attrs_json;
|
|
|
|
|
op_info_json[kJAttrs] = attrs_json;
|
|
|
|
|
std::string json_str = op_info_json.dump();
|
|
|
|
|
size_t hash_id = std::hash<std::string>()(json_str);
|
|
|
|
|
json_name_ = op_name + "_" + std::to_string(hash_id);
|
|
|
|
|
json_info_ = json_str;
|
|
|
|
|
if (creater_type_ == PREBUILD) {
|
|
|
|
|
op_info_json["kernel_name"] = NormalizeFullScopeName(anf_node->fullname_with_scope());
|
|
|
|
|
op_info_json[kJKernelName] = NormalizeFullScopeName(anf_node->fullname_with_scope());
|
|
|
|
|
} else {
|
|
|
|
|
op_info_json["kernel_name"] = json_name_;
|
|
|
|
|
op_info_json[kJKernelName] = json_name_;
|
|
|
|
|
}
|
|
|
|
|
(*kernel_json)["op_info"] = op_info_json;
|
|
|
|
|
(*kernel_json)[kJOpInfo] = op_info_json;
|
|
|
|
|
if (creater_type_ == SINGLE_BUILD) {
|
|
|
|
|
TbeUtils::SaveJsonInfo(json_name_, json_info_);
|
|
|
|
|
}
|
|
|
|
@ -101,9 +134,10 @@ bool TbeKernelJsonCreator::GenTbeSingleKernelJson(const shared_ptr<mindspore::An
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelJsonCreator::GenInputDescJson(const shared_ptr<AnfNode> &anf_node, size_t real_input_index, bool value,
|
|
|
|
|
const shared_ptr<OpIOInfo> &input_ptr, const string &op_input_name,
|
|
|
|
|
size_t input_i, vector<nlohmann::json> *input_list) {
|
|
|
|
|
bool TbeKernelJsonCreator::GenInputDescJson(const std::shared_ptr<AnfNode> &anf_node, size_t real_input_index,
|
|
|
|
|
bool value, const std::shared_ptr<OpIOInfo> &input_ptr,
|
|
|
|
|
const string &op_input_name, size_t input_i,
|
|
|
|
|
std::vector<nlohmann::json> *input_list) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_ptr);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_list);
|
|
|
|
@ -119,22 +153,22 @@ bool TbeKernelJsonCreator::GenInputDescJson(const shared_ptr<AnfNode> &anf_node,
|
|
|
|
|
ori_shape.emplace_back(1);
|
|
|
|
|
}
|
|
|
|
|
nlohmann::json input_desc_json;
|
|
|
|
|
input_desc_json["dtype"] = dtype;
|
|
|
|
|
input_desc_json["name"] = op_input_name + std::to_string(input_i);
|
|
|
|
|
input_desc_json["ori_shape"] = ori_shape;
|
|
|
|
|
input_desc_json["ori_format"] = kOpFormat_NCHW;
|
|
|
|
|
input_desc_json["shape"] = shape;
|
|
|
|
|
input_desc_json["format"] = format;
|
|
|
|
|
input_desc_json["valid"] = value;
|
|
|
|
|
input_desc_json["param_type"] = input_ptr->param_type();
|
|
|
|
|
input_desc_json[kJDtype] = dtype;
|
|
|
|
|
input_desc_json[kJName] = op_input_name + std::to_string(input_i);
|
|
|
|
|
input_desc_json[kJOriShape] = ori_shape;
|
|
|
|
|
input_desc_json[kJOriFormat] = kOpFormat_NCHW;
|
|
|
|
|
input_desc_json[kJShape] = shape;
|
|
|
|
|
input_desc_json[kJFormat] = format;
|
|
|
|
|
input_desc_json[kJValid] = value;
|
|
|
|
|
input_desc_json[kJParamType] = input_ptr->param_type();
|
|
|
|
|
input_list->emplace_back(input_desc_json);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelJsonCreator::GenInputList(const shared_ptr<AnfNode> &anf_node, size_t input_tensor_num,
|
|
|
|
|
const shared_ptr<OpIOInfo> &input_ptr, size_t *real_input_index,
|
|
|
|
|
string *op_input_name, vector<nlohmann::json> *input_list) {
|
|
|
|
|
bool TbeKernelJsonCreator::GenInputList(const std::shared_ptr<AnfNode> &anf_node, size_t input_tensor_num,
|
|
|
|
|
const std::shared_ptr<OpIOInfo> &input_ptr, size_t *real_input_index,
|
|
|
|
|
string *op_input_name, std::vector<nlohmann::json> *input_list) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_ptr);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(real_input_index);
|
|
|
|
@ -149,8 +183,8 @@ bool TbeKernelJsonCreator::GenInputList(const shared_ptr<AnfNode> &anf_node, siz
|
|
|
|
|
if (input_ptr->param_type() == "optional") {
|
|
|
|
|
*op_input_name = input_ptr->name() + "_optional_";
|
|
|
|
|
nlohmann::json input_desc_json;
|
|
|
|
|
input_desc_json["valid"] = false;
|
|
|
|
|
input_desc_json["name"] = *op_input_name + std::to_string(*real_input_index);
|
|
|
|
|
input_desc_json[kJValid] = false;
|
|
|
|
|
input_desc_json[kJName] = *op_input_name + std::to_string(*real_input_index);
|
|
|
|
|
input_list->emplace_back(input_desc_json);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
@ -179,7 +213,7 @@ bool TbeKernelJsonCreator::GenInputList(const shared_ptr<AnfNode> &anf_node, siz
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool GetInputNameAndRealNum(const std::shared_ptr<AnfNode> &anf_node, const shared_ptr<OpIOInfo> &input_ptr,
|
|
|
|
|
bool GetInputNameAndRealNum(const std::shared_ptr<AnfNode> &anf_node, const std::shared_ptr<OpIOInfo> &input_ptr,
|
|
|
|
|
size_t *dyn_input_index, size_t *input_num, std::string *op_input_name) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_ptr);
|
|
|
|
@ -193,7 +227,7 @@ bool GetInputNameAndRealNum(const std::shared_ptr<AnfNode> &anf_node, const shar
|
|
|
|
|
dyn_input_sizes = GetValue<const std::vector<int>>(primitive->GetAttr(kAttrDynInputSizes));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (input_ptr->param_type() == "dynamic") {
|
|
|
|
|
if (input_ptr->param_type() == kParamDynamic) {
|
|
|
|
|
if (*dyn_input_index >= dyn_input_sizes.size()) {
|
|
|
|
|
MS_LOG(ERROR) << "dyn input index" << *dyn_input_index << "is over dyn input num" << dyn_input_sizes.size();
|
|
|
|
|
return false;
|
|
|
|
@ -259,9 +293,9 @@ bool TbeKernelJsonCreator::GenTbeOutputsJson(const std::shared_ptr<AnfNode> &anf
|
|
|
|
|
return GenOutputDescJson(anf_node, outputs_ptr, outputs_json);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelJsonCreator::GenOutputDescJson(const shared_ptr<mindspore::AnfNode> &anf_node,
|
|
|
|
|
const vector<shared_ptr<mindspore::kernel::OpIOInfo>> &outputs_ptr,
|
|
|
|
|
nlohmann::json *outputs_json) {
|
|
|
|
|
bool TbeKernelJsonCreator::GenOutputDescJson(
|
|
|
|
|
const std::shared_ptr<mindspore::AnfNode> &anf_node,
|
|
|
|
|
const std::vector<std::shared_ptr<mindspore::kernel::OpIOInfo>> &outputs_ptr, nlohmann::json *outputs_json) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(outputs_json);
|
|
|
|
|
size_t output_idx = 0;
|
|
|
|
|
auto op_name = AnfAlgo::GetCNodeName(anf_node);
|
|
|
|
@ -269,9 +303,9 @@ bool TbeKernelJsonCreator::GenOutputDescJson(const shared_ptr<mindspore::AnfNode
|
|
|
|
|
|
|
|
|
|
for (const auto &output_ptr : outputs_ptr) {
|
|
|
|
|
size_t output_obj_num = 0;
|
|
|
|
|
if (output_ptr->param_type() == "required") {
|
|
|
|
|
if (output_ptr->param_type() == kParamRequred) {
|
|
|
|
|
output_obj_num = 1;
|
|
|
|
|
} else if (output_ptr->param_type() == "dynamic") {
|
|
|
|
|
} else if (output_ptr->param_type() == kParamDynamic) {
|
|
|
|
|
if (outputs_ptr.size() > 1) {
|
|
|
|
|
MS_LOG(ERROR) << "Dynamic output is unsupported multi output!";
|
|
|
|
|
return false;
|
|
|
|
@ -282,8 +316,8 @@ bool TbeKernelJsonCreator::GenOutputDescJson(const shared_ptr<mindspore::AnfNode
|
|
|
|
|
MS_LOG(INFO) << "op:" << op_name << ", output" << output_ptr->name() << " is optional, output is none.";
|
|
|
|
|
std::vector<nlohmann::json> output_list;
|
|
|
|
|
nlohmann::json output_obj;
|
|
|
|
|
output_obj["name"] = output_ptr->name();
|
|
|
|
|
output_obj["valid"] = false;
|
|
|
|
|
output_obj[kJName] = output_ptr->name();
|
|
|
|
|
output_obj[kJValid] = false;
|
|
|
|
|
output_list.emplace_back(output_obj);
|
|
|
|
|
(*outputs_json).push_back(output_list);
|
|
|
|
|
continue;
|
|
|
|
@ -298,9 +332,9 @@ bool TbeKernelJsonCreator::GenOutputDescJson(const shared_ptr<mindspore::AnfNode
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TbeKernelJsonCreator::GenOutputList(const shared_ptr<AnfNode> &anf_node, const size_t &output_obj_num,
|
|
|
|
|
const shared_ptr<OpIOInfo> &output_ptr, size_t *output_idx,
|
|
|
|
|
vector<nlohmann::json> *output_list) {
|
|
|
|
|
void TbeKernelJsonCreator::GenOutputList(const std::shared_ptr<AnfNode> &anf_node, const size_t &output_obj_num,
|
|
|
|
|
const std::shared_ptr<OpIOInfo> &output_ptr, size_t *output_idx,
|
|
|
|
|
std::vector<nlohmann::json> *output_list) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(output_idx);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(output_list);
|
|
|
|
|
for (size_t i = 0; i < output_obj_num; i++) {
|
|
|
|
@ -312,14 +346,14 @@ void TbeKernelJsonCreator::GenOutputList(const shared_ptr<AnfNode> &anf_node, co
|
|
|
|
|
ori_shape.emplace_back(1);
|
|
|
|
|
}
|
|
|
|
|
nlohmann::json output_obj;
|
|
|
|
|
output_obj["dtype"] = dtype;
|
|
|
|
|
output_obj["shape"] = shape;
|
|
|
|
|
output_obj["format"] = format;
|
|
|
|
|
output_obj["ori_shape"] = ori_shape;
|
|
|
|
|
output_obj["ori_format"] = kOpFormat_NCHW;
|
|
|
|
|
output_obj["name"] = output_ptr->name();
|
|
|
|
|
output_obj["valid"] = true;
|
|
|
|
|
output_obj["param_type"] = output_ptr->param_type();
|
|
|
|
|
output_obj[kJDtype] = dtype;
|
|
|
|
|
output_obj[kJShape] = shape;
|
|
|
|
|
output_obj[kJFormat] = format;
|
|
|
|
|
output_obj[kJOriShape] = ori_shape;
|
|
|
|
|
output_obj[kJOriFormat] = kOpFormat_NCHW;
|
|
|
|
|
output_obj[kJName] = output_ptr->name();
|
|
|
|
|
output_obj[kJValid] = true;
|
|
|
|
|
output_obj[kJParamType] = output_ptr->param_type();
|
|
|
|
|
output_list->emplace_back(output_obj);
|
|
|
|
|
(*output_idx)++;
|
|
|
|
|
}
|
|
|
|
@ -340,24 +374,24 @@ bool TbeKernelJsonCreator::GenTbeAttrJson(const std::shared_ptr<AnfNode> &anf_no
|
|
|
|
|
for (const auto &attr_ptr : attrs_ptr) {
|
|
|
|
|
std::string attr_name = attr_ptr->name();
|
|
|
|
|
nlohmann::json attr_obj;
|
|
|
|
|
attr_obj["name"] = attr_name;
|
|
|
|
|
if (op_name == "LayerNorm" && attr_obj["name"] == "epsilon" && creater_type_ == OP_SELECT_FORMAT) {
|
|
|
|
|
attr_obj[kJName] = attr_name;
|
|
|
|
|
if (op_name == parallel::LAYER_NORM && attr_obj[kJName] == "epsilon" && creater_type_ == OP_SELECT_FORMAT) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (primitive->GetAttr(attr_name) != nullptr) {
|
|
|
|
|
auto value = primitive->GetAttr(attr_name);
|
|
|
|
|
std::string type = attr_ptr->type();
|
|
|
|
|
ParseAttrValue(type, value, &attr_obj);
|
|
|
|
|
attr_obj["valid"] = true;
|
|
|
|
|
attr_obj[kJValid] = true;
|
|
|
|
|
} else {
|
|
|
|
|
if (op_info->impl_path().empty()) {
|
|
|
|
|
attr_obj["valid"] = false;
|
|
|
|
|
attr_obj[kJValid] = false;
|
|
|
|
|
} else {
|
|
|
|
|
if (attr_ptr->param_type() == "required" && creater_type_ == SINGLE_BUILD) {
|
|
|
|
|
if (attr_ptr->param_type() == kParamRequred && creater_type_ == SINGLE_BUILD) {
|
|
|
|
|
MS_LOG(EXCEPTION) << "op name: " << op_info->op_name() << " attr: " << attr_name
|
|
|
|
|
<< " is required, but not set.";
|
|
|
|
|
} else {
|
|
|
|
|
attr_obj["valid"] = false;
|
|
|
|
|
attr_obj[kJValid] = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -370,48 +404,48 @@ void TbeKernelJsonCreator::ParseAttrValue(const std::string &type, const mindspo
|
|
|
|
|
nlohmann::json *attr_obj) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(value);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(attr_obj);
|
|
|
|
|
if (type == "int") {
|
|
|
|
|
if (type == kVTypeInt) {
|
|
|
|
|
auto attr_value = GetValue<int>(value);
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "str") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeStr) {
|
|
|
|
|
auto attr_value = GetValue<std::string>(value);
|
|
|
|
|
if (attr_value == kOpFormat_FRAC_Z) {
|
|
|
|
|
attr_value = kOpFormat_FRACTAL_Z;
|
|
|
|
|
}
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "bool") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeBool) {
|
|
|
|
|
auto attr_value = GetValue<bool>(value);
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "float") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeFloat) {
|
|
|
|
|
auto attr_value = GetValue<float>(value);
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "listInt") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeListInt) {
|
|
|
|
|
std::vector<int> attr_value;
|
|
|
|
|
auto value_type = value->type();
|
|
|
|
|
MS_EXCEPTION_IF_NULL(value_type);
|
|
|
|
|
auto value_type_str = value_type->ToString();
|
|
|
|
|
if (value_type_str == "Int32") {
|
|
|
|
|
if (value_type_str == kVTypeInt32) {
|
|
|
|
|
int data = GetValue<int>(value);
|
|
|
|
|
attr_value.push_back(data);
|
|
|
|
|
} else {
|
|
|
|
|
attr_value = GetValue<std::vector<int>>(value);
|
|
|
|
|
}
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "listFloat") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeListFloat) {
|
|
|
|
|
std::vector<float> attr_value;
|
|
|
|
|
auto value_type = value->type();
|
|
|
|
|
MS_EXCEPTION_IF_NULL(value_type);
|
|
|
|
|
auto value_type_str = value_type->ToString();
|
|
|
|
|
if (value_type_str == "float") {
|
|
|
|
|
if (value_type_str == kVTypeFloat) {
|
|
|
|
|
auto data = GetValue<float>(value);
|
|
|
|
|
attr_value.push_back(data);
|
|
|
|
|
} else {
|
|
|
|
|
attr_value = GetValue<std::vector<float>>(value);
|
|
|
|
|
}
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
} else if (type == "listListInt") {
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else if (type == kVTypeListListInt) {
|
|
|
|
|
auto attr_value = GetValue<std::vector<std::vector<int>>>(value);
|
|
|
|
|
(*attr_obj)["value"] = attr_value;
|
|
|
|
|
(*attr_obj)[kJValue] = attr_value;
|
|
|
|
|
} else {
|
|
|
|
|
MS_LOG(EXCEPTION) << "type: " << type << "not support";
|
|
|
|
|
}
|
|
|
|
@ -503,35 +537,35 @@ bool TbeKernelBuild::GetIOSize(const nlohmann::json &kernel_json, std::vector<si
|
|
|
|
|
}
|
|
|
|
|
input_size_list->clear();
|
|
|
|
|
output_size_list->clear();
|
|
|
|
|
for (size_t i = 0; i < kernel_json["op_info"]["inputs"].size(); i++) {
|
|
|
|
|
for (size_t m = 0; m < kernel_json["op_info"]["inputs"][i].size(); m++) {
|
|
|
|
|
for (size_t i = 0; i < kernel_json[kJOpInfo][kJInputs].size(); i++) {
|
|
|
|
|
for (size_t m = 0; m < kernel_json[kJOpInfo][kJInputs][i].size(); m++) {
|
|
|
|
|
size_t size_i = 1;
|
|
|
|
|
if (kernel_json["op_info"]["inputs"][i][m]["valid"] == false) {
|
|
|
|
|
std::string input_name = kernel_json["op_info"]["inputs"][i][m]["name"];
|
|
|
|
|
if (kernel_json[kJOpInfo][kJInputs][i][m][kJValid] == false) {
|
|
|
|
|
std::string input_name = kernel_json[kJOpInfo][kJInputs][i][m][kJName];
|
|
|
|
|
MS_LOG(INFO) << "Input name:" << input_name << "is optional, valid is false.";
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (const auto &j : kernel_json["op_info"]["inputs"][i][m]["shape"]) {
|
|
|
|
|
for (const auto &j : kernel_json[kJOpInfo][kJInputs][i][m][kJShape]) {
|
|
|
|
|
size_i *= static_cast<size_t>(j);
|
|
|
|
|
}
|
|
|
|
|
std::string dtype = kernel_json["op_info"]["inputs"][i][m]["dtype"];
|
|
|
|
|
std::string dtype = kernel_json[kJOpInfo][kJInputs][i][m][kJDtype];
|
|
|
|
|
size_t nbyte = tbe::GetDtypeNbyte(dtype);
|
|
|
|
|
size_i *= nbyte;
|
|
|
|
|
input_size_list->push_back(size_i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (size_t i = 0; i < kernel_json["op_info"]["outputs"].size(); i++) {
|
|
|
|
|
for (size_t m = 0; m < kernel_json["op_info"]["outputs"][i].size(); m++) {
|
|
|
|
|
for (size_t i = 0; i < kernel_json[kJOpInfo][kJOutputs].size(); i++) {
|
|
|
|
|
for (size_t m = 0; m < kernel_json[kJOpInfo][kJOutputs][i].size(); m++) {
|
|
|
|
|
size_t size_i = 1;
|
|
|
|
|
if (kernel_json["op_info"]["outputs"][i][m]["valid"] == false) {
|
|
|
|
|
std::string output_name = kernel_json["op_info"]["outputs"][i][m]["name"];
|
|
|
|
|
if (kernel_json[kJOpInfo][kJOutputs][i][m][kJValid] == false) {
|
|
|
|
|
std::string output_name = kernel_json[kJOpInfo][kJOutputs][i][m][kJName];
|
|
|
|
|
MS_LOG(INFO) << "Output name:" << output_name << " is optional, valid is false.";
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
for (const auto &j : kernel_json["op_info"]["outputs"][i][m]["shape"]) {
|
|
|
|
|
for (const auto &j : kernel_json[kJOpInfo][kJOutputs][i][m][kJShape]) {
|
|
|
|
|
size_i *= static_cast<size_t>(j);
|
|
|
|
|
}
|
|
|
|
|
std::string dtype = kernel_json["op_info"]["outputs"][i][m]["dtype"];
|
|
|
|
|
std::string dtype = kernel_json[kJOpInfo][kJOutputs][i][m][kJDtype];
|
|
|
|
|
size_t nbyte = tbe::GetDtypeNbyte(dtype);
|
|
|
|
|
size_i *= nbyte;
|
|
|
|
|
output_size_list->push_back(size_i);
|
|
|
|
@ -540,9 +574,9 @@ bool TbeKernelBuild::GetIOSize(const nlohmann::json &kernel_json, std::vector<si
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelBuild::GenFusionScopeJson(const vector<mindspore::AnfNodePtr> &input_nodes,
|
|
|
|
|
const vector<mindspore::AnfNodePtr> &compute_nodes, nlohmann::json *fusion_str,
|
|
|
|
|
std::string *fusion_kernel) {
|
|
|
|
|
bool TbeKernelBuild::GenFusionScopeJson(const std::vector<mindspore::AnfNodePtr> &input_nodes,
|
|
|
|
|
const std::vector<mindspore::AnfNodePtr> &compute_nodes,
|
|
|
|
|
nlohmann::json *fusion_str, std::string *fusion_kernel) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(fusion_str);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(fusion_kernel);
|
|
|
|
|
// get input layer info
|
|
|
|
@ -552,7 +586,7 @@ bool TbeKernelBuild::GenFusionScopeJson(const vector<mindspore::AnfNodePtr> &inp
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// gen fusion scopre_op jsom
|
|
|
|
|
vector<nlohmann::json> compute_list;
|
|
|
|
|
std::vector<nlohmann::json> compute_list;
|
|
|
|
|
(*fusion_kernel) = kFusionKernelNamePrfix;
|
|
|
|
|
// index: fusion build option input record, next one from 0
|
|
|
|
|
static size_t index = 0;
|
|
|
|
@ -565,7 +599,7 @@ bool TbeKernelBuild::GenFusionScopeJson(const vector<mindspore::AnfNodePtr> &inp
|
|
|
|
|
}
|
|
|
|
|
index = 0;
|
|
|
|
|
// gen data input json
|
|
|
|
|
vector<nlohmann::json> data_list;
|
|
|
|
|
std::vector<nlohmann::json> data_list;
|
|
|
|
|
for (const auto &layer : input_layers) {
|
|
|
|
|
for (const auto &data_input : layer) {
|
|
|
|
|
nlohmann::json data_str;
|
|
|
|
@ -588,51 +622,51 @@ void TbeKernelBuild::GenDescJson(const std::shared_ptr<mindspore::AnfNode> &anf_
|
|
|
|
|
if (node_out_idx > 0) {
|
|
|
|
|
output_desc_name = output_desc_name + "_" + std::to_string(node_out_idx);
|
|
|
|
|
}
|
|
|
|
|
(*output_desc)["name"] = NormalizeFullScopeName(output_desc_name);
|
|
|
|
|
(*output_desc)[kJName] = NormalizeFullScopeName(output_desc_name);
|
|
|
|
|
auto type_id = AnfAlgo::GetOutputDeviceDataType(anf_node, node_out_idx);
|
|
|
|
|
(*output_desc)["data_type"] = tbe::TypeIdToString(type_id);
|
|
|
|
|
(*output_desc)[kJDataType] = tbe::TypeIdToString(type_id);
|
|
|
|
|
auto ori_shape = AnfAlgo::GetOutputInferShape(anf_node, node_out_idx);
|
|
|
|
|
if (ori_shape.empty()) {
|
|
|
|
|
ori_shape.emplace_back(1);
|
|
|
|
|
}
|
|
|
|
|
(*output_desc)["ori_shape"] = ori_shape;
|
|
|
|
|
(*output_desc)[kJOriShape] = ori_shape;
|
|
|
|
|
auto shape = AnfAlgo::GetOutputDeviceShape(anf_node, node_out_idx);
|
|
|
|
|
if (shape.empty()) {
|
|
|
|
|
shape.emplace_back(1);
|
|
|
|
|
}
|
|
|
|
|
(*output_desc)["shape"] = shape;
|
|
|
|
|
(*output_desc)[kJShape] = shape;
|
|
|
|
|
auto format = AnfAlgo::GetOutputFormat(anf_node, node_out_idx);
|
|
|
|
|
if (format == kOpFormat_DEFAULT) {
|
|
|
|
|
format = ori_shape.size() == 4 ? kOpFormat_NCHW : kOpFormat_ND;
|
|
|
|
|
}
|
|
|
|
|
(*output_desc)["format"] = format;
|
|
|
|
|
(*output_desc)["ori_format"] = kOpFormat_NCHW;
|
|
|
|
|
(*output_desc)["output_index"] = desc_output_idx;
|
|
|
|
|
(*output_desc)[kJFormat] = format;
|
|
|
|
|
(*output_desc)[kJOriFormat] = kOpFormat_NCHW;
|
|
|
|
|
(*output_desc)[kJOutputIndex] = desc_output_idx;
|
|
|
|
|
if (fusion_data_type == kFusionAddN && format == kOpFormat_NC1HWC0) {
|
|
|
|
|
std::vector<size_t> spec_shape = {};
|
|
|
|
|
spec_shape.emplace_back(shape[0]);
|
|
|
|
|
spec_shape.emplace_back(shape[1]);
|
|
|
|
|
spec_shape.emplace_back(shape[2] * shape[3]);
|
|
|
|
|
spec_shape.emplace_back(shape[4]);
|
|
|
|
|
(*output_desc)["shape"] = spec_shape;
|
|
|
|
|
(*output_desc)[kJShape] = spec_shape;
|
|
|
|
|
} else if (fusion_data_type == kFusionReLUGradV2) {
|
|
|
|
|
std::vector<size_t> spec_shape = {};
|
|
|
|
|
spec_shape.emplace_back(shape[0]);
|
|
|
|
|
spec_shape.emplace_back(shape[1]);
|
|
|
|
|
spec_shape.emplace_back(shape[2] * shape[3]);
|
|
|
|
|
spec_shape.emplace_back(16);
|
|
|
|
|
(*output_desc)["shape"] = spec_shape;
|
|
|
|
|
(*output_desc)["data_type"] = "bool";
|
|
|
|
|
(*output_desc)[kJShape] = spec_shape;
|
|
|
|
|
(*output_desc)[kJDataType] = kVTypeBool;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TbeKernelBuild::GenReusedOutputDesc(const shared_ptr<mindspore::AnfNode> &anf_node, size_t index,
|
|
|
|
|
void TbeKernelBuild::GenReusedOutputDesc(const std::shared_ptr<mindspore::AnfNode> &anf_node, size_t index,
|
|
|
|
|
size_t output_index, nlohmann::json *output_desc) {
|
|
|
|
|
std::string output_desc_name = anf_node->fullname_with_scope() + "_" + std::to_string(index);
|
|
|
|
|
(*output_desc)["name"] = NormalizeFullScopeName(output_desc_name);
|
|
|
|
|
(*output_desc)["output_index"] = output_index;
|
|
|
|
|
(*output_desc)[kJName] = NormalizeFullScopeName(output_desc_name);
|
|
|
|
|
(*output_desc)[kJOutputIndex] = output_index;
|
|
|
|
|
std::vector<size_t> shape;
|
|
|
|
|
(*output_desc)["shape"] = shape;
|
|
|
|
|
(*output_desc)[kJShape] = shape;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelBuild::GetSpecInputLayers(const std::string &op_name,
|
|
|
|
@ -657,6 +691,8 @@ bool TbeKernelBuild::GetInputLayers(const std::vector<mindspore::AnfNodePtr> &in
|
|
|
|
|
const std::vector<mindspore::AnfNodePtr> &compute_nodes,
|
|
|
|
|
std::vector<std::vector<mindspore::AnfNodePtr>> *input_layers,
|
|
|
|
|
std::map<const AnfNodePtr, FusionDataType> *spec_data_input) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_layers);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(spec_data_input);
|
|
|
|
|
auto result = std::find_if(compute_nodes.begin(), compute_nodes.end(), [](const auto &it) {
|
|
|
|
|
auto op_name = AnfAlgo::GetCNodeName(it);
|
|
|
|
|
return op_name == kConv2DBackpropInputOpName;
|
|
|
|
@ -712,10 +748,10 @@ bool TbeKernelBuild::GenFusionDataInputJson(const std::shared_ptr<mindspore::Anf
|
|
|
|
|
if (!data_input) {
|
|
|
|
|
MS_LOG(INFO) << "data input is optional node";
|
|
|
|
|
auto name = std::string(kOptional) + std::to_string(*index);
|
|
|
|
|
(*data_str)["name"] = name;
|
|
|
|
|
(*data_str)[kJName] = name;
|
|
|
|
|
nlohmann::json output_desc;
|
|
|
|
|
output_desc["name"] = name;
|
|
|
|
|
output_desc["shape"] = "NULL";
|
|
|
|
|
output_desc[kJName] = name;
|
|
|
|
|
output_desc[kJShape] = "NULL";
|
|
|
|
|
output_desc_list.push_back(output_desc);
|
|
|
|
|
(*index)++;
|
|
|
|
|
} else {
|
|
|
|
@ -727,14 +763,14 @@ bool TbeKernelBuild::GenFusionDataInputJson(const std::shared_ptr<mindspore::Anf
|
|
|
|
|
auto real_node = kernel_idx.first;
|
|
|
|
|
size_t real_idx = kernel_idx.second;
|
|
|
|
|
MS_LOG(INFO) << "real name " << real_node->fullname_with_scope() << " index:" << real_idx;
|
|
|
|
|
// "output_desc"
|
|
|
|
|
// kJOutputDesc
|
|
|
|
|
nlohmann::json output_desc;
|
|
|
|
|
GenDescJson(real_node, real_idx, real_idx, &output_desc, fusion_data_type);
|
|
|
|
|
output_desc_list.push_back(output_desc);
|
|
|
|
|
(*data_str)["name"] = NormalizeFullScopeName(real_node->fullname_with_scope());
|
|
|
|
|
(*data_str)[kJName] = NormalizeFullScopeName(real_node->fullname_with_scope());
|
|
|
|
|
}
|
|
|
|
|
(*data_str)["output_desc"] = output_desc_list;
|
|
|
|
|
(*data_str)["type"] = "Data";
|
|
|
|
|
(*data_str)[kJOutputDesc] = output_desc_list;
|
|
|
|
|
(*data_str)[kJtype] = "Data";
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -765,6 +801,7 @@ bool TbeKernelBuild::IsDynamicInput(const mindspore::CNodePtr &cnode) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t TbeKernelBuild::GetOptionalInput(const mindspore::CNodePtr &cnode, bool is_dynamic_input) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(cnode);
|
|
|
|
|
if (is_dynamic_input) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -779,8 +816,8 @@ size_t TbeKernelBuild::GetOptionalInput(const mindspore::CNodePtr &cnode, bool i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string TbeKernelBuild::GetRealOpType(const std::string &origin_type) {
|
|
|
|
|
static std::map<std::string, std::string> buffer_fussion_op_map = {{"DepthwiseConv2dNative", "DepthwiseConv2D"},
|
|
|
|
|
{"TensorAdd", "Add"}};
|
|
|
|
|
static std::map<std::string, std::string> buffer_fussion_op_map = {
|
|
|
|
|
{parallel::DEPTHWISE_CONV2D_NATIVE, parallel::DEPTHWISE_CONV2D}, {parallel::TENSOR_ADD, parallel::ADD}};
|
|
|
|
|
string result = origin_type;
|
|
|
|
|
auto iter = buffer_fussion_op_map.find(origin_type);
|
|
|
|
|
if (iter != buffer_fussion_op_map.end()) {
|
|
|
|
@ -806,7 +843,7 @@ bool TbeKernelBuild::GenFusionComputeInputJson(const mindspore::CNodePtr &cnode,
|
|
|
|
|
GenDescJson(real_node, real_idx, real_idx, &input_desc);
|
|
|
|
|
if (is_dynamic_input) {
|
|
|
|
|
MS_LOG(INFO) << "node has dynamic input.";
|
|
|
|
|
input_desc["dyn_index"] = (i - 1);
|
|
|
|
|
input_desc[kJDynIndex] = (i - 1);
|
|
|
|
|
}
|
|
|
|
|
input_desc_list_tmp.emplace_back(input_desc);
|
|
|
|
|
}
|
|
|
|
@ -815,7 +852,7 @@ bool TbeKernelBuild::GenFusionComputeInputJson(const mindspore::CNodePtr &cnode,
|
|
|
|
|
MS_LOG(INFO) << "node has optional input.";
|
|
|
|
|
for (size_t i = 0; i < optional_num; ++i) {
|
|
|
|
|
nlohmann::json optional_input_desc;
|
|
|
|
|
optional_input_desc["name"] = std::string(kOptional) + std::to_string(*index);
|
|
|
|
|
optional_input_desc[kJName] = std::string(kOptional) + std::to_string(*index);
|
|
|
|
|
(*index)++;
|
|
|
|
|
(*layer_iter)->emplace_back(nullptr);
|
|
|
|
|
input_desc_list_tmp.emplace_back(optional_input_desc);
|
|
|
|
@ -841,6 +878,7 @@ std::vector<size_t> TbeKernelBuild::GetDescOutputIndex(const std::vector<int> &o
|
|
|
|
|
|
|
|
|
|
bool TbeKernelBuild::GenFusionComputeOutputJson(const mindspore::CNodePtr &cnode,
|
|
|
|
|
std::vector<nlohmann::json> *output_desc_list) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(output_desc_list);
|
|
|
|
|
auto output_size = AnfAlgo::GetOutputTensorNum(cnode);
|
|
|
|
|
if (AnfAlgo::HasNodeAttr(kAttrOutputUsedNum, cnode)) {
|
|
|
|
|
auto output_used_nums = AnfAlgo::GetNodeAttr<std::vector<int>>(cnode, kAttrOutputUsedNum);
|
|
|
|
@ -883,22 +921,22 @@ bool TbeKernelBuild::GenFusionComputeJson(const mindspore::AnfNodePtr &compute_n
|
|
|
|
|
// gen input desc
|
|
|
|
|
std::vector<nlohmann::json> input_desc_list;
|
|
|
|
|
(void)GenFusionComputeInputJson(cnode, layer_iter, &input_desc_list, index);
|
|
|
|
|
(*compute_op_str)["input_desc"] = input_desc_list;
|
|
|
|
|
(*compute_op_str)[kJInputDesc] = input_desc_list;
|
|
|
|
|
// gen output desc
|
|
|
|
|
std::vector<nlohmann::json> output_desc_list;
|
|
|
|
|
if (!GenFusionComputeOutputJson(cnode, &output_desc_list)) {
|
|
|
|
|
MS_LOG(INFO) << "Fusion Error: gen fusion output desc faild, node full name: " << cnode->fullname_with_scope();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
(*compute_op_str)["output_desc"] = output_desc_list;
|
|
|
|
|
(*compute_op_str)[kJOutputDesc] = output_desc_list;
|
|
|
|
|
// gen others
|
|
|
|
|
auto origin_type = AnfAlgo::GetCNodeName(cnode);
|
|
|
|
|
// replace special op type for buffer fusion op
|
|
|
|
|
auto type = GetRealOpType(origin_type);
|
|
|
|
|
(*compute_op_str)["type"] = type;
|
|
|
|
|
(*compute_op_str)[kJtype] = type;
|
|
|
|
|
tbe::TbeAdapter::NormalizeFuncName(&type);
|
|
|
|
|
(*compute_op_str)["func_name"] = type;
|
|
|
|
|
(*compute_op_str)["name"] = NormalizeFullScopeName(cnode->fullname_with_scope());
|
|
|
|
|
(*compute_op_str)[kJFuncName] = type;
|
|
|
|
|
(*compute_op_str)[kJName] = NormalizeFullScopeName(cnode->fullname_with_scope());
|
|
|
|
|
(void)(*fusion_kernel_name).append("_");
|
|
|
|
|
(void)(*fusion_kernel_name).append(type);
|
|
|
|
|
return true;
|
|
|
|
@ -906,16 +944,17 @@ bool TbeKernelBuild::GenFusionComputeJson(const mindspore::AnfNodePtr &compute_n
|
|
|
|
|
|
|
|
|
|
size_t TbeKernelBuild::GetIOSizeImpl(const nlohmann::json &desc) {
|
|
|
|
|
size_t ret = 1;
|
|
|
|
|
for (const auto &shape_item : desc["shape"]) {
|
|
|
|
|
for (const auto &shape_item : desc[kJShape]) {
|
|
|
|
|
ret *= static_cast<size_t>(shape_item);
|
|
|
|
|
}
|
|
|
|
|
std::string data_type = desc["data_type"];
|
|
|
|
|
std::string data_type = desc[kJDataType];
|
|
|
|
|
size_t nbyte = tbe::GetDtypeNbyte(data_type);
|
|
|
|
|
ret *= nbyte;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool TbeKernelBuild::GetIOSize(const nlohmann::json &fusion_op_list, const vector<mindspore::AnfNodePtr> &output_nodes,
|
|
|
|
|
bool TbeKernelBuild::GetIOSize(const nlohmann::json &fusion_op_list,
|
|
|
|
|
const std::vector<mindspore::AnfNodePtr> &output_nodes,
|
|
|
|
|
std::vector<size_t> *input_size_list, std::vector<size_t> *output_size_list) {
|
|
|
|
|
MS_EXCEPTION_IF_NULL(input_size_list);
|
|
|
|
|
MS_EXCEPTION_IF_NULL(output_size_list);
|
|
|
|
@ -923,15 +962,15 @@ bool TbeKernelBuild::GetIOSize(const nlohmann::json &fusion_op_list, const vecto
|
|
|
|
|
output_size_list->clear();
|
|
|
|
|
|
|
|
|
|
for (const auto &op : fusion_op_list) {
|
|
|
|
|
if (op["type"] == "Data") {
|
|
|
|
|
const auto &data_output_desc = op["output_desc"];
|
|
|
|
|
if (op[kJtype] == "Data") {
|
|
|
|
|
const auto &data_output_desc = op[kJOutputDesc];
|
|
|
|
|
for (const auto &data_output : data_output_desc) {
|
|
|
|
|
if (data_output["shape"] == "NULL") {
|
|
|
|
|
if (data_output[kJShape] == "NULL") {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
auto ret = GetIOSizeImpl(data_output);
|
|
|
|
|
input_size_list->push_back(ret);
|
|
|
|
|
MS_LOG(INFO) << "Fusion info: scope input name: " << op["name"] << ", size: " << ret;
|
|
|
|
|
MS_LOG(INFO) << "Fusion info: scope input name: " << op[kJName] << ", size: " << ret;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -943,13 +982,13 @@ bool TbeKernelBuild::GetIOSize(const nlohmann::json &fusion_op_list, const vecto
|
|
|
|
|
auto normal_name = NormalizeFullScopeName(real_node->fullname_with_scope());
|
|
|
|
|
MS_LOG(INFO) << "Fusion info: real node name: " << normal_name << ", real output index: " << real_idx;
|
|
|
|
|
for (const auto &op : fusion_op_list) {
|
|
|
|
|
if (op["name"] == normal_name) {
|
|
|
|
|
auto op_output_desces = op["output_desc"];
|
|
|
|
|
if (op[kJName] == normal_name) {
|
|
|
|
|
auto op_output_desces = op[kJOutputDesc];
|
|
|
|
|
if (output_node != real_node) {
|
|
|
|
|
// tuple_get item
|
|
|
|
|
MS_LOG(INFO) << "output is a tuple getitem node";
|
|
|
|
|
auto output_desc = op_output_desces[real_idx];
|
|
|
|
|
if (output_desc["shape"].empty()) {
|
|
|
|
|
if (output_desc[kJShape].empty()) {
|
|
|
|
|
MS_LOG(INFO) << "Fusion error: output_desc's shape is empty. real_index " << real_idx;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -958,7 +997,7 @@ bool TbeKernelBuild::GetIOSize(const nlohmann::json &fusion_op_list, const vecto
|
|
|
|
|
MS_LOG(INFO) << "Fusion info: scope output index: " << real_idx << ", size: " << ret;
|
|
|
|
|
} else {
|
|
|
|
|
for (const auto &output_desc : op_output_desces) {
|
|
|
|
|
if (output_desc["shape"].empty()) {
|
|
|
|
|
if (output_desc[kJShape].empty()) {
|
|
|
|
|
MS_LOG(INFO) << "Fusion info: output_desc's shape is empty, may be this node output";
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|