Skip to content

Commit 56d83fc

Browse files
ZacharyGarrettcopybara-github
authored andcommitted
Refactoring dataset_reduce module into loop_builder.
- Rename `build_dataset_reduce_fn` to `build_training_loop` - Parameterize by a new enum `LoopImplementation` - Update all previous usages This refactoring will make it easier to introduce alternative looping strateies in the future. Namely of interest is a `tf.foldl` based implementation that works across "datasets-as-arrays" (tf.Tensor with the zeroth dimesion being the number of examples) as introduced in https://arxiv.org/abs/2307.09619. PiperOrigin-RevId: 656540932
1 parent 87c6a10 commit 56d83fc

19 files changed

+213
-177
lines changed

tensorflow_federated/python/learning/BUILD

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ py_library(
4646
)
4747

4848
py_library(
49-
name = "dataset_reduce",
50-
srcs = ["dataset_reduce.py"],
49+
name = "loop_builder",
50+
srcs = ["loop_builder.py"],
5151
)
5252

5353
py_cpu_gpu_test(
54-
name = "dataset_reduce_test",
55-
srcs = ["dataset_reduce_test.py"],
56-
deps = [":dataset_reduce"],
54+
name = "loop_builder_test",
55+
srcs = ["loop_builder_test.py"],
56+
deps = [":loop_builder"],
5757
)
5858

