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)
Example #3
0
    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))
Example #5
0
  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)
Example #6
0
 def test_is_sum_compatible_negative_examples(self, type_spec):
     self.assertFalse(type_utils.is_sum_compatible(type_spec))
Example #7
0
 def test_is_sum_compatible_positive_examples(self, type_spec):
     self.assertTrue(type_utils.is_sum_compatible(type_spec))