A thread-local stack of context switches.
| 197 | # `_ContextSwitchStack` is a `threading.local` to match the semantics of |
| 198 | # ``DefaultGraphStack`, which is also a `threading.local`. |
| 199 | class _ContextSwitchStack(threading.local): |
| 200 | """A thread-local stack of context switches.""" |
| 201 | |
| 202 | def __init__(self, eager): |
| 203 | super(_ContextSwitchStack, self).__init__() |
| 204 | self.stack = [] |
| 205 | if eager: |
| 206 | # Initialize the stack with a pointer to enter the eager context; this |
| 207 | # ensures that the fact that eager execution was enabled is propagated |
| 208 | # across threads, since (1) `enable_eager_execution` modifies a |
| 209 | # process-level flag (`default_execution_mode`) and (2) `__init__` is |
| 210 | # called each time a threading.local object is used in a separate thread. |
| 211 | self.push(is_building_function=False, enter_context_fn=eager_mode, |
| 212 | device_stack=None) |
| 213 | |
| 214 | def push(self, is_building_function, enter_context_fn, device_stack): |
| 215 | """Push metadata about a context switch onto the stack. |
| 216 | |
| 217 | A context switch can take any one of the two forms: installing a graph as |
| 218 | the default graph, or entering the eager context. For each context switch, |
| 219 | we record whether or not the entered context is building a function. |
| 220 | |
| 221 | Args: |
| 222 | is_building_function: (bool.) Whether the context is building a function. |
| 223 | enter_context_fn: (function.) A callable that executes the context switch. |
| 224 | For example, `graph.as_default` or `eager_mode`. |
| 225 | device_stack: If applicable, the device function stack for this |
| 226 | graph. When breaking out of graphs in init_scope, the innermost nonempty |
| 227 | device stack is used. Eager contexts put `None` here and the value is |
| 228 | never used. |
| 229 | """ |
| 230 | |
| 231 | self.stack.append( |
| 232 | ContextSwitch(is_building_function, enter_context_fn, device_stack)) |
| 233 | |
| 234 | def pop(self): |
| 235 | """Pop the stack.""" |
| 236 | |
| 237 | self.stack.pop() |
| 238 | |
| 239 | |
| 240 | class LogicalDevice( |