diff --git a/src/common/backend/utils/adt/vector.cpp b/src/common/backend/utils/adt/vector.cpp index 6c4ee42e3..a65160f20 100644 --- a/src/common/backend/utils/adt/vector.cpp +++ b/src/common/backend/utils/adt/vector.cpp @@ -1575,7 +1575,7 @@ struct ElementOpL2 { struct ElementOpIP { static float32x4_t op(float32x4_t x, float32x4_t y) { - return vsubq_f32(x, y); + return vmulq_f32(x, y); } }; @@ -1590,9 +1590,7 @@ void VectorOpNYD4(size_t ny, float *x, char *pqTable, Size subSize, int offset, for (i = 0; i < ny; i++) { y = DatumGetVector(pqTable + (offset + i) * subSize)->x; float32x4_t accu = ElementOp::op(x0, vld1q_f32(y)); - accu = vaddq_f32(accu, accu); - accu = vaddq_f32(accu, accu); - dis[i] = vgetq_lane_f32(accu, 0); + dis[i] = vaddvq_f32(accu); } } @@ -1612,9 +1610,7 @@ void VectorOpNYD8(size_t ny, float *x, char *pqTable, Size subSize, int offset, float32x4_t accu = ElementOp::op(x0, vld1q_f32(y)); y += batch; accu = vaddq_f32(accu, ElementOp::op(x1, vld1q_f32(y))); - accu = vaddq_f32(accu, accu); - accu = vaddq_f32(accu, accu); - dis[i] = vgetq_lane_f32(accu, 0); + dis[i] = vaddvq_f32(accu); } } @@ -1640,9 +1636,7 @@ void VectorOpNYD16(size_t ny, float *x, char *pqTable, Size subSize, int offset, accu = vaddq_f32(accu, ElementOp::op(x2, vld1q_f32(y))); y += batch; accu = vaddq_f32(accu, ElementOp::op(x3, vld1q_f32(y))); - accu = vaddq_f32(accu, accu); - accu = vaddq_f32(accu, accu); - dis[i] = vgetq_lane_f32(accu, 0); + dis[i] = vaddvq_f32(accu); } } #endif @@ -1653,7 +1647,6 @@ void VectorL2SquaredDistanceNYRef(size_t d, size_t ny, float *x, char *pqTable, for (size_t i = 0; i < ny; i++) { y = DatumGetVector(pqTable + (offset + i) * subSize)->x; dis[i] = VectorL2SquaredDistance(d, x, y); - y += d; } } diff --git a/src/gausskernel/storage/access/datavec/ivfbuild.cpp b/src/gausskernel/storage/access/datavec/ivfbuild.cpp index 210ed25f7..0a41539b2 100644 --- a/src/gausskernel/storage/access/datavec/ivfbuild.cpp +++ b/src/gausskernel/storage/access/datavec/ivfbuild.cpp @@ -58,7 +58,7 @@ static void CreatePQPages(IvfflatBuildState *buildstate, ForkNumber fNum) Buffer buf; Page page; uint16 pqTableNblk; - uint16 pqPreComputeTableNblk; + uint32 pqPreComputeTableNblk; GenericXLogState *state; IvfGetPQInfoFromMetaPage(index, &pqTableNblk, NULL, &pqPreComputeTableNblk, NULL); @@ -72,7 +72,7 @@ static void CreatePQPages(IvfflatBuildState *buildstate, ForkNumber fNum) } /* create pq distance table page */ - for (uint16 i = 0; i < pqPreComputeTableNblk; i++) { + for (uint32 i = 0; i < pqPreComputeTableNblk; i++) { buf = IvfflatNewBuffer(index, forkNum); IvfflatInitRegisterPage(index, &buf, &page, &state); MarkBufferDirty(buf); @@ -695,9 +695,9 @@ static void CreateMetaPage(Relation index, IvfflatBuildState *buildstate, ForkNu (metap->pqTableSize + IVF_PQTABLE_STORAGE_SIZE - 1) / IVF_PQTABLE_STORAGE_SIZE); if (buildstate->byResidual && (buildstate->params->funcType == IVF_PQ_DIS_L2 || buildstate->params->funcType == IVF_PQ_DIS_COSINE)) { - uint32 TableLen = buildstate->lists * buildstate->pqM * buildstate->pqKsub; - metap->pqPreComputeTableSize = (uint32)TableLen * sizeof(float); - metap->pqPreComputeTableNblk = (uint16)( + uint64 TableLen = buildstate->lists * buildstate->pqM * buildstate->pqKsub; + metap->pqPreComputeTableSize = (uint64)TableLen * sizeof(float); + metap->pqPreComputeTableNblk = (uint32)( (metap->pqPreComputeTableSize + IVF_PQTABLE_STORAGE_SIZE - 1) / IVF_PQTABLE_STORAGE_SIZE); } } else { diff --git a/src/gausskernel/storage/access/datavec/ivfinsert.cpp b/src/gausskernel/storage/access/datavec/ivfinsert.cpp index 21d1561d3..a5cb60a82 100644 --- a/src/gausskernel/storage/access/datavec/ivfinsert.cpp +++ b/src/gausskernel/storage/access/datavec/ivfinsert.cpp @@ -37,7 +37,7 @@ static void FindInsertPage(Relation index, Datum *values, BlockNumber *insertPag { double minDistance = DBL_MAX; uint16 pqTableNblk; - uint16 pqDisTableNblk; + uint32 pqDisTableNblk; IvfGetPQInfoFromMetaPage(index, &pqTableNblk, NULL, &pqDisTableNblk, NULL); BlockNumber nextblkno = IVFPQTABLE_START_BLKNO + pqTableNblk + pqDisTableNblk; FmgrInfo *procinfo; diff --git a/src/gausskernel/storage/access/datavec/ivfscan.cpp b/src/gausskernel/storage/access/datavec/ivfscan.cpp index d5c290c3f..e0d38891a 100644 --- a/src/gausskernel/storage/access/datavec/ivfscan.cpp +++ b/src/gausskernel/storage/access/datavec/ivfscan.cpp @@ -54,7 +54,7 @@ static void GetScanLists(IndexScanDesc scan, Datum value) { IvfflatScanOpaque so = (IvfflatScanOpaque)scan->opaque; uint16 pqTableNblk; - uint16 pqDisTableNblk; + uint32 pqDisTableNblk; IvfGetPQInfoFromMetaPage(scan->indexRelation, &pqTableNblk, NULL, &pqDisTableNblk, NULL); BlockNumber nextblkno = IVFPQTABLE_START_BLKNO + pqTableNblk + pqDisTableNblk; int listId = 0; @@ -86,6 +86,12 @@ static void GetScanLists(IndexScanDesc scan, Datum value) scanlist->distance = distance; scanlist->key = listId; listId++; + if (so->funcType == IVFPQ_DIS_COSINE && so->byResidual) { + Vector *vd = (Vector *)DatumGetPointer(value); + scanlist->pqDistance = VectorL2SquaredDistance(so->dimensions, list->center.x, vd->x); + } else { + scanlist->pqDistance = distance; + } /* Add to heap */ pairingheap_add(so->listQueue, &scanlist->ph_node); } @@ -246,7 +252,7 @@ static void GetScanItemsPQ(IndexScanDesc scan, Datum value, float *simTable) int listCount = 0; while (!pairingheap_is_empty(so->listQueue)) { IvfflatScanList *scanlist = (IvfflatScanList *)pairingheap_remove_first(so->listQueue); - double dis0 = so->byResidual ? scanlist->distance : 0; + double dis0 = so->byResidual ? scanlist->pqDistance : 0; BlockNumber searchPage = scanlist->startPage; int key = scanlist->key; float *simTable2; diff --git a/src/gausskernel/storage/access/datavec/ivfutils.cpp b/src/gausskernel/storage/access/datavec/ivfutils.cpp index def990b3f..4af5b03ba 100644 --- a/src/gausskernel/storage/access/datavec/ivfutils.cpp +++ b/src/gausskernel/storage/access/datavec/ivfutils.cpp @@ -235,16 +235,16 @@ float* IVFPQLoadPQDisTable(Relation index) Buffer buf; Page page; uint16 pqTableNblk; - uint16 nblks; + uint32 nblks; uint32 curFlushSize; - uint32 pqDisTableSize; + uint64 pqDisTableSize; float* disTable; IvfGetPQInfoFromMetaPage(index, &pqTableNblk, NULL, &nblks, &pqDisTableSize); disTable = (float*)palloc0(pqDisTableSize); BlockNumber startBlkno = IVFPQTABLE_START_BLKNO + pqTableNblk; - for (uint16 i = 0; i < nblks; i++) { + for (uint32 i = 0; i < nblks; i++) { curFlushSize = (i == nblks - 1) ? (pqDisTableSize - i * IVFPQTABLE_STORAGE_SIZE) : IVFPQTABLE_STORAGE_SIZE; buf = ReadBuffer(index, startBlkno + i); LockBuffer(buf, BUFFER_LOCK_SHARE); @@ -346,12 +346,12 @@ uint8 *LoadPQCode(IndexTuple itup) float GetPQDistance(float *pqDistanceTable, uint8 *code, double dis0, int pqM, int pqKsub, bool innerPro) { - float resDistance = dis0; + float resDistance = 0.0; for (int i = 0; i < pqM; i++) { int offset = i * pqKsub + code[i]; resDistance += pqDistanceTable[offset]; } - return innerPro ? (0 - resDistance) : resDistance; + return innerPro ? (dis0 - resDistance) : (dis0 + resDistance); } IvfpqPairingHeapNode * IvfpqCreatePairingHeapNode(float distance, ItemPointer heapTid, @@ -432,7 +432,7 @@ int getIVFPQfunctionType(FmgrInfo *procinfo, FmgrInfo *normprocinfo) * Get the info related to pqTable in metapage */ void IvfGetPQInfoFromMetaPage(Relation index, uint16 *pqTableNblk, uint32 *pqTableSize, - uint16 *pqPreComputeTableNblk, uint32 *pqPreComputeTableSize) + uint32 *pqPreComputeTableNblk, uint64 *pqPreComputeTableSize) { Buffer buf; Page page; @@ -528,14 +528,14 @@ int IvfGetByResidual(Relation index) return IVFPQ_DEFAULT_RESIDUAL; } -void IvfFlushPQInfoInternal(Relation index, char* table, BlockNumber startBlkno, uint16 nblks, uint32 totalSize) +void IvfFlushPQInfoInternal(Relation index, char* table, BlockNumber startBlkno, uint32 nblks, uint64 totalSize) { Buffer buf; Page page; uint32 curFlushSize; GenericXLogState *state; - for (uint16 i = 0; i < nblks; i++) { + for (uint32 i = 0; i < nblks; i++) { curFlushSize = (i == nblks - 1) ? (totalSize - i * IVF_PQTABLE_STORAGE_SIZE) : IVF_PQTABLE_STORAGE_SIZE; buf = ReadBufferExtended(index, MAIN_FORKNUM, startBlkno + i, RBM_NORMAL, NULL); @@ -560,14 +560,14 @@ void IvfFlushPQInfo(IvfflatBuildState *buildstate) float* preComputeTable = buildstate->preComputeTable; uint16 pqTableNblk; uint32 pqTableSize; - uint16 pqPrecomputeTableNblk; - uint32 pqPrecomputeTableSize; + uint32 pqPrecomputeTableNblk; + uint64 pqPrecomputeTableSize; IvfGetPQInfoFromMetaPage(index, &pqTableNblk, &pqTableSize, &pqPrecomputeTableNblk, &pqPrecomputeTableSize); /* Flush pq table */ IvfFlushPQInfoInternal(index, pqTable, IVF_PQTABLE_START_BLKNO, pqTableNblk, pqTableSize); - if (buildstate->byResidual && buildstate->params->funcType == IVF_PQ_DIS_L2) { + if (buildstate->byResidual && buildstate->params->funcType != IVF_PQ_DIS_IP) { /* Flush pq distance table */ IvfFlushPQInfoInternal(index, (char*)preComputeTable, IVF_PQTABLE_START_BLKNO + pqTableNblk, pqPrecomputeTableNblk, pqPrecomputeTableSize); diff --git a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp index ef8084c37..4e4eff80a 100644 --- a/src/gausskernel/storage/access/datavec/ivfvacuum.cpp +++ b/src/gausskernel/storage/access/datavec/ivfvacuum.cpp @@ -34,7 +34,7 @@ IndexBulkDeleteResult *ivfflatbulkdelete_internal(IndexVacuumInfo *info, IndexBu IndexBulkDeleteCallback callback, void *callbackState) { uint16 pqTableNblk; - uint16 pqDisTableNblk; + uint32 pqDisTableNblk; Relation index = info->index; IvfGetPQInfoFromMetaPage(index, &pqTableNblk, NULL, &pqDisTableNblk, NULL); BlockNumber blkno = IVFPQTABLE_START_BLKNO + pqTableNblk + pqDisTableNblk; diff --git a/src/include/access/datavec/ivfflat.h b/src/include/access/datavec/ivfflat.h index b5a929546..2be80dc57 100644 --- a/src/include/access/datavec/ivfflat.h +++ b/src/include/access/datavec/ivfflat.h @@ -261,7 +261,7 @@ typedef struct IvfflatMetaPageData { uint32 pqTableSize; uint16 pqTableNblk; uint64 pqPreComputeTableSize; - uint16 pqPreComputeTableNblk; + uint32 pqPreComputeTableNblk; } IvfflatMetaPageData; typedef IvfflatMetaPageData *IvfflatMetaPage; @@ -287,6 +287,7 @@ typedef struct IvfflatScanList { BlockNumber startPage; double distance; int key; + double pqDistance; } IvfflatScanList; typedef struct IvfflatScanOpaqueData { @@ -356,9 +357,9 @@ int IvfGetByResidual(Relation index); void IvfGetPQInfoFromMetaPage(Relation index, uint16 *pqTableNblk, uint32 *pqTableSize, - uint16 *pqPreComputeTableNblk, uint32 *pqPreComputeTableSize); + uint32 *pqPreComputeTableNblk, uint64 *pqPreComputeTableSize); int getIVFPQfunctionType(FmgrInfo *procinfo, FmgrInfo *normprocinfo); -void IvfFlushPQInfoInternal(Relation index, char* table, BlockNumber startBlkno, uint16 nblks, uint32 totalSize); +void IvfFlushPQInfoInternal(Relation index, char* table, BlockNumber startBlkno, uint32 nblks, uint64 totalSize); void IvfFlushPQInfo(IvfflatBuildState *buildstate); int IvfComputePQTable(VectorArray samples, PQParams *params);