Skip to content

Commit ae6c3c9

Browse files
committed
debug
1 parent 7ed26c1 commit ae6c3c9

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed

chapter_compiler_frontend/Intermediate_Representation.md

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,150 @@ considering the specific requirements of the compiler's design.
6161
:label:`ch06/ch06-categorize`
6262

6363

64+
### Linear Intermediate Representation
6465

66+
Linear IRs are widely used in compiler design, resembling assembly code
67+
for abstract machines. They represent the code to be compiled as a
68+
sequentially ordered series of operations. This ordering is important in
69+
practical terms. Linear IRs are popular because most processors utilize
70+
linear assembly languages.
71+
72+
Two common types of linear IRs are stack machine code and three-address
73+
code . Stack machine code, a form of single-address code, offers a
74+
straightforward and compact representation. Instructions in stack
75+
machine code typically consist solely of an opcode that specifies an
76+
operation, with operands stored on a stack. Most instructions retrieve
77+
operands from the stack and push the results of their operations back
78+
onto it. On the other hand, three-address code (3AC) emulates the
79+
instruction format used in modern RISC machines. It employs a set of
80+
quadruples, each containing an operator and three addresses (two
81+
operands and one target). Figure
82+
:numref:`ch04/ch04-linearIR` illustrates the stack machine code
83+
and three-address code representations for the expression $a-b*5$.
84+
85+
![Stack machine code and three-addresscode](../img/ch04/IR-linear_IR.png)
86+
:label:`ch04/ch04-linearIR`
87+
88+
### Graphical Intermediate Representation
89+
90+
Graphical IRs store information about the compilation process in the
91+
form of graphs. These graphs utilize nodes, edges, lists, trees, and
92+
other elements to collectively represent an algorithm. Although all
93+
graphical IRs consist of nodes and edges, they differ in terms of
94+
abstraction levels and graph structures. Common examples of graphical
95+
IRs include abstract syntax trees (ASTs), directed acyclic graphs
96+
(DAGs), and control-flow graphs (CFGs).
97+
98+
An AST is a tree-structured IR that closely resembles the structure of
99+
the source code. Figure :numref:`ch04/ch04-AST_DAG` depicts the AST for the expression
100+
$a5+a5b$. It is worth noting that the AST contains two identical copies
101+
of $a5$, which introduces redundancy. To address this redundancy, the
102+
DAG offers a simplified representation where identical subtrees can be
103+
shared by multiple parent nodes. By reusing subtrees, the DAG reduces
104+
the cost of the evaluation process, especially when the compiler can
105+
verify that the value of $a$ remains constant.
106+
107+
![AST and DAG](../img/ch04/IR-ASTDAG.png)
108+
:label:`ch04/ch04-AST_DAG`
109+
110+
### Hybrid Intermediate Representation
111+
112+
Hybrid IRs combine both linear IR and graphical IR elements. An example
113+
of a hybrid IR is LLVM IR , which is illustrated in Figure
114+
:numref:`ch04/ch04-LLVM_IR`. LLVM is an open-source compiler
115+
framework with the goal of providing unified IRs for different frontends
116+
and backends.
117+
118+
In LLVM IR, linear IRs are used to construct basic blocks, while
119+
graphical IRs represent the control flow between these blocks. Each
120+
instruction within a basic block is presented as a static single
121+
assignment (SSA) . SSA requires each variable to be defined before use,
122+
with values assigned to them only once. Multiple SSA instructions form a
123+
linear list within a basic block.
124+
125+
In the control flow graph (CFG), each node represents a basic block, and
126+
control transfer between these blocks is implemented through edges. This
127+
combination of linear IR for basic blocks and graphical IR for control
128+
flow allows for a flexible and efficient representation in LLVM IR.
129+
130+
![LLVM IR](../img/ch04/IR-LLVMIR.png)
131+
:label:`ch04/ch04-LLVM_IR`
132+
133+
## Intermediate Representation in Machine Learning Frameworks
134+
135+
Classical IRs (such as LLVM IR) primarily target programming languages
136+
for general-purpose computation tasks, which falls short of satisfying
137+
the unique requirements of machine-learning-related computation. When
138+
designing IRs tailored for machine learning frameworks, certain vital
139+
factors warrant attention:
140+
141+
- **Tensor Representation**. Given the predominance of tensor data in
142+
machine learning frameworks, it's imperative that the IRs can
143+
effectively handle tensor representation.
144+
145+
- **Automatic Differentiation**. A core aspect of machine learning
146+
involves evaluating derivatives of neural networks and optimizers
147+
through automatic differentiation. Accordingly, IRs must prioritize
148+
simplicity, performance, and scalability of higher-order
149+
differentials for automatic differentiation.
150+
151+
- **Computational Graph Mode**. Machine learning frameworks like
152+
TensorFlow, PyTorch, and MindSpore operate on two computational
153+
graph modes: static and dynamic. The static mode, with pre-defined
154+
computational graphs, enhances optimization but compromises on
155+
flexibility. Conversely, the dynamic mode trades running speed for
156+
flexibility and easier debugging by executing operators immediately
157+
in the computational graph. IRs should therefore support both modes,
158+
enabling users to choose the one best suited for their tasks while
159+
building algorithm models.
160+
161+
- **Support for Higher-order Functions and Closures**. Essential in
162+
functional programming, higher-order functions take or return
163+
functions, while closures bundle code blocks with references to the
164+
surrounding environment, facilitating access to an outer function's
165+
scope from an inner function. Such support reduces redundant code,
166+
improves abstraction, and enhances the flexibility and simplicity of
167+
framework representations.
168+
169+
- **Compilation Optimization**. Machine learning frameworks lean on
170+
compilation optimizations, including hardware-agnostic,
171+
hardware-specific, and deployment- or inference-related
172+
optimizations. These rely significantly on IRs implementations.
173+
174+
- **Just-in-Time (JIT) Compilation**. For expedited compilation and
175+
execution in machine learning frameworks, JIT compilation is
176+
frequently utilized. Optimization of JIT compilation, including loop
177+
unrolling, fusion, and inlining, plays a crucial role in optimizing
178+
parts of data flow graphs in IRs. A flawed IR design could
179+
potentially hamper JIT compilation performance in machine learning
180+
frameworks, thereby impacting the program's running capabilities.
181+
182+
Considering these factors, developers persistently refine classical IRs
183+
and introduce new IRs specifically tailored for machine learning
184+
frameworks. In the following section, we will delve into the IRs
185+
employed by various machine learning frameworks.
186+
187+
### Intermediate Representation in PyTorch
188+
189+
PyTorch is a dynamic, Python-oriented machine learning framework.
190+
Renowned for its usability and flexibility, PyTorch simplifies the
191+
process of writing and debugging machine learning programs. It
192+
introduces TorchScript, a method used for constructing serializable and
193+
optimizable models during the saving and loading of neural networks.
194+
195+
Particularly, TorchScript IR employs JIT compilation to convert Python
196+
code into target model files. All TorchScript programs can be saved
197+
within the Python process and later loaded into processes devoid of
198+
Python dependencies.
199+
200+
Aligning with the imperative programming paradigm, PyTorch incorporates
201+
the TorchScript IR, composed primarily of Single Static Assignment
202+
(SSA)-based linear IRs, to represent Python code. This representation
203+
can be achieved through either the Tracing or Scripting method of JIT
204+
compilation. TorchScript IR not only amplifies model deployment
205+
capabilities but also bolsters compilation performance. Additionally,
206+
TorchScript IR greatly improves the model visualization within the
207+
PyTorch framework.
208+
209+
Code `lst:torchscript` illustrates the use of the Scripting method
210+
to print a TorchScript IR graph.

0 commit comments

Comments
 (0)