1
1
#=
2
-
3
2
`TapedFunction` converts a Julia function to a friendly tape for user-specified interpreters.
4
- With this tape-like abstraction for functions, we gain some control over how the function is
3
+ With this tape-like abstraction for functions, we gain some control over how a function is
5
4
executed, like capturing continuations, caching variables, injecting additional control flows
6
- (i.e. produce/consume) between instructions on the tape, etc.
5
+ (i.e., produce/consume) between instructions on the tape, etc.
7
6
8
- Under the hood, we firstly used Julia's compiler API to get the IR code of the original function.
9
- We use the unoptimised typed code in a non-strict SSA form. Then we convert each IR instruction
7
+ Under the hood, we first used Julia's compiler API to get the IR code of the original function.
8
+ We use the unoptimized typed code in a non-strict SSA form. Then we convert each IR instruction
10
9
to a Julia data structure (an object of a subtype of AbstractInstruction). All the operands
11
10
(i.e., the variables) these instructions use are stored in a data structure called `Bindings`.
12
11
This conversion/binding process is performed at compile-time / tape-recording time and is only
@@ -17,9 +16,9 @@ In a nutshell, there are two types of instructions (or primitives) on a tape:
17
16
- Control-flow instruction: GotoInstruction and CondGotoInstruction, ReturnInstruction
18
17
19
18
Once the tape is recorded, we can run the tape just like calling the original function.
20
- We first plugin the arguments, run each instruction on the tape, and stop after encountering
19
+ We first plugin the arguments, run each instruction on the tape and stop after encountering
21
20
a ReturnInstruction. We also provide a mechanism to add a callback after each instruction.
22
- This API allowed us to implement the `produce/consume` machanism in TapedTask. And exploiting
21
+ This API allowed us to implement the `produce/consume` mechanism in TapedTask. And exploiting
23
22
these features, we implemented a fork mechanism for TapedTask.
24
23
25
24
Some potentially sharp edges of this implementation:
@@ -29,9 +28,9 @@ Some potentially sharp edges of this implementation:
29
28
So this works well. But, if you do something like `module A v=1 end; make tapedfunction; A.eval(:(v=2)); run tf;`,
30
29
The assignment won't work.
31
30
2. QuoteNode is also evaluated at the tape-recording time (compile-time). Primarily
32
- the result of evaluating a QuoteNode is a Symbol, which works well most of the time .
31
+ the result of evaluating a QuoteNode is a Symbol, which usually works well.
33
32
3. Each Instruction execution contains one unnecessary allocation at the moment.
34
- So writing a function with vectorised computation will be more performant,
33
+ So writing a function with vectorized computation will be more performant,
35
34
for example, using broadcasting instead of a loop.
36
35
=#
37
36
0 commit comments