add tensor_minnie and separate py from ir

This commit is contained in:
leopz 2020-05-28 10:59:57 +08:00
parent 14f9a6e31c
commit 4508134ceb
80 changed files with 1538 additions and 1250 deletions

View File

@ -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"

View File

@ -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>";

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

278
mindspore/ccsrc/ir/tensor.h Normal file
View File

@ -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_

View File

@ -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"

View File

@ -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_

View File

@ -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

View File

@ -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_

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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>

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 {

View File

@ -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"

View File

@ -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 {

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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"

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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) {}

View File

@ -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 {

View File

@ -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 {

View File

@ -19,6 +19,7 @@
#include "common/common_test.h"
#include "ir/value.h"
#include "ir/primitive.h"
#include "operator/ops.h"
#include "./common.h"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"