add golang demo for calling so lib

This commit is contained in:
codingcrush 2018-11-30 11:20:39 +08:00
parent 1a8eab9ec5
commit 2eef51f5a6
4 changed files with 241 additions and 1 deletions

View File

@ -531,4 +531,10 @@ prob
|---|---|---|
| ret | int | 返回码。0:成功非0:失败 |
| result | c_int | 检测结果是否异常。0:异常1:正常 |
| prob | c_float | 概率值,值越小,判定为异常的置信度越高 |
| prob | c_float | 概率值,值越小,判定为异常的置信度越高 |
#### Go代码中调用:
在Go中调用检测函数需要先加载cgo文件编写helper函数供go调用
详细demo见 `time_series_detector/demo/golang`目录

View File

@ -0,0 +1,95 @@
package detector
/*
#include <dlfcn.h>
#include <wrapper.h>
#cgo CFLAGS: -I.
#cgo LDFLAGS: -ldl
*/
import "C"
import (
"unsafe"
)
const LibPath = "../../lib/libdetect.so"
const xgbModelPath = "../../model/xgb_default_model"
const xgbThreshold = 0.15
var mPtr unsafe.Pointer
func init() {
hd := C.dlopen(C.CString(LibPath), C.RTLD_LAZY)
if hd == nil {
panic("dlopen failure")
}
loadModel := C.dlsym(hd, C.CString("load_model"))
valuePredict := C.dlsym(hd, C.CString("value_predict"))
ratePredict := C.dlsym(hd, C.CString("rate_predict"))
if loadModel == nil || valuePredict == nil || ratePredict == nil {
panic("dlsym failure")
}
C.setLoadModel(loadModel)
C.setValuePredict(valuePredict)
C.setRatePredict(ratePredict)
ptr := C.callLoadModel(C.CString(xgbModelPath))
if ptr == nil {
panic("load_model return NULL")
}
mPtr = ptr
}
func ValueDetect(sample Sample) (bool, float64) {
dataC := make([]C.int, len(sample.WeekAgo6h))
for index, value := range sample.WeekAgo6h {
dataC[index] = C.int(value)
}
dataB := make([]C.int, len(sample.Yesterday6h))
for index, value := range sample.Yesterday6h {
dataB[index] = C.int(value)
}
dataA := make([]C.int, len(sample.Last3h))
for index, value := range sample.Last3h {
dataA[index] = C.int(value)
}
prob := float64(C.callValuePredict(mPtr,
(*C.int)(unsafe.Pointer(&dataA[0])),
(*C.int)(unsafe.Pointer(&dataB[0])),
(*C.int)(unsafe.Pointer(&dataC[0])),
(C.int)(len(dataA)),
(C.int)(len(dataB)),
(C.int)(len(dataC)),
))
return prob >= xgbThreshold, prob
}
func RateDetect(sample Sample) (bool, float64) {
dataC := make([]C.double, len(sample.WeekAgo6h))
for index, value := range sample.WeekAgo6h {
dataC[index] = C.double(value)
}
dataB := make([]C.double, len(sample.Yesterday6h))
for index, value := range sample.Yesterday6h {
dataB[index] = C.double(value)
}
dataA := make([]C.double, len(sample.Last3h))
for index, value := range sample.Last3h {
dataA[index] = C.double(value)
}
prob := float64(C.callRatePredict(
(*C.double)(unsafe.Pointer(&dataA[0])),
(*C.double)(unsafe.Pointer(&dataB[0])),
(*C.double)(unsafe.Pointer(&dataC[0])),
(C.int)(len(dataA)),
(C.int)(len(dataB)),
(C.int)(len(dataC)),
))
return prob > 0, prob
}
type Sample struct {
Last3h []float64
Yesterday6h []float64
WeekAgo6h []float64
}

View File

@ -0,0 +1,54 @@
package detector
import (
_ "net/http/pprof"
"testing"
)
func TestValueDetect(t *testing.T) {
weekAgoData := make([]float64, 361)
for index := range weekAgoData {
weekAgoData[index] = 1
}
yesterdayData := weekAgoData
last3hData := make([]float64, 180)
for index := range last3hData {
last3hData[index] = 1
}
last3hData = append(last3hData, 10)
isOk, prob := ValueDetect(Sample{
WeekAgo6h: weekAgoData,
Last3h: last3hData,
Yesterday6h: yesterdayData,
})
t.Logf("value detect prob:%f", prob)
if isOk || prob == 1 || prob < 0 {
t.Fail()
}
}
func TestRateDetect(t *testing.T) {
weekAgoData := make([]float64, 361)
for index := range weekAgoData {
weekAgoData[index] = 1
}
yesterdayData := weekAgoData
last3hData := make([]float64, 180)
for index := range last3hData {
last3hData[index] = 1
}
last3hData = append(last3hData, 10)
isOk, prob := RateDetect(Sample{
WeekAgo6h: weekAgoData,
Last3h: last3hData,
Yesterday6h: yesterdayData,
})
t.Logf("rate detect prob:%f", prob)
if isOk || prob != 0 {
t.Fail()
}
}

View File

@ -0,0 +1,85 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int* data_a;
int* data_b;
int* data_c;
int len_a;
int len_b;
int len_c;
} ValueData;
typedef struct {
double* data_a;
double* data_b;
double* data_c;
int len_a;
int len_b;
int len_c;
} RateData;
void * (*load_model)(const char*);
void setLoadModel(void* fn) {
load_model = fn;
}
void * callLoadModel(const char *fname){
return load_model(fname);
};
int (*value_predict)(void *, ValueData*, int*, float*);
void setValuePredict(void* fn){
value_predict = fn;
}
float callValuePredict(void * mhandle, int* data_a, int* data_b, int* data_c, int len_a, int len_b, int len_c){
int sample_result=0;
float prob=0;
ValueData *dt=malloc(sizeof(ValueData));
dt->data_a = (int*)malloc(sizeof(int)*len_a);
dt->data_b = (int*)malloc(sizeof(int)*len_b);
dt->data_c = (int*)malloc(sizeof(int)*len_c);
memcpy(dt->data_a, data_a, sizeof(int)*len_a);
memcpy(dt->data_b, data_b, sizeof(int)*len_b);
memcpy(dt->data_c, data_c, sizeof(int)*len_c);
dt->len_a = len_a;
dt->len_b = len_b;
dt->len_c = len_c;
value_predict(mhandle, dt, &sample_result,&prob);
free(dt->data_a);
free(dt->data_b);
free(dt->data_c);
free(dt);
return prob;
}
int (*rate_predict)(RateData* data, int* sample_result, float* prob);
void setRatePredict(void* fn){
rate_predict = fn;
}
float callRatePredict(double *data_a, double* data_b, double* data_c, int len_a, int len_b, int len_c){
int sample_result=0;
float prob=0;
RateData *dt= malloc(sizeof(RateData));
dt->data_a = (double*)malloc(sizeof(double)*len_a);
dt->data_b = (double*)malloc(sizeof(double)*len_b);
dt->data_c = (double*)malloc(sizeof(double)*len_c);
memcpy(dt->data_a, data_a, sizeof(double)*len_a);
memcpy(dt->data_b, data_b, sizeof(double)*len_b);
memcpy(dt->data_c, data_c, sizeof(double)*len_c);
dt->len_a = len_a;
dt->len_b = len_b;
dt->len_c = len_c;
rate_predict(dt, &sample_result, &prob);
free(dt->data_a);
free(dt->data_b);
free(dt->data_c);
free(dt);
return prob;
}