41
41
42
42
__all__ = ['from_onnx' ]
43
43
44
-
45
44
class onnx_input ():
46
45
""" Dual purpose list or dictionary access object."""
47
46
def __init__ (self ):
@@ -127,7 +126,6 @@ def revert_caffe2_pad(pads):
127
126
raise tvm .error .OpAttributeInvalid ('Number of pads must be either 2 or 4.' )
128
127
return pads
129
128
130
-
131
129
def get_pad_pair (input1d , kernel1d , stride1d ):
132
130
"""infer pad size"""
133
131
if input1d % stride1d == 0 :
@@ -641,26 +639,22 @@ def _impl_v2(cls, inputs, attr, params):
641
639
642
640
@classmethod
643
641
def _impl_v11 (cls , inputs , attr , params ):
644
- pad_width = []
645
- pads = infer_value_simulated (inputs [1 ], params ).asnumpy ()
642
+ pads = inputs [1 ]
646
643
if len (inputs ) == 3 :
647
- value = infer_value_simulated (inputs [2 ], params ). asnumpy (). item ( )
644
+ value = _op . take (inputs [2 ], _op . const ( 0 ) )
648
645
else :
649
646
value = 0
650
- attr ["pad_value" ] = value
651
- dims = int (len (pads ) / 2 )
652
- for i in range (dims ):
653
- pad_width .append ((pads [i ], pads [i + dims ]))
654
- attr ['pad_width' ] = pad_width
647
+
648
+ pads_shape = infer_shape (pads )
649
+ dims = int (pads_shape [0 ] / 2 )
650
+ pad_width_expr = _op .transpose (_op .reshape (pads , (2 , dims )))
655
651
pad_mode = attr .get ('mode' , b'constant' ).decode ('utf-8' )
656
- if pad_mode in ['constant' , 'edge' , 'reflect' ]:
657
- attr ['pad_mode' ] = pad_mode
658
- attr .pop ('mode' , None )
659
- else :
652
+
653
+ if not pad_mode in ['constant' , 'edge' , 'reflect' ]:
660
654
raise tvm .error .OpAttributeInvalid ('Value ' + pad_mode +
661
655
' in attribute "mode" is invalid for operator Pad.' )
662
656
663
- return AttrCvt ( ' pad' ) (inputs [: 1 ], attr , params )
657
+ return _op . nn . pad (inputs [0 ], pad_width_expr , value , pad_mode = pad_mode )
664
658
665
659
666
660
class ParametricSoftPlus (OnnxOpConverter ):
@@ -868,17 +862,24 @@ class Upsample(OnnxOpConverter):
868
862
@classmethod
869
863
def _impl_v9 (cls , inputs , attr , params ):
870
864
scales = attr .get ('scales' )
865
+
866
+ input_shape = infer_shape (inputs [0 ])
867
+ dims = len (input_shape )
868
+
871
869
if not scales :
872
870
#Here we are going to higher OPSET version.
873
- assert len (inputs ) == 2 , "Upsample op take 2 inputs, {} given" .format (len (inputs ))
871
+ assert len (inputs ) == 2 , "Upsample op takes 2 inputs, {} given" .format (len (inputs ))
872
+
874
873
if get_name (inputs [1 ]) in params :
875
874
scales = params [inputs [1 ].name_hint ].asnumpy ()
876
- else :
875
+ elif dims == 5 :
877
876
scales = infer_value_simulated (inputs [1 ], params ).asnumpy ()
878
- inputs = inputs [:1 ]
879
- assert scales [0 ] == 1.0 and scales [1 ] == 1.0
880
- input_shape = infer_shape (inputs [0 ])
881
- dims = len (input_shape )
877
+ else :
878
+ scales = inputs [1 ]
879
+
880
+ if not isinstance (scales , Call ):
881
+ assert scales [0 ] == 1.0 and scales [1 ] == 1.0
882
+
882
883
mode = attr .get ('mode' )
883
884
if mode == b'nearest' :
884
885
method = "nearest_neighbor"
@@ -887,21 +888,31 @@ def _impl_v9(cls, inputs, attr, params):
887
888
else :
888
889
raise tvm .error .OpAttributeInvalid (
889
890
'Value {} in attribute "mode" of operator Upsample is not valid.' .format (mode ))
890
- attr = {'scale_h' : scales [- 2 ], 'scale_w' : scales [- 1 ], 'method' : method }
891
+
892
+ if method == 'nearest_neighbor' :
893
+ align_corners = False
894
+ else :
895
+ align_corners = True
896
+ # in 3d case, we use the purely static op
891
897
if dims == 5 :
892
- assert len (scales ) == 5
893
- attr ['scale_d' ] = scales [- 3 ]
894
- attr ['layout' ] = 'NCDHW'
895
- op_name = 'upsampling3d'
898
+ scale_h = scales [- 2 ]
899
+ scale_w = scales [- 1 ]
900
+ scale_d = scales [- 3 ]
901
+ layout = 'NCDHW'
902
+ return _op .nn .upsampling3d (inputs [0 ], scale_d , scale_h , scale_w ,
903
+ layout = layout , method = method )
904
+ # in 2d case, use dynamic op
896
905
else :
897
- assert len (scales ) == 4
898
- attr ['layout' ] = 'NCHW'
899
- if method == 'nearest_neighbor' :
900
- attr ['align_corners' ] = False
906
+ if isinstance (scales , Call ):
907
+ scale_h = _op .take (scales , _op .const (3 ))
908
+ scale_w = _op .take (scales , _op .const (4 ))
901
909
else :
902
- attr ['align_corners' ] = True
903
- op_name = 'upsampling'
904
- return AttrCvt (op_name )(inputs , attr )
910
+ assert len (scales ) == 4
911
+ scale_h = scales [- 2 ]
912
+ scale_w = scales [- 1 ]
913
+ layout = 'NCHW'
914
+
915
+ return _op .nn .upsampling (inputs [0 ], scale_h , scale_w , layout = layout , method = method , align_corners = align_corners )
905
916
906
917
907
918
class Shape (OnnxOpConverter ):
@@ -2289,3 +2300,5 @@ def from_onnx(model, shape=None, dtype="float32", opset=None, freeze_params=Fals
2289
2300
opset = 1
2290
2301
mod , params = g .from_onnx (graph , opset , freeze_params )
2291
2302
return mod , params
2303
+
2304
+
0 commit comments