diff --git a/internal/core/unittest/test_similarity_corelation.cpp b/internal/core/unittest/test_similarity_corelation.cpp index 18d3e73d9b..50f02f865f 100644 --- a/internal/core/unittest/test_similarity_corelation.cpp +++ b/internal/core/unittest/test_similarity_corelation.cpp @@ -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)); } diff --git a/internal/proxy/util.go b/internal/proxy/util.go index 21b106ed06..07906b7577 100644 --- a/internal/proxy/util.go +++ b/internal/proxy/util.go @@ -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 } diff --git a/pkg/util/indexparamcheck/bin_flat_checker_test.go b/pkg/util/indexparamcheck/bin_flat_checker_test.go index de40d232c8..4fa8814cd4 100644 --- a/pkg/util/indexparamcheck/bin_flat_checker_test.go +++ b/pkg/util/indexparamcheck/bin_flat_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/bin_ivf_flat_checker.go b/pkg/util/indexparamcheck/bin_ivf_flat_checker.go index ecc70b4e2f..dfcbc316a6 100644 --- a/pkg/util/indexparamcheck/bin_ivf_flat_checker.go +++ b/pkg/util/indexparamcheck/bin_ivf_flat_checker.go @@ -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) { diff --git a/pkg/util/indexparamcheck/bin_ivf_flat_checker_test.go b/pkg/util/indexparamcheck/bin_ivf_flat_checker_test.go index 1c6da2fae9..487e47198c 100644 --- a/pkg/util/indexparamcheck/bin_ivf_flat_checker_test.go +++ b/pkg/util/indexparamcheck/bin_ivf_flat_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/binary_vector_base_checker.go b/pkg/util/indexparamcheck/binary_vector_base_checker.go index 4401dc3c90..4fa69af204 100644 --- a/pkg/util/indexparamcheck/binary_vector_base_checker.go +++ b/pkg/util/indexparamcheck/binary_vector_base_checker.go @@ -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 diff --git a/pkg/util/indexparamcheck/constraints.go b/pkg/util/indexparamcheck/constraints.go index 97222010c1..f2e80db3d6 100644 --- a/pkg/util/indexparamcheck/constraints.go +++ b/pkg/util/indexparamcheck/constraints.go @@ -42,10 +42,11 @@ 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 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 +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 const ( FloatVectorDefaultMetricType = metric.IP diff --git a/pkg/util/indexparamcheck/diskann_checker_test.go b/pkg/util/indexparamcheck/diskann_checker_test.go index 0b1263c7c5..11005e1611 100644 --- a/pkg/util/indexparamcheck/diskann_checker_test.go +++ b/pkg/util/indexparamcheck/diskann_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/flat_checker_test.go b/pkg/util/indexparamcheck/flat_checker_test.go index 54d4bc5596..c44a215dae 100644 --- a/pkg/util/indexparamcheck/flat_checker_test.go +++ b/pkg/util/indexparamcheck/flat_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/hnsw_checker_test.go b/pkg/util/indexparamcheck/hnsw_checker_test.go index a8c5a84fb3..d2ea5d9f70 100644 --- a/pkg/util/indexparamcheck/hnsw_checker_test.go +++ b/pkg/util/indexparamcheck/hnsw_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/ivf_base_checker_test.go b/pkg/util/indexparamcheck/ivf_base_checker_test.go index 31b6925c52..e9ed4c017d 100644 --- a/pkg/util/indexparamcheck/ivf_base_checker_test.go +++ b/pkg/util/indexparamcheck/ivf_base_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/ivf_pq_checker_test.go b/pkg/util/indexparamcheck/ivf_pq_checker_test.go index 0bf726e044..11938473d0 100644 --- a/pkg/util/indexparamcheck/ivf_pq_checker_test.go +++ b/pkg/util/indexparamcheck/ivf_pq_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/ivf_sq_checker_test.go b/pkg/util/indexparamcheck/ivf_sq_checker_test.go index e2489bb733..eef0a73251 100644 --- a/pkg/util/indexparamcheck/ivf_sq_checker_test.go +++ b/pkg/util/indexparamcheck/ivf_sq_checker_test.go @@ -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() diff --git a/pkg/util/indexparamcheck/raft_ivf_pq_checker_test.go b/pkg/util/indexparamcheck/raft_ivf_pq_checker_test.go index 118df318f9..27d6939ed7 100644 --- a/pkg/util/indexparamcheck/raft_ivf_pq_checker_test.go +++ b/pkg/util/indexparamcheck/raft_ivf_pq_checker_test.go @@ -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() diff --git a/pkg/util/metric/metric_type.go b/pkg/util/metric/metric_type.go index f1676a3af9..107e42cf09 100644 --- a/pkg/util/metric/metric_type.go +++ b/pkg/util/metric/metric_type.go @@ -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" ) diff --git a/pkg/util/metric/similarity_corelation_test.go b/pkg/util/metric/similarity_corelation_test.go index 891f0a5a44..ce83b70f6a 100644 --- a/pkg/util/metric/similarity_corelation_test.go +++ b/pkg/util/metric/similarity_corelation_test.go @@ -43,6 +43,14 @@ func TestPositivelyRelated(t *testing.T) { JACCARD, false, }, + { + SUBSTRUCTURE, + false, + }, + { + SUPERSTRUCTURE, + false, + }, } for idx := range cases { diff --git a/tests/python_client/common/common_type.py b/tests/python_client/common/common_type.py index b60f105d5d..f1d0e16397 100644 --- a/tests/python_client/common/common_type.py +++ b/tests/python_client/common/common_type.py @@ -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'] diff --git a/tests/python_client/utils/util_pymilvus.py b/tests/python_client/utils/util_pymilvus.py index 73ec880874..947e151800 100644 --- a/tests/python_client/utils/util_pymilvus.py +++ b/tests/python_client/utils/util_pymilvus.py @@ -75,7 +75,7 @@ def skip_pq(): def binary_metrics(): - return ["JACCARD", "HAMMING"] + return ["JACCARD", "HAMMING", "SUBSTRUCTURE", "SUPERSTRUCTURE"] def structure_metrics():