18
18
import numpy as np
19
19
import torch
20
20
21
- from executorch .backends .arm .arm_backend import is_tosa
21
+ from executorch .backends .arm .arm_backend import is_tosa , is_vgf
22
22
from executorch .backends .arm .test .conftest import is_option_enabled
23
23
from executorch .backends .arm .tosa_specification import (
24
24
get_tosa_spec ,
57
57
torch .complex128 : np .complex128 ,
58
58
}
59
59
60
+ VALID_TARGET = {"corstone-300" , "corstone-320" , "vkml_emulation_layer" }
61
+
60
62
61
63
class QuantizationParams :
62
64
__slots__ = ["node_name" , "zp" , "scale" , "qmin" , "qmax" , "dtype" ]
@@ -218,6 +220,69 @@ def __torch_function__(self, func, types, args=..., kwargs=None):
218
220
return func (* args , ** kwargs )
219
221
220
222
223
+ def run_target (
224
+ executorch_program_manager : ExecutorchProgramManager ,
225
+ inputs : Tuple [torch .Tensor ],
226
+ intermediate_path : str | Path ,
227
+ target_board : Literal ["corestone-300" , "corestone-320" , "vkml_emulation_layer" ],
228
+ elf_path : str | Path ,
229
+ timeout : int = 120 , # s
230
+ ):
231
+ if target_board not in VALID_TARGET :
232
+ raise ValueError (f"Unsupported target: { target_board } " )
233
+
234
+ if target_board in ("corstone-300" , "corstone-320" ):
235
+ return run_corstone (
236
+ executorch_program_manager ,
237
+ inputs ,
238
+ intermediate_path ,
239
+ target_board ,
240
+ elf_path ,
241
+ timeout ,
242
+ )
243
+ elif target_board == "vkml_emulation_layer" :
244
+ return run_vkml_emulation_layer (
245
+ executorch_program_manager ,
246
+ intermediate_path ,
247
+ elf_path ,
248
+ )
249
+
250
+
251
+ def run_vkml_emulation_layer (
252
+ executorch_program_manager : ExecutorchProgramManager ,
253
+ intermediate_path : str | Path ,
254
+ elf_path : str | Path ,
255
+ ):
256
+ """Executes an inference of the exported_program on ML Emulation Layer for Vulkan
257
+ Args:
258
+ `executorch_program_manager`: The executorch program to run.
259
+ `intermediate_path`: Directory to save the .pte and capture outputs.
260
+ `elf_path`: Path to the Vulkan-capable executor_runner binary.
261
+ """
262
+
263
+ intermediate_path = Path (intermediate_path )
264
+ intermediate_path .mkdir (exist_ok = True )
265
+ elf_path = Path (elf_path )
266
+ if not elf_path .exists ():
267
+ raise FileNotFoundError (f"Did not find elf file { elf_path } " )
268
+
269
+ # Save pte to file
270
+ pte_path = os .path .join (intermediate_path , "program.pte" )
271
+ with open (pte_path , "wb" ) as f :
272
+ f .write (executorch_program_manager .buffer )
273
+
274
+ cmd_line = [elf_path , "-model_path" , pte_path ]
275
+ result = _run_cmd (cmd_line )
276
+
277
+ result_stdout = result .stdout .decode () # noqa: F841
278
+ # TODO: MLETORCH-1234: Support VGF e2e tests in VgfPipeline
279
+ # TODO: Add regex to check for error or fault messages in stdout from Emulation Layer
280
+ # TODO: Retrieve and return the output tensors once VGF runtime is able to dump them.
281
+ raise NotImplementedError (
282
+ "Output parsing from VKML Emulation Layer is not yet implemented. "
283
+ )
284
+
285
+
221
286
def run_corstone (
222
287
executorch_program_manager : ExecutorchProgramManager ,
223
288
inputs : Tuple [torch .Tensor ],
@@ -229,7 +294,7 @@ def run_corstone(
229
294
"""Executes an inference of the exported_program on FVP.
230
295
Returns a list of tensors with the output.
231
296
Args:
232
- `executorch_program_manager`: the executorch program to run.
297
+ `executorch_program_manager`: The executorch program to run.
233
298
The output of a EdgeProgramManager.to_executorch() call.
234
299
`inputs`: A list of tensors with the inputs of the inference.
235
300
`dump_path`: A directory where the .pte and inputs are saved to file.
@@ -558,18 +623,52 @@ def model_converter_installed() -> bool:
558
623
return True
559
624
560
625
561
- def get_elf_path (target_board ):
562
- elf_path = os .path .join (
563
- "arm_test" ,
564
- f"arm_semihosting_executor_runner_{ target_board } " ,
565
- "arm_executor_runner" ,
566
- )
626
+ def vkml_emulation_layer_installed () -> bool :
627
+ # Check VK_INSTANCE_LAYERS
628
+ vk_instance_layers = os .environ .get ("VK_INSTANCE_LAYERS" , "" )
629
+ required_layers = {
630
+ "VK_LAYER_ML_Graph_Emulation" ,
631
+ "VK_LAYER_ML_Tensor_Emulation" ,
632
+ }
633
+ existing_layers = set (vk_instance_layers .split (":" ))
634
+ layers_exists = required_layers .issubset (existing_layers )
635
+
636
+ # Check LD_LIBRARY_PATH for "emulation-layer/deploy"
637
+ ld_library_path = os .environ .get ("LD_LIBRARY_PATH" , "" )
638
+ deploy_exists = False
639
+ for path in ld_library_path .split (os .path .pathsep ):
640
+ if "emulation-layer/deploy" in path and os .path .isdir (path ):
641
+ deploy_exists = True
642
+
643
+ return layers_exists and deploy_exists
644
+
645
+
646
+ def assert_elf_path_exists (elf_path ):
567
647
if not os .path .exists (elf_path ):
568
648
raise FileNotFoundError (
569
- f"Did not find build arm_executor_runner in path { elf_path } , run setup_testing.sh?"
649
+ f"Did not find build arm_executor_runner or executor_runner in path { elf_path } , run setup_testing.sh?"
570
650
)
571
- else :
572
- return elf_path
651
+
652
+
653
+ def get_elf_path (target_board ):
654
+ if target_board not in VALID_TARGET :
655
+ raise ValueError (f"Unsupported target: { target_board } " )
656
+
657
+ if target_board in ("corstone-300" , "corstone-320" ):
658
+ elf_path = os .path .join (
659
+ "arm_test" ,
660
+ f"arm_semihosting_executor_runner_{ target_board } " ,
661
+ "arm_executor_runner" ,
662
+ )
663
+ assert_elf_path_exists (elf_path )
664
+ elif target_board == "vkml_emulation_layer" :
665
+ elf_path = os .path .join (
666
+ "cmake-out" ,
667
+ "executor_runner" ,
668
+ )
669
+ assert_elf_path_exists (elf_path )
670
+
671
+ return elf_path
573
672
574
673
575
674
def arm_executor_runner_exists (target_board ):
@@ -629,6 +728,8 @@ def transpose_data_format(data: list[np.ndarray], to: Literal["NHWC", "NCHW"]):
629
728
630
729
631
730
def get_target_board (compile_spec : list [CompileSpec ]) -> str | None :
731
+ if is_vgf (compile_spec ):
732
+ return "vkml_emulation_layer"
632
733
for spec in compile_spec :
633
734
if spec .key == "compile_flags" :
634
735
flags = spec .value .decode ()
0 commit comments