5959
py_library(

tensorflow_federated/python/learning/algorithms/BUILD

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ py_cpu_gpu_test(
6969
":fed_avg",
7070
"//tensorflow_federated/python/aggregators:factory_utils",
7171
"//tensorflow_federated/python/core/test:static_assert",
72-
"//tensorflow_federated/python/learning:dataset_reduce",
72+
"//tensorflow_federated/python/learning:loop_builder",
7373
"//tensorflow_federated/python/learning:model_update_aggregator",
7474
"//tensorflow_federated/python/learning/metrics:aggregator",
7575
"//tensorflow_federated/python/learning/models:model_examples",
@@ -116,7 +116,7 @@ py_cpu_gpu_test(
116116
deps = [
117117
":fed_avg_with_optimizer_schedule",
118118
"//tensorflow_federated/python/core/test:static_assert",
119-
"//tensorflow_federated/python/learning:dataset_reduce",
119+
"//tensorflow_federated/python/learning:loop_builder",
120120
"//tensorflow_federated/python/learning:model_update_aggregator",
121121
"//tensorflow_federated/python/learning/metrics:aggregator",
122122
"//tensorflow_federated/python/learning/models:model_examples",
@@ -160,7 +160,7 @@ py_cpu_gpu_test(
160160
"//tensorflow_federated/python/aggregators:factory_utils",
161161
"//tensorflow_federated/python/core/templates:iterative_process",
162162
"//tensorflow_federated/python/core/test:static_assert",
163-
"//tensorflow_federated/python/learning:dataset_reduce",
163+
"//tensorflow_federated/python/learning:loop_builder",
164164
"//tensorflow_federated/python/learning:model_update_aggregator",
165165
"//tensorflow_federated/python/learning/metrics:aggregator",
166166
"//tensorflow_federated/python/learning/models:model_examples",
@@ -293,7 +293,7 @@ py_library(
293293
"//tensorflow_federated/python/core/impl/types:computation_types",
294294
"//tensorflow_federated/python/core/impl/types:placements",
295295
"//tensorflow_federated/python/core/templates:measured_process",
296-
"//tensorflow_federated/python/learning:dataset_reduce",
296+
"//tensorflow_federated/python/learning:loop_builder",
297297
"//tensorflow_federated/python/learning:tensor_utils",
298298
"//tensorflow_federated/python/learning/metrics:aggregator",
299299
"//tensorflow_federated/python/learning/metrics:types",
@@ -317,7 +317,7 @@ py_cpu_gpu_test(
317317
deps = [
318318
":fed_sgd",
319319
"//tensorflow_federated/python/core/test:static_assert",
320-
"//tensorflow_federated/python/learning:dataset_reduce",
320+
"//tensorflow_federated/python/learning:loop_builder",
321321
"//tensorflow_federated/python/learning:model_update_aggregator",
322322
"//tensorflow_federated/python/learning/metrics:aggregator",
323323
"//tensorflow_federated/python/learning/models:functional",
@@ -376,7 +376,7 @@ py_library(
376376
"//tensorflow_federated/python/core/impl/types:type_conversions",
377377
"//tensorflow_federated/python/core/templates:measured_process",
378378
"//tensorflow_federated/python/learning:client_weight_lib",
379-
"//tensorflow_federated/python/learning:dataset_reduce",
379+
"//tensorflow_federated/python/learning:loop_builder",
380380
"//tensorflow_federated/python/learning:tensor_utils",
381381
"//tensorflow_federated/python/learning/metrics:aggregator",
382382
"//tensorflow_federated/python/learning/metrics:types",
@@ -415,7 +415,7 @@ py_cpu_gpu_test(
415415
"//tensorflow_federated/python/core/templates:measured_process",
416416
"//tensorflow_federated/python/core/test:static_assert",
417417
"//tensorflow_federated/python/learning:client_weight_lib",
418-
"//tensorflow_federated/python/learning:dataset_reduce",
418+
"//tensorflow_federated/python/learning:loop_builder",
419419
"//tensorflow_federated/python/learning:model_update_aggregator",
420420
"//tensorflow_federated/python/learning/metrics:aggregator",
421421
"//tensorflow_federated/python/learning/metrics:counters",
@@ -450,7 +450,7 @@ py_library(
450450
"//tensorflow_federated/python/core/impl/types:placements",
451451
"//tensorflow_federated/python/core/templates:aggregation_process",
452452
"//tensorflow_federated/python/core/templates:measured_process",
453-
"//tensorflow_federated/python/learning:dataset_reduce",
453+
"//tensorflow_federated/python/learning:loop_builder",
454454
"//tensorflow_federated/python/learning/metrics:sum_aggregation_factory",
455455
"//tensorflow_federated/python/learning/models:functional",
456456
"//tensorflow_federated/python/learning/models:model_weights",
@@ -520,7 +520,7 @@ py_cpu_gpu_test(
520520
":personalization_eval",
521521
"//tensorflow_federated/python/core/backends/native:execution_contexts",
522522
"//tensorflow_federated/python/core/impl/types:computation_types",
523-
"//tensorflow_federated/python/learning:dataset_reduce",
523+
"//tensorflow_federated/python/learning:loop_builder",
524524
"//tensorflow_federated/python/learning/models:keras_utils",
525525
"//tensorflow_federated/python/learning/models:model_examples",
526526
"//tensorflow_federated/python/learning/models:model_weights",

tensorflow_federated/python/learning/algorithms/fed_avg_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from tensorflow_federated.python.aggregators import factory_utils
2222
from tensorflow_federated.python.core.test import static_assert
23-
from tensorflow_federated.python.learning import dataset_reduce
23+
from tensorflow_federated.python.learning import loop_builder
2424
from tensorflow_federated.python.learning import model_update_aggregator
2525
from tensorflow_federated.python.learning.algorithms import fed_avg
2626
from tensorflow_federated.python.learning.metrics import aggregator
@@ -60,9 +60,9 @@ def test_construction_calls_model_fn(self, optimizer_fn, aggregation_factory):
6060
('simulation_tff_optimizer', True),
6161
)
6262
@mock.patch.object(
63-
dataset_reduce,
63+
loop_builder,
6464
'_dataset_reduce_fn',
65-
wraps=dataset_reduce._dataset_reduce_fn,
65+
wraps=loop_builder._dataset_reduce_fn,
6666
)
6767
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
6868
fed_avg.build_weighted_fed_avg(

tensorflow_federated/python/learning/algorithms/fed_avg_with_optimizer_schedule_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import tensorflow as tf
2020

2121
from tensorflow_federated.python.core.test import static_assert
22-
from tensorflow_federated.python.learning import dataset_reduce
22+
from tensorflow_federated.python.learning import loop_builder
2323
from tensorflow_federated.python.learning import model_update_aggregator
2424
from tensorflow_federated.python.learning.algorithms import fed_avg_with_optimizer_schedule
2525
from tensorflow_federated.python.learning.metrics import aggregator
@@ -68,9 +68,9 @@ def test_construction_of_functional_model(self):
6868
('simulation', True),
6969
)
7070
@mock.patch.object(
71-
dataset_reduce,
71+
loop_builder,
7272
'_dataset_reduce_fn',
73-
wraps=dataset_reduce._dataset_reduce_fn,
73+
wraps=loop_builder._dataset_reduce_fn,
7474
)
7575
def test_client_tf_dataset_reduce_fn(self, use_simulation, mock_reduce):
7676
client_learning_rate_fn = lambda x: 0.5

tensorflow_federated/python/learning/algorithms/fed_eval.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from tensorflow_federated.python.core.impl.types import placements
3030
from tensorflow_federated.python.core.templates import aggregation_process
3131
from tensorflow_federated.python.core.templates import measured_process
32-
from tensorflow_federated.python.learning import dataset_reduce
32+
from tensorflow_federated.python.learning import loop_builder
3333
from tensorflow_federated.python.learning.metrics import sum_aggregation_factory
3434
from tensorflow_federated.python.learning.models import functional
3535
from tensorflow_federated.python.learning.models import model_weights as model_weights_lib
@@ -105,8 +105,10 @@ def reduce_fn(num_examples, batch):
105105
else:
106106
return num_examples + tf.cast(model_output.num_examples, tf.int64)
107107

108-
dataset_reduce_fn = dataset_reduce.build_dataset_reduce_fn(
109-
use_experimental_simulation_loop
108+
dataset_reduce_fn = loop_builder.build_training_loop(
109+
loop_builder.LoopImplementation.DATASET_ITERATOR
110+
if use_experimental_simulation_loop
111+
else loop_builder.LoopImplementation.DATASET_REDUCE
110112
)
111113
num_examples = dataset_reduce_fn(
112114
reduce_fn, dataset, lambda: tf.zeros([], dtype=tf.int64)

tensorflow_federated/python/learning/algorithms/fed_prox_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from tensorflow_federated.python.aggregators import factory_utils
2222
from tensorflow_federated.python.core.templates import iterative_process
2323
from tensorflow_federated.python.core.test import static_assert
24-
from tensorflow_federated.python.learning import dataset_reduce
24+
from tensorflow_federated.python.learning import loop_builder
2525
from tensorflow_federated.python.learning import model_update_aggregator
2626
from tensorflow_federated.python.learning.algorithms import fed_prox
2727
from tensorflow_federated.python.learning.metrics import aggregator
@@ -64,9 +64,9 @@ def test_construction_calls_model_fn(self, optimizer_fn, aggregation_factory):
6464
('simulation_tff_optimizer', True),
6565
)
6666
@mock.patch.object(
67-
dataset_reduce,
67+
loop_builder,
6868
'_dataset_reduce_fn',
69-
wraps=dataset_reduce._dataset_reduce_fn,
69+
wraps=loop_builder._dataset_reduce_fn,
7070
)
7171
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
7272
fed_prox.build_weighted_fed_prox(

tensorflow_federated/python/learning/algorithms/fed_sgd.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from tensorflow_federated.python.core.impl.types import computation_types
3838
from tensorflow_federated.python.core.impl.types import placements
3939
from tensorflow_federated.python.core.templates import measured_process
40-
from tensorflow_federated.python.learning import dataset_reduce
40+
from tensorflow_federated.python.learning import loop_builder
4141
from tensorflow_federated.python.learning import tensor_utils
4242
from tensorflow_federated.python.learning.metrics import aggregator as metric_aggregator
4343
from tensorflow_federated.python.learning.metrics import types
@@ -65,8 +65,10 @@ def _build_client_update(
6565
Returns:
6666
A `tf.function`.
6767
"""
68-
dataset_reduce_fn = dataset_reduce.build_dataset_reduce_fn(
69-
use_experimental_simulation_loop
68+
dataset_reduce_fn = loop_builder.build_training_loop(
69+
loop_builder.LoopImplementation.DATASET_ITERATOR
70+
if use_experimental_simulation_loop
71+
else loop_builder.LoopImplementation.DATASET_REDUCE
7072
)
7173

7274
@tf.function
@@ -215,8 +217,10 @@ def _build_functional_client_update(
215217
Returns:
216218
A `tf.function`.
217219
"""
218-
dataset_reduce_fn = dataset_reduce.build_dataset_reduce_fn(
219-
use_experimental_simulation_loop
220+
dataset_reduce_fn = loop_builder.build_training_loop(
221+
loop_builder.LoopImplementation.DATASET_ITERATOR
222+
if use_experimental_simulation_loop
223+
else loop_builder.LoopImplementation.DATASET_REDUCE
220224
)
221225

222226
@tf.function

tensorflow_federated/python/learning/algorithms/fed_sgd_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import tensorflow as tf
2121

2222
from tensorflow_federated.python.core.test import static_assert
23-
from tensorflow_federated.python.learning import dataset_reduce
23+
from tensorflow_federated.python.learning import loop_builder
2424
from tensorflow_federated.python.learning import model_update_aggregator
2525
from tensorflow_federated.python.learning.algorithms import fed_sgd
2626
from tensorflow_federated.python.learning.metrics import aggregator
@@ -143,9 +143,9 @@ def test_non_finite_aggregation(self, bad_value):
143143
('non-simulation', False), ('simulation', True)
144144
)
145145
@mock.patch.object(
146-
dataset_reduce,
146+
loop_builder,
147147
'_dataset_reduce_fn',
148-
wraps=dataset_reduce._dataset_reduce_fn,
148+
wraps=loop_builder._dataset_reduce_fn,
149149
)
150150
@tensorflow_test_utils.skip_test_for_multi_gpu
151151
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
@@ -250,9 +250,9 @@ def test_non_finite_aggregation(self, bad_value):
250250
('non-simulation', False), ('simulation', True)
251251
)
252252
@mock.patch.object(
253-
dataset_reduce,
253+
loop_builder,
254254
'_dataset_reduce_fn',
255-
wraps=dataset_reduce._dataset_reduce_fn,
255+
wraps=loop_builder._dataset_reduce_fn,
256256
)
257257
@tensorflow_test_utils.skip_test_for_multi_gpu
258258
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):

tensorflow_federated/python/learning/algorithms/mime.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from tensorflow_federated.python.core.impl.types import type_conversions
4242
from tensorflow_federated.python.core.templates import measured_process
4343
from tensorflow_federated.python.learning import client_weight_lib
44-
from tensorflow_federated.python.learning import dataset_reduce
44+
from tensorflow_federated.python.learning import loop_builder
4545
from tensorflow_federated.python.learning import tensor_utils
4646
from tensorflow_federated.python.learning.metrics import aggregator as metric_aggregator
4747
from tensorflow_federated.python.learning.metrics import types
@@ -80,8 +80,10 @@ def _build_client_update_fn_for_mime_lite(
8080
@tensorflow_computation.tf_computation
8181
def client_update_fn(global_optimizer_state, initial_weights, data):
8282
model = model_fn()
83-
dataset_reduce_fn = dataset_reduce.build_dataset_reduce_fn(
84-
use_experimental_simulation_loop
83+
dataset_reduce_fn = loop_builder.build_training_loop(
84+
loop_builder.LoopImplementation.DATASET_ITERATOR
85+
if use_experimental_simulation_loop
86+
else loop_builder.LoopImplementation.DATASET_REDUCE
8587
)
8688
weight_tensor_specs = type_conversions.type_to_tf_tensor_specs(
8789
model_weights_lib.weights_type_from_model(model)
@@ -320,8 +322,10 @@ def _build_functional_client_update_fn_for_mime_lite(
320322

321323
@tensorflow_computation.tf_computation
322324
def client_update_fn(global_optimizer_state, incoming_weights, data):
323-
dataset_reduce_fn = dataset_reduce.build_dataset_reduce_fn(
324-
use_experimental_simulation_loop
325+
dataset_reduce_fn = loop_builder.build_training_loop(
326+
loop_builder.LoopImplementation.DATASET_ITERATOR
327+
if use_experimental_simulation_loop
328+
else loop_builder.LoopImplementation.DATASET_REDUCE
325329
)
326330
weight_tensor_specs = tf.nest.map_structure(
327331
lambda t: tf.TensorSpec(shape=t.shape, dtype=t.dtype),

tensorflow_federated/python/learning/algorithms/mime_test.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
from tensorflow_federated.python.core.templates import measured_process
3232
from tensorflow_federated.python.core.test import static_assert
3333
from tensorflow_federated.python.learning import client_weight_lib
34-
from tensorflow_federated.python.learning import dataset_reduce
34+
from tensorflow_federated.python.learning import loop_builder
3535
from tensorflow_federated.python.learning import model_update_aggregator
3636
from tensorflow_federated.python.learning.algorithms import fed_avg
3737
from tensorflow_federated.python.learning.algorithms import mime
@@ -191,9 +191,9 @@ class MimeLiteClientWorkExecutionTest(tf.test.TestCase, parameterized.TestCase):
191191
('non-simulation', False), ('simulation', True)
192192
)
193193
@mock.patch.object(
194-
dataset_reduce,
194+
loop_builder,
195195
'_dataset_reduce_fn',
196-
wraps=dataset_reduce._dataset_reduce_fn,
196+
wraps=loop_builder._dataset_reduce_fn,
197197
)
198198
@tensorflow_test_utils.skip_test_for_multi_gpu
199199
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
@@ -280,9 +280,9 @@ class MimeLiteFunctionalClientWorkExecutionTest(
280280
('non-simulation', False), ('simulation', True)
281281
)
282282
@mock.patch.object(
283-
dataset_reduce,
283+
loop_builder,
284284
'_dataset_reduce_fn',
285-
wraps=dataset_reduce._dataset_reduce_fn,
285+
wraps=loop_builder._dataset_reduce_fn,
286286
)
287287
@tensorflow_test_utils.skip_test_for_gpu
288288
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
@@ -390,9 +390,9 @@ def test_construction_calls_model_fn(self):
390390
('simulation_tff_optimizer', True),
391391
)
392392
@mock.patch.object(
393-
dataset_reduce,
393+
loop_builder,
394394
'_dataset_reduce_fn',
395-
wraps=dataset_reduce._dataset_reduce_fn,
395+
wraps=loop_builder._dataset_reduce_fn,
396396
)
397397
def test_client_tf_dataset_reduce_fn(self, simulation, mock_method):
398398
mime.build_weighted_mime_lite(

0 commit comments

Comments
 (0)