Skip to content

Commit 5877c2a

Browse files
perfacebook-github-bot
authored andcommitted
Corstone-320 download and tests (pytorch#5787)
Summary: Handle downloading of Corstone-320 FVP and add support for running unit tests on the platform. Pull Request resolved: pytorch#5787 Reviewed By: digantdesai Differential Revision: D63762487 Pulled By: mergennachin fbshipit-source-id: 286b80ff9bf38e8faf87f3668f5c3884ea82fa26
1 parent 393553c commit 5877c2a

File tree

5 files changed

+161
-67
lines changed

5 files changed

+161
-67
lines changed

backends/arm/test/models/test_mobilenet_v2_arm.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,11 @@ def test_mv2_u55_BI(self):
100100
)
101101
if common.is_option_enabled("corstone300"):
102102
tester.run_method_and_compare_outputs(
103-
atol=1.0, qtol=1, inputs=self.model_inputs
103+
atol=1.0, qtol=1, inputs=self.model_inputs, target_board="corstone-300"
104104
)
105105

106106
def test_mv2_u85_BI(self):
107-
(
107+
tester = (
108108
ArmTester(
109109
self.mv2,
110110
example_inputs=self.model_inputs,
@@ -116,4 +116,9 @@ def test_mv2_u85_BI(self):
116116
.check(list(self.operators_after_quantization))
117117
.partition()
118118
.to_executorch()
119+
.serialize()
119120
)
121+
if common.is_option_enabled("corstone300"):
122+
tester.run_method_and_compare_outputs(
123+
atol=1.0, qtol=1, inputs=self.model_inputs, target_board="corstone-320"
124+
)

backends/arm/test/ops/test_add.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,22 @@ def test_add_u55_BI(self, test_data: torch.Tensor):
137137
test_data,
138138
)
139139
if common.is_option_enabled("corstone300"):
140-
tester.run_method_and_compare_outputs(qtol=1, inputs=test_data)
140+
tester.run_method_and_compare_outputs(
141+
qtol=1, inputs=test_data, target_board="corstone-300"
142+
)
141143

142144
@parameterized.expand(Add.test_parameters)
143145
def test_add_u85_BI(self, test_data: torch.Tensor):
144146
test_data = (test_data,)
145-
self._test_add_ethos_BI_pipeline(
147+
tester = self._test_add_ethos_BI_pipeline(
146148
self.Add(),
147149
common.get_u85_compile_spec(permute_memory_to_nhwc=True),
148150
test_data,
149151
)
152+
if common.is_option_enabled("corstone300"):
153+
tester.run_method_and_compare_outputs(
154+
qtol=1, inputs=test_data, target_board="corstone-320"
155+
)
150156

151157
@parameterized.expand(Add2.test_parameters)
152158
def test_add2_tosa_MI(self, operand1: torch.Tensor, operand2: torch.Tensor):
@@ -165,11 +171,17 @@ def test_add2_u55_BI(self, operand1: torch.Tensor, operand2: torch.Tensor):
165171
self.Add2(), common.get_u55_compile_spec(), test_data
166172
)
167173
if common.is_option_enabled("corstone300"):
168-
tester.run_method_and_compare_outputs(qtol=1, inputs=test_data)
174+
tester.run_method_and_compare_outputs(
175+
qtol=1, inputs=test_data, target_board="corstone-300"
176+
)
169177

170178
@parameterized.expand(Add2.test_parameters)
171179
def test_add2_u85_BI(self, operand1: torch.Tensor, operand2: torch.Tensor):
172180
test_data = (operand1, operand2)
173-
self._test_add_ethos_BI_pipeline(
181+
tester = self._test_add_ethos_BI_pipeline(
174182
self.Add2(), common.get_u85_compile_spec(), test_data
175183
)
184+
if common.is_option_enabled("corstone300"):
185+
tester.run_method_and_compare_outputs(
186+
qtol=1, inputs=test_data, target_board="corstone-320"
187+
)

backends/arm/test/runner_utils.py

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def __init__(
177177
self.qp_input: list[QuantizationParams] = None
178178
self.qp_output: QuantizationParams = None
179179
self.timeout = 120
180+
self.target_board: str = None
180181

181182
self._has_init_run = False
182183

@@ -185,11 +186,17 @@ def init_run(
185186
exported_program: ExportedProgram,
186187
edge_program: ExportedProgram,
187188
is_quantized: bool,
189+
target_board: str,
188190
):
191+
192+
if target_board not in ["corstone-300", "corstone-320"]:
193+
raise RuntimeError(f"Unknown target board: {target_board}")
194+
189195
self.input_names = _get_input_names(edge_program)
190196
self.output_node = _get_output_node(exported_program)
191197
self.output_name = self.output_node.name
192198
self.is_quantized = is_quantized
199+
self.target_board = target_board
193200

194201
if is_quantized:
195202
self.qp_input = _get_input_quantization_params(exported_program)
@@ -205,7 +212,7 @@ def init_run(
205212
def set_timeout(self, timeout: int):
206213
self.timeout = timeout
207214

208-
def run_corstone300(
215+
def run_corstone(
209216
self,
210217
inputs: Tuple[torch.Tensor],
211218
) -> list[torch.Tensor]:
@@ -231,7 +238,7 @@ def run_corstone300(
231238
)
232239
elf_path = os.path.join(
233240
"cmake-out",
234-
"arm_semihosting_executor_runner_corstone-300",
241+
f"arm_semihosting_executor_runner_{self.target_board}",
235242
"arm_executor_runner",
236243
)
237244
assert os.path.exists(
@@ -242,32 +249,66 @@ def run_corstone300(
242249
for input_path in input_paths:
243250
cmd_line += f" -i {input_path}"
244251

245-
command_args = [
246-
"FVP_Corstone_SSE-300_Ethos-U55",
247-
"-C",
248-
"ethosu.num_macs=128",
249-
"-C",
250-
"mps3_board.visualisation.disable-visualisation=1",
251-
"-C",
252-
"mps3_board.telnetterminal0.start_telnet=0",
253-
"-C",
254-
"mps3_board.uart0.out_file='-'",
255-
"-C",
256-
"cpu0.CFGITCMSZ=11",
257-
"-C",
258-
"cpu0.semihosting-enable=1",
259-
"-C",
260-
"cpu0.semihosting-stack_base=0",
261-
"-C",
262-
"cpu0.semihosting-heap_limit=0",
263-
"-C",
264-
f"cpu0.semihosting-cmd_line='{cmd_line}'",
265-
"-a",
266-
elf_path,
267-
"--timelimit",
268-
f"{self.timeout}",
269-
]
270-
result = _run_cmd(command_args, check=False)
252+
command_args = {
253+
"corstone-300": [
254+
"FVP_Corstone_SSE-300_Ethos-U55",
255+
"-C",
256+
"ethosu.num_macs=128",
257+
"-C",
258+
"mps3_board.visualisation.disable-visualisation=1",
259+
"-C",
260+
"mps3_board.telnetterminal0.start_telnet=0",
261+
"-C",
262+
"mps3_board.uart0.out_file='-'",
263+
"-C",
264+
"cpu0.CFGITCMSZ=11",
265+
"-C",
266+
"cpu0.semihosting-enable=1",
267+
"-C",
268+
"cpu0.semihosting-stack_base=0",
269+
"-C",
270+
"cpu0.semihosting-heap_limit=0",
271+
"-C",
272+
f"cpu0.semihosting-cmd_line='{cmd_line}'",
273+
"-a",
274+
elf_path,
275+
"--timelimit",
276+
f"{self.timeout}",
277+
],
278+
"corstone-320": [
279+
"FVP_Corstone_SSE-320",
280+
"-C",
281+
"mps4_board.subsystem.ethosu.num_macs=128",
282+
"-C",
283+
"mps4_board.visualisation.disable-visualisation=1",
284+
"-C",
285+
"mps4_board.telnetterminal0.start_telnet=0",
286+
"-C",
287+
"mps4_board.uart0.out_file='-'",
288+
"-C",
289+
"mps4_board.uart0.unbuffered_output=1",
290+
"-C",
291+
"mps4_board.uart0.shutdown_on_eot=1",
292+
"-C",
293+
"mps4_board.subsystem.cpu0.semihosting-enable=1",
294+
"-C",
295+
"mps4_board.subsystem.cpu0.semihosting-stack_base=0",
296+
"-C",
297+
"mps4_board.subsystem.cpu0.semihosting-heap_limit=0",
298+
"-C",
299+
f"mps4_board.subsystem.cpu0.semihosting-cmd_line='{cmd_line}'",
300+
"-a",
301+
elf_path,
302+
"--timelimit",
303+
f"{self.timeout}",
304+
],
305+
}
306+
307+
result = _run_cmd(command_args[self.target_board], check=False)
308+
if result.returncode != 0:
309+
raise RuntimeError(
310+
f"Failed to run {command_args[self.target_board]}\nError: {result.stderr.decode()}"
311+
)
271312
result_stdout = result.stdout.decode()
272313

273314
error_regex = r"(^[EF][: ].*$)|(^.*Hard fault.*$)|(^.*Assertion.*$)"
@@ -276,10 +317,8 @@ def run_corstone300(
276317
# regex to check for error or fault messages in stdout from FVP
277318
if re.compile(error_regex, re.MULTILINE).search(result_stdout):
278319
raise RuntimeError(
279-
f"Corstone simulation failed, log: \n {result_stdout}\n{result.stderr.decode()}"
320+
f"Corstone simulation failed:\ncmd: {command_args[self.target_board]}\n, log: \n {result_stdout}\n{result.stderr.decode()}"
280321
)
281-
elif "E [" in result_stdout:
282-
logger.error(result_stdout)
283322

284323
tosa_ref_output = np.fromfile(out_path_with_suffix, dtype=np.float32)
285324
output_shape = self.output_node.args[0][0].meta["val"].shape

backends/arm/test/tester/arm_tester.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def __init__(self, runner_util: RunnerUtil, timeout: int = 1):
9898
self.runner.set_timeout(timeout)
9999

100100
def run_artifact(self, inputs):
101-
return self.runner.run_corstone300(inputs)
101+
return self.runner.run_corstone(inputs)
102102

103103
def dump_artifact(self, path_to_dump: Optional[str]):
104104
if not path_to_dump:
@@ -226,6 +226,7 @@ def run_method_and_compare_outputs(
226226
self,
227227
inputs: Optional[Tuple[torch.Tensor]] = None,
228228
stage: Optional[str] = None,
229+
target_board: Optional[str] = "corstone-300",
229230
num_runs=1,
230231
atol=1e-03,
231232
rtol=1e-03,
@@ -260,7 +261,12 @@ def run_method_and_compare_outputs(
260261
edge_program = self.stages[
261262
self.stage_name(tester.ToEdge)
262263
].artifact.exported_program()
263-
self.runner_util.init_run(exported_program, edge_program, is_quantized)
264+
self.runner_util.init_run(
265+
exported_program,
266+
edge_program,
267+
is_quantized,
268+
target_board,
269+
)
264270

265271
if is_quantized:
266272
reference_stage = self.stages[self.stage_name(tester.Quantize)]

examples/arm/setup.sh

Lines changed: 60 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,28 @@ function verify_md5() {
4545
script_dir=$(cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd)
4646

4747
if [[ "${ARCH}" == "x86_64" ]]; then
48-
# FVP
49-
fvp_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-300/FVP_Corstone_SSE-300_11.22_20_Linux64.tgz?rev=018659bd574f4e7b95fa647e7836ccf4&hash=22A79103C6FA5FFA7AFF3BE0447F3FF9"
50-
fvp_model_dir="Linux64_GCC-9.3"
51-
fvp_md5_checksum="98e93b949d0fbac977292d8668d34523"
48+
# FVPs
49+
corstone300_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-300/FVP_Corstone_SSE-300_11.22_20_Linux64.tgz?rev=018659bd574f4e7b95fa647e7836ccf4&hash=22A79103C6FA5FFA7AFF3BE0447F3FF9"
50+
corstone300_model_dir="Linux64_GCC-9.3"
51+
corstone300_md5_checksum="98e93b949d0fbac977292d8668d34523"
52+
53+
corstone320_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-320/FVP_Corstone_SSE-320_11.27_25_Linux64.tgz?rev=a507bffc219a4d5792f1192ab7002d89&hash=D9A824AA8227D2E679C9B9787FF4E8B6FBE3D7C6"
54+
corstone320_model_dir="Linux64_GCC-9.3"
55+
corstone320_md5_checksum="3deb3c68f9b2d145833f15374203514d"
5256

5357
# toochain
5458
toolchain_url="https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi.tar.xz"
5559
toolchain_dir="arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-eabi"
5660
toolchain_md5_checksum="00ebb1b70b1f88906c61206457eacb61"
5761
elif [[ "${ARCH}" == "aarch64" ]] || [[ "${ARCH}" == "arm64" ]]; then
58-
# FVP
59-
fvp_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-300/FVP_Corstone_SSE-300_11.22_20_Linux64_armv8l.tgz?rev=9cc6e9a32bb947ca9b21fa162144cb01&hash=7657A4CF27D42E892E3F08D452AAB073"
60-
fvp_model_dir="Linux64_armv8l_GCC-9.3"
61-
fvp_md5_checksum="cbbabbe39b07939cff7a3738e1492ef1"
62+
# FVPs
63+
corstone300_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-300/FVP_Corstone_SSE-300_11.22_20_Linux64_armv8l.tgz?rev=9cc6e9a32bb947ca9b21fa162144cb01&hash=7657A4CF27D42E892E3F08D452AAB073"
64+
corstone300_model_dir="Linux64_armv8l_GCC-9.3"
65+
corstone300_md5_checksum="cbbabbe39b07939cff7a3738e1492ef1"
66+
67+
corstone320_url="https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Corstone-320/FVP_Corstone_SSE-320_11.27_25_Linux64_armv8l.tgz?rev=b6ebe0923cb84f739e017385fd3c333c&hash=8965C4B98E2FF7F792A099B08831FE3CB6120493"
68+
corstone320_model_dir="Linux64_armv8l_GCC-9.3"
69+
corstone320_md5_checksum="3889f1d80a6d9861ea4aa6f1c88dd0ae"
6270

6371
# toochain
6472
if [[ "${OS}" == "Darwin" ]]; then
@@ -105,26 +113,50 @@ function setup_fvp() {
105113
fi
106114

107115
# Download and install the Corstone 300 FVP simulator platform
108-
cd "${root_dir}"
109-
if [[ ! -e FVP_cs300.tgz ]]; then
110-
echo "[${FUNCNAME[0]}] Downloading FVP ..."
111-
curl --output FVP_cs300.tgz "${fvp_url}"
112-
verify_md5 ${fvp_md5_checksum} FVP_cs300.tgz
113-
fi
114-
115-
echo "[${FUNCNAME[0]}] Installing FVP ..."
116-
rm -rf FVP
117-
mkdir -p FVP
118-
cd FVP
119-
tar xf ../FVP_cs300.tgz
120-
./FVP_Corstone_SSE-300.sh --i-agree-to-the-contained-eula --force --destination ./ --quiet --no-interactive
121-
122-
fvp_bin_path="$(cd models/${fvp_model_dir} && pwd)"
123-
export PATH=${PATH}:${fvp_bin_path}
124-
125-
hash FVP_Corstone_SSE-300_Ethos-U55
126-
echo "export PATH=\${PATH}:${fvp_bin_path}" >> ${setup_path_script}
127-
116+
fvps=("corstone300" "corstone320")
117+
118+
for fvp in "${fvps[@]}"; do
119+
cd "${root_dir}"
120+
if [[ ! -e "FVP_${fvp}.tgz" ]]; then
121+
echo "[${FUNCNAME[0]}] Downloading FVP ${fvp}..."
122+
url_variable=${fvp}_url
123+
fvp_url=${!url_variable}
124+
curl --output "FVP_${fvp}.tgz" "${fvp_url}"
125+
md5_variable=${fvp}_md5_checksum
126+
fvp_md5_checksum=${!md5_variable}
127+
verify_md5 ${fvp_md5_checksum} FVP_${fvp}.tgz
128+
fi
129+
130+
echo "[${FUNCNAME[0]}] Installing FVP ${fvp}..."
131+
rm -rf FVP-${fvp}
132+
mkdir -p FVP-${fvp}
133+
cd FVP-${fvp}
134+
tar xf ../FVP_${fvp}.tgz
135+
136+
# Install the FVP
137+
case ${fvp} in
138+
corstone300)
139+
./FVP_Corstone_SSE-300.sh --i-agree-to-the-contained-eula --force --destination ./ --quiet --no-interactive
140+
;;
141+
corstone320)
142+
./FVP_Corstone_SSE-320.sh --i-agree-to-the-contained-eula --force --destination ./ --quiet --no-interactive
143+
;;
144+
*)
145+
echo "[${FUNCNAME[0]}] Error: Unknown FVP model ${fvp}. Exiting."
146+
exit 1
147+
;;
148+
esac
149+
150+
model_dir_variable=${fvp}_model_dir
151+
fvp_model_dir=${!model_dir_variable}
152+
fvp_bin_path="$(cd models/${fvp_model_dir} && pwd)"
153+
export PATH=${PATH}:${fvp_bin_path}
154+
155+
echo "export PATH=\${PATH}:${fvp_bin_path}" >> ${setup_path_script}
156+
done
157+
158+
# Fixup for Corstone-320 python dependency
159+
echo "export LD_LIBRARY_PATH=${root_dir}/FVP-corstone320/python/lib/" >> ${setup_path_script}
128160
}
129161

130162
function setup_toolchain() {

0 commit comments

Comments
 (0)