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
9 changes: 7 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
PROJECT(hal-backend-ml CXX)
INCLUDE(GNUInstallDirs)

option(ENABLE_DUMMY "Enable dummy-passthrough backend" OFF)
option(ENABLE_VIVANTE "Enable vivante backend" OFF)
option(ENABLE_SNPE "Enable snpe backend" OFF)
option(BUILD_TESTS "Build unit tests" OFF)

SET(HAL_LIBDIR ${CMAKE_HAL_LIBDIR_PREFIX})
SET(HAL_LICENSEDIR ${CMAKE_HAL_LICENSEDIR_PREFIX})
Expand All @@ -23,7 +24,7 @@ SET(VERSION_FLAGS "-DVERSION='\"${VERSION}\"' -DVERSION_MAJOR=${VERSION_MAJOR} -
INCLUDE(FindPkgConfig)

# Common Options
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -fomit-frame-pointer -std=gnu++0x")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O2 -fomit-frame-pointer -std=c++14")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${VERSION_FLAGS}")
Expand Down Expand Up @@ -98,3 +99,7 @@ ADD_LIBRARY(${SNPE_LIBRARY_NAME} SHARED ${SNPE_SRCS} ${UTIL_SRCS})
TARGET_LINK_LIBRARIES(${SNPE_LIBRARY_NAME} ${snpe_build_dep_pkgs_LDFLAGS})
INSTALL(TARGETS ${SNPE_LIBRARY_NAME} DESTINATION ${HAL_LIBDIR} COMPONENT RuntimeLibraries)
ENDIF()

IF(BUILD_TESTS)
ADD_SUBDIRECTORY(test)
ENDIF()
150 changes: 141 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# HAL ML Accelerator Backends

This document provides an overview of the available Machine Learning (ML) accelerator backends within this project. It details their purpose, configuration, and specific custom properties that can be used to tailor their behavior.
This document provides an overview of the available Machine Learning (ML) accelerator backends within this project. It details their purpose, configuration, specific custom properties, and testing setup.

## 1. Vivante Backend (`ml-vivante`)

Expand All @@ -14,19 +14,20 @@ There are two options:
1. model.nb + model.json
2. model.nb + model.so

- **Model Files (`prop->model_files`):**
- **Model Files (`prop->model_files`):**
- `model_files[0]`: Path to the Vivante model file (e.g., `my_model.nb`). This file contains the neural network graph and weights.
- (Optional) `model_files[1]`: Path to the Vivante shared object file (e.g., `vnn_my_model.so`). This library provides functions like `vnn_CreateNeuralNetwork` and `vnn_ReleaseNeuralNetwork`.

Note that if the shared object file is not provided, the backend attempts to load the model using the JSON file (json path should be specified in `custom_properties`)

### Custom Properties (`prop->custom_properties`)

- **`json`**:
- **`json`**:
- **Description:** Path to the JSON file for the given model file.
- **Key:** `json`
- **Value:** Path to the JSON file.
- **Example:** `json:/path/to/my_model.json`

```json
// yolo-v8m.json
{
Expand Down Expand Up @@ -78,39 +79,40 @@ Note that if the shared object file is not provided, the backend attempts to loa

### Configuration

- **Model Files (`prop->model_files`):**
- **Model Files (`prop->model_files`):**
- `model_files[0]`: Path to the SNPE model file (e.g., `my_model.dlc`).

### Custom Properties (`prop->custom_properties`)

Custom properties for the SNPE backend are provided as a single string, with individual `key:value` pairs separated by commas.

**Format:** `key1:value1,key2:value2,key3:value3a;value3b`

- **`Runtime`**:
- **`Runtime`**:
- **Description:** Specifies the preferred SNPE runtime target for model execution.
- **Key:** `Runtime`
- **Value:**
- **Value:**
- `CPU`: Use CPU runtime.
- `GPU`: Use GPU runtime.
- `DSP`: Use DSP runtime.
- `NPU` or `AIP`: Use NPU/AIP runtime (specifically maps to `SNPE_RUNTIME_AIP_FIXED8_TF`).
- **Example:** `Runtime:DSP`

- **`OutputTensor`**:
- **`OutputTensor`**:
- **Description:** Specifies the names of the output tensors the application wishes to retrieve. If not provided, the backend uses all default output tensors defined in the model.
- **Key:** `OutputTensor`
- **Value:** A semicolon-separated list of output tensor names. Tensor names themselves can include colons.
- **Example:** `OutputTensor:detection_scores:0;detection_classes:0;raw_outputs/box_encodings`

- **`OutputType`**:
- **`OutputType`**:
- **Description:** Specifies the desired data types for the output tensors. The order of types in the list should correspond to the order of output tensors (either the default order or the order specified by the `OutputTensor` property).
- **Key:** `OutputType`
- **Value:** A semicolon-separated list of data types.
- `FLOAT32`: Output tensor data type will be 32-bit float.
- `TF8`: Output tensor data type will be 8-bit quantized (typically `uint8_t`).
- **Example:** `OutputType:FLOAT32;TF8` (assuming two output tensors, the first as float32, the second as TF8)

- **`InputType`**:
- **`InputType`**:
- **Description:** Specifies the data types for the input tensors. The order of types in the list should correspond to the order of input tensors as defined in the model.
- **Key:** `InputType`
- **Value:** A semicolon-separated list of data types.
Expand All @@ -121,3 +123,133 @@ Custom properties for the SNPE backend are provided as a single string, with ind
### Example `custom_properties` String for SNPE:

`"Runtime:DSP,OutputTensor:my_output_tensor1;my_output_tensor2,OutputType:FLOAT32;FLOAT32,InputType:TF8"`

### Input Data Files for Testing

For testing purposes, you can specify raw input data files to load instead of using zero-filled buffers. This is configured in the JSON config file under the `configParameters` object:

- **`input_file`**:
- **Description:** Array of paths to raw binary input data files. One file per input tensor.
- **Format:** Array of file paths
- **Example:** `["sample_raw_0", "sample_raw_1"]` (for multi-input models)
- **Example:** `["bus_416x416_float.raw"]` (for single-input models)

**Example JSON configuration with input files:**
```json
{

"metadata": {
"configParameters": [
{
"fwname": "tizen-hal",
"fw_opened": 0,
"num_models": 1,
"model_files": ["inception-v3-99.nb"],
"input_file": ["pizza_3x299x299_uint8.raw"],
"input_configured": 0,
"output_configured": 0,
"custom_properties": "backend:vivante,json:inception-v3-99.json"
}

]

}

}

