in coremltools/converters/onnx/_operators.py [0:0]
def _get_conv_params(builder, node, graph, err, params_dict, axis=None):
if "dilations" not in node.attrs:
params_dict["dilations"] = [1, 1]
else:
if axis == "height":
params_dict["dilations"] = node.attrs["dilations"]
params_dict["dilations"].append(1)
elif axis == "width":
params_dict["dilations"] = node.attrs["dilations"]
params_dict["dilations"].insert(0, 1)
else:
params_dict["dilations"] = node.attrs["dilations"]
if "pads" not in node.attrs:
params_dict["pads"] = [0, 0, 0, 0]
else:
pads = node.attrs["pads"]
if axis == "height":
pads = [pads[0], 0, pads[1], 0]
elif axis == "width":
pads = [0, pads[0], 0, pads[1]]
params_dict["pads"] = pads
if "kernel_shape" in node.attrs:
params_dict["kernel_shape"] = node.attrs["kernel_shape"]
else:
# w_shape is ONNX format shape
w_shape = params_dict["w_shape"]
if len(w_shape) == 4:
params_dict["kernel_shape"] = [w_shape[-2], w_shape[-1]]
else:
params_dict["kernel_shape"] = [w_shape[-1]]
params_dict["strides"] = node.attrs.get("strides", [1, 1] if axis is None else [1])
if axis == "height":
if params_dict["W"] is not None:
params_dict["W"] = np.expand_dims(params_dict["W"], axis=-1)
params_dict["kernel_shape"].append(1)
params_dict["strides"].append(1)
elif axis == "width":
if params_dict["W"] is not None:
params_dict["W"] = np.expand_dims(params_dict["W"], axis=-2)
params_dict["strides"].insert(0, 1)
params_dict["kernel_shape"].insert(0, 1)
params_dict["out_shape"] = None
params_dict["padding_type"] = "valid"
params_dict["same_padding_asymmetry_mode"] = "BOTTOM_RIGHT_HEAVY"
if params_dict["W"] is not None:
if not params_dict["is_deconv"]:
params_dict["W"] = params_dict["W"].transpose((2, 3, 1, 0)) # type: ignore
else:
params_dict["W"] = params_dict["W"].transpose((2, 3, 0, 1)) # type: ignore
if "auto_pad" in node.attrs and \
not (_compare(node.attrs["auto_pad"], 'VALID') or _compare(node.attrs["auto_pad"], 'NOTSET')):
params_dict["padding_type"] = "same"
if _compare(node.attrs["auto_pad"], "SAME_LOWER"):
params_dict["same_padding_asymmetry_mode"] = "TOP_LEFT_HEAVY"
if params_dict["is_deconv"]:
if "output_shape" in node.attrs:
if axis == "height":
params_dict["out_shape"] = (
node.attrs["output_shape"][-1],
1,
) # (Hout, wout)
elif axis == "width":
params_dict["out_shape"] = (
1,
node.attrs["output_shape"][-1],
) # (Hout, wout)
else:
params_dict["out_shape"] = (
node.attrs["output_shape"][-2],
node.attrs["output_shape"][-1],
) # (Hout, wout)
elif "output_padding" in node.attrs:
params_dict["crops"] = copy.copy(params_dict["pads"])
params_dict["pads"] = [0, 0, 0, 0]
post_pads = node.attrs["output_padding"]
if sum(post_pads) != 0:
t = l = b = r = 0
if len(post_pads) == 1:
if axis == "height":
b = post_pads[0]
elif axis == "width":
r = post_pads[0]
else:
err.unsupported_op_configuration(
builder,
node,
graph,
"length 1 output padding attribute only supported for 1D conv",
)
elif len(post_pads) == 2:
if axis == "height":
b, r = post_pads
elif axis == "width":
r, b = post_pads
else:
b, r = post_pads
elif len(post_pads) == 4:
b, r, t, l = post_pads
else:
return err.unsupported_op_configuration(
builder,
node,
graph,
"Supports only length 1 or 2 or 4 output padding attribute",
)
def _update_crop_pad(idx, v):
if params_dict["crops"][idx] >= v:
params_dict["crops"][idx] -= v
else:
params_dict["pads"][idx] = v - params_dict["crops"][idx]
_update_crop_pad(0, t)
_update_crop_pad(1, l)
_update_crop_pad(2, b)
_update_crop_pad(3, r)
params_dict["is_post_crop"] = (
True if sum(params_dict["crops"]) > 0 else False
)
params_dict["is_pre_pad"] = (
True if sum(params_dict["pads"]) > 0 else False
)