forked from huawei/mindspore2022
518 lines
19 KiB
C++
518 lines
19 KiB
C++
/**
|
|
* Copyright 2019 Huawei Technologies Co., Ltd
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "kernel/akg/akgkernelbuild.h"
|
|
#include <Python.h>
|
|
#include <sys/types.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
#include <cctype>
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <map>
|
|
#include <utility>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
#include <sstream>
|
|
#include <iterator>
|
|
#include <numeric>
|
|
#include <unordered_set>
|
|
#include "common/utils.h"
|
|
#include "utils/convert_utils.h"
|
|
#include "utils/any.h"
|
|
#include "utils/utils.h"
|
|
#include "session/anf_runtime_algorithm.h"
|
|
#include "kernel/akg/akg_kernel_attrs_process.h"
|
|
|
|
namespace mindspore {
|
|
namespace kernel {
|
|
constexpr int ME_MAX_KERNEL_NAME_LENGTH = 200;
|
|
constexpr int32_t ARGS_SIZE = 1;
|
|
constexpr auto kCompileWithJsonFunc = "compilewithjson";
|
|
// json key
|
|
constexpr auto kInputDesc = "input_desc";
|
|
constexpr auto kShape = "shape";
|
|
constexpr auto kDataType = "data_type";
|
|
constexpr auto kOutputDesc = "output_desc";
|
|
constexpr auto kName = "name";
|
|
constexpr auto kTensorName = "tensor_name";
|
|
constexpr auto kValue = "value";
|
|
constexpr auto KInpputNames = "input_names";
|
|
constexpr auto KInput = "input";
|
|
constexpr auto KDtype = "dtype";
|
|
int AkgKernelBuild::op_cnt_ = 0;
|
|
std::mutex AkgKernelBuild::op_cnt_mtx_;
|
|
|
|
std::string PyObjectToStr(PyObject *const PyObj) {
|
|
char *pChar = nullptr;
|
|
std::string str_res;
|
|
if (PyObj == nullptr) {
|
|
MS_LOG(ERROR) << "Input parameter is nullptr.";
|
|
return str_res;
|
|
}
|
|
PyObject *strArgs = PyObject_Str(PyObj);
|
|
if (strArgs != nullptr) {
|
|
(void)PyArg_Parse(strArgs, "s", &pChar);
|
|
}
|
|
if (pChar == nullptr) {
|
|
MS_LOG(ERROR) << "pChar is nullptr.";
|
|
return str_res;
|
|
}
|
|
str_res = pChar;
|
|
return str_res;
|
|
}
|
|
|
|
std::string AkgKernelBuild::GetProcessor(const AnfNodePtr &anf_node) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
std::string device;
|
|
switch (AnfAlgo::GetProcessor(anf_node)) {
|
|
case Processor::AICORE:
|
|
device = kProcessorAiCore;
|
|
break;
|
|
|
|
case Processor::AICPU:
|
|
device = kProcessorAiCpu;
|
|
break;
|
|
|
|
case Processor::CUDA:
|
|
device = kProcessorCuda;
|
|
break;
|
|
|
|
default:
|
|
MS_LOG(ERROR) << "Unknown processor type.";
|
|
break;
|
|
}
|
|
|
|
return device;
|
|
}
|
|
|
|
bool GetIOSize(const nlohmann::json &node_json, std::vector<size_t> *const input_size,
|
|
std::vector<size_t> *const output_size) {
|
|
if (input_size == nullptr || output_size == nullptr) {
|
|
MS_LOG(ERROR) << "input size or output size is nullptr";
|
|
return false;
|
|
}
|
|
input_size->clear();
|
|
output_size->clear();
|
|
|
|
for (size_t i = 0; i < node_json[kInputDesc].size(); i++) {
|
|
for (size_t m = 0; m < node_json[kInputDesc][i].size(); m++) {
|
|
std::string dtype = node_json[kInputDesc][i][m][kDataType];
|
|
size_t nbyte = GetDtypeNbyte(dtype);
|
|
size_t size_i = std::accumulate(node_json[kInputDesc][i][m][kShape].begin(),
|
|
node_json[kInputDesc][i][m][kShape].end(), nbyte, std::multiplies<size_t>());
|
|
input_size->push_back(size_i);
|
|
}
|
|
}
|
|
|
|
for (size_t i = 0; i < node_json[kOutputDesc].size(); i++) {
|
|
std::string dtype = node_json[kOutputDesc][i][kDataType];
|
|
size_t nbyte = GetDtypeNbyte(dtype);
|
|
size_t size_i = std::accumulate(node_json[kOutputDesc][i][kShape].begin(), node_json[kOutputDesc][i][kShape].end(),
|
|
nbyte, std::multiplies<size_t>());
|
|
output_size->push_back(size_i);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int AkgKernelBuild::GetOpCntInc() {
|
|
op_cnt_mtx_.lock();
|
|
int cnt = op_cnt_++;
|
|
op_cnt_mtx_.unlock();
|
|
return cnt;
|
|
}
|
|
|
|
bool AkgKernelBuild::CreateInputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const inputs_json) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
MS_EXCEPTION_IF_NULL(inputs_json);
|
|
|
|
// for dynamic input number, dyn_input_sizes has the info of dynamic input num for each input.
|
|
std::string op_name = AnfAlgo::GetCNodeName(anf_node);
|
|
auto op_info = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
|
|
if (op_info == nullptr) {
|
|
MS_LOG(ERROR) << "Apply kernel [" << op_name << "] op_info is nullptr";
|
|
return false;
|
|
}
|
|
|
|
std::vector<std::shared_ptr<OpIOInfo>> inputs_ptr = op_info->inputs_ptr();
|
|
if (inputs_ptr.empty()) {
|
|
MS_LOG(INFO) << "Apply kernel [" << op_name << "] regist info has no input info";
|
|
return true;
|
|
}
|
|
auto op_info_input_num = inputs_ptr.size();
|
|
|
|
// for dynamic input number, dyn_input_sizes has the info of dynamic input num for each input.
|
|
std::vector<int> dyn_input_sizes;
|
|
auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
|
|
MS_EXCEPTION_IF_NULL(primitive);
|
|
|
|
if (primitive->GetAttr(kAttrDynInputSizes) != nullptr) {
|
|
dyn_input_sizes = GetValue<const std::vector<int>>(primitive->GetAttr(kAttrDynInputSizes));
|
|
}
|
|
|
|
size_t real_input_index = 0;
|
|
std::vector<nlohmann::json> input_list;
|
|
for (size_t i = 0; i < op_info_input_num; i++) {
|
|
size_t input_tensor_num;
|
|
std::shared_ptr<OpIOInfo> input_ptr = inputs_ptr[i];
|
|
std::string op_input_name;
|
|
if (input_ptr == nullptr) {
|
|
MS_LOG(ERROR) << "Apply kernel [" << op_name << "] regist input[" << i << "] is nullptr";
|
|
return false;
|
|
}
|
|
|
|
op_input_name = input_ptr->name();
|
|
if (dyn_input_sizes.empty()) {
|
|
input_tensor_num = 1;
|
|
} else {
|
|
input_tensor_num = IntToSize(dyn_input_sizes[i]);
|
|
}
|
|
|
|
input_list.clear();
|
|
for (size_t input_i = 0; input_i < input_tensor_num; input_i++) {
|
|
// dtype : float16
|
|
auto type_id = AnfAlgo::GetInputDeviceDataType(anf_node, real_input_index);
|
|
TypePtr type_ptr = TypeIdToType(type_id);
|
|
MS_EXCEPTION_IF_NULL(type_ptr);
|
|
std::string dtype = type_ptr->ToString();
|
|
dtype = Dtype2String(dtype);
|
|
if (dtype.empty()) {
|
|
MS_LOG(ERROR) << "Op [" << op_name << "] input [" << input_i << "] data type is null. ";
|
|
return false;
|
|
}
|
|
nlohmann::json input_desc_json;
|
|
input_desc_json[kDataType] = dtype;
|
|
input_desc_json[kName] = op_input_name;
|
|
input_desc_json[kTensorName] =
|
|
op_input_name + "_" + std::to_string(real_input_index) + "_" + std::to_string(input_i);
|
|
input_desc_json[kShape] = AnfAlgo::GetInputDeviceShape(anf_node, real_input_index);
|
|
input_list.emplace_back(input_desc_json);
|
|
}
|
|
inputs_json->emplace_back(input_list);
|
|
real_input_index++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AkgKernelBuild::CreateOutputDescJson(const AnfNodePtr &anf_node, nlohmann::json *const outputs_json) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
MS_EXCEPTION_IF_NULL(outputs_json);
|
|
size_t output_tensor_num = AnfAlgo::GetOutputTensorNum(anf_node);
|
|
std::string op_name = AnfAlgo::GetCNodeName(anf_node);
|
|
|
|
auto op_info_ptr = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
|
|
auto outputs = op_info_ptr->outputs_ptr();
|
|
for (size_t i = 0; i < output_tensor_num; i++) {
|
|
nlohmann::json output_json;
|
|
auto type_id = AnfAlgo::GetOutputDeviceDataType(anf_node, i);
|
|
TypePtr type_ptr = TypeIdToType(type_id);
|
|
MS_EXCEPTION_IF_NULL(type_ptr);
|
|
std::string dtype = type_ptr->ToString();
|
|
dtype = Dtype2String(dtype);
|
|
if (dtype.empty()) {
|
|
MS_LOG(ERROR) << "Op [" << op_name << "] output [" << i << "] data type is null. ";
|
|
return false;
|
|
}
|
|
|
|
std::string output_name = outputs[i]->name();
|
|
output_json[kDataType] = dtype;
|
|
output_json[kName] = output_name;
|
|
output_json[kTensorName] = output_name + "_" + std::to_string(i);
|
|
output_json[kShape] = AnfAlgo::GetOutputDeviceShape(anf_node, i);
|
|
outputs_json->push_back(output_json);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void GetJson(const AnfNodePtr &anf_node, const std::vector<int> &dyn_input_sizes,
|
|
const std::shared_ptr<OpAttr> &op_attr, nlohmann::json *const attr_json, const ValuePtr &attr_value) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
MS_EXCEPTION_IF_NULL(op_attr);
|
|
MS_EXCEPTION_IF_NULL(attr_json);
|
|
std::string type = op_attr->type();
|
|
if (type == "int") {
|
|
(*attr_json)[kValue] = GetValue<int>(attr_value);
|
|
} else if (type == "str") {
|
|
(*attr_json)[kValue] = GetValue<std::string>(attr_value);
|
|
} else if (type == "bool") {
|
|
(*attr_json)[kValue] = GetValue<bool>(attr_value);
|
|
} else if (type == "float") {
|
|
(*attr_json)[kValue] = GetValue<float>(attr_value);
|
|
} else if (type == "listInt") {
|
|
(*attr_json)[kValue] = GetValue<std::vector<int>>(attr_value);
|
|
} else if (type == "listStr") {
|
|
std::vector<std::string> data_format;
|
|
if (op_attr->name() == kArgDataformat) {
|
|
size_t tensor_args_num = !dyn_input_sizes.empty() ? dyn_input_sizes.size() : AnfAlgo::GetInputTensorNum(anf_node);
|
|
for (size_t format_i = 0; format_i < tensor_args_num; format_i++) {
|
|
auto input_format = AnfAlgo::GetInputFormat(anf_node, format_i);
|
|
data_format.push_back(input_format);
|
|
}
|
|
} else {
|
|
data_format = GetValue<std::vector<std::string>>(attr_value);
|
|
}
|
|
(*attr_json)[kValue] = data_format;
|
|
} else {
|
|
MS_LOG(WARNING) << "attr type:" << type;
|
|
}
|
|
}
|
|
|
|
bool AkgKernelBuild::CreateAttrDescJson(const AnfNodePtr &anf_node, const std::string &op_name,
|
|
const std::shared_ptr<OpInfo> &op_info, nlohmann::json *const attrs_json) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
MS_EXCEPTION_IF_NULL(attrs_json);
|
|
MS_EXCEPTION_IF_NULL(op_info);
|
|
std::vector<std::shared_ptr<OpAttr>> attrs = op_info->attrs_ptr();
|
|
if (attrs.empty()) {
|
|
MS_LOG(INFO) << "Apply kernel [" << op_name << "] op info attrs is empty";
|
|
return true;
|
|
}
|
|
std::vector<std::shared_ptr<OpIOInfo>> inputs = op_info->inputs_ptr();
|
|
|
|
std::vector<int> dyn_input_sizes;
|
|
auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
|
|
MS_EXCEPTION_IF_NULL(primitive);
|
|
if (primitive->GetAttr(kAttrDynInputSizes) != nullptr) {
|
|
dyn_input_sizes = GetValue<const std::vector<int>>(primitive->GetAttr(kAttrDynInputSizes));
|
|
}
|
|
|
|
if (inputs.empty()) {
|
|
MS_LOG(ERROR) << "Apply kernel [" << op_name << "] op info inputs is empty";
|
|
return false;
|
|
}
|
|
|
|
// create input name list for atch "x_shape" in att with "x" in primitive.
|
|
std::map<size_t, std::string> op_info_shape_name;
|
|
for (size_t op_info_input_i = 0; op_info_input_i < inputs.size(); op_info_input_i++) {
|
|
std::string input_name = inputs[op_info_input_i]->name();
|
|
std::string x_shape_name = input_name + "_shape";
|
|
(void)op_info_shape_name.insert(make_pair(op_info_input_i, x_shape_name));
|
|
}
|
|
|
|
for (const auto &op_attr : attrs) {
|
|
nlohmann::json attr_json;
|
|
ValuePtr attr_value = primitive->GetAttr(op_attr->name());
|
|
if (attr_value == nullptr && op_attr->name() != kArgDataformat) {
|
|
if (op_attr->param_type() == "required") {
|
|
// match "x_shape" in att with "x" in primitive.
|
|
std::string attr_name = op_attr->name();
|
|
auto find_item = std::find_if(
|
|
op_info_shape_name.begin(), op_info_shape_name.end(),
|
|
[attr_name](const std::map<size_t, std::string>::value_type item) { return item.second == attr_name; });
|
|
if (find_item != op_info_shape_name.end()) {
|
|
if (!dyn_input_sizes.empty()) {
|
|
if (find_item->first >= dyn_input_sizes.size() - 1) {
|
|
MS_LOG(EXCEPTION) << "dyn_input_sizes list index:" << find_item->first
|
|
<< " is out of range:" << dyn_input_sizes.size() - 1 << ".";
|
|
return false;
|
|
}
|
|
size_t tensor_idx = IntToSize(std::accumulate(&dyn_input_sizes[0], &dyn_input_sizes[find_item->first], 0));
|
|
for (int input_i = 0; input_i < dyn_input_sizes[find_item->first]; input_i++) {
|
|
attr_json[kValue] = AnfAlgo::GetPrevNodeOutputInferShape(anf_node, tensor_idx);
|
|
attr_json[kName] = op_attr->name();
|
|
attrs_json->push_back(attr_json);
|
|
tensor_idx++;
|
|
}
|
|
} else {
|
|
attr_json[kValue] = AnfAlgo::GetPrevNodeOutputInferShape(anf_node, find_item->first);
|
|
attr_json[kName] = op_attr->name();
|
|
attrs_json->push_back(attr_json);
|
|
}
|
|
} else {
|
|
MS_LOG(ERROR) << "op [" << op_name << "] should have attr :" << op_attr->name();
|
|
return false;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
GetJson(anf_node, dyn_input_sizes, op_attr, &attr_json, attr_value);
|
|
|
|
attr_json[kName] = op_attr->name();
|
|
attrs_json->push_back(attr_json);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool AkgKernelBuild::GenerateSingleKernelJson(const AnfNodePtr &anf_node, const std::string &op_name,
|
|
nlohmann::json *const node_json) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
MS_EXCEPTION_IF_NULL(node_json);
|
|
int op_cnt = GetOpCntInc();
|
|
auto op_info_ptr = mindspore::kernel::OpLib::FindOp(op_name, OpImplyType::kAKG);
|
|
MS_EXCEPTION_IF_NULL(op_info_ptr);
|
|
|
|
// get basic params from currentNodeOpDesc
|
|
(*node_json)["platform"] = "AKG";
|
|
(*node_json)[kName] = op_name;
|
|
(*node_json)["fusion_type"] = AnfAlgo::GetFusionType(anf_node);
|
|
(*node_json)["impl_path"] = op_info_ptr->impl_path();
|
|
(*node_json)["process"] = AkgKernelBuild::GetProcessor(anf_node);
|
|
|
|
auto primitive = AnfAlgo::GetCNodePrimitive(anf_node);
|
|
MS_EXCEPTION_IF_NULL(primitive);
|
|
ValuePtr input_names_v = primitive->GetAttr(KInpputNames);
|
|
if (input_names_v == nullptr) {
|
|
MS_LOG(ERROR) << "ApplyKernel has no input_names, op[" << op_name << "].";
|
|
return false;
|
|
}
|
|
std::vector<std::string> prim_input_names = GetValue<const std::vector<std::string>>(input_names_v);
|
|
std::string inputs_name;
|
|
for (const auto &prim_input_name : prim_input_names) {
|
|
(void)inputs_name.append("_input_").append(prim_input_name).append("_");
|
|
}
|
|
|
|
// input desc
|
|
nlohmann::json inputs_json;
|
|
if (!CreateInputDescJson(anf_node, &inputs_json)) {
|
|
MS_LOG(ERROR) << "Create input desc json failed, op[" << op_name << "].";
|
|
return false;
|
|
}
|
|
(*node_json)[kInputDesc] = inputs_json;
|
|
MS_LOG(INFO) << "Akg create input desc json success.";
|
|
std::string inputs_shape = "inputs_shape_";
|
|
for (auto &i : inputs_json) {
|
|
for (auto &m : i) {
|
|
std::string data_type = m[kDataType];
|
|
(void)inputs_shape.append("_").append(data_type).append("_");
|
|
for (auto &j : m[kShape]) {
|
|
size_t n = j;
|
|
(void)inputs_shape.append(std::to_string(n)).append("_");
|
|
}
|
|
}
|
|
}
|
|
|
|
// output desc
|
|
nlohmann::json outputs_json;
|
|
if (!CreateOutputDescJson(anf_node, &outputs_json)) {
|
|
MS_LOG(ERROR) << "Create output desc json failed, op[" << op_name << "].";
|
|
return false;
|
|
}
|
|
|
|
(*node_json)[kOutputDesc] = outputs_json;
|
|
MS_LOG(INFO) << "Akg create output desc json success.";
|
|
std::string outputs_shape = "outputs_shape_";
|
|
for (auto &i : outputs_json) {
|
|
std::string data_type = i[kDataType];
|
|
(void)outputs_shape.append("_").append(data_type).append("_");
|
|
for (auto &j : i[kShape]) {
|
|
size_t m = j;
|
|
(void)outputs_shape.append(std::to_string(m)).append("_");
|
|
}
|
|
}
|
|
|
|
// attribute desc
|
|
nlohmann::json attrs_json;
|
|
if (!CreateAttrDescJson(anf_node, op_name, op_info_ptr, &attrs_json)) {
|
|
MS_LOG(ERROR) << "Create attr desc json failed, op[" << op_name << "].";
|
|
return false;
|
|
}
|
|
(*node_json)["attr"] = attrs_json;
|
|
std::string json_str = node_json->dump();
|
|
size_t hash_id = std::hash<std::string>()(json_str);
|
|
json_name_ = op_name + "_";
|
|
(void)json_name_.append(std::to_string(hash_id));
|
|
MS_LOG(INFO) << "full scope name is : " << anf_node->fullname_with_scope() << ", json info name is : " << json_name_;
|
|
json_info_ = json_str;
|
|
(*node_json)["id"] = op_cnt;
|
|
(*node_json)["op"] = json_name_;
|
|
MS_LOG(INFO) << "Akg create node desc json success.";
|
|
return true;
|
|
}
|
|
|
|
KernelPackPtr AkgKernelBuild::OpBuild(const std::string &node_json, const AnfNodePtr &anf_node) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
auto processor = AkgKernelBuild::GetProcessor(anf_node);
|
|
auto cached_kernel_pack = SearchCache(json_name_, processor);
|
|
if (cached_kernel_pack != nullptr) {
|
|
MS_LOG(INFO) << "Use cached kernel, json_name_[" << json_name_ << "], fullname_with_scope["
|
|
<< anf_node->fullname_with_scope() << "].";
|
|
return cached_kernel_pack;
|
|
}
|
|
|
|
PyObject *pModule = nullptr;
|
|
PyObject *pFunc = nullptr;
|
|
PyObject *pArg = nullptr;
|
|
PyObject *pRes = nullptr;
|
|
|
|
pModule = PyImport_ImportModule(kAkgModule);
|
|
if (pModule == nullptr) {
|
|
MS_LOG(ERROR) << "Failed to import [" << kAkgModule << "].";
|
|
return nullptr;
|
|
}
|
|
|
|
pFunc = PyObject_GetAttrString(pModule, kCompileWithJsonFunc);
|
|
pArg = PyTuple_New(ARGS_SIZE);
|
|
(void)PyTuple_SetItem(pArg, 0, Py_BuildValue("s", node_json.c_str()));
|
|
|
|
(void)alarm(AUTODIFF_COMPILE_OVERTIME);
|
|
pRes = PyEval_CallObject(pFunc, pArg);
|
|
(void)alarm(0);
|
|
if (pRes == nullptr) {
|
|
MS_LOG(ERROR) << "No ret got, failed to call function [" << kCompileWithJsonFunc << "], args:\n("
|
|
<< PyObjectToStr(pArg) << ").";
|
|
return nullptr;
|
|
}
|
|
if (PyObject_IsTrue(pRes) != 1) {
|
|
MS_LOG(ERROR) << "Illegal ret, failed to call function [" << kCompileWithJsonFunc << "], args:\n("
|
|
<< PyObjectToStr(pArg) << ").";
|
|
return nullptr;
|
|
}
|
|
|
|
auto new_kernel_pack = InsertCache(json_name_, processor);
|
|
kernel::SaveJsonInfo(json_name_, json_info_);
|
|
if (new_kernel_pack == nullptr) {
|
|
MS_LOG(ERROR) << "Insert to cache failed, json_name_[" << json_name_ << "], fullname_with_scope["
|
|
<< anf_node->fullname_with_scope() << "].";
|
|
return nullptr;
|
|
}
|
|
return new_kernel_pack;
|
|
}
|
|
|
|
KernelPackPtr AkgKernelBuild::BuildByJson(const AnfNodePtr &anf_node, std::vector<size_t> *const input_size,
|
|
std::vector<size_t> *const output_size) {
|
|
MS_EXCEPTION_IF_NULL(anf_node);
|
|
std::string op_name = AnfAlgo::GetCNodeName(anf_node);
|
|
auto it = kAkgKernelAttrsProcessMap.find(op_name);
|
|
if (it != kAkgKernelAttrsProcessMap.end()) {
|
|
it->second(anf_node);
|
|
}
|
|
MS_LOG(INFO) << "Akg start compile, op[" << op_name << "], device[" << AkgKernelBuild::GetProcessor(anf_node) << "]";
|
|
nlohmann::json node_json;
|
|
if (!GenerateSingleKernelJson(anf_node, op_name, &node_json)) {
|
|
MS_LOG(ERROR) << "Op[" << op_name << "] create single kernel json failed.";
|
|
}
|
|
|
|
std::string json_str = node_json.dump();
|
|
auto kernel_pack = OpBuild(json_str, anf_node);
|
|
if (kernel_pack == nullptr) {
|
|
MS_LOG(ERROR) << "Akg build failed op[" << op_name << "], json:" << json_str;
|
|
return nullptr;
|
|
}
|
|
|
|
if (!GetIOSize(node_json, input_size, output_size)) {
|
|
MS_LOG(ERROR) << "Cal mem size failed.";
|
|
return nullptr;
|
|
}
|
|
MS_LOG(INFO) << "Akg compile success, op[" << op_name << "], device[" << AkgKernelBuild::GetProcessor(anf_node)
|
|
<< "]";
|
|
return kernel_pack;
|
|
}
|
|
} // namespace kernel
|
|
} // namespace mindspore
|