コード例 #1
0
def _create_next_with_fake_client_output(tree):
    """Creates a next computation with a fake client output.

  This function is intended to be used by
  `get_canonical_form_for_iterative_process` to create a next computation with
  a fake client output when no client output is returned by the `next` function
  of the `tff.utils.IterativeProcess`.

  NOTE: This function does not assert that there is no client output in `tree`,
  the caller is expected to perform this check before calling this function.

  Args:
    tree: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A new `building_blocks.ComputationBuildingBlock` representing a next
    computaiton with a fake client output.
  """
    if isinstance(tree.result, building_blocks.Tuple):
        arg_1 = tree.result[0]
        arg_2 = tree.result[1]
    else:
        arg_1 = building_blocks.Selection(tree.result, index=0)
        arg_2 = building_blocks.Selection(tree.result, index=1)

    empty_tuple = building_blocks.Tuple([])
    client_output = building_block_factory.create_federated_value(
        empty_tuple, placements.CLIENTS)
    output = building_blocks.Tuple([arg_1, arg_2, client_output])
    return building_blocks.Lambda(tree.parameter_name, tree.parameter_type,
                                  output)
コード例 #2
0
def federated_value(value, placement):
  """Returns a federated value at `placement`, with `value` as the constituent.

  Deprecation warning: Using `tff.federated_value` with arguments other than
  simple Python constants is deprecated. When placing the result of a
  `tf_computation`, prefer `tff.federated_eval`.

  Args:
    value: A value of a non-federated TFF type to be placed.
    placement: The desired result placement (either `tff.SERVER` or
      `tff.CLIENTS`).

  Returns:
    A federated value with the given placement `placement`, and the member
    constituent `value` equal at all locations.

  Raises:
    TypeError: If the arguments are not of the appropriate types.
  """
  if isinstance(value, value_impl.Value):
    warnings.warn(
        'Deprecation warning: Using `tff.federated_value` with arguments '
        'other than simple Python constants is deprecated. When placing the '
        'result of a `tf_computation`, prefer `tff.federated_eval`.',
        DeprecationWarning)
  value = value_impl.to_value(value, None)
  if type_analysis.contains(value.type_signature, lambda t: t.is_federated()):
    raise TypeError('Cannot place value {} containing federated types at '
                    'another placement; requested to be placed at {}.'.format(
                        value, placement))

  comp = building_block_factory.create_federated_value(value.comp, placement)
  comp = _bind_comp_as_reference(comp)
  return value_impl.Value(comp)
コード例 #3
0
  def federated_secure_modular_sum(arg):
    py_typecheck.check_type(arg, building_blocks.ComputationBuildingBlock)
    arg.type_signature.check_struct()
    if arg.type_signature.is_struct_with_python():
      container_type = arg.type_signature.python_container
    else:
      container_type = None
    summand_arg = building_blocks.Selection(arg, index=0)
    raw_summed_values = building_block_factory.create_federated_sum(summand_arg)

    unplaced_modulus = building_blocks.Selection(arg, index=1)
    placed_modulus = building_block_factory.create_federated_value(
        unplaced_modulus, placements.SERVER)
    modulus_arg = building_block_factory.create_federated_zip(
        building_blocks.Struct([raw_summed_values, placed_modulus],
                               container_type=container_type))

    def map_structure_mod(summed_values, modulus):
      modulus = _ensure_structure(modulus, unplaced_modulus.type_signature,
                                  raw_summed_values.type_signature.member)
      return structure.map_structure(tf.math.mod, summed_values, modulus)

    modulus_fn = building_block_factory.create_tensorflow_binary_operator(
        map_structure_mod,
        operand_type=raw_summed_values.type_signature.member,
        second_operand_type=placed_modulus.type_signature.member)
    modulus_computed = building_block_factory.create_federated_apply(
        modulus_fn, modulus_arg)

    return modulus_computed
コード例 #4
0
  def federated_value(self, value, placement):
    """Implements `federated_value` as defined in `api/intrinsics.py`."""
    # TODO(b/113112108): Verify that neither the value, nor any of its parts
    # are of a federated type.

    value = value_impl.to_value(value, None, self._context_stack)

    value = value_impl.ValueImpl.get_comp(value)
    comp = building_block_factory.create_federated_value(value, placement)
    return value_impl.ValueImpl(comp, self._context_stack)
コード例 #5
0
 def test_reduces_federated_value_at_server_to_equivalent_noarg_function(self):
   zero = building_block_factory.create_tensorflow_constant(
       computation_types.TensorType(tf.int32, shape=[]), 0)
   federated_value = building_block_factory.create_federated_value(
       zero, placements.SERVER)
   extracted_tf = transformations.consolidate_and_extract_local_processing(
       federated_value, DEFAULT_GRAPPLER_CONFIG)
   executable_tf = computation_wrapper_instances.building_block_to_computation(
       extracted_tf)
   self.assertEqual(executable_tf(), 0)
