Skip to content

Commit

Permalink
[TOPI][RESIZE] bilinear weights computed inline inside topi.
Browse files Browse the repository at this point in the history
               * weights arg removed across nnvm/tvm.
  • Loading branch information
srkreddy1238 committed Jun 14, 2018
1 parent aef6ea9 commit d24c986
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 217 deletions.
41 changes: 12 additions & 29 deletions nnvm/src/top/image/resize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,23 @@ inline bool ResizeInferShape(const nnvm::NodeAttrs& attrs,
std::vector<TShape>* out_shape) {
static const Layout kNCHW("NCHW");
const ResizeParam& param = nnvm::get<ResizeParam>(attrs.parsed);
CHECK_EQ(in_shape->size(), (param.method == "BILINEAR") ? 2U : 1U);
CHECK_EQ(in_shape->size(), 1U);
CHECK_EQ(out_shape->size(), 1U);
TShape dshape = (*in_shape)[0];
if (dshape.ndim() == 0) return false;
dshape = ConvertLayout(dshape, param.layout, kNCHW);

TShape oshape = dshape;
if (param.layout == "NCHW") {
oshape[2] = param.out_size[0];
oshape[3] = param.out_size[1];
oshape[2] = param.size[0];
oshape[3] = param.size[1];
} else {
oshape[1] = param.out_size[0];
oshape[2] = param.out_size[1];
oshape[1] = param.size[0];
oshape[2] = param.size[1];
}

oshape = ConvertLayout(oshape, kNCHW, param.layout);
NNVM_ASSIGN_OUTPUT_SHAPE(attrs, *out_shape, 0, oshape);

if (param.method == "BILINEAR") {
// frame wise (srcx, srcy, x_diff, y_diff)
TShape wshape({param.out_size[0],
param.out_size[1],
4U});

NNVM_ASSIGN_OUTPUT_SHAPE(attrs, *in_shape, 1, wshape);
}
return true;
}

