diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d9291573..d700a6ee22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,14 @@ Please mark all change in change log and use the ticket from JIRA. - \#246 - Exclude src/external folder from code coverage for jenkin ci - \#248 - Reside src/external in thirdparty - \#316 - Some files not merged after vectors added +- \#327 - Search does not use GPU when index type is FLAT +- \#340 - Test cases run failed on 0.6.0 +- \#374 - sdk_simple return empty result ## Feature - \#12 - Pure CPU version for Milvus - \#77 - Support table partition +- \#127 - Support new Index type IVFPQ - \#226 - Experimental shards middleware for Milvus - \#346 - Support build index with multiple gpu @@ -21,7 +25,8 @@ Please mark all change in change log and use the ticket from JIRA. - \#260 - C++ SDK README - \#314 - add Find FAISS in CMake - \#310 - Add Q&A for 'protocol https not supported or disable in libcurl' issue -- \#322 - Add option to enable / disable prometheus +- \#322 - Add option to enable / disable prometheus +- \#358 - Add more information in build.sh and install.md ## Task diff --git a/ci/jenkins/Jenkinsfile b/ci/jenkins/Jenkinsfile index 40d9686415..f0562ada64 100644 --- a/ci/jenkins/Jenkinsfile +++ b/ci/jenkins/Jenkinsfile @@ -33,128 +33,267 @@ pipeline { } stages { - stage("Ubuntu 18.04") { + stage("Ubuntu 18.04 x86_64") { environment { OS_NAME = "ubuntu18.04" - PACKAGE_VERSION = VersionNumber([ - versionNumberString : '${SEMVER}-${LOWER_BUILD_TYPE}-ubuntu18.04-x86_64-${BUILD_DATE_FORMATTED, "yyyyMMdd"}-${BUILDS_TODAY}' - ]); - DOCKER_VERSION = "${SEMVER}-${OS_NAME}-${LOWER_BUILD_TYPE}" + CPU_ARCH = "amd64" } - stages { - stage("Run Build") { - agent { - kubernetes { - label 'build' - defaultContainer 'jnlp' - yamlFile 'ci/jenkins/pod/milvus-build-env-pod.yaml' - } + parallel { + stage ("GPU Version") { + environment { + BINRARY_VERSION = "gpu" + PACKAGE_VERSION = VersionNumber([ + versionNumberString : '${SEMVER}-gpu-${OS_NAME}-${CPU_ARCH}-${LOWER_BUILD_TYPE}-${BUILD_DATE_FORMATTED, "yyyyMMdd"}-${BUILDS_TODAY}' + ]); + DOCKER_VERSION = "${SEMVER}-gpu-${OS_NAME}-${LOWER_BUILD_TYPE}" } stages { - stage('Build') { - steps { - container('milvus-build-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/build.groovy" - } + stage("Run Build") { + agent { + kubernetes { + label "${BINRARY_VERSION}-build" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/milvus-gpu-version-build-env-pod.yaml' } } - } - stage('Code Coverage') { - steps { - container('milvus-build-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/coverage.groovy" + + stages { + stage('Build') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/build.groovy" + } + } } } - } - } - stage('Upload Package') { - steps { - container('milvus-build-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/package.groovy" + stage('Code Coverage') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/coverage.groovy" + } + } } } - } - } - } - } - - stage("Publish docker images") { - agent { - kubernetes { - label 'publish' - defaultContainer 'jnlp' - yamlFile 'ci/jenkins/pod/docker-pod.yaml' - } - } - - stages { - stage('Publish') { - steps { - container('publish-images'){ - script { - load "${env.WORKSPACE}/ci/jenkins/step/publishImages.groovy" - } - } - } - } - } - } - - stage("Deploy to Development") { - agent { - kubernetes { - label 'dev-test' - defaultContainer 'jnlp' - yamlFile 'ci/jenkins/pod/testEnvironment.yaml' - } - } - - stages { - stage("Deploy to Dev") { - steps { - container('milvus-test-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/deploySingle2Dev.groovy" - } - } - } - } - - stage("Dev Test") { - steps { - container('milvus-test-env') { - script { - boolean isNightlyTest = isTimeTriggeredBuild() - if (isNightlyTest) { - load "${env.WORKSPACE}/ci/jenkins/step/singleDevNightlyTest.groovy" - } else { - load "${env.WORKSPACE}/ci/jenkins/step/singleDevTest.groovy" + stage('Upload Package') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/package.groovy" + } } } } } } - stage ("Cleanup Dev") { - steps { - container('milvus-test-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + stage("Publish docker images") { + agent { + kubernetes { + label "${BINRARY_VERSION}-publish" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/docker-pod.yaml' + } + } + + stages { + stage('Publish') { + steps { + container('publish-images'){ + script { + load "${env.WORKSPACE}/ci/jenkins/step/publishImages.groovy" + } + } + } + } + } + } + + stage("Deploy to Development") { + agent { + kubernetes { + label "${BINRARY_VERSION}-dev-test" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/testEnvironment.yaml' + } + } + + stages { + stage("Deploy to Dev") { + steps { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/deploySingle2Dev.groovy" + } + } + } + } + + stage("Dev Test") { + steps { + container('milvus-test-env') { + script { + boolean isNightlyTest = isTimeTriggeredBuild() + if (isNightlyTest) { + load "${env.WORKSPACE}/ci/jenkins/step/singleDevNightlyTest.groovy" + } else { + load "${env.WORKSPACE}/ci/jenkins/step/singleDevTest.groovy" + } + } + } + } + } + + stage ("Cleanup Dev") { + steps { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + } + } + } + } + } + post { + unsuccessful { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + } } } } } } - post { - unsuccessful { - container('milvus-test-env') { - script { - load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + } + + stage ("CPU Version") { + environment { + BINRARY_VERSION = "cpu" + PACKAGE_VERSION = VersionNumber([ + versionNumberString : '${SEMVER}-cpu-${OS_NAME}-${CPU_ARCH}-${LOWER_BUILD_TYPE}-${BUILD_DATE_FORMATTED, "yyyyMMdd"}-${BUILDS_TODAY}' + ]); + DOCKER_VERSION = "${SEMVER}-cpu-${OS_NAME}-${LOWER_BUILD_TYPE}" + } + + stages { + stage("Run Build") { + agent { + kubernetes { + label "${BINRARY_VERSION}-build" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/milvus-cpu-version-build-env-pod.yaml' + } + } + + stages { + stage('Build') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/build.groovy" + } + } + } + } + stage('Code Coverage') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/coverage.groovy" + } + } + } + } + stage('Upload Package') { + steps { + container('milvus-build-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/package.groovy" + } + } + } + } + } + } + + stage("Publish docker images") { + agent { + kubernetes { + label "${BINRARY_VERSION}-publish" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/docker-pod.yaml' + } + } + + stages { + stage('Publish') { + steps { + container('publish-images'){ + script { + load "${env.WORKSPACE}/ci/jenkins/step/publishImages.groovy" + } + } + } + } + } + } + + stage("Deploy to Development") { + agent { + kubernetes { + label "${BINRARY_VERSION}-dev-test" + defaultContainer 'jnlp' + yamlFile 'ci/jenkins/pod/testEnvironment.yaml' + } + } + + stages { + stage("Deploy to Dev") { + steps { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/deploySingle2Dev.groovy" + } + } + } + } + + stage("Dev Test") { + steps { + container('milvus-test-env') { + script { + boolean isNightlyTest = isTimeTriggeredBuild() + if (isNightlyTest) { + load "${env.WORKSPACE}/ci/jenkins/step/singleDevNightlyTest.groovy" + } else { + load "${env.WORKSPACE}/ci/jenkins/step/singleDevTest.groovy" + } + } + } + } + } + + stage ("Cleanup Dev") { + steps { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + } + } + } + } + } + post { + unsuccessful { + container('milvus-test-env') { + script { + load "${env.WORKSPACE}/ci/jenkins/step/cleanupSingleDev.groovy" + } + } } } } diff --git a/ci/jenkins/pod/milvus-cpu-version-build-env-pod.yaml b/ci/jenkins/pod/milvus-cpu-version-build-env-pod.yaml new file mode 100644 index 0000000000..561bfe8140 --- /dev/null +++ b/ci/jenkins/pod/milvus-cpu-version-build-env-pod.yaml @@ -0,0 +1,34 @@ +apiVersion: v1 +kind: Pod +metadata: + name: milvus-cpu-build-env + labels: + app: milvus + componet: cpu-build-env +spec: + containers: + - name: milvus-build-env + image: registry.zilliz.com/milvus/milvus-cpu-build-env:v0.6.0-ubuntu18.04 + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + command: + - cat + tty: true + resources: + limits: + memory: "32Gi" + cpu: "8.0" + requests: + memory: "16Gi" + cpu: "4.0" + - name: milvus-mysql + image: mysql:5.6 + env: + - name: MYSQL_ROOT_PASSWORD + value: 123456 + ports: + - containerPort: 3306 + name: mysql diff --git a/ci/jenkins/pod/milvus-build-env-pod.yaml b/ci/jenkins/pod/milvus-gpu-version-build-env-pod.yaml similarity index 80% rename from ci/jenkins/pod/milvus-build-env-pod.yaml rename to ci/jenkins/pod/milvus-gpu-version-build-env-pod.yaml index da938d8ba2..422dd72ab2 100644 --- a/ci/jenkins/pod/milvus-build-env-pod.yaml +++ b/ci/jenkins/pod/milvus-gpu-version-build-env-pod.yaml @@ -1,14 +1,14 @@ apiVersion: v1 kind: Pod metadata: - name: milvus-build-env + name: milvus-gpu-build-env labels: app: milvus - componet: build-env + componet: gpu-build-env spec: containers: - name: milvus-build-env - image: registry.zilliz.com/milvus/milvus-build-env:v0.5.1-ubuntu18.04 + image: registry.zilliz.com/milvus/milvus-gpu-build-env:v0.6.0-ubuntu18.04 env: - name: POD_IP valueFrom: diff --git a/ci/jenkins/step/build.groovy b/ci/jenkins/step/build.groovy index bae4259a6f..6c1da64a82 100644 --- a/ci/jenkins/step/build.groovy +++ b/ci/jenkins/step/build.groovy @@ -1,8 +1,11 @@ timeout(time: 60, unit: 'MINUTES') { dir ("ci/scripts") { withCredentials([usernamePassword(credentialsId: "${params.JFROG_CREDENTIALS_ID}", usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { - sh "export JFROG_ARTFACTORY_URL='${params.JFROG_ARTFACTORY_URL}' && export JFROG_USER_NAME='${USERNAME}' && export JFROG_PASSWORD='${PASSWORD}' && ./build.sh -t ${params.BUILD_TYPE} -o /opt/milvus -l -g -j -u -c" + if ("${env.BINRARY_VERSION}" == "gpu") { + sh "export JFROG_ARTFACTORY_URL='${params.JFROG_ARTFACTORY_URL}' && export JFROG_USER_NAME='${USERNAME}' && export JFROG_PASSWORD='${PASSWORD}' && ./build.sh -t ${params.BUILD_TYPE} -o /opt/milvus -l -g -j -u -c" + } else { + sh "export JFROG_ARTFACTORY_URL='${params.JFROG_ARTFACTORY_URL}' && export JFROG_USER_NAME='${USERNAME}' && export JFROG_PASSWORD='${PASSWORD}' && ./build.sh -t ${params.BUILD_TYPE} -o /opt/milvus -l -m -j -u -c" + } } } } - diff --git a/ci/jenkins/step/cleanupSingleDev.groovy b/ci/jenkins/step/cleanupSingleDev.groovy index 3b8c1833b5..30325e0c91 100644 --- a/ci/jenkins/step/cleanupSingleDev.groovy +++ b/ci/jenkins/step/cleanupSingleDev.groovy @@ -1,12 +1,12 @@ try { - def helmResult = sh script: "helm status ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu", returnStatus: true + def helmResult = sh script: "helm status ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}", returnStatus: true if (!helmResult) { - sh "helm del --purge ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu" + sh "helm del --purge ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}" } } catch (exc) { - def helmResult = sh script: "helm status ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu", returnStatus: true + def helmResult = sh script: "helm status ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}", returnStatus: true if (!helmResult) { - sh "helm del --purge ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu" + sh "helm del --purge ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}" } throw exc } diff --git a/ci/jenkins/step/deploySingle2Dev.groovy b/ci/jenkins/step/deploySingle2Dev.groovy index f4964df5e2..f1daaf22ec 100644 --- a/ci/jenkins/step/deploySingle2Dev.groovy +++ b/ci/jenkins/step/deploySingle2Dev.groovy @@ -1,9 +1,13 @@ sh 'helm init --client-only --skip-refresh --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts' sh 'helm repo update' dir ('milvus-helm') { - checkout([$class: 'GitSCM', branches: [[name: "0.5.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.5.0:refs/remotes/origin/0.5.0"]]]) - dir ("milvus-gpu") { - sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu -f ci/db_backend/sqlite_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + checkout([$class: 'GitSCM', branches: [[name: "0.6.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.6.0:refs/remotes/origin/0.6.0"]]]) + dir ("milvus") { + if ("${env.BINRARY_VERSION}" == "gpu") { + sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f gpu_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + } else { + sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f ci/filebeat/values.yaml --namespace milvus ." + } } } diff --git a/ci/jenkins/step/publishImages.groovy b/ci/jenkins/step/publishImages.groovy index 62df0c73bf..72e9924c62 100644 --- a/ci/jenkins/step/publishImages.groovy +++ b/ci/jenkins/step/publishImages.groovy @@ -1,6 +1,6 @@ container('publish-images') { timeout(time: 15, unit: 'MINUTES') { - dir ("docker/deploy/${OS_NAME}") { + dir ("docker/deploy/${env.BINRARY_VERSION}/${env.OS_NAME}") { def binaryPackage = "${PROJECT_NAME}-${PACKAGE_VERSION}.tar.gz" withCredentials([usernamePassword(credentialsId: "${params.JFROG_CREDENTIALS_ID}", usernameVariable: 'JFROG_USERNAME', passwordVariable: 'JFROG_PASSWORD')]) { diff --git a/ci/jenkins/step/singleDevNightlyTest.groovy b/ci/jenkins/step/singleDevNightlyTest.groovy index 9aeab2eb4e..d357badfd3 100644 --- a/ci/jenkins/step/singleDevNightlyTest.groovy +++ b/ci/jenkins/step/singleDevNightlyTest.groovy @@ -1,22 +1,26 @@ timeout(time: 90, unit: 'MINUTES') { dir ("tests/milvus_python_test") { sh 'python3 -m pip install -r requirements.txt' - sh "pytest . --alluredir=\"test_out/dev/single/sqlite\" --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu-milvus-gpu-engine.milvus.svc.cluster.local" + sh "pytest . --alluredir=\"test_out/dev/single/sqlite\" --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}-milvus-engine.milvus.svc.cluster.local" } // mysql database backend test load "${env.WORKSPACE}/ci/jenkins/jenkinsfile/cleanupSingleDev.groovy" if (!fileExists('milvus-helm')) { dir ("milvus-helm") { - checkout([$class: 'GitSCM', branches: [[name: "0.5.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.5.0:refs/remotes/origin/0.5.0"]]]) + checkout([$class: 'GitSCM', branches: [[name: "0.6.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.6.0:refs/remotes/origin/0.6.0"]]]) } } dir ("milvus-helm") { - dir ("milvus-gpu") { - sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + dir ("milvus") { + if ("${env.BINRARY_VERSION}" == "gpu") { + sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f gpu_values.yaml -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + } else { + sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + } } } dir ("tests/milvus_python_test") { - sh "pytest . --alluredir=\"test_out/dev/single/mysql\" --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu-milvus-gpu-engine.milvus.svc.cluster.local" + sh "pytest . --alluredir=\"test_out/dev/single/mysql\" --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}-milvus-engine.milvus.svc.cluster.local" } } diff --git a/ci/jenkins/step/singleDevTest.groovy b/ci/jenkins/step/singleDevTest.groovy index 86e6f126d9..c1de5907b0 100644 --- a/ci/jenkins/step/singleDevTest.groovy +++ b/ci/jenkins/step/singleDevTest.groovy @@ -1,24 +1,27 @@ timeout(time: 60, unit: 'MINUTES') { dir ("tests/milvus_python_test") { sh 'python3 -m pip install -r requirements.txt' - sh "pytest . --alluredir=\"test_out/dev/single/sqlite\" --level=1 --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu-milvus-gpu-engine.milvus.svc.cluster.local" + sh "pytest . --alluredir=\"test_out/dev/single/sqlite\" --level=1 --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}-milvus-engine.milvus.svc.cluster.local" } + // mysql database backend test // load "${env.WORKSPACE}/ci/jenkins/jenkinsfile/cleanupSingleDev.groovy" - // Remove mysql-version tests: 10-28 - // if (!fileExists('milvus-helm')) { // dir ("milvus-helm") { - // checkout([$class: 'GitSCM', branches: [[name: "0.5.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.5.0:refs/remotes/origin/0.5.0"]]]) + // checkout([$class: 'GitSCM', branches: [[name: "0.6.0"]], userRemoteConfigs: [[url: "https://github.com/milvus-io/milvus-helm.git", name: 'origin', refspec: "+refs/heads/0.6.0:refs/remotes/origin/0.6.0"]]]) // } // } // dir ("milvus-helm") { - // dir ("milvus-gpu") { - // sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + // dir ("milvus") { + // if ("${env.BINRARY_VERSION}" == "gpu") { + // sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f gpu_values.yaml -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + // } else { + // sh "helm install --wait --timeout 300 --set engine.image.tag=${DOCKER_VERSION} --set expose.type=clusterIP --name ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION} -f ci/db_backend/mysql_values.yaml -f ci/filebeat/values.yaml --namespace milvus ." + // } // } // } // dir ("tests/milvus_python_test") { - // sh "pytest . --alluredir=\"test_out/dev/single/mysql\" --level=1 --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-gpu-milvus-gpu-engine.milvus.svc.cluster.local" + // sh "pytest . --alluredir=\"test_out/dev/single/mysql\" --level=1 --ip ${env.PIPELINE_NAME}-${env.BUILD_NUMBER}-single-${env.BINRARY_VERSION}-milvus-engine.milvus.svc.cluster.local" // } } diff --git a/core/build.sh b/core/build.sh index 85dea0ab88..3afb5d1b37 100755 --- a/core/build.sh +++ b/core/build.sh @@ -18,64 +18,65 @@ FAISS_ROOT="" #FAISS root path FAISS_SOURCE="BUNDLED" WITH_PROMETHEUS="ON" -while getopts "p:d:t:f:ulrcgjhxzme" arg -do - case $arg in - p) - INSTALL_PREFIX=$OPTARG - ;; - d) - DB_PATH=$OPTARG - ;; - t) - BUILD_TYPE=$OPTARG # BUILD_TYPE - ;; - f) - FAISS_ROOT=$OPTARG - FAISS_SOURCE="AUTO" - ;; - u) - echo "Build and run unittest cases" ; - BUILD_UNITTEST="ON"; - ;; - l) - RUN_CPPLINT="ON" - ;; - r) - if [[ -d ${BUILD_OUTPUT_DIR} ]]; then - rm ./${BUILD_OUTPUT_DIR} -r - MAKE_CLEAN="ON" - fi - ;; - c) - BUILD_COVERAGE="ON" - ;; - z) - PROFILING="ON" - ;; - j) - USE_JFROG_CACHE="ON" - ;; - x) - CUSTOMIZATION="OFF" # force use ori faiss - ;; - g) - GPU_VERSION="ON" - ;; - m) - WITH_MKL="ON" - ;; - e) - WITH_PROMETHEUS="OFF" - ;; - h) # help - echo " +while getopts "p:d:t:f:ulrcgjhxzme" arg; do + case $arg in + p) + INSTALL_PREFIX=$OPTARG + ;; + d) + DB_PATH=$OPTARG + ;; + t) + BUILD_TYPE=$OPTARG # BUILD_TYPE + ;; + f) + FAISS_ROOT=$OPTARG + FAISS_SOURCE="AUTO" + ;; + u) + echo "Build and run unittest cases" + BUILD_UNITTEST="ON" + ;; + l) + RUN_CPPLINT="ON" + ;; + r) + if [[ -d ${BUILD_OUTPUT_DIR} ]]; then + rm ./${BUILD_OUTPUT_DIR} -r + MAKE_CLEAN="ON" + fi + ;; + c) + BUILD_COVERAGE="ON" + ;; + z) + PROFILING="ON" + ;; + j) + USE_JFROG_CACHE="ON" + ;; + x) + CUSTOMIZATION="OFF" # force use ori faiss + ;; + g) + GPU_VERSION="ON" + ;; + m) + WITH_MKL="ON" + ;; + e) + WITH_PROMETHEUS="OFF" + ;; + h) # help + echo " parameter: -p: install prefix(default: $(pwd)/milvus) -d: db data path(default: /tmp/milvus) -t: build type(default: Debug) --f: faiss root path(default: empty) +-f: FAISS root path(default: empty). The path should be an absolute path + containing the pre-installed lib/ and include/ directory of FAISS. If they can't be found, + we will build the original FAISS from source instead. -u: building unit test options(default: OFF) -l: run cpplint, clang-format and clang-tidy(default: OFF) -r: remove previous build directory(default: OFF) @@ -84,30 +85,30 @@ parameter: -j: use jfrog cache build directory(default: OFF) -g: build GPU version(default: OFF) -m: build with MKL(default: OFF) --e: build without prometheus +-e: build without prometheus(default: OFF) -h: help usage: ./build.sh -p \${INSTALL_PREFIX} -t \${BUILD_TYPE} -f \${FAISS_ROOT} [-u] [-l] [-r] [-c] [-z] [-j] [-g] [-m] [-e] [-h] " - exit 0 - ;; - ?) - echo "ERROR! unknown argument" - exit 1 - ;; - esac + exit 0 + ;; + ?) + echo "ERROR! unknown argument" + exit 1 + ;; + esac done if [[ ! -d ${BUILD_OUTPUT_DIR} ]]; then - mkdir ${BUILD_OUTPUT_DIR} + mkdir ${BUILD_OUTPUT_DIR} fi cd ${BUILD_OUTPUT_DIR} # remove make cache since build.sh -l use default variables # force update the variables each time -make rebuild_cache > /dev/null 2>&1 +make rebuild_cache >/dev/null 2>&1 CMAKE_CMD="cmake \ -DBUILD_UNIT_TEST=${BUILD_UNITTEST} \ @@ -129,25 +130,25 @@ echo ${CMAKE_CMD} ${CMAKE_CMD} if [[ ${MAKE_CLEAN} == "ON" ]]; then - make clean + make clean fi if [[ ${RUN_CPPLINT} == "ON" ]]; then - # cpplint check - make lint - if [ $? -ne 0 ]; then - echo "ERROR! cpplint check failed" - exit 1 - fi - echo "cpplint check passed!" + # cpplint check + make lint + if [ $? -ne 0 ]; then + echo "ERROR! cpplint check failed" + exit 1 + fi + echo "cpplint check passed!" - # clang-format check - make check-clang-format - if [ $? -ne 0 ]; then - echo "ERROR! clang-format check failed" - exit 1 - fi - echo "clang-format check passed!" + # clang-format check + make check-clang-format + if [ $? -ne 0 ]; then + echo "ERROR! clang-format check failed" + exit 1 + fi + echo "clang-format check passed!" # # clang-tidy check # make check-clang-tidy @@ -158,11 +159,11 @@ if [[ ${RUN_CPPLINT} == "ON" ]]; then # echo "clang-tidy check passed!" else - # strip binary symbol - if [[ ${BUILD_TYPE} != "Debug" ]]; then - strip src/milvus_server - fi + # strip binary symbol + if [[ ${BUILD_TYPE} != "Debug" ]]; then + strip src/milvus_server + fi - # compile and build - make -j 8 install || exit 1 + # compile and build + make -j 8 install || exit 1 fi diff --git a/core/src/db/DBImpl.cpp b/core/src/db/DBImpl.cpp index d688c88ff2..2559b3a46b 100644 --- a/core/src/db/DBImpl.cpp +++ b/core/src/db/DBImpl.cpp @@ -179,9 +179,10 @@ DBImpl::PreloadTable(const std::string& table_id) { } // get all table files from parent table + meta::DatesT dates; std::vector ids; meta::TableFilesSchema files_array; - auto status = GetFilesToSearch(table_id, ids, files_array); + auto status = GetFilesToSearch(table_id, ids, dates, files_array); if (!status.ok()) { return status; } @@ -190,7 +191,7 @@ DBImpl::PreloadTable(const std::string& table_id) { std::vector partiton_array; status = meta_ptr_->ShowPartitions(table_id, partiton_array); for (auto& schema : partiton_array) { - status = GetFilesToSearch(schema.table_id_, ids, files_array); + status = GetFilesToSearch(schema.table_id_, ids, dates, files_array); } int64_t size = 0; @@ -304,6 +305,10 @@ DBImpl::InsertVectors(const std::string& table_id, const std::string& partition_ if (!partition_tag.empty()) { std::string partition_name; status = meta_ptr_->GetPartitionName(table_id, partition_tag, target_table_name); + if (!status.ok()) { + ENGINE_LOG_ERROR << status.message(); + return status; + } } // insert vectors into target table @@ -400,7 +405,7 @@ DBImpl::Query(const std::string& table_id, const std::vector& parti if (partition_tags.empty()) { // no partition tag specified, means search in whole table // get all table files from parent table - status = GetFilesToSearch(table_id, ids, files_array); + status = GetFilesToSearch(table_id, ids, dates, files_array); if (!status.ok()) { return status; } @@ -408,7 +413,7 @@ DBImpl::Query(const std::string& table_id, const std::vector& parti std::vector partiton_array; status = meta_ptr_->ShowPartitions(table_id, partiton_array); for (auto& schema : partiton_array) { - status = GetFilesToSearch(schema.table_id_, ids, files_array); + status = GetFilesToSearch(schema.table_id_, ids, dates, files_array); } } else { // get files from specified partitions @@ -416,7 +421,7 @@ DBImpl::Query(const std::string& table_id, const std::vector& parti GetPartitionsByTags(table_id, partition_tags, partition_name_array); for (auto& partition_name : partition_name_array) { - status = GetFilesToSearch(partition_name, ids, files_array); + status = GetFilesToSearch(partition_name, ids, dates, files_array); } } @@ -446,7 +451,7 @@ DBImpl::QueryByFileID(const std::string& table_id, const std::vector& file_ids, +DBImpl::GetFilesToSearch(const std::string& table_id, const std::vector& file_ids, const meta::DatesT& dates, meta::TableFilesSchema& files) { - meta::DatesT dates; meta::DatePartionedTableFilesSchema date_files; auto status = meta_ptr_->FilesToSearch(table_id, file_ids, dates, date_files); if (!status.ok()) { diff --git a/core/src/db/DBImpl.h b/core/src/db/DBImpl.h index 932fc990e4..a0c5cc356d 100644 --- a/core/src/db/DBImpl.h +++ b/core/src/db/DBImpl.h @@ -153,7 +153,8 @@ class DBImpl : public DB { MemSerialize(); Status - GetFilesToSearch(const std::string& table_id, const std::vector& file_ids, meta::TableFilesSchema& files); + GetFilesToSearch(const std::string& table_id, const std::vector& file_ids, const meta::DatesT& dates, + meta::TableFilesSchema& files); Status GetPartitionsByTags(const std::string& table_id, const std::vector& partition_tags, diff --git a/core/src/db/engine/ExecutionEngine.h b/core/src/db/engine/ExecutionEngine.h index 51c77eb78e..86a014cf66 100644 --- a/core/src/db/engine/ExecutionEngine.h +++ b/core/src/db/engine/ExecutionEngine.h @@ -26,6 +26,7 @@ namespace milvus { namespace engine { +// TODO(linxj): replace with VecIndex::IndexType enum class EngineType { INVALID = 0, FAISS_IDMAP = 1, @@ -33,7 +34,8 @@ enum class EngineType { FAISS_IVFSQ8, NSG_MIX, FAISS_IVFSQ8H, - MAX_VALUE = FAISS_IVFSQ8H, + FAISS_PQ, + MAX_VALUE = FAISS_PQ, }; enum class MetricType { diff --git a/core/src/db/engine/ExecutionEngineImpl.cpp b/core/src/db/engine/ExecutionEngineImpl.cpp index dd80ec796b..f52ac6d4d2 100644 --- a/core/src/db/engine/ExecutionEngineImpl.cpp +++ b/core/src/db/engine/ExecutionEngineImpl.cpp @@ -116,6 +116,14 @@ ExecutionEngineImpl::CreatetVecIndex(EngineType type) { index = GetVecIndexFactory(IndexType::FAISS_IVFSQ8_HYBRID); break; } + case EngineType::FAISS_PQ: { +#ifdef MILVUS_CPU_VERSION + index = GetVecIndexFactory(IndexType::FAISS_IVFPQ_CPU); +#else + index = GetVecIndexFactory(IndexType::FAISS_IVFPQ_MIX); +#endif + break; + } default: { ENGINE_LOG_ERROR << "Unsupported index type"; return nullptr; diff --git a/core/src/grpc/gen-milvus/milvus.pb.h b/core/src/grpc/gen-milvus/milvus.pb.h index 53ed2db22e..536365b23b 100644 --- a/core/src/grpc/gen-milvus/milvus.pb.h +++ b/core/src/grpc/gen-milvus/milvus.pb.h @@ -1321,7 +1321,8 @@ class RowRecord : void clear_vector_data(); float vector_data(int index) const; void set_vector_data(int index, float value); - void add_vector_data(float value); +// void add_vector_data(float value); + void add_vector_data(std::vector::const_iterator begin, std::vector::const_iterator end); const ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >& vector_data() const; ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >* @@ -1473,7 +1474,9 @@ class InsertParam : void clear_row_id_array(); ::PROTOBUF_NAMESPACE_ID::int64 row_id_array(int index) const; void set_row_id_array(int index, ::PROTOBUF_NAMESPACE_ID::int64 value); - void add_row_id_array(::PROTOBUF_NAMESPACE_ID::int64 value); +// void add_row_id_array(::PROTOBUF_NAMESPACE_ID::int64 value); + void add_row_id_array(std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator begin, + std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator end); const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >& row_id_array() const; ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >* @@ -2136,7 +2139,9 @@ class TopKQueryResult : void clear_ids(); ::PROTOBUF_NAMESPACE_ID::int64 ids(int index) const; void set_ids(int index, ::PROTOBUF_NAMESPACE_ID::int64 value); - void add_ids(::PROTOBUF_NAMESPACE_ID::int64 value); +// void add_ids(::PROTOBUF_NAMESPACE_ID::int64 value); + void add_ids(std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator begin, + std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator end); const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >& ids() const; ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >* @@ -2147,7 +2152,8 @@ class TopKQueryResult : void clear_distances(); float distances(int index) const; void set_distances(int index, float value); - void add_distances(float value); +// void add_distances(float value); + void add_distances(std::vector::const_iterator begin, std::vector::const_iterator end); const ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >& distances() const; ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >* @@ -3922,9 +3928,14 @@ inline void RowRecord::set_vector_data(int index, float value) { vector_data_.Set(index, value); // @@protoc_insertion_point(field_set:milvus.grpc.RowRecord.vector_data) } -inline void RowRecord::add_vector_data(float value) { - vector_data_.Add(value); - // @@protoc_insertion_point(field_add:milvus.grpc.RowRecord.vector_data) +//inline void RowRecord::add_vector_data(float value) { +// vector_data_.Add(value); +// // @@protoc_insertion_point(field_add:milvus.grpc.RowRecord.vector_data) +//} +inline void RowRecord::add_vector_data(std::vector::const_iterator begin, + std::vector::const_iterator end) { + vector_data_.Add(begin, end); + // @@protoc_insertion_point(field_add:milvus.grpc.RowRecord.vector_data) } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >& RowRecord::vector_data() const { @@ -4037,9 +4048,14 @@ inline void InsertParam::set_row_id_array(int index, ::PROTOBUF_NAMESPACE_ID::in row_id_array_.Set(index, value); // @@protoc_insertion_point(field_set:milvus.grpc.InsertParam.row_id_array) } -inline void InsertParam::add_row_id_array(::PROTOBUF_NAMESPACE_ID::int64 value) { - row_id_array_.Add(value); - // @@protoc_insertion_point(field_add:milvus.grpc.InsertParam.row_id_array) +//inline void InsertParam::add_row_id_array(::PROTOBUF_NAMESPACE_ID::int64 value) { +// row_id_array_.Add(value); +// // @@protoc_insertion_point(field_add:milvus.grpc.InsertParam.row_id_array) +//} +inline void InsertParam::add_row_id_array(std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator begin, + std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator end) { + row_id_array_.Add(begin, end); + // @@protoc_insertion_point(field_add:milvus.grpc.InsertParam.row_id_array) } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >& InsertParam::row_id_array() const { @@ -4588,9 +4604,14 @@ inline void TopKQueryResult::set_ids(int index, ::PROTOBUF_NAMESPACE_ID::int64 v ids_.Set(index, value); // @@protoc_insertion_point(field_set:milvus.grpc.TopKQueryResult.ids) } -inline void TopKQueryResult::add_ids(::PROTOBUF_NAMESPACE_ID::int64 value) { - ids_.Add(value); - // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.ids) +//inline void TopKQueryResult::add_ids(::PROTOBUF_NAMESPACE_ID::int64 value) { +// ids_.Add(value); +// // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.ids) +//} +inline void TopKQueryResult::add_ids(std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator begin, + std::vector<::PROTOBUF_NAMESPACE_ID::int64>::const_iterator end) { + ids_.Add(begin,end); + // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.ids) } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< ::PROTOBUF_NAMESPACE_ID::int64 >& TopKQueryResult::ids() const { @@ -4618,9 +4639,13 @@ inline void TopKQueryResult::set_distances(int index, float value) { distances_.Set(index, value); // @@protoc_insertion_point(field_set:milvus.grpc.TopKQueryResult.distances) } -inline void TopKQueryResult::add_distances(float value) { - distances_.Add(value); - // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.distances) +//inline void TopKQueryResult::add_distances(float value) { +// distances_.Add(value); +// // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.distances) +//} +inline void TopKQueryResult::add_distances(std::vector::const_iterator begin, std::vector::const_iterator end) { + distances_.Add(begin, end); + // @@protoc_insertion_point(field_add:milvus.grpc.TopKQueryResult.distances) } inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField< float >& TopKQueryResult::distances() const { diff --git a/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.cpp b/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.cpp index b027539c37..cbd4f4f09c 100644 --- a/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.cpp +++ b/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.cpp @@ -39,17 +39,19 @@ GPUIVFPQ::Train(const DatasetPtr& dataset, const Config& config) { GETTENSOR(dataset) - // TODO(linxj): set device here. - // TODO(linxj): set gpu resource here. - faiss::gpu::StandardGpuResources res; - faiss::gpu::GpuIndexIVFPQ device_index(&res, dim, build_cfg->nlist, build_cfg->m, build_cfg->nbits, - GetMetricType(build_cfg->metric_type)); // IP not support - device_index.train(rows, (float*)p_data); - - std::shared_ptr host_index = nullptr; - host_index.reset(faiss::gpu::index_gpu_to_cpu(&device_index)); - - return std::make_shared(host_index); + auto temp_resource = FaissGpuResourceMgr::GetInstance().GetRes(gpu_id_); + if (temp_resource != nullptr) { + ResScope rs(temp_resource, gpu_id_, true); + auto device_index = new faiss::gpu::GpuIndexIVFPQ(temp_resource->faiss_res.get(), dim, build_cfg->nlist, + build_cfg->m, build_cfg->nbits, + GetMetricType(build_cfg->metric_type)); // IP not support + device_index->train(rows, (float*)p_data); + std::shared_ptr host_index = nullptr; + host_index.reset(faiss::gpu::index_gpu_to_cpu(device_index)); + return std::make_shared(host_index); + } else { + KNOWHERE_THROW_MSG("Build IVFSQ can't get gpu resource"); + } } std::shared_ptr @@ -66,7 +68,14 @@ GPUIVFPQ::GenParams(const Config& config) { VectorIndexPtr GPUIVFPQ::CopyGpuToCpu(const Config& config) { - KNOWHERE_THROW_MSG("not support yet"); + std::lock_guard lk(mutex_); + + faiss::Index* device_index = index_.get(); + faiss::Index* host_index = faiss::gpu::index_gpu_to_cpu(device_index); + + std::shared_ptr new_index; + new_index.reset(host_index); + return std::make_shared(new_index); } } // namespace knowhere diff --git a/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.h b/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.h index 13ea1075ca..f699445d65 100644 --- a/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.h +++ b/core/src/index/knowhere/knowhere/index/vector_index/IndexGPUIVFPQ.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include "IndexGPUIVF.h" @@ -28,6 +29,10 @@ class GPUIVFPQ : public GPUIVF { explicit GPUIVFPQ(const int& device_id) : GPUIVF(device_id) { } + GPUIVFPQ(std::shared_ptr index, const int64_t& device_id, ResPtr& resource) + : GPUIVF(std::move(index), device_id, resource) { + } + IndexModelPtr Train(const DatasetPtr& dataset, const Config& config) override; diff --git a/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.cpp b/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.cpp index 03acbf31d7..841ef63245 100644 --- a/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.cpp +++ b/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.cpp @@ -17,11 +17,19 @@ #include #include +#ifdef MILVUS_GPU_VERSION +#include +#endif + #include #include #include "knowhere/adapter/VectorAdapter.h" #include "knowhere/common/Exception.h" +#ifdef MILVUS_GPU_VERSION +#include "knowhere/index/vector_index/IndexGPUIVF.h" +#include "knowhere/index/vector_index/IndexGPUIVFPQ.h" +#endif #include "knowhere/index/vector_index/IndexIVFPQ.h" namespace knowhere { @@ -60,4 +68,22 @@ IVFPQ::Clone_impl(const std::shared_ptr& index) { return std::make_shared(index); } +VectorIndexPtr +IVFPQ::CopyCpuToGpu(const int64_t& device_id, const Config& config) { +#ifdef MILVUS_GPU_VERSION + if (auto res = FaissGpuResourceMgr::GetInstance().GetRes(device_id)) { + ResScope rs(res, device_id, false); + auto gpu_index = faiss::gpu::index_cpu_to_gpu(res->faiss_res.get(), device_id, index_.get()); + + std::shared_ptr device_index; + device_index.reset(gpu_index); + return std::make_shared(device_index, device_id, res); + } else { + KNOWHERE_THROW_MSG("CopyCpuToGpu Error, can't get gpu_resource"); + } +#else + KNOWHERE_THROW_MSG("Calling IVFPQ::CopyCpuToGpu when we are using CPU version"); +#endif +} + } // namespace knowhere diff --git a/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.h b/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.h index 69aaa5090b..fc50c68389 100644 --- a/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.h +++ b/core/src/index/knowhere/knowhere/index/vector_index/IndexIVFPQ.h @@ -34,6 +34,9 @@ class IVFPQ : public IVF { IndexModelPtr Train(const DatasetPtr& dataset, const Config& config) override; + VectorIndexPtr + CopyCpuToGpu(const int64_t& device_id, const Config& config) override; + protected: std::shared_ptr GenParams(const Config& config) override; diff --git a/core/src/index/knowhere/knowhere/index/vector_index/helpers/Cloner.cpp b/core/src/index/knowhere/knowhere/index/vector_index/helpers/Cloner.cpp index 5ff2bfc2e3..363e629eca 100644 --- a/core/src/index/knowhere/knowhere/index/vector_index/helpers/Cloner.cpp +++ b/core/src/index/knowhere/knowhere/index/vector_index/helpers/Cloner.cpp @@ -49,7 +49,7 @@ CopyCpuToGpu(const VectorIndexPtr& index, const int64_t& device_id, const Config if (auto cpu_index = std::dynamic_pointer_cast(index)) { return cpu_index->CopyCpuToGpu(device_id, config); } else if (auto cpu_index = std::dynamic_pointer_cast(index)) { - KNOWHERE_THROW_MSG("IVFPQ not support transfer to gpu"); + return cpu_index->CopyCpuToGpu(device_id, config); } else if (auto cpu_index = std::dynamic_pointer_cast(index)) { return cpu_index->CopyCpuToGpu(device_id, config); } else if (auto cpu_index = std::dynamic_pointer_cast(index)) { diff --git a/core/src/index/unittest/test_ivf.cpp b/core/src/index/unittest/test_ivf.cpp index 5cb820df95..79ef1aa170 100644 --- a/core/src/index/unittest/test_ivf.cpp +++ b/core/src/index/unittest/test_ivf.cpp @@ -213,7 +213,7 @@ TEST_P(IVFTest, clone_test) { { // copy from gpu to cpu - std::vector support_idx_vec{"GPUIVF", "GPUIVFSQ", "IVFSQHybrid"}; + std::vector support_idx_vec{"GPUIVF", "GPUIVFSQ", "GPUIVFPQ", "IVFSQHybrid"}; auto finder = std::find(support_idx_vec.cbegin(), support_idx_vec.cend(), index_type); if (finder != support_idx_vec.cend()) { EXPECT_NO_THROW({ @@ -238,7 +238,7 @@ TEST_P(IVFTest, clone_test) { { // copy to gpu - std::vector support_idx_vec{"IVF", "GPUIVF", "IVFSQ", "GPUIVFSQ"}; + std::vector support_idx_vec{"IVF", "GPUIVF", "IVFSQ", "GPUIVFSQ", "IVFPQ", "GPUIVFPQ"}; auto finder = std::find(support_idx_vec.cbegin(), support_idx_vec.cend(), index_type); if (finder != support_idx_vec.cend()) { EXPECT_NO_THROW({ diff --git a/core/src/scheduler/interface/interfaces.h b/core/src/scheduler/interface/interfaces.h index 9920e4f80a..311560adc6 100644 --- a/core/src/scheduler/interface/interfaces.h +++ b/core/src/scheduler/interface/interfaces.h @@ -33,8 +33,7 @@ namespace milvus { namespace interface { struct dumpable { - virtual ~dumpable() { - } + virtual ~dumpable() = default; virtual json Dump() const = 0; diff --git a/core/src/scheduler/optimizer/BuildIndexPass.cpp b/core/src/scheduler/optimizer/BuildIndexPass.cpp index 725b2509c3..db04c4ac3c 100644 --- a/core/src/scheduler/optimizer/BuildIndexPass.cpp +++ b/core/src/scheduler/optimizer/BuildIndexPass.cpp @@ -34,9 +34,16 @@ BuildIndexPass::Run(const TaskPtr& task) { if (build_gpu_ids_.empty()) return false; - ResourcePtr res_ptr = ResMgrInst::GetInstance()->GetResource(ResourceType::GPU, build_gpu_ids_[specified_gpu_id_]); - auto label = std::make_shared(std::weak_ptr(res_ptr)); - task->label() = label; + ResourcePtr res_ptr; + if (build_gpu_ids_[0] == server::CPU_DEVICE_ID && build_gpu_ids_.size() == 1) { + res_ptr = ResMgrInst::GetInstance()->GetResource("cpu"); + auto label = std::make_shared(std::weak_ptr(res_ptr)); + task->label() = label; + } else { + res_ptr = ResMgrInst::GetInstance()->GetResource(ResourceType::GPU, build_gpu_ids_[specified_gpu_id_]); + auto label = std::make_shared(std::weak_ptr(res_ptr)); + task->label() = label; + } specified_gpu_id_ = (specified_gpu_id_ + 1) % build_gpu_ids_.size(); return true; diff --git a/core/src/scheduler/optimizer/OnlyGPUPass.cpp b/core/src/scheduler/optimizer/OnlyGPUPass.cpp index e867e45159..8afea162a6 100644 --- a/core/src/scheduler/optimizer/OnlyGPUPass.cpp +++ b/core/src/scheduler/optimizer/OnlyGPUPass.cpp @@ -34,7 +34,8 @@ OnlyGPUPass::Run(const TaskPtr& task) { auto search_task = std::static_pointer_cast(task); if (search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IVFSQ8 && - search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IVFFLAT) { + search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IVFFLAT && + search_task->file_->engine_type_ != (int)engine::EngineType::FAISS_IDMAP) { return false; } diff --git a/core/src/sdk/grpc/ClientProxy.cpp b/core/src/sdk/grpc/ClientProxy.cpp index 4ec94cfa98..eaf29e9c69 100644 --- a/core/src/sdk/grpc/ClientProxy.cpp +++ b/core/src/sdk/grpc/ClientProxy.cpp @@ -32,13 +32,6 @@ UriCheck(const std::string& uri) { return (index != std::string::npos); } -void -CopyRowRecord(::milvus::grpc::RowRecord* target, const RowRecord& src) { - auto vector_data = target->mutable_vector_data(); - vector_data->Resize(static_cast(src.data.size()), 0.0); - memcpy(vector_data->mutable_data(), src.data.data(), src.data.size() * sizeof(float)); -} - Status ClientProxy::Connect(const ConnectParam& param) { std::string uri = param.ip_address + ":" + param.port; @@ -196,17 +189,14 @@ ClientProxy::Insert(const std::string& table_name, const std::string& partition_ for (auto& record : record_array) { ::milvus::grpc::RowRecord* grpc_record = insert_param.add_row_record_array(); - CopyRowRecord(grpc_record, record); + grpc_record->add_vector_data(record.data.begin(), record.data.end()); } // Single thread ::milvus::grpc::VectorIds vector_ids; if (!id_array.empty()) { /* set user's ids */ - auto row_ids = insert_param.mutable_row_id_array(); - row_ids->Reserve(static_cast(id_array.size())); - memcpy(row_ids->mutable_data(), id_array.data(), id_array.size() * sizeof(int64_t)); - + insert_param.add_row_id_array(id_array.begin(), id_array.end()); client_ptr_->Insert(vector_ids, insert_param, status); } else { client_ptr_->Insert(vector_ids, insert_param, status); @@ -236,7 +226,7 @@ ClientProxy::Search(const std::string& table_name, const std::vectoradd_vector_data(record.data.begin(), record.data.end()); } // step 2: convert range array diff --git a/core/src/server/Config.cpp b/core/src/server/Config.cpp index a2a1354dd4..23171cb35a 100644 --- a/core/src/server/Config.cpp +++ b/core/src/server/Config.cpp @@ -762,6 +762,12 @@ Config::CheckResourceConfigIndexBuildDevice(const std::vector& valu } } + if (value.size() > 1 && value[0] == "cpu") { + std::string msg = + "Invalid index build resource. " + "Possible reason: resource_config.index_build_device does not support hybrid of cpu and gpux."; + } + return Status::OK(); } diff --git a/core/src/server/grpc_impl/GrpcRequestTask.cpp b/core/src/server/grpc_impl/GrpcRequestTask.cpp index b8a9dbccbf..c54e9dd388 100644 --- a/core/src/server/grpc_impl/GrpcRequestTask.cpp +++ b/core/src/server/grpc_impl/GrpcRequestTask.cpp @@ -682,11 +682,8 @@ SearchTask::OnExecute() { // step 7: construct result array topk_result_->set_row_num(record_count); - topk_result_->mutable_ids()->Resize(static_cast(result_ids.size()), 0); - memcpy(topk_result_->mutable_ids()->mutable_data(), result_ids.data(), result_ids.size() * sizeof(int64_t)); - topk_result_->mutable_distances()->Resize(static_cast(result_distances.size()), 0.0); - memcpy(topk_result_->mutable_distances()->mutable_data(), result_distances.data(), - result_distances.size() * sizeof(float)); + topk_result_->add_ids(result_ids.begin(), result_ids.end()); + topk_result_->add_distances(result_distances.begin(), result_distances.end()); // step 8: print time cost percent rc.RecordSection("construct result and send"); diff --git a/core/src/wrapper/ConfAdapter.cpp b/core/src/wrapper/ConfAdapter.cpp index 2dcf6bab7e..461745f1fd 100644 --- a/core/src/wrapper/ConfAdapter.cpp +++ b/core/src/wrapper/ConfAdapter.cpp @@ -16,6 +16,7 @@ // under the License. #include "wrapper/ConfAdapter.h" +#include "WrapperException.h" #include "knowhere/index/vector_index/helpers/IndexParameter.h" #include "utils/Log.h" @@ -76,7 +77,7 @@ IVFConfAdapter::MatchNlist(const int64_t& size, const int64_t& nlist) { if (size <= TYPICAL_COUNT / 16384 + 1) { // handle less row count, avoid nlist set to 0 return 1; - } else if (int(size / TYPICAL_COUNT) * nlist == 0) { + } else if (int(size / TYPICAL_COUNT) * nlist <= 0) { // calculate a proper nlist if nlist not specified or size less than TYPICAL_COUNT return int(size / TYPICAL_COUNT * 16384); } @@ -87,7 +88,11 @@ knowhere::Config IVFConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) { auto conf = std::make_shared(); conf->k = metaconf.k; - conf->nprobe = metaconf.nprobe; + + if (metaconf.nprobe <= 0) + conf->nprobe = 16; // hardcode here + else + conf->nprobe = metaconf.nprobe; switch (type) { case IndexType::FAISS_IVFFLAT_GPU: @@ -123,11 +128,47 @@ IVFPQConfAdapter::Match(const TempMetaConf& metaconf) { conf->metric_type = metaconf.metric_type; conf->gpu_id = conf->gpu_id; conf->nbits = 8; - conf->m = 8; + + if (!(conf->d % 4)) + conf->m = conf->d / 4; // compression radio = 16 + else if (!(conf->d % 2)) + conf->m = conf->d / 2; // compression radio = 8 + else if (!(conf->d % 3)) + conf->m = conf->d / 3; // compression radio = 12 + else + conf->m = conf->d; // same as SQ8, compression radio = 4 + MatchBase(conf); return conf; } +knowhere::Config +IVFPQConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) { + auto conf = std::make_shared(); + conf->k = metaconf.k; + + if (metaconf.nprobe <= 0) { + WRAPPER_LOG_ERROR << "The nprobe of PQ is wrong!"; + throw WrapperException("The nprobe of PQ is wrong!"); + } else { + conf->nprobe = metaconf.nprobe; + } + + return conf; +} + +int64_t +IVFPQConfAdapter::MatchNlist(const int64_t& size, const int64_t& nlist) { + if (size <= TYPICAL_COUNT / 16384 + 1) { + // handle less row count, avoid nlist set to 0 + return 1; + } else if (int(size / TYPICAL_COUNT) * nlist <= 0) { + // calculate a proper nlist if nlist not specified or size less than TYPICAL_COUNT + return int(size / TYPICAL_COUNT * 16384); + } + return nlist; +} + knowhere::Config NSGConfAdapter::Match(const TempMetaConf& metaconf) { auto conf = std::make_shared(); @@ -136,13 +177,14 @@ NSGConfAdapter::Match(const TempMetaConf& metaconf) { conf->metric_type = metaconf.metric_type; conf->gpu_id = conf->gpu_id; + double factor = metaconf.size / TYPICAL_COUNT; auto scale_factor = round(metaconf.dim / 128.0); scale_factor = scale_factor >= 4 ? 4 : scale_factor; - conf->nprobe = 6 + 10 * scale_factor; - conf->knng = 100 + 100 * scale_factor; - conf->search_length = 40 + 5 * scale_factor; - conf->out_degree = 50 + 5 * scale_factor; - conf->candidate_pool_size = 200 + 100 * scale_factor; + conf->nprobe = conf->nlist > 10000 ? conf->nlist * 0.02 : conf->nlist * 0.1; + conf->knng = (100 + 100 * scale_factor) * factor; + conf->search_length = (40 + 5 * scale_factor) * factor; + conf->out_degree = (50 + 5 * scale_factor) * factor; + conf->candidate_pool_size = (200 + 100 * scale_factor) * factor; MatchBase(conf); // WRAPPER_LOG_DEBUG << "nlist: " << conf->nlist @@ -156,6 +198,9 @@ NSGConfAdapter::MatchSearch(const TempMetaConf& metaconf, const IndexType& type) auto conf = std::make_shared(); conf->k = metaconf.k; conf->search_length = metaconf.search_length; + if (metaconf.search_length == TEMPMETA_DEFAULT_VALUE) { + conf->search_length = 30; // TODO(linxj): hardcode here. + } return conf; } diff --git a/core/src/wrapper/ConfAdapter.h b/core/src/wrapper/ConfAdapter.h index 4c8e528a2d..5ec3d52486 100644 --- a/core/src/wrapper/ConfAdapter.h +++ b/core/src/wrapper/ConfAdapter.h @@ -79,6 +79,13 @@ class IVFPQConfAdapter : public IVFConfAdapter { public: knowhere::Config Match(const TempMetaConf& metaconf) override; + + knowhere::Config + MatchSearch(const TempMetaConf& metaconf, const IndexType& type) override; + + protected: + static int64_t + MatchNlist(const int64_t& size, const int64_t& nlist); }; class NSGConfAdapter : public IVFConfAdapter { diff --git a/core/src/wrapper/ConfAdapterMgr.cpp b/core/src/wrapper/ConfAdapterMgr.cpp index b329588cf2..d0eba04529 100644 --- a/core/src/wrapper/ConfAdapterMgr.cpp +++ b/core/src/wrapper/ConfAdapterMgr.cpp @@ -53,6 +53,7 @@ AdapterMgr::RegisterAdapter() { REGISTER_CONF_ADAPTER(IVFPQConfAdapter, IndexType::FAISS_IVFPQ_CPU, ivfpq_cpu); REGISTER_CONF_ADAPTER(IVFPQConfAdapter, IndexType::FAISS_IVFPQ_GPU, ivfpq_gpu); + REGISTER_CONF_ADAPTER(IVFPQConfAdapter, IndexType::FAISS_IVFPQ_MIX, ivfpq_mix); REGISTER_CONF_ADAPTER(NSGConfAdapter, IndexType::NSG_MIX, nsg_mix); } diff --git a/core/src/wrapper/VecIndex.cpp b/core/src/wrapper/VecIndex.cpp index 2323783c3d..81a13c60f9 100644 --- a/core/src/wrapper/VecIndex.cpp +++ b/core/src/wrapper/VecIndex.cpp @@ -145,6 +145,10 @@ GetVecIndexFactory(const IndexType& type, const Config& cfg) { index = std::make_shared(gpu_device); break; } + case IndexType::FAISS_IVFPQ_MIX: { + index = std::make_shared(gpu_device); + return std::make_shared(index, IndexType::FAISS_IVFPQ_MIX); + } case IndexType::FAISS_IVFSQ8_MIX: { index = std::make_shared(gpu_device); return std::make_shared(index, IndexType::FAISS_IVFSQ8_MIX); @@ -276,6 +280,10 @@ ConvertToCpuIndexType(const IndexType& type) { case IndexType::FAISS_IVFSQ8_MIX: { return IndexType::FAISS_IVFSQ8_CPU; } + case IndexType::FAISS_IVFPQ_GPU: + case IndexType::FAISS_IVFPQ_MIX: { + return IndexType::FAISS_IVFPQ_CPU; + } default: { return type; } } } @@ -291,9 +299,12 @@ ConvertToGpuIndexType(const IndexType& type) { case IndexType::FAISS_IVFSQ8_CPU: { return IndexType::FAISS_IVFSQ8_GPU; } + case IndexType::FAISS_IVFPQ_MIX: + case IndexType::FAISS_IVFPQ_CPU: { + return IndexType::FAISS_IVFPQ_GPU; + } default: { return type; } } } - } // namespace engine } // namespace milvus diff --git a/core/src/wrapper/VecIndex.h b/core/src/wrapper/VecIndex.h index cd9ba86951..efe01a25d7 100644 --- a/core/src/wrapper/VecIndex.h +++ b/core/src/wrapper/VecIndex.h @@ -33,6 +33,7 @@ namespace engine { using Config = knowhere::Config; +// TODO(linxj): replace with string, Do refactor serialization enum class IndexType { INVALID = 0, FAISS_IDMAP = 1, @@ -47,6 +48,7 @@ enum class IndexType { FAISS_IVFSQ8_GPU, FAISS_IVFSQ8_HYBRID, // only support build on gpu. NSG_MIX, + FAISS_IVFPQ_MIX, }; class VecIndex; diff --git a/core/unittest/server/test_config.cpp b/core/unittest/server/test_config.cpp index 7f4376bb67..0c65e9322c 100644 --- a/core/unittest/server/test_config.cpp +++ b/core/unittest/server/test_config.cpp @@ -295,7 +295,7 @@ TEST_F(ConfigTest, SERVER_CONFIG_VALID_TEST) { std::vector device_ids; s = config.GetResourceConfigIndexBuildDevice(device_ids); ASSERT_TRUE(s.ok()); - ASSERT_TRUE(int32_val == resource_index_build_device); + ASSERT_TRUE(device_ids[0] == resource_index_build_device); } TEST_F(ConfigTest, SERVER_CONFIG_INVALID_TEST) { diff --git a/core/unittest/wrapper/test_wrapper.cpp b/core/unittest/wrapper/test_wrapper.cpp index ddfdfa2fad..025601a1cd 100644 --- a/core/unittest/wrapper/test_wrapper.cpp +++ b/core/unittest/wrapper/test_wrapper.cpp @@ -29,33 +29,40 @@ INITIALIZE_EASYLOGGINGPP -using ::testing::Combine; using ::testing::TestWithParam; using ::testing::Values; +using ::testing::Combine; class KnowhereWrapperTest - : public DataGenBase, - public TestWithParam<::std::tuple> { + : public DataGenBase, + public TestWithParam<::std::tuple> { protected: - void - SetUp() override { + void SetUp() override { #ifdef MILVUS_GPU_VERSION knowhere::FaissGpuResourceMgr::GetInstance().InitDevice(DEVICEID, PINMEM, TEMPMEM, RESNUM); #endif - std::string generator_type; std::tie(index_type, generator_type, dim, nb, nq, k) = GetParam(); GenData(dim, nb, nq, xb, xq, ids, k, gt_ids, gt_dis); + milvus::engine::TempMetaConf tempconf; + tempconf.metric_type = knowhere::METRICTYPE::L2; + tempconf.gpu_id = DEVICEID; + tempconf.size = nb; + tempconf.dim = dim; + tempconf.k = k; + tempconf.nprobe = 16; + index_ = GetVecIndexFactory(index_type); - conf = ParamGenerator::GetInstance().Gen(index_type); - conf->k = k; - conf->d = dim; - conf->gpu_id = DEVICEID; + conf = ParamGenerator::GetInstance().GenBuild(index_type, tempconf); + searchconf = ParamGenerator::GetInstance().GenSearchConf(index_type, tempconf); + +// conf->k = k; +// conf->d = dim; +// conf->gpu_id = DEVICEID; } - void - TearDown() override { + void TearDown() override { #ifdef MILVUS_GPU_VERSION knowhere::FaissGpuResourceMgr::GetInstance().Free(); #endif @@ -65,24 +72,27 @@ class KnowhereWrapperTest milvus::engine::IndexType index_type; milvus::engine::VecIndexPtr index_ = nullptr; knowhere::Config conf; + knowhere::Config searchconf; }; -INSTANTIATE_TEST_CASE_P( - WrapperParam, KnowhereWrapperTest, - Values( -//["Index type", "Generator type", "dim", "nb", "nq", "k", "build config", "search config"] +INSTANTIATE_TEST_CASE_P(WrapperParam, KnowhereWrapperTest, + Values( + //["Index type", "Generator type", "dim", "nb", "nq", "k", "build config", "search config"] + #ifdef MILVUS_GPU_VERSION std::make_tuple(milvus::engine::IndexType::FAISS_IVFFLAT_GPU, "Default", DIM, NB, 10, 10), - std::make_tuple(milvus::engine::IndexType::FAISS_IVFFLAT_MIX, "Default", 64, 100000, 10, 10), + std::make_tuple(milvus::engine::IndexType::FAISS_IVFFLAT_MIX, "Default", 64, 1000, 10, 10), // std::make_tuple(milvus::engine::IndexType::FAISS_IVFSQ8_GPU, "Default", DIM, NB, // 10, 10), std::make_tuple(milvus::engine::IndexType::FAISS_IVFSQ8_GPU, "Default", DIM, NB, 10, 10), std::make_tuple(milvus::engine::IndexType::FAISS_IVFSQ8_MIX, "Default", DIM, NB, 10, 10), + std::make_tuple(milvus::engine::IndexType::FAISS_IVFPQ_MIX, "Default", 64, 1000, 10, 10), + // std::make_tuple(IndexType::NSG_MIX, "Default", 128, 250000, 10, 10), #endif // std::make_tuple(IndexType::SPTAG_KDT_RNT_CPU, "Default", 128, 250000, 10, 10), - std::make_tuple(milvus::engine::IndexType::FAISS_IDMAP, "Default", 64, 100000, 10, 10), - std::make_tuple(milvus::engine::IndexType::FAISS_IVFFLAT_CPU, "Default", 64, 100000, 10, 10), + std::make_tuple(milvus::engine::IndexType::FAISS_IDMAP, "Default", 64, 1000, 10, 10), + std::make_tuple(milvus::engine::IndexType::FAISS_IVFFLAT_CPU, "Default", 64, 1000, 10, 10), std::make_tuple(milvus::engine::IndexType::FAISS_IVFSQ8_CPU, "Default", DIM, NB, 10, 10))); TEST_P(KnowhereWrapperTest, BASE_TEST) { @@ -93,12 +103,11 @@ TEST_P(KnowhereWrapperTest, BASE_TEST) { std::vector res_dis(elems); index_->BuildAll(nb, xb.data(), ids.data(), conf); - index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); AssertResult(res_ids, res_dis); } #ifdef MILVUS_GPU_VERSION - TEST_P(KnowhereWrapperTest, TO_GPU_TEST) { EXPECT_EQ(index_->GetType(), index_type); @@ -107,13 +116,13 @@ TEST_P(KnowhereWrapperTest, TO_GPU_TEST) { std::vector res_dis(elems); index_->BuildAll(nb, xb.data(), ids.data(), conf); - index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); AssertResult(res_ids, res_dis); { auto dev_idx = index_->CopyToGpu(DEVICEID); for (int i = 0; i < 10; ++i) { - dev_idx->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + dev_idx->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); } AssertResult(res_ids, res_dis); } @@ -125,7 +134,7 @@ TEST_P(KnowhereWrapperTest, TO_GPU_TEST) { auto dev_idx = new_index->CopyToGpu(DEVICEID); for (int i = 0; i < 10; ++i) { - dev_idx->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + dev_idx->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); } AssertResult(res_ids, res_dis); } @@ -139,7 +148,7 @@ TEST_P(KnowhereWrapperTest, SERIALIZE_TEST) { std::vector res_ids(elems); std::vector res_dis(elems); index_->BuildAll(nb, xb.data(), ids.data(), conf); - index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + index_->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); AssertResult(res_ids, res_dis); { @@ -152,7 +161,7 @@ TEST_P(KnowhereWrapperTest, SERIALIZE_TEST) { std::vector res_ids(elems); std::vector res_dis(elems); - new_index->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + new_index->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); AssertResult(res_ids, res_dis); } @@ -166,7 +175,7 @@ TEST_P(KnowhereWrapperTest, SERIALIZE_TEST) { std::vector res_ids(elems); std::vector res_dis(elems); - new_index->Search(nq, xq.data(), res_dis.data(), res_ids.data(), conf); + new_index->Search(nq, xq.data(), res_dis.data(), res_ids.data(), searchconf); AssertResult(res_ids, res_dis); } } diff --git a/core/unittest/wrapper/utils.h b/core/unittest/wrapper/utils.h index c16b8fc930..1eaa7ae4ec 100644 --- a/core/unittest/wrapper/utils.h +++ b/core/unittest/wrapper/utils.h @@ -15,18 +15,22 @@ // specific language governing permissions and limitations // under the License. + #pragma once #include -#include -#include -#include #include #include +#include +#include +#include + -#include "knowhere/index/vector_index/helpers/IndexParameter.h" #include "wrapper/VecIndex.h" #include "wrapper/utils.h" +#include "knowhere/index/vector_index/helpers/IndexParameter.h" +#include "wrapper/ConfAdapterMgr.h" +#include "wrapper/ConfAdapter.h" class DataGenBase; @@ -40,29 +44,31 @@ constexpr int64_t PINMEM = 1024 * 1024 * 200; constexpr int64_t TEMPMEM = 1024 * 1024 * 300; constexpr int64_t RESNUM = 2; -static const char* CONFIG_PATH = "/tmp/milvus_test"; -static const char* CONFIG_FILE = "/server_config.yaml"; +static const char *CONFIG_PATH = "/tmp/milvus_test"; +static const char *CONFIG_FILE = "/server_config.yaml"; class KnowhereTest : public ::testing::Test { protected: - void - SetUp() override; - void - TearDown() override; + void SetUp() override; + void TearDown() override; }; class DataGenBase { public: - virtual void - GenData(const int& dim, const int& nb, const int& nq, float* xb, float* xq, int64_t* ids, const int& k, - int64_t* gt_ids, float* gt_dis); + virtual void GenData(const int& dim, const int& nb, const int& nq, float* xb, float* xq, int64_t* ids, + const int& k, int64_t* gt_ids, float* gt_dis); - virtual void - GenData(const int& dim, const int& nb, const int& nq, std::vector& xb, std::vector& xq, - std::vector& ids, const int& k, std::vector& gt_ids, std::vector& gt_dis); + virtual void GenData(const int& dim, + const int& nb, + const int& nq, + std::vector& xb, + std::vector& xq, + std::vector& ids, + const int& k, + std::vector& gt_ids, + std::vector& gt_dis); - void - AssertResult(const std::vector& ids, const std::vector& dis); + void AssertResult(const std::vector& ids, const std::vector& dis); int dim = DIM; int nb = NB; @@ -79,14 +85,22 @@ class DataGenBase { class ParamGenerator { public: - static ParamGenerator& - GetInstance() { + static ParamGenerator& GetInstance() { static ParamGenerator instance; return instance; } - knowhere::Config - Gen(const milvus::engine::IndexType& type) { + knowhere::Config GenSearchConf(const milvus::engine::IndexType& type, const milvus::engine::TempMetaConf& conf) { + auto adapter = milvus::engine::AdapterMgr::GetInstance().GetAdapter(type); + return adapter->MatchSearch(conf, type); + } + + knowhere::Config GenBuild(const milvus::engine::IndexType& type, const milvus::engine::TempMetaConf& conf) { + auto adapter = milvus::engine::AdapterMgr::GetInstance().GetAdapter(type); + return adapter->Match(conf); + } + + knowhere::Config Gen(const milvus::engine::IndexType& type) { switch (type) { case milvus::engine::IndexType::FAISS_IDMAP: { auto tempconf = std::make_shared(); @@ -113,34 +127,37 @@ class ParamGenerator { tempconf->metric_type = knowhere::METRICTYPE::L2; return tempconf; } - // case milvus::engine::IndexType::FAISS_IVFPQ_CPU: - // case milvus::engine::IndexType::FAISS_IVFPQ_GPU: { - // auto tempconf = std::make_shared(); - // tempconf->nlist = 100; - // tempconf->nprobe = 16; - // tempconf->nbits = 8; - // tempconf->m = 8; - // tempconf->metric_type = knowhere::METRICTYPE::L2; - // return tempconf; - // } - // case milvus::engine::IndexType::NSG_MIX: { - // auto tempconf = std::make_shared(); - // tempconf->nlist = 100; - // tempconf->nprobe = 16; - // tempconf->search_length = 8; - // tempconf->knng = 200; - // tempconf->search_length = 40; // TODO(linxj): be 20 when search - // tempconf->out_degree = 60; - // tempconf->candidate_pool_size = 200; - // tempconf->metric_type = knowhere::METRICTYPE::L2; - // return tempconf; - // } + case milvus::engine::IndexType::FAISS_IVFPQ_CPU: + case milvus::engine::IndexType::FAISS_IVFPQ_GPU: + case milvus::engine::IndexType::FAISS_IVFPQ_MIX: { + auto tempconf = std::make_shared(); + tempconf->nlist = 100; + tempconf->nprobe = 16; + tempconf->nbits = 8; + tempconf->m = 8; + tempconf->metric_type = knowhere::METRICTYPE::L2; + return tempconf; + } + case milvus::engine::IndexType::NSG_MIX: { + auto tempconf = std::make_shared(); + tempconf->nlist = 100; + tempconf->nprobe = 16; + tempconf->search_length = 8; + tempconf->knng = 200; + tempconf->search_length = 40; // TODO(linxj): be 20 when search + tempconf->out_degree = 60; + tempconf->candidate_pool_size = 200; + tempconf->metric_type = knowhere::METRICTYPE::L2; + return tempconf; + } } } }; -// class SanityCheck : public DataGenBase { + +//class SanityCheck : public DataGenBase { // public: // void GenData(const int &dim, const int &nb, const int &nq, float *xb, float *xq, long *ids, // const int &k, long *gt_ids, float *gt_dis) override; //}; + diff --git a/docker/build_env/cpu/ubuntu16.04/Dockerfile b/docker/build_env/cpu/ubuntu16.04/Dockerfile new file mode 100644 index 0000000000..45e2b53938 --- /dev/null +++ b/docker/build_env/cpu/ubuntu16.04/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:16.04 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates gnupg2 apt-transport-https && \ + wget -P /tmp https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + apt-key add /tmp/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + sh -c 'echo deb https://apt.repos.intel.com/mkl all main > /etc/apt/sources.list.d/intel-mkl.list' && \ + wget -qO- "https://cmake.org/files/v3.14/cmake-3.14.3-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local && \ + apt-get update && apt-get install -y --no-install-recommends \ + g++ git gfortran lsb-core \ + libboost-serialization-dev libboost-filesystem-dev libboost-system-dev libboost-regex-dev \ + curl libtool automake libssl-dev pkg-config libcurl4-openssl-dev python3-pip \ + clang-format-6.0 clang-tidy-6.0 \ + lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.5-281 intel-mkl-core-2019.5-281 && \ + apt-get remove --purge -y && \ + rm -rf /var/lib/apt/lists/* + +RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so \ + /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so + +RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.5.281/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' + +COPY docker-entrypoint.sh /app/docker-entrypoint.sh + +WORKDIR /opt/milvus + +ENTRYPOINT [ "/app/docker-entrypoint.sh" ] +CMD [ "start" ] diff --git a/docker/build_env/ubuntu16.04/docker-entrypoint.sh b/docker/build_env/cpu/ubuntu16.04/docker-entrypoint.sh similarity index 100% rename from docker/build_env/ubuntu16.04/docker-entrypoint.sh rename to docker/build_env/cpu/ubuntu16.04/docker-entrypoint.sh diff --git a/docker/build_env/cpu/ubuntu18.04/Dockerfile b/docker/build_env/cpu/ubuntu18.04/Dockerfile new file mode 100644 index 0000000000..7c76e2ec7a --- /dev/null +++ b/docker/build_env/cpu/ubuntu18.04/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:18.04 + +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates gnupg2 && \ + wget -P /tmp https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + apt-key add /tmp/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB && \ + sh -c 'echo deb https://apt.repos.intel.com/mkl all main > /etc/apt/sources.list.d/intel-mkl.list' && \ + wget -qO- "https://cmake.org/files/v3.14/cmake-3.14.3-Linux-x86_64.tar.gz" | tar --strip-components=1 -xz -C /usr/local && \ + apt-get update && apt-get install -y --no-install-recommends \ + g++ git gfortran lsb-core \ + libboost-serialization-dev libboost-filesystem-dev libboost-system-dev libboost-regex-dev \ + curl libtool automake libssl-dev pkg-config libcurl4-openssl-dev python3-pip \ + clang-format-6.0 clang-tidy-6.0 \ + lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.5-281 intel-mkl-core-2019.5-281 && \ + apt-get remove --purge -y && \ + rm -rf /var/lib/apt/lists/* + +RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so \ + /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so + +RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.5.281/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' + +COPY docker-entrypoint.sh /app/docker-entrypoint.sh + +WORKDIR /opt/milvus + +ENTRYPOINT [ "/app/docker-entrypoint.sh" ] +CMD [ "start" ] diff --git a/docker/build_env/ubuntu18.04/docker-entrypoint.sh b/docker/build_env/cpu/ubuntu18.04/docker-entrypoint.sh similarity index 100% rename from docker/build_env/ubuntu18.04/docker-entrypoint.sh rename to docker/build_env/cpu/ubuntu18.04/docker-entrypoint.sh diff --git a/docker/build_env/ubuntu16.04/Dockerfile b/docker/build_env/gpu/ubuntu16.04/Dockerfile similarity index 86% rename from docker/build_env/ubuntu16.04/Dockerfile rename to docker/build_env/gpu/ubuntu16.04/Dockerfile index a93ce83f72..d35a7dccfd 100644 --- a/docker/build_env/ubuntu16.04/Dockerfile +++ b/docker/build_env/gpu/ubuntu16.04/Dockerfile @@ -11,15 +11,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget && \ git flex bison gfortran lsb-core \ curl libtool automake libboost1.58-all-dev libssl-dev pkg-config libcurl4-openssl-dev python3-pip \ clang-format-6.0 clang-tidy-6.0 \ - lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.4-243 intel-mkl-core-2019.4-243 && \ + lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.5-281 intel-mkl-core-2019.5-281 && \ apt-get remove --purge -y && \ rm -rf /var/lib/apt/lists/* RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so -RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.4.243/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' +RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.5.281/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' COPY docker-entrypoint.sh /app/docker-entrypoint.sh + +WORKDIR /opt/milvus + ENTRYPOINT [ "/app/docker-entrypoint.sh" ] CMD [ "start" ] - diff --git a/docker/build_env/gpu/ubuntu16.04/docker-entrypoint.sh b/docker/build_env/gpu/ubuntu16.04/docker-entrypoint.sh new file mode 100755 index 0000000000..1e85e7e9e1 --- /dev/null +++ b/docker/build_env/gpu/ubuntu16.04/docker-entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +if [ "$1" = 'start' ]; then + tail -f /dev/null +fi + +exec "$@" + diff --git a/docker/build_env/ubuntu18.04/Dockerfile b/docker/build_env/gpu/ubuntu18.04/Dockerfile similarity index 86% rename from docker/build_env/ubuntu18.04/Dockerfile rename to docker/build_env/gpu/ubuntu18.04/Dockerfile index 7f7353de31..9f2f3f55ac 100644 --- a/docker/build_env/ubuntu18.04/Dockerfile +++ b/docker/build_env/gpu/ubuntu18.04/Dockerfile @@ -11,15 +11,17 @@ RUN apt-get update && apt-get install -y --no-install-recommends wget && \ git flex bison gfortran lsb-core \ curl libtool automake libboost-all-dev libssl-dev pkg-config libcurl4-openssl-dev python3-pip \ clang-format-6.0 clang-tidy-6.0 \ - lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.4-243 intel-mkl-core-2019.4-243 && \ + lcov mysql-client libmysqlclient-dev intel-mkl-gnu-2019.5-281 intel-mkl-core-2019.5-281 && \ apt-get remove --purge -y && \ rm -rf /var/lib/apt/lists/* RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so -RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.4.243/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' +RUN sh -c 'echo export LD_LIBRARY_PATH=/opt/intel/compilers_and_libraries_2019.5.281/linux/mkl/lib/intel64:\$LD_LIBRARY_PATH > /etc/profile.d/mkl.sh' COPY docker-entrypoint.sh /app/docker-entrypoint.sh + +WORKDIR /opt/milvus + ENTRYPOINT [ "/app/docker-entrypoint.sh" ] CMD [ "start" ] - diff --git a/docker/build_env/gpu/ubuntu18.04/docker-entrypoint.sh b/docker/build_env/gpu/ubuntu18.04/docker-entrypoint.sh new file mode 100755 index 0000000000..1e85e7e9e1 --- /dev/null +++ b/docker/build_env/gpu/ubuntu18.04/docker-entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -e + +if [ "$1" = 'start' ]; then + tail -f /dev/null +fi + +exec "$@" + diff --git a/docker/deploy/cpu/ubuntu16.04/Dockerfile b/docker/deploy/cpu/ubuntu16.04/Dockerfile new file mode 100644 index 0000000000..9e90c6a89c --- /dev/null +++ b/docker/deploy/cpu/ubuntu16.04/Dockerfile @@ -0,0 +1,20 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + gfortran libsqlite3-dev libmysqlclient-dev libcurl4-openssl-dev python3 && \ + apt-get remove --purge -y && \ + rm -rf /var/lib/apt/lists/* + +RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so + +COPY ./docker-entrypoint.sh /opt +COPY ./milvus /opt/milvus +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/milvus/lib" + +WORKDIR /opt/milvus + +ENTRYPOINT [ "/opt/docker-entrypoint.sh" ] + +CMD [ "start" ] + +EXPOSE 19530 diff --git a/docker/deploy/ubuntu16.04/docker-entrypoint.sh b/docker/deploy/cpu/ubuntu16.04/docker-entrypoint.sh similarity index 99% rename from docker/deploy/ubuntu16.04/docker-entrypoint.sh rename to docker/deploy/cpu/ubuntu16.04/docker-entrypoint.sh index 446c174d74..12937df395 100755 --- a/docker/deploy/ubuntu16.04/docker-entrypoint.sh +++ b/docker/deploy/cpu/ubuntu16.04/docker-entrypoint.sh @@ -7,4 +7,3 @@ if [ "$1" == 'start' ]; then fi exec "$@" - diff --git a/docker/deploy/cpu/ubuntu18.04/Dockerfile b/docker/deploy/cpu/ubuntu18.04/Dockerfile new file mode 100644 index 0000000000..0064f4aad2 --- /dev/null +++ b/docker/deploy/cpu/ubuntu18.04/Dockerfile @@ -0,0 +1,21 @@ +FROM ubuntu:18.04 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + gfortran libsqlite3-dev libmysqlclient-dev libcurl4-openssl-dev python3 && \ + apt-get remove --purge -y && \ + rm -rf /var/lib/apt/lists/* + +RUN ln -s /usr/lib/x86_64-linux-gnu/libmysqlclient.so /usr/lib/x86_64-linux-gnu/libmysqlclient_r.so + +COPY ./docker-entrypoint.sh /opt +COPY ./milvus /opt/milvus +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/milvus/lib" + +WORKDIR /opt/milvus + +ENTRYPOINT [ "/opt/docker-entrypoint.sh" ] + +CMD [ "start" ] + +EXPOSE 19530 + diff --git a/docker/deploy/ubuntu18.04/docker-entrypoint.sh b/docker/deploy/cpu/ubuntu18.04/docker-entrypoint.sh similarity index 99% rename from docker/deploy/ubuntu18.04/docker-entrypoint.sh rename to docker/deploy/cpu/ubuntu18.04/docker-entrypoint.sh index 446c174d74..12937df395 100755 --- a/docker/deploy/ubuntu18.04/docker-entrypoint.sh +++ b/docker/deploy/cpu/ubuntu18.04/docker-entrypoint.sh @@ -7,4 +7,3 @@ if [ "$1" == 'start' ]; then fi exec "$@" - diff --git a/docker/deploy/ubuntu16.04/Dockerfile b/docker/deploy/gpu/ubuntu16.04/Dockerfile similarity index 97% rename from docker/deploy/ubuntu16.04/Dockerfile rename to docker/deploy/gpu/ubuntu16.04/Dockerfile index c5ca0ab03e..ee5402d3a9 100644 --- a/docker/deploy/ubuntu16.04/Dockerfile +++ b/docker/deploy/gpu/ubuntu16.04/Dockerfile @@ -15,6 +15,8 @@ COPY ./docker-entrypoint.sh /opt COPY ./milvus /opt/milvus ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/milvus/lib" +WORKDIR /opt/milvus + ENTRYPOINT [ "/opt/docker-entrypoint.sh" ] CMD [ "start" ] diff --git a/docker/deploy/gpu/ubuntu16.04/docker-entrypoint.sh b/docker/deploy/gpu/ubuntu16.04/docker-entrypoint.sh new file mode 100755 index 0000000000..12937df395 --- /dev/null +++ b/docker/deploy/gpu/ubuntu16.04/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +if [ "$1" == 'start' ]; then + cd /opt/milvus/scripts && ./start_server.sh +fi + +exec "$@" diff --git a/docker/deploy/ubuntu18.04/Dockerfile b/docker/deploy/gpu/ubuntu18.04/Dockerfile similarity index 97% rename from docker/deploy/ubuntu18.04/Dockerfile rename to docker/deploy/gpu/ubuntu18.04/Dockerfile index 0d16ae46e1..0760fe527e 100644 --- a/docker/deploy/ubuntu18.04/Dockerfile +++ b/docker/deploy/gpu/ubuntu18.04/Dockerfile @@ -15,6 +15,8 @@ COPY ./docker-entrypoint.sh /opt COPY ./milvus /opt/milvus ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/milvus/lib" +WORKDIR /opt/milvus + ENTRYPOINT [ "/opt/docker-entrypoint.sh" ] CMD [ "start" ] diff --git a/docker/deploy/gpu/ubuntu18.04/docker-entrypoint.sh b/docker/deploy/gpu/ubuntu18.04/docker-entrypoint.sh new file mode 100755 index 0000000000..12937df395 --- /dev/null +++ b/docker/deploy/gpu/ubuntu18.04/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +if [ "$1" == 'start' ]; then + cd /opt/milvus/scripts && ./start_server.sh +fi + +exec "$@" diff --git a/install.md b/install.md index 4d2088a3be..6711b41f76 100644 --- a/install.md +++ b/install.md @@ -29,10 +29,15 @@ $ ./build.sh -t Release ``` By default, it will build CPU version. To build GPU version, add `-g` option -``` +```shell $ ./build.sh -g ``` +If you want to know the complete build options, run +```shell +$./build.sh -h +``` + When the build is completed, all the stuff that you need in order to run Milvus will be installed under `[Milvus root path]/core/milvus`. ## Launch Milvus server @@ -43,13 +48,13 @@ $ cd [Milvus root path]/core/milvus Add `lib/` directory to `LD_LIBRARY_PATH` -``` +```shell $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:[Milvus root path]/core/milvus/lib ``` Then start Milvus server: -``` +```shell $ cd scripts $ ./start_server.sh ``` @@ -65,7 +70,7 @@ $ ./stop_server.sh `protocol https not supported or disabled in libcurl`. First, make sure you have `libcurl4-openssl-dev` installed in your system. Then try reinstall CMake from source with `--system-curl` option: -``` +```shell $ ./bootstrap --system-curl $ make $ sudo make install diff --git a/tests/milvus_python_test/conftest.py b/tests/milvus_python_test/conftest.py index 8bab824606..dc58063a45 100644 --- a/tests/milvus_python_test/conftest.py +++ b/tests/milvus_python_test/conftest.py @@ -42,16 +42,22 @@ def connect(request): port = request.config.getoption("--port") milvus = Milvus() try: - milvus.connect(host=ip, port=port) - except: + status = milvus.connect(host=ip, port=port) + logging.getLogger().info(status) + if not status.OK(): + # try again + logging.getLogger().info("------------------------------------") + logging.getLogger().info("Try to connect again") + logging.getLogger().info("------------------------------------") + res = milvus.connect(host=ip, port=port) + except Exception as e: + logging.getLogger().error(str(e)) pytest.exit("Milvus server can not connected, exit pytest ...") - def fin(): try: milvus.disconnect() except: pass - request.addfinalizer(fin) return milvus @@ -129,4 +135,4 @@ def ip_table(request, connect): request.addfinalizer(teardown) - return table_name \ No newline at end of file + return table_name diff --git a/tests/milvus_python_test/test_connect.py b/tests/milvus_python_test/test_connect.py index 96ce1d3bdf..dd7e80c1f9 100644 --- a/tests/milvus_python_test/test_connect.py +++ b/tests/milvus_python_test/test_connect.py @@ -249,8 +249,8 @@ class TestConnect: ''' milvus = Milvus() uri_value = "tcp://%s:19540" % args["ip"] - milvus.connect(host=args["ip"], port="", uri=uri_value) - assert milvus.connected() + with pytest.raises(Exception) as e: + milvus.connect(host=args["ip"], port="", uri=uri_value) def test_connect_param_priority_uri(self, args): '''