diff --git a/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py b/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py index 4122a757b..c4ab0ccc6 100644 --- a/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py +++ b/coremltools/converters/mil/mil/ops/defs/iOS15/elementwise_unary.py @@ -446,7 +446,18 @@ def type_inference(self): @precondition(allow=VALUE) def value_inference(self): - return np.asarray(np.reciprocal(self.x.val + self.epsilon.val)) + x_val = self.x.val + epsilon_val = self.epsilon.val + + # ✅ New check for unsupported int types + if np.issubdtype(x_val.dtype, np.integer): + raise ValueError( + f"CoreML 'inverse' op does not support integer types. " + f"Got input dtype: {x_val.dtype}. Please cast input to float32 or use float constants." + ) + + return np.asarray(np.reciprocal(x_val + epsilon_val)) + @register_op diff --git a/coremltools/test/test_inverse_conversion.py b/coremltools/test/test_inverse_conversion.py new file mode 100644 index 000000000..feb249991 --- /dev/null +++ b/coremltools/test/test_inverse_conversion.py @@ -0,0 +1,22 @@ +import torch +import torch.nn as nn +import coremltools as ct + +def test_inverse_with_int32_shape_input(): + class Model(nn.Module): + def forward(self, x): + return 16 / x.shape[0] # int32 division + + model = Model() + model.eval() # Make sure to silence the eval warning + inputs = (torch.randn(2, 3, 4),) + traced = torch.jit.trace(model, inputs) + + try: + ct.convert(traced, inputs=[ct.TensorType(shape=(2, 3, 4))], convert_to="mlprogram") + except ValueError as e: + error_str = str(e).lower() + assert "inverse" in error_str + assert any(keyword in error_str for keyword in ["int32", "integer"]) + else: + assert False, "Expected ValueError due to int32 input to inverse op"