Skip to content

Commit 8b1fb4d

Browse files
Xingyu Zhouzhiics
authored andcommitted
[Relay][Op] Enhance Upsample Operator to support float scales (#4206)
* :add scale2 for upsample * update unit test for upsampling * support latest upsample op for multiple frontend * fix lint * fix lint * fix lint * fix lint * update scale description and rebase
1 parent 2e07447 commit 8b1fb4d

File tree

18 files changed

+104
-68
lines changed

18 files changed

+104
-68
lines changed

include/tvm/expr_operator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,9 @@ inline Expr make_zero(Type t) {
700700
} \
701701
inline Expr Name(const Expr& a, int b) { \
702702
return Name(a, make_const(a.type(), b)); \
703+
} \
704+
inline Expr Name(const Expr& a, double b) { \
705+
return Name(a, make_const(Float(64), b)); \
703706
}
704707

705708
#define TVM_DEFINE_LOGICAL_OP_CONST_VAL_OVERLOAD(Name) \

include/tvm/relay/attrs/nn.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,17 @@ struct FIFOBufferAttrs : public tvm::AttrsNode<FIFOBufferAttrs> {
387387

388388
/*! \brief Attributes for upsampling operator */
389389
struct UpSamplingAttrs : public tvm::AttrsNode<UpSamplingAttrs> {
390-
int scale;
390+
double scale_h;
391+
double scale_w;
391392
std::string layout;
392393
std::string method;
393394
bool align_corners;
394395

395396
TVM_DECLARE_ATTRS(UpSamplingAttrs, "relay.attrs.UpSamplingAttrs") {
396-
TVM_ATTR_FIELD(scale)
397-
.describe("Should be true to preserve the values at the corner pixels");
397+
TVM_ATTR_FIELD(scale_h)
398+
.describe("The upsampling factor for height");
399+
TVM_ATTR_FIELD(scale_w)
400+
.describe("The upsampling factor for width");
398401
TVM_ATTR_FIELD(layout).set_default("NCHW")
399402
.describe("Dimension ordering of input data. Can be 'NCHW', 'NHWC', etc."
400403
"'N', 'C', 'H', 'W' stands for batch, channel, height, and width"

nnvm/python/nnvm/to_relay.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ def _upsampling(children, attrs, odtype='float32'):
219219
method = attrs.get_str('method', 'NEAREST_NEIGHBOR')
220220
return op.nn.upsampling(
221221
children[0],
222-
scale=scale,
222+
scale_h=scale,
223+
scale_w=scale,
223224
layout=layout,
224225
method=method)
225226

python/tvm/relay/frontend/caffe2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def _impl(cls, inputs, args, params):
280280
assert width_scale == height_scale
281281

282282
return _op.nn.upsampling(
283-
inputs[0], scale=int(width_scale), method="NEAREST_NEIGHBOR")
283+
inputs[0], scale_h=int(width_scale), scale_w=int(width_scale), method="NEAREST_NEIGHBOR")
284284

285285

286286
class Sum(Caffe2OpConverter):

python/tvm/relay/frontend/coreml.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ def _UpsampleLayerParams(op, inexpr, etab):
313313
raise tvm.error.OpAttributeUnimplemented(
314314
'Upsample height and width must be equal.')
315315
interpolationMode = 'nearest_neighbor' if op.mode == 0 else 'bilinear'
316-
return _op.nn.upsampling(inexpr, scale=op.scalingFactor[0], method=interpolationMode)
316+
return _op.nn.upsampling(inexpr, scale_h=op.scalingFactor[0],
317+
scale_w=op.scalingFactor[1], method=interpolationMode)
317318

318319

319320
def _L2NormalizeLayerParams(op, inexpr, etab):

python/tvm/relay/frontend/darknet.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def _darknet_shortcut(inputs, params, attrs, prefix):
129129

130130
if input_0_size > input_1_size:
131131
scale = int(input_0_size/input_1_size)
132-
input_1 = get_relay_op('upsampling')(input_1, scale=scale)
132+
input_1 = get_relay_op('upsampling')(input_1, scale_h=scale, scale_w=scale)
133133

134134
elif input_0_size < input_1_size:
135135
stride = int(input_1_size/input_0_size)
@@ -196,7 +196,8 @@ def _darknet_reshape(inputs, params, attrs, prefix):
196196
def _darknet_upsampling(inputs, params, attrs, prefix):
197197
"""Process the upsampling operation."""
198198
new_attrs = {}
199-
new_attrs['scale'] = attrs.get('scale', 1)
199+
new_attrs['scale_h'] = attrs.get('scale', 1)
200+
new_attrs['scale_w'] = attrs.get('scale', 1)
200201
return get_relay_op('upsampling')(*inputs, **new_attrs)
201202

202203
def _darknet_l2normalize(inputs, params, attrs, prefix):

python/tvm/relay/frontend/keras.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,13 +398,14 @@ def _convert_upsample(inexpr, keras_layer, _):
398398
params = {}
399399
if upsample_type == 'UpSampling1D':
400400
h = keras_layer.size
401-
params['scale'] = h
401+
params['scale_h'] = h
402402
elif upsample_type == 'UpSampling2D':
403403
h, w = keras_layer.size
404404
if h != w:
405405
raise tvm.error.OpAttributeInvalid(
406406
'Height must equal width for operator Upsample.')
407-
params['scale'] = h
407+
params['scale_h'] = h
408+
params['scale_w'] = h
408409

409410
if hasattr(keras_layer, 'interpolation'):
410411
interpolation = keras_layer.interpolation
@@ -418,7 +419,8 @@ def _convert_upsample(inexpr, keras_layer, _):
418419
if h != w or w != d:
419420
raise tvm.error.OpAttributeInvalid(
420421
'Height, width, and depth must all be equal for operator Upsample.')
421-
params['scale'] = h
422+
params['scale_h'] = h
423+
params['scale_w'] = h
422424
else:
423425
raise tvm.error.OpNotImplemented(
424426
'Operator {} is not supported for frontend Keras.'.format(upsample_type))

python/tvm/relay/frontend/nnvm_common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def _transpose(inputs, attrs):
112112

113113
def _upsampling(inputs, attrs):
114114
scale = attrs.get_int("scale")
115-
return _op.nn.upsampling(inputs[0], scale=scale)
115+
return _op.nn.upsampling(inputs[0], scale_h=scale, scale_w=scale)
116116

117117

118118
def _elemwise_sum(inputs, _, _dtype='float32'):

python/tvm/relay/frontend/onnx.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ def _impl_v9(cls, inputs, attr, params):
581581
assert len(inputs) == 2, "Upsample op take 2 inputs, {} given".format(len(inputs))
582582
scales = params[inputs[1].name_hint].asnumpy()
583583
inputs = inputs[:1]
584-
assert len(scales) == 4 and scales[0] == 1.0 and scales[1] == 1.0 and scales[2] == scales[3]
584+
assert len(scales) == 4 and scales[0] == 1.0 and scales[1] == 1.0
585585
mode = attr.get('mode')
586586
if mode == b'nearest':
587587
method = "nearest_neighbor"
@@ -590,7 +590,8 @@ def _impl_v9(cls, inputs, attr, params):
590590
else:
591591
raise tvm.error.OpAttributeInvalid(
592592
'Value {} in attribute "mode" of operator Upsample is not valid.'.format(mode))
593-
attr = {'scale':int(scales[-1]), 'method':method, 'layout':'NCHW', 'align_corners':True}
593+
attr = {'scale_h':scales[-2], 'scale_w':scales[-1], 'method':method,
594+
'layout':'NCHW', 'align_corners':True}
594595
return AttrCvt('upsampling')(inputs, attr)
595596

596597

python/tvm/relay/op/nn/_nn.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,12 @@ def schedule_upsampling(_, outs, target):
409409

410410
@reg.register_compute("nn.upsampling")
411411
def compute_upsampling(attrs, inputs, out_dtype, target):
412-
scale = attrs.scale
412+
scale_h = attrs.scale_h
413+
scale_w = attrs.scale_w
413414
layout = attrs.layout
414415
method = attrs.method
415416
align_corners = attrs.align_corners
416-
return [topi.nn.upsampling(inputs[0], scale, layout, method, align_corners)]
417+
return [topi.nn.upsampling(inputs[0], scale_h, scale_w, layout, method, align_corners)]
417418

418419
# pad
419420
reg.register_schedule("nn.pad", schedule_broadcast)

0 commit comments

Comments
 (0)