Skip to content

Commit cf1487b

Browse files
committed
refactor(examples): Add test and update dependencies
Add test for examples and update dependencies: - Add test that runs examples and checks their output - Simplify makefile for building examples and use shell pkg-config paths - Fix tf print identation by adding spaces instead of zero-valued runes - Replace archived `github.com/nfnt/resize` with `golang.org/x/image/draw` in torch example - Remove `exec_genop` example since the `vaccel_arg_list` API is deprecated and does not work correctly with `genop` anymore - Fix linter errors for current Go PR: #22 Signed-off-by: Kostis Papazafeiropoulos <papazof@gmail.com> Reviewed-by: Anastassios Nanos <ananos@nubificus.co.uk> Approved-by: Anastassios Nanos <ananos@nubificus.co.uk>
1 parent 88db8d7 commit cf1487b

11 files changed

Lines changed: 177 additions & 157 deletions

File tree

.golangci.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ linters:
1717
paths:
1818
- third_party$
1919
- builtin$
20-
- examples$
20+
rules:
21+
# Skip path traversal check for examples - arbitrary files may be opened
22+
- path-except: 'examples/*/*.go'
23+
linters:
24+
- gosec
25+
text: "G703"
2126
issues:
2227
uniq-by-line: false
2328
formatters:
@@ -29,4 +34,3 @@ formatters:
2934
paths:
3035
- third_party$
3136
- builtin$
32-
- examples$

Makefile

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,18 @@
1-
.PHONY: all
2-
all: noop classify exec nonser tf tflite exec_genop torch
1+
BIN_DIR = bin
32

4-
prepare:
5-
@go mod tidy
6-
@mkdir -p bin/
7-
8-
noop: prepare
9-
go build -o bin/noop examples/noop/main.go
10-
11-
classify: prepare
12-
go build -o bin/classify examples/classify/main.go
13-
14-
exec: prepare
15-
go build -o bin/exec examples/exec/main.go
3+
PKG_CONFIG_PC_PATH := $(shell pkg-config --variable pc_path pkg-config)
4+
PKG_CONFIG_ENV_PATH := $(value PKG_CONFIG_PATH)
5+
export PKG_CONFIG_PATH := $(PKG_CONFIG_PC_PATH)$(if $(PKG_CONFIG_ENV_PATH),:$(PKG_CONFIG_ENV_PATH))
166

17-
nonser: prepare
18-
go build -o bin/nonser examples/nonser/main.go
7+
.PHONY: all prepare clean
8+
all: noop classify detect exec nonser tf tflite torch
199

20-
tf: prepare
21-
go build -o bin/tf examples/tf/main.go
22-
23-
tflite: prepare
24-
go build -o bin/tflite examples/tflite/main.go
25-
26-
exec_genop: prepare
27-
go build -o bin/exec_genop examples/exec_genop/main.go
10+
prepare:
11+
@go mod tidy
12+
@mkdir -p $(BIN_DIR)/
2813

29-
torch:
30-
go build -o bin/torch examples/torch/main.go
14+
%: prepare examples/%/main.go
15+
go build -o $(BIN_DIR)/$@ examples/$@/main.go
3116

3217
clean:
33-
rm -rf bin
18+
rm -rf $(BIN_DIR)

