tfp.experimental.auto_batching.lowering.lower_function_calls
Stay organized with collections
Save and categorize content based on your preferences.
Lowers a Program
that may have (recursive) FunctionCallOp instructions.
tfp.experimental.auto_batching.lowering.lower_function_calls(
program
)
Mutates the ControlFlowGraph
of the input program in place. After
lowering, the result CFG
What is the stack discipline? Every function body becomes a CFG
subset that:
Never transfers control in except to the first block
(corresponding to being called), or to a block stored with
PushGotoOp
(corresponding to a subroutine returning)
Never transfers control out except with IndirectGotoOp
(corresponding to returning), or with a PushGotoOp
(corresponding to calling a subroutine)
Every path through the graph has the following effect on the
variable stacks:
The formal parameters receive exactly one net pop
The return variables receive exactly one net push
All other variable stacks are left as they are
No data is read except the top frames of the formal parameter
stacks
Why mutate in place? Because tying the knot in the result seemed
too hard without an explicit indirection between Block
s and
references thereto in various Op
s. Specifically, when building a
new CFG to replicate the structure of an existing one, it is
necessary to allocate Block
s to serve as the targets of all
BranchOp
, GotoOp
(and FunctionCallOp
) before building those
Op
s, and then correctly reuse those Block
s when processing said
targets. With an explicit indirection, however, it would have been
possible to reuse the same Label
s, simply creating a new mapping
from them to Block
s.
Note that the semantics assumed by this transformation is that the
CFGs being transformed do not use variable stacks internally, but
they will only be used to implement the function sequence when
function calls are lowered. This semantics licenses placing
PopOp
s to enforce a stack discipline for FunctionCallOp
s.
Args |
program
|
A Program whose function calls to lower. Block s in
the program may be mutated.
|
Returns |
lowered
|
A Program that defines no Function s and does not use the
FunctionCallOp instruction. May share structure with the input
program .
|
Raises |
ValueError
|
If an invalid instruction is encountered, if a live
variable is undefined, if different paths into a Block cause
different sets of variables to be defined, or if trying to lower
function calls in a program that already has loops (within a
Function body) or IndirectGotoOp instructions (they confuse
the liveness analysis).
|
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2023-11-21 UTC.
[null,null,["Last updated 2023-11-21 UTC."],[],[],null,["# tfp.experimental.auto_batching.lowering.lower_function_calls\n\n\u003cbr /\u003e\n\n|----------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| [View source on GitHub](https://github.com/tensorflow/probability/blob/v0.23.0/tensorflow_probability/python/experimental/auto_batching/lowering.py#L402-L479) |\n\nLowers a `Program` that may have (recursive) FunctionCallOp instructions.\n\n#### View aliases\n\n\n**Main aliases**\n\n[`tfp.experimental.auto_batching.frontend.lowering.lower_function_calls`](https://www.tensorflow.org/probability/api_docs/python/tfp/experimental/auto_batching/lowering/lower_function_calls)\n\n\u003cbr /\u003e\n\n tfp.experimental.auto_batching.lowering.lower_function_calls(\n program\n )\n\nMutates the `ControlFlowGraph` of the input program in place. After\nlowering, the result CFG\n\n- Has no `FunctionCallOp` instructions\n\n- Obeys a stack discipline\n\nWhat is the stack discipline? Every function body becomes a CFG\nsubset that:\n\n- Never transfers control in except to the first block\n (corresponding to being called), or to a block stored with\n `PushGotoOp` (corresponding to a subroutine returning)\n\n- Never transfers control out except with `IndirectGotoOp`\n (corresponding to returning), or with a `PushGotoOp`\n (corresponding to calling a subroutine)\n\n- Every path through the graph has the following effect on the\n variable stacks:\n\n - The formal parameters receive exactly one net pop\n\n - The return variables receive exactly one net push\n\n - All other variable stacks are left as they are\n\n - No data is read except the top frames of the formal parameter\n stacks\n\nWhy mutate in place? Because tying the knot in the result seemed\ntoo hard without an explicit indirection between `Block`s and\nreferences thereto in various `Op`s. Specifically, when building a\nnew CFG to replicate the structure of an existing one, it is\nnecessary to allocate `Block`s to serve as the targets of all\n`BranchOp`, `GotoOp` (and `FunctionCallOp`) before building those\n`Op`s, and then correctly reuse those `Block`s when processing said\ntargets. With an explicit indirection, however, it would have been\npossible to reuse the same `Label`s, simply creating a new mapping\nfrom them to `Block`s.\n\nNote that the semantics assumed by this transformation is that the\nCFGs being transformed do not use variable stacks internally, but\nthey will only be used to implement the function sequence when\nfunction calls are lowered. This semantics licenses placing\n`PopOp`s to enforce a stack discipline for `FunctionCallOp`s.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Args ---- ||\n|-----------|------------------------------------------------------------------------------------|\n| `program` | A `Program` whose function calls to lower. `Block`s in the program may be mutated. |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Returns ------- ||\n|-----------|------------------------------------------------------------------------------------------------------------------------------------------|\n| `lowered` | A `Program` that defines no `Function`s and does not use the `FunctionCallOp` instruction. May share structure with the input `program`. |\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n| Raises ------ ||\n|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `ValueError` | If an invalid instruction is encountered, if a live variable is undefined, if different paths into a `Block` cause different sets of variables to be defined, or if trying to lower function calls in a program that already has loops (within a `Function` body) or `IndirectGotoOp` instructions (they confuse the liveness analysis). |\n\n\u003cbr /\u003e"]]