Hello! Thank you for updating coremltools!
While converting my PyTorch model, I got Dimension mismatch error, and I found one parameter, which is then going to be output_size , somehow turn into negative value.
I'll show the exact point below. I tried logging as discussed in #818.
What is the problem?
=node= %1497 = floor[](%1496)
<class 'coremltools.converters.mil.mil.var.Var'>
lnegth 1
input_value [128]
which_derived_from %1496: (1,i8)*(Tensor) = const(val=[128], name="1496")
===Converting op 1497 : floor : shape = (1,) ===
=node= %1498 = int[](%1497)
<class 'coremltools.converters.mil.mil.var.Var'>
lnegth 1
input_value [-128]
which_derived_from %1497: (1,i8)*(Tensor) = floor(x=%1496, name="1497")
===Converting op 1498 : int : shape = (1,) ===
Thank you for your help in advance.
Just curious, does the bug go away if you change the data type from int8 to int32? I mean, the issue is with a
(1,i8)*(Tensor)
int8 tensor.
PS: Also note that PyTorch 1.6.0 doesn't like floor() on int8 or int32. Try
import torch
dummy_input = torch.tensor((126,127,-127,-128),dtype=torch.int8)
print ( torch.floor(dummy_input ))
which gives:
RuntimeError: floor_vml_cpu not implemented for 'Char'
or, RuntimeError: floor_vml_cpu not implemented for 'Int', with dtype=torch.int32
@leovinus2001 Thank you for your help!
You're right. Operating floor on int8 is strange. I should have noticed it.
As for my situation, the problem is found to be from the op to (coremltools/coremltools/converters/mil/frontend/torch/ops.py).
In my case, lin(inputs)==5 but the number deciding dtype is not from inputs[2] but inputs[1].
I suppose that because inputs[2] == False, dtype was set to 0, which means uint8, and this caused the problem.
So, I changed to op as below and it worked.
@register_torch_op
def to(context, node):
# @non_blocking and @copy are unused
inputs = _get_inputs(context, node)
if len(inputs) == 6:
_input = inputs[0]
device = inputs[1]
dtype = inputs[2].val
# non_blocking = inputs[3]
# copy = inputs[4]
# memory_format = inputs[5] # usually None
elif len(inputs) == 5:
_input = inputs[0]
#============here=======================
#dtype = inputs[2].val
dtype = inputs[1].val
#======================================
# non_blocking = inputs[3]
# copy = inputs[4]
elif len(inputs) == 4:
_input = inputs[0]
dtype = inputs[1].val
# non_blocking = inputs[2]
# copy = inputs[3]
elif len(inputs) == 3:
# Since @non_blocking and @copy are unused, add back to context
_input = inputs[0]
# non_blocking = inputs[1]
# copy = inputs[2]
context.add(_input, torch_name=node.name)
return
else:
raise ValueError(
"Received invalid arguments for PyTorch conversion of op {}".format(node)
)
torch_dtype = NUM_TO_TORCH_DTYPE[dtype]
if isinstance(_input, Var):
_input = _input.val
# numpy -> torch -> torch cast -> numpy
# This path is needed to use the mapping of passed in dtypes to torch dtypes.
casted_input = torch.tensor(_input).type(torch_dtype).numpy()
const = mb.const(mode="immediate_value", val=casted_input, name=node.name)
context.add(const)
Great to hear that you found a working solution. There were a few other reports of shape with negative dimensions, like #751 #739 where they see (1, 32, -128, -128), and we could wonder whether there is a coremltools root cause that could be fixed.
@mushipand Can i ask you how did you modify logging to output 'input_value' and 'which_derived_from'?
@shiron8bit I am so sorry for the late reply.
I got those information by myinputs[i].val /myinputs[i].op respectively, where myinputs = _get_inputs(context, node).
(FYI, myinputs[i].val fails when myinputs[I] is NoneType object.)
You may know but there is a great discussion about logging at #818 .
Most helpful comment
@shiron8bit I am so sorry for the late reply.
I got those information by
myinputs[i].val/myinputs[i].oprespectively, wheremyinputs = _get_inputs(context, node).(FYI,
myinputs[i].valfails whenmyinputs[I]is NoneType object.)You may know but there is a great discussion about logging at #818 .