• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2018 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"""Utilities for API compatibility between TensorFlow release versions.
16
17See [Version
18Compatibility](https://tensorflow.org/guide/version_compat#backward_forward)
19"""
20
21from __future__ import absolute_import
22from __future__ import division
23from __future__ import print_function
24
25import datetime
26
27from tensorflow.python.util import tf_contextlib
28from tensorflow.python.util.tf_export import tf_export
29
30_FORWARD_COMPATIBILITY_HORIZON = datetime.date(2019, 3, 15)
31
32
33@tf_export("compat.forward_compatible")
34def forward_compatible(year, month, day):
35  """Return true if the forward compatibility window has expired.
36
37  See [Version
38  compatibility](https://tensorflow.org/guide/version_compat#backward_forward).
39
40  Forward-compatibility refers to scenarios where the producer of a TensorFlow
41  model (a GraphDef or SavedModel) is compiled against a version of the
42  TensorFlow library newer than what the consumer was compiled against. The
43  "producer" is typically a Python program that constructs and trains a model
44  while the "consumer" is typically another program that loads and serves the
45  model.
46
47  TensorFlow has been supporting a 3 week forward-compatibility window for
48  programs compiled from source at HEAD.
49
50  For example, consider the case where a new operation `MyNewAwesomeAdd` is
51  created with the intent of replacing the implementation of an existing Python
52  wrapper - `tf.add`.  The Python wrapper implementation should change from
53  something like:
54
55  ```python
56  def add(inputs, name=None):
57    return gen_math_ops.add(inputs, name)
58  ```
59
60  to:
61
62  ```python
63  from tensorflow.python.compat import compat
64
65  def add(inputs, name=None):
66    if compat.forward_compatible(year, month, day):
67      # Can use the awesome new implementation.
68      return gen_math_ops.my_new_awesome_add(inputs, name)
69    # To maintain forward compatibiltiy, use the old implementation.
70    return gen_math_ops.add(inputs, name)
71  ```
72
73  Where `year`, `month`, and `day` specify the date beyond which binaries
74  that consume a model are expected to have been updated to include the
75  new operations. This date is typically at least 3 weeks beyond the date
76  the code that adds the new operation is committed.
77
78  Args:
79    year:  A year (e.g., 2018).
80    month: A month (1 <= month <= 12) in year.
81    day:   A day (1 <= day <= 31, or 30, or 29, or 28) in month.
82
83  Returns:
84    True if the caller can expect that serialized TensorFlow graphs produced
85    can be consumed by programs that are compiled with the TensorFlow library
86    source code after (year, month, day).
87  """
88  return _FORWARD_COMPATIBILITY_HORIZON > datetime.date(year, month, day)
89
90
91@tf_export("compat.forward_compatibility_horizon")
92@tf_contextlib.contextmanager
93def forward_compatibility_horizon(year, month, day):
94  """Context manager for testing forward compatibility of generated graphs.
95
96  See [Version
97  compatibility](https://tensorflow.org/guide/version_compat#backward_forward).
98
99  To ensure forward compatibility of generated graphs (see `forward_compatible`)
100  with older binaries, new features can be gated with:
101
102  ```python
103  if compat.forward_compatible(year=2018, month=08, date=01):
104    generate_graph_with_new_features()
105  else:
106    generate_graph_so_older_binaries_can_consume_it()
107  ```
108
109  However, when adding new features, one may want to unittest it before
110  the forward compatibility window expires. This context manager enables
111  such tests. For example:
112
113  ```python
114  from tensorflow.python.compat import compat
115
116  def testMyNewFeature(self):
117    with compat.forward_compatibility_horizon(2018, 08, 02):
118       # Test that generate_graph_with_new_features() has an effect
119  ```
120
121  Args :
122    year:  A year (e.g. 2018).
123    month: A month (1 <= month <= 12) in year.
124    day:   A day (1 <= day <= 31, or 30, or 29, or 28) in month.
125
126  Yields:
127    Nothing.
128  """
129  global _FORWARD_COMPATIBILITY_HORIZON
130  try:
131    old_compat_date = _FORWARD_COMPATIBILITY_HORIZON
132    _FORWARD_COMPATIBILITY_HORIZON = datetime.date(year, month, day)
133    yield
134  finally:
135    _FORWARD_COMPATIBILITY_HORIZON = old_compat_date
136