Skip to content

Commit 54b0238

Browse files
authored
MV2 cpp and python example (#13)
1 parent 5cf3a1f commit 54b0238

File tree

11 files changed

+191
-0
lines changed

11 files changed

+191
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@
1010
xcuserdata/
1111
.swiftpm/
1212
*.xcworkspace/
13+
14+
# MV2
15+
mv2/cpp/build
16+

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[submodule "mv2/cpp/executorch"]
2+
path = mv2/cpp/executorch
3+
url = https://github.com/pytorch/executorch.git
4+
branch = release/0.6

mv2/cpp/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
2+
project(executorch_mv2_demo CXX)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
7+
# Set options for executorch build.
8+
option(EXECUTORCH_ENABLE_LOGGING "" ON)
9+
option(EXECUTORCH_BUILD_EXTENSION_DATA_LOADER "" ON)
10+
option(EXECUTORCH_BUILD_EXTENSION_MODULE "" ON)
11+
option(EXECUTORCH_BUILD_EXTENSION_TENSOR "" ON)
12+
option(EXECUTORCH_BUILD_KERNELS_OPTIMIZED "" ON)
13+
option(EXECUTORCH_BUILD_XNNPACK "" ON)
14+
15+
# Add ExecutorTorch subdirectory
16+
add_subdirectory("executorch")
17+
18+
set(DEMO_SOURCES main.cpp)
19+
20+
# Create executable
21+
add_executable(executorch_mv2_demo_app ${DEMO_SOURCES})
22+
23+
# Include directories
24+
target_include_directories(executorch_mv2_demo_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
25+
26+
# Link libraries
27+
target_link_libraries(
28+
executorch_mv2_demo_app
29+
PRIVATE executorch
30+
extension_module_static
31+
extension_tensor
32+
optimized_native_cpu_ops_lib
33+
xnnpack_backend
34+
)
35+
36+
# Set output directory
37+
set_target_properties(executorch_mv2_demo_app
38+
PROPERTIES
39+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
40+
)

mv2/cpp/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# ExecutorTorch MobileNetV2 Demo C++ Application
2+
3+
This is a simple C++ demo application that uses the ExecutorTorch library for MobileNetV2 model inference.
4+
5+
## Build instructions
6+
7+
0. Export the model. See [mv2/python/README.md](../python/README.md)
8+
9+
1. The ExecuTorch repository is already configured as a git submodule at `~/executorch-examples/cpp/executorch/`. To initialize it:
10+
```bash
11+
cd ~/executorch-examples/
12+
git submodule sync
13+
git submodule update --init --recursive
14+
```
15+
16+
2. Install dev requirements for ExecuTorch
17+
18+
```bash
19+
cd ~/executorch-examples/mv2/cpp/executorch
20+
pip install -r requirements-dev.txt
21+
```
22+
23+
3. Build the project:
24+
```bash
25+
cd ~/executorch-examples/mv2/cpp
26+
chmod +x build.sh
27+
./build.sh
28+
```
29+
30+
4. Run the demo application:
31+
```bash
32+
./build/bin/executorch_mv2_demo_app
33+
```
34+
35+
## Dependencies
36+
37+
- CMake 3.18 or higher
38+
- C++17 compatible compiler
39+
- ExecutorTorch library (release/0.6)
40+
41+
## Notes
42+
43+
- Make sure you have the correct model file (`.pte`) compatible with ExecutorTorch.
44+
- This demo currently initializes the input tensor with random data. In a real application, you would replace this with actual input data.

mv2/cpp/build.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Create build directory if it doesn't exist
5+
mkdir -p build
6+
cd build
7+
8+
# Configure CMake
9+
cmake -DCMAKE_BUILD_TYPE=Release ..
10+
11+
# Build the project
12+
cmake --build . -j$(nproc)
13+
14+
echo "Build complete! Executable located at: ./bin/executorch_mv2_demo_app"

mv2/cpp/executorch

Submodule executorch added at 9820413

mv2/cpp/main.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <executorch/extension/module/module.h>
2+
#include <executorch/extension/tensor/tensor.h>
3+
#include <iostream>
4+
5+
using namespace ::executorch::extension;
6+
7+
int main(int argc, char* argv[]) {
8+
// Load the model.
9+
Module module("../python/model_mv2_xnnpack.pte");
10+
11+
// Create an input tensor.
12+
float input[1 * 3 * 224 * 224];
13+
auto tensor = from_blob(input, {1, 3, 224, 224});
14+
15+
// Perform an inference.
16+
const auto result = module.forward(tensor);
17+
18+
if (result.ok()) {
19+
// Retrieve the output data.
20+
const auto output = result->at(0).toTensor().const_data_ptr<float>();
21+
std::cout << "Success" << std::endl;
22+
}
23+
}

mv2/python/README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
### Virtual environment setup
2+
Create and activate a Python virtual environment:
3+
```bash
4+
python3 -m venv .venv && source .venv/bin/activate && pip install --upgrade pip
5+
```
6+
Or alternatively, [install conda on your machine](https://conda.io/projects/conda/en/latest/user-guide/install/index.html)
7+
```bash
8+
conda create -yn executorch-examples-mv2 python=3.10.0 && conda activate executorch-examples-mv2
9+
```
10+
11+
### Install dependencies
12+
```
13+
pip install -r requirements.txt
14+
```
15+
16+
### Export a model
17+
```
18+
python export.py
19+
```
20+
21+
### Run model via pybind
22+
```
23+
python run.py
24+
```

mv2/python/export.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import torch
2+
import torchvision.models as models
3+
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
4+
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
5+
from executorch.exir import to_edge_transform_and_lower
6+
7+
model = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
8+
sample_inputs = (torch.randn(1, 3, 224, 224), )
9+
10+
et_program = to_edge_transform_and_lower(
11+
torch.export.export(model, sample_inputs),
12+
partitioner=[XnnpackPartitioner()]
13+
).to_executorch()
14+
15+
with open("model_mv2_xnnpack.pte", "wb") as f:
16+
f.write(et_program.buffer)

mv2/python/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
executorch==0.6.0

mv2/python/run.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import torch
2+
from executorch.runtime import Runtime
3+
from typing import List
4+
5+
runtime = Runtime.get()
6+
7+
input_tensor: torch.Tensor = torch.randn(1, 3, 224, 224)
8+
program = runtime.load_program("model_mv2_xnnpack.pte")
9+
method = program.load_method("forward")
10+
output: List[torch.Tensor] = method.execute([input_tensor])
11+
print("Run succesfully via executorch")
12+
13+
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
14+
import torchvision.models as models
15+
16+
eager_reference_model = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
17+
eager_reference_output = eager_reference_model(input_tensor)
18+
19+
print("Comparing against original PyTorch module")
20+
print(torch.allclose(output[0], eager_reference_output, rtol=1e-3, atol=1e-5))

0 commit comments

Comments
 (0)