Skip to content

Commit 95a0ae5

Browse files
authored
Merge pull request #199 from dop-amin/refactor_examples
refactor: Major example refactoring
2 parents 5fafd80 + 1bd6e87 commit 95a0ae5

File tree

419 files changed

+26080
-6640
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

419 files changed

+26080
-6640
lines changed

.github/workflows/test_basic.yaml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,26 @@ jobs:
2525
- name: Run examples
2626
run: |
2727
python3 example.py --dry-run --only-target=${{ matrix.target }}
28+
tests:
29+
name: Tests (${{ matrix.target }})
30+
runs-on: ubuntu-latest
31+
strategy:
32+
matrix:
33+
target:
34+
- slothy.targets.arm_v7m.cortex_m7
35+
- slothy.targets.arm_v81m.cortex_m55r1
36+
- slothy.targets.arm_v81m.cortex_m85r1
37+
- slothy.targets.aarch64.cortex_a55
38+
- slothy.targets.aarch64.cortex_a72_frontend
39+
- slothy.targets.aarch64.apple_m1_firestorm_experimental
40+
- slothy.targets.aarch64.apple_m1_icestorm_experimental
41+
- slothy.targets.aarch64.aarch64_big_experimental
42+
steps:
43+
- uses: actions/checkout@v3
44+
- uses: ./.github/actions/setup-ubuntu
45+
- name: Run tests
46+
run: |
47+
python3 test.py --only-target=${{ matrix.target }}
2848
tutorial:
2949
runs-on: ubuntu-latest
3050
steps:
@@ -40,7 +60,7 @@ jobs:
4060
- uses: ./.github/actions/setup-ubuntu
4161
- name: Run examples
4262
run: |
43-
python3 example.py --examples simple0,simple1,simple0_loop,simple1_loop
63+
python3 test.py --tests simple0_m55,simple1_m55,simple0_loop_m55,simple1_loop_m55
4464
examples_ntt_kyber_dilithium_helium_core:
4565
runs-on: ubuntu-latest
4666
steps:

