Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9e4f7e9
TVM runtime for golang v0.1
srkreddy1238 Jul 18, 2018
b4e2787
without swig but use C and unsafe directly.
srkreddy1238 Jul 28, 2018
fe11106
TVMFunction, TVMArray, TVMModule wrappers. TVMValue enhancements to a…
srkreddy1238 Aug 1, 2018
c9af1b9
some fixes.
srkreddy1238 Aug 2, 2018
8391c0b
Some API enhamcements with slices.
srkreddy1238 Aug 2, 2018
135d912
TVMValue interface with generic TVMTypes.
srkreddy1238 Aug 2, 2018
80187a5
Alignment and formatting.
srkreddy1238 Aug 2, 2018
3edc8cd
Review comments.
srkreddy1238 Aug 5, 2018
6ab54d3
Enhancements : Finalizers and variadic functions to keep the API as c…
srkreddy1238 Aug 8, 2018
feaed9a
cpp lint and documentation.
srkreddy1238 Aug 9, 2018
3595e62
Return value handling standardised. TVMType hidden, use dtype string …
srkreddy1238 Aug 10, 2018
a21e40a
Use TVMCopy for Set and Get
srkreddy1238 Aug 12, 2018
1d12759
gotvm package organized interface wise.
srkreddy1238 Aug 14, 2018
9a551bb
Review comments.
srkreddy1238 Aug 14, 2018
000167d
TVMValue wrappers.
srkreddy1238 Aug 16, 2018
2ac9928
Remove `TVM` prefix as we already have `gotvm` pkg prefix inplace.
srkreddy1238 Aug 16, 2018
357890a
Packed function system for golang.
srkreddy1238 Aug 21, 2018
46fba37
Go test cases
srkreddy1238 Aug 22, 2018
a14d5c3
GetGlobalFunction to return TVMFunction instead of closure.
srkreddy1238 Aug 22, 2018
3193bc3
Packed function to follow signature as ```(args ...Value) (interface{…
srkreddy1238 Aug 22, 2018
fe511bb
Sample applications to demonstrate function closures arguments and re…
srkreddy1238 Aug 22, 2018
76969a8
Source and test cases organization
srkreddy1238 Aug 22, 2018
15009e3
Testcases
srkreddy1238 Aug 23, 2018
41062b5
More testcases
srkreddy1238 Aug 24, 2018
7cc32c8
Structural changes as per review comments.
srkreddy1238 Aug 27, 2018
6c05b70
* Value internal structure aware of dtype.
srkreddy1238 Aug 30, 2018
9468d0d
* GoTVMVersion ; we don't need this extra version info.
srkreddy1238 Sep 20, 2018
8b67811
* tvm.cc -> tvm_runtime_pack.cc
srkreddy1238 Sep 20, 2018
cd601c0
* Empty lines cleanup rebase to latest base.
srkreddy1238 Sep 20, 2018
45641cb
* Unnecessary wrapper cleanup.
srkreddy1238 Sep 21, 2018
441ebed
* CI build/integration changes.
srkreddy1238 Sep 22, 2018
d882aea
* Wrappers minimizations (Part 1)
srkreddy1238 Sep 25, 2018
0efd74e
* Wrappers cleanup (Part 2)
srkreddy1238 Sep 25, 2018
e107788
* Review comments.
srkreddy1238 Oct 2, 2018
ab9a905
* Fix minimum compiler version.
srkreddy1238 Oct 6, 2018
a2920b5
* Review comments.
srkreddy1238 Nov 29, 2018
388ae17
* Review comments.
srkreddy1238 Dec 1, 2018
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
64 changes: 64 additions & 0 deletions golang/Makefile
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); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you set CGO_CXXFLAGS here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

(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
107 changes: 107 additions & 0 deletions golang/README.md
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have pre-built images with go support? If not, I think it would be nice to mention that users may include docker/install/ubuntu_install_golang.sh rule in their Dockerfiles. I tested that way, it worked, but I had to export PATH="/usr/lib/go-1.10/bin:$PATH". Could you please mention that too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Demo CPU docker should support golang if it is build from Dockerfile.ci_cpu. cc @tqchen can confirm on this.

Anyway I added a section Docker to golang README with above info.


### 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"```
```
17 changes: 17 additions & 0 deletions golang/sample/Makefile
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
171 changes: 171 additions & 0 deletions golang/sample/complex.go
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])
}
Loading