Wraps a python function and uses it as a TensorFlow op. Given a python function `func`, which takes numpy arrays as its arguments and returns numpy arrays as its outputs, wrap this function as an operation in a TensorFlow graph. The following snippet constructs a simple TensorFlow graph tha
(func, inp, Tout, stateful=True, name=None)
| 426 | |
| 427 | |
| 428 | def py_func_common(func, inp, Tout, stateful=True, name=None): |
| 429 | """Wraps a python function and uses it as a TensorFlow op. |
| 430 | |
| 431 | Given a python function `func`, which takes numpy arrays as its |
| 432 | arguments and returns numpy arrays as its outputs, wrap this function as an |
| 433 | operation in a TensorFlow graph. The following snippet constructs a simple |
| 434 | TensorFlow graph that invokes the `np.sinh()` NumPy function as a operation |
| 435 | in the graph: |
| 436 | |
| 437 | ```python |
| 438 | def my_func(x): |
| 439 | # x will be a numpy array with the contents of the placeholder below |
| 440 | return np.sinh(x) |
| 441 | input = tf.compat.v1.placeholder(tf.float32) |
| 442 | y = tf.compat.v1.py_func(my_func, [input], tf.float32) |
| 443 | ``` |
| 444 | |
| 445 | **N.B.** The `tf.compat.v1.py_func()` operation has the following known |
| 446 | limitations: |
| 447 | |
| 448 | * The body of the function (i.e. `func`) will not be serialized in a |
| 449 | `GraphDef`. Therefore, you should not use this function if you need to |
| 450 | serialize your model and restore it in a different environment. |
| 451 | |
| 452 | * The operation must run in the same address space as the Python program |
| 453 | that calls `tf.compat.v1.py_func()`. If you are using distributed |
| 454 | TensorFlow, you |
| 455 | must run a `tf.distribute.Server` in the same process as the program that |
| 456 | calls |
| 457 | `tf.compat.v1.py_func()` and you must pin the created operation to a device |
| 458 | in that |
| 459 | server (e.g. using `with tf.device():`). |
| 460 | |
| 461 | Args: |
| 462 | func: A Python function, which accepts `ndarray` objects as arguments and |
| 463 | returns a list of `ndarray` objects (or a single `ndarray`). This function |
| 464 | must accept as many arguments as there are tensors in `inp`, and these |
| 465 | argument types will match the corresponding `tf.Tensor` objects in `inp`. |
| 466 | The returns `ndarray`s must match the number and types defined `Tout`. |
| 467 | Important Note: Input and output numpy `ndarray`s of `func` are not |
| 468 | guaranteed to be copies. In some cases their underlying memory will be |
| 469 | shared with the corresponding TensorFlow tensors. In-place modification |
| 470 | or storing `func` input or return values in python datastructures |
| 471 | without explicit (np.)copy can have non-deterministic consequences. |
| 472 | inp: A list of `Tensor` objects. |
| 473 | Tout: A list or tuple of tensorflow data types or a single tensorflow data |
| 474 | type if there is only one, indicating what `func` returns. |
| 475 | stateful: (Boolean.) If True, the function should be considered stateful. If |
| 476 | a function is stateless, when given the same input it will return the same |
| 477 | output and have no observable side effects. Optimizations such as common |
| 478 | subexpression elimination are only performed on stateless operations. |
| 479 | name: A name for the operation (optional). |
| 480 | |
| 481 | Returns: |
| 482 | A list of `Tensor` or a single `Tensor` which `func` computes. |
| 483 | """ |
| 484 | if context.executing_eagerly(): |
| 485 | result = func(*[x.numpy() for x in inp]) |
no test coverage detected