コード例 #6
0
 def test_strip_placement_federated_value_at_clients(self):
     int_data = building_blocks.Data('x', tf.int32)
     float_data = building_blocks.Data('x', tf.float32)
     fed_int = building_block_factory.create_federated_value(
         int_data, placements.CLIENTS)
     fed_float = building_block_factory.create_federated_value(
         float_data, placements.CLIENTS)
     tup = building_blocks.Struct([fed_int, fed_float],
                                  container_type=tuple)
     before = building_block_factory.create_federated_zip(tup)
     after, modified = tree_transformations.strip_placement(before)
     self.assertTrue(modified)
     self.assert_has_no_intrinsics_nor_federated_types(after)
     tuple_type = computation_types.StructWithPythonType(
         [(None, tf.int32), (None, tf.float32)], tuple)
     type_test_utils.assert_types_identical(
         before.type_signature, computation_types.at_clients(tuple_type))
     type_test_utils.assert_types_identical(after.type_signature,
                                            tuple_type)
コード例 #7
0
  def federated_value(self, value, placement):
    """Implements `federated_value` as defined in `api/intrinsics.py`."""
    value = value_impl.to_value(value, None, self._context_stack)
    if type_analysis.contains(value.type_signature, lambda t: t.is_federated()):
      raise TypeError('Cannt place value {} containing federated types at '
                      'another placement; requested to be placed at {}.'.format(
                          value, placement))

    value = value_impl.ValueImpl.get_comp(value)
    comp = building_block_factory.create_federated_value(value, placement)
    comp = self._bind_comp_as_reference(comp)
    return value_impl.ValueImpl(comp, self._context_stack)
コード例 #8
0
  def federated_value(self, value, placement):
    """Implements `federated_value` as defined in `api/intrinsics.py`."""
    value = value_impl.to_value(value, None, self._context_stack)
    if type_utils.type_tree_contains_types(value.type_signature,
                                           computation_types.FederatedType):
      raise TypeError('Cannt place value {} containing federated types at '
                      'another placement; requested to be placed at {}.'.format(
                          value, placement))

    value = value_impl.ValueImpl.get_comp(value)
    comp = building_block_factory.create_federated_value(value, placement)
    return value_impl.ValueImpl(comp, self._context_stack)
コード例 #9
0
 def test_reduces_federated_value_at_clients_to_equivalent_noarg_function(
         self):
     zero = building_block_factory.create_tensorflow_constant(
         computation_types.TensorType(tf.int32, shape=[]), 0)
     federated_value = building_block_factory.create_federated_value(
         zero, placements.CLIENTS)
     federated_value_func = building_blocks.Lambda(None, None,
                                                   federated_value)
     extracted_tf = compiler.consolidate_and_extract_local_processing(
         federated_value_func, DEFAULT_GRAPPLER_CONFIG)
     executable_tf = computation_impl.ConcreteComputation.from_building_block(
         extracted_tf)
     self.assertEqual(executable_tf(), 0)
コード例 #10
0
def _create_before_and_after_broadcast_for_no_broadcast(tree):
    """Creates a before and after broadcast computations for the given `tree`.

  This function is intended to be used by
  `get_canonical_form_for_iterative_process` to create before and after
  broadcast computations for the given `tree` when there is no
  `intrinsic_defs.FEDERATED_BROADCAST` in `tree`.

  NOTE: This function does not assert that there is no
  `intrinsic_defs.FEDERATED_BROADCAST` in `tree`, the caller is expected to
  perform this check before calling this function.

  Args:
    tree: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A pair of the form `(before, after)`, where each of `before` and `after`
    is a `tff_framework.ComputationBuildingBlock` that represents a part of the
    result as specified by
    `transformations.force_align_and_split_by_intrinsics`.
  """
    name_generator = building_block_factory.unique_name_generator(tree)

    parameter_name = next(name_generator)
    empty_tuple = building_blocks.Tuple([])
    value = building_block_factory.create_federated_value(
        empty_tuple, placements.SERVER)
    before_broadcast = building_blocks.Lambda(parameter_name,
                                              tree.type_signature.parameter,
                                              value)

    parameter_name = next(name_generator)
    type_signature = computation_types.FederatedType(
        before_broadcast.type_signature.result.member, placements.CLIENTS)
    parameter_type = computation_types.NamedTupleType(
        [tree.type_signature.parameter, type_signature])
    ref = building_blocks.Reference(parameter_name, parameter_type)
    arg = building_blocks.Selection(ref, index=0)
    call = building_blocks.Call(tree, arg)
    after_broadcast = building_blocks.Lambda(ref.name, ref.type_signature,
                                             call)

    return before_broadcast, after_broadcast
