Executor Design Doc¶
In fluid, we encourage the user to use deep learning programming paradigms to describe the training process. When the user-written Python program is executed, it will first create a protobuf message
ProgramDesc that describes the process and is conceptually like an abstract syntax tree.
The executor runs the
ProgramDesc like an interpreter.
ProgramDesc contains the intrinsics (operators in this case) and variables which will be used, executor explicitly executes the stored precompiled code.
An executor takes a
block_id and a
ProgramDesc is a list of blocks and each block contains the protobuf definition of all the parameters and operators in the block. The
block_id specifies the entrance block. And the
Scope is the container of all the variable instances, which is persistent throughout different runs.
Executor explicitly executes all the intrinsics (operators here) in the
block_idth block of a
ProgramDesc. Essentially, it instantiates Variables and Operators, then runs all the operators in sequence one-by-one.
It is very similar to how a push stack frame works when entering a block, following which it cleans up all the temporary variables when a mini-batch is finished. It does not however, have the stack frame pop process.
A executor does not own any computing resources, a user can only construct an executor using the specified places.
Running an Executor¶
void Run(ProgramDesc, Scope, block_id, create_local_scope);
Executor only provides a unified way to execute
ProgramDesc is the target that will be executed, the
Scope specifies the variable container, the
block_id indicates the entrance block and
create_local_scope is a boolean that states whether it will destroy the temporary variables after the execution is finished.