未验证 提交 69a92b7b 编写于 作者: Z zyfncg 提交者: GitHub

[cherry-pick] Optimize performance of dygraph (#42231, #42253) (#42309)

* Optimize the performanece of sum api (#42231)

* optimize the performanece of sum api

* optimize IsDenseTensorInput

* remove debug log

* Add move construct for KernelSignature (#42253)

* add move construct for KernelSignature

* add noexcept

* fix cherry-pick problem
上级 9e1aa116
......@@ -70,6 +70,11 @@ class InferShapeArgumentMappingContext : public phi::ArgumentMappingContext {
}
bool IsDenseTensorInput(const std::string& name) const override {
auto var_type = ctx_.GetInputVarType(name);
return var_type == proto::VarType::LOD_TENSOR;
}
bool IsDenseTensorInputs(const std::string& name) const override {
auto var_types = ctx_.GetInputsVarType(name);
return std::all_of(var_types.begin(), var_types.end(),
[](const proto::VarType::Type& type) {
......@@ -78,11 +83,8 @@ class InferShapeArgumentMappingContext : public phi::ArgumentMappingContext {
}
bool IsSelectedRowsInput(const std::string& name) const override {
auto var_types = ctx_.GetInputsVarType(name);
return std::all_of(var_types.begin(), var_types.end(),
[](const proto::VarType::Type& type) {
return type == proto::VarType::SELECTED_ROWS;
});
auto var_type = ctx_.GetInputVarType(name);
return var_type == proto::VarType::SELECTED_ROWS;
}
bool IsDenseTensorVectorInput(const std::string& name) const override {
......
......@@ -365,6 +365,11 @@ std::vector<DDim> InterpretercoreInferShapeContext::GetInputsDim(
return GetDims(vars);
}
proto::VarType::Type InterpretercoreInferShapeContext::GetInputVarType(
const std::string& name) const {
return GetVarType(InputVars(name).at(0));
}
std::vector<proto::VarType::Type>
InterpretercoreInferShapeContext::GetInputsVarType(
const std::string& name) const {
......
......@@ -100,6 +100,8 @@ class InterpretercoreInferShapeContext : public InferShapeContext {
std::vector<DDim> GetInputsDim(const std::string& name) const override;
proto::VarType::Type GetInputVarType(const std::string& name) const override;
std::vector<proto::VarType::Type> GetInputsVarType(
const std::string& name) const override;
......
......@@ -245,6 +245,10 @@ class CompileTimeInferShapeContext : public InferShapeContext {
bool IsRunMKLDNNKernel() const override;
proto::VarType::Type GetInputVarType(const std::string &name) const override {
return GetVarType(Inputs(name).at(0));
}
std::vector<proto::VarType::Type> GetInputsVarType(
const std::string &name) const override {
return GetVarTypes(Inputs(name));
......
......@@ -981,6 +981,10 @@ class RuntimeInferShapeContext : public InferShapeContext {
return GetDims(vars);
}
proto::VarType::Type GetInputVarType(const std::string& name) const override {
return GetVarType(InputVars(name).at(0));
}
std::vector<proto::VarType::Type> GetInputsVarType(
const std::string& name) const override {
return GetVarTypes(InputVars(name));
......
......@@ -479,6 +479,11 @@ class ExecutionArgumentMappingContext : public phi::ArgumentMappingContext {
}
bool IsDenseTensorInput(const std::string& name) const override {
const auto* var = ctx_.InputVar(name);
return var->IsType<phi::DenseTensor>();
}
bool IsDenseTensorInputs(const std::string& name) const override {
auto vars = ctx_.MultiInputVar(name);
return std::all_of(vars.begin(), vars.end(), [](const Variable* var) {
return var->IsType<phi::DenseTensor>();
......@@ -486,10 +491,8 @@ class ExecutionArgumentMappingContext : public phi::ArgumentMappingContext {
}
bool IsSelectedRowsInput(const std::string& name) const override {
auto vars = ctx_.MultiInputVar(name);
return std::all_of(vars.begin(), vars.end(), [](const Variable* var) {
const auto* var = ctx_.InputVar(name);
return var->IsType<phi::SelectedRows>();
});
}
bool IsDenseTensorVectorInput(const std::string& name) const override {
......
......@@ -65,6 +65,8 @@ class InferShapeContext {
virtual bool HasOutput(const std::string &name) const = 0;
virtual bool HasAttr(const std::string &name) const = 0;
virtual proto::VarType::Type GetInputVarType(
const std::string &name) const = 0;
virtual std::vector<proto::VarType::Type> GetInputsVarType(
const std::string &name) const = 0;
virtual std::vector<proto::VarType::Type> GetOutputsVarType(
......
......@@ -300,6 +300,15 @@ class DygraphInferShapeContext : public framework::InferShapeContext {
return vec_res;
}
framework::proto::VarType::Type GetInputVarType(
const std::string& name) const override {
auto it = var_map_in_->find(name);
PADDLE_ENFORCE_NE(
it, var_map_in_->end(),
platform::errors::NotFound("can not find [%s] in input", name));
return framework::ToVarType(it->second[0]->Var().Type());
}
std::vector<framework::proto::VarType::Type> GetInputsVarType(
const std::string& name) const override {
std::vector<framework::proto::VarType::Type> vec_res;
......
......@@ -89,6 +89,12 @@ class ReduceSumVarTypeInference : public paddle::framework::VarTypeInference {
BOOST_GET_CONST(int, ctx->GetAttr("out_dtype")));
if (data_type >= 0) {
ctx->SetOutputDataType("Out", data_type);
} else {
auto x_type = ctx->GetInputDataType("X");
if (x_type == framework::proto::VarType::BOOL ||
x_type == framework::proto::VarType::INT32) {
ctx->SetOutputDataType("Out", framework::proto::VarType::INT64);
}
}
}
};
......
......@@ -1204,11 +1204,7 @@ paddle::experimental::DataType CastPyArg2DataType(PyObject* obj,
const std::string& op_type,
ssize_t arg_pos) {
if (obj == Py_None) {
PADDLE_THROW(platform::errors::InvalidArgument(
"%s(): argument (position %d) must be "
"data_type, but got %s",
op_type, arg_pos + 1,
((PyTypeObject*)obj->ob_type)->tp_name)); // NOLINT
return paddle::experimental::DataType::UNDEFINED;
}
framework::proto::VarType::Type type = CastPyArg2ProtoType(obj, arg_pos);
......
......@@ -63,6 +63,12 @@ bool ProtoArgumentMappingContext::IsDenseTensorInput(
const std::string& name) const {
return true;
}
bool ProtoArgumentMappingContext::IsDenseTensorInputs(
const std::string& name) const {
return true;
}
bool ProtoArgumentMappingContext::IsSelectedRowsInput(
const std::string& name) const {
return false;
......
......@@ -41,6 +41,7 @@ class ProtoArgumentMappingContext : public ::phi::ArgumentMappingContext {
size_t OutputSize(const std::string& name) const override;
bool IsDenseTensorInput(const std::string& name) const override;
bool IsDenseTensorInputs(const std::string& name) const override;
bool IsSelectedRowsInput(const std::string& name) const override;
bool IsDenseTensorVectorInput(const std::string& name) const override;
......
......@@ -58,6 +58,18 @@ struct KernelSignature {
// TODO(chenweihang): add assign constructor to solve windows compile
// problem, remove it later
KernelSignature(const KernelSignature& other)
: name(other.name),
input_names(other.input_names),
attr_names(other.attr_names),
output_names(other.output_names) {}
KernelSignature(KernelSignature&& other) noexcept
: name(other.name),
input_names(std::move(other.input_names)),
attr_names(std::move(other.attr_names)),
output_names(std::move(other.output_names)) {}
KernelSignature& operator=(const KernelSignature& other) {
name = other.name;
input_names = other.input_names;
......@@ -65,6 +77,14 @@ struct KernelSignature {
output_names = other.output_names;
return *this;
}
KernelSignature& operator=(KernelSignature&& other) noexcept {
name = other.name;
input_names.swap(other.input_names);
attr_names.swap(other.attr_names);
output_names.swap(other.output_names);
return *this;
}
};
std::ostream& operator<<(std::ostream& os, KernelSignature signature);
......@@ -86,6 +106,7 @@ class ArgumentMappingContext {
virtual size_t OutputSize(const std::string& name) const = 0;
virtual bool IsDenseTensorInput(const std::string& name) const = 0;
virtual bool IsDenseTensorInputs(const std::string& name) const = 0;
virtual bool IsSelectedRowsInput(const std::string& name) const = 0;
// For compatibility with LoDTensorArray
virtual bool IsDenseTensorVectorInput(const std::string& name) const = 0;
......
......@@ -2254,8 +2254,7 @@ void SumRawInferMeta(const MetaTensor& x,
if (dtype != DataType::UNDEFINED) {
out_dtype = dtype;
} else {
if (x.dtype() == DataType::BOOL || x.dtype() == DataType::INT32 ||
x.dtype() == DataType::INT64) {
if (x.dtype() == DataType::BOOL || x.dtype() == DataType::INT32) {
out_dtype = DataType::INT64;
} else {
out_dtype = x.dtype();
......
......@@ -29,6 +29,9 @@ void SumRawKernel(const Context& dev_ctx,
bool reduce_all,
DataType out_dtype,
DenseTensor* out) {
if (out_dtype == DataType::UNDEFINED && out->dtype() != x.dtype()) {
out_dtype = out->dtype();
}
phi::Reduce<CPUContext, T, phi::funcs::SumFunctor>(
dev_ctx, x, reduce_all, dims, keep_dim, out_dtype, out);
}
......
......@@ -27,6 +27,9 @@ void SumRawKernel(const Context& dev_ctx,
bool reduce_all,
DataType out_dtype,
DenseTensor* out) {
if (out_dtype == DataType::UNDEFINED && out->dtype() != x.dtype()) {
out_dtype = out->dtype();
}
phi::Reduce<T, kps::AddFunctor, kps::IdentityFunctor>(
dev_ctx, x, reduce_all, dims, keep_dim, out_dtype, out);
}
......
......@@ -18,7 +18,7 @@
namespace phi {
KernelSignature SumOpArgumentMapping(const ArgumentMappingContext& ctx) {
if (ctx.IsDenseTensorInput("X")) {
if (ctx.IsDenseTensorInputs("X")) {
return KernelSignature("add_n", {"X"}, {}, {"Out"});
}
return KernelSignature("unregistered", {}, {}, {});
......
......@@ -68,6 +68,10 @@ class TestArgumentMappingContext : public phi::ArgumentMappingContext {
return dense_tensor_inputs.count(name) > 0;
}
bool IsDenseTensorInputs(const std::string& name) const override {
return dense_tensor_inputs.count(name) > 0;
}
bool IsSelectedRowsInput(const std::string& name) const override {
return selected_rows_inputs.count(name) > 0;
}
......
......@@ -899,15 +899,10 @@ def sum(x, axis=None, dtype=None, keepdim=False, name=None):
else:
reduce_all_flag = False
def get_dtype(x, dtype):
dtype_flag = False
if dtype is not None:
return (True, dtype)
src_type = convert_dtype(x.dtype)
if src_type in ['bool','int32', 'int64']:
return (True, 'int64')
return (False, src_type)
dtype_flag, dtype = get_dtype(x, dtype)
dtype_flag = True
dtype = convert_np_dtype_to_dtype_(dtype)
if in_dygraph_mode():
if reduce_all_flag:
......@@ -915,17 +910,14 @@ def sum(x, axis=None, dtype=None, keepdim=False, name=None):
else:
axis = axis if axis != None and axis != [] else [0]
out_dtype = convert_np_dtype_to_dtype_(dtype)
out = _C_ops.final_state_sum(x, axis, out_dtype, keepdim)
return out
return _C_ops.final_state_sum(x, axis, dtype, keepdim)
if _in_legacy_dygraph():
axis = axis if axis != None and axis != [] else [0]
if dtype_flag:
return _C_ops.reduce_sum(x, 'dim', axis, 'keep_dim', keepdim,
'reduce_all', reduce_all_flag, 'in_dtype',
x.dtype, 'out_dtype',
convert_np_dtype_to_dtype_(dtype))
x.dtype, 'out_dtype', dtype)
else:
return _C_ops.reduce_sum(x, 'dim', axis, 'keep_dim', keepdim,
'reduce_all', reduce_all_flag)
......@@ -939,7 +931,7 @@ def sum(x, axis=None, dtype=None, keepdim=False, name=None):
if dtype_flag:
attrs.update({
'in_dtype': x.dtype,
'out_dtype': convert_np_dtype_to_dtype_(dtype)
'out_dtype': dtype
})
check_variable_and_dtype(
......@@ -953,7 +945,7 @@ def sum(x, axis=None, dtype=None, keepdim=False, name=None):
helper = LayerHelper('sum', **locals())
if dtype_flag:
out = helper.create_variable_for_type_inference(
dtype=convert_np_dtype_to_dtype_(dtype))
dtype=dtype)
else:
out = helper.create_variable_for_type_inference(dtype=x.dtype)
helper.append_op(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册