| ExceptionWrapper holds an exception.
| If exception pointers are being used,
| it’ll hold the original exception pointer
| otherwise just the message.
|
| ExceptionWrapperTerminate terminates
| the program with the specified exception.
| This preserves the exception ptr and
| ExceptionTracer will correctly grab
| it on exit.
|
| Controls compilation and runtime cloning
| of execution steps.
|
| If step.create_workspace=False,
| this wrapper will compile the execution
| step and its children once, and calls
| to ExecutionStepWrapper::compiled()
| will always return the same compiled
| step. If step.create_workspace=True,
| no compilation is done at creation time.
| Instead, a new CompiledExecutionStep
| is created for every compiled() call.
|
| CompiledExecutionStep owns its Workspace,
| and the lifetime of the compiled step
| along with its workspace will be tied
| to the lifetime of the CompileGuard
| object returned by compiled().
|
| ExecuteStepRecursive will call call
| compiled() once before the given execution
| step is run and keep it alive for the length
| of its execution. This means that, for
| steps with create_workspace=true,
| a child workspace will be created every
| time the step is executed, and destroyed
| right afterwards.
|
| ScopeExitGuard runs the provided function
| when it’s destructed.
|
| Injects a blob named ‘GLOBAL_WORKSPACE_ID’
| for each workspace, only if another
| blob named ‘NODE_ID’ is present. ‘NODE_ID’
| blob can be used in a distributed run
| and in this case ‘GLOBAL_WORKSPACE_ID’
| can be used across machines for other
| purposes (e.g. to support model parallelism).
| Essentially, ‘GLOBAL_WORKSPACE_ID’
| is an identifier for a workspace that
| is unique across all ’NODE_ID’s.
|