.. _l-onnx-doc-CastLike: ======== CastLike ======== .. contents:: :local: .. _l-onnx-op-castlike-15: 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** :: 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, )