コード例 #11
0
def _create_next_with_fake_client_output(tree):
    r"""Creates a next computation with a fake client output.

  This function returns the AST:

  Lambda
  |
  [Comp, Comp, Tuple]
               |
               []

  In the AST, `Lambda` and the first two `Comps`s in the result of `Lambda` are
  `tree` and the empty `Tuple` is the fake client output.

  This function is intended to be used by
  `get_canonical_form_for_iterative_process` to create a next computation with
  a fake client output when no client output is returned by `tree` (which
  represents the `next` function of the `tff.utils.IterativeProcess`). As a
  result, this function does not assert that there is no client output in `tree`
  and it does not assert that `tree` has the expected structure, the caller is
  expected to perform these checks before calling this function.

  Args:
    tree: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A new `building_blocks.ComputationBuildingBlock` representing a next
    computaiton with a fake client output.
  """
    if isinstance(tree.result, building_blocks.Tuple):
        arg_1 = tree.result[0]
        arg_2 = tree.result[1]
    else:
        arg_1 = building_blocks.Selection(tree.result, index=0)
        arg_2 = building_blocks.Selection(tree.result, index=1)

    empty_tuple = building_blocks.Tuple([])
    client_output = building_block_factory.create_federated_value(
        empty_tuple, placements.CLIENTS)
    output = building_blocks.Tuple([arg_1, arg_2, client_output])
    return building_blocks.Lambda(tree.parameter_name, tree.parameter_type,
                                  output)
コード例 #12
0
def _create_dummy_before_and_after_broadcast(comp):
    """Creates a before and after broadcast computations for the given `comp`.

  This function is intended to be used instead of
  `transformations.force_align_and_split_by_intrinsic` to generate dummy before
  and after computations, when there is no `intrinsic_defs.FEDERATED_BROADCAST`
  present in `comp`.

  Note: This function does not assert that there is no
  `intrinsic_defs.FEDERATED_BROADCAST` present in `comp`, the caller is expected
  to perform this check before calling this function.

  Args:
    comp: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A pair of the form `(before, after)`, where each of `before` and `after`
    is a `tff_framework.ComputationBuildingBlock` that represents a part of the
    result as specified by `transformations.force_align_and_split_by_intrinsic`.
  """
    name_generator = building_block_factory.unique_name_generator(comp)

    parameter_name = six.next(name_generator)
    empty_tuple = building_blocks.Tuple([])
    federated_value_at_server = building_block_factory.create_federated_value(
        empty_tuple, placements.SERVER)
    before_broadcast = building_blocks.Lambda(parameter_name,
                                              comp.type_signature.parameter,
                                              federated_value_at_server)

    parameter_name = six.next(name_generator)
    type_signature = computation_types.FederatedType(
        before_broadcast.type_signature.result.member, placements.CLIENTS)
    parameter_type = computation_types.NamedTupleType(
        [comp.type_signature.parameter, type_signature])
    ref = building_blocks.Reference(parameter_name, parameter_type)
    arg = building_blocks.Selection(ref, index=0)
    call = building_blocks.Call(comp, arg)
    after_broadcast = building_blocks.Lambda(ref.name, ref.type_signature,
                                             call)

    return before_broadcast, after_broadcast
コード例 #13
0
def create_whimsy_called_federated_value(
        placement: placements.PlacementLiteral, value_type=tf.int32):
    value = building_blocks.Data('data', value_type)
    return building_block_factory.create_federated_value(value, placement)
