# Copyright 2018 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== """Strategy combinations for combinations.combine().""" import sys import unittest from tensorflow.core.protobuf import config_pb2 from tensorflow.python import tf2 from tensorflow.python.distribute import central_storage_strategy from tensorflow.python.distribute import cluster_resolver from tensorflow.python.distribute import collective_all_reduce_strategy from tensorflow.python.distribute import combinations from tensorflow.python.distribute import distribute_lib from tensorflow.python.distribute import mirrored_strategy as mirrored_lib from tensorflow.python.distribute import multi_process_runner from tensorflow.python.distribute import multi_worker_test_base from tensorflow.python.distribute import one_device_strategy as one_device_lib from tensorflow.python.distribute import parameter_server_strategy_v2 from tensorflow.python.distribute import sharded_variable from tensorflow.python.distribute import test_util from tensorflow.python.distribute import tpu_strategy as tpu_lib from tensorflow.python.distribute.cluster_resolver import tpu_cluster_resolver from tensorflow.python.eager import context from tensorflow.python.eager import remote from tensorflow.python.framework import device as tf_device from tensorflow.python.framework import errors from tensorflow.python.framework import test_util as framework_test_util from tensorflow.python.platform import flags from tensorflow.python.tpu import device_assignment as device_assignment_lib from tensorflow.python.training import server_lib from tensorflow.python.util.tf_export import tf_export _did_connect_to_cluster = False _topology = None CollectiveAllReduceExtended = ( collective_all_reduce_strategy.CollectiveAllReduceExtended ) def _version_chooser(tf1_cls, tf2_cls): def creator(*args, **kwargs): if tf2.enabled(): return tf2_cls(*args, **kwargs) return tf1_cls(*args, **kwargs) return creator MirroredStrategy = _version_chooser( mirrored_lib.MirroredStrategyV1, mirrored_lib.MirroredStrategy ) CentralStorageStrategy = _version_chooser( central_storage_strategy.CentralStorageStrategyV1, central_storage_strategy.CentralStorageStrategy, ) OneDeviceStrategy = _version_chooser( one_device_lib.OneDeviceStrategyV1, one_device_lib.OneDeviceStrategy ) # Only V2 CollectiveAllReduceStrategy combinations are supported. CollectiveAllReduceStrategy = ( collective_all_reduce_strategy.CollectiveAllReduceStrategy ) # pylint: disable=missing-docstring def _get_tpu_strategy_creator( steps_per_run, use_single_core=False, enable_packed_variable=False, enable_spmd_xla_paritioning=False, **kwargs ): def _create_tpu_strategy(): FLAGS = flags.FLAGS # pylint: disable=invalid-name global _did_connect_to_cluster global _topology try: # Attempt to locally discover the TPU. This will fail for Cloud TPU, in # which case we fall back to the values passed as flags. resolver = tpu_cluster_resolver.TPUClusterResolver() did_automatically_resolve = True except ValueError: did_automatically_resolve = False # These flags will be defined by tpu_test_wrapper.py. resolver = tpu_cluster_resolver.TPUClusterResolver( tpu=hasattr(FLAGS, "tpu") and FLAGS.tpu or "", zone=hasattr(FLAGS, "zone") and FLAGS.zone or None, project=hasattr(FLAGS, "project") and FLAGS.project or None, ) # Only connect once per process, rather than per test method. if not _did_connect_to_cluster: if getattr(FLAGS, "tpu", "") or did_automatically_resolve: remote.connect_to_cluster(resolver) _did_connect_to_cluster = True _topology = tpu_cluster_resolver.initialize_tpu_system(resolver) device_assignment = None if use_single_core: device_assignment = device_assignment_lib.DeviceAssignment( _topology, core_assignment=device_assignment_lib.SINGLE_CORE_ASSIGNMENT, ) # Steps per run is only supported in TF 1.x if tf2.enabled(): strategy = tpu_lib.TPUStrategyV2( resolver, device_assignment, experimental_spmd_xla_partitioning=enable_spmd_xla_paritioning, **kwargs ) else: strategy = tpu_lib.TPUStrategyV1( resolver, steps_per_run, device_assignment, **kwargs ) if enable_packed_variable and enable_spmd_xla_paritioning: raise ValueError("Packed Variable is not compatible with SPMD mode") strategy._enable_packed_variable_in_eager_mode = ( # pylint: disable=protected-access enable_packed_variable ) return strategy return _create_tpu_strategy def _mirrored_strategy_with_collective_key_base(devices): required_cpus_nums = sum( 1 for d in devices if tf_device.DeviceSpec.from_string(d).device_type == "CPU" ) # If required virtual CPUs are not setup yet, config the logical devices. if required_cpus_nums > len(context.context().list_logical_devices("CPU")): context._reset_context() # pylint: disable=protected-access test_util.set_logical_devices_to_at_least("CPU", required_cpus_nums) # Increase collective base key to avoid key collision across subtests. mirrored_lib.MirroredStrategyV1._collective_key_base += 100000 mirrored_lib.MirroredStrategy._collective_key_base += 100000 return MirroredStrategy(devices) def _mirrored_strategy_with_no_merge_call(devices): mirrored_lib.MirroredStrategyV1._collective_key_base += 100000 mirrored_lib.MirroredStrategy._collective_key_base += 100000 out = MirroredStrategy(devices) # Stub out merge call usage. out.extended._use_merge_call = lambda: False # pylint: disable=protected-access return out def _get_multi_worker_mirrored_creator(required_gpus, use_merge_call=True): def _create_multi_worker_mirrored(): tf_config = cluster_resolver.TFConfigClusterResolver() master = tf_config.master() if tf_config.rpc_layer: # Strip off the rpc_layer suffix. master = master[len("%s://" % tf_config.rpc_layer) :] resolver = cluster_resolver.SimpleClusterResolver( cluster_spec=tf_config.cluster_spec(), task_type=tf_config.task_type, task_id=tf_config.task_id, master=master, environment=tf_config.environment, num_accelerators={"GPU": required_gpus}, rpc_layer=tf_config.rpc_layer or "grpc", ) # Disable health check and coordination service. We don't have a reliable # way to shutdown the strategy (and thus the strategy health check or # coordination service heartbeat) at the end of a test. Turning on the # strategy health check or coordination service heartbeat causes some # flakiness since we re-create part of the server when creating a strategy, # and our tests are capable of handling failures. CollectiveAllReduceExtended._enable_check_health = ( # pylint: disable=protected-access False ) context.context().configure_coordination_service(service_type="") # Always create the strategy in eager mode so that it starts the server and # configures the eager context. The eager context can no longer be # configured after initialization. with context.eager_mode(): strategy = CollectiveAllReduceStrategy(cluster_resolver=resolver) if not use_merge_call: strategy.extended._use_merge_call = lambda: False # pylint: disable=protected-access # TODO(b/152320929): Wait for the cluster before proceeding, otherwise # collectives may hang if any worker launches collectives before the chief # creates the strategy. try: multi_process_runner.get_barrier().wait() except ValueError: # If the creator is called in the main process, # multi_process_runner.get_barrier() raises ValueError, which is safe to # ignore. pass return strategy def skip_if_cannot_start_grpc_server(): try: return _create_multi_worker_mirrored() except errors.UnknownError as e: if "Could not start gRPC server" in e.message and ( len(sys.argv) >= 1 and "bazel" in sys.argv[0] ): raise unittest.SkipTest("Cannot start std servers.") else: raise return skip_if_cannot_start_grpc_server # Due to b/195615322, FixedShardsPartitioner will wrongly partition # RNG state, so we use MinSizePartitioner as the default. Maximum RNG # state size is int64[3] which is 8 * 3 bytes, so we set # min_shard_bytes to 8 * 3 + 1. DEFAULT_PARTITIONER = sharded_variable.MinSizePartitioner( min_shard_bytes=8 * 3 + 1, max_shards=2 ) def _get_ps_strategy_creator( num_workers, num_ps, required_gpus=0, variable_partitioner=DEFAULT_PARTITIONER, ): def _create_ps_strategy(resolver, variable_partitioner): return parameter_server_strategy_v2.ParameterServerStrategyV2( resolver, variable_partitioner=variable_partitioner ) def _create_parameter_server(): if framework_test_util.is_xla_enabled(): # To address test failures resulting in XLA with MultiProcessRunner, # continue to use in-process cluster for XLA tests. cluster_def = multi_worker_test_base.create_in_process_cluster( num_workers=num_workers, num_ps=num_ps, rpc_layer="grpc" ) resolver = cluster_resolver.SimpleClusterResolver( server_lib.ClusterSpec(cluster_def), num_accelerators={"GPU": required_gpus}, rpc_layer="grpc", ) return _create_ps_strategy(resolver, variable_partitioner) else: tf_config = cluster_resolver.TFConfigClusterResolver() cluster_def = tf_config.cluster_spec().as_dict() if not cluster_def: # When MultiProcessRunner cluster is used, the cluster is not created # initially when the decorator is called. When the test runs, initially # this method is invoked via decorator before setting up the # MultiProcessRunner with worker and ps in the combinations.py. After # setup is done, the subprocess invokes this method again to get # strategy object. We return None strategy when the main thread invokes # this method before setting up cluster. # Returning None is fine here, since this thread will proceed to create # MultiProcessRunner and invoke tests with decorator inside # subprocesses. return None # MultiProcessRunner is already setup and this method is invoked from a # subprocess running the actual test. resolver = cluster_resolver.SimpleClusterResolver( server_lib.ClusterSpec(cluster_def), num_accelerators={"GPU": required_gpus}, task_type=tf_config.task_type, task_id=tf_config.task_id, environment=tf_config.environment, rpc_layer=tf_config.rpc_layer or "grpc", ) if tf_config.task_type in ("worker", "ps"): worker_config = config_pb2.ConfigProto() worker_config.inter_op_parallelism_threads = 4 # max num_workers + 1 try: server = server_lib.Server( cluster_def, job_name=tf_config.task_type, task_index=tf_config.task_id, protocol="grpc", config=worker_config, ) except errors.UnknownError as e: if "Could not start gRPC server" in e.message: raise unittest.SkipTest("Cannot start std servers.") else: raise # Blocking the process that starts a server from exiting. server.join() return _create_ps_strategy(resolver, variable_partitioner) return _create_parameter_server def _deferred_pool_runner( has_chief, num_workers, initializer=None, share_gpu=True ): """Returns a callable that returns the pool runner. It creates the pool runner only upon first invocation. This avoids creating it when this file is imported. Args: has_chief: whether there should be a chief. num_workers: the number of workers excluding the chief. initializer: initializer of each process. share_gpu: whether to share GPU between the workers. Returns: A callable that returns the runner. """ container = [] def get_or_create(): if not container: cluster_spec = multi_worker_test_base.create_cluster_spec( has_chief=has_chief, num_workers=num_workers, num_ps=0, has_eval=False ) runner = multi_process_runner.MultiProcessPoolRunner( cluster_spec, initializer=initializer, share_gpu=share_gpu ) container.append(runner) return container[0] return get_or_create # We need to create the strategy in the initializer to start the server before # any test runs. _two_worker_pool = _deferred_pool_runner( has_chief=True, num_workers=1, initializer=_get_multi_worker_mirrored_creator(required_gpus=0), ) # Two-worker pool where each worker gets it's own GPU. Useful for testing MWMS # on a single host. _two_worker_pool_noshare = _deferred_pool_runner( has_chief=True, num_workers=1, initializer=_get_multi_worker_mirrored_creator(required_gpus=0), share_gpu=False, ) _four_worker_pool = _deferred_pool_runner( has_chief=True, num_workers=3, initializer=_get_multi_worker_mirrored_creator(required_gpus=0), ) # pylint: disable=g-long-lambda default_strategy = combinations.NamedDistribution( "Default", distribute_lib._get_default_strategy, # pylint: disable=protected-access required_gpus=None, ) one_device_strategy = combinations.NamedDistribution( "OneDeviceCPU", lambda: OneDeviceStrategy("/cpu:0"), required_gpus=None ) one_device_strategy_gpu = combinations.NamedDistribution( "OneDeviceGPU", lambda: OneDeviceStrategy("/gpu:0"), required_gpus=1 ) one_device_strategy_on_worker_1 = combinations.NamedDistribution( "OneDeviceOnWorker1CPU", lambda: OneDeviceStrategy("/job:worker/replica:0/task:1/cpu:0"), required_gpus=None, ) one_device_strategy_gpu_on_worker_1 = combinations.NamedDistribution( "OneDeviceOnWorker1GPU", lambda: OneDeviceStrategy("/job:worker/replica:0/task:1/gpu:0"), required_gpus=1, ) tpu_strategy = combinations.NamedDistribution( "TPU", _get_tpu_strategy_creator(steps_per_run=2), required_tpu=True ) tpu_strategy_packed_var = combinations.NamedDistribution( "TPUPackedVar", _get_tpu_strategy_creator(steps_per_run=2, enable_packed_variable=True), required_tpu=True, ) tpu_strategy_spmd = combinations.NamedDistribution( "TPUUseSPMD", _get_tpu_strategy_creator( steps_per_run=2, enable_spmd_xla_paritioning=True ), required_tpu=True, ) tpu_strategy_one_step = combinations.NamedDistribution( "TPUOneStep", _get_tpu_strategy_creator(steps_per_run=1), required_tpu=True ) tpu_strategy_one_core = combinations.NamedDistribution( "TPUOneCore", _get_tpu_strategy_creator(steps_per_run=2, use_single_core=True), required_tpu=True, ) tpu_strategy_one_step_one_core = combinations.NamedDistribution( "TPUOneStepOneCore", _get_tpu_strategy_creator(steps_per_run=1, use_single_core=True), required_tpu=True, ) cloud_tpu_strategy = combinations.NamedDistribution( "CloudTPU", _get_tpu_strategy_creator(steps_per_run=2), required_tpu=True, use_cloud_tpu=True, ) mirrored_strategy_with_one_cpu = combinations.NamedDistribution( "Mirrored1CPU", lambda: _mirrored_strategy_with_collective_key_base(["/cpu:0"]), ) mirrored_strategy_with_one_gpu = combinations.NamedDistribution( "Mirrored1GPU", lambda: _mirrored_strategy_with_collective_key_base(["/gpu:0"]), required_gpus=1, ) mirrored_strategy_with_gpu_and_cpu = combinations.NamedDistribution( "MirroredCPUAndGPU", lambda: _mirrored_strategy_with_collective_key_base(["/gpu:0", "/cpu:0"]), required_gpus=1, ) mirrored_strategy_with_two_cpus = combinations.NamedDistribution( "Mirrored2CPUs", lambda: _mirrored_strategy_with_collective_key_base(["/cpu:0", "/cpu:1"]), required_gpus=0, ) mirrored_strategy_with_two_gpus = combinations.NamedDistribution( "Mirrored2GPUs", lambda: _mirrored_strategy_with_collective_key_base(["/gpu:0", "/gpu:1"]), required_gpus=2, ) mirrored_strategy_with_two_gpus_no_merge_call = combinations.NamedDistribution( "Mirrored2GPUsNoMergeCall", lambda: _mirrored_strategy_with_no_merge_call(["/gpu:0", "/gpu:1"]), required_physical_gpus=2, ) # Should call set_virtual_cpus_to_at_least(3) in your test's setUp methods. # Deprecated, use mirrored_strategy_with_two_cpus instead. mirrored_strategy_with_cpu_1_and_2 = combinations.NamedDistribution( "Mirrored2CPU", lambda: _mirrored_strategy_with_collective_key_base(["/cpu:1", "/cpu:2"]), ) mirrored_strategy_with_cpu_1_and_2.__doc__ = ( """Mirrored strategy with 2 virtual CPUs. Should set up logical devices before use """ ) central_storage_strategy_with_two_gpus = combinations.NamedDistribution( "CentralStorage2GPUs", lambda: CentralStorageStrategy(["/gpu:0", "/gpu:1"]), required_gpus=2, ) central_storage_strategy_with_gpu_and_cpu = combinations.NamedDistribution( "CentralStorageCPUAndGPU", lambda: CentralStorageStrategy(["/gpu:0", "/cpu:0"]), required_gpus=1, ) # chief + 1 worker, with CPU. multi_worker_mirrored_2x1_cpu = combinations.NamedDistribution( "MultiWorkerMirrored2x1CPU", _get_multi_worker_mirrored_creator(required_gpus=0), has_chief=True, num_workers=1, pool_runner_fn=_two_worker_pool, no_xla=True, ) # chief + 1 worker, with 1 GPU each. multi_worker_mirrored_2x1_gpu = combinations.NamedDistribution( "MultiWorkerMirrored2x1GPU", _get_multi_worker_mirrored_creator(required_gpus=1), has_chief=True, num_workers=1, required_gpus=1, pool_runner_fn=_two_worker_pool, share_gpu=False, ) # Same as above, but not sharing the GPU between the workers. multi_worker_mirrored_2x1_gpu_noshare = combinations.NamedDistribution( "MultiWorkerMirrored2x1GPUNoShare", _get_multi_worker_mirrored_creator(required_gpus=1), has_chief=True, num_workers=1, required_gpus=1, pool_runner_fn=_two_worker_pool_noshare, share_gpu=False, ) # chief + 1 worker, with 2 GPU each. multi_worker_mirrored_2x2_gpu = combinations.NamedDistribution( "MultiWorkerMirrored2x2GPU", _get_multi_worker_mirrored_creator(required_gpus=2), has_chief=True, num_workers=1, required_gpus=2, pool_runner_fn=_two_worker_pool, no_xla=True, ) multi_worker_mirrored_2x2_gpu_no_merge_call = combinations.NamedDistribution( "MultiWorkerMirrored2x2GPUNoMergeCall", _get_multi_worker_mirrored_creator(required_gpus=2, use_merge_call=False), has_chief=True, num_workers=1, required_physical_gpus=2, pool_runner_fn=_two_worker_pool, no_xla=True, ) # chief + 3 workers, with CPU. multi_worker_mirrored_4x1_cpu = combinations.NamedDistribution( "MultiWorkerMirrored4x1CPU", _get_multi_worker_mirrored_creator(required_gpus=0), has_chief=True, num_workers=3, pool_runner_fn=_four_worker_pool, no_xla=True, ) def parameter_server_strategy_fn( name, num_workers, num_ps, required_gpus=0, variable_partitioner=DEFAULT_PARTITIONER, ): return combinations.NamedDistribution( name, _get_ps_strategy_creator( num_workers=num_workers, num_ps=num_ps, required_gpus=required_gpus, variable_partitioner=variable_partitioner, ), required_gpus=required_gpus, num_workers=num_workers, has_chief=True, num_ps=num_ps, ) parameter_server_strategy_3worker_2ps_cpu = parameter_server_strategy_fn( "ParameterServer3Worker2PSCPU", num_workers=3, num_ps=2 ) parameter_server_strategy_1worker_2ps_cpu = parameter_server_strategy_fn( "ParameterServer1Worker2PSCPU", num_workers=1, num_ps=2 ) parameter_server_strategy_3worker_2ps_1gpu = parameter_server_strategy_fn( "ParameterServer3Worker2PS1GPU", num_workers=3, num_ps=2, required_gpus=1 ) parameter_server_strategy_1worker_2ps_1gpu = parameter_server_strategy_fn( "ParameterServer1Worker2PS1GPU", num_workers=1, num_ps=2, required_gpus=1 ) graph_and_eager_modes = ["graph", "eager"] # TODO(crccw): remove after tf-nightly picks up the new API. def set_virtual_cpus_to_at_least(num_virtual_cpus): test_util.set_logical_devices_to_at_least("CPU", num_virtual_cpus) strategies_minus_tpu = [ default_strategy, one_device_strategy, one_device_strategy_gpu, mirrored_strategy_with_gpu_and_cpu, mirrored_strategy_with_two_gpus, central_storage_strategy_with_gpu_and_cpu, ] strategies_minus_default_and_tpu = [ one_device_strategy, one_device_strategy_gpu, mirrored_strategy_with_gpu_and_cpu, mirrored_strategy_with_two_gpus, ] tpu_strategies = [ tpu_strategy, # steps_per_run=2 tpu_strategy_one_step, tpu_strategy_packed_var, cloud_tpu_strategy, ] all_strategies_minus_default = strategies_minus_default_and_tpu + tpu_strategies all_strategies = strategies_minus_tpu + tpu_strategies two_replica_strategies = [ mirrored_strategy_with_gpu_and_cpu, mirrored_strategy_with_two_gpus, multi_worker_mirrored_2x1_cpu, multi_worker_mirrored_2x1_gpu, tpu_strategy, # steps_per_run=2 tpu_strategy_one_step, central_storage_strategy_with_gpu_and_cpu, ] four_replica_strategies = [ multi_worker_mirrored_2x2_gpu, multi_worker_mirrored_4x1_cpu, ] # TODO(b/159831907): replace with two_replica_strategies after the tests using # it work with MWMS. multidevice_strategies = [ mirrored_strategy_with_gpu_and_cpu, mirrored_strategy_with_two_gpus, tpu_strategy, # steps_per_run=2 tpu_strategy_one_step, ] multiworker_strategies = [ multi_worker_mirrored_2x1_cpu, multi_worker_mirrored_2x1_gpu, multi_worker_mirrored_2x2_gpu, ] def strategy_minus_tpu_combinations(): return combinations.combine( distribution=strategies_minus_tpu, mode=["graph", "eager"] ) def tpu_strategy_combinations(): return combinations.combine(distribution=tpu_strategies, mode=["graph"]) def all_strategy_combinations(): return strategy_minus_tpu_combinations() + tpu_strategy_combinations() def all_strategy_minus_default_and_tpu_combinations(): return combinations.combine( distribution=[ one_device_strategy, one_device_strategy_gpu, mirrored_strategy_with_gpu_and_cpu, mirrored_strategy_with_two_gpus, ], mode=["graph", "eager"], ) def all_strategy_combinations_minus_default(): return ( all_strategy_minus_default_and_tpu_combinations() + tpu_strategy_combinations() ) tf_export( "__internal__.distribute.combinations.central_storage_strategy_with_gpu_and_cpu", v1=[], ).export_constant(__name__, "central_storage_strategy_with_gpu_and_cpu") tf_export( "__internal__.distribute.combinations.central_storage_strategy_with_two_gpus", v1=[], ).export_constant(__name__, "central_storage_strategy_with_two_gpus") tf_export( "__internal__.distribute.combinations.cloud_tpu_strategy", v1=[] ).export_constant(__name__, "cloud_tpu_strategy") tf_export( "__internal__.distribute.combinations.default_strategy", v1=[] ).export_constant(__name__, "default_strategy") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_cpu_1_and_2", v1=[], ).export_constant(__name__, "mirrored_strategy_with_cpu_1_and_2") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_two_cpus", v1=[], ).export_constant(__name__, "mirrored_strategy_with_two_cpus") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_gpu_and_cpu", v1=[], ).export_constant(__name__, "mirrored_strategy_with_gpu_and_cpu") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_one_cpu", v1=[] ).export_constant(__name__, "mirrored_strategy_with_one_cpu") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_one_gpu", v1=[] ).export_constant(__name__, "mirrored_strategy_with_one_gpu") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_two_gpus", v1=[], ).export_constant(__name__, "mirrored_strategy_with_two_gpus") tf_export( "__internal__.distribute.combinations.mirrored_strategy_with_two_gpus_no_merge_call", v1=[], ).export_constant(__name__, "mirrored_strategy_with_two_gpus_no_merge_call") tf_export( "__internal__.distribute.combinations.multi_worker_mirrored_2x1_cpu", v1=[] ).export_constant(__name__, "multi_worker_mirrored_2x1_cpu") tf_export( "__internal__.distribute.combinations.multi_worker_mirrored_2x1_gpu", v1=[] ).export_constant(__name__, "multi_worker_mirrored_2x1_gpu") tf_export( "__internal__.distribute.combinations.multi_worker_mirrored_2x1_gpu_noshare", v1=[], ).export_constant(__name__, "multi_worker_mirrored_2x1_gpu_noshare") tf_export( "__internal__.distribute.combinations.multi_worker_mirrored_2x2_gpu", v1=[] ).export_constant(__name__, "multi_worker_mirrored_2x2_gpu") tf_export( "__internal__.distribute.combinations.multi_worker_mirrored_2x2_gpu_no_merge_call", v1=[], ).export_constant(__name__, "multi_worker_mirrored_2x2_gpu_no_merge_call") tf_export( "__internal__.distribute.combinations.one_device_strategy", v1=[] ).export_constant(__name__, "one_device_strategy") tf_export( "__internal__.distribute.combinations.one_device_strategy_gpu", v1=[] ).export_constant(__name__, "one_device_strategy_gpu") tf_export( "__internal__.distribute.combinations.tpu_strategy", v1=[] ).export_constant(__name__, "tpu_strategy") tf_export( "__internal__.distribute.combinations.parameter_server_strategy_3worker_2ps_cpu", v1=[], ).export_constant(__name__, "parameter_server_strategy_3worker_2ps_cpu") tf_export( "__internal__.distribute.combinations.parameter_server_strategy_1worker_2ps_cpu", v1=[], ).export_constant(__name__, "parameter_server_strategy_1worker_2ps_cpu") tf_export( "__internal__.distribute.combinations.parameter_server_strategy_3worker_2ps_1gpu", v1=[], ).export_constant(__name__, "parameter_server_strategy_3worker_2ps_1gpu") tf_export( "__internal__.distribute.combinations.parameter_server_strategy_1worker_2ps_1gpu", v1=[], ).export_constant(__name__, "parameter_server_strategy_1worker_2ps_1gpu") tf_export( "__internal__.distribute.combinations.tpu_strategy_one_core", v1=[] ).export_constant(__name__, "tpu_strategy_one_core") tf_export( "__internal__.distribute.combinations.tpu_strategy_packed_var", v1=[] ).export_constant(__name__, "tpu_strategy_packed_var")