Add binary metric types SUBSTRUCTURE/SUPERSTRUCTURE back (#26766)

Signed-off-by: Yudong Cai <yudong.cai@zilliz.com>
This commit is contained in:
Cai Yudong 2023-08-31 20:07:00 +08:00 committed by GitHub
parent aad3d47a06
commit 8dc16b599b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 155 additions and 12 deletions

View File

@ -20,4 +20,6 @@ TEST(SimilarityCorelation, Naive) {
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::L2));
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::HAMMING));
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::JACCARD));
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::SUBSTRUCTURE));
ASSERT_FALSE(milvus::PositivelyRelated(knowhere::metric::SUPERSTRUCTURE));
}

View File

@ -446,7 +446,7 @@ func validateMetricType(dataType schemapb.DataType, metricTypeStrRaw string) err
if dataType == schemapb.DataType_FloatVector {
return nil
}
case metric.JACCARD, metric.HAMMING:
case metric.JACCARD, metric.HAMMING, metric.SUBSTRUCTURE, metric.SUPERSTRUCTURE:
if dataType == schemapb.DataType_BinaryVector {
return nil
}

View File

@ -31,6 +31,7 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.HAMMING,
@ -39,6 +40,14 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -51,6 +60,8 @@ func Test_binFlatChecker_CheckTrain(t *testing.T) {
{p3, false},
{p4, true},
{p5, true},
{p6, true},
{p7, true},
}
c := newBinFlatChecker()

View File

