Skip to content

Commit 944bdee

Browse files
committed
Merge remote-tracking branch 'ups/develop' into multithreads
2 parents 9b34f8d + 9dc3ed4 commit 944bdee

File tree

4 files changed

+195
-15
lines changed

4 files changed

+195
-15
lines changed

paddle/fluid/inference/analysis/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,9 @@ cc_test(test_subgraph_splitter
1515
DEPS analysis paddle_fluid tensor
1616
ARGS --inference_model_dir=${PYTHON_TESTS_DIR}/book/word2vec.inference.model)
1717
set_tests_properties(test_subgraph_splitter PROPERTIES DEPENDS test_word2vec)
18+
19+
cc_test(test_dfg_graphviz_draw_pass
20+
SRCS dfg_graphviz_draw_pass_tester.cc
21+
DEPS analysis
22+
ARGS --inference_model_dir=${PYTHON_TESTS_DIR}/book/word2vec.inference.model)
23+
set_tests_properties(test_dfg_graphviz_draw_pass PROPERTIES DEPENDS test_word2vec)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
/*
16+
* This file create an DFG_GraphvizDrawPass which helps to draw a data flow
17+
* graph's structure using graphviz.
18+
*/
19+
20+
#pragma once
21+
22+
#include <fstream>
23+
#include <string>
24+
#include "paddle/fluid/inference/analysis/pass.h"
25+
26+
namespace paddle {
27+
namespace inference {
28+
namespace analysis {
29+
30+
/*
31+
* Output a dot file and write to some place.
32+
*/
33+
class DFG_GraphvizDrawPass : public DataFlowGraphPass {
34+
public:
35+
DFG_GraphvizDrawPass(const std::string& dir, const std::string& id)
36+
: dir_(dir), id_(id) {}
37+
38+
bool Initialize() override { return Pass::Initialize(); }
39+
void Run(DataFlowGraph* graph) override {
40+
auto content = Draw(graph);
41+
std::ofstream file(GenDotPath());
42+
file.write(content.c_str(), content.size());
43+
file.close();
44+
LOG(INFO) << "draw dot to " << GenDotPath();
45+
}
46+
47+
bool Finalize() override { return Pass::Finalize(); }
48+
49+
Pass* CreatePrinterPass(std::ostream& os,
50+
const std::string& banner) const override {
51+
return nullptr;
52+
}
53+
54+
private:
55+
// Path of the dot file to output.
56+
std::string GenDotPath() const {
57+
return dir_ + "/" + "graph_" + id_ + ".dot";
58+
}
59+
60+
std::string Draw(DataFlowGraph* graph) { return graph->DotString(); }
61+
62+
std::string dir_;
63+
std::string id_;
64+
};
65+
66+
} // namespace analysis
67+
} // namespace inference
68+
} // namespace paddle
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License. */
14+
15+
#include "paddle/fluid/inference/analysis/dfg_graphviz_draw_pass.h"
16+
17+
#include <gtest/gtest.h>
18+
#include <fstream>
19+
#include <string>
20+
#include "paddle/fluid/inference/analysis/ut_helper.h"
21+
22+
namespace paddle {
23+
namespace inference {
24+
namespace analysis {
25+
26+
TEST_F(DFG_Tester, dfg_graphviz_draw_pass_tester) {
27+
auto dfg = ProgramDescToDFG(desc);
28+
DFG_GraphvizDrawPass pass("./", "test");
29+
pass.Initialize();
30+
pass.Run(&dfg);
31+
32+
// test content
33+
std::ifstream file("./graph_test.dot");
34+
ASSERT_TRUE(file.is_open());
35+
36+
std::string line;
37+
int no{0};
38+
while (std::getline(file, line)) {
39+
no++;
40+
}
41+
ASSERT_EQ(no, 82);
42+
}
43+
44+
} // namespace analysis
45+
} // namespace inference
46+
} // namespace paddle

python/paddle/fluid/layers/nn.py

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@
8181
'label_smooth',
8282
'roi_pool',
8383
'dice_loss',
84+
'image_resize',
85+
'image_resize_short',
8486
'resize_bilinear',
8587
'gather',
8688
'random_crop',
@@ -3929,22 +3931,25 @@ def dice_loss(input, label, epsilon=0.00001):
39293931
return reduce_mean(dice_score)
39303932

39313933

