-
-
Notifications
You must be signed in to change notification settings - Fork 202
Expand file tree
/
Copy pathrun_benchmark.py
More file actions
107 lines (89 loc) · 3.97 KB
/
run_benchmark.py
File metadata and controls
107 lines (89 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Benchmark constant folding over a module of integer addition of constants using
xDSL's pattern rewriting machinery. The workload module is generated by the
``get_constant_folding_module()`` function, which is then transformed by the
``xdsl.transforms.test_constant_folding.TestConstantFoldingPass`` xDSL
transformation pass.
xDSL is a Python-native compiler framework built around SSA-based intermediate
representations. It re-implements many of MLIR's data structures and methods in
Python. This benchmark exercises the simple pattern rewriting transformation of
constant folding. This is a fair proxy for pattern rewriting transformations in
general, which are a major component of MLIR-like compilers in lowering passes.
Pattern rewriting in both xDSL and MLIR is a pointer-chasing, unstructured
workload, which makes it hard to optimise ahead-of-time. This diminishes the
traditional performance advantage of ahead-of-time compiled languages such as
C++ over dynamic languages such as Python -- making it an interesting benchmark.
More information about the design and impact of this benchmark can be found in
the Master's thesis ``Performance and Dynamism in User-extensible Compiler
Infrastructures'', which is `available on GitHub
<https://github.com/EdmundGoodman/masters-project>`_.
"""
import random
import pyperf
from xdsl.context import Context
from xdsl.dialects.arith import AddiOp, Arith, ConstantOp
from xdsl.dialects.builtin import (
Builtin,
IntegerAttr,
ModuleOp,
i32,
)
from xdsl.dialects.test import TestOp
from xdsl.ir import Operation
from xdsl.transforms.test_constant_folding import TestConstantFoldingPass
RANDOM_SEED = 0
def get_constant_folding_module(size: int = 100) -> ModuleOp:
"""Generate an integer addition constant folding workload of a given size.
The output of running the command
`print(WorkloadBuilder().constant_folding_module(size=5))` is shown
below:
```mlir
"builtin.module"() ({
%0 = "arith.constant"() {"value" = 865 : i32} : () -> i32
%1 = "arith.constant"() {"value" = 395 : i32} : () -> i32
%2 = "arith.addi"(%1, %0) : (i32, i32) -> i32
%3 = "arith.constant"() {"value" = 777 : i32} : () -> i32
%4 = "arith.addi"(%3, %2) : (i32, i32) -> i32
%5 = "arith.constant"() {"value" = 912 : i32} : () -> i32
"test.op"(%4) : (i32) -> ()
}) : () -> ()
```
"""
assert size >= 0
random.seed(RANDOM_SEED)
ops: list[Operation] = []
ops.append(ConstantOp(IntegerAttr(random.randint(1, 1000), i32)))
for i in range(1, size + 1):
if i % 2 == 0:
ops.append(AddiOp(ops[i - 1], ops[i - 2]))
else:
ops.append(ConstantOp(IntegerAttr(random.randint(1, 1000), i32)))
ops.append(TestOp([ops[(size // 2) * 2]]))
return ModuleOp(ops)
def bench_xdsl_constant_folding(loops: int, size: int) -> float:
"""Benchmark constant folding integer additions with xDSL."""
ctx = Context(allow_unregistered=True)
ctx.load_dialect(Arith)
ctx.load_dialect(Builtin)
constant_folding_pass = TestConstantFoldingPass()
constant_folding_workload = get_constant_folding_module(size)
range_it = range(loops)
t0 = pyperf.perf_counter()
for _ in range_it:
constant_folding_workload_mutable = constant_folding_workload.clone()
constant_folding_pass.apply(ctx, constant_folding_workload_mutable)
return pyperf.perf_counter() - t0
def add_cmdline_args(cmd, args):
"""Add command line arguments to a pyperf runner"""
cmd.extend(("--size", str(args.size)))
if __name__ == "__main__":
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args)
runner.metadata["description"] = "Benchmark xDSL constant folding integer addition"
runner.argparser.add_argument(
"--size",
type=int,
default=1000,
help="Number of integer additions (default: 1000)",
)
args = runner.parse_args()
runner.bench_time_func("xdsl_constant_fold", bench_xdsl_constant_folding, args.size)