tff.framework.MergeableCompForm
Stay organized with collections
Save and categorize content based on your preferences.
A data class for computations containing a single logical aggregation.
tff.framework.MergeableCompForm(
*,
up_to_merge: tff.Computation
,
merge: tff.Computation
,
after_merge: tff.Computation
)
MergeableCompForm
contains three member computations, up_to_merge
and merge
, and after_merge
. A computation in MergeableCompForm
is
defined to be equivalent to invoking up_to_merge
on subsets of
CLIENTS
-placed arguments in sequence, invoking merge
on the stream of
these results, and passing the resulting value (placed at tff.SERVER
) to
after_merge
, in addition to the original argument to up_to_merge
.
In the case of a no-arg up_to_merge
computation, after_merge
should accept
only the result of merge
. up_to_merge
should return a single
tff.SERVER
-placed value.
We require that computations in MergeableCompForm
contain no AST
nodes with signatures taking arguments at tff.CLIENTS
and producing results
at tff.SERVER
.
MergeableCompForm
computations are often generated by aligning a computation
containing a single logical aggregation on this aggregation, and splitting it
along its merge boundary. That is, since merge
can be invoked repeatedly
without changing the results of the computation, a computation of the form:
@tff.federated_computation(...)
def single_aggregation(arg):
result_at_clients = work(arg)
agg_result = tff.federated_aggregate(
result_at_clients, zero, accumulate, merge, report)
return postprocess(arg, agg_result)
can be represented as the MergeableCompForm
triplet:
@tff.federated_computation(tff.AbstractType('T'))
def up_to_merge(arg):
result_at_clients = work(arg)
agg_result = tff.federated_aggregate(
result_at_clients, accumulate_zero, accumulate, merge, identity_report)
return agg_result
@tff.federated_computation([up_to_merge.type_signature.result.member,
up_to_merge.type_signature.result.member])
def merge(arg):
return merge(arg[0], arg[1])
@tff.federated_computation(
tff.AbstractType('T'),
tff.FederatedType(merge.type_signature.result, tff.SERVER),
)
def after_merge(original_arg, merged_result):
return postprocess(original_arg, merged_result)
A fair amount of complexity can be hidden in postprocess
; it could, for
example, compute some value on clients based on the result of the aggregation.
But the restriction that after_merge
can contain no aggregations ensures
that after_merge
can also be executed in a subround fashion: a
tff.CLIENTS
-placed result can only depend on its own local state and the
result of the aggregation, while a tff.SERVER
-placed result can only depend
on the result of the single aggregation or a tff.SERVER
-placed value.
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2024-09-20 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2024-09-20 UTC."],[],[],null,["# tff.framework.MergeableCompForm\n\n\u003cbr /\u003e\n\n|-------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [View source on GitHub](https://github.com/tensorflow/federated/blob/v0.87.0 Version 2.0, January 2004 Licensed under the Apache License, Version 2.0 (the) |\n\nA data class for computations containing a single logical aggregation. \n\n tff.framework.MergeableCompForm(\n *,\n up_to_merge: ../../tff/Computation,\n merge: ../../tff/Computation,\n after_merge: ../../tff/Computation\n )\n\n`MergeableCompForm` contains three member computations, `up_to_merge`\nand `merge`, and `after_merge`. A computation in `MergeableCompForm` is\ndefined to be equivalent to invoking `up_to_merge` on subsets of\n`CLIENTS`-placed arguments in sequence, invoking `merge` on the stream of\nthese results, and passing the resulting value (placed at [`tff.SERVER`](../../tff#SERVER)) to\n`after_merge`, in addition to the original argument to `up_to_merge`.\nIn the case of a no-arg `up_to_merge` computation, `after_merge` should accept\nonly the result of `merge`. `up_to_merge` should return a single\n[`tff.SERVER`](../../tff#SERVER)-placed value.\n\nWe require that computations in `MergeableCompForm` contain *no* AST\nnodes with signatures taking arguments at [`tff.CLIENTS`](../../tff#CLIENTS) and producing results\nat [`tff.SERVER`](../../tff#SERVER).\n\n`MergeableCompForm` computations are often generated by aligning a computation\ncontaining a single logical aggregation on this aggregation, and splitting it\nalong its merge boundary. That is, since `merge` can be invoked repeatedly\nwithout changing the results of the computation, a computation of the form: \n\n @tff.federated_computation(...)\n def single_aggregation(arg):\n result_at_clients = work(arg)\n agg_result = tff.federated_aggregate(\n result_at_clients, zero, accumulate, merge, report)\n return postprocess(arg, agg_result)\n\ncan be represented as the `MergeableCompForm` triplet: \n\n @tff.federated_computation(tff.AbstractType('T'))\n def up_to_merge(arg):\n result_at_clients = work(arg)\n agg_result = tff.federated_aggregate(\n result_at_clients, accumulate_zero, accumulate, merge, identity_report)\n return agg_result\n\n @tff.federated_computation([up_to_merge.type_signature.result.member,\n up_to_merge.type_signature.result.member])\n def merge(arg):\n return merge(arg[0], arg[1])\n\n @tff.federated_computation(\n tff.AbstractType('T'),\n tff.FederatedType(merge.type_signature.result, tff.SERVER),\n )\n def after_merge(original_arg, merged_result):\n return postprocess(original_arg, merged_result)\n\nA fair amount of complexity can be hidden in `postprocess`; it could, for\nexample, compute some value on clients based on the result of the aggregation.\nBut the restriction that `after_merge` can contain no aggregations ensures\nthat `after_merge` can also be executed in a subround fashion: a\n[`tff.CLIENTS`](../../tff#CLIENTS)-placed result can only depend on its own local state and the\nresult of the aggregation, while a [`tff.SERVER`](../../tff#SERVER)-placed result can only depend\non the result of the single aggregation or a [`tff.SERVER`](../../tff#SERVER)-placed value."]]