```

The raw binary files should contain tensor data in the model's expected format (e.g., float32, uint8) with the exact size matching the input tensor dimensions. If input files are not provided, the test will use zero-filled buffers.

## 3. Testing with GTest

The project includes a comprehensive testing framework using Google Test (GTest) to validate backend functionality.

### Test Structure

The test setup consists of the following components:

- **`test/main.cpp`**: Main test entry point that initializes GTest and manages the global properties structure.
- **`test/hal_backend_ml_vivante_test.cpp`**: Test cases for the Vivante backend.
- **`test/hal_backend_ml_snpe_test.cpp`**: Test cases for the SNPE backend.
- **`test/hal_backend_ml_dummy_passthrough_test.cpp`**: Test cases for the dummy passthrough backend.
- **`test/hal_backend_ml_test_util.cpp`**: Utility functions used by tests.
- **`test/hal_backend_ml_test_util.h`**: Header file for test utilities.
- **`test/hal_backend_ml_test_wrapper.h`**: Wrapper functions for backend APIs.

### Building Tests

Tests are built when the corresponding backend is enabled and BUILD_TESTS option is set to ON:

**For Vivante tests:**
```bash
cmake -DENABLE_VIVANTE=ON -DBUILD_TESTS=ON .
make hal-backend-ml-vivante-test
```

**For SNPE tests:**
```bash
cmake -DENABLE_SNPE=ON -DBUILD_TESTS=ON .
make hal-backend-ml-snpe-test
```

**For Dummy Passthrough tests:**
```bash
cmake -DENABLE_DUMMY=ON -DBUILD_TESTS=ON .
make hal-backend-ml-dummy-passthrough-test
```

The test executables are linked against:
- `libgtest.so` - Google Test framework
- `libgtest_main.so` - Provides main() function for tests
- Backend-specific library (`libhal-backend-ml-vivante.so`, `libhal-backend-ml-snpe.so`, or `libhal-backend-ml-dummy-passthrough.so`)
- `pthread` - Threading support

### Running Tests

The test executables require a JSON configuration file path as a command-line argument:

```bash
# Run Vivante backend tests
/hal/bin/ml-accelerator/hal-backend-ml-vivante-test /path/to/model_config.json

# Run SNPE backend tests
/hal/bin/ml-accelerator/hal-backend-ml-snpe-test /path/to/model_config.json