examples/examples_test.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package main
4+
5+
import (
6+
"os"
7+
"os/exec"
8+
"path/filepath"
9+
"strings"
10+
"testing"
11+
)
12+
13+
type libvaccelPaths struct {
14+
libDir string
15+
imagesDir string
16+
modelsDir string
17+
inputDir string
18+
labelsDir string
19+
}
20+
21+
func pkgConfigVar(t *testing.T, pkg, variable string) string {
22+
t.Helper()
23+
cmd := exec.Command("pkg-config", "--variable="+variable, pkg) //nolint:gosec
24+
cmd.Env = os.Environ()
25+
out, err := cmd.Output()
26+
if err != nil {
27+
t.Skipf("pkg-config %s not found: %v", pkg, err)
28+
}
29+
return strings.TrimSpace(string(out))
30+
}
31+
32+
func resolveLibvaccelPaths(t *testing.T) libvaccelPaths {
33+
t.Helper()
34+
prefix := pkgConfigVar(t, "vaccel", "prefix")
35+
return libvaccelPaths{
36+
libDir: pkgConfigVar(t, "vaccel", "libdir"),
37+
imagesDir: filepath.Join(prefix, "share", "vaccel", "images"),
38+
modelsDir: filepath.Join(prefix, "share", "vaccel", "models"),
39+
inputDir: filepath.Join(prefix, "share", "vaccel", "input"),
40+
labelsDir: filepath.Join(prefix, "share", "vaccel", "labels"),
41+
}
42+
}
43+
44+
func TestExamples(t *testing.T) {
45+
paths := resolveLibvaccelPaths(t)
46+
env := append(
47+
os.Environ(),
48+
"LD_LIBRARY_PATH="+paths.libDir,
49+
"VACCEL_PLUGINS=libvaccel-noop.so",
50+
)
51+
52+
tests := []struct {
53+
name string
54+
dir string
55+
args []string
56+
env []string
57+
wantOut string
58+
}{
59+
{
60+
name: "noop",
61+
},
62+
{
63+
name: "classify",
64+
args: []string{filepath.Join(paths.imagesDir, "example.jpg")},
65+
wantOut: `Output(1): This is a dummy classification tag!
66+
Output(2): This is a dummy classification tag!`,
67+
},
68+
{
69+
name: "detect",
70+
args: []string{filepath.Join(paths.imagesDir, "example.jpg")},
71+
wantOut: `Output(1): This is a dummy imgname!
72+
Output(2): This is a dummy imgname!`,
73+
},
74+
{
75+
name: "exec",
76+
args: []string{filepath.Join(paths.libDir, "libmytestlib.so"), "10"},
77+
wantOut: `Output(1): 10
78+
Output(2): 10
79+
Output(3): 10`,
80+
},
81+
{
82+
name: "nonser",
83+
args: []string{filepath.Join(paths.libDir, "libmytestlib.so")},
84+
wantOut: `Input: 10 20 30 40 50
85+
Output: 10 20 30 40 50 `,
86+
},
87+
{
88+
name: "tf",
89+
args: []string{filepath.Join(paths.modelsDir, "tf")},
90+
wantOut: `Success!
91+
Output tensor => type:1 nr_dims:2
92+
dim[0]: 1
93+
dim[1]: 30
94+
Result Tensor:
95+
Tensor shape: [1 30]
96+
Values:
97+
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]`,
98+
},
99+
{
100+
name: "tflite",
101+
args: []string{filepath.Join(paths.modelsDir, "tf/lstm2.tflite")},
102+
wantOut: `Success, TFLite status: 0
103+
Output tensor => type:1 nr_dims:2
104+
dim[0]: 1
105+
dim[1]: 30
106+
Result Tensor:
107+
Tensor shape: [1 30]
108+
Values:
109+
[1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000, 1.0000]`,
110+
},
111+
{
112+
name: "torch",
113+
args: []string{
114+
filepath.Join(paths.imagesDir, "example.jpg"),
115+
filepath.Join(paths.modelsDir, "torch", "cnn_trace.pt"),
116+
filepath.Join(paths.labelsDir, "imagenet.txt"),
117+
},
118+
wantOut: `Success!
119+
Prediction: tench, Tinca tinca`,
120+
},
121+
}
122+
123+
for _, tt := range tests {
124+
t.Run(tt.name, func(t *testing.T) {
125+
main := filepath.Join(tt.name, "main.go")
126+
127+
cmd := exec.Command( //nolint:gosec
128+
"stdbuf",
129+
append([]string{"-oL", "-eL", "go", "run", main}, tt.args...)...,
130+
)
131+
cmdEnv := make([]string, len(env)+len(tt.env))
132+
copy(cmdEnv, env)
133+
copy(cmdEnv[len(env):], tt.env)
134+
cmd.Env = cmdEnv
135+
136+
out, err := cmd.CombinedOutput()
137+
if err != nil {
138+
t.Fatalf("example failed: %v\n%s", err, out)
139+
}
140+
if tt.wantOut != "" && !strings.Contains(string(out), tt.wantOut) {
141+
t.Errorf("got %q, want %q", out, tt.wantOut)
142+
}
143+
})
144+
}
145+
}

examples/exec/main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ func main() {
2222

2323
path := os.Args[1]
2424
input := os.Args[2]
25-
inputInt64, e := strconv.Atoi(input)
25+
parsedInput, e := strconv.ParseInt(input, 10, 32)
2626
if e != nil {
2727
fmt.Println("error converting input")
2828
return
2929
}
30-
inputInt32 := int32(inputInt64)
30+
inputInt32 := int32(parsedInput)
3131

3232
var session vaccel.Session
3333
err := session.Init(0)

examples/exec_genop/main.go

Lines changed: 0 additions & 103 deletions
This file was deleted.

examples/nonser/main.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"C"
77
"fmt"
88
"os"
9-
"reflect"
109
"unsafe"
1110

1211
"github.com/nubificus/vaccel-go/vaccel"
@@ -53,11 +52,7 @@ func Deserialize(buf unsafe.Pointer) unsafe.Pointer {
5352
sizeExtr := *((*uint32)(buf))
5453

5554
/* Convert unsafe.Pointer to Slice */
56-
var slice []uint32
57-
header := (*reflect.SliceHeader)(unsafe.Pointer(&slice))
58-
header.Data = uintptr(buf)
59-
header.Len = int(sizeExtr + 1)
60-
header.Cap = int(sizeExtr + 1)
55+
slice := unsafe.Slice((*uint32)(buf), sizeExtr+1)
6156

6257
/* Reconstruct the structure */
6358
mydatabuf := new(MyData)

examples/tf/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func main() {
100100

101101
err = outNode.Init("StatefulPartitionedCall", 0)
102102
if err != vaccel.OK {
103-
fmt.Println("Cound not configure output TF Node")
103+
fmt.Println("Could not configure output TF Node")
104104
goto DeleteInTensor
105105
}
106106

0 commit comments

Comments
 (0)