common/OptimizationRunner.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
#
2+
# Copyright (c) 2022 Arm Limited
3+
# Copyright (c) 2022 Hanno Becker
4+
# Copyright (c) 2023 Amin Abdulrahman, Matthias Kannwischer
5+
# SPDX-License-Identifier: MIT
6+
#
7+
# Permission is hereby granted, free of charge, to any person obtaining a copy
8+
# of this software and associated documentation files (the "Software"), to deal
9+
# in the Software without restriction, including without limitation the rights
10+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
# copies of the Software, and to permit persons to whom the Software is
12+
# furnished to do so, subject to the following conditions:
13+
#
14+
# The above copyright notice and this permission notice shall be included in all
15+
# copies or substantial portions of the Software.
16+
#
17+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
# SOFTWARE.
24+
#
25+
# Author: Hanno Becker <hannobecker@posteo.de>
26+
#
27+
28+
import logging
29+
import sys
30+
from pathlib import Path
31+
32+
from slothy import Slothy
33+
34+
import slothy.targets.arm_v7m.arch_v7m as Arch_Armv7M
35+
import slothy.targets.arm_v81m.arch_v81m as Arch_Armv81M
36+
import slothy.targets.arm_v7m.cortex_m7 as Target_CortexM7
37+
import slothy.targets.arm_v81m.cortex_m55r1 as Target_CortexM55r1
38+
import slothy.targets.arm_v81m.cortex_m85r1 as Target_CortexM85r1
39+
40+
import slothy.targets.aarch64.aarch64_neon as AArch64_Neon
41+
import slothy.targets.aarch64.cortex_a55 as Target_CortexA55
42+
import slothy.targets.aarch64.cortex_a72_frontend as Target_CortexA72
43+
import slothy.targets.aarch64.aarch64_big_experimental as Target_AArch64Big
44+
import slothy.targets.aarch64.apple_m1_firestorm_experimental as Target_AppleM1_firestorm
45+
import slothy.targets.aarch64.apple_m1_icestorm_experimental as Target_AppleM1_icestorm
46+
47+
target_label_dict = {
48+
Target_CortexA55: "a55",
49+
Target_CortexA72: "a72",
50+
Target_CortexM7: "m7",
51+
Target_CortexM55r1: "m55",
52+
Target_CortexM85r1: "m85",
53+
Target_AppleM1_firestorm: "m1_firestorm",
54+
Target_AppleM1_icestorm: "m1_icestorm",
55+
Target_AArch64Big: "aarch64_big",
56+
}
57+
58+
arch_label_dict = {
59+
Arch_Armv7M: "armv7m",
60+
Arch_Armv81M: "armv8m",
61+
AArch64_Neon: "aarch64",
62+
}
63+
64+
65+
class OptimizationRunnerException(Exception):
66+
"""Exception thrown when an example goes wrong"""
67+
68+
69+
class OptimizationRunner:
70+
"""Common boilerplate for SLOTHY examples"""
71+
72+
def __init__(
73+
self,
74+
infile,
75+
name=None,
76+
funcname=None,
77+
suffix="opt",
78+
rename=False,
79+
outfile="",
80+
arch=Arch_Armv81M,
81+
target=Target_CortexM55r1,
82+
timeout=None,
83+
subfolder="",
84+
base_dir="examples",
85+
outfile_full=False,
86+
var="",
87+
**kwargs,
88+
):
89+
if name is None:
90+
name = infile
91+
92+
if var != "":
93+
name += f"_{var}"
94+
infile += f"_{var}"
95+
name += f"_{target_label_dict[target]}"
96+
97+
self.arch = arch
98+
self.target = target
99+
self.funcname = funcname
100+
self.infile = infile
101+
self.suffix = suffix
102+
if outfile_full is True:
103+
self.outfile = outfile
104+
else:
105+
if outfile == "":
106+
self.outfile = (
107+
f"{infile}_{self.suffix}_{target_label_dict[self.target]}"
108+
)
109+
else:
110+
self.outfile = (
111+
f"{outfile}_{self.suffix}_{target_label_dict[self.target]}"
112+
)
113+
if funcname is None:
114+
self.funcname = self.infile
115+
subfolder = arch_label_dict[self.arch] + "/" + subfolder
116+
self.infile_full = f"{base_dir}/naive/{subfolder}{self.infile}.s"
117+
if outfile_full is False:
118+
self.outfile_full = f"{base_dir}/opt/{subfolder}{self.outfile}.s"
119+
else:
120+
self.outfile_full = self.outfile
121+
self.name = name
122+
self.rename = rename
123+
self.timeout = timeout
124+
self.extra_args = kwargs
125+
self.target_reserved = ""
126+
127+
# By default, optimize the whole file
128+
129+
def core(self, slothy):
130+
slothy.optimize()
131+
132+
def run(
133+
self,
134+
debug=False,
135+
log_model=False,
136+
log_model_dir="models",
137+
dry_run=False,
138+
silent=False,
139+
timeout=0,
140+
debug_logfile=None,
141+
only_target=None,
142+
):
143+
144+
if dry_run is True:
145+
annotation = " (dry run only)"
146+
else:
147+
annotation = ""
148+
149+
print(f"* Example: {self.name}{annotation}...")
150+
151+
# skip eaxmples for all but the target that was asked for
152+
if only_target is not None and self.target.__name__ != only_target:
153+
return
154+
155+
handlers = []
156+
157+
h_err = logging.StreamHandler(sys.stderr)
158+
h_err.setLevel(logging.WARNING)
159+
handlers.append(h_err)
160+
161+
if silent is False:
162+
h_info = logging.StreamHandler(sys.stdout)
163+
h_info.setLevel(logging.DEBUG)
164+
h_info.addFilter(lambda r: r.levelno == logging.INFO)
165+
handlers.append(h_info)
166+
167+
if debug is True:
168+
h_verbose = logging.StreamHandler(sys.stdout)
169+
h_verbose.setLevel(logging.DEBUG)
170+
h_verbose.addFilter(lambda r: r.levelno < logging.INFO)
171+
handlers.append(h_verbose)
172+
173+
if debug_logfile is not None:
174+
h_file = logging.FileHandler(debug_logfile)
175+
h_file.setLevel(logging.DEBUG)
176+
handlers.append(h_file)
177+
178+
if debug is True or debug_logfile is not None:
179+
base_level = logging.DEBUG
180+
else:
181+
base_level = logging.INFO
182+
183+
logging.basicConfig(
184+
level=base_level,
185+
handlers=handlers,
186+
)
187+
logger = logging.getLogger(self.name)
188+
189+
slothy = Slothy(self.arch, self.target, logger=logger)
190+
slothy.load_source_from_file(self.infile_full)
191+
192+
if timeout != 0:
193+
slothy.config.timeout = timeout
194+
elif self.timeout is not None:
195+
slothy.config.timeout = self.timeout
196+
197+
if dry_run is True:
198+
slothy.config.constraints.functional_only = True
199+
slothy.config.constraints.allow_reordering = False
200+
slothy.config.constraints.allow_renaming = False
201+
slothy.config.variable_size = True
202+
203+
if log_model is True:
204+
slothy.config.log_model_dir = log_model_dir
205+
slothy.config.log_model = self.name
206+
207+
# On Apple M1, we must not use x18
208+
if "m1" in target_label_dict[self.target]:
209+
self.target_reserved = ["x18"]
210+
211+
self.core(slothy, *self.extra_args)
212+
213+
if self.rename:
214+
slothy.rename_function(
215+
self.funcname,
216+
f"{self.funcname}_{self.suffix}_{target_label_dict[self.target]}",
217+
)
218+
219+
if dry_run is False:
220+
out_dir = Path(self.outfile_full).parent
221+
out_dir.mkdir(parents=True, exist_ok=True)
222+
slothy.write_source_to_file(self.outfile_full)

0 commit comments

Comments
 (0)