# Run Dummy Passthrough backend tests
/hal/bin/ml-accelerator/hal-backend-ml-dummy-passthrough-test /path/to/model_config.json
```

### Test Configuration

The JSON configuration file should contain:
- Model file paths
- Input tensor specifications
- Output tensor specifications
- Quantization parameters
- Any backend-specific custom properties

### Building Dependencies

To build with GTest support, ensure the following dependencies are installed:

**On Tizen systems:**

You should set `build_tests` as `1` in gbs to enable test:
```bash
gbs build {your_gbs_options} --define "build_tests 1"
```

The build system automatically includes GTest support when building test executables via the CMake configuration in [`test/CMakeLists.txt`](./test/CMakeLists.txt).

### Test Installations

When building with tests enabled, test binaries are installed to:
```
/hal/bin/ml-accelerator/
```

For example:
- Vivante test: `/hal/bin/ml-accelerator/hal-backend-ml-vivante-test`
- SNPE test: `/hal/bin/ml-accelerator/hal-backend-ml-snpe-test`
- Dummy Passthrough test: `/hal/bin/ml-accelerator/hal-backend-ml-dummy-passthrough-test`
33 changes: 32 additions & 1 deletion packaging/hal-backend-ml-accelerator.spec
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Group: Machine Learning/ML Framework
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz

%define _module_name hal-backend-ml-accelerator
%define _module_name_snpe hal-backend-ml-snpe
%define _module_name_vivante hal-backend-ml-vivante
%define _module_name_dummypassthrough hal-backend-ml-dummy-passthrough
BuildRequires: cmake
BuildRequires: pkgconfig(hal-rootstrap)

Expand All @@ -27,6 +31,9 @@ BuildRequires: pkgconfig(hal-rootstrap)

%endif # For DA

%if 0%{?build_tests}
BuildRequires: gtest-devel
%endif

%description
ML HAL backend drivers for various targets
Expand Down Expand Up @@ -57,6 +64,30 @@ Summary: hal-backend-ml-accelerator for snpe
%define enable_snpe -DENABLE_SNPE=ON
%endif

%if 0%{?build_tests}
%define _testdir %{_hal_bindir}/ml-accelerator/
%define enable_tests -DBUILD_TESTS=ON -DTEST_DIR=%{_testdir}

%package halbackendtest
Summary: Test Binary for Hal backend
Requires: %{name} = %{version}-%{release}
%description halbackendtest
Test Binary for hal-backend

%files halbackendtest
%manifest packaging/hal-backend-ml-accelerator.manifest
%if 0%{?dummy_support}
%{_testdir}%{_module_name_dummypassthrough}-test
%endif
%if 0%{?vivante_support}
%{_testdir}%{_module_name_vivante}-test
%endif
%if 0%{?snpe_support}
%{_testdir}%{_module_name_snpe}-test
%endif
%else
%define enable_tests -DBUILD_TESTS=OFF
%endif

%prep
%setup -q
Expand All @@ -68,8 +99,8 @@ Summary: hal-backend-ml-accelerator for snpe
%{?enable_dummy} \
%{?enable_vivante} \
%{?enable_snpe} \
%{?enable_tests} \
.

make %{?_smp_mflags}

%install
Expand Down
54 changes: 54 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Check if we're in TEST mode
IF(NOT DEFINED TEST_DIR)
SET(TEST_DIR "/hal/bin/ml-accelerator/")
ENDIF()

# Test installation directory
SET(TEST_INSTALL_DIR "${TEST_DIR}")

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/gtest)

SET(PROJECT_NAME_FULL "hal-backend-ml-accelerator")
SET(PROJECT_NAME_SNPE "hal-backend-ml-snpe")
SET(PROJECT_NAME_VIVANTE "hal-backend-ml-vivante")
SET(PROJECT_NAME_DUMMY "hal-backend-ml-dummy-passthrough")

# Common test sources
SET(COMMON_TEST_SRCS
main.cpp
hal_backend_ml_test_util.cc
)

# Vivante tests
IF(ENABLE_VIVANTE)
ADD_EXECUTABLE(${VIVANTE_LIBRARY_NAME}-test
${COMMON_TEST_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/hal_backend_ml_vivante_test.cc
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME_VIVANTE}-test libgtest.so libgtest_main.so -pthread)
TARGET_LINK_LIBRARIES(${VIVANTE_LIBRARY_NAME}-test ${VIVANTE_LIBRARY_NAME} ${TEST_PKGS_LDFLAGS} -lpthread)
INSTALL(TARGETS ${PROJECT_NAME_VIVANTE}-test RUNTIME DESTINATION ${TEST_INSTALL_DIR})
ENDIF()

# SNPE tests
IF(ENABLE_SNPE)
ADD_EXECUTABLE(${SNPE_LIBRARY_NAME}-test
${COMMON_TEST_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/hal_backend_ml_snpe_test.cc
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME_SNPE}-test libgtest.so libgtest_main.so -pthread)
TARGET_LINK_LIBRARIES(${PROJECT_NAME_SNPE}-test ${SNPE_LIBRARY_NAME} ${TEST_PKGS_LDFLAGS} -lpthread)
INSTALL(TARGETS ${PROJECT_NAME_SNPE}-test RUNTIME DESTINATION ${TEST_INSTALL_DIR})
ENDIF()

# Dummy Passthrough tests
IF(ENABLE_DUMMY)
ADD_EXECUTABLE(${PROJECT_NAME_DUMMY}-test
${COMMON_TEST_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/hal_backend_ml_dummy_passthrough_test.cc
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME_DUMMY}-test libgtest.so libgtest_main.so -pthread)
TARGET_LINK_LIBRARIES(${PROJECT_NAME_DUMMY}-test ${DUMMY_PASSTHROUGH_LIBRARY_NAME} ${TEST_PKGS_LDFLAGS} -lpthread)
INSTALL(TARGETS ${PROJECT_NAME_DUMMY}-test RUNTIME DESTINATION ${TEST_INSTALL_DIR})
ENDIF()
Loading
Loading