Expand All @@ -67,7 +58,7 @@ inline bool ResizeLayout(const NodeAttrs& attrs,
const std::vector<Layout> *last_in_layouts,
std::vector<Layout> *out_layouts) {
const ResizeParam& param = nnvm::get<ResizeParam>(attrs.parsed);
CHECK_EQ(in_layouts->size(), (param.method == "BILINEAR") ? 2U : 1U);
CHECK_EQ(in_layouts->size(), 1U);
CHECK_EQ(out_layouts->size(), 1U);
const Layout layout(param.layout);
NNVM_ASSIGN_LAYOUT(*in_layouts, 0, layout);
Expand All @@ -78,35 +69,27 @@ inline bool ResizeLayout(const NodeAttrs& attrs,
NNVM_REGISTER_OP(resize)
.describe(R"(Perform resize to input array with nearest neighbour or bilinear interpolation.
- **data**: Input[0] is 4D array of shape
- **data**: data is 4D array of shape
(batch_size, channels, in_height, in_width) for NCHW
(batch_size, in_height, in_width, channels) for NHWC
Input[1] is 3D Tensor with shape [out_shape[0], out_shape[1], 4]
holds (srcx, srcy, x_diff, y_diff) for each out value.
weights is valid only for method=BILINEAR
helper function tvm.contrib.image.bilinear_weights
available to generate this param at frontend.
- **out**: Output is 4D array of shape
for layout NCHW
(batch_size, channels, out_size[0], out_size[1])
(batch_size, channels, size[0], size[1])
for layout NHWC
(batch_size, out_size[0], out_size[1], channels)
(batch_size, size[0], size[1], channels)
)" NNVM_ADD_FILELINE)
.add_argument("data", "4D Tensor", "Input data.")
.add_argument("weight", "3D Tensor", "Weight matrix.")
.add_arguments(ResizeParam::__FIELDS__())
.set_attr_parser(ParamParser<ResizeParam>)
.set_attr<FGetAttrDict>("FGetAttrDict", ParamGetAttrDict<ResizeParam>)
.set_attr<FListInputNames>("FListInputNames", UseBilinearListInputNames<ResizeParam>)
.set_attr<FInferShape>("FInferShape", ResizeInferShape)
.set_attr<FInferType>("FInferType", ElemwiseType<-1, 1>)
.set_attr<FInferType>("FInferType", ElemwiseType<1, 1>)
.set_attr<FCorrectLayout>("FCorrectLayout", ResizeLayout)
.set_num_outputs(1)
.set_num_inputs(UseBilinearNumInputs<ResizeParam>)
.set_num_inputs(1)
.set_attr<FTVMCompute>(
"FTVMCompute", [](const NodeAttrs& attrs,
const Array<Tensor>& inputs,
Expand All @@ -121,7 +104,7 @@ NNVM_REGISTER_OP(resize)
oshape.push_back(out_info[0]->shape[2]);
}

return Array<Tensor>{ topi::image::resize(inputs, oshape, param.layout,
return Array<Tensor>{ topi::image::resize(inputs[0], oshape, param.layout,
param.align_corners, param.method)};
})
.set_support_level(2);
Expand Down
4 changes: 2 additions & 2 deletions nnvm/src/top/image/resize.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ namespace nnvm {
namespace top {

struct ResizeParam : public dmlc::Parameter<ResizeParam> {
TShape out_size;
TShape size;
std::string layout;
std::string method;
bool align_corners;

DMLC_DECLARE_PARAMETER(ResizeParam) {
DMLC_DECLARE_FIELD(out_size)
DMLC_DECLARE_FIELD(size)
.describe("Output size");
DMLC_DECLARE_FIELD(layout)
.set_default("NCHW")
Expand Down
16 changes: 0 additions & 16 deletions nnvm/src/top/nn/nn_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,6 @@ inline std::vector<std::string> UseBiasListInputNames(const NodeAttrs& attrs) {
}
}

template<typename ParamType>
inline uint32_t UseBilinearNumInputs(const NodeAttrs& attrs) {
const ParamType& param = get<ParamType>(attrs.parsed);
return param.method == "BILINEAR" ? 2 : 1;
}

template<typename ParamType>
inline std::vector<std::string> UseBilinearListInputNames(const NodeAttrs& attrs) {
const ParamType& param = nnvm::get<ParamType>(attrs.parsed);
if (param.method == "BILINEAR") {
return {"data", "weight"};
} else {
return {"data"};
}
}

/*!
* \brief Convert shape in src_layout to shape in dst_layout
* \param src original shape
Expand Down
28 changes: 6 additions & 22 deletions nnvm/src/top/nn/upsampling.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ inline bool UpSamplingInferShape(const nnvm::NodeAttrs& attrs,
std::vector<TShape>* out_shape) {
static const Layout kNCHW("NCHW");
const UpSamplingParam& param = nnvm::get<UpSamplingParam>(attrs.parsed);
CHECK_EQ(in_shape->size(), (param.method == "BILINEAR") ? 2U : 1U);
CHECK_EQ(in_shape->size(), 1U);
CHECK_EQ(out_shape->size(), 1U);
TShape dshape = (*in_shape)[0];
if (dshape.ndim() == 0) return false;
Expand All @@ -44,15 +44,6 @@ inline bool UpSamplingInferShape(const nnvm::NodeAttrs& attrs,
oshape = ConvertLayout(oshape, kNCHW, param.layout);
NNVM_ASSIGN_OUTPUT_SHAPE(attrs, *out_shape, 0, oshape);

if (param.method == "BILINEAR") {
// frame wise (srcx, srcy, x_diff, y_diff)
TShape wshape({dshape[2] * param.scale,
dshape[3] * param.scale,
4U});

NNVM_ASSIGN_OUTPUT_SHAPE(attrs, *in_shape, 1, wshape);
}

return true;
}

Expand All @@ -61,7 +52,7 @@ inline bool UpsamplingLayout(const NodeAttrs& attrs,
const std::vector<Layout> *last_in_layouts,
std::vector<Layout> *out_layouts) {
const UpSamplingParam& param = nnvm::get<UpSamplingParam>(attrs.parsed);
CHECK_EQ(in_layouts->size(), (param.method == "BILINEAR") ? 2U : 1U);
CHECK_EQ(in_layouts->size(), 1U);
CHECK_EQ(out_layouts->size(), 1U);
const Layout layout(param.layout);
NNVM_ASSIGN_LAYOUT(*in_layouts, 0, layout);
Expand All @@ -72,16 +63,10 @@ inline bool UpsamplingLayout(const NodeAttrs& attrs,
NNVM_REGISTER_OP(upsampling)
.describe(R"(Perform upsampling to input array with nearest neighbour or bilinear interpolation.
- **data**: data[0] is 4D array of shape
- **data**: data is 4D array of shape
(batch_size, channels, in_height, in_width) for NCHW
(batch_size, in_height, in_width, channels) for NHWC
data[1] is 3D Tensor with shape [out_shape[0], out_shape[1], 4]
holds (srcx, srcy, x_diff, y_diff) for each out value.
weights is valid only for method=BILINEAR
helper function tvm.contrib.image.bilinear_weights
available to generate this param at frontend.
- **out**: Output is 4D array of shape
for layout NCHW
(batch_size, channels, in_height*scale, in_width*scale)
Expand All @@ -95,12 +80,11 @@ NNVM_REGISTER_OP(upsampling)
.add_arguments(UpSamplingParam::__FIELDS__())
.set_attr_parser(ParamParser<UpSamplingParam>)
.set_attr<FGetAttrDict>("FGetAttrDict", ParamGetAttrDict<UpSamplingParam>)
.set_attr<FListInputNames>("FListInputNames", UseBilinearListInputNames<UpSamplingParam>)
.set_attr<FInferShape>("FInferShape", UpSamplingInferShape)
.set_attr<FInferType>("FInferType", ElemwiseType<-1, 1>)
.set_attr<FInferType>("FInferType", ElemwiseType<1, 1>)
.set_attr<FCorrectLayout>("FCorrectLayout", UpsamplingLayout)
.set_num_outputs(1)
.set_num_inputs(UseBilinearNumInputs<UpSamplingParam>)
.set_num_inputs(1)
.set_attr<FTVMCompute>(
"FTVMCompute", [](const NodeAttrs& attrs,
const Array<Tensor>& inputs,
Expand All @@ -115,7 +99,7 @@ NNVM_REGISTER_OP(upsampling)
oshape.push_back(out_info[0]->shape[2]);
}

return Array<Tensor>{ topi::nn::upsampling(inputs, oshape, param.layout, param.method)};
return Array<Tensor>{ topi::nn::upsampling(inputs[0], oshape, param.layout, param.method)};
})
.set_support_level(2);

Expand Down
20 changes: 6 additions & 14 deletions nnvm/tests/python/compiler/test_top_level2.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,21 +235,17 @@ def test_upsampling_bilinear():
dtype = "float32"
dshape = (1, 4, 32, 32)
oshape = (1, 4, 32*scale, 32*scale)
wshape = (32*scale, 32*scale, 4)
shape_dict = {"x": dshape}
dtype_dict = {"x": dtype}
for target, ctx in ctx_list():
graph, lib, _ = nnvm.compiler.build(y, target, shape_dict, dtype_dict)
m = graph_runtime.create(graph, lib, ctx)
a_np = np.random.uniform(size=dshape).astype(dtype)
data = tvm.nd.array(a_np)
from tvm.contrib.image import bilinear_weights
weights_np = bilinear_weights(32, 32, 32*scale, 32*scale, False)
weights = tvm.nd.array(weights_np)
m.run(x=data, y_weight=weights)
m.run(x=data)
out = m.get_output(0, tvm.nd.empty(oshape, dtype))
b_np = topi.testing.bilinear_resize_python(a_np, weights_np, (32*scale, 32*scale), "NCHW")
np.testing.assert_allclose(out.asnumpy(), b_np, rtol=1e-5)
b_np = topi.testing.bilinear_resize_python(a_np, (32*scale, 32*scale), "NCHW")
np.testing.assert_allclose(out.asnumpy(), b_np, rtol=1e-5, atol=1e-5)

def test_resize_bilinear():
x = sym.Variable("x")
Expand All @@ -258,21 +254,17 @@ def test_resize_bilinear():
dtype = "float32"
dshape = (1, 32, 32, 4)
oshape = (1, 32*scale, 32*scale, 4)
wshape = (32*scale, 32*scale, 4)
shape_dict = {"x": dshape}
dtype_dict = {"x": dtype}
for target, ctx in ctx_list():
graph, lib, _ = nnvm.compiler.build(y, target, shape_dict, dtype_dict)
m = graph_runtime.create(graph, lib, ctx)
a_np = np.random.uniform(size=dshape).astype(dtype)
data = tvm.nd.array(a_np)
from tvm.contrib.image import bilinear_weights
weights_np = bilinear_weights(32, 32, 32*scale, 32*scale, False)
weights = tvm.nd.array(weights_np)
m.run(x=data, y_weight=weights)
m.run(x=data)
out = m.get_output(0, tvm.nd.empty(oshape, dtype))
b_np = topi.testing.bilinear_resize_python(a_np, weights_np, (32*scale, 32*scale), "NHWC")
np.testing.assert_allclose(out.asnumpy(), b_np, rtol=1e-5)
b_np = topi.testing.bilinear_resize_python(a_np, (32*scale, 32*scale), "NHWC")
np.testing.assert_allclose(out.asnumpy(), b_np, rtol=1e-5, atol=1e-5)

if __name__ == "__main__":
test_conv2d()
Expand Down
30 changes: 0 additions & 30 deletions python/tvm/contrib/image.py

This file was deleted.

Loading

0 comments on commit d24c986

Please sign in to comment.