forked from apache/tvm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RUNTIME][GOLANG] TVM runtime for golang v0.1 (apache#1470)
- Loading branch information
1 parent
069aa38
commit 1cb602f
Showing
31 changed files
with
3,872 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
.PHONY: clean all | ||
|
||
TVM_BASE = $(CURDIR)/../ | ||
TARGET = gotvm | ||
LIBS = -lm -ldl | ||
NATIVE_SRC = tvm_runtime_pack.cc | ||
|
||
GOPATH=$(CURDIR)/gopath | ||
GOPATHDIR=${GOPATH}/src/${TARGET}/ | ||
CGO_CPPFLAGS="-I. -I${TVM_BASE}/ -I${TVM_BASE}/3rdparty/dmlc-core/include -I${TVM_BASE}/include -I${TVM_BASE}/3rdparty/dlpack/include/" | ||
CGO_CXXFLAGS="-std=c++11" | ||
CGO_CFLAGS="-I${TVM_BASE}" | ||
CGO_LDFLAGS="-ldl -lm" | ||
|
||
all: | ||
@mkdir gopath 2>/dev/null || true | ||
@mkdir gopath/src 2>/dev/null || true | ||
@mkdir gopath/src/$(TARGET) 2>/dev/null || true | ||
@cp src/$(TARGET).cc gopath/src/$(TARGET) | ||
@cp src/$(TARGET).h gopath/src/$(TARGET) | ||
@cp src/$(NATIVE_SRC) gopath/src/$(TARGET) | ||
@cp src/*.go gopath/src/$(TARGET) | ||
@export GOPATH=$(GOPATH); \ | ||
export CGO_CPPFLAGS=$(CGO_CPPFLAGS); \ | ||
export CGO_CXXFLAGS=$(CGO_CXXFLAGS); \ | ||
export CGO_CFLAGS=$(CGO_CFLAGS); \ | ||
export CGO_LDFLAGS=$(CGO_LDFLAGS); \ | ||
(cd $(GOPATHDIR) && go clean -cache \ | ||
&& golint && go build -o $(TARGET).a \ | ||
&& go install) | ||
@find . -name gotvm.a | ||
@#mkdir gopath/doc 2>/dev/null || true | ||
@#godoc -html -goroot gopath/ gotvm | grep -v "for documentation on the gotvm command" > gopath/doc/gotvm.html | ||
@#echo "Run 'godoc -http=:6060 -goroot=./gopath' for documentation" | ||
|
||
samples: all | ||
cp gopath/pkg/linux_amd64/gotvm.a sample/ -rfa | ||
make -C sample | ||
|
||
tests: all | ||
@(cd sample; python3 deploy.py) | ||
@export GOPATH=$(GOPATH); \ | ||
export CGO_CPPFLAGS=$(CGO_CPPFLAGS); \ | ||
export CGO_CXXFLAGS=$(CGO_CXXFLAGS); \ | ||
export CGO_CFLAGS=$(CGO_CFLAGS); \ | ||
export CGO_LDFLAGS=$(CGO_LDFLAGS); \ | ||
(cd $(GOPATHDIR) \ | ||
&& cp ../../../sample/deploy.so . \ | ||
&& go test -v) | ||
|
||
clean: | ||
@if [ -d $(GOPATHDIR) ] ; then \ | ||
export GOPATH=$(GOPATH); \ | ||
export CGO_CPPFLAGS=$(CGO_CPPFLAGS); \ | ||
export CGO_CFLAGS=$(CGO_CFLAGS); \ | ||
export CGO_LDFLAGS=$(CGO_LDFLAGS); \ | ||
(cd $(GOPATHDIR) && go clean -cache); fi | ||
@rm -rf gopath | ||
@make -C sample clean | ||
|
||
lint: | ||
@(cd src; golint) | ||
@python3 ${TVM_BASE}/dmlc-core/scripts/lint.py gotvm cpp src/*.cc | ||
@python3 ${TVM_BASE}/dmlc-core/scripts/lint.py gotvm cpp src/*.h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# gotvm - Golang Frontend for TVM Runtime | ||
|
||
This folder contain golang interface for TVM runtime. It brings TVM runtime to Golang. | ||
|
||
- It enable c runtime api of tvm exposed to golang. | ||
- It enables module loading (lib, graph and params) and inference operations. | ||
|
||
## Installation | ||
|
||
### Requirements | ||
|
||
- go compiler (https://golang.org/) version 0.10 or above. | ||
|
||
### Modules | ||
|
||
- src | ||
Module that generates golang package corresponding to the c runtime api exposed from tvm source tree. | ||
This process build golang package _gotvm.a_ | ||
|
||
- samples | ||
Sample golang reference application to inference through gotvm package. | ||
|
||
### Build | ||
|
||
Once the Requirements are installed | ||
|
||
To build _gotvm_ package | ||
|
||
```bash | ||
make | ||
``` | ||
|
||
To build and run internal tests | ||
|
||
```bash | ||
make tests | ||
``` | ||
|
||
To build sample apps. | ||
|
||
```bash | ||
make samples | ||
``` | ||
|
||
## Run | ||
|
||
To Demonstrates sample TVM module compilation using python and deploy via golang. | ||
```bash | ||
./simple | ||
``` | ||
|
||
To deploy a realtime module with lib, graph and param. | ||
```bash | ||
./complex | ||
``` | ||
|
||
To demonstrate go function closure conversion to packed function handle. | ||
|
||
```bash | ||
./pack_func_convert | ||
``` | ||
|
||
To demonstrate a packed function handle given as an argument. | ||
|
||
```bash | ||
pack_func_handle_arg | ||
``` | ||
|
||
To register go function with runtime as a global function. | ||
|
||
```bash | ||
pack_func_register | ||
``` | ||
|
||
To demonstrate function closure passed as argument to a function call. | ||
|
||
```bash | ||
./pack_func_closure_arg | ||
``` | ||
|
||
To demonstrate function closure returned from a packed function. | ||
|
||
```bash | ||
./pack_func_closure_return | ||
``` | ||
|
||
## Documentation | ||
gotvm.go is documented with sufficient information about gotvm package. | ||
A html version documentation can be accessed by running below command after building runtime. | ||
|
||
```bash | ||
godoc -http=:6060 -goroot=./gopath | ||
``` | ||
After above command try http://127.0.0.1:6060 from any browser. | ||
|
||
Also please refer to the sample applications under sample folder. | ||
|
||
## Docker | ||
Docker setup may need below additions for dependencies and environment preparation. | ||
|
||
Please refer ```docker/install/ubuntu_install_golang.sh``` for the packages dependencies. | ||
|
||
go compiler 1.10 on ubuntu doesn't install on standard path, hence an explicit export may be needed as shown below. | ||
|
||
```bash | ||
export PATH="/usr/lib/go-1.10/bin:$PATH"``` | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.PHONY: clean all | ||
|
||
SOURCES=$(wildcard *.go) | ||
EXECUTABLE=$(patsubst %.go, %, $(SOURCES)) | ||
|
||
all: $(EXECUTABLE) | ||
@golint | ||
@python3 deploy.py | ||
|
||
%: %.o | ||
@go tool link -linkmode external -extld "g++" -extldflags "-ldl" -o $@ $< | ||
|
||
%.o: %.go | ||
@go tool compile -pack -o $@ $< | ||
|
||
clean: | ||
@rm -f $(EXECUTABLE) *.so *.o *.a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
/*! | ||
* Copyright (c) 2018 by Contributors | ||
* \brief Sample golang application deployment over tvm. | ||
* \file complex.go | ||
*/ | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"math/rand" | ||
"./gotvm" | ||
"runtime" | ||
) | ||
|
||
// NNVM compiled model paths. | ||
const ( | ||
modLib = "./mobilenet.so" | ||
modJSON = "./mobilenet.json" | ||
modParams = "./mobilenet.params" | ||
) | ||
|
||
// main | ||
func main() { | ||
defer runtime.GC() | ||
// Welcome | ||
fmt.Printf("TVM Version : v%v\n", gotvm.TVMVersion) | ||
fmt.Printf("DLPACK Version: v%v\n\n", gotvm.DLPackVersion) | ||
|
||
// Query global functions available | ||
funcNames, err := gotvm.FuncListGlobalNames() | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Global Functions:%v\n", funcNames) | ||
|
||
// Import tvm module (so) | ||
modp, err := gotvm.LoadModuleFromFile(modLib) | ||
if err != nil { | ||
fmt.Print(err) | ||
fmt.Printf("Please copy tvm compiled modules here and update the sample.go accordingly.\n") | ||
fmt.Printf("You may need to update modLib, modJSON, modParams, tshapeIn, tshapeOut\n") | ||
return | ||
} | ||
fmt.Printf("Module Imported:%p\n", modp) | ||
bytes, err := ioutil.ReadFile(modJSON) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
jsonStr := string(bytes) | ||
|
||
// Load module on tvm runtime - call tvm.graph_runtime.create | ||
funp, err := gotvm.GetGlobalFunction("tvm.graph_runtime.create") | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Calling tvm.graph_runtime.create\n") | ||
// Call function | ||
graphrt, err := funp.Invoke(jsonStr, modp, (int64)(gotvm.KDLCPU), (int64)(0)) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
graphmod := graphrt.AsModule() | ||
fmt.Printf("Graph runtime Created\n") | ||
|
||
// Array allocation attributes | ||
tshapeIn := []int64{1, 224, 224, 3} | ||
tshapeOut := []int64{1, 1001} | ||
|
||
// Allocate input Array | ||
inX, err := gotvm.Empty(tshapeIn, "float32", gotvm.CPU(0)) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
|
||
// Allocate output Array | ||
out, err := gotvm.Empty(tshapeOut) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Input and Output Arrays allocated\n") | ||
|
||
// Get module function from graph runtime : load_params | ||
// Read params | ||
bytes, err = ioutil.ReadFile(modParams) | ||
if err != nil { | ||
fmt.Print(err) | ||
} | ||
|
||
// Load Params | ||
funp, err = graphmod.GetFunction("load_params") | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Func load_params:%p\n", funp) | ||
|
||
// Call function | ||
_, err = funp.Invoke(bytes) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Module params loaded\n") | ||
|
||
// Set some data in input Array | ||
inSlice := make([]float32, (244 * 244 * 3)) | ||
rand.Seed(10) | ||
rand.Shuffle(len(inSlice), func(i, j int) {inSlice[i], | ||
inSlice[j] = rand.Float32(), | ||
rand.Float32() }) | ||
inX.CopyFrom(inSlice) | ||
|
||
// Set Input | ||
funp, err = graphmod.GetFunction("set_input") | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
|
||
// Call function | ||
_, err = funp.Invoke("input", inX) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
|
||
fmt.Printf("Module input is set\n") | ||
|
||
// Run | ||
funp, err = graphmod.GetFunction("run") | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
|
||
// Call function | ||
_, err = funp.Invoke() | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Module Executed \n") | ||
|
||
// Call runtime function get_output | ||
funp, err = graphmod.GetFunction("get_output") | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
|
||
// Call function | ||
_, err = funp.Invoke(int64(0), out) | ||
if err != nil { | ||
fmt.Print(err) | ||
return | ||
} | ||
fmt.Printf("Got Module Output \n") | ||
|
||
// Print results | ||
outIntf, _ := out.AsSlice() | ||
outSlice := outIntf.([]float32) | ||
fmt.Printf("Result:%v\n", outSlice[:10]) | ||
} |
Oops, something went wrong.