Skip to content

Commit 9df8ec8

Browse files
committed
[CLML][CODEGEN] CLML native codegen utility
This util generates native CLML code given a DNN model. It does import via tvmc, extracts clml_modules, get the json source and finally generates clml_models.cc that holds source for various sub graphs. cpp_clml tool has additional infrastructure to compile it as a standalong binary that runs these models. This PR adds symbol name to the generates json grpah. Also, extends const_loader interface to get constant params.
1 parent a75f110 commit 9df8ec8

File tree

11 files changed

+2387
-0
lines changed

11 files changed

+2387
-0
lines changed

apps/cpp_clml/CMakeLists.txt

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
cmake_minimum_required(VERSION 3.13)
2+
3+
project(clml_run VERSION 2.0)
4+
5+
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
6+
message( FATAL_ERROR "CMAKE_TOOLCHAIN_FILE Not set, forcing exit. Suggested value: {ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake." )
7+
endif(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
8+
9+
if(NOT DEFINED ANDROID_ABI)
10+
message( FATAL_ERROR "ANDROID_ABI Not set, forcing exit. Suggested value(s): arm64-v8a (64), armeabi-v7a (32)" )
11+
endif(NOT DEFINED ANDROID_ABI)
12+
13+
if(NOT DEFINED CLML_SDK)
14+
message( FATAL_ERROR "CLML_SDK Not set, forcing exit." )
15+
endif(NOT DEFINED CLML_SDK)
16+
17+
# CMake/Android variables
18+
set( ANDROID_STL c++_static CACHE STRING "Target Android STL") # default
19+
20+
# Source variables
21+
set( OPENCL_INCLUDE_DIRS ${CLML_SDK} CACHE PATH "filepath to OpenCL headers")
22+
set( ANDROID_SOURCE_TREE /path/to/android/au/ CACHE FILEPATH "optional filepath to the Android AU Tree, for building examples using ION Buffers") # tree required to build ION/DMA Buffer samples
23+
24+
#c++ 11 is required
25+
set(CMAKE_CXX_STANDARD 11)
26+
set(CMAKE_CXX_STANDARD_REQUIRED True)
27+
# set(CMAKE_CXX_FLAGS "-Wall -Werror")
28+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
29+
30+
#we do not want to pass -fno-exceptions
31+
if(${CMAKE_CXX_FLAGS} MATCHES "-fno-exceptions")
32+
string(REGEX REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
33+
endif()
34+
35+
#we do not want to pass -fno-rtti
36+
if(${CMAKE_CXX_FLAGS} MATCHES "-fno-rtti")
37+
string(REGEX REPLACE "-fno-rtti" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
38+
endif()
39+
40+
set(COMMON_SOURCE_FILES
41+
clml_models.cc
42+
clml_runner.cc
43+
clml_runner.h
44+
main.cc
45+
../../3rdparty/cnpy/cnpy.cpp
46+
)
47+
48+
include_directories(
49+
src
50+
${OPENCL_INCLUDE_DIRS}
51+
"../../3rdparty/dmlc-core/include"
52+
"../../3rdparty/cnpy/"
53+
)
54+
55+
add_executable(clml_run ${COMMON_SOURCE_FILES})
56+
target_link_options(clml_run PRIVATE -Wl,--unresolved-symbols=ignore-in-shared-libs)
57+
target_link_libraries(clml_run ${CLML_SDK}/lib64/libOpenCL.so z)

apps/cpp_clml/README.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<!--- Licensed to the Apache Software Foundation (ASF) under one -->
2+
<!--- or more contributor license agreements. See the NOTICE file -->
3+
<!--- distributed with this work for additional information -->
4+
<!--- regarding copyright ownership. The ASF licenses this file -->
5+
<!--- to you under the Apache License, Version 2.0 (the -->
6+
<!--- "License"); you may not use this file except in compliance -->
7+
<!--- with the License. You may obtain a copy of the License at -->
8+
9+
<!--- http://www.apache.org/licenses/LICENSE-2.0 -->
10+
11+
<!--- Unless required by applicable law or agreed to in writing, -->
12+
<!--- software distributed under the License is distributed on an -->
13+
<!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->
14+
<!--- KIND, either express or implied. See the License for the -->
15+
<!--- specific language governing permissions and limitations -->
16+
<!--- under the License. -->
17+
18+
# OpenCLML Debug Tool
19+
20+
Tool to generate OpenCLML source file given a model from any framework and compile it as a native application that runs on Android target.
21+
This tool helps to debug or triage OpenCLML offloaded sub graphs as a standalone application.
22+
23+
### Codegen
24+
25+
Models can be downloaded from well known frameworks like Tensorflow, PyTorch, TFLite, Onnx ..etc.
26+
Assuming ```resnet50.h5``` is a Keras ResNet50 model file, use the below command to generate a OpenCLML source for the model.
27+
28+
```bash
29+
python3 scripts/clml_codegen.py resnet50.h5
30+
```
31+
32+
Above command generates ```clml_models.cc``` and ```clml_params.npz```.
33+
```clml_models.cc``` contains cpp representation of all OpenCLML subgraphs offloaded by TVM compilation. This file will be used to build tool ```clml_run```.
34+
```clml_params.npz``` is a numpy dump of all params involved in all sub graphs of TVM module. This file to be copied to target.
35+
36+
### Build Tool
37+
38+
Copy the generated models source ```clml_models.cc``` under ```cpp_clml```.
39+
40+
Below commands will compile the tool ```clml_run``` from generated source and other static dependents.
41+
42+
```bash
43+
cmake -S . -B build_64 -D ANDROID_ABI=arm64-v8a -D CLML_SDK=<CLML SDK PATH> -D CMAKE_TOOLCHAIN_FILE=<ANDROID NDK PATH>/build/cmake/android.toolchain.cmake -D ANDROID_PLATFORM=latest
44+
cmake --build build_64
45+
```
46+
47+
### Run the tool
48+
49+
Copy ```clml_params.npz``` and ```clml_run``` to the target Android device
50+
51+
```bash
52+
Android:/data/local/tmp $ ./clml_run --dump-meta
53+
Input =
54+
Output =
55+
Params =
56+
DumpMeta = 1
57+
.....
58+
Subgraph Name: tvmgen_default_clml_main_1
59+
Input Count : 1
60+
Output Count : 1
61+
Input MetaInfo
62+
Input: tvmgen_default_clml_main_1_input_0
63+
Dtype : float32
64+
Shape : [1, 1, 1, 2048]
65+
Output MetaInfo
66+
Output: tvmgen_default_clml_main_1_layer_out_5
67+
Dtype : float32
68+
Shape : [1, 1000]
69+
70+
Subgraph Name: tvmgen_default_clml_main_0
71+
Input Count : 1
72+
Output Count : 1
73+
Input MetaInfo
74+
Input: tvmgen_default_clml_main_0_input_0
75+
Dtype : float32
76+
Shape : [1, 3, 230, 230]
77+
Output MetaInfo
78+
Output: tvmgen_default_clml_main_0_layer_out_406
79+
Dtype : float32
80+
Shape : [1, 2048, 1, 1]
81+
.....
82+
```
83+
84+
The meta information above indicates that the ResNet50 model is partitioned such a way that there exists two OpenCLML subgraphs.
85+
86+
Below command runs the models by setting the parameters from ```clml_params.npz```.
87+
88+
```bash
89+
Android:/data/local/tmp $ ./clml_run --params=./clml_params.npz
90+
Input =
91+
Output =
92+
Params = ./clml_params.npz
93+
DumpMeta = 1
94+
......
95+
CLMLRunner Loading Params:./clml_params.npz
96+
CLMLRunner Loading Params:./clml_params.npz
97+
CLMLRunner::Run :tvmgen_default_clml_main_1
98+
CLMLRunner::Run :tvmgen_default_clml_main_0
99+
......
100+
```
101+
102+
Below command can set the model inputs from ```input.npz``` and can output sub graph outputs to ```output.npz```.
103+
```input.npz``` should have numpy arrays for ```tvmgen_default_clml_main_1_input_0``` from sub graph ```tvmgen_default_clml_main_1``` and ```tvmgen_default_clml_main_0_input_0``` from sub graph ```tvmgen_default_clml_main_0```.
104+
105+
```bash
106+
Android:/data/local/tmp $ ./clml_run --params=./clml_params.npz --input=./input.npz --output=./output.npz <
107+
Input = ./input.npz
108+
Output = ./output.npz
109+
Params = ./clml_params.npz
110+
DumpMeta = 0
111+
Call Build Modules
112+
CLMLRunner Constructor: Input:./input.npz Output:./output.npz Params:./clml_params.npz
113+
CLML Target version:3
114+
CLMLRunner Loading Params:./clml_params.npz
115+
CLMLRunner Loading Inputs:./input.npz
116+
Set Input For:tvmgen_default_clml_main_1_input_0
117+
118+
CLMLRunner Constructor: Input:./input.npz Output:./output.npz Params:./clml_params.npz
119+
CLML Target version:3
120+
CLMLRunner Loading Params:./clml_params.npz
121+
CLMLRunner Loading Inputs:./input.npz
122+
Set Input For:tvmgen_default_clml_main_0_input_0
123+
124+
Loop Through the Modules
125+
CLMLRunner::Run :tvmgen_default_clml_main_1
126+
Saving Output:tvmgen_default_clml_main_1_layer_out_5
127+
CLMLRunner::Run :tvmgen_default_clml_main_0
128+
Saving Output:tvmgen_default_clml_main_0_layer_out_406
129+
......
130+
```
131+
132+
The generated output file ```output.npz``` contains all the output from all sub modules.
133+
In this case it contains ```tvmgen_default_clml_main_1_layer_out_5``` for sub graph ```tvmgen_default_clml_main_1``` and ```tvmgen_default_clml_main_0_layer_out_406``` for sub graph ```tvmgen_default_clml_main_0``` as shown below.
134+
135+
136+
```bash
137+
Android:/data/local/tmp $ unzip -l output.npz
138+
Archive: output.npz
139+
Length Date Time Name
140+
--------- ---------- ----- ----
141+
4080 1980-00-00 00:00 tvmgen_default_clml_main_1_layer_out_5.npy
142+
8272 1980-00-00 00:00 tvmgen_default_clml_main_0_layer_out_406.npy
143+
--------- -------
144+
12352 2 files
145+
```

0 commit comments

Comments
 (0)