def federated_sum(self, value): """Implements `federated_sum` as defined in `api/intrinsics.py`. Args: value: As in `api/intrinsics.py`. Returns: As in `api/intrinsics.py`. Raises: TypeError: As in `api/intrinsics.py`. """ value = value_impl.to_value(value, None, self._context_stack) type_utils.check_federated_value_placement(value, placements.CLIENTS, 'value to be summed') if not type_utils.is_sum_compatible(value.type_signature): raise TypeError( 'The value type {} is not compatible with the sum operator.'.format( str(value.type_signature))) # TODO(b/113112108): Replace this as noted above. result_type = computation_types.FederatedType(value.type_signature.member, placements.SERVER, True) intrinsic = value_impl.ValueImpl( computation_building_blocks.Intrinsic( intrinsic_defs.FEDERATED_SUM.uri, computation_types.FunctionType(value.type_signature, result_type)), self._context_stack) return intrinsic(value)
def _make_sequence_sum_for(type_spec): py_typecheck.check_type(type_spec, computation_types.SequenceType) if not type_utils.is_sum_compatible(type_spec.element): raise TypeError( 'The value type {} is not compatible with the sum operator.'.format( str(type_spec))) return value_impl.ValueImpl( computation_building_blocks.Intrinsic( intrinsic_defs.SEQUENCE_SUM.uri, computation_types.FunctionType(type_spec, type_spec.element)), self._context_stack)
def federated_sum(self, value): """Implements `federated_sum` as defined in `api/intrinsics.py`.""" value = value_impl.to_value(value, None, self._context_stack) value = value_utils.ensure_federated_value(value, placements.CLIENTS, 'value to be summed') if not type_utils.is_sum_compatible(value.type_signature): raise TypeError( 'The value type {} is not compatible with the sum operator.'. format(value.type_signature)) value = value_impl.ValueImpl.get_comp(value) comp = building_block_factory.create_federated_sum(value) return value_impl.ValueImpl(comp, self._context_stack)
def sequence_sum(self, value): """Implements `sequence_sum` as defined in `api/intrinsics.py`. Args: value: As in `api/intrinsics.py`. Returns: As in `api/intrinsics.py`. Raises: TypeError: As in `api/intrinsics.py`. """ value = value_impl.to_value(value, None, self._context_stack) if isinstance(value.type_signature, computation_types.SequenceType): element_type = value.type_signature.element else: py_typecheck.check_type(value.type_signature, computation_types.FederatedType) py_typecheck.check_type(value.type_signature.member, computation_types.SequenceType) element_type = value.type_signature.member.element if not type_utils.is_sum_compatible(element_type): raise TypeError( 'The value type {} is not compatible with the sum operator.'. format(value.type_signature.member)) if isinstance(value.type_signature, computation_types.SequenceType): value = value_impl.ValueImpl.get_comp(value) return computation_constructing_utils.create_sequence_sum(value) elif isinstance(value.type_signature, computation_types.FederatedType): intrinsic_type = computation_types.FunctionType( value.type_signature.member, value.type_signature.member.element) intrinsic = computation_building_blocks.Intrinsic( intrinsic_defs.SEQUENCE_SUM.uri, intrinsic_type) intrinsic_impl = value_impl.ValueImpl(intrinsic, self._context_stack) if value.type_signature.placement is placements.SERVER: return self.federated_apply(intrinsic_impl, value) elif value.type_signature.placement is placements.CLIENTS: return self.federated_map(intrinsic_impl, value) else: raise TypeError('Unsupported placement {}.'.format( value.type_signature.placement)) else: raise TypeError( 'Cannot apply `tff.sequence_sum()` to a value of type {}.'. format(value.type_signature))
def federated_sum(self, value): """Implements `federated_sum` as defined in `api/intrinsics.py`. Args: value: As in `api/intrinsics.py`. Returns: As in `api/intrinsics.py`. Raises: TypeError: As in `api/intrinsics.py`. """ value = value_impl.to_value(value, None, self._context_stack) type_utils.check_federated_value_placement(value, placements.CLIENTS, 'value to be summed') if not type_utils.is_sum_compatible(value.type_signature): raise TypeError( 'The value type {} is not compatible with the sum operator.'.format( value.type_signature)) value = value_impl.ValueImpl.get_comp(value) comp = computation_constructing_utils.create_federated_sum(value) return value_impl.ValueImpl(comp, self._context_stack)
def test_is_sum_compatible_negative_examples(self, type_spec): self.assertFalse(type_utils.is_sum_compatible(type_spec))
def test_is_sum_compatible_positive_examples(self, type_spec): self.assertTrue(type_utils.is_sum_compatible(type_spec))