CastLike#
CastLike - 15#
Version
name: CastLike (GitHub)
domain: main
since_version: 15
function: False
support_level: SupportType.COMMON
shape inference: True
This version of the operator has been available since version 15.
Summary
The operator casts the elements of a given input tensor (the first input) to the same data type as the elements of the second input tensor. See documentation of the Cast operator for further details.
Inputs
input (heterogeneous) - T1: Input tensor to be cast.
target_type (heterogeneous) - T2: The (first) input tensor will be cast to produce a tensor of the same type as this (second input) tensor.
Outputs
output (heterogeneous) - T2: Output tensor produced by casting the first input tensor to have the same type as the second input tensor.
Type Constraints
T1 in ( tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain input types. Casting from complex is not supported.
T2 in ( tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8) ): Constrain output types. Casting to complex is not supported.
Examples
default
import numpy as np
import onnx
shape = (3, 4)
test_cases = [
("FLOAT", "FLOAT16"),
("FLOAT", "DOUBLE"),
("FLOAT16", "FLOAT"),
("FLOAT16", "DOUBLE"),
("DOUBLE", "FLOAT"),
("DOUBLE", "FLOAT16"),
("FLOAT", "STRING"),
("STRING", "FLOAT"),
("FLOAT", "BFLOAT16"),
("BFLOAT16", "FLOAT"),
]
for from_type, to_type in test_cases:
input_type_proto = None
output_type_proto = None
if "BFLOAT16" == from_type or "BFLOAT16" == to_type:
np_fp32 = np.array(
[
"0.47892547",
"0.48033667",
"0.49968487",
"0.81910545",
"0.47031248",
"0.816468",
"0.21087195",
"0.7229038",
"NaN",
"INF",
"+INF",
"-INF",
],
dtype=np.float32,
)
little_endisan = sys.byteorder == "little"
np_uint16_view = np_fp32.view(dtype=np.uint16)
np_bfp16 = (
np_uint16_view[1::2] if little_endisan else np_uint16_view[0::2]
)
if "BFLOAT16" == to_type:
assert from_type == "FLOAT"
input = np_fp32.reshape([3, 4])
output = np_bfp16.reshape([3, 4])
input_type_proto = onnx.helper.make_tensor_type_proto(
int(TensorProto.FLOAT), input.shape
)
output_type_proto = onnx.helper.make_tensor_type_proto(
int(TensorProto.BFLOAT16), output.shape
)
else:
assert to_type == "FLOAT"
input = np_bfp16.reshape([3, 4])
# convert bfloat to FLOAT
np_fp32_zeros = np.zeros((len(np_bfp16) * 2,), dtype=np.uint16)
if little_endisan:
np_fp32_zeros[1::2] = np_bfp16
else:
np_fp32_zeros[0::2] = np_bfp16
np_fp32_from_bfloat = np_fp32_zeros.view(dtype=np.float32)
output = np_fp32_from_bfloat.reshape([3, 4])
input_type_proto = onnx.helper.make_tensor_type_proto(
int(TensorProto.BFLOAT16), input.shape
)
output_type_proto = onnx.helper.make_tensor_type_proto(
int(TensorProto.FLOAT), output.shape
)
elif "STRING" != from_type:
input = np.random.random_sample(shape).astype(
helper.tensor_dtype_to_np_dtype(getattr(TensorProto, from_type))
)
if "STRING" == to_type:
# Converting input to str, then give it np.object dtype for generating script
ss = []
for i in input.flatten():
s = str(i).encode("utf-8")
su = s.decode("utf-8")
ss.append(su)
output = np.array(ss).astype(np.object).reshape([3, 4])
else:
output = input.astype(
helper.tensor_dtype_to_np_dtype(getattr(TensorProto, to_type))
)
else:
input = np.array(
[
"0.47892547",
"0.48033667",
"0.49968487",
"0.81910545",
"0.47031248",
"0.816468",
"0.21087195",
"0.7229038",
"NaN",
"INF",
"+INF",
"-INF",
],
dtype=np.dtype(np.object),
).reshape([3, 4])
output = input.astype(
helper.tensor_dtype_to_np_dtype(getattr(TensorProto, to_type))
)
like = output.flatten()[0:1]
node = onnx.helper.make_node(
"CastLike",
inputs=["input", "like"],
outputs=["output"],
)
if input_type_proto and output_type_proto:
expect(
node,
inputs=[input, like],
outputs=[output],
name="test_castlike_" + from_type + "_to_" + to_type,
input_type_protos=[input_type_proto, output_type_proto],
output_type_protos=[output_type_proto],
)
else:
expect(
node,
inputs=[input, like],
outputs=[output],
name="test_castlike_" + from_type + "_to_" + to_type,
)