Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions backends/openvino/tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Unit Tests for OpenVINO Backend

## Directory Structure

Below is the layout of the `backends/openvino/tests` directory, which includes the necessary files for the example applications:

```
backends/openvino/tests
├── ops # Directory with base op test script and individual op tests.
├── base_openvino_op_test.py # Script which contains the base class for all op tests.
└── test_<op_name>.py # Individual op tests scripts.
├── models # Directory with model test scripts.
└── test_classification.py # Test script for classification models.
├── README.md # Documentation for unit tests (this file)
└── test_runner.py # Script to execute unit tests.
```

## Executing Unit Tests

### Prerequisites

Before you begin, refer to instructions provided in [OpenVINO Backend for ExecuTorch](../README.md) to install openvino and setup executorch environment.
Once openvino is installed and executorch environment is set, refer to [OpenVINO Backend Examples](../../../examples/openvino/README.md) to build openvino_example_runner.

### Usage

`test_runner.py` allows to run op or model tests for openvino backend.

### **Arguments**
- **`--build_folder`** (required):
Path to cmake binary directory. (Refer to [OpenVINO Backend Examples](../../../examples/openvino/README.md))
Examples:
- `../../../cmake-openvino-out` (Relative path from `backends/openvino/tests` directory)
- `<executorch_root>/cmake-openvino-out` (Absolute path to the default build folder)

- **`--test_type`** (optional):
Type of the tests to run.
Supported values:
- `ops` (default)
- `models`

- **`--pattern`** (optional):
Pattern to match test files. Provide complete file name to run individual tests. The default value is `test_*.py`
Examples:
- `test_convolution.py` (Assuming `--test_type` parameter is provided as `ops`, this will run only convolution tests)
- `test_add*.py` (Assuming `--test_type` parameter is provided as `ops`, this will run add and addmm op tests)

- **`--device`** (optional):
Target device to compile and run tests. Default is `CPU`.
Examples: `CPU`, `GPU`


## **Examples**

### Execute Tests for All Ops on CPU
```bash
python test_runner.py --build_folder ../../../cmake-openvino-out --device CPU --test_type ops
```

### Execute Convolution Op Tests on CPU
```bash
python test_runner.py --build_folder ../../../cmake-openvino-out --device CPU --test_type ops --pattern test_convolution.py
```

### Execute Tests for all Models on GPU
```bash
python test_runner.py --build_folder ../../../cmake-openvino-out --device GPU --test_type models
5 changes: 1 addition & 4 deletions backends/openvino/tests/ops/base_openvino_op_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,10 @@ def execute_layer_test(
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
env=env,
cwd=tmp_dir,
)

stdout_str = proc.stdout.decode('utf-8')

# Check if execution completed successfully
self.assertIn("Model executed successfully.", stdout_str)
self.assertTrue(proc.returncode == 0)

# Read the outputs from the temporary files
output_dir = f"{tmp_dir}/outputs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,8 @@ def parse_arguments():
# Discover all existing op tests in "ops" folder
suite = loader.discover(test_params['test_type'], pattern=test_params['pattern'])
# Start running tests
unittest.TextTestRunner().run(suite)
result = unittest.TextTestRunner().run(suite)
if result.wasSuccessful():
print("OpenVINO backend tests completed successfully")
else:
print("OpenVINO backend tests completed with failures")
10 changes: 3 additions & 7 deletions examples/openvino/aot/aot_openvino_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from executorch.backends.openvino import OpenVINOQuantizer
from executorch.backends.openvino.partitioner import OpenvinoPartitioner
from executorch.exir import EdgeProgramManager
from executorch.exir import to_edge
from executorch.exir import to_edge_transform_and_lower
from executorch.exir.backend.backend_details import CompileSpec
from sklearn.metrics import accuracy_score
from timm.data import resolve_data_config
Expand Down Expand Up @@ -201,13 +201,9 @@ def main(

aten_dialect: ExportedProgram = export(quantized_model, example_args)

# Convert to edge dialect
edge_program: EdgeProgramManager = to_edge(aten_dialect)
to_be_lowered_module = edge_program.exported_program()

# Lower the module to the backend with a custom partitioner
# Convert to edge dialect and lower the module to the backend with a custom partitioner
compile_spec = [CompileSpec("device", device.encode())]
lowered_module = edge_program.to_backend(OpenvinoPartitioner(compile_spec))
lowered_module: EdgeProgramManager = to_edge_transform_and_lower(aten_dialect, partitioner=[OpenvinoPartitioner(compile_spec),])

# Apply backend-specific passes
exec_prog = lowered_module.to_executorch(config=executorch.exir.ExecutorchBackendConfig())
Expand Down
13 changes: 9 additions & 4 deletions examples/openvino/executor_runner/openvino_executor_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ std::vector<std::vector<std::string>>
get_inputs_paths(const char *input_list_path) {
size_t idx = 0;

auto split = [](std::string s, std::string delimiter) {
auto split_and_add_prefix = [](std::string s, std::string delimiter, std::string prefix = "") {
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
std::string token;
std::vector<std::string> res;

while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
token = s.substr(pos_start, pos_end - pos_start);
pos_start = pos_end + delim_len;
res.push_back(token);
res.push_back(prefix + token);
}
res.push_back(s.substr(pos_start));
res.push_back(prefix + s.substr(pos_start));
return res;
};

Expand All @@ -121,10 +121,15 @@ get_inputs_paths(const char *input_list_path) {
if (!input_list.is_open()) {
ET_CHECK_MSG(false, "Failed to read input list file: %s", input_list_path);
}
std::string inputs_dir = "";
size_t last_pos = std::string(input_list_path).rfind('/');
if (last_pos != std::string::npos) {
inputs_dir = std::string(input_list_path).substr(0, last_pos+1);
}
std::string file_path;
auto retval = std::vector<std::vector<std::string>>();
while (std::getline(input_list, file_path)) {
auto input_files = split(file_path, " ");
auto input_files = split_and_add_prefix(file_path, " ", inputs_dir);
if (input_files.size() == 0) {
break;
}
Expand Down