onnx-go icon indicating copy to clipboard operation
onnx-go copied to clipboard

Make a onnx-go compatible with tiny Go

Open owulveryck opened this issue 5 years ago • 11 comments

This issue will track the work done to make the package compatible with tiny-go.

The computation backend is, by now outside of this experiment.

Once the package works with tiny go, we may write a very simple backend to use it for example in webassembly.

owulveryck avatar Aug 02 '19 19:08 owulveryck

With this piece of code :

package main

import (
        "fmt"
        "github.com/owulveryck/onnx-go/backend/x/gorgonnx"
)

func main() {
        backend := gorgonnx.NewGraph()
        fmt.Println(backend)
}

We have the following error :

/usr/local/tinygo/bin/tinygo run main.go
# context
../../../usr/local/go/src/context/context.go:471:26: reflect.TypeOf(key).Comparable undefined (type reflect.Type has no field or method Comparable)

I will try to stub the method Comparable in tinygo.

blackrez avatar Aug 02 '19 20:08 blackrez

Just stub the method and don't work.

 /usr/local/tinygo/bin/tinygo run main.go                                                   
# database/sql/driver
../../../usr/local/go/src/database/sql/driver/types.go:227:20: rv.Type().Elem().Implements undefined (type reflect.Type has no field or method Implements)

Then I remove /usr/local/go/src/database/sql/driver/driver.go and /usr/local/go/src/database/sql/driver/types.go and...I have got a lot of issue with reflect and json.

