forked from mindspore-Ecosystem/mindspore
add tensor_minnie and separate py from ir
This commit is contained in:
parent
14f9a6e31c
commit
4508134ceb
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include "utils/ordered_set.h"
|
||||
#include "utils/utils.h"
|
||||
#include "debug/trace.h"
|
||||
#include "debug/label.h"
|
||||
#include "utils/context/ms_context.h"
|
||||
#include "operator/ops.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -16,7 +16,9 @@
|
|||
|
||||
#include "debug/draw.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
@ -28,7 +30,7 @@
|
|||
#include "utils/graph_utils.h"
|
||||
#include "utils/utils.h"
|
||||
#include "operator/composite/composite.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
|
@ -323,15 +325,17 @@ void BaseDigraph::FuncGraphParameters(const FuncGraphPtr &key) {
|
|||
auto py_p = param_value->value();
|
||||
if (py::hasattr(py_p, "default_input")) {
|
||||
py_p = py_p.attr("default_input");
|
||||
std::vector<int> shape;
|
||||
if (py::hasattr(py_p, PYTHON_TENSOR_FLAG)) {
|
||||
auto m_tensor = py_p.cast<std::shared_ptr<tensor::Tensor>>();
|
||||
py::tuple shape = m_tensor->GetPyTupleShape();
|
||||
buffer_ << "[" << py::str(shape) << "]";
|
||||
shape = m_tensor->shape();
|
||||
} else if (py::hasattr(py_p, PYTHON_META_TENSOR_FLAG)) {
|
||||
auto m_tensor = py_p.cast<std::shared_ptr<tensor::MetaTensor>>();
|
||||
py::tuple shape = m_tensor->GetPyTupleShape();
|
||||
buffer_ << "[" << py::str(shape) << "]";
|
||||
shape = m_tensor->shape();
|
||||
}
|
||||
std::ostringstream shape_str;
|
||||
std::copy(shape.begin(), shape.end(), std::ostream_iterator<int>(shape_str, ","));
|
||||
buffer_ << "[" << shape_str.str() << "]";
|
||||
}
|
||||
}
|
||||
buffer_ << "</td></tr>";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include "ir/meta_func_graph.h"
|
||||
#include "utils/graph_utils.h"
|
||||
#include "operator/composite/composite.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_utils.h"
|
||||
#include "pipeline/static_analysis/evaluator.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include "device/kernel_runtime_manager.h"
|
||||
#include "device/convert_tensor_utils.h"
|
||||
#include "ir/dtype/type.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "kernel/common_utils.h"
|
||||
#include "utils/utils.h"
|
||||
#include "common/utils.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace device {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "session/kernel_graph.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
#include "session/session_context.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "device/ascend/profiling/profiling_utils.h"
|
||||
#include "device/kernel_info.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include <map>
|
||||
|
||||
#include "device/device_address.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "predict/generator/utils/ir_model_util.h"
|
||||
#ifdef ENABLE_DUMP_E2E
|
||||
#include "debug/e2e_dump.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include <unordered_map>
|
||||
|
||||
#include "ir/func_graph.h"
|
||||
#include "ir/primitive.h"
|
||||
#include "ir/primitive_base.h"
|
||||
|
||||
namespace mindspore {
|
||||
// namespace to support intermediate representation definition
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "pipeline/static_analysis/static_analysis.h"
|
||||
#include "operator/ops.h"
|
||||
#include "parallel/ops_info/ops_utils.h"
|
||||
#include "debug/label.h"
|
||||
|
||||
namespace mindspore {
|
||||
// namespace to support intermediate representation definition
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,24 +22,14 @@
|
|||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "ir/manager.h"
|
||||
#include "ir/func_graph_cloner.h"
|
||||
#include "operator/ops.h"
|
||||
#include "utils/ordered_set.h"
|
||||
#include "pipeline/static_analysis/static_analysis.h"
|
||||
#include "pipeline/static_analysis/abstract_function.h"
|
||||
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "debug/trace.h"
|
||||
#include "debug/draw.h"
|
||||
#include "debug/label.h"
|
||||
#include "ir/manager.h"
|
||||
#include "operator/ops.h"
|
||||
#include "pybind_api/export_flags.h"
|
||||
#include "utils/ordered_set.h"
|
||||
#include "utils/convert_utils.h"
|
||||
|
||||
namespace mindspore {
|
||||
using mindspore::abstract::AbstractFunction;
|
||||
using mindspore::abstract::AbstractFunctionPtr;
|
||||
using mindspore::abstract::AnalysisContextPtr;
|
||||
using mindspore::abstract::PrimitiveAbstractClosure;
|
||||
using mindspore::abstract::VirtualAbstractClosure;
|
||||
/*
|
||||
* Methods of Graph
|
||||
*/
|
||||
|
@ -59,34 +49,6 @@ FuncGraph::FuncGraph()
|
|||
debug_info_ = std::make_shared<GraphDebugInfo>();
|
||||
}
|
||||
|
||||
AbstractFunctionPtr FuncGraph::abstract() {
|
||||
AbstractBasePtrList args_spec_list;
|
||||
|
||||
for (auto &p : parameters_) {
|
||||
MS_EXCEPTION_IF_NULL(p);
|
||||
if (p->abstract() == nullptr) {
|
||||
MS_LOG(ERROR) << "Error!!";
|
||||
return nullptr;
|
||||
}
|
||||
args_spec_list.push_back(p->abstract());
|
||||
}
|
||||
|
||||
if (nullptr == output()) {
|
||||
MS_LOG(ERROR) << "Error func graph no output";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<VirtualAbstractClosure>(args_spec_list, output()->abstract());
|
||||
}
|
||||
|
||||
abstract::AbstractBasePtr FuncGraph::MakeAbstractClosure(const abstract::AnalysisContextPtr &context) {
|
||||
AnalysisContextPtr temp_context = context;
|
||||
if (temp_context == nullptr) {
|
||||
temp_context = abstract::AnalysisContext::DummyContext();
|
||||
}
|
||||
return std::make_shared<abstract::FuncGraphAbstractClosure>(shared_from_base<FuncGraph>(), temp_context);
|
||||
}
|
||||
|
||||
AnfNodePtr FuncGraph::output() const {
|
||||
// If return value is set, return should have two inputs.
|
||||
if (return_ != nullptr && return_->inputs().size() == 2) {
|
||||
|
@ -97,28 +59,6 @@ AnfNodePtr FuncGraph::output() const {
|
|||
}
|
||||
}
|
||||
|
||||
void FuncGraph::set_output(const AnfNodePtr &value, bool force_new_ret) {
|
||||
if (force_new_ret || return_ == nullptr) {
|
||||
std::vector<AnfNodePtr> params({NewValueNode(prim::kPrimReturn), value});
|
||||
FuncGraphPtr this_graph = shared_from_base<FuncGraph>();
|
||||
return_ = this_graph->NewCNode(params);
|
||||
} else {
|
||||
if (manager_.lock()) {
|
||||
manager_.lock()->SetEdge(return_, 1, value);
|
||||
} else {
|
||||
return_->set_input(1, value);
|
||||
}
|
||||
}
|
||||
|
||||
return_->set_abstract(value->abstract());
|
||||
|
||||
AnfNodePtr input0 = return_->input(0);
|
||||
|
||||
PrimitivePtr return_prim = prim::kPrimReturn;
|
||||
auto f = std::make_shared<PrimitiveAbstractClosure>(return_prim, input0);
|
||||
input0->set_abstract(f);
|
||||
}
|
||||
|
||||
ParameterPtr FuncGraph::add_parameter() {
|
||||
FuncGraphPtr this_func_graph = shared_from_base<FuncGraph>();
|
||||
ParameterPtr p = std::make_shared<Parameter>(this_func_graph);
|
||||
|
@ -469,8 +409,6 @@ std::shared_ptr<std::list<FuncGraphPtr>> FuncGraph::recursive_graphs() {
|
|||
return mng->recursive_graphs(shared_from_base<FuncGraph>());
|
||||
}
|
||||
|
||||
void FuncGraph::DumpFuncGraph(const std::string &path) { draw::Draw(path + ".dot", shared_from_base<FuncGraph>()); }
|
||||
|
||||
AnfNodePtr FuncGraph::GetDefaultValueByName(const std::string &name) {
|
||||
auto itr = this->parameter_default_value_.find(name);
|
||||
if (itr == parameter_default_value_.end()) {
|
||||
|
@ -594,207 +532,6 @@ AnfNodePtr FuncGraph::GetParameterByName(const std::string &name) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateVarParams(const FuncGraphPtr &specialized_graph,
|
||||
std::vector<AnfNodePtr> *specialized_parameter_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes, int variable_args_count,
|
||||
int pos_args_input_count) {
|
||||
// if there is variable argument, pass the input arguments that does not match positional args to it as a tuple
|
||||
if (specialized_graph->has_vararg()) {
|
||||
TraceManager::DebugTrace(
|
||||
std::make_shared<TraceGenerateVarArg>(specialized_graph->GetVariableArgParameter()->debug_info()));
|
||||
std::vector<AnfNodePtr> var_param_tuple_nodes;
|
||||
var_param_tuple_nodes.push_back(NewValueNode(prim::kPrimMakeTuple));
|
||||
|
||||
if (variable_args_count < 0) {
|
||||
MS_LOG(EXCEPTION) << "Function:" << this->ToString() << ", variable_args_count " << variable_args_count
|
||||
<< " were given.";
|
||||
}
|
||||
// for python variable argument input , there is no upper limit
|
||||
for (int i = 0; i < variable_args_count; ++i) {
|
||||
ParameterPtr p = std::make_shared<Parameter>(specialized_graph);
|
||||
std::string param_name = specialized_graph->GetVariableArgName() + std::to_string(i);
|
||||
p->set_name(param_name);
|
||||
MS_EXCEPTION_IF_NULL(p->debug_info());
|
||||
p->debug_info()->set_name(param_name);
|
||||
var_param_tuple_nodes.push_back(p);
|
||||
MS_EXCEPTION_IF_NULL(specialized_parameter_list);
|
||||
specialized_parameter_list->push_back(p);
|
||||
}
|
||||
auto var_tuple_param = specialized_graph->NewCNode(var_param_tuple_nodes);
|
||||
(void)repl_nodes->emplace(specialized_graph->GetVariableArgParameter(), var_tuple_param);
|
||||
TraceManager::EndTrace();
|
||||
} else if (variable_args_count > 0) {
|
||||
MS_LOG(EXCEPTION) << "Function:" << this->ToString() << " takes " << this->GetPositionalArgsCount()
|
||||
<< " positional arguments, but " << pos_args_input_count << " were given.";
|
||||
}
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateKwParams(const FuncGraphPtr &specialized_graph,
|
||||
std::vector<AnfNodePtr> *specialized_parameter_list,
|
||||
const std::vector<abstract::AbstractKeywordArgPtr> &kwarg_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes) {
|
||||
std::vector<AnfNodePtr> kwarg_keys_tuple_nodes = {NewValueNode(prim::kPrimMakeTuple)};
|
||||
std::vector<AnfNodePtr> kwarg_values_tuple_nodes = {NewValueNode(prim::kPrimMakeTuple)};
|
||||
|
||||
for (const auto &kwarg : kwarg_list) {
|
||||
MS_EXCEPTION_IF_NULL(kwarg);
|
||||
std::string kw_param_name = kwarg->get_key();
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
AnfNodePtr param_node = specialized_graph->GetParameterByName(kw_param_name);
|
||||
// if not find correspoding parameter node
|
||||
if (param_node == nullptr) {
|
||||
if (!has_kwarg()) {
|
||||
MS_LOG(EXCEPTION) << "Got unexpected keyword argument: " << kw_param_name;
|
||||
} else {
|
||||
ParameterPtr p = std::make_shared<Parameter>(specialized_graph);
|
||||
std::string param_name = specialized_graph->GetVariableKwargName() + "[" + kw_param_name + "]";
|
||||
MS_EXCEPTION_IF_NULL(specialized_parameter_list);
|
||||
auto find_kw_arg_in_list = std::any_of(specialized_parameter_list->begin(), specialized_parameter_list->end(),
|
||||
[param_name](const AnfNodePtr &node) {
|
||||
MS_EXCEPTION_IF_NULL(node);
|
||||
auto param = node->cast<ParameterPtr>();
|
||||
return param != nullptr && param->name() == param_name;
|
||||
});
|
||||
if (find_kw_arg_in_list) {
|
||||
MS_LOG(EXCEPTION) << "Multiply values for keyword argument:" << kw_param_name;
|
||||
}
|
||||
p->set_name(param_name);
|
||||
p->debug_info()->set_name(param_name);
|
||||
kwarg_keys_tuple_nodes.push_back(NewValueNode(kw_param_name));
|
||||
auto extract_node =
|
||||
specialized_graph->NewCNode({NewValueNode(prim::kPrimExtractKeywordArg), NewValueNode(kw_param_name), p});
|
||||
kwarg_values_tuple_nodes.push_back(extract_node);
|
||||
specialized_parameter_list->push_back(p);
|
||||
}
|
||||
} else {
|
||||
auto node_itr = std::find(specialized_parameter_list->begin(), specialized_parameter_list->end(), param_node);
|
||||
// multiply values found given for parameter
|
||||
if (node_itr != specialized_parameter_list->end()) {
|
||||
MS_LOG(EXCEPTION) << "Multiply values for specific argument:" << kw_param_name;
|
||||
} else {
|
||||
specialized_parameter_list->push_back(param_node);
|
||||
auto extract_node = specialized_graph->NewCNode(
|
||||
{NewValueNode(prim::kPrimExtractKeywordArg), NewValueNode(kw_param_name), param_node});
|
||||
(void)repl_nodes->emplace(param_node, extract_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenerateKwargReplNode(specialized_graph, repl_nodes, kwarg_keys_tuple_nodes, kwarg_values_tuple_nodes);
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateKwargReplNode(const FuncGraphPtr &specialized_graph,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes,
|
||||
const std::vector<AnfNodePtr> &kwarg_keys_tuple_nodes,
|
||||
const std::vector<AnfNodePtr> &kwarg_values_tuple_nodes) {
|
||||
if (has_kwarg()) {
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
TraceManager::DebugTrace(
|
||||
std::make_shared<TraceGenerateKwArg>(specialized_graph->GetVariableKwargParameter()->debug_info()));
|
||||
auto make_tuple_keys = specialized_graph->NewCNode(kwarg_keys_tuple_nodes);
|
||||
auto make_tuple_values = specialized_graph->NewCNode(kwarg_values_tuple_nodes);
|
||||
auto make_dict_node =
|
||||
specialized_graph->NewCNode({NewValueNode(prim::kPrimMakeDict), make_tuple_keys, make_tuple_values});
|
||||
MS_EXCEPTION_IF_NULL(repl_nodes);
|
||||
(void)repl_nodes->emplace(specialized_graph->GetVariableKwargParameter(), make_dict_node);
|
||||
TraceManager::EndTrace();
|
||||
}
|
||||
}
|
||||
|
||||
bool FuncGraph::NeedGenerate(const std::vector<abstract::AbstractKeywordArgPtr> &kwarg_list) {
|
||||
// if the function does not have any vararg/kwarg/kwonly/default value/kw args input
|
||||
// return the original graph
|
||||
if (!has_vararg() && kwonlyargs_count() == 0 && !has_kwarg() && GetDefaultValueCount() == 0 && kwarg_list.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the graph is generated for specific input, do not need to generate again
|
||||
if (is_generated()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateDefaultValue(const FuncGraphPtr &specialized_graph,
|
||||
const std::vector<AnfNodePtr> &specialized_parameter_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes) {
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
for (size_t i = 0; i < specialized_graph->parameters().size() - hyper_param_count(); ++i) {
|
||||
auto param_node = specialized_graph->parameters()[i];
|
||||
MS_EXCEPTION_IF_NULL(param_node);
|
||||
auto param_name = param_node->cast<ParameterPtr>()->name();
|
||||
auto node_itr = std::find(specialized_parameter_list.begin(), specialized_parameter_list.end(), param_node);
|
||||
if (node_itr != specialized_parameter_list.end()) {
|
||||
continue;
|
||||
}
|
||||
if (param_name == specialized_graph->GetVariableArgName() ||
|
||||
param_name == specialized_graph->GetVariableKwargName()) {
|
||||
continue;
|
||||
}
|
||||
auto default_value = specialized_graph->GetDefaultValueByName(param_name);
|
||||
if (default_value == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "Miss argument input for parameter:" << param_name;
|
||||
}
|
||||
MS_EXCEPTION_IF_NULL(repl_nodes);
|
||||
(void)repl_nodes->emplace(param_node, default_value);
|
||||
}
|
||||
}
|
||||
|
||||
FuncGraphPtr FuncGraph::GenerateGraph(const AbstractBasePtrList &args_spec_list) {
|
||||
std::vector<abstract::AbstractKeywordArgPtr> kwarg_list;
|
||||
size_t arguments_count = args_spec_list.size();
|
||||
for (const auto &arg : args_spec_list) {
|
||||
// if it is a keyword argument
|
||||
MS_EXCEPTION_IF_NULL(arg);
|
||||
if (arg->isa<abstract::AbstractKeywordArg>()) {
|
||||
kwarg_list.push_back(dyn_cast<abstract::AbstractKeywordArg>(arg));
|
||||
}
|
||||
}
|
||||
if (!NeedGenerate(kwarg_list)) {
|
||||
return shared_from_base<FuncGraph>();
|
||||
}
|
||||
FuncGraphPtr specialized_graph = BasicClone(shared_from_base<FuncGraph>());
|
||||
size_t kwarg_count = kwarg_list.size();
|
||||
int pos_args_input_count = SizeToInt(arguments_count - kwarg_count - hyper_param_count());
|
||||
int pos_args_count = std::min(pos_args_input_count, this->GetPositionalArgsCount());
|
||||
int variable_args_count = pos_args_input_count - pos_args_count;
|
||||
std::vector<AnfNodePtr> specialized_parameter_list;
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> repl_nodes;
|
||||
// the parameters that has arg input, copy from original parameters
|
||||
for (size_t i = 0; i < IntToSize(pos_args_count); ++i) {
|
||||
specialized_parameter_list.push_back(specialized_graph->parameters()[i]);
|
||||
}
|
||||
|
||||
GenerateVarParams(specialized_graph, &specialized_parameter_list, &repl_nodes, variable_args_count,
|
||||
pos_args_input_count);
|
||||
|
||||
GenerateKwParams(specialized_graph, &specialized_parameter_list, kwarg_list, &repl_nodes);
|
||||
|
||||
GenerateDefaultValue(specialized_graph, specialized_parameter_list, &repl_nodes);
|
||||
|
||||
// append hyper parameter to specialized_parameter_list
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
auto params = specialized_graph->parameters();
|
||||
(void)std::transform(params.end() - SizeToInt(hyper_param_count()), params.end(),
|
||||
std::back_inserter(specialized_parameter_list), [](const AnfNodePtr &node) { return node; });
|
||||
|
||||
std::shared_ptr<mindspore::FuncGraphManager> manager = mindspore::Manage(specialized_graph, false);
|
||||
auto tr = manager->Transact();
|
||||
for (auto &node_pair : repl_nodes) {
|
||||
MS_LOG(DEBUG) << "GenerateGraph replace:" << node_pair.first->DebugString() << "-"
|
||||
<< node_pair.second->DebugString();
|
||||
(void)tr.Replace(node_pair.first, node_pair.second);
|
||||
}
|
||||
tr.SetParameters(specialized_graph, specialized_parameter_list);
|
||||
tr.Commit();
|
||||
specialized_graph->set_has_kwarg(false);
|
||||
specialized_graph->set_has_vararg(false);
|
||||
specialized_graph->set_kwonlyargs_count(0);
|
||||
specialized_graph->ClearDefaultValues();
|
||||
specialized_graph->set_is_generate(true);
|
||||
return specialized_graph;
|
||||
}
|
||||
|
||||
void FuncGraph::add_parameter_obj_node(const AnfNodePtr &p) { paramter_obj_nodes_.push_back(p); }
|
||||
|
||||
std::list<CNodePtr> FuncGraph::GetOrderedCnodes() {
|
||||
|
@ -873,133 +610,6 @@ void FuncGraph::CheckOrder() {
|
|||
}
|
||||
}
|
||||
|
||||
const char kPrimHasEffect[] = "_side_effect_flag";
|
||||
|
||||
bool FuncGraph::HasEffect(const CNodePtr &cnode) {
|
||||
auto prim = GetCNodePrimitive(cnode);
|
||||
if (prim != nullptr && prim->isa<prim::DoSignaturePrimitive>()) {
|
||||
auto do_sig = prim->cast<prim::DoSignaturePrimitivePtr>();
|
||||
auto prim_val = do_sig->function();
|
||||
if (prim_val != nullptr && prim_val->isa<Primitive>()) {
|
||||
prim = prim_val->cast<PrimitivePtr>();
|
||||
} else {
|
||||
prim = nullptr;
|
||||
}
|
||||
}
|
||||
if (prim != nullptr) {
|
||||
auto effect_val = prim->GetAttr(kPrimHasEffect);
|
||||
if (effect_val && effect_val->isa<BoolImm>()) {
|
||||
auto effect_bool = GetValue<bool>(effect_val);
|
||||
return effect_bool;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> FindRoots(const std::vector<CNodePtr> &segment) {
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> roots = std::make_shared<OrderedSet<CNodePtr>>(segment);
|
||||
for (const auto &node : segment) {
|
||||
if (roots->size() == 1) {
|
||||
return roots;
|
||||
}
|
||||
auto input_size = node->size();
|
||||
for (size_t i = 0; i < input_size; i++) {
|
||||
auto in_node = node->input(i);
|
||||
auto in_cnode = in_node->cast<CNodePtr>();
|
||||
if (in_cnode != nullptr) {
|
||||
(void)roots->erase(in_cnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> FindLeaves(const std::vector<CNodePtr> &segment) {
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> nodes = std::make_shared<OrderedSet<CNodePtr>>(segment);
|
||||
for (const auto &node : segment) {
|
||||
if (nodes->size() == 1) {
|
||||
return nodes;
|
||||
}
|
||||
if (IsPrimitiveCNode(node, prim::kPrimSwitch)) {
|
||||
(void)nodes->erase(node);
|
||||
continue;
|
||||
}
|
||||
auto input_size = node->size();
|
||||
for (size_t i = 0; i < input_size; i++) {
|
||||
auto in_node = node->input(i);
|
||||
if (!in_node->isa<CNode>()) {
|
||||
continue;
|
||||
}
|
||||
auto in_cnode = in_node->cast<CNodePtr>();
|
||||
if (in_cnode != nullptr) {
|
||||
if (std::find(segment.begin(), segment.end(), in_cnode) != segment.end()) {
|
||||
(void)nodes->erase(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void FuncGraph::ReleaseFullOrderToEffectOrder() {
|
||||
MS_LOG(DEBUG) << "Flag has_effect " << has_flag(GRAPH_FLAG_HAS_EFFECT) << ".";
|
||||
if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
|
||||
std::list<AnfNodePtr> depends_order;
|
||||
std::vector<CNodePtr> segment;
|
||||
for (const auto &cnode : order_) {
|
||||
if (IsPrimitiveCNode(cnode, prim::kPrimReturn)) {
|
||||
continue;
|
||||
}
|
||||
if (HasEffect(cnode)) {
|
||||
MS_LOG(DEBUG) << "Meet a effect node " << cnode->DebugString() << ".";
|
||||
if (segment.size() > 0) {
|
||||
auto roots = FindRoots(segment);
|
||||
for (auto iter = roots->begin(); iter != roots->end(); (void)iter++) {
|
||||
depends_order.push_back(*iter);
|
||||
}
|
||||
}
|
||||
segment.clear();
|
||||
depends_order.push_back(cnode);
|
||||
} else {
|
||||
MS_LOG(DEBUG) << "Meet a general node " << cnode->DebugString() << ".";
|
||||
segment.push_back(cnode);
|
||||
}
|
||||
}
|
||||
if (segment.size() > 1) {
|
||||
auto roots = FindRoots(segment);
|
||||
for (auto iter = roots->begin(); iter != roots->end(); (void)iter++) {
|
||||
depends_order.push_back(*iter);
|
||||
}
|
||||
}
|
||||
std::vector<AnfNodePtr> depend_inputs;
|
||||
auto old_ret = output();
|
||||
for (auto iter = depends_order.rbegin(); iter != depends_order.rend(); (void)iter++) {
|
||||
if (*iter != old_ret) {
|
||||
depend_inputs.push_back(*iter);
|
||||
}
|
||||
}
|
||||
set_flags(GRAPH_FLAG_HAS_EFFECT, false);
|
||||
set_flags(GRAPH_FLAG_EFFECT_PATIAL_ORDER, true);
|
||||
if (!depend_inputs.empty()) {
|
||||
SetEffectDepends(depend_inputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FuncGraph::SetEffectDepends(const std::vector<AnfNodePtr> &depend_inputs) {
|
||||
auto old_ret = output();
|
||||
std::vector<AnfNodePtr> inputs{NewValueNode(prim::kPrimDepend), old_ret};
|
||||
(void)inputs.insert(inputs.end(), depend_inputs.begin(), depend_inputs.end());
|
||||
auto new_ret = NewCNode(inputs);
|
||||
auto mng = manager();
|
||||
if (mng) {
|
||||
(void)mng->Replace(old_ret, new_ret);
|
||||
} else {
|
||||
return_->set_input(1, new_ret);
|
||||
}
|
||||
}
|
||||
|
||||
size_t NewFgSeenGeneration() {
|
||||
static size_t fg_seen_generation = 0;
|
||||
return ++fg_seen_generation;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -30,9 +30,9 @@
|
|||
|
||||
#include "ir/anf.h"
|
||||
#include "ir/manager.h"
|
||||
#include "utils/any.h"
|
||||
#include "utils/ordered_set.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
#include "utils/ordered_map.h"
|
||||
#include "utils/base_ref.h"
|
||||
|
||||
namespace mindspore {
|
||||
using BaseRefCounterMap = OrderedMap<BaseRef, int, BaseRefHash>;
|
||||
|
@ -50,6 +50,16 @@ const char FUNC_GRAPH_FLAG_DEFER_INLINE[] = "defer_inline";
|
|||
const char FUNC_GRAPH_FLAG_CORE[] = "core";
|
||||
const char FUNC_GRAPH_FLAG_SPECIALIZE_PARAMETER[] = "spec_param";
|
||||
|
||||
namespace abstract {
|
||||
class AbstractKeywordArg;
|
||||
using AbstractKeywordArgPtr = std::shared_ptr<AbstractKeywordArg>;
|
||||
class AbstractFunction;
|
||||
using AbstractFunctionPtr = std::shared_ptr<AbstractFunction>;
|
||||
} // namespace abstract
|
||||
|
||||
class FuncGraphManager;
|
||||
using FuncGraphManagerPtr = std::shared_ptr<FuncGraphManager>;
|
||||
|
||||
// ANF transform class
|
||||
// either a primitive or a func_graph
|
||||
class FuncGraphTransform {
|
||||
|
|
|
@ -0,0 +1,422 @@
|
|||
/**
|
||||
* Copyright 2020 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 "ir/func_graph.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "ir/manager.h"
|
||||
#include "ir/func_graph_cloner.h"
|
||||
#include "operator/ops.h"
|
||||
#include "utils/ordered_set.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
#include "pipeline/static_analysis/static_analysis.h"
|
||||
#include "pipeline/static_analysis/abstract_function.h"
|
||||
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "debug/trace.h"
|
||||
#include "debug/draw.h"
|
||||
#include "debug/label.h"
|
||||
|
||||
namespace mindspore {
|
||||
using mindspore::abstract::AbstractFunction;
|
||||
using mindspore::abstract::AbstractFunctionPtr;
|
||||
using mindspore::abstract::AnalysisContextPtr;
|
||||
using mindspore::abstract::PrimitiveAbstractClosure;
|
||||
using mindspore::abstract::VirtualAbstractClosure;
|
||||
|
||||
AbstractFunctionPtr FuncGraph::abstract() {
|
||||
AbstractBasePtrList args_spec_list;
|
||||
|
||||
for (auto &p : parameters_) {
|
||||
MS_EXCEPTION_IF_NULL(p);
|
||||
if (p->abstract() == nullptr) {
|
||||
MS_LOG(ERROR) << "Error!!";
|
||||
return nullptr;
|
||||
}
|
||||
args_spec_list.push_back(p->abstract());
|
||||
}
|
||||
|
||||
if (nullptr == output()) {
|
||||
MS_LOG(ERROR) << "Error func graph no output";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::make_shared<VirtualAbstractClosure>(args_spec_list, output()->abstract());
|
||||
}
|
||||
|
||||
abstract::AbstractBasePtr FuncGraph::MakeAbstractClosure(const abstract::AnalysisContextPtr &context) {
|
||||
AnalysisContextPtr temp_context = context;
|
||||
if (temp_context == nullptr) {
|
||||
temp_context = abstract::AnalysisContext::DummyContext();
|
||||
}
|
||||
return std::make_shared<abstract::FuncGraphAbstractClosure>(shared_from_base<FuncGraph>(), temp_context);
|
||||
}
|
||||
|
||||
void FuncGraph::set_output(const AnfNodePtr &value, bool force_new_ret) {
|
||||
if (force_new_ret || return_ == nullptr) {
|
||||
std::vector<AnfNodePtr> params({NewValueNode(prim::kPrimReturn), value});
|
||||
FuncGraphPtr this_graph = shared_from_base<FuncGraph>();
|
||||
return_ = this_graph->NewCNode(params);
|
||||
} else {
|
||||
if (manager_.lock()) {
|
||||
manager_.lock()->SetEdge(return_, 1, value);
|
||||
} else {
|
||||
return_->set_input(1, value);
|
||||
}
|
||||
}
|
||||
|
||||
return_->set_abstract(value->abstract());
|
||||
|
||||
AnfNodePtr input0 = return_->input(0);
|
||||
|
||||
PrimitivePtr return_prim = prim::kPrimReturn;
|
||||
auto f = std::make_shared<PrimitiveAbstractClosure>(return_prim, input0);
|
||||
input0->set_abstract(f);
|
||||
}
|
||||
|
||||
void FuncGraph::DumpFuncGraph(const std::string &path) { draw::Draw(path + ".dot", shared_from_base<FuncGraph>()); }
|
||||
|
||||
void FuncGraph::GenerateVarParams(const FuncGraphPtr &specialized_graph,
|
||||
std::vector<AnfNodePtr> *specialized_parameter_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes, int variable_args_count,
|
||||
int pos_args_input_count) {
|
||||
// if there is variable argument, pass the input arguments that does not match positional args to it as a tuple
|
||||
if (specialized_graph->has_vararg()) {
|
||||
TraceManager::DebugTrace(
|
||||
std::make_shared<TraceGenerateVarArg>(specialized_graph->GetVariableArgParameter()->debug_info()));
|
||||
std::vector<AnfNodePtr> var_param_tuple_nodes;
|
||||
var_param_tuple_nodes.push_back(NewValueNode(prim::kPrimMakeTuple));
|
||||
|
||||
if (variable_args_count < 0) {
|
||||
MS_LOG(EXCEPTION) << "Function:" << this->ToString() << ", variable_args_count " << variable_args_count
|
||||
<< " were given.";
|
||||
}
|
||||
// for python variable argument input , there is no upper limit
|
||||
for (int i = 0; i < variable_args_count; ++i) {
|
||||
ParameterPtr p = std::make_shared<Parameter>(specialized_graph);
|
||||
std::string param_name = specialized_graph->GetVariableArgName() + std::to_string(i);
|
||||
p->set_name(param_name);
|
||||
MS_EXCEPTION_IF_NULL(p->debug_info());
|
||||
p->debug_info()->set_name(param_name);
|
||||
var_param_tuple_nodes.push_back(p);
|
||||
MS_EXCEPTION_IF_NULL(specialized_parameter_list);
|
||||
specialized_parameter_list->push_back(p);
|
||||
}
|
||||
auto var_tuple_param = specialized_graph->NewCNode(var_param_tuple_nodes);
|
||||
(void)repl_nodes->emplace(specialized_graph->GetVariableArgParameter(), var_tuple_param);
|
||||
TraceManager::EndTrace();
|
||||
} else if (variable_args_count > 0) {
|
||||
MS_LOG(EXCEPTION) << "Function:" << this->ToString() << " takes " << this->GetPositionalArgsCount()
|
||||
<< " positional arguments, but " << pos_args_input_count << " were given.";
|
||||
}
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateKwParams(const FuncGraphPtr &specialized_graph,
|
||||
std::vector<AnfNodePtr> *specialized_parameter_list,
|
||||
const std::vector<abstract::AbstractKeywordArgPtr> &kwarg_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes) {
|
||||
std::vector<AnfNodePtr> kwarg_keys_tuple_nodes = {NewValueNode(prim::kPrimMakeTuple)};
|
||||
std::vector<AnfNodePtr> kwarg_values_tuple_nodes = {NewValueNode(prim::kPrimMakeTuple)};
|
||||
|
||||
for (const auto &kwarg : kwarg_list) {
|
||||
MS_EXCEPTION_IF_NULL(kwarg);
|
||||
std::string kw_param_name = kwarg->get_key();
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
AnfNodePtr param_node = specialized_graph->GetParameterByName(kw_param_name);
|
||||
// if not find correspoding parameter node
|
||||
if (param_node == nullptr) {
|
||||
if (!has_kwarg()) {
|
||||
MS_LOG(EXCEPTION) << "Got unexpected keyword argument: " << kw_param_name;
|
||||
} else {
|
||||
ParameterPtr p = std::make_shared<Parameter>(specialized_graph);
|
||||
std::string param_name = specialized_graph->GetVariableKwargName() + "[" + kw_param_name + "]";
|
||||
MS_EXCEPTION_IF_NULL(specialized_parameter_list);
|
||||
auto find_kw_arg_in_list = std::any_of(specialized_parameter_list->begin(), specialized_parameter_list->end(),
|
||||
[param_name](const AnfNodePtr &node) {
|
||||
MS_EXCEPTION_IF_NULL(node);
|
||||
auto param = node->cast<ParameterPtr>();
|
||||
return param != nullptr && param->name() == param_name;
|
||||
});
|
||||
if (find_kw_arg_in_list) {
|
||||
MS_LOG(EXCEPTION) << "Multiply values for keyword argument:" << kw_param_name;
|
||||
}
|
||||
p->set_name(param_name);
|
||||
p->debug_info()->set_name(param_name);
|
||||
kwarg_keys_tuple_nodes.push_back(NewValueNode(kw_param_name));
|
||||
auto extract_node =
|
||||
specialized_graph->NewCNode({NewValueNode(prim::kPrimExtractKeywordArg), NewValueNode(kw_param_name), p});
|
||||
kwarg_values_tuple_nodes.push_back(extract_node);
|
||||
specialized_parameter_list->push_back(p);
|
||||
}
|
||||
} else {
|
||||
auto node_itr = std::find(specialized_parameter_list->begin(), specialized_parameter_list->end(), param_node);
|
||||
// multiply values found given for parameter
|
||||
if (node_itr != specialized_parameter_list->end()) {
|
||||
MS_LOG(EXCEPTION) << "Multiply values for specific argument:" << kw_param_name;
|
||||
} else {
|
||||
specialized_parameter_list->push_back(param_node);
|
||||
auto extract_node = specialized_graph->NewCNode(
|
||||
{NewValueNode(prim::kPrimExtractKeywordArg), NewValueNode(kw_param_name), param_node});
|
||||
(void)repl_nodes->emplace(param_node, extract_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GenerateKwargReplNode(specialized_graph, repl_nodes, kwarg_keys_tuple_nodes, kwarg_values_tuple_nodes);
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateKwargReplNode(const FuncGraphPtr &specialized_graph,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes,
|
||||
const std::vector<AnfNodePtr> &kwarg_keys_tuple_nodes,
|
||||
const std::vector<AnfNodePtr> &kwarg_values_tuple_nodes) {
|
||||
if (has_kwarg()) {
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
TraceManager::DebugTrace(
|
||||
std::make_shared<TraceGenerateKwArg>(specialized_graph->GetVariableKwargParameter()->debug_info()));
|
||||
auto make_tuple_keys = specialized_graph->NewCNode(kwarg_keys_tuple_nodes);
|
||||
auto make_tuple_values = specialized_graph->NewCNode(kwarg_values_tuple_nodes);
|
||||
auto make_dict_node =
|
||||
specialized_graph->NewCNode({NewValueNode(prim::kPrimMakeDict), make_tuple_keys, make_tuple_values});
|
||||
MS_EXCEPTION_IF_NULL(repl_nodes);
|
||||
(void)repl_nodes->emplace(specialized_graph->GetVariableKwargParameter(), make_dict_node);
|
||||
TraceManager::EndTrace();
|
||||
}
|
||||
}
|
||||
|
||||
bool FuncGraph::NeedGenerate(const std::vector<abstract::AbstractKeywordArgPtr> &kwarg_list) {
|
||||
// if the function does not have any vararg/kwarg/kwonly/default value/kw args input
|
||||
// return the original graph
|
||||
if (!has_vararg() && kwonlyargs_count() == 0 && !has_kwarg() && GetDefaultValueCount() == 0 && kwarg_list.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the graph is generated for specific input, do not need to generate again
|
||||
if (is_generated()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FuncGraph::GenerateDefaultValue(const FuncGraphPtr &specialized_graph,
|
||||
const std::vector<AnfNodePtr> &specialized_parameter_list,
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> *repl_nodes) {
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
for (size_t i = 0; i < specialized_graph->parameters().size() - hyper_param_count(); ++i) {
|
||||
auto param_node = specialized_graph->parameters()[i];
|
||||
MS_EXCEPTION_IF_NULL(param_node);
|
||||
auto param_name = param_node->cast<ParameterPtr>()->name();
|
||||
auto node_itr = std::find(specialized_parameter_list.begin(), specialized_parameter_list.end(), param_node);
|
||||
if (node_itr != specialized_parameter_list.end()) {
|
||||
continue;
|
||||
}
|
||||
if (param_name == specialized_graph->GetVariableArgName() ||
|
||||
param_name == specialized_graph->GetVariableKwargName()) {
|
||||
continue;
|
||||
}
|
||||
auto default_value = specialized_graph->GetDefaultValueByName(param_name);
|
||||
if (default_value == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "Miss argument input for parameter:" << param_name;
|
||||
}
|
||||
MS_EXCEPTION_IF_NULL(repl_nodes);
|
||||
(void)repl_nodes->emplace(param_node, default_value);
|
||||
}
|
||||
}
|
||||
|
||||
FuncGraphPtr FuncGraph::GenerateGraph(const AbstractBasePtrList &args_spec_list) {
|
||||
std::vector<abstract::AbstractKeywordArgPtr> kwarg_list;
|
||||
size_t arguments_count = args_spec_list.size();
|
||||
for (const auto &arg : args_spec_list) {
|
||||
// if it is a keyword argument
|
||||
MS_EXCEPTION_IF_NULL(arg);
|
||||
if (arg->isa<abstract::AbstractKeywordArg>()) {
|
||||
kwarg_list.push_back(dyn_cast<abstract::AbstractKeywordArg>(arg));
|
||||
}
|
||||
}
|
||||
if (!NeedGenerate(kwarg_list)) {
|
||||
return shared_from_base<FuncGraph>();
|
||||
}
|
||||
FuncGraphPtr specialized_graph = BasicClone(shared_from_base<FuncGraph>());
|
||||
size_t kwarg_count = kwarg_list.size();
|
||||
int pos_args_input_count = SizeToInt(arguments_count - kwarg_count - hyper_param_count());
|
||||
int pos_args_count = std::min(pos_args_input_count, this->GetPositionalArgsCount());
|
||||
int variable_args_count = pos_args_input_count - pos_args_count;
|
||||
std::vector<AnfNodePtr> specialized_parameter_list;
|
||||
std::unordered_map<AnfNodePtr, AnfNodePtr> repl_nodes;
|
||||
// the parameters that has arg input, copy from original parameters
|
||||
for (size_t i = 0; i < IntToSize(pos_args_count); ++i) {
|
||||
specialized_parameter_list.push_back(specialized_graph->parameters()[i]);
|
||||
}
|
||||
|
||||
GenerateVarParams(specialized_graph, &specialized_parameter_list, &repl_nodes, variable_args_count,
|
||||
pos_args_input_count);
|
||||
|
||||
GenerateKwParams(specialized_graph, &specialized_parameter_list, kwarg_list, &repl_nodes);
|
||||
|
||||
GenerateDefaultValue(specialized_graph, specialized_parameter_list, &repl_nodes);
|
||||
|
||||
// append hyper parameter to specialized_parameter_list
|
||||
MS_EXCEPTION_IF_NULL(specialized_graph);
|
||||
auto params = specialized_graph->parameters();
|
||||
(void)std::transform(params.end() - SizeToInt(hyper_param_count()), params.end(),
|
||||
std::back_inserter(specialized_parameter_list), [](const AnfNodePtr &node) { return node; });
|
||||
|
||||
std::shared_ptr<mindspore::FuncGraphManager> manager = mindspore::Manage(specialized_graph, false);
|
||||
auto tr = manager->Transact();
|
||||
for (auto &node_pair : repl_nodes) {
|
||||
MS_LOG(DEBUG) << "GenerateGraph replace:" << node_pair.first->DebugString() << "-"
|
||||
<< node_pair.second->DebugString();
|
||||
(void)tr.Replace(node_pair.first, node_pair.second);
|
||||
}
|
||||
tr.SetParameters(specialized_graph, specialized_parameter_list);
|
||||
tr.Commit();
|
||||
specialized_graph->set_has_kwarg(false);
|
||||
specialized_graph->set_has_vararg(false);
|
||||
specialized_graph->set_kwonlyargs_count(0);
|
||||
specialized_graph->ClearDefaultValues();
|
||||
specialized_graph->set_is_generate(true);
|
||||
return specialized_graph;
|
||||
}
|
||||
|
||||
const char kPrimHasEffect[] = "_side_effect_flag";
|
||||
|
||||
bool FuncGraph::HasEffect(const CNodePtr &cnode) {
|
||||
auto prim = GetCNodePrimitive(cnode);
|
||||
if (prim != nullptr && prim->isa<prim::DoSignaturePrimitive>()) {
|
||||
auto do_sig = prim->cast<prim::DoSignaturePrimitivePtr>();
|
||||
auto prim_val = do_sig->function();
|
||||
if (prim_val != nullptr && prim_val->isa<Primitive>()) {
|
||||
prim = prim_val->cast<PrimitivePtr>();
|
||||
} else {
|
||||
prim = nullptr;
|
||||
}
|
||||
}
|
||||
if (prim != nullptr) {
|
||||
auto effect_val = prim->GetAttr(kPrimHasEffect);
|
||||
if (effect_val && effect_val->isa<BoolImm>()) {
|
||||
auto effect_bool = GetValue<bool>(effect_val);
|
||||
return effect_bool;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> FindRoots(const std::vector<CNodePtr> &segment) {
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> roots = std::make_shared<OrderedSet<CNodePtr>>(segment);
|
||||
for (const auto &node : segment) {
|
||||
if (roots->size() == 1) {
|
||||
return roots;
|
||||
}
|
||||
auto input_size = node->size();
|
||||
for (size_t i = 0; i < input_size; i++) {
|
||||
auto in_node = node->input(i);
|
||||
auto in_cnode = in_node->cast<CNodePtr>();
|
||||
if (in_cnode != nullptr) {
|
||||
(void)roots->erase(in_cnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
}
|
||||
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> FindLeaves(const std::vector<CNodePtr> &segment) {
|
||||
std::shared_ptr<OrderedSet<CNodePtr>> nodes = std::make_shared<OrderedSet<CNodePtr>>(segment);
|
||||
for (const auto &node : segment) {
|
||||
if (nodes->size() == 1) {
|
||||
return nodes;
|
||||
}
|
||||
if (IsPrimitiveCNode(node, prim::kPrimSwitch)) {
|
||||
(void)nodes->erase(node);
|
||||
continue;
|
||||
}
|
||||
auto input_size = node->size();
|
||||
for (size_t i = 0; i < input_size; i++) {
|
||||
auto in_node = node->input(i);
|
||||
if (!in_node->isa<CNode>()) {
|
||||
continue;
|
||||
}
|
||||
auto in_cnode = in_node->cast<CNodePtr>();
|
||||
if (in_cnode != nullptr) {
|
||||
if (std::find(segment.begin(), segment.end(), in_cnode) != segment.end()) {
|
||||
(void)nodes->erase(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void FuncGraph::ReleaseFullOrderToEffectOrder() {
|
||||
MS_LOG(DEBUG) << "Flag has_effect " << has_flag(GRAPH_FLAG_HAS_EFFECT) << ".";
|
||||
if (has_flag(GRAPH_FLAG_HAS_EFFECT)) {
|
||||
std::list<AnfNodePtr> depends_order;
|
||||
std::vector<CNodePtr> segment;
|
||||
for (const auto &cnode : order_) {
|
||||
if (IsPrimitiveCNode(cnode, prim::kPrimReturn)) {
|
||||
continue;
|
||||
}
|
||||
if (HasEffect(cnode)) {
|
||||
MS_LOG(DEBUG) << "Meet a effect node " << cnode->DebugString() << ".";
|
||||
if (segment.size() > 0) {
|
||||
auto roots = FindRoots(segment);
|
||||
for (auto iter = roots->begin(); iter != roots->end(); (void)iter++) {
|
||||
depends_order.push_back(*iter);
|
||||
}
|
||||
}
|
||||
segment.clear();
|
||||
depends_order.push_back(cnode);
|
||||
} else {
|
||||
MS_LOG(DEBUG) << "Meet a general node " << cnode->DebugString() << ".";
|
||||
segment.push_back(cnode);
|
||||
}
|
||||
}
|
||||
if (segment.size() > 1) {
|
||||
auto roots = FindRoots(segment);
|
||||
for (auto iter = roots->begin(); iter != roots->end(); (void)iter++) {
|
||||
depends_order.push_back(*iter);
|
||||
}
|
||||
}
|
||||
std::vector<AnfNodePtr> depend_inputs;
|
||||
auto old_ret = output();
|
||||
for (auto iter = depends_order.rbegin(); iter != depends_order.rend(); (void)iter++) {
|
||||
if (*iter != old_ret) {
|
||||
depend_inputs.push_back(*iter);
|
||||
}
|
||||
}
|
||||
set_flags(GRAPH_FLAG_HAS_EFFECT, false);
|
||||
set_flags(GRAPH_FLAG_EFFECT_PATIAL_ORDER, true);
|
||||
if (!depend_inputs.empty()) {
|
||||
SetEffectDepends(depend_inputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FuncGraph::SetEffectDepends(const std::vector<AnfNodePtr> &depend_inputs) {
|
||||
auto old_ret = output();
|
||||
std::vector<AnfNodePtr> inputs{NewValueNode(prim::kPrimDepend), old_ret};
|
||||
(void)inputs.insert(inputs.end(), depend_inputs.begin(), depend_inputs.end());
|
||||
auto new_ret = NewCNode(inputs);
|
||||
auto mng = manager();
|
||||
if (mng) {
|
||||
(void)mng->Replace(old_ret, new_ret);
|
||||
} else {
|
||||
return_->set_input(1, new_ret);
|
||||
}
|
||||
}
|
||||
} // namespace mindspore
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -17,11 +17,14 @@
|
|||
*/
|
||||
|
||||
#include "ir/manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <list>
|
||||
#include "./common.h"
|
||||
|
||||
#include "ir/func_graph.h"
|
||||
#include "utils/profile.h"
|
||||
#include "utils/convert_utils.h"
|
||||
#include "operator/ops.h"
|
||||
#include "debug/trace.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -37,6 +37,7 @@
|
|||
#include "utils/graph_utils.h"
|
||||
#include "utils/counter.h"
|
||||
#include "utils/hashing.h"
|
||||
#include "utils/base_ref.h"
|
||||
#include "ir/anf.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,51 +22,20 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "device/device_address.h"
|
||||
#include "pybind_api/api_register.h"
|
||||
#include "pybind_api/export_flags.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
||||
namespace tensor {
|
||||
|
||||
void DataBuf2Contiguous(const py::array &src, py::array *const dest) {
|
||||
if (dest == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "Failed to copy data to a contiguous buffer as dest is nullptr!";
|
||||
}
|
||||
|
||||
Py_buffer pybuf_src;
|
||||
if (PyObject_GetBuffer(src.ptr(), &pybuf_src, PyBUF_ANY_CONTIGUOUS)) {
|
||||
MS_LOG(EXCEPTION) << "Failed to get buffer info from the src!";
|
||||
}
|
||||
|
||||
if (!PyBuffer_IsContiguous(&pybuf_src, 'C')) {
|
||||
if (PyBuffer_ToContiguous(dest->request(true).ptr, &pybuf_src, pybuf_src.len, 'C')) {
|
||||
MS_LOG(EXCEPTION) << "Can't copy numpy.ndarray to a contiguous buffer.";
|
||||
}
|
||||
} else {
|
||||
*dest = src;
|
||||
}
|
||||
|
||||
PyBuffer_Release(&pybuf_src);
|
||||
}
|
||||
|
||||
// MetaTensor has default type_id_ which is TypeId::kTypeUnknown.
|
||||
MetaTensor::MetaTensor() : data_type_(TypeId::kTypeUnknown) {}
|
||||
|
||||
MetaTensor::MetaTensor(const TypeId data_type, const std::vector<int> &shape) : data_type_(data_type), shape_(shape) {}
|
||||
|
||||
MetaTensor::MetaTensor(const TypePtr &type_ptr, const py::tuple &shape) {
|
||||
MetaTensor::MetaTensor(const TypePtr &type_ptr, const std::vector<int> &shape) {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (type_ptr != nullptr) {
|
||||
data_type = type_ptr->type_id();
|
||||
}
|
||||
data_type_ = data_type;
|
||||
shape_.resize(shape.size());
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
shape_[i] = py::int_(shape[i]);
|
||||
}
|
||||
shape_ = shape;
|
||||
}
|
||||
|
||||
MetaTensor::MetaTensor(const MetaTensor &meta_tensor)
|
||||
|
@ -102,26 +71,6 @@ int MetaTensor::DimensionSize(const size_t index) const {
|
|||
return dim_size;
|
||||
}
|
||||
|
||||
abstract::AbstractBasePtr MetaTensor::ToAbstract() {
|
||||
auto tens = shared_from_base<MetaTensor>();
|
||||
auto dtype = tens->Dtype();
|
||||
if (!IsSubType(dtype, kNumber)) {
|
||||
MS_LOG(EXCEPTION) << "Expect MetaTensor type kNumber but got: " << dtype->ToString() << ".";
|
||||
}
|
||||
auto tensor_shape = tens->shape();
|
||||
auto abs_tensor = std::make_shared<abstract::AbstractTensor>(dtype, tensor_shape);
|
||||
abs_tensor->set_value(shared_from_base<MetaTensor>());
|
||||
return abs_tensor;
|
||||
}
|
||||
|
||||
py::tuple MetaTensor::GetPyTupleShape() const {
|
||||
py::tuple dims(shape_.size());
|
||||
for (size_t i = 0; i < dims.size(); ++i) {
|
||||
dims[i] = py::int_(shape_[i]);
|
||||
}
|
||||
return dims;
|
||||
}
|
||||
|
||||
int MetaTensor::ElementsNum() const {
|
||||
return std::accumulate(shape_.begin(), shape_.end(), 1LL, std::multiplies<int>());
|
||||
}
|
||||
|
@ -157,435 +106,5 @@ std::string MetaTensor::DumpText() const {
|
|||
oss << "]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
Tensor::Tensor(const TypePtr &type_ptr, const py::tuple &shape) {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (type_ptr != nullptr) {
|
||||
data_type = type_ptr->type_id();
|
||||
}
|
||||
data_type_ = data_type;
|
||||
shape_.resize(shape.size());
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
shape_[i] = py::int_(shape[i]);
|
||||
}
|
||||
init(data_type_, shape_, &data_);
|
||||
}
|
||||
|
||||
Tensor::Tensor(TypeId data_type, const std::vector<int> &shape) { init(data_type, shape, &data_); }
|
||||
|
||||
Tensor::Tensor(const py::array &input, const TypePtr &data_type) { init(input, data_type); }
|
||||
|
||||
Tensor::Tensor(const py::list &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::tuple &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::float_ &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::int_ &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const Tensor &tensor, const TypePtr &data_type)
|
||||
: MetaTensor(tensor), device_address_(tensor.device_address_) {
|
||||
init(tensor.data_, data_type);
|
||||
dirty_ = tensor.is_dirty();
|
||||
}
|
||||
|
||||
Tensor &Tensor::operator=(const Tensor &tensor) {
|
||||
if (this != &tensor) {
|
||||
MetaTensor::operator=(tensor);
|
||||
dirty_ = tensor.is_dirty();
|
||||
device_address_ = tensor.device_address();
|
||||
data_ = tensor.data_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Tensor::operator==(const Tensor &tensor) const {
|
||||
return (MetaTensor::operator==(tensor) && data_ == tensor.data_);
|
||||
}
|
||||
|
||||
bool Tensor::ValueEqual(const Tensor &other) const {
|
||||
auto equal = [&other, this]() -> bool {
|
||||
auto np = py::module::import("numpy");
|
||||
auto equal = np.attr("equal")(data_, other.data_);
|
||||
auto all_equal = np.attr("all")(equal);
|
||||
return all_equal.cast<bool>();
|
||||
};
|
||||
return (MetaTensor::operator==(other) && (data_.is(other.data_) || equal()));
|
||||
}
|
||||
|
||||
int Tensor::DataDim() const { return static_cast<int>(data_.ndim()); }
|
||||
|
||||
int Tensor::DataSize() const { return static_cast<int>(data_.size()); }
|
||||
|
||||
py::array Tensor::data() const { return data_; }
|
||||
|
||||
int Tensor::data_type_c() const { return static_cast<int>(data_type_); }
|
||||
|
||||
std::vector<int> Tensor::shape_c(void) const { return shape(); }
|
||||
|
||||
void *Tensor::data_c(bool writable) {
|
||||
// operand of bit operation should be unsigned int.
|
||||
unsigned int flags = ((unsigned int)data_.flags()) & pybind11::detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_;
|
||||
bool is_c_contiguous = (flags != 0) ? true : false;
|
||||
if (!is_c_contiguous) {
|
||||
py::array data_c;
|
||||
init(data_type_, shape_, &data_c);
|
||||
DataBuf2Contiguous(data_, &data_c);
|
||||
data_ = data_c;
|
||||
}
|
||||
return data_.request(writable).ptr;
|
||||
}
|
||||
|
||||
TypeId Tensor::GetDataType(const py::buffer_info &buf) const {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (buf.format.compare("e") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat16;
|
||||
} else if (buf.format.compare("f") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat32;
|
||||
} else if (buf.format.compare("d") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat64;
|
||||
} else if (buf.format.compare("B") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt8;
|
||||
} else if (buf.format.compare("H") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt16;
|
||||
} else if (buf.format.compare("I") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt32;
|
||||
} else if (buf.format.compare("L") == 0 || buf.format.compare("Q") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt64;
|
||||
} else if (buf.format.compare("b") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt8;
|
||||
} else if (buf.format.compare("h") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt16;
|
||||
} else if (buf.format.compare("i") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt32;
|
||||
} else if (buf.format.compare("l") == 0 || buf.format.compare("q") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt64;
|
||||
} else if (buf.format.compare("?") == 0) {
|
||||
data_type = TypeId::kNumberTypeBool;
|
||||
} else {
|
||||
MS_LOG(WARNING) << "Get unsupported DataType " << buf.format << ".";
|
||||
}
|
||||
return data_type;
|
||||
}
|
||||
|
||||
void Tensor::init(const py::array &input, const TypePtr &type_ptr) {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (type_ptr != nullptr) {
|
||||
data_type = type_ptr->type_id();
|
||||
}
|
||||
init(input, data_type);
|
||||
}
|
||||
|
||||
void Tensor::init(const py::array &input, const TypeId &data_type) {
|
||||
py::buffer_info buf = input.request();
|
||||
|
||||
data_type_ = GetDataType(buf);
|
||||
if (TypeId::kTypeUnknown == data_type && TypeId::kTypeUnknown == data_type_) {
|
||||
MS_LOG(EXCEPTION) << "Unsupported tensor type!";
|
||||
}
|
||||
|
||||
std::vector<ssize_t> tm = buf.shape;
|
||||
size_t len = tm.size();
|
||||
std::vector<int> dims(len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
dims[i] = static_cast<int>(tm[i]);
|
||||
}
|
||||
(void)set_shape(dims);
|
||||
|
||||
if (TypeId::kTypeUnknown != data_type && TypeId::kTypeUnknown != data_type_ && data_type_ != data_type) {
|
||||
// If user defined data type is not same as GetDataType from the data
|
||||
bool success = convert_data(input, data_type_, &data_, data_type);
|
||||
if (success) {
|
||||
data_type_ = data_type;
|
||||
} else {
|
||||
data_type_ = TypeId::kTypeUnknown;
|
||||
MS_LOG(EXCEPTION) << "Convert data from " << data_type_ << " to " << data_type << " failed!";
|
||||
}
|
||||
} else {
|
||||
data_ = input;
|
||||
}
|
||||
dirty_ = true;
|
||||
}
|
||||
|
||||
void Tensor::init(TypeId data_type, const std::vector<int> &shape, py::array *const data) {
|
||||
data_type_ = data_type;
|
||||
shape_ = shape;
|
||||
switch (data_type) {
|
||||
case kNumberTypeBool:
|
||||
*data = py::array_t<bool, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt8:
|
||||
*data = py::array_t<int8_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt16:
|
||||
*data = py::array_t<int16_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt32:
|
||||
*data = py::array_t<int32_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt64:
|
||||
*data = py::array_t<int64_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt8:
|
||||
*data = py::array_t<uint8_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt16:
|
||||
*data = py::array_t<uint16_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt32:
|
||||
*data = py::array_t<uint32_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt64:
|
||||
*data = py::array_t<uint64_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat16:
|
||||
*data = py::array_t<float16, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat32:
|
||||
*data = py::array_t<float, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat64:
|
||||
*data = py::array_t<double, py::array::c_style>(shape);
|
||||
break;
|
||||
default:
|
||||
MS_LOG(EXCEPTION) << "Cannot construct Tensor because of unsupported data type: " << data_type << ".";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TypePtr Tensor::SetDtype(const TypePtr type_ptr) {
|
||||
MS_EXCEPTION_IF_NULL(type_ptr);
|
||||
(void)set_data_type(type_ptr->type_id());
|
||||
return type_ptr;
|
||||
}
|
||||
|
||||
TypeId Tensor::set_data_type(const TypeId data_type) {
|
||||
if (data_.size() > 0 && data_type_ != data_type) {
|
||||
bool success = convert_data(data_, data_type_, &data_, data_type);
|
||||
if (success) {
|
||||
data_type_ = data_type;
|
||||
} else {
|
||||
MS_LOG(EXCEPTION) << "Convert data from " << data_type_ << " to " << data_type << " failed!";
|
||||
}
|
||||
} else if (data_.size() == 0) {
|
||||
data_type_ = data_type;
|
||||
}
|
||||
|
||||
return data_type_;
|
||||
}
|
||||
|
||||
bool Tensor::is_init() { return init_flag_; }
|
||||
|
||||
void Tensor::set_init_flag(bool flag) { init_flag_ = flag; }
|
||||
|
||||
bool Tensor::convert_data(const py::array &in, const TypeId in_data_type, py::array *const out,
|
||||
const TypeId out_data_type) {
|
||||
if (out == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
if (TypeId::kTypeUnknown == in_data_type || TypeId::kTypeUnknown == out_data_type) {
|
||||
result = false;
|
||||
} else if (in_data_type == out_data_type) {
|
||||
*out = in;
|
||||
} else if (TypeId::kNumberTypeFloat64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float64").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeFloat32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeFloat16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int64").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt8 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int8").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt8 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint8").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint64").cast<py::array>();
|
||||
} else {
|
||||
data_type_ = TypeId::kTypeUnknown;
|
||||
MS_LOG(EXCEPTION) << "Cannot convert from " << TypeIdLabel(in_data_type) << " to " << TypeIdLabel(out_data_type)
|
||||
<< ".";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract::AbstractBasePtr Tensor::ToAbstract() {
|
||||
auto tens = shared_from_base<Tensor>();
|
||||
auto dtype = tens->Dtype();
|
||||
if (!IsSubType(dtype, kNumber)) {
|
||||
MS_LOG(EXCEPTION) << "Expect tensor type kNumber but got: " << dtype->ToString() << ".";
|
||||
}
|
||||
auto tensor_shape = tens->shape();
|
||||
auto abs_tensor = std::make_shared<abstract::AbstractTensor>(dtype, tensor_shape);
|
||||
abs_tensor->set_value(shared_from_base<Tensor>());
|
||||
return abs_tensor;
|
||||
}
|
||||
|
||||
std::string Tensor::GetShapeAndDataTypeInfo() const {
|
||||
std::ostringstream buf;
|
||||
buf << "Tensor \nshape:[" << shape() << "]" << this->Dtype()->ToString();
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
std::string Tensor::ToString() const {
|
||||
const int small_tensor_size = 30;
|
||||
std::ostringstream buf;
|
||||
buf << "Tensor \nshape:[" << shape() << "]" << this->Dtype()->ToString();
|
||||
// only print small tensor
|
||||
if (DataSize() < small_tensor_size) {
|
||||
buf << "val:" << std::string(py::str(data()));
|
||||
}
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
std::string Tensor::ToStringRepr() const {
|
||||
std::ostringstream buf;
|
||||
auto type_ptr = this->Dtype();
|
||||
MS_EXCEPTION_IF_NULL(type_ptr);
|
||||
buf << "Tensor shape:[" << shape() << "]" << type_ptr->ToString();
|
||||
buf << "\nval:" << std::string(py::str(data()));
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
py::array Tensor::data_sync() {
|
||||
if (device_address_ != nullptr) {
|
||||
if (!device_address_->SyncDeviceToHost(this->shape(), static_cast<size_t>(this->data().nbytes()), this->data_type(),
|
||||
this->data_c(true))) {
|
||||
MS_LOG(EXCEPTION) << "SyncDeviceToHost when asnumpy.";
|
||||
}
|
||||
}
|
||||
return data_;
|
||||
}
|
||||
|
||||
REGISTER_PYBIND_DEFINE(Tensor, ([](const py::module *m) {
|
||||
// dtype should define before Tensor, because Tensor init depend dtype
|
||||
(void)py::class_<Tensor, std::shared_ptr<Tensor>>(*m, "Tensor")
|
||||
.def(py::init<TypePtr, py::tuple>(), py::arg("dtype"), py::arg("shape"))
|
||||
.def(py::init<py::array, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::float_, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::int_, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::list, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::tuple, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<Tensor, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def_readonly(PYTHON_TENSOR_FLAG, &Tensor::parse_info_)
|
||||
.def("asnumpy", &Tensor::data_sync, R"mydelimiter(
|
||||
Convert tensor to numpy.ndarray.
|
||||
|
||||
Returns:
|
||||
numpy.ndarray.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> array = data.asnumpy()
|
||||
>>> array
|
||||
array([[1., 1., 1.],
|
||||
[1., 1., 1.]])
|
||||
)mydelimiter")
|
||||
.def("size", &Tensor::DataSize, R"mydelimiter(
|
||||
Get tensor's data size.
|
||||
|
||||
Returns:
|
||||
int, the size of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.size()
|
||||
6
|
||||
)mydelimiter")
|
||||
.def("is_init", &Tensor::is_init, R"mydelimiter(
|
||||
Get tensor init_flag.
|
||||
|
||||
Returns:
|
||||
bool, whether the tensor init.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.is_init()
|
||||
False
|
||||
)mydelimiter")
|
||||
.def("set_init_flag", &Tensor::set_init_flag, R"mydelimiter(
|
||||
Set tensor init_flag.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.set_init_flag(True)
|
||||
)mydelimiter")
|
||||
.def("dim", &Tensor::DataDim, R"mydelimiter(
|
||||
Get tensor's data dimension.
|
||||
|
||||
Returns:
|
||||
int, the dimension of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.dim()
|
||||
2
|
||||
)mydelimiter")
|
||||
.def("dtype", &Tensor::Dtype, R"mydelimiter(
|
||||
Get the tensor's data type.
|
||||
|
||||
Returns:
|
||||
type, the data type of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 1), np.int32))
|
||||
>>> data.dtype()
|
||||
Int32
|
||||
)mydelimiter")
|
||||
.def("set_dtype", &Tensor::SetDtype, R"mydelimiter(
|
||||
Set the tensor's data type.
|
||||
|
||||
Arg:
|
||||
dtype (:class:`mindspore.dtype`): The type of output tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((1, 2), np.float32))
|
||||
>>> data.set_dtype(mindspore.int32)
|
||||
mindspore.int32
|
||||
)mydelimiter")
|
||||
.def("shape", &Tensor::GetPyTupleShape, R"mydelimiter(
|
||||
Get the tensor's shape.
|
||||
|
||||
Returns:
|
||||
tuple[int], the shape of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((3, 3)))
|
||||
>>> data.shape()
|
||||
(3, 3)
|
||||
)mydelimiter")
|
||||
.def("__str__", &Tensor::ToString)
|
||||
.def("__repr__", &Tensor::ToStringRepr)
|
||||
.def(py::pickle(
|
||||
[](const Tensor &t) { // __getstate__
|
||||
/* Return a tuple that fully encodes the state of the object */
|
||||
return py::make_tuple(t.data());
|
||||
},
|
||||
[](const py::tuple &t) { // __setstate__
|
||||
if (t.size() != 1) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
/* Create a new C++ instance */
|
||||
Tensor tensor(t[0].cast<py::array>());
|
||||
return tensor;
|
||||
}));
|
||||
(void)py::class_<MetaTensor, std::shared_ptr<MetaTensor>>(*m, "MetaTensor")
|
||||
.def(py::init<TypePtr, py::tuple>(), py::arg("dtype"), py::arg("shape"))
|
||||
.def_readonly(PYTHON_META_TENSOR_FLAG, &MetaTensor::parse_info_)
|
||||
.def("dtype", &MetaTensor::Dtype, "Get the MetaTensor's dtype.")
|
||||
.def("shape", &MetaTensor::GetPyTupleShape, "Get the MetaTensor's shape.");
|
||||
}));
|
||||
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -21,80 +21,12 @@
|
|||
#include <vector>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "device/device_address.h"
|
||||
|
||||
#include "pybind11/numpy.h"
|
||||
#include "pybind11/pybind11.h"
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "ir/base.h"
|
||||
#include "ir/dtype.h"
|
||||
#include "utils/log_adapter.h"
|
||||
#include "utils/convert_utils.h"
|
||||
#include "utils/hashing.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
using float16 = Eigen::half;
|
||||
|
||||
namespace pybind11 {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Similar to enums in `pybind11/numpy.h`. Determined by doing:
|
||||
// python3 -c 'import numpy as np; print(np.dtype(np.float16).num)'
|
||||
constexpr int NPY_FLOAT16 = 23;
|
||||
|
||||
template <typename T>
|
||||
struct npy_scalar_caster {
|
||||
PYBIND11_TYPE_CASTER(T, _("PleaseOverride"));
|
||||
using Array = array_t<T>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
// Taken from Eigen casters. Permits either scalar dtype or scalar array.
|
||||
handle type = dtype::of<T>().attr("type");
|
||||
if (!convert && !isinstance<Array>(src) && !isinstance(src, type)) return false;
|
||||
|
||||
Array tmp = Array::ensure(src);
|
||||
if (tmp && tmp.size() == 1 && tmp.ndim() == 0) {
|
||||
this->value = *tmp.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static handle cast(T src, return_value_policy, handle) {
|
||||
Array tmp({1});
|
||||
tmp.mutable_at(0) = src;
|
||||
tmp.resize({});
|
||||
|
||||
// You could also just return the array if you want a scalar array.
|
||||
object scalar = tmp[tuple()];
|
||||
return scalar.release();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct npy_format_descriptor<float16> {
|
||||
static constexpr auto name = "float16";
|
||||
static pybind11::dtype dtype() {
|
||||
handle ptr = npy_api::get().PyArray_DescrFromType_(NPY_FLOAT16);
|
||||
return reinterpret_borrow<pybind11::dtype>(ptr);
|
||||
}
|
||||
virtual ~npy_format_descriptor<float16>() {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_caster<float16> : public npy_scalar_caster<float16> {
|
||||
static constexpr auto name = "float16";
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
|
||||
using mindspore::device::DeviceAddress;
|
||||
using DeviceAddressPtr = std::shared_ptr<mindspore::device::DeviceAddress>;
|
||||
// brief mindspore namespace.
|
||||
//
|
||||
// mindspore namespace is the top level namespace of Mindsporeession project.
|
||||
|
@ -133,7 +65,7 @@ class MetaTensor : public Value {
|
|||
// param shape The shape of the tensor.
|
||||
MetaTensor(const TypeId data_type, const std::vector<int> &shape);
|
||||
|
||||
MetaTensor(const TypePtr &type_ptr, const py::tuple &shape);
|
||||
MetaTensor(const TypePtr &type_ptr, const std::vector<int> &shape);
|
||||
// brief Constructs a MetaTensor object from an existing MetaTensor instance.
|
||||
//
|
||||
// The constructed MetaTensor object will have the same data type and shape as the
|
||||
|
@ -164,7 +96,6 @@ class MetaTensor : public Value {
|
|||
// All the types are defined in "ir/dtype.h".
|
||||
TypePtr Dtype() const;
|
||||
abstract::AbstractBasePtr ToAbstract() override;
|
||||
py::tuple GetPyTupleShape() const;
|
||||
TypeId data_type() const { return data_type_; }
|
||||
std::string ToString() const override;
|
||||
std::string DumpText() const override;
|
||||
|
@ -256,175 +187,7 @@ class MetaTensor : public Value {
|
|||
DeviceInfo device_info_;
|
||||
};
|
||||
|
||||
// Tensor entity class
|
||||
class Tensor : public MetaTensor {
|
||||
public:
|
||||
Tensor() = default;
|
||||
abstract::AbstractBasePtr ToAbstract() override;
|
||||
// brief Constructor for Python.
|
||||
//
|
||||
// param type_ptr [TypePty] Data type of the tensor.
|
||||
// param py_shape [py::tuple] The shape represented by py::tuple of the tensor.
|
||||
Tensor(const TypePtr &type_ptr, const py::tuple &shape);
|
||||
|
||||
// brief Constructor for C++.
|
||||
//
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
// param shape The shape represented by std::vector<int> of the tensor.
|
||||
Tensor(TypeId data_type, const std::vector<int> &shape);
|
||||
|
||||
// brief Constructor for Python.
|
||||
//
|
||||
// param input [py::array] Data value of the tensor.
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
explicit Tensor(const py::array &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::list] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::list &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::tuple] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::tuple &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::float_] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::float_ &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::int_] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::int_ &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [Tensor] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
Tensor(const Tensor &tensor, const TypePtr &data_type = nullptr);
|
||||
|
||||
~Tensor() override = default;
|
||||
|
||||
MS_DECLARE_PARENT(Tensor, MetaTensor);
|
||||
|
||||
// brief Overloads operator = for Tensor.
|
||||
//
|
||||
// The constructed Tensor object has the same type and shape with tensor.
|
||||
//
|
||||
// param tensor An existing Tensor object.
|
||||
Tensor &operator=(const Tensor &tensor);
|
||||
|
||||
// brief Compares two Tensor objects.
|
||||
//
|
||||
// Compare two tensor objects to see if they have same data type, shape and
|
||||
// data value.
|
||||
//
|
||||
// param tensor The Tensor object to be compared.
|
||||
// return true: If having same type, shape and data, return true, or return false.
|
||||
bool operator==(const Tensor &tensor) const;
|
||||
|
||||
// It is different from 'operator==' which just compare shape/type/address, it do real value comparison.
|
||||
bool ValueEqual(const Tensor &other) const;
|
||||
|
||||
bool operator==(const Value &other) const override {
|
||||
if (other.isa<Tensor>()) {
|
||||
auto other_ = static_cast<const Tensor &>(other);
|
||||
return *this == other_;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// brief Gets tensor's dimension
|
||||
//
|
||||
// return The number of dimensions of the tensor data.
|
||||
int DataDim() const;
|
||||
|
||||
// brief Getting tensor data size
|
||||
//
|
||||
// return The total number of elements of the tensor data.
|
||||
int DataSize() const;
|
||||
|
||||
// brief Tensor's data value.
|
||||
//
|
||||
// return [py::array] The tensor's data in py::array.
|
||||
py::array data() const;
|
||||
|
||||
// brief Get the data type fo the tensor for C++
|
||||
//
|
||||
// return [int] The tensor's data type will be cast to int to return.
|
||||
int data_type_c() const;
|
||||
|
||||
// brief Get the tensor's shape for C++
|
||||
//
|
||||
// return [std::vector<int>]
|
||||
std::vector<int> shape_c(void) const;
|
||||
|
||||
// brief Get Tensor data pointer for c++ type
|
||||
//
|
||||
// param writable true if writable, false if read only
|
||||
// return The pointer to the object
|
||||
void *data_c(bool writable = false);
|
||||
|
||||
// brief Get data type from tensor data.
|
||||
//
|
||||
// param buf The buffer info of the py::array data.
|
||||
// return The [TypeId] of the tensor data.
|
||||
TypeId GetDataType(const py::buffer_info &buf) const;
|
||||
|
||||
// brief Sets the data type of a tensor.
|
||||
//
|
||||
// param data_type The data type of the tensor to be set.
|
||||
//
|
||||
TypeId set_data_type(const TypeId data_type) override;
|
||||
TypePtr SetDtype(const TypePtr type_ptr) override;
|
||||
std::string GetShapeAndDataTypeInfo() const;
|
||||
std::string ToString() const override;
|
||||
std::string ToStringRepr() const;
|
||||
py::array data_; // < Tensor's data value
|
||||
const bool parse_info_ = true;
|
||||
bool is_init();
|
||||
void set_init_flag(bool flag);
|
||||
|
||||
private:
|
||||
// brief init tensor
|
||||
//
|
||||
// param input [py::array] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
// return true if succeed, false if failed.
|
||||
void init(const py::array &input, const TypeId &data_type);
|
||||
void init(const py::array &input, const TypePtr &type_ptr);
|
||||
bool init_flag_{false};
|
||||
// brief init tensor attribute
|
||||
//
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
// param shape [py::array] The shape of the tensor.
|
||||
// return true if succeed, false if failed.
|
||||
void init(TypeId data_type, const std::vector<int> &shape, py::array *data);
|
||||
|
||||
bool convert_data(const py::array &in, const TypeId in_data_type, py::array *out, const TypeId out_data_type);
|
||||
|
||||
public:
|
||||
bool is_dirty() const { return dirty_; }
|
||||
void set_dirty(const bool dirty) { dirty_ = dirty; }
|
||||
DeviceAddressPtr device_address() const { return device_address_; }
|
||||
void set_device_address(const DeviceAddressPtr &device_address) { device_address_ = device_address; }
|
||||
py::array data_sync();
|
||||
|
||||
private:
|
||||
bool dirty_{true};
|
||||
DeviceAddressPtr device_address_{nullptr};
|
||||
};
|
||||
|
||||
using TensorPtr = std::shared_ptr<Tensor>;
|
||||
using MetaTensorPtr = std::shared_ptr<MetaTensor>;
|
||||
using TensorPtrList = std::vector<std::shared_ptr<Tensor>>;
|
||||
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* Copyright 2020 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 "ir/meta_tensor.h"
|
||||
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace tensor {
|
||||
abstract::AbstractBasePtr MetaTensor::ToAbstract() {
|
||||
auto tens = shared_from_base<MetaTensor>();
|
||||
auto dtype = tens->Dtype();
|
||||
if (!IsSubType(dtype, kNumber)) {
|
||||
MS_LOG(EXCEPTION) << "Expect MetaTensor type kNumber but got: " << dtype->ToString() << ".";
|
||||
}
|
||||
auto tensor_shape = tens->shape();
|
||||
auto abs_tensor = std::make_shared<abstract::AbstractTensor>(dtype, tensor_shape);
|
||||
abs_tensor->set_value(shared_from_base<MetaTensor>());
|
||||
return abs_tensor;
|
||||
}
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,494 @@
|
|||
/**
|
||||
* Copyright 2020 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 "ir/tensor.h"
|
||||
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "device/device_address.h"
|
||||
#include "pybind_api/api_register.h"
|
||||
#include "pybind_api/export_flags.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
||||
namespace tensor {
|
||||
|
||||
void DataBuf2Contiguous(const py::array &src, py::array *const dest) {
|
||||
if (dest == nullptr) {
|
||||
MS_LOG(EXCEPTION) << "Failed to copy data to a contiguous buffer as dest is nullptr!";
|
||||
}
|
||||
|
||||
Py_buffer pybuf_src;
|
||||
if (PyObject_GetBuffer(src.ptr(), &pybuf_src, PyBUF_ANY_CONTIGUOUS)) {
|
||||
MS_LOG(EXCEPTION) << "Failed to get buffer info from the src!";
|
||||
}
|
||||
|
||||
if (!PyBuffer_IsContiguous(&pybuf_src, 'C')) {
|
||||
if (PyBuffer_ToContiguous(dest->request(true).ptr, &pybuf_src, pybuf_src.len, 'C')) {
|
||||
MS_LOG(EXCEPTION) << "Can't copy numpy.ndarray to a contiguous buffer.";
|
||||
}
|
||||
} else {
|
||||
*dest = src;
|
||||
}
|
||||
|
||||
PyBuffer_Release(&pybuf_src);
|
||||
}
|
||||
|
||||
Tensor::Tensor(const TypePtr &type_ptr, const py::tuple &shape) {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (type_ptr != nullptr) {
|
||||
data_type = type_ptr->type_id();
|
||||
}
|
||||
data_type_ = data_type;
|
||||
shape_.resize(shape.size());
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
shape_[i] = py::int_(shape[i]);
|
||||
}
|
||||
init(data_type_, shape_, &data_);
|
||||
}
|
||||
|
||||
Tensor::Tensor(TypeId data_type, const std::vector<int> &shape) { init(data_type, shape, &data_); }
|
||||
|
||||
Tensor::Tensor(const py::array &input, const TypePtr &data_type) { init(input, data_type); }
|
||||
|
||||
Tensor::Tensor(const py::list &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::tuple &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::float_ &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const py::int_ &input, const TypePtr &data_type) { init(py::array(input), data_type); }
|
||||
|
||||
Tensor::Tensor(const Tensor &tensor, const TypePtr &data_type)
|
||||
: MetaTensor(tensor), device_address_(tensor.device_address_) {
|
||||
init(tensor.data_, data_type);
|
||||
dirty_ = tensor.is_dirty();
|
||||
}
|
||||
|
||||
Tensor &Tensor::operator=(const Tensor &tensor) {
|
||||
if (this != &tensor) {
|
||||
MetaTensor::operator=(tensor);
|
||||
dirty_ = tensor.is_dirty();
|
||||
device_address_ = tensor.device_address();
|
||||
data_ = tensor.data_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Tensor::operator==(const Tensor &tensor) const {
|
||||
return (MetaTensor::operator==(tensor) && data_ == tensor.data_);
|
||||
}
|
||||
|
||||
bool Tensor::ValueEqual(const Tensor &other) const {
|
||||
auto equal = [&other, this]() -> bool {
|
||||
auto np = py::module::import("numpy");
|
||||
auto equal = np.attr("equal")(data_, other.data_);
|
||||
auto all_equal = np.attr("all")(equal);
|
||||
return all_equal.cast<bool>();
|
||||
};
|
||||
return (MetaTensor::operator==(other) && (data_.is(other.data_) || equal()));
|
||||
}
|
||||
|
||||
py::tuple Tensor::GetPyTupleShape() const {
|
||||
std::vector<int> shape = this->shape();
|
||||
py::tuple dims(shape.size());
|
||||
for (size_t i = 0; i < dims.size(); ++i) {
|
||||
dims[i] = py::int_(shape[i]);
|
||||
}
|
||||
return dims;
|
||||
}
|
||||
|
||||
int Tensor::DataDim() const { return static_cast<int>(data_.ndim()); }
|
||||
|
||||
int Tensor::DataSize() const { return static_cast<int>(data_.size()); }
|
||||
|
||||
py::array Tensor::data() const { return data_; }
|
||||
|
||||
int Tensor::data_type_c() const { return static_cast<int>(data_type_); }
|
||||
|
||||
std::vector<int> Tensor::shape_c(void) const { return shape(); }
|
||||
|
||||
void *Tensor::data_c(bool writable) {
|
||||
// operand of bit operation should be unsigned int.
|
||||
unsigned int flags = ((unsigned int)data_.flags()) & pybind11::detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_;
|
||||
bool is_c_contiguous = (flags != 0) ? true : false;
|
||||
if (!is_c_contiguous) {
|
||||
py::array data_c;
|
||||
init(data_type_, shape_, &data_c);
|
||||
DataBuf2Contiguous(data_, &data_c);
|
||||
data_ = data_c;
|
||||
}
|
||||
return data_.request(writable).ptr;
|
||||
}
|
||||
|
||||
TypeId Tensor::GetDataType(const py::buffer_info &buf) const {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (buf.format.compare("e") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat16;
|
||||
} else if (buf.format.compare("f") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat32;
|
||||
} else if (buf.format.compare("d") == 0) {
|
||||
data_type = TypeId::kNumberTypeFloat64;
|
||||
} else if (buf.format.compare("B") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt8;
|
||||
} else if (buf.format.compare("H") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt16;
|
||||
} else if (buf.format.compare("I") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt32;
|
||||
} else if (buf.format.compare("L") == 0 || buf.format.compare("Q") == 0) {
|
||||
data_type = TypeId::kNumberTypeUInt64;
|
||||
} else if (buf.format.compare("b") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt8;
|
||||
} else if (buf.format.compare("h") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt16;
|
||||
} else if (buf.format.compare("i") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt32;
|
||||
} else if (buf.format.compare("l") == 0 || buf.format.compare("q") == 0) {
|
||||
data_type = TypeId::kNumberTypeInt64;
|
||||
} else if (buf.format.compare("?") == 0) {
|
||||
data_type = TypeId::kNumberTypeBool;
|
||||
} else {
|
||||
MS_LOG(WARNING) << "Get unsupported DataType " << buf.format << ".";
|
||||
}
|
||||
return data_type;
|
||||
}
|
||||
|
||||
void Tensor::init(const py::array &input, const TypePtr &type_ptr) {
|
||||
TypeId data_type = TypeId::kTypeUnknown;
|
||||
if (type_ptr != nullptr) {
|
||||
data_type = type_ptr->type_id();
|
||||
}
|
||||
init(input, data_type);
|
||||
}
|
||||
|
||||
void Tensor::init(const py::array &input, const TypeId &data_type) {
|
||||
py::buffer_info buf = input.request();
|
||||
|
||||
data_type_ = GetDataType(buf);
|
||||
if (TypeId::kTypeUnknown == data_type && TypeId::kTypeUnknown == data_type_) {
|
||||
MS_LOG(EXCEPTION) << "Unsupported tensor type!";
|
||||
}
|
||||
|
||||
std::vector<ssize_t> tm = buf.shape;
|
||||
size_t len = tm.size();
|
||||
std::vector<int> dims(len);
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
dims[i] = static_cast<int>(tm[i]);
|
||||
}
|
||||
(void)set_shape(dims);
|
||||
|
||||
if (TypeId::kTypeUnknown != data_type && TypeId::kTypeUnknown != data_type_ && data_type_ != data_type) {
|
||||
// If user defined data type is not same as GetDataType from the data
|
||||
bool success = convert_data(input, data_type_, &data_, data_type);
|
||||
if (success) {
|
||||
data_type_ = data_type;
|
||||
} else {
|
||||
data_type_ = TypeId::kTypeUnknown;
|
||||
MS_LOG(EXCEPTION) << "Convert data from " << data_type_ << " to " << data_type << " failed!";
|
||||
}
|
||||
} else {
|
||||
data_ = input;
|
||||
}
|
||||
dirty_ = true;
|
||||
}
|
||||
|
||||
void Tensor::init(TypeId data_type, const std::vector<int> &shape, py::array *const data) {
|
||||
data_type_ = data_type;
|
||||
shape_ = shape;
|
||||
switch (data_type) {
|
||||
case kNumberTypeBool:
|
||||
*data = py::array_t<bool, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt8:
|
||||
*data = py::array_t<int8_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt16:
|
||||
*data = py::array_t<int16_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt32:
|
||||
*data = py::array_t<int32_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeInt64:
|
||||
*data = py::array_t<int64_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt8:
|
||||
*data = py::array_t<uint8_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt16:
|
||||
*data = py::array_t<uint16_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt32:
|
||||
*data = py::array_t<uint32_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeUInt64:
|
||||
*data = py::array_t<uint64_t, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat16:
|
||||
*data = py::array_t<float16, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat32:
|
||||
*data = py::array_t<float, py::array::c_style>(shape);
|
||||
break;
|
||||
case kNumberTypeFloat64:
|
||||
*data = py::array_t<double, py::array::c_style>(shape);
|
||||
break;
|
||||
default:
|
||||
MS_LOG(EXCEPTION) << "Cannot construct Tensor because of unsupported data type: " << data_type << ".";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TypePtr Tensor::SetDtype(const TypePtr type_ptr) {
|
||||
MS_EXCEPTION_IF_NULL(type_ptr);
|
||||
(void)set_data_type(type_ptr->type_id());
|
||||
return type_ptr;
|
||||
}
|
||||
|
||||
TypeId Tensor::set_data_type(const TypeId data_type) {
|
||||
if (data_.size() > 0 && data_type_ != data_type) {
|
||||
bool success = convert_data(data_, data_type_, &data_, data_type);
|
||||
if (success) {
|
||||
data_type_ = data_type;
|
||||
} else {
|
||||
MS_LOG(EXCEPTION) << "Convert data from " << data_type_ << " to " << data_type << " failed!";
|
||||
}
|
||||
} else if (data_.size() == 0) {
|
||||
data_type_ = data_type;
|
||||
}
|
||||
|
||||
return data_type_;
|
||||
}
|
||||
|
||||
bool Tensor::is_init() { return init_flag_; }
|
||||
|
||||
void Tensor::set_init_flag(bool flag) { init_flag_ = flag; }
|
||||
|
||||
bool Tensor::convert_data(const py::array &in, const TypeId in_data_type, py::array *const out,
|
||||
const TypeId out_data_type) {
|
||||
if (out == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
if (TypeId::kTypeUnknown == in_data_type || TypeId::kTypeUnknown == out_data_type) {
|
||||
result = false;
|
||||
} else if (in_data_type == out_data_type) {
|
||||
*out = in;
|
||||
} else if (TypeId::kNumberTypeFloat64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float64").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeFloat32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeFloat16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("float16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int64").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeInt8 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("int8").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt8 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint8").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt16 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint16").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt32 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint32").cast<py::array>();
|
||||
} else if (TypeId::kNumberTypeUInt64 == out_data_type) {
|
||||
*out = in.attr("astype").cast<py::function>()("uint64").cast<py::array>();
|
||||
} else {
|
||||
data_type_ = TypeId::kTypeUnknown;
|
||||
MS_LOG(EXCEPTION) << "Cannot convert from " << TypeIdLabel(in_data_type) << " to " << TypeIdLabel(out_data_type)
|
||||
<< ".";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract::AbstractBasePtr Tensor::ToAbstract() {
|
||||
auto tens = shared_from_base<Tensor>();
|
||||
auto dtype = tens->Dtype();
|
||||
if (!IsSubType(dtype, kNumber)) {
|
||||
MS_LOG(EXCEPTION) << "Expect tensor type kNumber but got: " << dtype->ToString() << ".";
|
||||
}
|
||||
auto tensor_shape = tens->shape();
|
||||
auto abs_tensor = std::make_shared<abstract::AbstractTensor>(dtype, tensor_shape);
|
||||
abs_tensor->set_value(shared_from_base<Tensor>());
|
||||
return abs_tensor;
|
||||
}
|
||||
|
||||
std::string Tensor::GetShapeAndDataTypeInfo() const {
|
||||
std::ostringstream buf;
|
||||
buf << "Tensor \nshape:[" << shape() << "]" << this->Dtype()->ToString();
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
std::string Tensor::ToString() const {
|
||||
const int small_tensor_size = 30;
|
||||
std::ostringstream buf;
|
||||
buf << "Tensor \nshape:[" << shape() << "]" << this->Dtype()->ToString();
|
||||
// only print small tensor
|
||||
if (DataSize() < small_tensor_size) {
|
||||
buf << "val:" << std::string(py::str(data()));
|
||||
}
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
std::string Tensor::ToStringRepr() const {
|
||||
std::ostringstream buf;
|
||||
auto type_ptr = this->Dtype();
|
||||
MS_EXCEPTION_IF_NULL(type_ptr);
|
||||
buf << "Tensor shape:[" << shape() << "]" << type_ptr->ToString();
|
||||
buf << "\nval:" << std::string(py::str(data()));
|
||||
return buf.str();
|
||||
}
|
||||
|
||||
py::array Tensor::data_sync() {
|
||||
if (device_address_ != nullptr) {
|
||||
if (!device_address_->SyncDeviceToHost(this->shape(), static_cast<size_t>(this->data().nbytes()), this->data_type(),
|
||||
this->data_c(true))) {
|
||||
MS_LOG(EXCEPTION) << "SyncDeviceToHost when asnumpy.";
|
||||
}
|
||||
}
|
||||
return data_;
|
||||
}
|
||||
|
||||
REGISTER_PYBIND_DEFINE(Tensor, ([](const py::module *m) {
|
||||
// dtype should define before Tensor, because Tensor init depend dtype
|
||||
(void)py::class_<Tensor, std::shared_ptr<Tensor>>(*m, "Tensor")
|
||||
.def(py::init<TypePtr, py::tuple>(), py::arg("dtype"), py::arg("shape"))
|
||||
.def(py::init<py::array, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::float_, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::int_, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::list, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<py::tuple, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def(py::init<Tensor, TypePtr>(), py::arg("input"), py::arg("dtype") = nullptr)
|
||||
.def_readonly(PYTHON_TENSOR_FLAG, &Tensor::parse_info_)
|
||||
.def("asnumpy", &Tensor::data_sync, R"mydelimiter(
|
||||
Convert tensor to numpy.ndarray.
|
||||
|
||||
Returns:
|
||||
numpy.ndarray.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> array = data.asnumpy()
|
||||
>>> array
|
||||
array([[1., 1., 1.],
|
||||
[1., 1., 1.]])
|
||||
)mydelimiter")
|
||||
.def("size", &Tensor::DataSize, R"mydelimiter(
|
||||
Get tensor's data size.
|
||||
|
||||
Returns:
|
||||
int, the size of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.size()
|
||||
6
|
||||
)mydelimiter")
|
||||
.def("is_init", &Tensor::is_init, R"mydelimiter(
|
||||
Get tensor init_flag.
|
||||
|
||||
Returns:
|
||||
bool, whether the tensor init.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.is_init()
|
||||
False
|
||||
)mydelimiter")
|
||||
.def("set_init_flag", &Tensor::set_init_flag, R"mydelimiter(
|
||||
Set tensor init_flag.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.set_init_flag(True)
|
||||
)mydelimiter")
|
||||
.def("dim", &Tensor::DataDim, R"mydelimiter(
|
||||
Get tensor's data dimension.
|
||||
|
||||
Returns:
|
||||
int, the dimension of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 3)))
|
||||
>>> data.dim()
|
||||
2
|
||||
)mydelimiter")
|
||||
.def("dtype", &Tensor::Dtype, R"mydelimiter(
|
||||
Get the tensor's data type.
|
||||
|
||||
Returns:
|
||||
type, the data type of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((2, 1), np.int32))
|
||||
>>> data.dtype()
|
||||
Int32
|
||||
)mydelimiter")
|
||||
.def("set_dtype", &Tensor::SetDtype, R"mydelimiter(
|
||||
Set the tensor's data type.
|
||||
|
||||
Arg:
|
||||
dtype (:class:`mindspore.dtype`): The type of output tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((1, 2), np.float32))
|
||||
>>> data.set_dtype(mindspore.int32)
|
||||
mindspore.int32
|
||||
)mydelimiter")
|
||||
.def("shape", &Tensor::GetPyTupleShape, R"mydelimiter(
|
||||
Get the tensor's shape.
|
||||
|
||||
Returns:
|
||||
tuple[int], the shape of tensor.
|
||||
|
||||
Examples:
|
||||
>>> data = mindspore.Tensor(np.ones((3, 3)))
|
||||
>>> data.shape()
|
||||
(3, 3)
|
||||
)mydelimiter")
|
||||
.def("__str__", &Tensor::ToString)
|
||||
.def("__repr__", &Tensor::ToStringRepr)
|
||||
.def(py::pickle(
|
||||
[](const Tensor &t) { // __getstate__
|
||||
/* Return a tuple that fully encodes the state of the object */
|
||||
return py::make_tuple(t.data());
|
||||
},
|
||||
[](const py::tuple &t) { // __setstate__
|
||||
if (t.size() != 1) {
|
||||
throw std::runtime_error("Invalid state!");
|
||||
}
|
||||
/* Create a new C++ instance */
|
||||
Tensor tensor(t[0].cast<py::array>());
|
||||
return tensor;
|
||||
}));
|
||||
(void)py::class_<MetaTensor, std::shared_ptr<MetaTensor>>(*m, "MetaTensor")
|
||||
.def(py::init<TypePtr, const std::vector<int>>(), py::arg("dtype"), py::arg("shape"))
|
||||
.def_readonly(PYTHON_META_TENSOR_FLAG, &MetaTensor::parse_info_)
|
||||
.def("dtype", &MetaTensor::Dtype, "Get the MetaTensor's dtype.")
|
||||
.def("shape", &MetaTensor::shape, "Get the MetaTensor's shape.");
|
||||
}));
|
||||
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,278 @@
|
|||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_IR_TENSOR_H_
|
||||
#define MINDSPORE_CCSRC_IR_TENSOR_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "pybind11/numpy.h"
|
||||
#include "pybind11/pybind11.h"
|
||||
|
||||
#include "Eigen/Core"
|
||||
#include "device/device_address.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
using float16 = Eigen::half;
|
||||
|
||||
namespace pybind11 {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Similar to enums in `pybind11/numpy.h`. Determined by doing:
|
||||
// python3 -c 'import numpy as np; print(np.dtype(np.float16).num)'
|
||||
constexpr int NPY_FLOAT16 = 23;
|
||||
|
||||
template <typename T>
|
||||
struct npy_scalar_caster {
|
||||
PYBIND11_TYPE_CASTER(T, _("PleaseOverride"));
|
||||
using Array = array_t<T>;
|
||||
|
||||
bool load(handle src, bool convert) {
|
||||
// Taken from Eigen casters. Permits either scalar dtype or scalar array.
|
||||
handle type = dtype::of<T>().attr("type");
|
||||
if (!convert && !isinstance<Array>(src) && !isinstance(src, type)) return false;
|
||||
|
||||
Array tmp = Array::ensure(src);
|
||||
if (tmp && tmp.size() == 1 && tmp.ndim() == 0) {
|
||||
this->value = *tmp.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static handle cast(T src, return_value_policy, handle) {
|
||||
Array tmp({1});
|
||||
tmp.mutable_at(0) = src;
|
||||
tmp.resize({});
|
||||
|
||||
// You could also just return the array if you want a scalar array.
|
||||
object scalar = tmp[tuple()];
|
||||
return scalar.release();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct npy_format_descriptor<float16> {
|
||||
static constexpr auto name = "float16";
|
||||
static pybind11::dtype dtype() {
|
||||
handle ptr = npy_api::get().PyArray_DescrFromType_(NPY_FLOAT16);
|
||||
return reinterpret_borrow<pybind11::dtype>(ptr);
|
||||
}
|
||||
virtual ~npy_format_descriptor<float16>() {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_caster<float16> : public npy_scalar_caster<float16> {
|
||||
static constexpr auto name = "float16";
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace pybind11
|
||||
|
||||
using mindspore::device::DeviceAddress;
|
||||
using DeviceAddressPtr = std::shared_ptr<mindspore::device::DeviceAddress>;
|
||||
// brief mindspore namespace.
|
||||
//
|
||||
// mindspore namespace is the top level namespace of Mindsporeession project.
|
||||
// Other namespace should be a sub namespace of mindspore namespace in the ME project.
|
||||
namespace mindspore {
|
||||
|
||||
// brief mindspore::tensor namespace
|
||||
//
|
||||
// A sub namespace in ME to support tensor related definition.
|
||||
namespace tensor {
|
||||
// Tensor entity class
|
||||
class Tensor : public MetaTensor {
|
||||
public:
|
||||
Tensor() = default;
|
||||
abstract::AbstractBasePtr ToAbstract() override;
|
||||
// brief Constructor for Python.
|
||||
//
|
||||
// param type_ptr [TypePty] Data type of the tensor.
|
||||
// param py_shape [py::tuple] The shape represented by py::tuple of the tensor.
|
||||
Tensor(const TypePtr &type_ptr, const py::tuple &shape);
|
||||
|
||||
// brief Constructor for C++.
|
||||
//
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
// param shape The shape represented by std::vector<int> of the tensor.
|
||||
Tensor(TypeId data_type, const std::vector<int> &shape);
|
||||
|
||||
// brief Constructor for Python.
|
||||
//
|
||||
// param input [py::array] Data value of the tensor.
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
explicit Tensor(const py::array &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::list] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::list &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::tuple] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::tuple &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::float_] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::float_ &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [py::int_] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
explicit Tensor(const py::int_ &input, const TypePtr &data_type = nullptr);
|
||||
|
||||
// brief Constructor
|
||||
//
|
||||
// param input [Tensor] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
Tensor(const Tensor &tensor, const TypePtr &data_type = nullptr);
|
||||
|
||||
~Tensor() override = default;
|
||||
|
||||
MS_DECLARE_PARENT(Tensor, MetaTensor);
|
||||
|
||||
// brief Overloads operator = for Tensor.
|
||||
//
|
||||
// The constructed Tensor object has the same type and shape with tensor.
|
||||
//
|
||||
// param tensor An existing Tensor object.
|
||||
Tensor &operator=(const Tensor &tensor);
|
||||
|
||||
// brief Compares two Tensor objects.
|
||||
//
|
||||
// Compare two tensor objects to see if they have same data type, shape and
|
||||
// data value.
|
||||
//
|
||||
// param tensor The Tensor object to be compared.
|
||||
// return true: If having same type, shape and data, return true, or return false.
|
||||
bool operator==(const Tensor &tensor) const;
|
||||
|
||||
// It is different from 'operator==' which just compare shape/type/address, it do real value comparison.
|
||||
bool ValueEqual(const Tensor &other) const;
|
||||
|
||||
bool operator==(const Value &other) const override {
|
||||
if (other.isa<Tensor>()) {
|
||||
auto other_ = static_cast<const Tensor &>(other);
|
||||
return *this == other_;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
py::tuple GetPyTupleShape() const;
|
||||
|
||||
// brief Gets tensor's dimension
|
||||
//
|
||||
// return The number of dimensions of the tensor data.
|
||||
int DataDim() const;
|
||||
|
||||
// brief Getting tensor data size
|
||||
//
|
||||
// return The total number of elements of the tensor data.
|
||||
int DataSize() const;
|
||||
|
||||
// brief Tensor's data value.
|
||||
//
|
||||
// return [py::array] The tensor's data in py::array.
|
||||
py::array data() const;
|
||||
|
||||
// brief Get the data type fo the tensor for C++
|
||||
//
|
||||
// return [int] The tensor's data type will be cast to int to return.
|
||||
int data_type_c() const;
|
||||
|
||||
// brief Get the tensor's shape for C++
|
||||
//
|
||||
// return [std::vector<int>]
|
||||
std::vector<int> shape_c(void) const;
|
||||
|
||||
// brief Get Tensor data pointer for c++ type
|
||||
//
|
||||
// param writable true if writable, false if read only
|
||||
// return The pointer to the object
|
||||
void *data_c(bool writable = false);
|
||||
|
||||
// brief Get data type from tensor data.
|
||||
//
|
||||
// param buf The buffer info of the py::array data.
|
||||
// return The [TypeId] of the tensor data.
|
||||
TypeId GetDataType(const py::buffer_info &buf) const;
|
||||
|
||||
// brief Sets the data type of a tensor.
|
||||
//
|
||||
// param data_type The data type of the tensor to be set.
|
||||
//
|
||||
TypeId set_data_type(const TypeId data_type) override;
|
||||
TypePtr SetDtype(const TypePtr type_ptr) override;
|
||||
std::string GetShapeAndDataTypeInfo() const;
|
||||
std::string ToString() const override;
|
||||
std::string ToStringRepr() const;
|
||||
py::array data_; // < Tensor's data value
|
||||
const bool parse_info_ = true;
|
||||
bool is_init();
|
||||
void set_init_flag(bool flag);
|
||||
|
||||
private:
|
||||
// brief init tensor
|
||||
//
|
||||
// param input [py::array] the data for tensor
|
||||
// param data_type [TypeId] data type
|
||||
// return true if succeed, false if failed.
|
||||
void init(const py::array &input, const TypeId &data_type);
|
||||
void init(const py::array &input, const TypePtr &type_ptr);
|
||||
bool init_flag_{false};
|
||||
// brief init tensor attribute
|
||||
//
|
||||
// param data_type [TypeId] Data type of the tensor.
|
||||
// param shape [py::array] The shape of the tensor.
|
||||
// return true if succeed, false if failed.
|
||||
void init(TypeId data_type, const std::vector<int> &shape, py::array *data);
|
||||
|
||||
bool convert_data(const py::array &in, const TypeId in_data_type, py::array *out, const TypeId out_data_type);
|
||||
|
||||
public:
|
||||
bool is_dirty() const { return dirty_; }
|
||||
void set_dirty(const bool dirty) { dirty_ = dirty; }
|
||||
DeviceAddressPtr device_address() const { return device_address_; }
|
||||
void set_device_address(const DeviceAddressPtr &device_address) { device_address_ = device_address; }
|
||||
py::array data_sync();
|
||||
|
||||
private:
|
||||
bool dirty_{true};
|
||||
DeviceAddressPtr device_address_{nullptr};
|
||||
};
|
||||
|
||||
using TensorPtr = std::shared_ptr<Tensor>;
|
||||
using TensorPtrList = std::vector<std::shared_ptr<Tensor>>;
|
||||
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_IR_TENSOR_H_
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include "ir/anf.h"
|
||||
#include "ir/dtype.h"
|
||||
#include "utils/utils.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "pipeline/static_analysis/dshape.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_IR_PARAM_VALUE_MINNIE_H_
|
||||
#define MINDSPORE_CCSRC_IR_PARAM_VALUE_MINNIE_H_
|
||||
#ifndef MINDSPORE_CCSRC_MINNIE_PARAM_VALUE_MINNIE_H_
|
||||
#define MINDSPORE_CCSRC_MINNIE_PARAM_VALUE_MINNIE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -39,5 +39,6 @@ class ParamValueMinnie : public ParamValue {
|
|||
};
|
||||
|
||||
using ParamValueMinniePtr = std::shared_ptr<ParamValueMinnie>;
|
||||
|
||||
} // namespace mindspore
|
||||
#endif // MINDSPORE_CCSRC_IR_PARAM_VALUE_MINNIE_H_
|
||||
#endif // MINDSPORE_CCSRC_MINNIE_PARAM_VALUE_MINNIE_H_
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* Copyright 2020 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 "minnie/tensor_minnie.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace tensor {
|
||||
TensorMinnie &TensorMinnie::operator=(const TensorMinnie &tensor) {
|
||||
if (&tensor == this) {
|
||||
return *this;
|
||||
}
|
||||
this->tensor_addr_ = tensor.tensor_addr();
|
||||
this->tensor_size_ = tensor.tensor_size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TensorMinnie::operator==(const TensorMinnie &tensor) {
|
||||
return tensor_addr_ == tensor.tensor_addr() && tensor_size_ == tensor.tensor_size();
|
||||
}
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Copyright 2020 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_CCSRC_MINNIE_TENSOR_MINNIE_H_
|
||||
#define MINDSPORE_CCSRC_MINNIE_TENSOR_MINNIE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace tensor {
|
||||
// definition of Tensor Minnie
|
||||
class TensorMinnie : public MetaTensor {
|
||||
public:
|
||||
TensorMinnie() : MetaTensor() {}
|
||||
~TensorMinnie() override = default;
|
||||
MS_DECLARE_PARENT(TensorMinnie, MetaTensor)
|
||||
|
||||
// brief Overloads operator = for TensorMinnie.
|
||||
//
|
||||
// The constructed TensorMinnie object has the same type and shape with tensor_base.
|
||||
//
|
||||
// param meta_tensor An existing TensorMinnie object.
|
||||
virtual TensorMinnie &operator=(const TensorMinnie &tensor);
|
||||
|
||||
// brief Compares two TensorMinnie objects.
|
||||
//
|
||||
// The constructed TensorMinnie object has the same type and shape with tensor_base.
|
||||
//
|
||||
// param meta_tensor The TensorMinnie object to be compared.
|
||||
// return true: If having same type and shape, return true, or return false.
|
||||
virtual bool operator==(const TensorMinnie &tensor);
|
||||
|
||||
// brief Get the tensor's size for C++
|
||||
//
|
||||
// return size_t
|
||||
size_t tensor_size() const { return tensor_size_; }
|
||||
|
||||
// brief Set Tensor data size for c++ type
|
||||
void set_tensor_size(size_t size) { tensor_size_ = size; }
|
||||
|
||||
// brief Get Tensor data pointer for c++ type
|
||||
//
|
||||
// return The pointer to the object
|
||||
void *tensor_addr() const { return tensor_addr_; }
|
||||
|
||||
// brief Set Tensor data pointer for c++ type
|
||||
void set_tensor_addr(void *addr) { tensor_addr_ = addr; }
|
||||
|
||||
protected:
|
||||
// brief Data addr of the tensor.
|
||||
void *tensor_addr_;
|
||||
|
||||
// brief Data size of the tensor.
|
||||
size_t tensor_size_;
|
||||
};
|
||||
|
||||
using TensorMinniePtr = std::shared_ptr<TensorMinnie>;
|
||||
|
||||
} // namespace tensor
|
||||
} // namespace mindspore
|
||||
|
||||
#endif // MINDSPORE_CCSRC_MINNIE_TENSOR_MINNIE_H_
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -17,8 +17,6 @@
|
|||
#include "operator/ops.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "pipeline/parse/python_adapter.h"
|
||||
#include "pipeline/parse/data_converter.h"
|
||||
|
||||
namespace mindspore {
|
||||
// namespace to support primitive operators
|
||||
|
@ -255,15 +253,5 @@ const PrimitivePtr kPrimScalarSummary = std::make_shared<Primitive>("ScalarSumma
|
|||
const PrimitivePtr kPrimImageSummary = std::make_shared<Primitive>("ImageSummary");
|
||||
const PrimitivePtr kPrimTensorSummary = std::make_shared<Primitive>("TensorSummary");
|
||||
const PrimitivePtr kPrimHistogramSummary = std::make_shared<Primitive>("HistogramSummary");
|
||||
|
||||
ValuePtr GetPythonOps(const std::string &op_name, const std::string &module_name) {
|
||||
py::object obj = parse::python_adapter::GetPyFn(module_name, op_name);
|
||||
ValuePtr node = nullptr;
|
||||
bool succ = parse::ConvertData(obj, &node);
|
||||
if (!succ) {
|
||||
MS_LOG(EXCEPTION) << "get Python op " << op_name << " from " << module_name << " fail";
|
||||
}
|
||||
return node;
|
||||
}
|
||||
} // namespace prim
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -21,7 +21,7 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
#include "ir/anf.h"
|
||||
#include "ir/primitive.h"
|
||||
#include "ir/primitive_base.h"
|
||||
|
||||
namespace mindspore {
|
||||
// namespace to support primitive operators
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* Copyright 2020 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 "operator/ops.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "pipeline/parse/python_adapter.h"
|
||||
#include "pipeline/parse/data_converter.h"
|
||||
|
||||
namespace mindspore {
|
||||
// namespace to support primitive operators
|
||||
namespace prim {
|
||||
ValuePtr GetPythonOps(const std::string &op_name, const std::string &module_name) {
|
||||
py::object obj = parse::python_adapter::GetPyFn(module_name, op_name);
|
||||
ValuePtr node = nullptr;
|
||||
bool succ = parse::ConvertData(obj, &node);
|
||||
if (!succ) {
|
||||
MS_LOG(EXCEPTION) << "get Python op " << op_name << " from " << module_name << " fail";
|
||||
}
|
||||
return node;
|
||||
}
|
||||
} // namespace prim
|
||||
} // namespace mindspore
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -29,6 +29,7 @@
|
|||
#include "ir/anf.h"
|
||||
#include "ir/func_graph.h"
|
||||
#include "debug/info.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace parallel {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "common/utils.h"
|
||||
#include "ir/func_graph.h"
|
||||
#include "parallel/ops_info/operator_info.h"
|
||||
#include "parallel/graph_util/graph_info.h"
|
||||
#include "parallel/strategy.h"
|
||||
#include "parallel/tensor_layout/tensor_layout.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/value.h"
|
||||
#include "parallel/auto_parallel/costmodel.h"
|
||||
#include "parallel/device_matrix.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -25,7 +25,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include "ir/dtype.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/value.h"
|
||||
#include "parallel/auto_parallel/edge_costmodel.h"
|
||||
#include "parallel/auto_parallel/graph_costmodel.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/value.h"
|
||||
#include "parallel/auto_parallel/operator_costmodel.h"
|
||||
#include "parallel/ops_info/activation_info.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "ir/anf.h"
|
||||
#include "ir/param_value_py.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "optimizer/opt.h"
|
||||
#include "optimizer/optimizer.h"
|
||||
#include "parallel/auto_parallel/dp_algo_costmodel.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -27,7 +27,7 @@
|
|||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/param_value_py.h"
|
||||
#include "operator/ops.h"
|
||||
#include "optimizer/optimizer.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "ir/manager.h"
|
||||
#include "pipeline/parse/python_adapter.h"
|
||||
#include "pipeline/parse/parse_base.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
||||
// forward declaration of ResourceBase
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -26,7 +26,7 @@
|
|||
#include <mutex>
|
||||
#include "debug/draw.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "pipeline/action.h"
|
||||
#include "vm/segment_runner.h"
|
||||
#include "vm/transform.h"
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "transform/convert.h"
|
||||
#include "transform/df_graph_manager.h"
|
||||
#include "transform/graph_builder.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "pipeline/remove_value_node_dup.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "optimizer/cse.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include "ir/base.h"
|
||||
#include "ir/dtype.h"
|
||||
#include "ir/value.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "pipeline/static_analysis/dshape.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -34,7 +34,7 @@
|
|||
#include "./common.h"
|
||||
#include "pipeline/resource.h"
|
||||
#include "pipeline/parse/resolve.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "utils/convert_utils.h"
|
||||
#include "pipeline/parse/data_converter.h"
|
||||
#include "pipeline/static_analysis/param_validator.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -25,7 +25,7 @@
|
|||
#include "pipeline/static_analysis/prim.h"
|
||||
#include "operator/ops.h"
|
||||
#include "utils/symbolic.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/func_graph_cloner.h"
|
||||
#include "./common.h"
|
||||
#include "pipeline/parse/data_converter.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
#include "pre_activate/common/pass_manager.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unordered_set>
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "predict/schema/inner/ms_generated.h"
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -21,7 +21,7 @@
|
|||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace executor {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -20,7 +20,7 @@
|
|||
#include <set>
|
||||
#include <list>
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/anf.h"
|
||||
#include "common/trans.h"
|
||||
#include "device/kernel_runtime.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "session/cpu_session.h"
|
||||
#include <algorithm>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/anf.h"
|
||||
#include "kernel/kernel.h"
|
||||
#include "common/utils.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -25,7 +25,7 @@
|
|||
#include "session/session_context.h"
|
||||
#include "session/kernel_graph.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "utils/any.h"
|
||||
#include "utils/base_ref.h"
|
||||
#include "utils/contract.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -22,7 +22,7 @@
|
|||
#include <utility>
|
||||
#include <string>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "pipeline/resource.h"
|
||||
#include "utils/context/ms_context.h"
|
||||
namespace mindspore {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -32,7 +32,7 @@
|
|||
#include "ir/anf.h"
|
||||
#include "ir/func_graph.h"
|
||||
#include "transform/util.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "transform/df_graph_manager.h"
|
||||
#include "utils/config_manager.h"
|
||||
#include "transform/op_declare.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "transform/types.h"
|
||||
#include "transform/util.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "transform/df_graph_manager.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include <unordered_map>
|
||||
#include "ir/anf.h"
|
||||
#include "ir/dtype.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
#include "graph/tensor.h"
|
||||
#ifdef OPEN_SOURCE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -24,7 +24,7 @@
|
|||
#include "securec/include/securec.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/dtype.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "transform/types.h"
|
||||
|
||||
#include "graph/tensor.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -20,7 +20,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace callbacks {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <memory>
|
||||
#include "transform/types.h"
|
||||
#include "transform/util.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace callbacks {
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#ifdef ENABLE_GE
|
||||
#include "transform/df_graph_manager.h"
|
||||
#endif
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
#ifdef ENABLE_GE
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "pybind11/pybind11.h"
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "pipeline/parse/parse.h"
|
||||
#include "pipeline/parse/parse_base.h"
|
||||
#include "ir/value.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -31,7 +31,7 @@
|
|||
#include "ir/anf.h"
|
||||
#include "ir/primitive.h"
|
||||
#include "ir/scalar.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/label.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "ir/anf.h"
|
||||
#include "pipeline/static_analysis/abstract_value.h"
|
||||
#include "utils/any.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "device/convert_tensor_utils.h"
|
||||
#include "./securec.h"
|
||||
#ifndef NO_DLIB
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -26,10 +26,11 @@
|
|||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/manager.h"
|
||||
#include "ir/func_graph_cloner.h"
|
||||
#include "ir/primitive.h"
|
||||
#include "utils/convert_utils.h"
|
||||
#include "utils/primitive_utils.h"
|
||||
#include "debug/draw.h"
|
||||
|
@ -37,8 +38,6 @@
|
|||
namespace mindspore {
|
||||
namespace compile {
|
||||
|
||||
using PrimitivePyPtr = std::shared_ptr<PrimitivePy>;
|
||||
|
||||
// Indicate a call to a new frame.
|
||||
struct CallWrap : public Base {
|
||||
explicit CallWrap(const VMFramePtr &vm_frame) : frame(vm_frame) {}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* This is the C++ adaptation and derivative work of Myia (https://github.com/mila-iqia/myia/).
|
||||
*
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "ir/anf.h"
|
||||
#include "ir/manager.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "utils/base_ref.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
|
||||
#include "securec/include/securec.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace tensor {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "common/common_test.h"
|
||||
#include "ir/value.h"
|
||||
#include "ir/primitive.h"
|
||||
#include "operator/ops.h"
|
||||
#include "./common.h"
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "pipeline/static_analysis/helper.h"
|
||||
#include "operator/ops.h"
|
||||
#include "debug/draw.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "utils/symbolic.h"
|
||||
#include "./common.h"
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "common/common_test.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "ir/manager.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "operator/ops.h"
|
||||
#include "pipeline/parse/parse.h"
|
||||
#include "pipeline/parse/data_converter.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -21,7 +21,7 @@
|
|||
#include "pipeline/resource.h"
|
||||
#include "pipeline/action.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include "common/backend_common_test.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -19,7 +19,7 @@
|
|||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "pipeline/resource.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "utils/utils.h"
|
||||
#include "kernel/kernel_build_info.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -16,7 +16,7 @@
|
|||
#include "common/backend_common_test.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include "common/backend_common_test.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include "common/backend_common_test.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include "common/backend_common_test.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
#include "common/backend_common_test.h"
|
||||
#include "ir/anf.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
#include "session/anf_runtime_algorithm.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2019 Huawei Technologies Co., Ltd
|
||||
* Copyright 2019-2020 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.
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include "common/backend_common_test.h"
|
||||
#include "kernel/kernel.h"
|
||||
#include "operator/ops.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "ir/manager.h"
|
||||
#include "debug/anf_ir_dump.h"
|
||||
#include "common/py_func_graph_fetcher.h"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
#include "transform/util.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
|
||||
#include "common/common_test.h"
|
||||
#include "pipeline/parse/parse.h"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "operator/ops.h"
|
||||
#include "vm/segment_runner.h"
|
||||
#include "vm/transform.h"
|
||||
#include "ir/meta_tensor.h"
|
||||
#include "ir/tensor.h"
|
||||
#include "utils/convert_utils.h"
|
||||
#include "utils/log_adapter.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue