mirror of
https://github.com/swdee/go-rknnlite.git
synced 2025-09-26 19:31:12 +08:00
added integration test and github workflow action
This commit is contained in:
76
.github/workflows/ci.yml
vendored
76
.github/workflows/ci.yml
vendored
@@ -8,19 +8,67 @@ on:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint & fmt
|
||||
runs-on: ubuntu-latest
|
||||
name: Lint and gofmt
|
||||
runs-on: [ self-hosted, rk3588, npu ]
|
||||
|
||||
container:
|
||||
image: swdee/go-rknnlite:latest
|
||||
# pass in NPU
|
||||
options: >-
|
||||
--device /dev/dri:/dev/dri
|
||||
-v /usr/include/rknn_api.h:/usr/include/rknn_api.h
|
||||
-v /usr/lib/librknnrt.so:/usr/lib/librknnrt.so
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v4
|
||||
with:
|
||||
version: v1.58.2
|
||||
- name: Check gofmt
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Fetch Go modules
|
||||
run: go mod download
|
||||
|
||||
- name: Install nodejs for golangci
|
||||
run: |
|
||||
if diff -u <(echo -n) <(gofmt -d .); then
|
||||
echo "All files are gofmted"
|
||||
else
|
||||
echo "Please run gofmt -s -w ."
|
||||
exit 1
|
||||
fi
|
||||
apt-get update
|
||||
apt-get install -y nodejs
|
||||
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: v2.1.2
|
||||
args: -v --config .golangci.yml
|
||||
|
||||
|
||||
integration-test:
|
||||
name: Integration on RK3588
|
||||
runs-on: [ self-hosted, rk3588, npu ]
|
||||
|
||||
container:
|
||||
image: swdee/go-rknnlite:latest
|
||||
# pass in NPU
|
||||
options: >-
|
||||
--device /dev/dri:/dev/dri
|
||||
-v /usr/include/rknn_api.h:/usr/include/rknn_api.h
|
||||
-v /usr/lib/librknnrt.so:/usr/lib/librknnrt.so
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Fetch Go modules
|
||||
run: go mod download
|
||||
|
||||
- name: Download model & image for integration test
|
||||
run: |
|
||||
mkdir -p example/data
|
||||
curl -L \
|
||||
https://raw.githubusercontent.com/swdee/go-rknnlite-data/master/mobilenet_v1-rk3588.rknn \
|
||||
-o example/data/mobilenet_v1-rk3588.rknn
|
||||
curl -L \
|
||||
https://raw.githubusercontent.com/swdee/go-rknnlite-data/master/cat_224x224.jpg \
|
||||
-o example/data/cat_224x224.jpg
|
||||
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
export RKNN_MODEL=example/data/mobilenet_v1-rk3588.rknn
|
||||
export RKNN_IMAGE=example/data/cat_224x224.jpg
|
||||
go test -timeout 5m -tags=integration ./...
|
||||
|
@@ -1,14 +1,20 @@
|
||||
|
||||
version: "2"
|
||||
|
||||
run:
|
||||
timeout: 5m # give linters up to 5m to complete
|
||||
tests: true # also run linters on *_test.go
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- linters:
|
||||
- typecheck
|
||||
path: ^example/ppocr/.*\.go$
|
||||
text: "main redeclared in this block" # ignore multiple main() declaractions in ppocr directory
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- govet
|
||||
- unused
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
ignore: '' # workaround to bug #4743, fix to upgrade to v1.62.0+
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
111
inference_integration_test.go
Normal file
111
inference_integration_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
//go:build integration
|
||||
// +build integration
|
||||
|
||||
package rknnlite
|
||||
|
||||
import (
|
||||
"gocv.io/x/gocv"
|
||||
"image"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMobileNetTop5(t *testing.T) {
|
||||
|
||||
modelFile := os.Getenv("RKNN_MODEL")
|
||||
|
||||
if modelFile == "" {
|
||||
t.Fatalf("No Model file provided in RKNN_MODEL")
|
||||
}
|
||||
|
||||
imgFile := os.Getenv("RKNN_IMAGE")
|
||||
|
||||
if imgFile == "" {
|
||||
t.Fatalf("No Image file provided in RKNN_IMAGE")
|
||||
}
|
||||
|
||||
// Initialize runtime
|
||||
rt, err := NewRuntime(modelFile, NPUCoreAuto)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("NewRuntime failed: %v", err)
|
||||
}
|
||||
|
||||
defer rt.Close()
|
||||
|
||||
// load image
|
||||
img := gocv.IMRead(imgFile, gocv.IMReadColor)
|
||||
|
||||
if img.Empty() {
|
||||
t.Fatalf("Error reading image from: %s", imgFile)
|
||||
}
|
||||
|
||||
// convert colorspace and resize image
|
||||
rgbImg := gocv.NewMat()
|
||||
gocv.CvtColor(img, &rgbImg, gocv.ColorBGRToRGB)
|
||||
|
||||
cropImg := rgbImg.Clone()
|
||||
scaleSize := image.Pt(int(rt.InputAttrs()[0].Dims[1]), int(rt.InputAttrs()[0].Dims[2]))
|
||||
gocv.Resize(rgbImg, &cropImg, scaleSize, 0, 0, gocv.InterpolationArea)
|
||||
|
||||
defer img.Close()
|
||||
defer rgbImg.Close()
|
||||
defer cropImg.Close()
|
||||
|
||||
// run inference
|
||||
outputs, err := rt.Inference([]gocv.Mat{cropImg})
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Inference error: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := outputs.Free(); err != nil {
|
||||
t.Errorf("Free Outputs: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Extract Top5
|
||||
top5 := GetTop5(outputs.Output)
|
||||
|
||||
if len(top5) != 5 {
|
||||
t.Fatalf("expected 5 results, got %d", len(top5))
|
||||
}
|
||||
|
||||
// Probabilities must be in [0,1] and descending
|
||||
for i, p := range top5 {
|
||||
|
||||
if p.Probability < 0 || p.Probability > 1 {
|
||||
t.Errorf("entry %d: probability %v out of [0,1]", i, p.Probability)
|
||||
}
|
||||
|
||||
if i > 0 && p.Probability > top5[i-1].Probability {
|
||||
t.Errorf("probabilities not descending: index %d has %v > previous %v",
|
||||
i, p.Probability, top5[i-1].Probability)
|
||||
}
|
||||
}
|
||||
|
||||
// Label indices must be in range [0, numClasses)
|
||||
numClasses := int(rt.OutputAttrs()[0].Dims[1])
|
||||
|
||||
for i, p := range top5 {
|
||||
if int(p.LabelIndex) < 0 || int(p.LabelIndex) >= numClasses {
|
||||
t.Errorf("entry %d: label index %d out of range [0,%d)", i, p.LabelIndex, numClasses)
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity check: at least one probability above a tiny epsilon
|
||||
const eps = 1e-3
|
||||
var found bool
|
||||
|
||||
for _, p := range top5 {
|
||||
if p.Probability > eps {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
t.Errorf("all probabilities ≤ %v, something's wrong", eps)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user