Wraps the TF 1.x function fn into a graph function. The python function `fn` will be called once with symbolic arguments specified in the `signature`, traced, and turned into a graph function. Any variables created by `fn` will be owned by the object returned by `wrap_function`. The resulti
(fn, signature, name=None)
| 540 | |
| 541 | @tf_export(v1=["wrap_function"]) |
| 542 | def wrap_function(fn, signature, name=None): |
| 543 | """Wraps the TF 1.x function fn into a graph function. |
| 544 | |
| 545 | The python function `fn` will be called once with symbolic arguments specified |
| 546 | in the `signature`, traced, and turned into a graph function. Any variables |
| 547 | created by `fn` will be owned by the object returned by `wrap_function`. The |
| 548 | resulting graph function can be called with tensors which match the |
| 549 | signature. |
| 550 | |
| 551 | ```python |
| 552 | def f(x, do_add): |
| 553 | v = tf.Variable(5.0) |
| 554 | if do_add: |
| 555 | op = v.assign_add(x) |
| 556 | else: |
| 557 | op = v.assign_sub(x) |
| 558 | with tf.control_dependencies([op]): |
| 559 | return v.read_value() |
| 560 | |
| 561 | f_add = tf.compat.v1.wrap_function(f, [tf.TensorSpec((), tf.float32), True]) |
| 562 | |
| 563 | assert float(f_add(1.0)) == 6.0 |
| 564 | assert float(f_add(1.0)) == 7.0 |
| 565 | |
| 566 | # Can call tf.compat.v1.wrap_function again to get a new trace, a new set |
| 567 | # of variables, and possibly different non-template arguments. |
| 568 | f_sub= tf.compat.v1.wrap_function(f, [tf.TensorSpec((), tf.float32), False]) |
| 569 | |
| 570 | assert float(f_sub(1.0)) == 4.0 |
| 571 | assert float(f_sub(1.0)) == 3.0 |
| 572 | ``` |
| 573 | |
| 574 | Both `tf.compat.v1.wrap_function` and `tf.function` create a callable |
| 575 | TensorFlow graph. But while `tf.function` runs all stateful operations |
| 576 | (e.g. `tf.print`) and sequences operations to provide the same semantics as |
| 577 | eager execution, `wrap_function` is closer to the behavior of `session.run` in |
| 578 | TensorFlow 1.x. It will not run any operations unless they are required to |
| 579 | compute the function's outputs, either through a data dependency or a control |
| 580 | dependency. Nor will it sequence operations. |
| 581 | |
| 582 | Unlike `tf.function`, `wrap_function` will only trace the Python function |
| 583 | once. As with placeholders in TF 1.x, shapes and dtypes must be provided to |
| 584 | `wrap_function`'s `signature` argument. |
| 585 | |
| 586 | Since it is only traced once, variables and state may be created inside the |
| 587 | function and owned by the function wrapper object. |
| 588 | |
| 589 | Args: |
| 590 | fn: python function to be wrapped |
| 591 | signature: the placeholder and python arguments to be passed to the wrapped |
| 592 | function |
| 593 | name: Optional. The name of the function. |
| 594 | |
| 595 | Returns: |
| 596 | the wrapped graph function. |
| 597 | """ |
| 598 | holder = VariableHolder(fn) |
| 599 | func_graph_name = "wrapped_function" |
no test coverage detected