3932-
def resize_bilinear(input, out_shape=None, scale=None, name=None):
3934+
def image_resize(input,
3935+
out_shape=None,
3936+
scale=None,
3937+
name=None,
3938+
resample='BILINEAR'):
39333939
"""
3934-
The mathematical meaning of resize bilinear layer is
3935-
Bilinear interpolation.
3936-
Bilinear interpolation is an extension of linear interpolation for
3937-
interpolating functions of two variables (e.g. H-direction and
3938-
W-direction in this layer) on a rectilinear 2D grid.
3940+
Resize a batch of images.
39393941
3940-
For details, please refer to Wikipedia:
3941-
https://en.wikipedia.org/wiki/Bilinear_interpolation
3942+
The input must be a tensor of the shape (num_batches, channels, in_h, in_w),
3943+
and the resizing only applies on the last two dimensions(hight and width).
3944+
3945+
Supporting resample methods:
3946+
'BILINEAR' : Bilinear interpolation
39423947
39433948
Args:
3944-
input (Variable): The input tensor of resize bilinear layer,
3949+
input (Variable): The input tensor of image resize layer,
39453950
This is a 4-D tensor of the shape
39463951
(num_batches, channels, in_h, in_w).
3947-
out_shape(list|tuple|Variable|None): Output shape of resize bilinear
3952+
out_shape(list|tuple|Variable|None): Output shape of image resize
39483953
layer, the shape is (out_h, out_w).
39493954
Default: None
39503955
scale(float|None): The multiplier for the input height or width.
@@ -3953,6 +3958,8 @@ def resize_bilinear(input, out_shape=None, scale=None, name=None):
39533958
Default: None
39543959
name(str|None): A name for this layer(optional). If set None, the layer
39553960
will be named automatically.
3961+
resample(str): The resample method. It can only be 'BILINEAR' currently.
3962+
Default: 'BILINEAR'
39563963
39573964
Returns:
39583965
out (Variable): The output is a 4-D tensor of the shape
@@ -3961,8 +3968,12 @@ def resize_bilinear(input, out_shape=None, scale=None, name=None):
39613968
Examples:
39623969
.. code-block:: python
39633970
3964-
out = fluid.layers.resize_bilinear(input, out_shape=[12, 12])
3971+
out = fluid.layers.image_resize(input, out_shape=[12, 12])
39653972
"""
3973+
resample_methods = {'BILINEAR': 'bilinear_interp'}
3974+
if resample not in resample_methods:
3975+
raise ValueError(
3976+
"The 'resample' of image_resize can only be 'BILINEAR' currently.")
39663977
if out_shape is None and scale is None:
39673978
raise ValueError("One of out_shape and scale must not be None")
39683979
helper = LayerHelper('bilinear_interp', **locals())
@@ -3990,31 +4001,80 @@ def _is_list_or_turple_(data):
39904001

39914002
out = helper.create_tmp_variable(dtype)
39924003
helper.append_op(
3993-
type="bilinear_interp",
4004+
type=resample_methods[resample],
39944005
inputs=inputs,
39954006
outputs={"Out": out},
39964007
attrs={"out_h": out_h,
39974008
"out_w": out_w})
39984009
return out
39994010

40004011

4012+
def resize_bilinear(input, out_shape=None, scale=None, name=None):
4013+
"""
4014+
This is an alias of layer 'image_resize' with bilinear interpolation.
4015+
4016+
The mathematical meaning of resize bilinear layer is
4017+
Bilinear interpolation.
4018+
Bilinear interpolation is an extension of linear interpolation for
4019+
interpolating functions of two variables (e.g. H-direction and
4020+
W-direction in this layer) on a rectilinear 2D grid.
4021+
4022+
For details, please refer to Wikipedia:
4023+
https://en.wikipedia.org/wiki/Bilinear_interpolation
4024+
"""
4025+
4026+
return image_resize(input, out_shape, scale, name, 'BILINEAR')
4027+
4028+
4029+
def image_resize_short(input, out_short_len, resample='BILINEAR'):
4030+
"""
4031+
Resize a batch of images. The short edge of input images will be
4032+
resized to the given 'out_short_len'. The long edge of input images
4033+
will be resized proportionately to make images' length-width ratio
4034+
constant.
4035+
4036+
Args:
4037+
input (Variable): The input tensor of image resize layer,
4038+
This is a 4-D tensor of the shape
4039+
(num_batches, channels, in_h, in_w).
4040+
out_short_len(int): The length of output images' short edge.
4041+
4042+
Returns:
4043+
out (Variable): The output is a 4-D tensor of the shape
4044+
(num_batches, channls, out_h, out_w).
4045+
"""
4046+
in_shape = input.shape
4047+
if len(in_shape) != 4:
4048+
raise ValueError(
4049+
"The rank of input must be 4 (num_batches, channels, in_h, in_w).")
4050+
hw = in_shape[2:4]
4051+
short_idx = hw.index(min(hw))
4052+
long_idx = 1 - short_idx
4053+
out_shape = list(hw)
4054+
out_shape[short_idx] = out_short_len
4055+
out_shape[long_idx] = int(
4056+
float(out_shape[long_idx]) * (float(out_short_len) / float(hw[
4057+
short_idx])) + 0.5)
4058+
return image_resize(input=input, out_shape=out_shape, resample=resample)
4059+
4060+
40014061
def gather(input, index):
40024062
"""
40034063
Output is obtained by gathering entries of the outer-most dimension
40044064
of X indexed by `index` and concatenate them together.
40054065
40064066
.. math::
40074067
4008-
Out = X[Index]
4068+
Out = X[Index]
40094069
40104070
40114071
.. code-block:: text
40124072
40134073
40144074
Given:
40154075
4016-
X = [[1, 2],
4017-
[3, 4],
4076+
X = [[1, 2],
4077+
[3, 4],
40184078
[5, 6]]
40194079
40204080
Index = [1, 2]

0 commit comments

Comments
 (0)