Skip to content

Alternative to run_all_in_graph_and_eager_mode #1288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 17, 2020
Merged

Alternative to run_all_in_graph_and_eager_mode #1288

merged 5 commits into from
Mar 17, 2020

Conversation

gabrieldemarmiesse
Copy link
Member

@gabrieldemarmiesse gabrieldemarmiesse commented Mar 11, 2020

So, replacing this run_all_in_graph_and_eager_mode is quite difficult but it's worth it for two reasons:

  • It's not a public API, so it can go away at any time. The behavior can change silently.
  • We don't need to execute the test methods in graph mode. We only need to execute a small part of the test in graph mode (for the layers, it's the call method, for the metrics/losses, it's the update_state...). It allows us to enjoy the eager mode outside those selected functions and we don't have to do self.session self.evaluate(tf.compat.v1.initialize_global_variables(...)). We can just do .numpy() to get results. This has the benefit to make testing much easier and bring new contributors who might be put off by this testing which looks like coding in tensorflow 1.x.
  • It does not run tf.function in eager mode. So it's not actually helping us at all. I think it's just a TF 1.x relict and is useful only to force graph mode when tf.function is not present. See [WIP] Should break in eager mode. #1289

So how to do that, in a clean way? Well that's more or less difficult.

From the discussion in #13 , all public functions should have the @tf.functions decorator. #807 shows that it's a problem when using python variables, but in this case, we should just use the input_signature to convert automatically scalars to tensorflow tensors. See https://www.tensorflow.org/api_docs/python/tf/function . We can even add tests to ensure we don't draw the graph multiple times with the method get_concrete_function.

We already use tf.function many time in the codebase, and even when we don't use it, keras enforce it with black magic when subclassing Metric or even Layer.

Let's then assume that all public functions have the tf.function decorator.

Here is my proposal. It uses pytest features and it won't work when subclassing tf.test.TestCase. But I believe we don't need subclassing anyway for most of the tests present in tf.addons. Worst case scenario we can code it again for tf.test.TestCase with the absl parametrize decorator.

conftest.py must be present when running the tests which means that we need to make bazel aware of it. This is why I linked it to tensorflow_addons/utils which is present all the time in the tests.

Some reference:
https://docs.pytest.org/en/latest/fixture.html

@gabrieldemarmiesse gabrieldemarmiesse changed the title Alternative to run_all_in_graph_and_eager_mode for testing keras objects [WIP] Alternative to run_all_in_graph_and_eager_mode for testing keras objects Mar 11, 2020
@boring-cyborg boring-cyborg bot added the losses label Mar 11, 2020
@gabrieldemarmiesse gabrieldemarmiesse changed the title [WIP] Alternative to run_all_in_graph_and_eager_mode for testing keras objects Alternative to run_all_in_graph_and_eager_mode for testing keras objects Mar 11, 2020
@gabrieldemarmiesse gabrieldemarmiesse changed the title Alternative to run_all_in_graph_and_eager_mode for testing keras objects Alternative to run_all_in_graph_and_eager_mode Mar 11, 2020
Copy link
Member

@seanpmorgan seanpmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks this definitely simplifies the testing for new contributors! I think this should work since the only support for graph mode in 2.x is tf.function. It's possible some people will want to use Addons using tf.compat.v1 but to me that's outside of our scope.

Couple of clarifying questions, and then I also wish we had a better understanding of the keras black magic. Checking the metrics module it says it'll run as graph but quite difficult for me to see where that is happening:
https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/metrics.py#L218

It's possible that this isn't being controlled with tf.function in which case I think the tests should fail with or without the experimental config so probably a non-issue.

@pytest.fixture(scope="function", params=["eager_mode", "tf_function"])
def maybe_run_functions_eagerly(request):
if request.param == "eager_mode":
tf.config.experimental_run_functions_eagerly(True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I agree this is preferable to a private API, but just want to note it is still experimental and could change on us:
tensorflow/community#218

Copy link
Member Author

@gabrieldemarmiesse gabrieldemarmiesse Mar 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we communicate to the TF team that this flag is really needed on our side? So that it gets out of experimental mode? It's a much needed feature for debugging in general. CF #13 (comment)

@gabrieldemarmiesse
Copy link
Member Author

Checking the metrics module it says it'll run as graph but quite difficult for me to see where that is happening:
https://github.com/tensorflow/tensorflow/blob/v2.1.0/tensorflow/python/keras/metrics.py#L218
It's possible that this isn't being controlled with tf.function in which case I think the tests should fail with or without the experimental config so probably a non-issue.

https://github.com/tensorflow/tensorflow/blob/ac303a810d440d56033766651ddeffd3e2ee5f57/tensorflow/python/keras/metrics.py#L156

Copy link
Member

@seanpmorgan seanpmorgan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks!

@seanpmorgan seanpmorgan merged commit 66487f9 into tensorflow:master Mar 17, 2020
jrruijli pushed a commit to jrruijli/addons that referenced this pull request Dec 23, 2020
* Alternative to run_all_in_graph_and_eager_mode.

* Better names when printing stuff.

* Give another example.

* Get finalizer out.

* Moved the maybe_run_functions_eagerly to test_utils.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants