github.com/milvus-io/milvus-sdk-go/v2@v2.4.1/entity/genidx/genidx.go (about)

     1  //go:build ignore
     2  // +build ignore
     3  
     4  // Copyright (C) 2019-2021 Zilliz. All rights reserved.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
     7  // with the License. You may obtain a copy of the License at
     8  //
     9  // http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software distributed under the License
    12  // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
    13  // or implied. See the License for the specific language governing permissions and limitations under the License.
    14  
    15  // This program generates entity/indexes_gen.go. Invoked by go generate
    16  package main
    17  
    18  import (
    19  	"fmt"
    20  	"os"
    21  	"strings"
    22  	"text/template"
    23  
    24  	"github.com/milvus-io/milvus-sdk-go/v2/entity"
    25  )
    26  
    27  var indexTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT
    28  // This file is generated by go generate 
    29  
    30  package entity
    31  
    32  import (
    33  	"errors"
    34  	"encoding/json"
    35  	"fmt"
    36  )
    37  
    38  {{ range .Indexes }}{{with .}}
    39  
    40  var _ Index = &Index{{.IdxName}}{}
    41  
    42  // Index{{.IdxName}} idx type for {{.IdxType}}
    43  type Index{{.IdxName}} struct { //auto generated fields{{range .ConstructParams}}{{with .}}
    44  	{{.Name}} {{.ParamType}}{{end}}{{end}}
    45  	metricType MetricType
    46  }
    47  
    48  // Name returns index type name, implementing Index interface
    49  func(i *Index{{.IdxName}}) Name() string {
    50  	return "{{.IdxName}}"
    51  }
    52  
    53  // IndexType returns IndexType, implementing Index interface
    54  func(i *Index{{.IdxName}}) IndexType() IndexType {
    55  	return IndexType("{{.IdxType}}")
    56  }
    57  
    58  // SupportBinary returns whether index type support binary vector
    59  func(i *Index{{.IdxName}}) SupportBinary() bool {
    60  	return {{.VectorSupport}} & 2 > 0
    61  }
    62  
    63  // Params returns index construction params, implementing Index interface
    64  func(i *Index{{.IdxName}}) Params() map[string]string {
    65  	params := map[string]string {//auto generated mapping {{range .ConstructParams}}{{with .}}
    66  		"{{.Name}}": fmt.Sprintf("%v",i.{{.Name}}),{{end}}{{end}}
    67  	}
    68  	bs, _ := json.Marshal(params)
    69  	return map[string]string {
    70  		"params": string(bs),
    71  		"index_type": string(i.IndexType()),
    72  		"metric_type": string(i.metricType),
    73  	}
    74  }
    75  
    76  // NewIndex{{.IdxName}} create index with construction parameters
    77  func NewIndex{{.IdxName}}(metricType MetricType, {{range .ConstructParams}}{{with .}}
    78  	{{.Name}} {{.ParamType}},
    79  {{end}}{{end}}) (*Index{{.IdxName}}, error) {
    80  	// auto generate parameters validation code, if any{{range .ConstructParams}}{{with .}}
    81  	{{.ValidationCode}}
    82  	{{end}}{{end}}
    83  	return &Index{{.IdxName}}{ {{range .ConstructParams}}{{with .}}
    84  	//auto generated setting
    85  	{{.Name}}: {{.Name}},{{end}}{{end}}
    86  	metricType: metricType,
    87  	}, nil
    88  }
    89  {{end}}{{end}}
    90  `))
    91  
    92  var indexTestTemplate = template.Must(template.New("").Funcs(template.FuncMap{
    93  	"SContains": func(s, sub string) bool { return strings.Contains(s, sub) },
    94  }).Parse(`// Code generated by go generate; DO NOT EDIT
    95  // This file is generated by go generate
    96  
    97  package entity
    98  
    99  import (
   100  	"testing"
   101  
   102  	"github.com/stretchr/testify/assert"
   103  )
   104  
   105  {{range $idx := .Indexes}}{{with.}}
   106  func TestIndex{{.IdxName}}(t *testing.T){
   107  	{{range .ConstructParams}}{{with.}}
   108  	var {{.Name}} {{.ParamType}}{{end}}{{end}}
   109  
   110  	{{if SContains $idx.IdxName "Bin" }}mt := HAMMING{{else}}mt := L2{{end}}
   111  	
   112  
   113  	t.Run("valid usage case", func(t *testing.T){
   114  		{{range $i, $example := .ValidExamples}}
   115  		{{$example}}
   116  		idx{{$i}}, err := NewIndex{{$idx.IdxName}}(mt, {{range $idx.ConstructParams}}{{with.}}
   117  			{{.Name}},{{end}}{{end}}
   118  		)
   119  		assert.Nil(t, err)
   120  		assert.NotNil(t, idx{{$i}})
   121  		assert.Equal(t, "{{$idx.IdxName}}", idx{{$i}}.Name())
   122  		assert.EqualValues(t, "{{$idx.IdxType}}", idx{{$i}}.IndexType())
   123  		assert.NotNil(t, idx{{$i}}.Params())
   124  		{{if SContains $idx.IdxName "Bin" }}assert.True(t, idx{{$i}}.SupportBinary()){{else}}assert.False(t, idx{{$i}}.SupportBinary()){{end}}
   125  		{{end}}
   126  	})
   127  
   128  	t.Run("invalid usage case", func(t *testing.T){
   129  		{{range $i, $example := .InvalidExamples}}
   130  		{{$example}}
   131  		idx{{$i}}, err := NewIndex{{$idx.IdxName}}(mt, {{range $idx.ConstructParams}}{{with.}}
   132  			{{.Name}},{{end}}{{end}}
   133  		)
   134  		assert.NotNil(t, err)
   135  		assert.Nil(t, idx{{$i}})
   136  		{{end}}
   137  	})
   138  }
   139  {{end}}{{end}}
   140  `))
   141  
   142  var indexSearchParamTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT
   143  // This file is generated by go generate 
   144  
   145  package entity
   146  
   147  import (
   148  	"errors"
   149  )
   150  
   151  {{ range .Indexes }}{{with.}}
   152  var _ SearchParam = &Index{{.IdxName}}SearchParam{}
   153  
   154  // Index{{.IdxName}}SearchParam search param struct for index type {{.IdxType}}
   155  type Index{{.IdxName}}SearchParam struct { //auto generated fields
   156  	baseSearchParams
   157  	{{range .SearchParams}}{{with.}}
   158  	{{.Name}} {{.ParamType}}{{end}}{{end}}
   159  }
   160  
   161  // NewIndex{{.IdxName}}SearchParam create index search param
   162  func NewIndex{{.IdxName}}SearchParam({{range .SearchParams}}{{with .}}
   163  	{{.Name}} {{.ParamType}},
   164  {{end}}{{end}}) (*Index{{.IdxName}}SearchParam, error) {
   165  	// auto generate parameters validation code, if any{{range .SearchParams}}{{with .}}
   166  	{{.ValidationCode}}
   167  	{{end}}{{end}}
   168  	sp := &Index{{.IdxName}}SearchParam{
   169  		baseSearchParams: newBaseSearchParams(),
   170  	}
   171  	
   172  	//auto generated setting{{range .SearchParams}}{{with .}}
   173  	sp.params["{{.Name}}"] = {{.Name}}{{end}}{{end}}
   174  
   175  	return sp, nil
   176  }
   177  {{end}}{{end}}
   178  `))
   179  
   180  var indexSearchParamTestTemplate = template.Must(template.New("").Parse(`// Code generated by go generate; DO NOT EDIT
   181  // This file is generated by go generate
   182  
   183  package entity
   184  
   185  import (
   186  	"testing"
   187  
   188  	"github.com/stretchr/testify/assert"
   189  )
   190  
   191  {{range $idx := .Indexes}}{{with.}}
   192  func TestIndex{{.IdxName}}SearchParam(t *testing.T) {
   193  	{{range .SearchParams}}{{with.}}
   194  	var {{.Name}} {{.ParamType}}{{end}}{{end}}
   195  
   196  	t.Run("valid usage case", func(t *testing.T){
   197  		{{range $i, $example := .ValidSearchParams}}
   198  		{{$example}}
   199  		idx{{$i}}, err := NewIndex{{$idx.IdxName}}SearchParam({{range $idx.SearchParams}}{{with.}}
   200  			{{.Name}},{{end}}{{end}}
   201  		)
   202  		assert.Nil(t, err)
   203  		assert.NotNil(t, idx{{$i}})
   204  		assert.NotNil(t, idx{{$i}}.Params())
   205  		{{end}}
   206  	})
   207  	{{ if .InvalidSearchParams }}
   208  	t.Run("invalid usage case", func(t *testing.T){
   209  		{{range $i, $example := .InvalidSearchParams}}
   210  		{{$example}}
   211  		idx{{$i}}, err := NewIndex{{$idx.IdxName}}SearchParam({{range $idx.SearchParams}}{{with.}}
   212  			{{.Name}},{{end}}{{end}}
   213  		)
   214  		assert.NotNil(t, err)
   215  		assert.Nil(t, idx{{$i}})
   216  		{{end}}
   217  	})
   218  	{{end}}
   219  }
   220  {{end}}{{end}}
   221  `))
   222  
   223  type idxDef struct {
   224  	IdxName             string
   225  	IdxType             entity.IndexType
   226  	VectorSupport       int8
   227  	ConstructParams     []idxParam
   228  	SearchParams        []idxParam
   229  	ValidExamples       []string // valid value examples, used in tests
   230  	InvalidExamples     []string // invalid value examples, used in tests
   231  	ValidSearchParams   []string
   232  	InvalidSearchParams []string
   233  }
   234  
   235  type idxParam struct {
   236  	Name           string
   237  	Type           string // default int
   238  	ValidationRule string // support format `[min, max]`, `in (...)` `{other param}===0 (mod self)`
   239  }
   240  
   241  // ParamType param definition type
   242  func (ip idxParam) ParamType() string {
   243  	if ip.Type == "" {
   244  		return "int"
   245  	}
   246  	return ip.Type
   247  }
   248  
   249  // ValidationCode auto generate validation code by validation rule
   250  func (ip idxParam) ValidationCode() string {
   251  	if ip.Type == "" {
   252  		ip.Type = "int"
   253  	}
   254  	switch {
   255  	case strings.HasPrefix(ip.ValidationRule, "in ("): // TODO change to regex
   256  		raw := ip.ValidationRule[4 : len(ip.ValidationRule)-1]
   257  		return fmt.Sprintf(`validRange := []%s{%s}
   258  	%sOk := false
   259  	for _, v := range validRange {
   260  		if v == %s {
   261  			%sOk = true
   262  			break
   263  		}
   264  	}
   265  	if !%sOk {
   266  		return nil, errors.New("%s not valid")
   267  	}`, ip.Type, raw, ip.Name, ip.Name, ip.Name, ip.Name, ip.Name)
   268  	case strings.Contains(ip.ValidationRule, "==="): // TODO change to regex
   269  		//TODO NOT IMPLEMENT YET
   270  	case strings.Contains(ip.ValidationRule, "[") &&
   271  		strings.Contains(ip.ValidationRule, "]"): // TODO change to regex
   272  		// very restrict format contstraint to `[min, max]`
   273  		// not extra space allowed
   274  		raw := ip.ValidationRule[1 : len(ip.ValidationRule)-1]
   275  		parts := strings.Split(raw, ",")
   276  		min := strings.TrimSpace(parts[0])
   277  		max := strings.TrimSpace(parts[1])
   278  		return fmt.Sprintf(`if %s < %s {
   279  		return nil, errors.New("%s has to be in range [%s, %s]")
   280  	}
   281  	if %s > %s {
   282  		return nil, errors.New("%s has to be in range [%s, %s]")
   283  	}`, ip.Name, min, ip.Name, min, max, ip.Name, max, ip.Name, min, max)
   284  	default:
   285  		return ""
   286  	}
   287  
   288  	return ""
   289  }
   290  
   291  type vectorTypeSupport int8
   292  
   293  const (
   294  	floatVectorSupport  vectorTypeSupport = 1
   295  	binaryVectorSupport vectorTypeSupport = 1 << 1
   296  )
   297  
   298  func main() {
   299  	f, err := os.OpenFile("indexes_gen.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
   300  	if err != nil {
   301  		fmt.Println(err.Error())
   302  		os.Exit(1)
   303  	}
   304  	defer f.Close()
   305  	ft, err := os.OpenFile("indexes_gen_test.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
   306  	if err != nil {
   307  		fmt.Println(err.Error())
   308  		os.Exit(1)
   309  	}
   310  	defer ft.Close()
   311  	fp, err := os.OpenFile("indexes_search_param_gen.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
   312  	if err != nil {
   313  		fmt.Println(err.Error())
   314  		os.Exit(1)
   315  	}
   316  	defer fp.Close()
   317  	fpt, err := os.OpenFile("indexes_search_param_gen_test.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0755)
   318  	if err != nil {
   319  		fmt.Println(err.Error())
   320  		os.Exit(1)
   321  	}
   322  	defer fpt.Close()
   323  
   324  	settings := struct {
   325  		Indexes []idxDef
   326  	}{
   327  		Indexes: []idxDef{
   328  			// FLAT
   329  			{
   330  				IdxName:         "Flat",
   331  				IdxType:         entity.Flat,
   332  				ConstructParams: []idxParam{},
   333  				SearchParams:    []idxParam{},
   334  				ValidExamples: []string{
   335  					"",
   336  				},
   337  				InvalidExamples: []string{},
   338  				ValidSearchParams: []string{
   339  					"",
   340  				},
   341  				InvalidSearchParams: []string{},
   342  			},
   343  			// BIN_FLAT
   344  			{
   345  				IdxName:       "BinFlat",
   346  				IdxType:       entity.BinFlat,
   347  				VectorSupport: int8(binaryVectorSupport),
   348  				ConstructParams: []idxParam{
   349  					{
   350  						Name:           "nlist",
   351  						ValidationRule: "[1, 65536]",
   352  					},
   353  				},
   354  				SearchParams: []idxParam{
   355  					{
   356  						Name:           "nprobe",
   357  						ValidationRule: "[1, 65536]", //[1, nlist]
   358  					},
   359  				},
   360  				ValidExamples: []string{
   361  					"nlist = 10",
   362  				},
   363  				InvalidExamples: []string{
   364  					"nlist = 0",
   365  					"nlist = 65537",
   366  				},
   367  				ValidSearchParams: []string{
   368  					"nprobe = 10",
   369  				},
   370  				InvalidSearchParams: []string{
   371  					"nprobe = 0",
   372  					"nprobe = 65537",
   373  				},
   374  			},
   375  			// IVF_FLAT
   376  			{
   377  				IdxName: "IvfFlat",
   378  				IdxType: entity.IvfFlat,
   379  				ConstructParams: []idxParam{
   380  					{
   381  						Name:           "nlist",
   382  						ValidationRule: "[1, 65536]",
   383  					},
   384  				},
   385  				SearchParams: []idxParam{
   386  					{
   387  						Name:           "nprobe",
   388  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   389  					},
   390  				},
   391  				ValidExamples: []string{
   392  					"nlist = 10",
   393  				},
   394  				InvalidExamples: []string{
   395  					"nlist = 0",
   396  					"nlist = 65537",
   397  				},
   398  				ValidSearchParams: []string{
   399  					"nprobe = 10",
   400  				},
   401  				InvalidSearchParams: []string{
   402  					"nprobe = 0",
   403  					"nprobe = 65537",
   404  				},
   405  			},
   406  			// BIN_IVF_FLAT
   407  			{
   408  				IdxName:       "BinIvfFlat",
   409  				IdxType:       entity.BinIvfFlat,
   410  				VectorSupport: int8(binaryVectorSupport),
   411  				ConstructParams: []idxParam{
   412  					{
   413  						Name:           "nlist",
   414  						ValidationRule: "[1, 65536]",
   415  					},
   416  				},
   417  				SearchParams: []idxParam{
   418  					{
   419  						Name:           "nprobe",
   420  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   421  					},
   422  				},
   423  				ValidExamples: []string{
   424  					"nlist = 10",
   425  				},
   426  				InvalidExamples: []string{
   427  					"nlist = 0",
   428  					"nlist = 65537",
   429  				},
   430  				ValidSearchParams: []string{
   431  					"nprobe = 10",
   432  				},
   433  				InvalidSearchParams: []string{
   434  					"nprobe = 0",
   435  					"nprobe = 65537",
   436  				},
   437  			},
   438  			// IVF_SQ8
   439  			{
   440  				IdxName: "IvfSQ8",
   441  				IdxType: entity.IvfSQ8,
   442  				ConstructParams: []idxParam{
   443  					{
   444  						Name:           "nlist",
   445  						ValidationRule: "[1, 65536]",
   446  					},
   447  				},
   448  				SearchParams: []idxParam{
   449  					{
   450  						Name:           "nprobe",
   451  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   452  					},
   453  				},
   454  				ValidExamples: []string{
   455  					"nlist = 10",
   456  				},
   457  				InvalidExamples: []string{
   458  					"nlist = 0",
   459  					"nlist = 65537",
   460  				},
   461  				ValidSearchParams: []string{
   462  					"nprobe = 10",
   463  				},
   464  				InvalidSearchParams: []string{
   465  					"nprobe = 0",
   466  					"nprobe = 65537",
   467  				},
   468  			},
   469  			// IVF_PQ
   470  			{
   471  				IdxName: "IvfPQ",
   472  				IdxType: entity.IvfPQ,
   473  				ConstructParams: []idxParam{
   474  					{
   475  						Name:           "nlist",
   476  						ValidationRule: "[1, 65536]",
   477  					},
   478  					{
   479  						Name:           "m",
   480  						ValidationRule: "dim===0 (mod self)",
   481  					},
   482  					{
   483  						Name:           "nbits",
   484  						ValidationRule: "[1, 16]",
   485  					},
   486  				},
   487  				SearchParams: []idxParam{
   488  					{
   489  						Name:           "nprobe",
   490  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   491  					},
   492  				},
   493  				ValidExamples: []string{
   494  					"nlist, m, nbits = 10, 8, 8",
   495  				},
   496  				InvalidExamples: []string{
   497  					"nlist, m, nbits = 0, 8, 8",
   498  					"nlist, m, nbits = 65537, 8, 8",
   499  					"nlist, m, nbits = 10, 8, 0",
   500  					"nlist, m, nbits = 10, 8, 17",
   501  				},
   502  				ValidSearchParams: []string{
   503  					"nprobe = 10",
   504  				},
   505  				InvalidSearchParams: []string{
   506  					"nprobe = 0",
   507  					"nprobe = 65537",
   508  				},
   509  			},
   510  			// HNSW
   511  			{
   512  				IdxName: "HNSW",
   513  				IdxType: entity.HNSW,
   514  				ConstructParams: []idxParam{
   515  					{
   516  						Name:           "M",
   517  						ValidationRule: "[4, 64]",
   518  					},
   519  					{
   520  						Name:           "efConstruction",
   521  						ValidationRule: "[8, 512]",
   522  					},
   523  				},
   524  				SearchParams: []idxParam{
   525  					{
   526  						Name:           "ef",
   527  						ValidationRule: "[1, 32768]", // [topK, 32768], refer to index construct param, not supported yet
   528  					},
   529  				},
   530  				ValidExamples: []string{
   531  					"M, efConstruction = 16, 40",
   532  				},
   533  				InvalidExamples: []string{
   534  					"M, efConstruction = 3, 40",
   535  					"M, efConstruction = 65, 40",
   536  					"M, efConstruction = 16, 7",
   537  					"M, efConstruction = 16, 513",
   538  				},
   539  				ValidSearchParams: []string{
   540  					"ef = 16",
   541  				},
   542  				InvalidSearchParams: []string{
   543  					"ef = 0",
   544  					"ef = 32769",
   545  				},
   546  			},
   547  			// IVF_HNSW
   548  			{
   549  				IdxName: "IvfHNSW",
   550  				IdxType: entity.IvfHNSW,
   551  				ConstructParams: []idxParam{
   552  					{
   553  						Name:           "nlist",
   554  						ValidationRule: "[1, 65536]",
   555  					},
   556  					{
   557  						Name:           "M",
   558  						ValidationRule: "[4, 64]",
   559  					},
   560  					{
   561  						Name:           "efConstruction",
   562  						ValidationRule: "[8, 512]",
   563  					},
   564  				},
   565  				SearchParams: []idxParam{
   566  					{
   567  						Name:           "nprobe",
   568  						ValidationRule: "[1, 65536]", //[1, nlist]
   569  					},
   570  					{
   571  						Name:           "ef",
   572  						ValidationRule: "[1, 32768]", // [topK, 32768], refer to index construct param, not supported yet
   573  					},
   574  				},
   575  				ValidExamples: []string{
   576  					"nlist, M, efConstruction = 10, 16, 40",
   577  				},
   578  				InvalidExamples: []string{
   579  					"nlist, M, efConstruction = 0, 16, 40",
   580  					"nlist, M, efConstruction = 65537, 16, 40",
   581  					"nlist, M, efConstruction = 10, 3, 40",
   582  					"nlist, M, efConstruction = 10, 65, 40",
   583  					"nlist, M, efConstruction = 10, 16, 7",
   584  					"nlist, M, efConstruction = 10, 16, 513",
   585  				},
   586  				ValidSearchParams: []string{
   587  					"nprobe, ef = 10, 16",
   588  				},
   589  				InvalidSearchParams: []string{
   590  					"nprobe, ef = 0, 16",
   591  					"nprobe, ef = 65537, 16",
   592  					"nprobe, ef = 10, 0",
   593  					"nprobe, ef = 10, 32769",
   594  				},
   595  			},
   596  			{
   597  				IdxName:         "DISKANN",
   598  				IdxType:         entity.DISKANN,
   599  				ConstructParams: []idxParam{},
   600  				SearchParams: []idxParam{
   601  					{
   602  						Name:           "search_list",
   603  						ValidationRule: "[1, 65535]",
   604  					},
   605  				},
   606  				ValidExamples: []string{
   607  					"",
   608  				},
   609  				InvalidExamples: []string{},
   610  				ValidSearchParams: []string{
   611  					"search_list = 30",
   612  				},
   613  				InvalidSearchParams: []string{
   614  					"search_list = 0",
   615  					"search_list = 65537",
   616  				},
   617  			},
   618  			{
   619  				IdxName:         "AUTOINDEX",
   620  				IdxType:         entity.AUTOINDEX,
   621  				ConstructParams: []idxParam{},
   622  				SearchParams: []idxParam{
   623  					{
   624  						Name:           "level",
   625  						ValidationRule: "[1, 9223372036854775807]",
   626  					},
   627  				},
   628  				ValidExamples: []string{
   629  					"",
   630  				},
   631  				InvalidExamples: []string{},
   632  				ValidSearchParams: []string{
   633  					"level = 1",
   634  				},
   635  				InvalidSearchParams: []string{
   636  					"level = 0",
   637  					"level = -1",
   638  				},
   639  			},
   640  			{
   641  				IdxName: "GPUIvfFlat",
   642  				IdxType: entity.GPUIvfFlat,
   643  				ConstructParams: []idxParam{
   644  					{
   645  						Name:           "nlist",
   646  						ValidationRule: "[1, 65536]",
   647  					},
   648  				},
   649  				SearchParams: []idxParam{
   650  					{
   651  						Name:           "nprobe",
   652  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   653  					},
   654  				},
   655  				ValidExamples: []string{
   656  					"nlist = 10",
   657  				},
   658  				InvalidExamples: []string{
   659  					"nlist = 0",
   660  					"nlist = 65537",
   661  				},
   662  				ValidSearchParams: []string{
   663  					"nprobe = 10",
   664  				},
   665  				InvalidSearchParams: []string{
   666  					"nprobe = 0",
   667  					"nprobe = 65537",
   668  				},
   669  			},
   670  			{
   671  				IdxName: "GPUIvfPQ",
   672  				IdxType: entity.GPUIvfPQ,
   673  				ConstructParams: []idxParam{
   674  					{
   675  						Name:           "nlist",
   676  						ValidationRule: "[1, 65536]",
   677  					},
   678  					{
   679  						Name:           "m",
   680  						ValidationRule: "dim===0 (mod self)",
   681  					},
   682  					{
   683  						Name:           "nbits",
   684  						ValidationRule: "[1, 64]",
   685  					},
   686  				},
   687  				SearchParams: []idxParam{
   688  					{
   689  						Name:           "nprobe",
   690  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   691  					},
   692  				},
   693  				ValidExamples: []string{
   694  					"nlist, m, nbits = 10, 8, 8",
   695  				},
   696  				InvalidExamples: []string{
   697  					"nlist, m, nbits = 0, 8, 8",
   698  					"nlist, m, nbits = 65537, 8, 8",
   699  					"nlist, m, nbits = 10, 8, 0",
   700  					"nlist, m, nbits = 10, 8, 65",
   701  				},
   702  				ValidSearchParams: []string{
   703  					"nprobe = 10",
   704  				},
   705  				InvalidSearchParams: []string{
   706  					"nprobe = 0",
   707  					"nprobe = 65537",
   708  				},
   709  			},
   710  			{
   711  				IdxName: "SCANN",
   712  				IdxType: entity.SCANN,
   713  				ConstructParams: []idxParam{
   714  					{
   715  						Name:           "nlist",
   716  						ValidationRule: "[1, 65536]",
   717  					},
   718  					{
   719  						Name:           "with_raw_data",
   720  						Type:           "bool",
   721  						ValidationRule: "in (false, true)",
   722  					},
   723  				},
   724  				SearchParams: []idxParam{
   725  					{
   726  						Name:           "nprobe",
   727  						ValidationRule: "[1, 65536]", // [1, nlist], refer to index construct param, not supported yet
   728  					},
   729  					{
   730  						Name:           "reorder_k",
   731  						ValidationRule: "[1, 9223372036854775807]", // [topk, MAX_INT], refer to index construct param, not supported yet
   732  					},
   733  				},
   734  				ValidExamples: []string{
   735  					"nlist = 100",
   736  					"with_raw_data = true",
   737  				},
   738  				InvalidExamples: []string{
   739  					"nlist = 0",
   740  					"nlist = 65537",
   741  				},
   742  				ValidSearchParams: []string{
   743  					"nprobe, reorder_k = 10, 200",
   744  				},
   745  				InvalidSearchParams: []string{
   746  					"nprobe, reorder_k = 0, 200",
   747  					"nprobe, reorder_k = 65537, 200",
   748  					"nprobe, reorder_k = 10, -1",
   749  				},
   750  			},
   751  		},
   752  	}
   753  
   754  	indexTemplate.Execute(f, settings)
   755  	indexTestTemplate.Execute(ft, settings)
   756  	indexSearchParamTemplate.Execute(fp, settings)
   757  	indexSearchParamTestTemplate.Execute(fpt, settings)
   758  }