Skip to content

Commit 3279a2b

Browse files
committed
merge develop
2 parents c68778b + 7a4a512 commit 3279a2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1910
-678
lines changed

paddle/fluid/framework/ir/graph_pattern_detector.cc

100755100644
Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,32 @@ PDNode *patterns::Slice::operator()() {
16411641
return slice_out;
16421642
}
16431643

1644+
PDNode *patterns::NearestInterp::operator()() {
1645+
auto prev_op = pattern->NewNode(prev_op_repr())->assert_is_op();
1646+
1647+
auto nearest_interp_op =
1648+
pattern->NewNode(nearest_interp_op_repr())
1649+
->assert_is_ops({"nearest_interp", "nearest_interp_v2"});
1650+
1651+
auto nearest_interp_in =
1652+
pattern->NewNode(nearest_interp_in_repr())
1653+
->AsInput()
1654+
->assert_is_ops_input({"nearest_interp", "nearest_interp_v2"}, "X");
1655+
auto nearest_interp_out =
1656+
pattern->NewNode(nearest_interp_out_repr())
1657+
->AsOutput()
1658+
->assert_is_ops_output({"nearest_interp", "nearest_interp_v2"},
1659+
"Out");
1660+
1661+
auto next_op = pattern->NewNode(next_op_repr())->assert_is_op();
1662+
1663+
prev_op->LinksTo({nearest_interp_in});
1664+
nearest_interp_op->LinksFrom({nearest_interp_in})
1665+
.LinksTo({nearest_interp_out});
1666+
next_op->LinksFrom({nearest_interp_out});
1667+
return nearest_interp_out;
1668+
}
1669+
16441670
PDNode *patterns::Matmul::operator()() {
16451671
auto matmul_op = pattern->NewNode(matmul_op_repr())->assert_is_op("matmul");
16461672

@@ -2376,15 +2402,8 @@ PDNode *patterns::MultipleQuantize::operator()() {
23762402

23772403
PDNode *patterns::QuantizePlacement::operator()(
23782404
const std::unordered_set<std::string> &quantize_enabled_op_types) {
2379-
std::unordered_set<std::string> supported_op_types =
2380-
std::unordered_set<std::string>({"concat", "conv2d", "elementwise_add",
2381-
"fc", "matmul", "pool2d", "prior_box",
2382-
"reshape2", "transpose2", "fusion_gru",
2383-
"fusion_lstm", "multi_gru", "slice"});
2384-
if (!quantize_enabled_op_types.empty()) {
2385-
supported_op_types = quantize_enabled_op_types;
2386-
}
2387-
auto *op = pattern->NewNode(op_repr())->assert_is_ops(supported_op_types);
2405+
auto *op =
2406+
pattern->NewNode(op_repr())->assert_is_ops(quantize_enabled_op_types);
23882407
return op;
23892408
}
23902409

paddle/fluid/framework/ir/graph_pattern_detector.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,21 @@ struct Slice : public PatternBase {
995995
PATTERN_DECL_NODE(next_op);
996996
};
997997

998+
// Nearest Interp op
999+
// Forward pass for nearest_interp.
1000+
// nearest_interp_out is a result of the operator.
1001+
struct NearestInterp : public PatternBase {
1002+
NearestInterp(PDPattern* pattern, const std::string& name_scope)
1003+
: PatternBase(pattern, name_scope, "nearest_interp") {}
1004+
1005+
PDNode* operator()();
1006+
PATTERN_DECL_NODE(prev_op);
1007+
PATTERN_DECL_NODE(nearest_interp_in);
1008+
PATTERN_DECL_NODE(nearest_interp_op);
1009+
PATTERN_DECL_NODE(nearest_interp_out);
1010+
PATTERN_DECL_NODE(next_op);
1011+
};
1012+
9981013
// Matmul op
9991014
// Forward pass for matmul.
10001015
struct Matmul : public PatternBase {

paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass.cc

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,67 @@ void CPUQuantizePass::QuantizeFusionLSTM(Graph* graph) const {
10531053
PrettyLogDetail("--- quantized %d fusion_lstm ops", quantize_count);
10541054
}
10551055

1056+
void CPUQuantizePass::QuantizeNearestInterp(Graph* graph) const {
1057+
GraphPatternDetector gpd;
1058+
auto pattern = gpd.mutable_pattern();
1059+
patterns::NearestInterp nearest_interp_pattern{pattern, name_scope_};
1060+
nearest_interp_pattern();
1061+
1062+
int quantize_nearest_interp_count = 0;
1063+
auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
1064+
Graph* g) {
1065+
VLOG(4) << "Quantize nearest_interp op";
1066+
GET_IR_NODE_FROM_SUBGRAPH(nearest_interp_op, nearest_interp_op,
1067+
nearest_interp_pattern);
1068+
1069+
// skip if should not be quantized
1070+
if (!platform::HasOpINT8DataType(nearest_interp_op->Op())) {
1071+
LogQuantizationDisabled(nearest_interp_op);
1072+
return;
1073+
}
1074+
GET_IR_NODE_FROM_SUBGRAPH(prev_op, prev_op, nearest_interp_pattern);
1075+
GET_IR_NODE_FROM_SUBGRAPH(next_op, next_op, nearest_interp_pattern);
1076+
1077+
// skip if prev op and next op is not quantized
1078+
if (!(IsOpDequantized(prev_op)) && !(IsOpQuantized(next_op))) {
1079+
LogCannotQuantizeOp(nearest_interp_op,
1080+
"There are no other quantized operators nearby, so "
1081+
"quantization is not recommended.");
1082+
return;
1083+
}
1084+
1085+
GET_IR_NODE_FROM_SUBGRAPH(nearest_interp_in, nearest_interp_in,
1086+
nearest_interp_pattern);
1087+
GET_IR_NODE_FROM_SUBGRAPH(nearest_interp_out, nearest_interp_out,
1088+
nearest_interp_pattern);
1089+
1090+
if (!AreScalesPresentForNodes({nearest_interp_in, nearest_interp_out})) {
1091+
LogCannotQuantizeOp(nearest_interp_op);
1092+
return;
1093+
}
1094+
1095+
bool is_input_unsigned{false};
1096+
auto input_scale =
1097+
GetScaleValueForNode(nearest_interp_in, &is_input_unsigned);
1098+
QuantizeInput(g, nearest_interp_op, nearest_interp_in, "X", input_scale,
1099+
is_input_unsigned);
1100+
1101+
bool is_output_unsigned{false};
1102+
auto output_scale =
1103+
GetScaleValueForNode(nearest_interp_out, &is_output_unsigned);
1104+
DequantizeOutput(g, nearest_interp_op, nearest_interp_out, "Out",
1105+
output_scale, is_output_unsigned);
1106+
1107+
++quantize_nearest_interp_count;
1108+
};
1109+
1110+
gpd(graph, handler);
1111+
AddStatis(quantize_nearest_interp_count);
1112+
1113+
PrettyLogDetail("--- quantized %d nearest_interp ops",
1114+
quantize_nearest_interp_count);
1115+
}
1116+
10561117
void CPUQuantizePass::ApplyImpl(ir::Graph* graph) const {
10571118
VLOG(3) << "Quantizing the graph.";
10581119
PADDLE_ENFORCE_NOT_NULL(
@@ -1076,6 +1137,7 @@ void CPUQuantizePass::ApplyImpl(ir::Graph* graph) const {
10761137
QuantizeMultiGru(graph);
10771138
QuantizeFusionLSTM(graph);
10781139
QuantizeSlice(graph);
1140+
QuantizeNearestInterp(graph);
10791141
}
10801142

10811143
} // namespace ir

paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class CPUQuantizePass : public FusePassBase {
6262
void QuantizeMultiGru(Graph* graph) const;
6363
void QuantizeFusionLSTM(Graph* graph) const;
6464
void QuantizeSlice(Graph* graph) const;
65+
void QuantizeNearestInterp(Graph* graph) const;
6566

6667
void QuantizeInput(Graph* g, Node* op, Node* input, std::string input_name,
6768
double scale_to_one, bool is_input_unsigned,

paddle/fluid/framework/ir/mkldnn/cpu_quantize_pass_tester.cc

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ void SetOp(ProgramDesc* prog, const std::string& type, const std::string& name,
5858
op->SetAttr("Scale_in", 1.0f);
5959
op->SetAttr("Scale_out", 1.0f);
6060
op->SetAttr("Scale_weights", std::vector<float>{1.0f});
61-
} else if (type == "pool2d" || type == "transpose2" || type == "reshape2") {
61+
} else if (type == "pool2d" || type == "transpose2" || type == "reshape2" ||
62+
type == "nearest_interp" || type == "nearest_interp_v2") {
6263
op->SetInput("X", {inputs[0]});
6364
op->SetOutput("Out", {outputs[0]});
6465
} else if (type == "slice") {
@@ -434,6 +435,18 @@ TEST(CpuQuantizePass, sliceBetweenNonQuantizedOp) {
434435
TestImmutableOpBetweenNonQuantizedOp("slice");
435436
}
436437

438+
TEST(CpuQuantizePass, nearestInterp) { TestImmutableOp("nearest_interp"); }
439+
440+
TEST(CpuQuantizePass, nearestInterpBetweenNonQuantizedOp) {
441+
TestImmutableOpBetweenNonQuantizedOp("nearest_interp");
442+
}
443+
444+
TEST(CpuQuantizePass, nearestInterpV2) { TestImmutableOp("nearest_interp_v2"); }
445+
446+
TEST(CpuQuantizePass, nearestInterpV2BetweenNonQuantizedOp) {
447+
TestImmutableOpBetweenNonQuantizedOp("nearest_interp_v2");
448+
}
449+
437450
static const std::initializer_list<std::string> variable_names_matmul = {
438451
"a", "b", "c", "d", "e", "f"};
439452

paddle/fluid/framework/ir/mkldnn/cpu_quantize_placement_pass.cc

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ See the License for the specific language governing permissions and
1313
limitations under the License. */
1414

1515
#include "paddle/fluid/framework/ir/mkldnn/cpu_quantize_placement_pass.h"
16+
1617
#include <unordered_set>
1718

1819
namespace paddle {
@@ -23,15 +24,34 @@ class Graph;
2324

2425
void CPUQuantizePlacementPass::ApplyImpl(ir::Graph* graph) const {
2526
VLOG(3) << "Marks operators which are to be quantized.";
27+
std::unordered_set<std::string> supported_op_types =
28+
std::unordered_set<std::string>(
29+
{"concat", "conv2d", "depthwise_conv2d", "elementwise_add", "fc",
30+
"matmul", "nearest_interp", "nearest_interp_v2", "pool2d",
31+
"prior_box", "reshape2", "transpose2", "fusion_gru", "fusion_lstm",
32+
"multi_gru", "slice"});
2633
const auto& excluded_ids_list =
2734
Get<std::unordered_set<int>>("quantize_excluded_op_ids");
2835
const auto& op_types_list =
2936
Get<std::unordered_set<std::string>>("quantize_enabled_op_types");
37+
38+
if (!op_types_list.empty()) {
39+
// Verify that all user-specified operators can be quantized.
40+
for (const auto& op : op_types_list) {
41+
PADDLE_ENFORCE_NE(
42+
supported_op_types.count(op), 0,
43+
platform::errors::InvalidArgument(
44+
"Pass attribute quantize_enabled_op_types contains operator %s "
45+
"that is not supported by OneDNN quantization.",
46+
op));
47+
}
48+
supported_op_types = op_types_list;
49+
}
3050
Init(name_scope_, graph);
3151
GraphPatternDetector gpd;
3252
patterns::QuantizePlacement quantize_placement_pattern{gpd.mutable_pattern(),
3353
"quantize_placement"};
34-
quantize_placement_pattern(op_types_list);
54+
quantize_placement_pattern(supported_op_types);
3555

3656
auto handler = [&](const GraphPatternDetector::subgraph_t& subgraph,
3757
Graph* g) {
@@ -46,16 +66,7 @@ void CPUQuantizePlacementPass::ApplyImpl(ir::Graph* graph) const {
4666
return;
4767
}
4868

49-
if (op->Op()->HasAttr("mkldnn_data_type") ||
50-
op->Op()->HasProtoAttr("mkldnn_data_type")) {
51-
// use_quantizer is no longer used
52-
// assign value for compatibility
53-
if (op->Op()->GetAttrIfExists<bool>("use_quantizer")) {
54-
op->Op()->SetAttr("mkldnn_data_type", std::string("int8"));
55-
}
56-
op->Op()->SetAttr("mkldnn_data_type", std::string("int8"));
57-
op->Op()->SetAttr("use_quantizer", true);
58-
}
69+
op->Op()->SetAttr("mkldnn_data_type", std::string("int8"));
5970
};
6071
gpd(graph, handler);
6172
}

paddle/fluid/framework/ir/mkldnn/cpu_quantize_placement_pass_tester.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,32 @@ TEST(QuantizerPlacementPass, default_attr_value) {
140140
DefaultAttrTest(5);
141141
}
142142

143+
void EnabledOpTypesTest(
144+
std::initializer_list<std::string> quantize_enabled_op_types,
145+
std::string missing_op) {
146+
auto prog = BuildProgramDesc();
147+
std::unique_ptr<ir::Graph> graph(new ir::Graph(prog));
148+
149+
auto pass = PassRegistry::Instance().Get("cpu_quantize_placement_pass");
150+
pass->Set("quantize_enabled_op_types",
151+
new std::unordered_set<std::string>(quantize_enabled_op_types));
152+
153+
try {
154+
graph.reset(pass->Apply(graph.release()));
155+
} catch (paddle::platform::EnforceNotMet& err) {
156+
std::string ex_msg = err.what();
157+
std::string expected_msg =
158+
"Pass attribute quantize_enabled_op_types contains operator " +
159+
missing_op + " that is not supported by OneDNN quantization.";
160+
EXPECT_TRUE(ex_msg.find(expected_msg) != std::string::npos);
161+
}
162+
}
163+
164+
TEST(QuantizerPlacementPass, unsupported_op_type) {
165+
// Dropout op is not supported by OneDNN quantization
166+
EnabledOpTypesTest({"conv2d", "dropout"}, "dropout");
167+
}
168+
143169
} // namespace ir
144170
} // namespace framework
145171
} // namespace paddle

paddle/fluid/inference/api/mkldnn_quantizer.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ void AnalysisPredictor::MkldnnQuantizer::CalculateScalesForOpOutputs(
124124
} else if (op->Type() == "relu") {
125125
is_unsigned = true;
126126
} else if (op->Type() == "transpose2" || op->Type() == "reshape2" ||
127-
op->Type() == "pool2d") {
127+
op->Type() == "pool2d" || op->Type() == "nearest_interp" ||
128+
op->Type() == "nearest_interp_v2") {
128129
auto input_var_name = op->Input("X")[0];
129130
PADDLE_ENFORCE_NE(scales_.find(input_var_name), scales_.end(),
130131
platform::errors::PreconditionNotMet(

paddle/fluid/inference/api/mkldnn_quantizer_config.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,18 @@ MkldnnQuantizerConfig::MkldnnQuantizerConfig() {
107107
rules_["fusion_lstm"]["ReorderedC0"] = ScaleAlgo::NONE;
108108
rules_["fusion_lstm"]["CheckedCell"] = ScaleAlgo::NONE;
109109
rules_["fusion_lstm"]["Hidden"] = ScaleAlgo::KL;
110+
111+
rules_["nearest_interp"]["X"] = ScaleAlgo::KL;
112+
rules_["nearest_interp"]["OutSize"] = ScaleAlgo::NONE;
113+
rules_["nearest_interp"]["SizeTensor"] = ScaleAlgo::NONE;
114+
rules_["nearest_interp"]["Scale"] = ScaleAlgo::NONE;
115+
rules_["nearest_interp"]["Out"] = ScaleAlgo::NONE;
116+
117+
rules_["nearest_interp_v2"]["X"] = ScaleAlgo::KL;
118+
rules_["nearest_interp_v2"]["OutSize"] = ScaleAlgo::NONE;
119+
rules_["nearest_interp_v2"]["SizeTensor"] = ScaleAlgo::NONE;
120+
rules_["nearest_interp_v2"]["Scale"] = ScaleAlgo::NONE;
121+
rules_["nearest_interp_v2"]["Out"] = ScaleAlgo::NONE;
110122
}
111123

112124
ScaleAlgo MkldnnQuantizerConfig::scale_algo(

paddle/fluid/inference/capi_exp/pd_config.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,10 @@ __pd_give PD_OneDimArrayCstr* PD_ConfigAllPasses(
459459
std::vector<std::string> passes = config->pass_builder()->AllPasses();
460460
return paddle_infer::CvtVecToOneDimArrayCstr(passes);
461461
}
462-
const char* PD_ConfigSummary(__pd_keep PD_Config* pd_config) {
462+
__pd_give PD_Cstr* PD_ConfigSummary(__pd_keep PD_Config* pd_config) {
463463
CHECK_AND_CONVERT_PD_CONFIG;
464464
auto sum_str = config->Summary();
465-
char* c = reinterpret_cast<char*>(malloc(sum_str.length() + 1));
466-
snprintf(c, sum_str.length() + 1, "%s", sum_str.c_str());
467-
return c;
465+
return paddle_infer::CvtStrToCstr(sum_str);
468466
}
469467

470468
} // extern "C"

0 commit comments

Comments
 (0)