FLANNという最近傍探索ライブラリをcgoでGoから使ってみるメモ。
環境
$ go version
go version go1.6 darwin/amd64
$ clang -v
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.0.0
Thread model: posix
OSはEl Capitan (10.11.1)
FLANNの導入
brewを使えば簡単に入る。
brew install homebrew/science/flann
Goから呼び出してみる
cgoはじめてなので手探り。取り敢えずサンプルレベルのものは動いた。
package main
// #cgo pkg-config: flann
// #cgo LDFLAGS: -lflann
// #include <flann/flann.h>
import "C"
import (
"fmt"
)
func main() {
dataset := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
datasetRows := 5
var speedup C.float
var p C.struct_FLANNParameters
p = C.DEFAULT_FLANN_PARAMETERS
p.algorithm = C.FLANN_INDEX_HIERARCHICAL
p.trees = 4;
p.branching = 32;
p.leaf_max_size = 100;
p.centers_init = C.FLANN_CENTERS_KMEANSPP;
index, _ := C.flann_build_index_byte((*C.uchar)(&dataset[0]), (C.int)(datasetRows), 2, &speedup, &p)
testset := []byte{5, 6}
testsetRows := 1
var indeces [1](C.int)
var dists [1](C.float)
C.flann_find_nearest_neighbors_index_byte(index, (*C.uchar)(&testset[0]), (C.int)(testsetRows), &indeces[0], &dists[0], 1, &p);
C.flann_free_index(index, &p)
fmt.Printf("index: %d dist: %f\n", (int)(indeces[0]), (float32)(dists[0]))
}
- FLANN自体はC++で実装されているが公式でCバインディングがあるのでそれを使う
- GoからC++のライブラリを使うときはCバインディングを介するのがセオリーらしい⇒cgoでGolangとC++ライブラリをリンクするとき、何が起きているのか
- pkg-configは
libflann_cpp
しかリンクしてくれないので、追加で#cgo LDFLAGS: -lflann
を指定してCバインディングもリンクするように
普通にビルドすればOK
$ go build -o flann
$ ./flann
index: 2 dist: 0.000000
知見があれば追記する。