• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ==============================================================================
15"""Functions for configuring TensorFlow execution."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21from typing import Union
22
23from tensorflow.python.eager import context
24from tensorflow.python.util import _pywrap_tensor_float_32_execution
25from tensorflow.python.util import deprecation
26from tensorflow.python.util.tf_export import tf_export
27
28
29@tf_export('config.experimental.tensor_float_32_execution_enabled')
30def tensor_float_32_execution_enabled():
31  """Returns whether TensorFloat-32 is enabled.
32
33  By default, TensorFloat-32 is enabled, but this can be changed with
34  `tf.config.experimental.enable_tensor_float_32_execution`.
35
36  Returns:
37    True if TensorFloat-32 is enabled (the default) and False otherwise
38  """
39  return _pywrap_tensor_float_32_execution.is_enabled()
40
41
42@tf_export('config.experimental.enable_tensor_float_32_execution')
43def enable_tensor_float_32_execution(enabled):
44  """Enable or disable the use of TensorFloat-32 on supported hardware.
45
46  [TensorFloat-32](https://blogs.nvidia.com/blog/2020/05/14/tensorfloat-32-precision-format),
47  or TF32 for short, is a math mode for NVIDIA Ampere GPUs. TensorFloat-32
48  execution causes certain float32 ops, such as matrix multiplications and
49  convolutions, to run much faster on Ampere GPUs but with reduced precision.
50  This reduced precision should not impact convergence of deep learning models
51  in practice.
52
53  TensorFloat-32 is enabled by default. TensorFloat-32 is only supported on
54  Ampere GPUs, so all other hardware will use the full float32 precision
55  regardless of whether TensorFloat-32 is enabled or not. If you want to use the
56  full float32 precision on Ampere, you can disable TensorFloat-32 execution
57  with this function. For example:
58
59  ```python
60  x = tf.fill((2, 2), 1.0001)
61  y = tf.fill((2, 2), 1.)
62  # TensorFloat-32 is enabled, so matmul is run with reduced precision
63  print(tf.linalg.matmul(x, y))  # [[2., 2.], [2., 2.]]
64  tf.config.experimental.enable_tensor_float_32_execution(False)
65  # Matmul is run with full precision
66  print(tf.linalg.matmul(x, y))  # [[2.0002, 2.0002], [2.0002, 2.0002]]
67  ```
68
69  To check whether TensorFloat-32 execution is currently enabled, use
70  `tf.config.experimental.tensor_float_32_execution_enabled`.
71
72  If TensorFloat-32 is enabled, float32 inputs of supported ops, such as
73  `tf.linalg.matmul`, will be rounded from 23 bits of precision to 10 bits of
74  precision in most cases. This allows the ops to execute much faster by
75  utilizing the GPU's tensor cores. TensorFloat-32 has the same dynamic range as
76  float32, meaning it is no more likely to underflow or overflow than float32.
77  Ops still use float32 accumulation when TensorFloat-32 is enabled. Enabling or
78  disabling TensorFloat-32 only affects Ampere GPUs and subsequent GPUs that
79  support TensorFloat-32.
80
81  Note TensorFloat-32 is not always used in supported ops, as only inputs of
82  certain shapes are supported. Support for more input shapes and more ops may
83  be added in the future. As a result, precision of float32 ops may decrease in
84  minor versions of TensorFlow.
85
86  TensorFloat-32 is also used for some complex64 ops. Currently, TensorFloat-32
87  is used in fewer cases for complex64 as it is for float32.
88
89  Args:
90    enabled: Bool indicating whether to enable TensorFloat-32 execution.
91  """
92  _pywrap_tensor_float_32_execution.enable(enabled)
93
94
95@tf_export('config.threading.get_intra_op_parallelism_threads')
96def get_intra_op_parallelism_threads():
97  """Get number of threads used within an individual op for parallelism.
98
99  Certain operations like matrix multiplication and reductions can utilize
100  parallel threads for speed ups. A value of 0 means the system picks an
101  appropriate number.
102
103  Returns:
104    Number of parallel threads
105  """
106  return context.context().intra_op_parallelism_threads
107
108
109@tf_export('config.threading.set_intra_op_parallelism_threads')
110def set_intra_op_parallelism_threads(num_threads):
111  """Set number of threads used within an individual op for parallelism.
112
113  Certain operations like matrix multiplication and reductions can utilize
114  parallel threads for speed ups. A value of 0 means the system picks an
115  appropriate number.
116
117  Args:
118    num_threads: Number of parallel threads
119  """
120  context.context().intra_op_parallelism_threads = num_threads
121
122
123@tf_export('config.threading.get_inter_op_parallelism_threads')
124def get_inter_op_parallelism_threads():
125  """Get number of threads used for parallelism between independent operations.
126
127  Determines the number of threads used by independent non-blocking operations.
128  0 means the system picks an appropriate number.
129
130  Returns:
131    Number of parallel threads
132  """
133  return context.context().inter_op_parallelism_threads
134
135
136@tf_export('config.threading.set_inter_op_parallelism_threads')
137def set_inter_op_parallelism_threads(num_threads):
138  """Set number of threads used for parallelism between independent operations.
139
140  Determines the number of threads used by independent non-blocking operations.
141  0 means the system picks an appropriate number.
142
143  Args:
144    num_threads: Number of parallel threads
145  """
146  context.context().inter_op_parallelism_threads = num_threads
147
148
149@tf_export('config.optimizer.get_jit')
150def get_optimizer_jit() -> str:
151  """Returns JIT compilation configuration for code inside `tf.function`.
152
153  Possible return values:
154     -`"autoclustering"` if
155     [autoclustering](https://www.tensorflow.org/xla#auto-clustering) is enabled
156     - `""` when no default compilation is applied.
157  """
158  if context.context().optimizer_jit:
159    return 'autoclustering'
160  return ''
161
162
163@tf_export('config.optimizer.set_jit')
164@deprecation.deprecated_arg_values(
165    None,
166    '`True` setting is deprecated, use `autoclustering` instead.',
167    warn_once=True,
168    jit_config=True)
169def set_optimizer_jit(enabled: Union[bool, str]):
170  """Configure JIT compilation.
171
172  Note: compilation is only applied to code that is compiled into a
173  graph (in TF2 that's only a code inside `tf.function`).
174
175  Args:
176    enabled: JIT compilation configuration.
177    Possible values:
178     - `"autoclustering"` (`True` is a deprecated alias): perform
179     [autoclustering](https://www.tensorflow.org/xla#auto-clustering)
180     (automatically identify and compile clusters of nodes) on all graphs using
181     [XLA](https://www.tensorflow.org/xla).
182     - `False`: do not automatically compile any graphs.
183  """
184  autoclustering_enabled = enabled in (True, 'autoclustering')
185  context.context().optimizer_jit = autoclustering_enabled
186
187
188@tf_export('config.optimizer.get_experimental_options')
189def get_optimizer_experimental_options():
190  """Get experimental optimizer options.
191
192  Refer to tf.config.optimizer.set_experimental_options for a list of current
193  options.
194
195  Note that optimizations are only applied in graph mode, (within tf.function).
196  In addition, as these are experimental options, the list is subject to change.
197
198  Returns:
199    Dictionary of configured experimental optimizer options
200  """
201  return context.context().get_optimizer_experimental_options()
202
203
204@tf_export('config.optimizer.set_experimental_options')
205def set_optimizer_experimental_options(options):
206  """Set experimental optimizer options.
207
208  Note that optimizations are only applied in graph mode, (within tf.function).
209  In addition, as these are experimental options, the list is subject to change.
210
211  Args:
212    options: Dictionary of experimental optimizer options to configure.
213      Valid keys:
214      - layout_optimizer: Optimize tensor layouts
215        e.g. This will try to use NCHW layout on GPU which is faster.
216      - constant_folding: Fold constants
217        Statically infer the value of tensors when possible, and materialize the
218        result using constants.
219      - shape_optimization: Simplify computations made on shapes.
220      - remapping: Remap subgraphs onto more efficient implementations.
221      - arithmetic_optimization: Simplify arithmetic ops with common
222        sub-expression elimination and arithmetic simplification.
223      - dependency_optimization: Control dependency optimizations. Remove
224        redundant control dependencies, which may enable other optimization.
225        This optimizer is also essential for pruning Identity and NoOp nodes.
226      - loop_optimization: Loop optimizations.
227      - function_optimization: Function optimizations and inlining.
228      - debug_stripper: Strips debug-related nodes from the graph.
229      - disable_model_pruning: Disable removal of unnecessary ops from the graph
230      - scoped_allocator_optimization: Try to allocate some independent Op
231        outputs contiguously in order to merge or eliminate downstream Ops.
232      - pin_to_host_optimization: Force small ops onto the CPU.
233      - implementation_selector: Enable the swap of kernel implementations based
234        on the device placement.
235      - auto_mixed_precision: Change certain float32 ops to float16 on Volta
236        GPUs and above. Without the use of loss scaling, this can cause
237        numerical underflow (see
238        `keras.mixed_precision.experimental.LossScaleOptimizer`).
239      - disable_meta_optimizer: Disable the entire meta optimizer.
240      - min_graph_nodes: The minimum number of nodes in a graph to optimizer.
241        For smaller graphs, optimization is skipped.
242  """
243  context.context().set_optimizer_experimental_options(options)
244
245
246@tf_export('config.get_soft_device_placement')
247def get_soft_device_placement():
248  """Get if soft device placement is enabled.
249
250  If enabled, an op will be placed on CPU if any of the following are true
251    1. there's no GPU implementation for the OP
252    2. no GPU devices are known or registered
253    3. need to co-locate with reftype input(s) which are from CPU
254
255  Returns:
256    If soft placement is enabled.
257  """
258  return context.context().soft_device_placement
259
260
261@tf_export('config.set_soft_device_placement')
262def set_soft_device_placement(enabled):
263  """Set if soft device placement is enabled.
264
265  If enabled, an op will be placed on CPU if any of the following are true
266    1. there's no GPU implementation for the OP
267    2. no GPU devices are known or registered
268    3. need to co-locate with reftype input(s) which are from CPU
269
270  Args:
271    enabled: Whether to enable soft placement.
272  """
273  context.context().soft_device_placement = enabled
274
275
276@tf_export('config.experimental.get_device_policy')
277def get_device_policy():
278  """Gets the current device policy.
279
280  The device policy controls how operations requiring inputs on a specific
281  device (e.g., on GPU:0) handle inputs on a different device (e.g. GPU:1).
282
283  This function only gets the device policy for the current thread. Any
284  subsequently started thread will again use the default policy.
285
286  Returns:
287    Current thread device policy
288  """
289  device_policy = context.context().device_policy
290  if device_policy == context.DEVICE_PLACEMENT_SILENT:
291    return 'silent'
292  elif device_policy == context.DEVICE_PLACEMENT_SILENT_FOR_INT32:
293    return 'silent_for_int32'
294  elif device_policy == context.DEVICE_PLACEMENT_WARN:
295    return 'warn'
296  elif device_policy == context.DEVICE_PLACEMENT_EXPLICIT:
297    return 'explicit'
298  else:
299    raise ValueError('Not a valid device policy: %r' % device_policy)
300
301
302@tf_export('config.experimental.set_device_policy')
303def set_device_policy(device_policy):
304  """Sets the current thread device policy.
305
306  The device policy controls how operations requiring inputs on a specific
307  device (e.g., on GPU:0) handle inputs on a different device (e.g. GPU:1).
308
309  When using the default, an appropriate policy will be picked automatically.
310  The default policy may change over time.
311
312  This function only sets the device policy for the current thread. Any
313  subsequently started thread will again use the default policy.
314
315  Args:
316    device_policy: A device policy.
317      Valid values:
318      - None: Switch to a system default.
319      - 'warn': Copies the tensors which are not on the right device and logs
320          a warning.
321      - 'explicit': Raises an error if the placement is not as required.
322      - 'silent': Silently copies the tensors. Note that this may hide
323          performance problems as there is no notification provided when
324          operations are blocked on the tensor being copied between devices.
325      - 'silent_for_int32': silently copies `int32` tensors, raising errors on
326          the other ones.
327
328  Raises:
329      ValueError: If an invalid `device_policy` is passed.
330  """
331  if device_policy == 'silent':
332    context.context().device_policy = context.DEVICE_PLACEMENT_SILENT
333  elif device_policy == 'silent_for_int32':
334    context.context().device_policy = context.DEVICE_PLACEMENT_SILENT_FOR_INT32
335  elif device_policy == 'warn':
336    context.context().device_policy = context.DEVICE_PLACEMENT_WARN
337  elif device_policy == 'explicit':
338    context.context().device_policy = context.DEVICE_PLACEMENT_EXPLICIT
339  elif device_policy is None:
340    context.context().device_policy = None
341  else:
342    raise ValueError('Not a valid device policy: %r' % device_policy)
343
344
345@tf_export('config.experimental.get_synchronous_execution')
346def get_synchronous_execution():
347  """Gets whether operations are executed synchronously or asynchronously.
348
349  TensorFlow can execute operations synchronously or asynchronously. If
350  asynchronous execution is enabled, operations may return "non-ready" handles.
351
352  Returns:
353    Current thread execution mode
354  """
355  return context.context().execution_mode == context.SYNC
356
357
358@tf_export('config.experimental.set_synchronous_execution')
359def set_synchronous_execution(enable):
360  """Specifies whether operations are executed synchronously or asynchronously.
361
362  TensorFlow can execute operations synchronously or asynchronously. If
363  asynchronous execution is enabled, operations may return "non-ready" handles.
364
365  When `enable` is set to None, an appropriate value will be picked
366  automatically. The value picked may change between TensorFlow releases.
367
368  Args:
369    enable: Whether operations should be dispatched synchronously.
370      Valid values:
371      - None: sets the system default.
372      - True: executes each operation synchronously.
373      - False: executes each operation asynchronously.
374  """
375  if enable is None:
376    context.context().execution_mode = None
377  elif enable:
378    context.context().execution_mode = context.SYNC
379  else:
380    context.context().execution_mode = context.ASYNC
381
382
383@tf_export('config.list_physical_devices',
384           'config.experimental.list_physical_devices')
385@deprecation.deprecated_endpoints(
386    'config.experimental.list_physical_devices')
387def list_physical_devices(device_type=None):
388  """Return a list of physical devices visible to the host runtime.
389
390  Physical devices are hardware devices present on the host machine. By default
391  all discovered CPU and GPU devices are considered visible.
392
393  This API allows querying the physical hardware resources prior to runtime
394  initialization. Thus, giving an opportunity to call any additional
395  configuration APIs. This is in contrast to `tf.config.list_logical_devices`,
396  which triggers runtime initialization in order to list the configured devices.
397
398  The following example lists the number of visible GPUs on the host.
399
400  >>> physical_devices = tf.config.list_physical_devices('GPU')
401  >>> print("Num GPUs:", len(physical_devices))
402  Num GPUs: ...
403
404  However, the number of GPUs available to the runtime may change during runtime
405  initialization due to marking certain devices as not visible or configuring
406  multiple logical devices.
407
408  Args:
409    device_type: (optional string) Only include devices matching this device
410      type. For example "CPU" or "GPU".
411
412  Returns:
413    List of discovered `tf.config.PhysicalDevice` objects
414  """
415  return context.context().list_physical_devices(device_type)
416
417
418@tf_export('config.list_logical_devices',
419           'config.experimental.list_logical_devices')
420@deprecation.deprecated_endpoints(
421    'config.experimental.list_logical_devices')
422def list_logical_devices(device_type=None):
423  """Return a list of logical devices created by runtime.
424
425  Logical devices may correspond to physical devices or remote devices in the
426  cluster. Operations and tensors may be placed on these devices by using the
427  `name` of the `tf.config.LogicalDevice`.
428
429  Calling `tf.config.list_logical_devices` triggers the runtime to configure any
430  `tf.config.PhysicalDevice` visible to the runtime, thereby preventing
431  further configuration. To avoid runtime initialization, call
432  `tf.config.list_physical_devices` instead.
433
434  For example:
435
436  >>> logical_devices = tf.config.list_logical_devices('GPU')
437  >>> if len(logical_devices) > 0:
438  ...   # Allocate on GPU:0
439  ...   with tf.device(logical_devices[0].name):
440  ...     one = tf.constant(1)
441  ...   # Allocate on GPU:1
442  ...   with tf.device(logical_devices[1].name):
443  ...     two = tf.constant(2)
444
445  Args:
446    device_type: (optional string) Only include devices matching this device
447      type. For example "CPU" or "GPU".
448
449  Returns:
450    List of initialized `LogicalDevice`s
451  """
452  return context.context().list_logical_devices(device_type=device_type)
453
454
455@tf_export('config.get_visible_devices',
456           'config.experimental.get_visible_devices')
457@deprecation.deprecated_endpoints(
458    'config.experimental.get_visible_devices')
459def get_visible_devices(device_type=None):
460  """Get the list of visible physical devices.
461
462  Returns the list of `PhysicalDevice`s currently marked as visible to the
463  runtime. A visible device will have at least one `LogicalDevice` associated
464  with it once the runtime is initialized.
465
466  The following example verifies all visible GPUs have been disabled:
467
468  >>> physical_devices = tf.config.list_physical_devices('GPU')
469  >>> try:
470  ...   # Disable all GPUS
471  ...   tf.config.set_visible_devices([], 'GPU')
472  ...   visible_devices = tf.config.get_visible_devices()
473  ...   for device in visible_devices:
474  ...     assert device.device_type != 'GPU'
475  ... except:
476  ...   # Invalid device or cannot modify virtual devices once initialized.
477  ...   pass
478
479  Args:
480    device_type: (optional string) Only include devices matching this device
481      type. For example "CPU" or "GPU".
482
483  Returns:
484    List of visible `PhysicalDevice`s
485  """
486  return context.context().get_visible_devices(device_type)
487
488
489@tf_export('config.set_visible_devices',
490           'config.experimental.set_visible_devices')
491@deprecation.deprecated_endpoints(
492    'config.experimental.set_visible_devices')
493def set_visible_devices(devices, device_type=None):
494  """Set the list of visible devices.
495
496  Specifies which `PhysicalDevice` objects are visible to the runtime.
497  TensorFlow will only allocate memory and place operations on visible
498  physical devices, as otherwise no `LogicalDevice` will be created on them.
499  By default all discovered devices are marked as visible.
500
501  The following example demonstrates disabling the first GPU on the machine.
502
503  >>> physical_devices = tf.config.list_physical_devices('GPU')
504  >>> try:
505  ...   # Disable first GPU
506  ...   tf.config.set_visible_devices(physical_devices[1:], 'GPU')
507  ...   logical_devices = tf.config.list_logical_devices('GPU')
508  ...   # Logical device was not created for first GPU
509  ...   assert len(logical_devices) == len(physical_devices) - 1
510  ... except:
511  ...   # Invalid device or cannot modify virtual devices once initialized.
512  ...   pass
513
514  Args:
515    devices: List of `PhysicalDevice`s to make visible
516    device_type: (optional) Only configure devices matching this device type.
517      For example "CPU" or "GPU". Other devices will be left unaltered.
518
519  Raises:
520    ValueError: If argument validation fails.
521    RuntimeError: Runtime is already initialized.
522  """
523  context.context().set_visible_devices(devices, device_type)
524
525
526@tf_export('config.experimental.get_memory_info')
527def get_memory_info(device):
528  """Get memory info for the chosen device, as a dict.
529
530  This function returns a dict containing information about the device's memory
531  usage. For example:
532
533  >>> if tf.config.list_physical_devices('GPU'):
534  ...   # Returns a dict in the form {'current': <current mem usage>,
535  ...   #                             'peak': <peak mem usage>}
536  ...   tf.config.experimental.get_memory_info('GPU:0')
537
538  Currently returns the following keys:
539    `'current'`: The current memory used by the device, in bytes.
540    `'peak'`: The peak memory used by the device across the run of the program,
541        in bytes.
542
543  More keys may be added in the future, including device-specific keys.
544
545  Currently raises an exception for the CPU.
546
547  For GPUs, TensorFlow will allocate all the memory by default, unless changed
548  with `tf.config.experimental.set_memory_growth`. The dict specifies only the
549  current and peak memory that TensorFlow is actually using, not the memory that
550  TensorFlow has allocated on the GPU.
551
552  Args:
553    device: Device string to get the memory information for, e.g. `"GPU:0"`. See
554      https://www.tensorflow.org/api_docs/python/tf/device for specifying device
555      strings.
556
557  Returns:
558    A dict with keys `'current'` and `'peak'`, specifying the current and peak
559    memory usage respectively.
560
561  Raises:
562    ValueError: Non-existent or CPU device specified.
563
564  """
565  return context.context().get_memory_info(device)
566
567
568@deprecation.deprecated(
569    None,
570    "Use tf.config.experimental.get_memory_info(device)['current'] instead.")
571@tf_export('config.experimental.get_memory_usage')
572def get_memory_usage(device):
573  """Get the current memory usage, in bytes, for the chosen device.
574
575  This function is deprecated in favor of
576  `tf.config.experimental.get_memory_info`. Calling this function is equivalent
577  to calling `tf.config.experimental.get_memory_info()['current']`.
578
579  See https://www.tensorflow.org/api_docs/python/tf/device for specifying device
580  strings.
581
582  For example:
583
584  >>> gpu_devices = tf.config.list_physical_devices('GPU')
585  >>> if gpu_devices:
586  ...   tf.config.experimental.get_memory_usage('GPU:0')
587
588  Does not work for CPU.
589
590  For GPUs, TensorFlow will allocate all the memory by default, unless changed
591  with `tf.config.experimental.set_memory_growth`. This function only returns
592  the memory that TensorFlow is actually using, not the memory that TensorFlow
593  has allocated on the GPU.
594
595  Args:
596    device: Device string to get the bytes in use for, e.g. `"GPU:0"`
597
598  Returns:
599    Total memory usage in bytes.
600
601  Raises:
602    ValueError: Non-existent or CPU device specified.
603  """
604  return get_memory_info(device)['current']
605
606
607@tf_export('config.experimental.get_memory_growth')
608def get_memory_growth(device):
609  """Get if memory growth is enabled for a `PhysicalDevice`.
610
611  If memory growth is enabled for a `PhysicalDevice`, the runtime initialization
612  will not allocate all memory on the device.
613
614  For example:
615
616  >>> physical_devices = tf.config.list_physical_devices('GPU')
617  >>> try:
618  ...   tf.config.experimental.set_memory_growth(physical_devices[0], True)
619  ...   assert tf.config.experimental.get_memory_growth(physical_devices[0])
620  ... except:
621  ...   # Invalid device or cannot modify virtual devices once initialized.
622  ...   pass
623
624  Args:
625    device: `PhysicalDevice` to query
626
627  Returns:
628    A boolean indicating the memory growth setting for the `PhysicalDevice`.
629
630  Raises:
631    ValueError: Invalid `PhysicalDevice` specified.
632  """
633  return context.context().get_memory_growth(device)
634
635
636@tf_export('config.experimental.set_memory_growth')
637def set_memory_growth(device, enable):
638  """Set if memory growth should be enabled for a `PhysicalDevice`.
639
640  If memory growth is enabled for a `PhysicalDevice`, the runtime initialization
641  will not allocate all memory on the device. Memory growth cannot be configured
642  on a `PhysicalDevice` with virtual devices configured.
643
644  For example:
645
646  >>> physical_devices = tf.config.list_physical_devices('GPU')
647  >>> try:
648  ...   tf.config.experimental.set_memory_growth(physical_devices[0], True)
649  ... except:
650  ...   # Invalid device or cannot modify virtual devices once initialized.
651  ...   pass
652
653  Args:
654    device: `PhysicalDevice` to configure
655    enable: (Boolean) Whether to enable or disable memory growth
656
657  Raises:
658    ValueError: Invalid `PhysicalDevice` specified.
659    RuntimeError: Runtime is already initialized.
660  """
661  context.context().set_memory_growth(device, enable)
662
663
664@tf_export('config.experimental.get_device_details')
665def get_device_details(device):
666  """Returns details about a physical devices.
667
668  This API takes in a `tf.config.PhysicalDevice` returned by
669  `tf.config.list_physical_devices`. It returns a dict with string keys
670  containing various details about the device. Each key is only supported by a
671  subset of devices, so you should not assume the returned dict will have any
672  particular key.
673
674  >>> gpu_devices = tf.config.list_physical_devices('GPU')
675  >>> if gpu_devices:
676  ...   details = tf.config.experimental.get_device_details(gpu_devices[0])
677  ...   details.get('device_name', 'Unknown GPU')
678
679  Currently, details are only returned for GPUs. This function returns an
680  empty dict if passed a non-GPU device.
681
682  The returned dict may have the following keys:
683  * `'device_name'`: A human-readable name of the device as a string, e.g.
684    "Titan V". Unlike `tf.config.PhysicalDevice.name`, this will be the same for
685    multiple devices if each device is the same model. Currently only available
686    for GPUs.
687  * `'compute_capability'`: The
688    [compute capability](https://developer.nvidia.com/cuda-gpus) of the device
689    as a tuple of two ints, in the form `(major_version, minor_version)`. Only
690    available for NVIDIA GPUs
691
692  Note: This is similar to `tf.sysconfig.get_build_info` in that both functions
693  can return information relating to GPUs. However, this function returns
694  run-time information about a specific device (such as a GPU's compute
695  capability), while `tf.sysconfig.get_build_info` returns compile-time
696  information about how TensorFlow was built (such as what version of CUDA
697  TensorFlow was built for).
698
699  Args:
700    device: A `tf.config.PhysicalDevice` returned by
701      `tf.config.list_physical_devices` or `tf.config.get_visible_devices`.
702
703  Returns:
704    A dict with string keys.
705  """
706  return context.context().get_device_details(device)
707
708
709@tf_export('config.get_logical_device_configuration',
710           'config.experimental.get_virtual_device_configuration')
711@deprecation.deprecated_endpoints(
712    'config.experimental.get_virtual_device_configuration')
713def get_logical_device_configuration(device):
714  """Get the virtual device configuration for a `tf.config.PhysicalDevice`.
715
716  Returns the list of `tf.config.LogicalDeviceConfiguration`
717  objects previously configured by a call to
718  `tf.config.set_logical_device_configuration`.
719
720  For example:
721
722  >>> physical_devices = tf.config.list_physical_devices('CPU')
723  >>> assert len(physical_devices) == 1, "No CPUs found"
724  >>> configs = tf.config.get_logical_device_configuration(
725  ...   physical_devices[0])
726  >>> try:
727  ...   assert configs is None
728  ...   tf.config.set_logical_device_configuration(
729  ...     physical_devices[0],
730  ...     [tf.config.LogicalDeviceConfiguration(),
731  ...      tf.config.LogicalDeviceConfiguration()])
732  ...   configs = tf.config.get_logical_device_configuration(
733  ...     physical_devices[0])
734  ...   assert len(configs) == 2
735  ... except:
736  ...   # Cannot modify virtual devices once initialized.
737  ...   pass
738
739  Args:
740    device: `PhysicalDevice` to query
741
742  Returns:
743    List of `tf.config.LogicalDeviceConfiguration` objects or
744    `None` if no virtual device configuration has been set for this physical
745    device.
746  """
747  return context.context().get_logical_device_configuration(device)
748
749
750@tf_export('config.set_logical_device_configuration',
751           'config.experimental.set_virtual_device_configuration')
752@deprecation.deprecated_endpoints(
753    'config.experimental.set_virtual_device_configuration')
754def set_logical_device_configuration(device, logical_devices):
755  """Set the logical device configuration for a `tf.config.PhysicalDevice`.
756
757  A visible `tf.config.PhysicalDevice` will by default have a single
758  `tf.config.LogicalDevice` associated with it once the runtime is initialized.
759  Specifying a list of `tf.config.LogicalDeviceConfiguration` objects allows
760  multiple devices to be created on the same `tf.config.PhysicalDevice`.
761
762  The following example splits the CPU into 2 logical devices:
763
764  >>> physical_devices = tf.config.list_physical_devices('CPU')
765  >>> assert len(physical_devices) == 1, "No CPUs found"
766  >>> # Specify 2 virtual CPUs. Note currently memory limit is not supported.
767  >>> try:
768  ...   tf.config.set_logical_device_configuration(
769  ...     physical_devices[0],
770  ...     [tf.config.LogicalDeviceConfiguration(),
771  ...      tf.config.LogicalDeviceConfiguration()])
772  ...   logical_devices = tf.config.list_logical_devices('CPU')
773  ...   assert len(logical_devices) == 2
774  ...
775  ...   tf.config.set_logical_device_configuration(
776  ...     physical_devices[0],
777  ...     [tf.config.LogicalDeviceConfiguration(),
778  ...      tf.config.LogicalDeviceConfiguration(),
779  ...      tf.config.LogicalDeviceConfiguration(),
780  ...      tf.config.LogicalDeviceConfiguration()])
781  ... except:
782  ...   # Cannot modify logical devices once initialized.
783  ...   pass
784
785  The following example splits the GPU into 2 logical devices with 100 MB each:
786
787  >>> physical_devices = tf.config.list_physical_devices('GPU')
788  >>> try:
789  ...   tf.config.set_logical_device_configuration(
790  ...     physical_devices[0],
791  ...     [tf.config.LogicalDeviceConfiguration(memory_limit=100),
792  ...      tf.config.LogicalDeviceConfiguration(memory_limit=100)])
793  ...
794  ...   logical_devices = tf.config.list_logical_devices('GPU')
795  ...   assert len(logical_devices) == len(physical_devices) + 1
796  ...
797  ...   tf.config.set_logical_device_configuration(
798  ...     physical_devices[0],
799  ...     [tf.config.LogicalDeviceConfiguration(memory_limit=10),
800  ...      tf.config.LogicalDeviceConfiguration(memory_limit=10)])
801  ... except:
802  ...   # Invalid device or cannot modify logical devices once initialized.
803  ...   pass
804
805  Args:
806    device: The `PhysicalDevice` to configure.
807    logical_devices: (optional) List of `tf.config.LogicalDeviceConfiguration`
808      objects to allocate for the specified `PhysicalDevice`. If None, the
809      default configuration will be used.
810
811  Raises:
812    ValueError: If argument validation fails.
813    RuntimeError: Runtime is already initialized.
814  """
815  context.context().set_logical_device_configuration(device, logical_devices)
816
817
818@tf_export('config.experimental.enable_mlir_bridge')
819def enable_mlir_bridge():
820  """Enables experimental MLIR-Based TensorFlow Compiler Bridge.
821
822  DO NOT USE, DEV AND TESTING ONLY AT THE MOMENT.
823
824  NOTE: MLIR-Based TensorFlow Compiler is under active development and has
825  missing features, please refrain from using. This API exists for development
826  and testing only.
827
828  TensorFlow Compiler Bridge (TF Bridge) is responsible for translating parts
829  of TensorFlow graph into a form that can be accepted as an input by a backend
830  compiler such as XLA.
831  """
832  context.context().enable_mlir_bridge = True
833
834
835@tf_export('config.experimental.enable_mlir_graph_optimization')
836def enable_mlir_graph_optimization():
837  """Enables experimental MLIR-Based TensorFlow Compiler Optimizations.
838
839  DO NOT USE, DEV AND TESTING ONLY AT THE MOMENT.
840
841  NOTE: MLIR-Based TensorFlow Compiler is under active development and has
842  missing features, please refrain from using. This API exists for development
843  and testing only.
844
845  TensorFlow Compiler Optimizations are responsible general graph level
846  optimizations that in the current stack mostly done by Grappler graph
847  optimizers.
848  """
849  context.context().enable_mlir_graph_optimization = True
850
851
852@tf_export('config.experimental.disable_mlir_bridge')
853def disable_mlir_bridge():
854  """Disables experimental MLIR-Based TensorFlow Compiler Bridge."""
855  context.context().enable_mlir_bridge = False
856
857
858@tf_export('config.experimental.disable_mlir_graph_optimization')
859def disable_mlir_graph_optimization():
860  """Disables experimental MLIR-Based TensorFlow Compiler Optimizations."""
861  context.context().enable_mlir_graph_optimization = False
862