# encoding/json
../../../usr/local/go/src/encoding/json/encode.go:346:23: Map not declared by package sync
../../../usr/local/go/src/encoding/json/encode.go:1264:21: Map not declared by package sync
../../../usr/local/go/src/encoding/json/encode.go:1101:24: sf.PkgPath undefined (type reflect.StructField has no field or method PkgPath)
../../../usr/local/go/src/encoding/json/encode.go:1102:11: sf.Anonymous undefined (type reflect.StructField has no field or method Anonymous)
../../../usr/local/go/src/encoding/json/encode.go:1117:15: sf.Tag undefined (type reflect.StructField has no field or method Tag)
../../../usr/local/go/src/encoding/json/encode.go:1130:11: ft.Name undefined (type reflect.Type has no field or method Name)
../../../usr/local/go/src/encoding/json/encode.go:1149:26: sf.Anonymous undefined (type reflect.StructField has no field or method Anonymous)
../../../usr/local/go/src/encoding/json/encode.go:1187:41: ft.Name undefined (type reflect.Type has no field or method Name)
../../../usr/local/go/src/encoding/json/encode.go:767:16: PtrTo not declared by package reflect
../../../usr/local/go/src/encoding/json/encode.go:708:11: t.Key undefined (type reflect.Type has no field or method Key)
../../../usr/local/go/src/encoding/json/encode.go:713:9: t.Key undefined (type reflect.Type has no field or method Key)
../../../usr/local/go/src/encoding/json/encode.go:392:7: t.Implements undefined (type reflect.Type has no field or method Implements)
../../../usr/local/go/src/encoding/json/encode.go:396:14: PtrTo not declared by package reflect
../../../usr/local/go/src/encoding/json/encode.go:401:7: t.Implements undefined (type reflect.Type has no field or method Implements)
../../../usr/local/go/src/encoding/json/encode.go:405:14: PtrTo not declared by package reflect
../../../usr/local/go/src/encoding/json/encode.go:365:11: WaitGroup not declared by package sync
../../../usr/local/go/src/encoding/json/decode.go:916:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:945:6: v.SetBytes undefined (type reflect.Value has no field or method SetBytes)
../../../usr/local/go/src/encoding/json/decode.go:949:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:983:9: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:991:23: v.OverflowInt undefined (type reflect.Value has no field or method OverflowInt)
../../../usr/local/go/src/encoding/json/decode.go:999:23: v.OverflowUint undefined (type reflect.Value has no field or method OverflowUint)
../../../usr/local/go/src/encoding/json/decode.go:1007:23: v.OverflowFloat undefined (type reflect.Value has no field or method OverflowFloat)
../../../usr/local/go/src/encoding/json/decode.go:622:40: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:638:12: t.Key undefined (type reflect.Type has no field or method Key)
../../../usr/local/go/src/encoding/json/decode.go:643:16: PtrTo not declared by package reflect
../../../usr/local/go/src/encoding/json/decode.go:643:24: t.Key undefined (type reflect.Type has no field or method Key)
../../../usr/local/go/src/encoding/json/decode.go:650:18: MakeMap not declared by package reflect
../../../usr/local/go/src/encoding/json/decode.go:771:12: t.Key undefined (type reflect.Type has no field or method Key)
../../../usr/local/go/src/encoding/json/decode.go:775:31: reflect.ValueOf(key).Convert undefined (type reflect.Value has no field or method Convert)
../../../usr/local/go/src/encoding/json/decode.go:776:17: PtrTo not declared by package reflect
../../../usr/local/go/src/encoding/json/decode.go:787:40: reflect.Zero(kt).OverflowInt undefined (type reflect.Value has no field or method OverflowInt)
../../../usr/local/go/src/encoding/json/decode.go:791:30: reflect.ValueOf(n).Convert undefined (type reflect.Value has no field or method Convert)
../../../usr/local/go/src/encoding/json/decode.go:795:40: reflect.Zero(kt).OverflowUint undefined (type reflect.Value has no field or method OverflowUint)
../../../usr/local/go/src/encoding/json/decode.go:799:30: reflect.ValueOf(n).Convert undefined (type reflect.Value has no field or method Convert)
../../../usr/local/go/src/encoding/json/decode.go:805:7: v.SetMapIndex undefined (type reflect.Value has no field or method SetMapIndex)
../../../usr/local/go/src/encoding/json/decode.go:517:8: v.NumMethod undefined (type reflect.Value has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:550:13: Copy not declared by package reflect
../../../usr/local/go/src/encoding/json/decode.go:554:7: v.SetLen undefined (type reflect.Value has no field or method SetLen)
../../../usr/local/go/src/encoding/json/decode.go:591:6: v.SetLen undefined (type reflect.Value has no field or method SetLen)
../../../usr/local/go/src/encoding/json/decode.go:450:41: v.Type().Name undefined (type reflect.Type has no field or method Name)
../../../usr/local/go/src/encoding/json/decode.go:476:15: v.Type().NumMethod undefined (type reflect.Type has no field or method NumMethod)
../../../usr/local/go/src/encoding/json/decode.go:306:30: cannot convert nil (untyped nil value) to reflect.Type
../../../usr/local/go/src/encoding/json/decode.go:309:39: d.errorContext.Struct.Name undefined (type reflect.Type has no field or method Name)
../../../usr/local/go/src/encoding/json/decode.go:291:26: cannot convert nil (untyped nil value) to reflect.Type
../../../usr/local/go/src/encoding/json/decode.go:159:15: cannot convert nil (untyped nil value) to reflect.Type

blackrez avatar Aug 02 '19 20:08 blackrez

Also there is a dependencies on uuid (which is linked to sql/drivers) and tinygo is not compatible to this module right now.

blackrez avatar Aug 02 '19 21:08 blackrez

With gorgonia (based on the example) :

# github.com/pkg/errors
../go/src/github.com/pkg/errors/stack.go:166:15: Callers not declared by package runtime
../go/src/github.com/pkg/errors/stack.go:39:16: fn.FileLine undefined (type *runtime.Func has no field or method FileLine)
../go/src/github.com/pkg/errors/stack.go:28:16: fn.FileLine undefined (type *runtime.Func has no field or method FileLine)

Will stub this method tomorrow.

blackrez avatar Aug 02 '19 21:08 blackrez

UUID is linked with sql/driver?

I think we can get rid of this. We need to find a way to generate names and avoid conflicts in our namespace.

owulveryck avatar Aug 03 '19 04:08 owulveryck

Just found this issue from Twitter!

Reflect support in TinyGo is still very minimal and doesn't support the JSON package yet. I hope that I can improve reflect support in the coming weeks so it becomes usable for serialization/deserialization.

aykevl avatar Aug 03 '19 15:08 aykevl

UUID is linked with sql/driver? I think we can get rid of this. We need to find a way to generate names and avoid conflicts in our namespace.

Yes* (and in general uuid is linked to sql^^), what are the restrictions of generations ?

*:https://github.com/google/uuid/blob/master/sql.go#L8

blackrez avatar Aug 03 '19 18:08 blackrez

PR #103 removes the need for the uuid package. (good) side effect: the generated binaries have lost a couple of megabytes :)

owulveryck avatar Aug 03 '19 20:08 owulveryck

What would be the primary use case, WebAssembly or embedded devices?

For embedded devices, this may be of interest: https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/new-neural-network-kernels-boost-efficiency-in-microcontrollers-by-5x CGo is partially supported in TinyGo, most notably the #cgo lines are not yet implemented. However, there is no overhead besides a function call in TinyGo (and I hope to add support for LTO across the CGo barrier in the future) so TinyGo may be of interest in general for CGo heavy applications.

aykevl avatar Aug 06 '19 17:08 aykevl

Webassembly is a target. It will allow the developers to build new kind of "web applications" involving neural networks easily. For example, let's consider a website that would do sentiment analysis on a picture. With the neural net coded into the webpage via WASM, no need to upload the photo anywhere (in term of ethics and compliance this would be, IMHO, a step forward).

But, TBH, that would also be very interesting to be able to run a neural net smoothly on an embedded device. This would give the possibility for the developer to add "smart capacities" to their objects.

Thank you for the link, I did not know about that; From what I see, this could be something to implement on the same level as the Cuda binding directly into the Gorgonia engine. I will have a closer look.

I hope this answers your questions, otherwise, do not hesitate to reply here (or to reach me directly, I am @owulveryck on gopher slack)

owulveryck avatar Aug 07 '19 06:08 owulveryck

Might be worth trying again. See also https://github.com/tinygo-org/tinygo/issues/447

dankegel avatar Jan 11 '22 05:01 dankegel