@ -9,8 +9,8 @@ type binIVFFlatChecker struct {
}
func (c binIVFFlatChecker) StaticCheck(params map[string]string) error {
if !CheckStrByValues(params, Metric, BinMetrics) {
return fmt.Errorf("metric type not found or not supported, supported: %v", BinMetrics)
if !CheckStrByValues(params, Metric, BinIvfMetrics) {
return fmt.Errorf("metric type not found or not supported, supported: %v", BinIvfMetrics)
}
if !CheckIntByRange(params, NLIST, MinNList, MaxNList) {

View File

@ -65,6 +65,7 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.HAMMING,
@ -79,6 +80,20 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUBSTRUCTURE,
NLIST: strconv.Itoa(100),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUPERSTRUCTURE,
NLIST: strconv.Itoa(100),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
}
cases := []struct {
params map[string]string
@ -96,6 +111,8 @@ func Test_binIVFFlatChecker_CheckTrain(t *testing.T) {
{p4, true},
{p5, true},
{p6, false},
{p7, false},
}
c := newBinIVFFlatChecker()

View File

@ -13,8 +13,8 @@ type binaryVectorBaseChecker struct {
}
func (c binaryVectorBaseChecker) staticCheck(params map[string]string) error {
if !CheckStrByValues(params, Metric, BinMetrics) {
return fmt.Errorf("metric type not found or not supported, supported: %v", BinMetrics)
if !CheckStrByValues(params, Metric, BinIDMapMetrics) {
return fmt.Errorf("metric type not found or not supported, supported: %v", BinIDMapMetrics)
}
return nil

View File

@ -42,7 +42,8 @@ const (
var METRICS = []string{metric.L2, metric.IP, metric.COSINE} // const
// BinIDMapMetrics is a set of all metric types supported for binary vector.
var BinMetrics = []string{metric.HAMMING, metric.JACCARD} // const
var BinIDMapMetrics = []string{metric.HAMMING, metric.JACCARD, metric.SUBSTRUCTURE, metric.SUPERSTRUCTURE} // const
var BinIvfMetrics = []string{metric.HAMMING, metric.JACCARD} // const
var HnswMetrics = []string{metric.L2, metric.IP, metric.COSINE, metric.HAMMING, metric.JACCARD} // const
var supportDimPerSubQuantizer = []int{32, 28, 24, 20, 16, 12, 10, 8, 6, 4, 3, 2, 1} // const
var supportSubQuantizer = []int{96, 64, 56, 48, 40, 32, 28, 24, 20, 16, 12, 8, 4, 3, 2, 1} // const

View File

@ -37,6 +37,7 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.HAMMING,
@ -45,6 +46,14 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -59,6 +68,8 @@ func Test_diskannChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newDiskannChecker()

View File

@ -23,6 +23,7 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.HAMMING,
@ -31,7 +32,14 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
DIM: strconv.Itoa(128),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
errIsNil bool
@ -41,6 +49,8 @@ func Test_flatChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newFlatChecker()

View File

@ -49,6 +49,7 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
EFConstruction: strconv.Itoa(200),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
HNSWM: strconv.Itoa(16),
@ -61,6 +62,18 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
EFConstruction: strconv.Itoa(200),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
HNSWM: strconv.Itoa(16),
EFConstruction: strconv.Itoa(200),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
HNSWM: strconv.Itoa(16),
EFConstruction: strconv.Itoa(200),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -76,6 +89,8 @@ func Test_hnswChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, true},
{p5, true},
{p6, false},
{p7, false},
}
c := newHnswChecker()

View File

@ -32,6 +32,7 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
NLIST: strconv.Itoa(1024),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
@ -42,6 +43,16 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
NLIST: strconv.Itoa(1024),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -55,6 +66,8 @@ func Test_ivfBaseChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newIVFBaseChecker()

View File

@ -84,6 +84,7 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
@ -98,6 +99,20 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -120,6 +135,8 @@ func Test_ivfPQChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newIVFPQChecker()

View File

@ -46,6 +46,7 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(100),
@ -58,6 +59,18 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(100),
NBITS: strconv.Itoa(8),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(100),
NBITS: strconv.Itoa(8),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -73,6 +86,8 @@ func Test_ivfSQChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newIVFSQChecker()

View File

@ -77,6 +77,7 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.COSINE,
}
p4 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
@ -91,6 +92,20 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
NBITS: strconv.Itoa(8),
Metric: metric.JACCARD,
}
p6 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
Metric: metric.SUBSTRUCTURE,
}
p7 := map[string]string{
DIM: strconv.Itoa(128),
NLIST: strconv.Itoa(1024),
IVFM: strconv.Itoa(4),
NBITS: strconv.Itoa(8),
Metric: metric.SUPERSTRUCTURE,
}
cases := []struct {
params map[string]string
@ -112,6 +127,8 @@ func Test_raftIVFPQChecker_CheckTrain(t *testing.T) {
{p3, true},
{p4, false},
{p5, false},
{p6, false},
{p7, false},
}
c := newRaftIVFPQChecker()

View File

@ -30,4 +30,10 @@ const (
// JACCARD represents jaccard distance
JACCARD MetricType = "JACCARD"
// SUBSTRUCTURE represents substructure distance
SUBSTRUCTURE MetricType = "SUBSTRUCTURE"
// SUPERSTRUCTURE represents superstructure distance
SUPERSTRUCTURE MetricType = "SUPERSTRUCTURE"
)

View File

@ -43,6 +43,14 @@ func TestPositivelyRelated(t *testing.T) {
JACCARD,
false,
},
{
SUBSTRUCTURE,
false,
},
{
SUPERSTRUCTURE,
false,
},
}
for idx := range cases {

View File

@ -239,7 +239,7 @@ delete_support = ["FLAT", "IVF_FLAT", "IVF_SQ8", "IVF_PQ"]
ivf = ["FLAT", "IVF_FLAT", "IVF_SQ8", "IVF_PQ"]
skip_pq = ["IVF_PQ"]
float_metrics = ["L2", "IP", "COSINE"]
binary_metrics = ["JACCARD", "HAMMING"]
binary_metrics = ["JACCARD", "HAMMING", "SUBSTRUCTURE", "SUPERSTRUCTURE"]
structure_metrics = ["SUBSTRUCTURE", "SUPERSTRUCTURE"]
all_scalar_data_types = ['int8', 'int16', 'int32', 'int64', 'float', 'double', 'bool', 'varchar']

View File

@ -75,7 +75,7 @@ def skip_pq():
def binary_metrics():
return ["JACCARD", "HAMMING"]
return ["JACCARD", "HAMMING", "SUBSTRUCTURE", "SUPERSTRUCTURE"]
def structure_metrics():