コード例 #14
0
def _create_before_and_after_aggregate_for_no_federated_secure_sum(tree):
  r"""Creates a before and after aggregate computations for the given `tree`.

  Lambda
  |
  Tuple
  |
  [Comp, Tuple]
         |
         [Tuple, []]
          |
          []

       Lambda(x)
       |
       Call
      /    \
  Comp      Tuple
            |
            [Sel(0),      Sel(0)]
            /            /
         Ref(x)    Sel(1)
                  /
            Ref(x)

  In the first AST, the first element returned by `Lambda`, `Comp`, is the
  result of the before aggregate returned by force aligning and splitting `tree`
  by `intrinsic_defs.FEDERATED_AGGREGATE.uri` and the second element returned by
  `Lambda` is an empty structure that represents the argument to the secure sum
  intrinsic. Therefore, the first AST has a type signature satisfying the
  requirements of before aggregate.

  In the second AST, `Comp` is the after aggregate returned by force aligning
  and splitting `tree` by intrinsic_defs.FEDERATED_AGGREGATE.uri; `Lambda` has a
  type signature satisfying the requirements of after aggregate; and the
  argument passed to `Comp` is a selection from the parameter of `Lambda` which
  intentionally drops `s4` on the floor.

  This function is intended to be used by
  `get_canonical_form_for_iterative_process` to create before and after
  broadcast computations for the given `tree` when there is no
  `intrinsic_defs.FEDERATED_SECURE_SUM` in `tree`. As a result, this function
  does not assert that there is no `intrinsic_defs.FEDERATED_SECURE_SUM` in
  `tree` and it does not assert that `tree` has the expected structure, the
  caller is expected to perform these checks before calling this function.

  Args:
    tree: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A pair of the form `(before, after)`, where each of `before` and `after`
    is a `tff_framework.ComputationBuildingBlock` that represents a part of the
    result as specified by
    `transformations.force_align_and_split_by_intrinsics`.
  """
  name_generator = building_block_factory.unique_name_generator(tree)

  before_aggregate, after_aggregate = (
      transformations.force_align_and_split_by_intrinsics(
          tree, [intrinsic_defs.FEDERATED_AGGREGATE.uri]))

  empty_tuple = building_blocks.Struct([])
  value = building_block_factory.create_federated_value(empty_tuple,
                                                        placements.CLIENTS)
  bitwidth = empty_tuple
  args = building_blocks.Struct([value, bitwidth])
  result = building_blocks.Struct([before_aggregate.result, args])
  before_aggregate = building_blocks.Lambda(before_aggregate.parameter_name,
                                            before_aggregate.parameter_type,
                                            result)

  ref_name = next(name_generator)
  s4_type = computation_types.FederatedType([], placements.SERVER)
  ref_type = computation_types.StructType([
      after_aggregate.parameter_type[0],
      computation_types.StructType([
          after_aggregate.parameter_type[1],
          s4_type,
      ]),
  ])
  ref = building_blocks.Reference(ref_name, ref_type)
  sel_arg = building_blocks.Selection(ref, index=0)
  sel = building_blocks.Selection(ref, index=1)
  sel_s3 = building_blocks.Selection(sel, index=0)
  arg = building_blocks.Struct([sel_arg, sel_s3])
  call = building_blocks.Call(after_aggregate, arg)
  after_aggregate = building_blocks.Lambda(ref.name, ref.type_signature, call)

  return before_aggregate, after_aggregate
コード例 #15
0
def _create_before_and_after_broadcast_for_no_broadcast(tree):
  r"""Creates a before and after broadcast computations for the given `tree`.

  This function returns the two ASTs:

  Lambda
  |
  Tuple
  |
  []

       Lambda(x)
       |
       Call
      /    \
  Comp      Sel(0)
           /
     Ref(x)

  The first AST is an empty structure that has a type signature satisfying the
  requirements of before broadcast.

  In the second AST, `Comp` is `tree`; `Lambda` has a type signature satisfying
  the requirements of after broadcast; and the argument passed to `Comp` is a
  selection from the parameter of `Lambda` which intentionally drops `c2` on the
  floor.

  This function is intended to be used by
  `get_canonical_form_for_iterative_process` to create before and after
  broadcast computations for the given `tree` when there is no
  `intrinsic_defs.FEDERATED_BROADCAST` in `tree`. As a result, this function
  does not assert that there is no `intrinsic_defs.FEDERATED_BROADCAST` in
  `tree` and it does not assert that `tree` has the expected structure, the
  caller is expected to perform these checks before calling this function.

  Args:
    tree: An instance of `building_blocks.ComputationBuildingBlock`.

  Returns:
    A pair of the form `(before, after)`, where each of `before` and `after`
    is a `tff_framework.ComputationBuildingBlock` that represents a part of the
    result as specified by
    `transformations.force_align_and_split_by_intrinsics`.
  """
  name_generator = building_block_factory.unique_name_generator(tree)

  parameter_name = next(name_generator)
  empty_tuple = building_blocks.Struct([])
  value = building_block_factory.create_federated_value(empty_tuple,
                                                        placements.SERVER)
  before_broadcast = building_blocks.Lambda(parameter_name,
                                            tree.type_signature.parameter,
                                            value)

  parameter_name = next(name_generator)
  type_signature = computation_types.FederatedType(
      before_broadcast.type_signature.result.member, placements.CLIENTS)
  parameter_type = computation_types.StructType(
      [tree.type_signature.parameter, type_signature])
  ref = building_blocks.Reference(parameter_name, parameter_type)
  arg = building_blocks.Selection(ref, index=0)
  call = building_blocks.Call(tree, arg)
  after_broadcast = building_blocks.Lambda(ref.name, ref.type_signature, call)

  return before_broadcast, after_broadcast