mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-20 21:14:14 +08:00
Rename TorchScript compiler to IR emitter to better reflect its function. (#33127)
Summary: Pull Request resolved: https://github.com/pytorch/pytorch/pull/33127 Test Plan: Imported from OSS Differential Revision: D19806503 Pulled By: ZolotukhinM fbshipit-source-id: ab78bdbbac5f12dbcc6c2e2573f5862a16ffcf3d
This commit is contained in:
committed by
Facebook Github Bot
parent
91744907d4
commit
806e7daa1f
@ -424,7 +424,7 @@ if (NOT INTERN_BUILD_MOBILE OR NOT BUILD_CAFFE2_MOBILE)
|
||||
${TORCH_SRC_DIR}/csrc/jit/register_string_ops.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/register_special_ops.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/scope.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/script/compiler.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/script/ir_emitter.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/testing/file_check.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/script/convert_to_ssa.cpp
|
||||
${TORCH_SRC_DIR}/csrc/jit/script/exit_transforms.cpp
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "test/cpp/jit/test_base.h"
|
||||
#include "torch/csrc/jit/custom_operator.h"
|
||||
#include "torch/csrc/jit/passes/alias_analysis.h"
|
||||
#include "torch/csrc/jit/script/compiler.h"
|
||||
#include "torch/csrc/jit/script/ir_emitter.h"
|
||||
#include "torch/csrc/utils/memory.h"
|
||||
|
||||
namespace torch {
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <torch/csrc/jit/testing/file_check.h>
|
||||
#include "ATen/core/ivalue.h"
|
||||
#include "torch/csrc/jit/graph_executor.h"
|
||||
#include "torch/csrc/jit/script/compiler.h"
|
||||
#include "torch/csrc/jit/script/ir_emitter.h"
|
||||
#include "torch/csrc/jit/script/module.h"
|
||||
|
||||
#include "onnx/onnx_pb.h"
|
||||
|
@ -45,11 +45,11 @@
|
||||
#include "torch/csrc/autograd/variable.h"
|
||||
|
||||
#include <torch/csrc/jit/testing/file_check.h>
|
||||
#include <torch/script.h>
|
||||
#include "torch/csrc/jit/profiling_record.h"
|
||||
#include "torch/csrc/jit/script/compiler.h"
|
||||
#include "torch/csrc/jit/script/ir_emitter.h"
|
||||
#include "torch/csrc/jit/script/module.h"
|
||||
#include "torch/jit.h"
|
||||
#include <torch/script.h>
|
||||
|
||||
#include "onnx/onnx_pb.h"
|
||||
|
||||
|
@ -151,7 +151,7 @@ libtorch_sources = [
|
||||
"torch/csrc/jit/register_special_ops.cpp",
|
||||
"torch/csrc/jit/register_distributed_ops.cpp",
|
||||
"torch/csrc/jit/scope.cpp",
|
||||
"torch/csrc/jit/script/compiler.cpp",
|
||||
"torch/csrc/jit/script/ir_emitter.cpp",
|
||||
"torch/csrc/jit/script/edit_distance.cpp",
|
||||
"torch/csrc/jit/script/logging.cpp",
|
||||
"torch/csrc/jit/script/convert_to_ssa.cpp",
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <torch/jit.h>
|
||||
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <ATen/core/stack.h>
|
||||
|
||||
#include <memory>
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <torch/csrc/jit/autodiff.h>
|
||||
|
||||
#include <ATen/core/functional.h>
|
||||
#include <c10/util/Exception.h>
|
||||
#include <torch/csrc/jit/jit_log.h>
|
||||
#include <torch/csrc/jit/operator.h>
|
||||
#include <torch/csrc/jit/passes/common_subexpression_elimination.h>
|
||||
@ -8,9 +9,8 @@
|
||||
#include <torch/csrc/jit/passes/dead_code_elimination.h>
|
||||
#include <torch/csrc/jit/passes/inliner.h>
|
||||
#include <torch/csrc/jit/passes/lower_tuples.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/symbolic_script.h>
|
||||
#include <c10/util/Exception.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
@ -508,11 +508,11 @@ The Parser uses the Lexer to build the AST for function definitions. `parseFunct
|
||||
|
||||
The Parser is written as a [top-down precedence parser](https://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing), or "Pratt" parser. They are simpler and easier to understand than typical parser generators, while still being flexible enough to parse programming languages. For the most part parsing is done by recursive decent. To resolve operator precedence issues, the function to parse an expression is augmented with a precedent _p_ such that calling the function means _parse an expression whose operators all have precedence higher than p_.
|
||||
|
||||
## Compiler ##
|
||||
## IR Emitter ##
|
||||
|
||||
[script/compiler.h](../script/compiler.h)
|
||||
[script/ir_emitter.h](../script/ir_emitter.h)
|
||||
|
||||
The file compiler.cpp translates Trees into Modules. Its name is slightly ambiguous because there are other compiler-like things in the system such as the FusionCompiler. The main entrypoint is `defineMethodsInModule` which takes a list of Def Tree Views representing function definitions and adds them as Methods to the module. During the lowering processing _semantic checking_ occurs. The compiler checks that all used variables are defined (sometimes called scope checking), and that all values have compatible types (type-checking). During this process it also emits the graph nodes corresponding to each statement in the Tree and generates a FunctionSchema for the whole definition.
|
||||
The file ir_emitter.cpp translates Trees into Modules. The main entrypoint is `defineMethodsInModule` which takes a list of Def Tree Views representing function definitions and adds them as Methods to the module. During the lowering processing _semantic checking_ occurs. The IR emitter checks that all used variables are defined (sometimes called scope checking), and that all values have compatible types (type-checking). During this process it also emits the graph nodes corresponding to each statement in the Tree and generates a FunctionSchema for the whole definition.
|
||||
|
||||
A few helper objects exist in the lowering process. SugaredValues are special values that represent objects that can appear during compilation but that are not first class values. For instance, in TorchScript methods `self` refers to the module, and `self.weight` refers to a Parameter of the module. Neither are first-class Types and have no corresponding Value in a graph. Resolver objects are std::functions that resolve externally-defined variables to SugaredValues. For instance, the identifier `torch` which contains most of our built-in ops is looked up through Resolver objects which interact with the python state of the program.
|
||||
|
||||
@ -522,7 +522,7 @@ The Environment tracks the mapping between variable names and the SugaredValues
|
||||
|
||||
[script/sugared_value.h](../script/sugared_value.h)
|
||||
|
||||
SugaredValues are how the compiler represents non-first class values during Graph creation. These values are things like the Module or a python function call that do not have corresponding Value objects in the Graph. The compiler _desugars_ the SugaredValue objects to instructions in the graph based on how they are used. The SugaredValue class has a number of abstract methods on it such as `attr` or `call`. Consider the expression `self.foo`. For methods, `self` will resolve to a special SugaredValue subclass, ModuleValue. When the compiler sees `self.foo`, it will then call the ModuleValue function `sv.attr("foo")`, asking the ModuleValue how it should desugar itself when the attribute `"foo"` accessed. If `foo` is a parameter, it would then ensure that the parameter was added to the Method being compiled, and return a `SimpleValue` sugared value that contains the Value object representing the parameter as an input. If `foo` were a sub-Module then it would return another SugaredModule. The method `call` is invoked when the compiler sees the value used as a function call.
|
||||
SugaredValues are how the IR emitter represents non-first class values during Graph creation. These values are things like the Module or a python function call that do not have corresponding Value objects in the Graph. The IR emitter _desugars_ the SugaredValue objects to instructions in the graph based on how they are used. The SugaredValue class has a number of abstract methods on it such as `attr` or `call`. Consider the expression `self.foo`. For methods, `self` will resolve to a special SugaredValue subclass, ModuleValue. When the emitter sees `self.foo`, it will then call the ModuleValue function `sv.attr("foo")`, asking the ModuleValue how it should desugar itself when the attribute `"foo"` accessed. If `foo` is a parameter, it would then ensure that the parameter was added to the Method being compiled, and return a `SimpleValue` sugared value that contains the Value object representing the parameter as an input. If `foo` were a sub-Module then it would return another SugaredModule. The method `call` is invoked when the emitter sees the value used as a function call.
|
||||
|
||||
SugaredValues are also how we interact with Python runtime during the compilation process. For instance, `math.pi` is resolved to 3.1415... by first resolving `math` to a SugaredValue representing accesses to Python modules (PythonModuleValue) whose `attr` function turns python numbers into `prim::Constant` Nodes in the graph.
|
||||
|
||||
@ -530,19 +530,19 @@ Finally, normal Values are also represented by the SimpleValue SugaredValue in p
|
||||
|
||||
## Resolver ##
|
||||
|
||||
[script/compiler.h](../script/compiler.h)
|
||||
[script/ir_emitter.h](../script/ir_emitter.h)
|
||||
|
||||
Any undefined variable during compilation is resolved with a call to an externally-provided Resolver. When called from Python (e.g `torch.jit.script`) this resolver interacts with the Python runtime via pybind11 to resolve symbols like `torch` and `math` to their Python equivalents.
|
||||
|
||||
*The combination of SugaredValue and Resolver decouples the implementation of the compiler from the pybind11 Python bindings that enable its interaction with the Python state.*
|
||||
*The combination of SugaredValue and Resolver decouples the implementation of the IR emitter from the pybind11 Python bindings that enable its interaction with the Python state.*
|
||||
|
||||
This makes it possible to use most of the compiler functionality when python is not present.
|
||||
This makes it possible to use most of the IR emitter functionality when python is not present.
|
||||
|
||||
## Environment ##
|
||||
|
||||
[script/compiler.cpp](../script/compiler.cpp)
|
||||
[script/ir_emitter.cpp](../script/ir_emitter.cpp)
|
||||
|
||||
The Environment object tracks the assignment of variable names during compilation. It is local to the compiler file. A stack of environments exist, with a new environment being created for sub-blocks introduced by control flow. The Environment keeps two tables, one for values which are not first class in the type system (Sugared values) and a type table for values which are. When first class values are set, we emit a prim::Store, and when they are referenced we emit a prim::Load. Sugared values are not re-assignable. The graph is converted to SSA in the convertToSSA pass.
|
||||
The Environment object tracks the assignment of variable names during compilation. It is local to the IR emitter file. A stack of environments exist, with a new environment being created for sub-blocks introduced by control flow. The Environment keeps two tables, one for values which are not first class in the type system (Sugared values) and a type table for values which are. When first class values are set, we emit a prim::Store, and when they are referenced we emit a prim::Load. Sugared values are not re-assignable. The graph is converted to SSA in the convertToSSA pass.
|
||||
|
||||
## Conversion To SSA ##
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include <torch/csrc/autograd/edge.h>
|
||||
#include <torch/csrc/autograd/function.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/script/logging.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
@ -28,13 +28,13 @@
|
||||
#include <torch/csrc/jit/passes/onnx.h>
|
||||
#include <torch/csrc/jit/passes/onnx/cast_all_constant_to_floating.h>
|
||||
#include <torch/csrc/jit/passes/onnx/constant_fold.h>
|
||||
#include <torch/csrc/jit/passes/onnx/fixup_onnx_loop.h>
|
||||
#include <torch/csrc/jit/passes/onnx/fixup_onnx_conditionals.h>
|
||||
#include <torch/csrc/jit/passes/onnx/fixup_onnx_loop.h>
|
||||
#include <torch/csrc/jit/passes/onnx/peephole.h>
|
||||
#include <torch/csrc/jit/passes/onnx/prepare_division_for_onnx.h>
|
||||
#include <torch/csrc/jit/passes/onnx/prepare_inplace_ops_for_onnx.h>
|
||||
#include <torch/csrc/jit/passes/onnx/scalar_type_analysis.h>
|
||||
#include <torch/csrc/jit/passes/onnx/unpack_quantized_weights.h>
|
||||
#include <torch/csrc/jit/passes/onnx/prepare_inplace_ops_for_onnx.h>
|
||||
#include <torch/csrc/jit/passes/peephole.h>
|
||||
#include <torch/csrc/jit/passes/quantization.h>
|
||||
#include <torch/csrc/jit/passes/remove_expands.h>
|
||||
@ -49,8 +49,8 @@
|
||||
#include <torch/csrc/jit/python_custom_class.h>
|
||||
#include <torch/csrc/jit/python_ir.h>
|
||||
#include <torch/csrc/jit/python_tracer.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/init.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/script/jit_exception.h>
|
||||
#include <torch/csrc/jit/script/module.h>
|
||||
#include <torch/csrc/jit/script/python_tree_views.h>
|
||||
|
@ -209,7 +209,7 @@ void CanonicalizeOutputs(Block* block) {
|
||||
|
||||
// Canonicalize a graph's control flow node outputs. We do this to solve jitter
|
||||
// issues with outputs added to control flow nodes after the first pass of
|
||||
// compilation in compiler.cpp
|
||||
// compilation in ir_emitter.cpp
|
||||
void CanonicalizeOutputs(std::shared_ptr<Graph>& graph) {
|
||||
CanonicalizeOutputs(graph->block());
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
#include <torch/csrc/jit/operator.h>
|
||||
#include <torch/csrc/jit/custom_operator.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/passes/decompose_ops.h>
|
||||
#include <torch/csrc/jit/passes/dead_code_elimination.h>
|
||||
#include <torch/csrc/jit/custom_operator.h>
|
||||
#include <torch/csrc/jit/operator.h>
|
||||
#include <torch/csrc/jit/passes/constant_propagation.h>
|
||||
#include <torch/csrc/jit/passes/dead_code_elimination.h>
|
||||
#include <torch/csrc/jit/passes/shape_analysis.h>
|
||||
#include <torch/csrc/jit/passes/utils/subgraph_utils.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
|
||||
namespace torch {
|
||||
namespace jit {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <torch/csrc/jit/passes/constant_pooling.h>
|
||||
#include <torch/csrc/jit/passes/dead_code_elimination.h>
|
||||
#include <torch/csrc/jit/passes/utils/subgraph_utils.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include <torch/csrc/jit/passes/inline_forked_closures.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
|
||||
namespace torch {
|
||||
namespace jit {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <torch/csrc/jit/passes/lift_closures.h>
|
||||
#include <torch/csrc/jit/ir.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
|
||||
namespace torch {
|
||||
namespace jit {
|
||||
|
@ -82,7 +82,7 @@ struct TORCH_API CompilationUnit {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for historic reasons, these are defined in compiler.cpp
|
||||
// for historic reasons, these are defined in ir_emitter.cpp
|
||||
// Returns the list of Function's just defined.
|
||||
std::vector<Function*> define(
|
||||
const c10::optional<c10::QualifiedName>& prefix,
|
||||
|
@ -2,9 +2,9 @@
|
||||
#include <torch/csrc/jit/ir.h>
|
||||
#include <torch/csrc/jit/ir_views.h>
|
||||
#include <torch/csrc/jit/passes/inline_forked_closures.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/exit_transforms.h>
|
||||
#include <torch/csrc/jit/script/inline_loop_condition.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/script/mini_environment.h>
|
||||
|
||||
namespace torch {
|
||||
@ -87,7 +87,7 @@ struct ControlFlowLoadStores {
|
||||
}
|
||||
}
|
||||
|
||||
// Following the same logic as emitIfElseBlocks in compiler.cpp,
|
||||
// Following the same logic as emitIfElseBlocks in ir_emitter.cpp,
|
||||
// we emit a node output if the variable is defined in each block
|
||||
// and the types of each block can be unified
|
||||
for (const auto& x : mutated_variables) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <torch/csrc/Device.h>
|
||||
#include <torch/csrc/jit/import.h>
|
||||
#include <torch/csrc/jit/python_ivalue.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/script/module.h>
|
||||
#include <torch/csrc/jit/script/module_python.h>
|
||||
#include <torch/csrc/jit/script/python_sugared_value.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <c10/util/Exception.h>
|
||||
#include <c10/util/StringUtil.h>
|
||||
#include <torch/csrc/jit/hooks_for_testing.h>
|
||||
@ -46,6 +46,7 @@ struct Refinement {
|
||||
TypePtr type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string identifier_;
|
||||
TypePtr type_;
|
||||
@ -1571,8 +1572,7 @@ struct to_ir {
|
||||
RefinementSet refinement;
|
||||
if (gathered.types.size() == 1 && obj.kind() == TK_VAR) {
|
||||
std::string ident = Var(obj).name().name();
|
||||
Refinement isinstance(
|
||||
std::move(ident), gathered.types.at(0));
|
||||
Refinement isinstance(std::move(ident), gathered.types.at(0));
|
||||
refinement = RefinementSet({isinstance}, {});
|
||||
}
|
||||
|
||||
@ -2648,7 +2648,10 @@ struct to_ir {
|
||||
}
|
||||
}
|
||||
|
||||
Value* emitUnaryOp(const TreeRef& tree, const std::string &magicMethod, const c10::Symbol &opSymbol) {
|
||||
Value* emitUnaryOp(
|
||||
const TreeRef& tree,
|
||||
const std::string& magicMethod,
|
||||
const c10::Symbol& opSymbol) {
|
||||
const auto& inputs = tree->trees();
|
||||
auto named_values = getNamedValues(inputs, /*maybe_unpack=*/false);
|
||||
auto val =
|
@ -5,8 +5,8 @@
|
||||
#include <torch/csrc/jit/operator.h>
|
||||
#include <torch/csrc/jit/passes/dead_code_elimination.h>
|
||||
#include <torch/csrc/jit/passes/inliner.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/error_report.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
#include <torch/csrc/jit/script/schema_matching.h>
|
||||
|
||||
namespace torch {
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include <torch/csrc/jit/symbolic_script.h>
|
||||
#include <torch/csrc/jit/operator.h>
|
||||
#include <torch/csrc/jit/script/compiler.h>
|
||||
#include <torch/csrc/jit/script/ir_emitter.h>
|
||||
|
||||
namespace torch {
|
||||
namespace jit {
|
||||
|
@ -161,7 +161,7 @@ def _get_math_builtins():
|
||||
|
||||
|
||||
def _get_global_builtins():
|
||||
# Taken from the 'globals' map in torch/csrc/jit/script/compiler.cpp
|
||||
# Taken from the 'globals' map in torch/csrc/jit/script/ir_emitter.cpp
|
||||
supported_builtins = [
|
||||
'print',
|
||||
'tuple',
|
||||
|
Reference in New Issue
Block a user