def serialize_value(value, type_spec=None): """Serializes a value into `executor_pb2.Value`. Args: value: A value to be serialized. type_spec: Optional type spec, a `tff.Type` or something convertible to it. Returns: An instance of `executor_pb2.Value` with the serialized content of `value`. Returns: TypeError: If the arguments are of the wrong types. ValueError: If the value is malformed. """ type_spec = computation_types.to_type(type_spec) if isinstance(value, computation_pb2.Computation): if type_spec is not None: type_utils.reconcile_value_type_with_type_spec( type_serialization.deserialize_type(value.type), type_spec) return executor_pb2.Value(computation=value) elif isinstance(value, computation_impl.ComputationImpl): return serialize_value( computation_impl.ComputationImpl.get_proto(value), type_utils.reconcile_value_with_type_spec(value, type_spec)) elif isinstance(type_spec, computation_types.TensorType): return serialize_tensor_value(value, type_spec) else: raise ValueError( 'Unable to serialize value with Python type {} and {} TFF type.'. format(str(py_typecheck.type_string(type(value))), str(type_spec) if type_spec is not None else 'unknown'))
def test_reconcile_value_type_with_type_spec_raises_type_error_value_type_and_bad_type_spec( self): value_type = computation_types.TensorType(tf.int32) type_spec = computation_types.TensorType(tf.string) with self.assertRaises(TypeError): type_utils.reconcile_value_type_with_type_spec( value_type, type_spec)
def test_reconcile_value_type_with_type_spec(self): self.assertEqual( str(type_utils.reconcile_value_type_with_type_spec(tf.int32, tf.int32)), 'int32') self.assertEqual( str(type_utils.reconcile_value_type_with_type_spec(tf.int32, None)), 'int32') with self.assertRaises(TypeError): type_utils.reconcile_value_type_with_type_spec(tf.int32, tf.bool)
def _serialize_computation( comp: computation_pb2.Computation, type_spec: Optional[computation_types.Type]) -> _SerializeReturnType: """Serializes a TFF computation.""" type_spec = type_utils.reconcile_value_type_with_type_spec( type_serialization.deserialize_type(comp.type), type_spec) return executor_pb2.Value(computation=comp), type_spec
def serialize_value(value, type_spec=None): """Serializes a value into `executor_pb2.Value`. Args: value: A value to be serialized. type_spec: Optional type spec, a `tff.Type` or something convertible to it. Returns: A tuple `(value_proto, ret_type_spec)` where `value_proto` is an instance of `executor_pb2.Value` with the serialized content of `value`, and the returned `ret_type_spec` is an instance of `tff.Type` that represents the TFF type of the serialized value. Raises: TypeError: If the arguments are of the wrong types. ValueError: If the value is malformed. """ type_spec = computation_types.to_type(type_spec) if isinstance(value, computation_pb2.Computation): type_spec = type_utils.reconcile_value_type_with_type_spec( type_serialization.deserialize_type(value.type), type_spec) return executor_pb2.Value(computation=value), type_spec elif isinstance(value, computation_impl.ComputationImpl): return serialize_value( computation_impl.ComputationImpl.get_proto(value), type_utils.reconcile_value_with_type_spec(value, type_spec)) elif isinstance(type_spec, computation_types.TensorType): return serialize_tensor_value(value, type_spec) elif isinstance(type_spec, computation_types.NamedTupleType): type_elements = anonymous_tuple.to_elements(type_spec) val_elements = anonymous_tuple.to_elements( anonymous_tuple.from_container(value)) tup_elems = [] for (e_name, e_type), (_, e_val) in zip(type_elements, val_elements): e_proto, _ = serialize_value(e_val, e_type) tup_elems.append( executor_pb2.Value.Tuple.Element( name=e_name if e_name else None, value=e_proto)) result_proto = (executor_pb2.Value(tuple=executor_pb2.Value.Tuple( element=tup_elems))) return result_proto, type_spec else: raise ValueError( 'Unable to serialize value with Python type {} and {} TFF type.'. format(str(py_typecheck.type_string(type(value))), str(type_spec) if type_spec is not None else 'unknown'))
def serialize_value(value, type_spec=None): """Serializes a value into `executor_pb2.Value`. Args: value: A value to be serialized. type_spec: Optional type spec, a `tff.Type` or something convertible to it. Returns: A tuple `(value_proto, ret_type_spec)` where `value_proto` is an instance of `executor_pb2.Value` with the serialized content of `value`, and the returned `ret_type_spec` is an instance of `tff.Type` that represents the TFF type of the serialized value. Raises: TypeError: If the arguments are of the wrong types. ValueError: If the value is malformed. """ type_spec = computation_types.to_type(type_spec) if isinstance(value, computation_pb2.Computation): type_spec = type_utils.reconcile_value_type_with_type_spec( type_serialization.deserialize_type(value.type), type_spec) return executor_pb2.Value(computation=value), type_spec elif isinstance(value, computation_impl.ComputationImpl): return serialize_value( computation_impl.ComputationImpl.get_proto(value), type_utils.reconcile_value_with_type_spec(value, type_spec)) elif isinstance(type_spec, computation_types.TensorType): return serialize_tensor_value(value, type_spec) elif isinstance(type_spec, computation_types.NamedTupleType): type_elements = anonymous_tuple.to_elements(type_spec) val_elements = anonymous_tuple.to_elements( anonymous_tuple.from_container(value)) tup_elems = [] for (e_name, e_type), (_, e_val) in zip(type_elements, val_elements): e_proto, _ = serialize_value(e_val, e_type) tup_elems.append( executor_pb2.Value.Tuple.Element( name=e_name if e_name else None, value=e_proto)) result_proto = (executor_pb2.Value(tuple=executor_pb2.Value.Tuple( element=tup_elems))) return result_proto, type_spec elif isinstance(type_spec, computation_types.SequenceType): if not isinstance(value, type_conversions.TF_DATASET_REPRESENTATION_TYPES): raise TypeError( 'Cannot serialize Python type {!s} as TFF type {!s}.'.format( py_typecheck.type_string(type(value)), type_spec if type_spec is not None else 'unknown')) value_type = computation_types.SequenceType( computation_types.to_type(value.element_spec)) if not type_analysis.is_assignable_from(type_spec, value_type): raise TypeError( 'Cannot serialize dataset with elements of type {!s} as TFF type {!s}.' .format(value_type, type_spec if type_spec is not None else 'unknown')) return serialize_sequence_value(value), type_spec elif isinstance(type_spec, computation_types.FederatedType): if type_spec.all_equal: value = [value] else: py_typecheck.check_type(value, list) items = [] for v in value: it, it_type = serialize_value(v, type_spec.member) type_analysis.check_assignable_from(type_spec.member, it_type) items.append(it) result_proto = executor_pb2.Value( federated=executor_pb2.Value.Federated( type=type_serialization.serialize_type(type_spec).federated, value=items)) return result_proto, type_spec else: raise ValueError( 'Unable to serialize value with Python type {} and {} TFF type.'. format(str(py_typecheck.type_string(type(value))), str(type_spec) if type_spec is not None else 'unknown'))
def test_reconcile_value_type_with_type_spec_returns_type( self, value_type, type_spec, expected_type): actual_type = type_utils.reconcile_value_type_with_type_spec( value_type, type_spec) self.assertEqual(actual_type, expected_type)