mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
Fix symbolic shape inference for faster_rcnn, mask_rcnn, yolov3 (#1867)
* Fix symbolic shape inference for faster_rcnn, mask_rcnn, yolov3 Force merge when --auto_merge, on symbolic dims which sympy cannot simplify Add symbolic inference for Resize opset 10 Add support for step != 1 in Slice Add support for computed dim in TopK Bug fixes in passing symbolic dims from subgraph Fix an outdate comment in Nuphar provider header
This commit is contained in:
parent
582a27f546
commit
80bda77203
3 changed files with 33 additions and 11 deletions
2
cmake/external/tvm
vendored
2
cmake/external/tvm
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 638d7d2407de27f98f542f61a37a33c90a2e75a9
|
||||
Subproject commit 2ad9c02cdcca2d78237e0a90f1f324383452511e
|
||||
|
|
@ -8,7 +8,7 @@ extern "C" {
|
|||
#endif
|
||||
/**
|
||||
* \param device_id nuphar device id, starts from zero.
|
||||
* \param target_str TVM target string.
|
||||
* \param settings_str Nuphar settings string.
|
||||
*/
|
||||
ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Nuphar, _In_ OrtSessionOptions* options, int allow_unaligned_buffers, _In_ const char* settings_str);
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ class SymbolicShapeInference:
|
|||
'Range' : self._infer_Range,
|
||||
'ReduceProd' : self._infer_ReduceProd,
|
||||
'Reshape' : self._infer_Reshape,
|
||||
'Resize' : self._infer_Resize,
|
||||
'Round' : self._pass_on_shape_and_type,
|
||||
'Scan' : self._infer_Scan,
|
||||
'Shape' : self._infer_Shape,
|
||||
|
|
@ -113,7 +114,9 @@ class SymbolicShapeInference:
|
|||
if type(self.symbolic_dims_[s]) == sympy.Symbol:
|
||||
map_to = s
|
||||
if not map_to:
|
||||
raise Exception('Cannot merge between symbolic expressions: ({}), please modify model input dims to avoid this!'.format(','.join(symbols)))
|
||||
if self.verbose_ > 0:
|
||||
print('Potential unsafe merge between symbolic expressions: ({})'.format(','.join(symbols)))
|
||||
map_to = symbols.pop() # force merge when unable to determine
|
||||
for s in symbols:
|
||||
if s == map_to:
|
||||
continue
|
||||
|
|
@ -307,7 +310,7 @@ class SymbolicShapeInference:
|
|||
# for new symbolic dims from subgraph output, add to main graph symbolic dims
|
||||
subgraph_shapes = [get_shape_from_type_proto(o.type) for o in symbolic_shape_inference.out_mp_.graph.output]
|
||||
subgraph_new_symbolic_dims = set([d for s in subgraph_shapes if s for d in s if type(d) == str and not d in self.symbolic_dims_])
|
||||
self.symbolic_dims_.update({d:symbolic_shape_inference[d] for d in subgraph_new_symbolic_dims})
|
||||
self.symbolic_dims_.update({d:symbolic_shape_inference.symbolic_dims_[d] for d in subgraph_new_symbolic_dims})
|
||||
|
||||
def _get_int_values(self, node, broadcast=False):
|
||||
values = [self._try_get_value(node, i) for i in range(len(node.input))]
|
||||
|
|
@ -510,7 +513,7 @@ class SymbolicShapeInference:
|
|||
vi.type.tensor_type.elem_type,
|
||||
data_shape[:axis] + indices_shape + data_shape[axis+1:]))
|
||||
if node.input[0] in self.sympy_data_:
|
||||
assert 0 == get_attribute(node, 'axis') # only handle 1D sympy compute
|
||||
assert 0 == get_attribute(node, 'axis', 0) # only handle 1D sympy compute
|
||||
idx = self._get_value(node, 1)
|
||||
data = self.sympy_data_[node.input[0]]
|
||||
if type(data) == list:
|
||||
|
|
@ -650,6 +653,16 @@ class SymbolicShapeInference:
|
|||
get_shape_from_sympy_shape(new_sympy_shape)))
|
||||
self._pass_on_sympy_data(node)
|
||||
|
||||
def _infer_Resize(self, node):
|
||||
assert get_opset(self.out_mp_) <= 10 # only support opset 10 Resize for now
|
||||
scales = self._try_get_value(node, 1)
|
||||
if scales is not None:
|
||||
input_sympy_shape = self._get_sympy_shape(node, 0)
|
||||
new_sympy_shape = [sympy.simplify(sympy.floor(d*s)) for d,s in zip(input_sympy_shape, scales)]
|
||||
self._update_computed_dims(new_sympy_shape)
|
||||
vi = self.known_vi_[node.output[0]]
|
||||
vi.CopyFrom(helper.make_tensor_value_info(node.output[0], self.known_vi_[node.input[0]].type.tensor_type.elem_type, get_shape_from_sympy_shape(new_sympy_shape)))
|
||||
|
||||
def _infer_Scan(self, node):
|
||||
subgraph = get_attribute(node, 'body')
|
||||
num_scan_inputs = get_attribute(node, 'num_scan_inputs')
|
||||
|
|
@ -713,12 +726,12 @@ class SymbolicShapeInference:
|
|||
new_shape[i] = self._new_symbolic_dim_from_output(node,0,i)
|
||||
else:
|
||||
for i,s,e,t in zip(axes, starts, ends, steps):
|
||||
# TODO: handle step
|
||||
assert t == 1
|
||||
idx = handle_negative_axis(i, len(new_shape))
|
||||
if is_literal(e):
|
||||
if e >= int(2 ** 31 - 1): # max value of int32
|
||||
e = new_shape[i]
|
||||
elif e <= -int(2 ** 31): # min value of int32
|
||||
e = 0
|
||||
elif is_literal(new_shape[i]):
|
||||
e = min(e, new_shape[i])
|
||||
else:
|
||||
|
|
@ -740,7 +753,7 @@ class SymbolicShapeInference:
|
|||
if is_literal(s) and int(s) < 0:
|
||||
s = new_shape[i] + s
|
||||
|
||||
new_shape[idx] = e - s
|
||||
new_shape[idx] = (e - s + (-1 if t > 0 else 1)) // t + 1
|
||||
|
||||
self._update_computed_dims(new_shape)
|
||||
new_shape = get_shape_from_sympy_shape(new_shape)
|
||||
|
|
@ -787,18 +800,26 @@ class SymbolicShapeInference:
|
|||
|
||||
def _infer_TopK(self, node):
|
||||
rank = self._get_shape_rank(node, 0)
|
||||
axis = handle_negative_axis(get_attribute(node, 'axis'), rank)
|
||||
axis = handle_negative_axis(get_attribute(node, 'axis', -1), rank)
|
||||
new_shape = self._get_shape(node, 0)
|
||||
|
||||
if get_opset(self.out_mp_) <= 9:
|
||||
k = get_attribute(node, 'k')
|
||||
else:
|
||||
k = self._try_get_value(node, 1)
|
||||
k = self._get_int_values(node)[1]
|
||||
|
||||
if k == None:
|
||||
k = self._new_symbolic_dim_from_output(node)
|
||||
else:
|
||||
k = as_scalar(k)
|
||||
|
||||
new_shape[axis] = k
|
||||
if type(k) in [int, str]:
|
||||
new_shape[axis] = k
|
||||
else:
|
||||
new_sympy_shape = self._get_sympy_shape(node, 0)
|
||||
new_sympy_shape[axis] = k
|
||||
self._update_computed_dims(new_sympy_shape) # note that TopK dim could be computed in sympy_data, so need to update computed_dims when it enters shape
|
||||
new_shape = get_shape_from_sympy_shape(new_sympy_shape)
|
||||
|
||||
for i_o in range(len(node.output)):
|
||||
vi = self.known_vi_[node.output[i_o]]
|
||||
|
|
@ -874,6 +895,7 @@ class SymbolicShapeInference:
|
|||
|
||||
if self.verbose_ > 0 or not self.auto_merge_ or out_type_undefined:
|
||||
print('Stopping at incomplete shape inference at ' + node.op_type + ': ' + node.name)
|
||||
print(node)
|
||||
print('node inputs:')
|
||||
for i in node.input:
|
||||
print(self.known_vi_[i])
|
||||
|
|
|
|||
Loading…
Reference in a new issue