Thanks for participating in the TVM community! We use https://discuss.tvm.ai for any general usage questions and discussions. The issue tracker is used for actionable items such as feature proposals discussion, roadmaps, and bug tracking. You are always welcomed to post on the forum first 😸
Issues that are inactive for a period of time may get closed. We adopt this policy so that we won't lose track of actionable issues that may fall at the bottom of the pile. Feel free to reopen a new one if you feel there is an additional problem that needs attention when an old one gets closed.
Hello everyone,
I am new here so I am not completely familiar with the way of communication here, but I will try to summarize my observations related to relay.squeeze functionality. This report may be a more comprehensive version of #11697, but also it contain additional scenario which is not related to that one.
relay.squeeze with argument axis=[]
Scenario 1.
Only relay.squeeze(axis=[])
def @main(%x: Tensor[(1, 1, 1, 1, 1, 2, 1, 3, 4, 5), float32]) { squeeze(%x, axis=[]) }
Expected behavior
Program should compile without errors.
Actual behavior
Program compile and the shape of the result tensor is the same as the input tensor shape.
Input tensor shape: (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)
Output tensor shape: (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)
Looks like parameter axis=[] does not change the shape of the relay.squeeze input tensor. (this is the assumption that may make problems later)
Scenario 2.
relay.squeeze(axis=[]) + relay.squeeze(axis=[...])
def @main(%x: Tensor[(1, 1, 1, 1, 1, 2, 1, 3, 4, 5), float32]) { %0 = squeeze(%x, axis=[]); squeeze(%0, axis=[0]) }
Expected behavior
Program should compile without errors as long as we send the appropriate parameters for the axis in second squeeze call. (for example using axis=[5] should be an error because dimension which is not equal to 1 could not be squeezed).
Actual behavior
Program does not compile, and there is 2 types of unexpected errors:
First one is obtained for parameter axis=[0], and the error message is:
TVMError:
An error occurred during the execution of TVM.
For more information, please see: https://tvm.apache.org/docs/errors.html
Check failed: GetConstInt(x->shape[val]) == 1 (2 vs. 1) : Dimension 0 must have size 1
Error of the same type is obtained using any of numbers 1, 2, 3 instead of 0 for the axis in previous example.
Second one is obtained for parameter axis=[4], and the error message is:
TVMError:
An error occurred during the execution of TVM.
For more information, please see: https://tvm.apache.org/docs/errors.html
Check failed: (0 <= i && i < p->size_) is false: IndexError: indexing 4 on an array of size 4
Error of the same type is also obtained using number 6 instead of 0 for the axis in previous example.
For other possible options for axis (which are 5, 7, 8 and 9) we get expected error since in input tensor those dimensions are not equal to 1.
From these error descriptions it looks like that using parameter axis=[] actually changes the shape of tensor internally (in CPP) in a same way as it will be when we send axis=None, but Python for some reason does not see this.
Scenario 3.
relay.squeeze(axis=[]) + relay.nn.bias_add
def @main(%x: Tensor[(1, 1, 1, 1, 5, 2, 1, 3, 4, 5), float32], %b: Tensor[(5), float32]) { %0 = squeeze(%x, axis=[]); nn.bias_add(%0, %b, axis=4) }
Expected behavior
Program should compile without errors as long as we send the appropriate parameters for the axis in bias_add call. (for example using axis=0 should be an error because corresponding dimension must be equal to the dimension of the tensor b which should be added).
Actual behavior
Program does not compile, and there is additional 2 types of unexpected errors:
First one is obtained for parameter axis=4, and the error message is:
TVMError:
An error occurred during the execution of TVM.
For more information, please see: https://tvm.apache.org/docs/errors.html
Check failed: ret == 0 (-1 vs. 0) : Assert fail: (5 == tir.tvm_struct_get(arg2, 0, 4)), arg2.ndim is expected to equal 5
Second one is obtained for parameter axis=9, and the error message is:
TVMError:
An error occurred during the execution of TVM.
For more information, please see: https://tvm.apache.org/docs/errors.html
Check failed: (num_newaxis >= 0) is false: expand_dims only accepts num_newaxis >= 0, but got num_newaxis = -5
For other possible options for axis (which are 0, 1, 2, 3, 5, 6, 7 and 8) we get expected error since in input tensor those dimensions are not equal to the shape of tensor b.
From these error descriptions it looks like that using parameter axis=[] actually changes the input tensor as it is described in Scenario 2.
relay.squeeze with argument axis=Constant
Scenario 1.
Using axis = Constant([]) instead of axis = [] will result with same errors described above, when used in the same scenario.
Scenario 2.
Using axis = Constant(2) where the argument of the Constant is tvm.nd.array created only using integer (in this example that integer is 2).
Expected behavior
Following code should pass without errors:
import numpy as np
import tvm
from tvm import relay, transform, cpu, IRModule
x_shape = (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)
x = relay.var('x', shape=x_shape)
arr = np.array(0)
ndarr = tvm.nd.array(arr)
const = relay.Constant(ndarr)
y = relay.squeeze(x, axis=const)
mod = IRModule.from_expr(y)
Actual behavior
Program does not compile with the following error:
Traceback (most recent call last):
File "/home/padre/TVM/Issues/Relay/Bugs/issue_with_relay_squeeze/relay_squeeze_test_constant.py", line 104, in <module>
y = relay.squeeze(x, axis=const)
File "/home/padre/TVM_full_repo/tvm/python/tvm/relay/op/transform.py", line 221, in squeeze
axis = list(axis.data.numpy())
TypeError: iteration over a 0-d array
Since the functionality of the tvm.nd.array is based on np.array, which could have dimension () and which in that case is not iterable, this scenario should be extra covered.
Environment
Ubuntu 20.04, TVM commit f5f5a75 compiled with LLVM support.
Steps to reproduce
Code may be the same as in #11697, just relay definition and corresponding GraphModule.run function should be changed according to the mentioned scenario.
Solution
All mentioned errors could be solved implementing few small changes in squeeze function defined inside python/tvm/relay/op/transform.py file.
1. change
Instead of:
if isinstance(axis, Constant):
axis = list(axis.data.numpy())
should be:
if isinstance(axis, Constant):
if axis.data.shape:
axis = list(axis.data.numpy())
else:
axis = [axis.data.numpy().item()]
Internal if statement could also be changed with try except block, depending on the speed.
2. change
Depending on the wanted functionality in front of the line:
return _make.squeeze(data, axis)
should stay (if using axis=[] should be same as using axis=None):
if not axis:
axis = None
or (if using axis=[] should not change the input tensor data):
if axis == []:
return data
Thanks for participating in the TVM community! We use https://discuss.tvm.ai for any general usage questions and discussions. The issue tracker is used for actionable items such as feature proposals discussion, roadmaps, and bug tracking. You are always welcomed to post on the forum first 😸
Issues that are inactive for a period of time may get closed. We adopt this policy so that we won't lose track of actionable issues that may fall at the bottom of the pile. Feel free to reopen a new one if you feel there is an additional problem that needs attention when an old one gets closed.
Hello everyone,
I am new here so I am not completely familiar with the way of communication here, but I will try to summarize my observations related to relay.squeeze functionality. This report may be a more comprehensive version of #11697, but also it contain additional scenario which is not related to that one.
relay.squeeze with argument
axis=[]Scenario 1.
Only relay.squeeze(axis=[])
def @main(%x: Tensor[(1, 1, 1, 1, 1, 2, 1, 3, 4, 5), float32]) { squeeze(%x, axis=[]) }Expected behavior
Program should compile without errors.
Actual behavior
Program compile and the shape of the result tensor is the same as the input tensor shape.
Input tensor shape: (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)Output tensor shape: (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)Looks like parameter
axis=[]does not change the shape of the relay.squeeze input tensor. (this is the assumption that may make problems later)Scenario 2.
relay.squeeze(axis=[]) + relay.squeeze(axis=[...])
def @main(%x: Tensor[(1, 1, 1, 1, 1, 2, 1, 3, 4, 5), float32]) { %0 = squeeze(%x, axis=[]); squeeze(%0, axis=[0]) }Expected behavior
Program should compile without errors as long as we send the appropriate parameters for the
axisin second squeeze call. (for example usingaxis=[5]should be an error because dimension which is not equal to 1 could not be squeezed).Actual behavior
Program does not compile, and there is 2 types of unexpected errors:
First one is obtained for parameter
axis=[0], and the error message is:TVMError:An error occurred during the execution of TVM.For more information, please see: https://tvm.apache.org/docs/errors.htmlCheck failed: GetConstInt(x->shape[val]) == 1 (2 vs. 1) : Dimension 0 must have size 1Error of the same type is obtained using any of numbers 1, 2, 3 instead of 0 for the
axisin previous example.Second one is obtained for parameter
axis=[4], and the error message is:TVMError:An error occurred during the execution of TVM.For more information, please see: https://tvm.apache.org/docs/errors.htmlCheck failed: (0 <= i && i < p->size_) is false: IndexError: indexing 4 on an array of size 4Error of the same type is also obtained using number 6 instead of 0 for the axis in previous example.
For other possible options for axis (which are 5, 7, 8 and 9) we get expected error since in input tensor those dimensions are not equal to 1.
From these error descriptions it looks like that using parameter
axis=[]actually changes the shape of tensor internally (in CPP) in a same way as it will be when we sendaxis=None, but Python for some reason does not see this.Scenario 3.
relay.squeeze(axis=[]) + relay.nn.bias_add
def @main(%x: Tensor[(1, 1, 1, 1, 5, 2, 1, 3, 4, 5), float32], %b: Tensor[(5), float32]) { %0 = squeeze(%x, axis=[]); nn.bias_add(%0, %b, axis=4) }Expected behavior
Program should compile without errors as long as we send the appropriate parameters for the
axisin bias_add call. (for example usingaxis=0should be an error because corresponding dimension must be equal to the dimension of the tensorbwhich should be added).Actual behavior
Program does not compile, and there is additional 2 types of unexpected errors:
First one is obtained for parameter
axis=4, and the error message is:TVMError:An error occurred during the execution of TVM.For more information, please see: https://tvm.apache.org/docs/errors.htmlCheck failed: ret == 0 (-1 vs. 0) : Assert fail: (5 == tir.tvm_struct_get(arg2, 0, 4)), arg2.ndim is expected to equal 5Second one is obtained for parameter
axis=9, and the error message is:TVMError:An error occurred during the execution of TVM.For more information, please see: https://tvm.apache.org/docs/errors.htmlCheck failed: (num_newaxis >= 0) is false: expand_dims only acceptsnum_newaxis >= 0, but got num_newaxis = -5For other possible options for axis (which are 0, 1, 2, 3, 5, 6, 7 and 8) we get expected error since in input tensor those dimensions are not equal to the shape of tensor
b.From these error descriptions it looks like that using parameter
axis=[]actually changes the input tensor as it is described in Scenario 2.relay.squeeze with argument
axis=ConstantScenario 1.
Using
axis = Constant([])instead ofaxis = []will result with same errors described above, when used in the same scenario.Scenario 2.
Using
axis = Constant(2)where the argument of theConstantistvm.nd.arraycreated only using integer (in this example that integer is 2).Expected behavior
Following code should pass without errors:
import numpy as npimport tvmfrom tvm import relay, transform, cpu, IRModulex_shape = (1, 1, 1, 1, 1, 2, 1, 3, 4, 5)x = relay.var('x', shape=x_shape)arr = np.array(0)ndarr = tvm.nd.array(arr)const = relay.Constant(ndarr)y = relay.squeeze(x, axis=const)mod = IRModule.from_expr(y)Actual behavior
Program does not compile with the following error:
Traceback (most recent call last):File "/home/padre/TVM/Issues/Relay/Bugs/issue_with_relay_squeeze/relay_squeeze_test_constant.py", line 104, in <module>y = relay.squeeze(x, axis=const)File "/home/padre/TVM_full_repo/tvm/python/tvm/relay/op/transform.py", line 221, in squeezeaxis = list(axis.data.numpy())TypeError: iteration over a 0-d arraySince the functionality of the
tvm.nd.arrayis based on np.array, which could have dimension()and which in that case is not iterable, this scenario should be extra covered.Environment
Ubuntu 20.04, TVM commit f5f5a75 compiled with LLVM support.
Steps to reproduce
Code may be the same as in #11697, just relay definition and corresponding GraphModule.run function should be changed according to the mentioned scenario.
Solution
All mentioned errors could be solved implementing few small changes in
squeezefunction defined insidepython/tvm/relay/op/transform.pyfile.1. change
Instead of:
if isinstance(axis, Constant):axis = list(axis.data.numpy())should be:
if isinstance(axis, Constant):if axis.data.shape:axis = list(axis.data.numpy())else:axis = [axis.data.numpy().item()]Internal if statement could also be changed with try except block, depending on the speed.
2. change
Depending on the wanted functionality in front of the line:
return _make.squeeze(data, axis)should stay (if using
axis=[]should be same as usingaxis=None):if not axis:axis = Noneor (if using
axis=[]should not change the input tensordata):if axis == []:return data