提交 2c836ff9 编写于 作者: S sneaxiy

check default grad maker

test=develop
上级 ed61d67c
...@@ -16,6 +16,7 @@ limitations under the License. */ ...@@ -16,6 +16,7 @@ limitations under the License. */
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
...@@ -183,6 +184,10 @@ struct OpInfoFiller<T, kGradOpDescMaker> { ...@@ -183,6 +184,10 @@ struct OpInfoFiller<T, kGradOpDescMaker> {
T maker(fwd_op, no_grad_set, grad_to_var, grad_block); T maker(fwd_op, no_grad_set, grad_to_var, grad_block);
return maker(); return maker();
}; };
info->use_default_grad_op_desc_maker_ =
std::is_base_of<DefaultGradOpDescMaker<true>, T>::value ||
std::is_base_of<DefaultGradOpDescMaker<false>, T>::value;
} }
}; };
......
...@@ -147,7 +147,7 @@ class SingleGradOpDescMaker : public GradOpDescMakerBase { ...@@ -147,7 +147,7 @@ class SingleGradOpDescMaker : public GradOpDescMakerBase {
public: public:
using GradOpDescMakerBase::GradOpDescMakerBase; using GradOpDescMakerBase::GradOpDescMakerBase;
std::vector<std::unique_ptr<OpDesc>> operator()() const { std::vector<std::unique_ptr<OpDesc>> operator()() const final {
std::vector<std::unique_ptr<OpDesc>> retv; std::vector<std::unique_ptr<OpDesc>> retv;
retv.emplace_back(this->Apply()); retv.emplace_back(this->Apply());
return retv; return retv;
...@@ -158,14 +158,14 @@ class SingleGradOpDescMaker : public GradOpDescMakerBase { ...@@ -158,14 +158,14 @@ class SingleGradOpDescMaker : public GradOpDescMakerBase {
}; };
template <bool DropEmptyIG = true> template <bool DropEmptyIG = true>
class DefaultGradOpDescMaker : public SingleGradOpDescMaker { class DefaultGradOpDescMaker final : public SingleGradOpDescMaker {
public: public:
using SingleGradOpDescMaker::SingleGradOpDescMaker; using SingleGradOpDescMaker::SingleGradOpDescMaker;
protected: protected:
virtual std::unique_ptr<OpDesc> Apply() const { std::unique_ptr<OpDesc> Apply() const final {
auto* grad = new OpDesc(); auto* grad = new OpDesc();
grad->SetType(this->GradOpType()); grad->SetType(this->ForwardOpType() + "_grad");
for (auto& input_param : this->InputNames()) { for (auto& input_param : this->InputNames()) {
grad->SetInput(input_param, this->Input(input_param)); grad->SetInput(input_param, this->Input(input_param));
...@@ -182,18 +182,12 @@ class DefaultGradOpDescMaker : public SingleGradOpDescMaker { ...@@ -182,18 +182,12 @@ class DefaultGradOpDescMaker : public SingleGradOpDescMaker {
return std::unique_ptr<OpDesc>(grad); return std::unique_ptr<OpDesc>(grad);
} }
virtual std::string GradOpType() const {
return this->ForwardOpType() + "_grad";
}
}; };
class EmptyGradOpMaker : public GradOpDescMakerBase { class EmptyGradOpMaker final : public GradOpDescMakerBase {
public: public:
using GradOpDescMakerBase::GradOpDescMakerBase; using GradOpDescMakerBase::GradOpDescMakerBase;
std::vector<std::unique_ptr<OpDesc>> operator()() const override { std::vector<std::unique_ptr<OpDesc>> operator()() const final { return {}; }
return {};
}
}; };
} // namespace framework } // namespace framework
......
...@@ -13,6 +13,9 @@ See the License for the specific language governing permissions and ...@@ -13,6 +13,9 @@ See the License for the specific language governing permissions and
limitations under the License. */ limitations under the License. */
#include "paddle/fluid/framework/op_info.h" #include "paddle/fluid/framework/op_info.h"
#include <set>
#include <string>
#include <vector>
namespace paddle { namespace paddle {
namespace framework { namespace framework {
...@@ -24,5 +27,17 @@ OpInfoMap& OpInfoMap::Instance() { ...@@ -24,5 +27,17 @@ OpInfoMap& OpInfoMap::Instance() {
static OpInfoMap g_op_info_map; static OpInfoMap g_op_info_map;
return g_op_info_map; return g_op_info_map;
} }
std::vector<std::string> OpInfoMap::GetUseDefaultGradOpDescMakerOps() const {
// Use set to sort op names
std::set<std::string> result_ops;
for (auto& pair : map_) {
if (pair.second.use_default_grad_op_desc_maker_) {
result_ops.insert(pair.first);
}
}
return std::vector<std::string>(result_ops.begin(), result_ops.end());
}
} // namespace framework } // namespace framework
} // namespace paddle } // namespace paddle
...@@ -17,6 +17,7 @@ limitations under the License. */ ...@@ -17,6 +17,7 @@ limitations under the License. */
#include <map> #include <map>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "paddle/fluid/framework/attribute.h" #include "paddle/fluid/framework/attribute.h"
#include "paddle/fluid/framework/no_need_buffer_vars_inference.h" #include "paddle/fluid/framework/no_need_buffer_vars_inference.h"
...@@ -42,6 +43,10 @@ struct OpInfo { ...@@ -42,6 +43,10 @@ struct OpInfo {
InferInplaceOpFN infer_inplace_; InferInplaceOpFN infer_inplace_;
InferNoNeedBufferVarsFN infer_no_need_buffer_vars_; InferNoNeedBufferVarsFN infer_no_need_buffer_vars_;
// NOTE(zjl): this flag is added to check whether
// the grad maker is the default one.
bool use_default_grad_op_desc_maker_{false};
bool HasOpProtoAndChecker() const { bool HasOpProtoAndChecker() const {
return proto_ != nullptr && checker_ != nullptr; return proto_ != nullptr && checker_ != nullptr;
} }
...@@ -105,6 +110,8 @@ class OpInfoMap { ...@@ -105,6 +110,8 @@ class OpInfoMap {
std::unordered_map<std::string, OpInfo>* mutable_map() { return &map_; } std::unordered_map<std::string, OpInfo>* mutable_map() { return &map_; }
std::vector<std::string> GetUseDefaultGradOpDescMakerOps() const;
private: private:
OpInfoMap() = default; OpInfoMap() = default;
std::unordered_map<std::string, OpInfo> map_; std::unordered_map<std::string, OpInfo> map_;
......
abs
acos
asin
atan
attention_lstm
bilinear_interp
bilinear_tensor_product
bpr_loss
brelu
conv_shift
cos
cos_sim
dequantize
elementwise_div
elementwise_max
elementwise_min
elu
fc
flatten
fsp
fused_embedding_fc_lstm
fused_embedding_seq_pool
fusion_gru
fusion_lstm
fusion_repeated_fc_relu
fusion_seqconv_eltadd_relu
fusion_seqexpand_concat_fc
fusion_seqpool_concat
fusion_squared_mat_sub
gelu
gru
hard_shrink
hierarchical_sigmoid
hinge_loss
huber_loss
im2sequence
l1_norm
label_smooth
leaky_relu
linear_chain_crf
log
log_loss
logsigmoid
lookup_table
lrn
lstm
lstm_unit
lstmp
margin_rank_loss
max_pool2d_with_index
max_pool3d_with_index
maxout
modified_huber_loss
multiplex
nce
nearest_interp
norm
pool2d
pool3d
pow
prelu
psroi_pool
quantize
rank_loss
reduce_max
reduce_mean
reduce_min
reduce_prod
reduce_sum
requantize
reshape
rnn_memory_helper
roi_align
roi_perspective_transform
roi_pool
round
row_conv
scatter
sequence_concat
sequence_conv
sequence_expand
sequence_expand_as
sequence_pad
sequence_scatter
sequence_slice
sequence_softmax
sequence_unpad
shuffle_channel
sigmoid_cross_entropy_with_logits
sin
softplus
softshrink
softsign
space_to_depth
spp
square
squared_l2_distance
squared_l2_norm
squeeze
stanh
swish
tanh_shrink
teacher_student_sigmoid_loss
tensor_array_to_tensor
thresholded_relu
transpose
tree_conv
unpool
unsqueeze
warpctc
...@@ -107,17 +107,6 @@ And the output will change the LoD information with input Ids. ...@@ -107,17 +107,6 @@ And the output will change the LoD information with input Ids.
} }
}; };
class FusedEmbeddingSeqPoolOpGradDescMaker
: public framework::DefaultGradOpDescMaker<true> {
using ::paddle::framework::DefaultGradOpDescMaker<
true>::DefaultGradOpDescMaker;
protected:
virtual std::string GradOpType() const {
return "fused_embedding_seq_pool_grad";
}
};
class FusedEmbeddingSeqPoolOpGrad : public framework::OperatorWithKernel { class FusedEmbeddingSeqPoolOpGrad : public framework::OperatorWithKernel {
public: public:
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
...@@ -160,7 +149,7 @@ class FusedEmbeddingSeqPoolOpGradVarTypeInference ...@@ -160,7 +149,7 @@ class FusedEmbeddingSeqPoolOpGradVarTypeInference
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_OPERATOR(fused_embedding_seq_pool, ops::FusedEmbeddingSeqPoolOp, REGISTER_OPERATOR(fused_embedding_seq_pool, ops::FusedEmbeddingSeqPoolOp,
ops::FusedEmbeddingSeqPoolOpGradDescMaker, paddle::framework::DefaultGradOpDescMaker<true>,
ops::FusedEmbeddingSeqPoolOpMaker); ops::FusedEmbeddingSeqPoolOpMaker);
REGISTER_OPERATOR(fused_embedding_seq_pool_grad, REGISTER_OPERATOR(fused_embedding_seq_pool_grad,
ops::FusedEmbeddingSeqPoolOpGrad, ops::FusedEmbeddingSeqPoolOpGrad,
......
...@@ -119,15 +119,6 @@ or not. And the output only shares the LoD information with input Ids. ...@@ -119,15 +119,6 @@ or not. And the output only shares the LoD information with input Ids.
} }
}; };
class LookupTableOpGradDescMaker
: public framework::DefaultGradOpDescMaker<true> {
using ::paddle::framework::DefaultGradOpDescMaker<
true>::DefaultGradOpDescMaker;
protected:
virtual std::string GradOpType() const { return "lookup_table_grad"; }
};
class LookupTableOpGrad : public framework::OperatorWithKernel { class LookupTableOpGrad : public framework::OperatorWithKernel {
public: public:
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
...@@ -169,7 +160,8 @@ class LookupTableOpGradVarTypeInference : public framework::VarTypeInference { ...@@ -169,7 +160,8 @@ class LookupTableOpGradVarTypeInference : public framework::VarTypeInference {
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_OPERATOR(lookup_table, ops::LookupTableOp, REGISTER_OPERATOR(lookup_table, ops::LookupTableOp,
ops::LookupTableOpGradDescMaker, ops::LookupTableOpMaker); paddle::framework::DefaultGradOpDescMaker<true>,
ops::LookupTableOpMaker);
REGISTER_OPERATOR(lookup_table_grad, ops::LookupTableOpGrad, REGISTER_OPERATOR(lookup_table_grad, ops::LookupTableOpGrad,
ops::LookupTableOpGradVarTypeInference); ops::LookupTableOpGradVarTypeInference);
......
...@@ -187,14 +187,6 @@ By default this operator uses a uniform distribution for sampling. ...@@ -187,14 +187,6 @@ By default this operator uses a uniform distribution for sampling.
} }
}; };
class NCEOpGradDescMaker : public framework::DefaultGradOpDescMaker<true> {
using ::paddle::framework::DefaultGradOpDescMaker<
true>::DefaultGradOpDescMaker;
protected:
virtual std::string GradOpType() const { return "nce_grad"; }
};
class NCEOpGrad : public framework::OperatorWithKernel { class NCEOpGrad : public framework::OperatorWithKernel {
public: public:
using framework::OperatorWithKernel::OperatorWithKernel; using framework::OperatorWithKernel::OperatorWithKernel;
...@@ -259,7 +251,9 @@ class NCEOpGradVarTypeInference : public framework::VarTypeInference { ...@@ -259,7 +251,9 @@ class NCEOpGradVarTypeInference : public framework::VarTypeInference {
} // namespace paddle } // namespace paddle
namespace ops = paddle::operators; namespace ops = paddle::operators;
REGISTER_OPERATOR(nce, ops::NCEOp, ops::NCEOpGradDescMaker, ops::NCEOpMaker); REGISTER_OPERATOR(nce, ops::NCEOp,
paddle::framework::DefaultGradOpDescMaker<true>,
ops::NCEOpMaker);
REGISTER_OPERATOR(nce_grad, ops::NCEOpGrad, ops::NCEOpGradVarTypeInference); REGISTER_OPERATOR(nce_grad, ops::NCEOpGrad, ops::NCEOpGradVarTypeInference);
REGISTER_OP_CPU_KERNEL(nce, ops::NCEKernel<paddle::platform::CPUPlace, float>, REGISTER_OP_CPU_KERNEL(nce, ops::NCEKernel<paddle::platform::CPUPlace, float>,
ops::NCEKernel<paddle::platform::CPUPlace, double>); ops::NCEKernel<paddle::platform::CPUPlace, double>);
......
...@@ -29,6 +29,7 @@ limitations under the License. */ ...@@ -29,6 +29,7 @@ limitations under the License. */
#include "paddle/fluid/framework/lod_rank_table.h" #include "paddle/fluid/framework/lod_rank_table.h"
#include "paddle/fluid/framework/lod_tensor.h" #include "paddle/fluid/framework/lod_tensor.h"
#include "paddle/fluid/framework/lod_tensor_array.h" #include "paddle/fluid/framework/lod_tensor_array.h"
#include "paddle/fluid/framework/op_info.h"
#include "paddle/fluid/framework/op_registry.h" #include "paddle/fluid/framework/op_registry.h"
#include "paddle/fluid/framework/parallel_executor.h" #include "paddle/fluid/framework/parallel_executor.h"
#include "paddle/fluid/framework/prune.h" #include "paddle/fluid/framework/prune.h"
...@@ -155,6 +156,9 @@ PYBIND11_MODULE(core, m) { ...@@ -155,6 +156,9 @@ PYBIND11_MODULE(core, m) {
return paddle::operators::AppendPythonCallableObjectAndReturnId(py_obj); return paddle::operators::AppendPythonCallableObjectAndReturnId(py_obj);
}); });
m.def("_get_use_default_grad_op_desc_maker_ops",
[] { return OpInfoMap::Instance().GetUseDefaultGradOpDescMakerOps(); });
// NOTE(zjl): ctest would load environment variables at the beginning even // NOTE(zjl): ctest would load environment variables at the beginning even
// though we have not `import paddle.fluid as fluid`. So we add this API // though we have not `import paddle.fluid as fluid`. So we add this API
// to enable eager deletion mode in unittest. // to enable eager deletion mode in unittest.
......
...@@ -425,6 +425,11 @@ function assert_api_not_changed() { ...@@ -425,6 +425,11 @@ function assert_api_not_changed() {
sed -i '/.*ComposeNotAligned.*/d' new.spec sed -i '/.*ComposeNotAligned.*/d' new.spec
python ${PADDLE_ROOT}/tools/diff_api.py ${PADDLE_ROOT}/paddle/fluid/API.spec new.spec python ${PADDLE_ROOT}/tools/diff_api.py ${PADDLE_ROOT}/paddle/fluid/API.spec new.spec
# Currently, we only check in PR_CI python 2.7
if [ "$1" == "cp27-cp27m" ]; then
python ${PADDLE_ROOT}/tools/diff_use_default_grad_op_maker.py ${PADDLE_ROOT}/paddle/fluid/op_use_default_grad_op_maker.spec
fi
deactivate deactivate
} }
...@@ -434,9 +439,12 @@ function assert_api_spec_approvals() { ...@@ -434,9 +439,12 @@ function assert_api_spec_approvals() {
fi fi
API_FILES=("paddle/fluid/API.spec" API_FILES=("paddle/fluid/API.spec"
"paddle/fluid/op_use_default_grad_op_maker.spec"
"python/paddle/fluid/parallel_executor.py" "python/paddle/fluid/parallel_executor.py"
"paddle/fluid/framework/operator.h" "paddle/fluid/framework/operator.h"
"paddle/fluid/framework/tensor.h" "paddle/fluid/framework/tensor.h"
"paddle/fluid/framework/details/op_registry.h"
"paddle/fluid/framework/grad_op_desc_maker.h"
"paddle/fluid/framework/lod_tensor.h" "paddle/fluid/framework/lod_tensor.h"
"paddle/fluid/framework/selected_rows.h" "paddle/fluid/framework/selected_rows.h"
"paddle/fluid/framework/op_desc.h" "paddle/fluid/framework/op_desc.h"
......
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
import os
os.environ['CUDA_VISIBLE_DEVICES'] = ''
import paddle.fluid as fluid
import sys
def get_op_diff(filename):
ops_created_by_py_func = set(
fluid.core._get_use_default_grad_op_desc_maker_ops())
with open(filename, 'r') as f:
ops_read_from_file = set([line.strip() for line in f.readlines()])
diff_ops = []
for op in ops_read_from_file:
if op not in ops_created_by_py_func:
diff_ops.append(op)
else:
ops_created_by_py_func.remove(op)
err_msg = []
diff_ops = list(diff_ops)
if len(diff_ops) > 0:
err_msg.append('Added grad op with DefaultGradOpDescMaker: ' + str(
diff_ops))
ops_created_by_py_func = list(ops_created_by_py_func)
if len(ops_created_by_py_func) > 0:
err_msg.append('Remove grad op with DefaultGradOpDescMaker: ' + str(
ops_created_by_py_func))
return err_msg
if len(sys.argv) != 2:
print('Usage: python diff_use_default_grad_op_maker.py [filepath]')
sys.exit(1)
file_path = str(sys.argv[1])
err_msg = get_op_diff(file_path)
if len(err_msg) > 0:
_, filename = os.path.split(file_path)
print('File `{}` is wrong compared to your PR revision!'.format(filename))
print(
'Please use `python generate_op_use_grad_op_desc_maker_spec.py [filepath]` to generate new `{}` file'.
format(filename))
print('Error message is: ' + '; '.join(err_msg))
sys.exit(1)
# Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
#
# 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.
import os
os.environ['CUDA_VISIBLE_DEVICES'] = ''
import paddle.fluid as fluid
import sys
if len(sys.argv) != 2:
print('Usage: python generate_op_use_grad_op_desc_maker_spec.py [filepath]')
sys.exit(1)
with open(sys.argv[1], 'w') as f:
ops = fluid.core._get_use_default_grad_op_desc_maker_ops()
for op in ops:
f.write(op + '\n')
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册