A method, apparatus, storage medium, and computer device for constructing a nearest neighbor graph.

By employing a two-stage parallel graph construction method, combined with GPU parallel processing and a pre-defined node pruning strategy, the problem of low efficiency in traditional nearest neighbor graph construction on GPUs is solved, achieving efficient and high-speed nearest neighbor graph construction suitable for ultra-large-scale datasets.

CN122087155APending Publication Date: 2026-05-26北京数智引航科技有限公司
View PDF 0 Cites 0 Cited by

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
北京数智引航科技有限公司
Filing Date
2026-01-07
Publication Date
2026-05-26

AI Technical Summary

Technical Problem

Traditional nearest neighbor graph construction methods are inefficient and slow to converge when implemented on GPUs. They lack a unified acceleration framework, making it difficult to efficiently construct various mainstream index structures. Furthermore, their processing capabilities are limited under large-scale datasets, with disk I/O operations becoming a bottleneck.

Method used

A two-stage parallel graph construction approach is adopted. In the first construction stage, coarse-grained sampling is performed through a shared resource pool and GPU parallel processing to improve the convergence speed. In the second construction stage, fine-grained sampling is performed to accurately determine neighbor nodes, and graph pruning efficiency is optimized by combining preset node pruning strategies.

Benefits of technology

It significantly improves the construction efficiency and convergence speed of nearest neighbor graphs, can efficiently process ultra-large-scale datasets, and fully utilizes the parallel computing power of GPUs to achieve high-speed, high-quality graph index construction.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122087155A_ABST
    Figure CN122087155A_ABST
Patent Text Reader

Abstract

This application provides a nearest neighbor graph construction method, apparatus, storage medium, and computer device. The nearest neighbor graph construction method provided in this application can achieve efficient GPU parallelization of the entire process of k-NN graph construction and pruning without sacrificing index quality, significantly improving throughput and convergence speed in large-scale high-dimensional scenarios, and providing a high-performance, scalable, and highly versatile underlying graph index construction foundation for approximate nearest neighbor search systems.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This application relates to the field of computer technology, and more specifically, to a method, apparatus, storage medium, and computer device for constructing a nearest neighbor graph. Background Technology

[0002] Approximate Nearest Neighbor Search (ANNS) plays a crucial role in data retrieval as a key search technique in numerous systems, including vector database systems, information retrieval systems, computer vision, recommender systems, and retrieval-augmented generation (RAG) systems. With the rapid development of internet technology, the size of datasets has exploded, with hundreds of millions of vector datasets (billions, tens of billions, etc.) becoming increasingly common. This has placed ever-higher demands on the search efficiency of ANNS. Among various ANNS algorithms, nearest neighbor graph-based indexing methods have gained increasing popularity due to their superior performance in both search efficiency and accuracy.

[0003] However, while traditional nearest-neighbor graph construction methods can build graph index structures for searching, they suffer from low graph structure construction efficiency and slow graph structure convergence when implemented on graphics processing units (GPUs), resulting in significant drawbacks. Summary of the Invention

[0004] In view of this, this application provides a method, apparatus, storage medium, and computer device for constructing nearest neighbor graphs, so as to improve the construction efficiency of constructing nearest neighbor graphs using GPUs and improve the convergence speed of graph structures.

[0005] Specifically, this application is implemented through the following technical solution: In a first aspect, embodiments of this disclosure provide a method for constructing a nearest neighbor graph, including: In the first construction phase, a shared resource pool is created for the current iteration based on the first neighbor list of the node corresponding to each piece of data obtained in the previous iteration; wherein, when the current iteration is the first iteration, the first neighbor list is the initial neighbor list of the node; From the shared resource pool, a first sampling node is selected for each node, and using the graphics processing unit (GPU), matrix calculations are performed on the first matrix composed of the data vectors corresponding to each node and the second matrix composed of the data vectors corresponding to each first sampling node to obtain the first distance between each node and the corresponding first sampling node. Based on the first distance and the first neighbor list, determine the first neighbor list corresponding to each node in the current iteration, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each data, and create a shared resource pool for the current iteration, until the first cutoff condition is met, obtain the first target neighbor list of each node and enter the second construction stage; In the second construction phase, for each node, the GPU is used to determine the second target neighbor list of the node based on the node's data vector and the first target neighbor list; Based on the second target neighbor list, construct the target nearest neighbor graph corresponding to each data entry.

[0006] Secondly, embodiments of this disclosure also provide a nearest neighbor graph construction apparatus, comprising: The first construction module is used in the first construction phase to create a shared resource pool for the current iteration based on the first neighbor list obtained in the previous iteration for each data node; wherein, when the current iteration is the first iteration, the first neighbor list is the initial neighbor list of the node; The calculation module is used to select a first sampling node for each node from the shared resource pool, and use the graphics processing unit (GPU) to perform matrix calculation on a first matrix composed of data vectors corresponding to each node and a second matrix composed of data vectors corresponding to each first sampling node, so as to obtain a first distance between each node and the corresponding first sampling node. The loop module is used to determine the first neighbor list corresponding to each node in the current iteration based on the first distance and the first neighbor list, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each piece of data, and create a shared resource pool for the current iteration, until the first cutoff condition is met, obtain the first target neighbor list of each node and enter the second construction stage; The second construction module is used in the second construction phase to determine, for each node, a second target neighbor list of the node using the GPU based on the node's data vector and the first target neighbor list; The third construction module is used to construct the target nearest neighbor graph corresponding to each data item based on the second target neighbor list.

[0007] Thirdly, an optional implementation of this disclosure also provides a computer-readable storage medium having a computer program stored thereon, which, when executed by a processor, performs the steps described in the first aspect above.

[0008] Fourthly, an optional implementation of this disclosure also provides a computer device, including a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein the processor executes the program to perform the steps described in the first aspect above.

[0009] The nearest neighbor graph construction method, apparatus, storage medium, and computer device provided in this disclosure employ a two-stage parallel graph construction approach. In the first construction stage, by constructing a shared resource pool and combining it with the parallel processing capabilities of the GPU, the distance calculation between data vectors corresponding to a large number of nodes is converted into a highly parallel matrix operation and iterated multiple times. This fully utilizes the parallel computing capabilities of the GPU, improving the distance calculation speed in the early stages of nearest neighbor graph construction, and thus using the rapidly calculated distances to improve the convergence speed of the nearest neighbor graph construction. In the second construction stage, the parallel computing capabilities of the GPU are used to mine nearest neighbors for each node individually. This avoids the neighbor omissions caused by shared sampling using the shared resource pool in the first construction stage, accurately determining the nearest neighbors corresponding to each node, thereby achieving fine-grained neighbor optimization. In summary, the GPU-based two-stage graph construction method provided in this application can achieve a smooth transition from rapid coarse convergence of the graph structure to fine-grained high-quality optimization. While ensuring the quality of the nearest neighbor graph structure, it significantly shortens the overall construction time of the nearest neighbor graph and improves the construction efficiency.

[0010] To make the above-mentioned objects, features and advantages of this disclosure more apparent and understandable, preferred embodiments are described below in detail with reference to the accompanying drawings. Attached Figure Description

[0011] Figure 1 This is a flowchart illustrating a nearest neighbor graph construction method according to an exemplary embodiment of this application; Figure 2 This is a schematic diagram of a nearest neighbor graph construction apparatus shown in an exemplary embodiment of this application; Figure 3 This is a schematic diagram of the structure of a computer device shown in an exemplary embodiment of this application. Detailed Implementation

[0012] Exemplary embodiments will now be described in detail, examples of which are illustrated in the accompanying drawings. When the following description relates to the drawings, unless otherwise indicated, the same numbers in different drawings denote the same or similar elements. The embodiments described in the following exemplary embodiments do not represent all embodiments consistent with this application. Rather, they are merely examples of apparatuses and methods consistent with some aspects of this application as detailed in the appended claims.

[0013] The terminology used in this application is for the purpose of describing particular embodiments only and is not intended to be limiting of the application. The singular forms “a,” “the,” and “the” used in this application and the appended claims are also intended to include the plural forms unless the context clearly indicates otherwise. It should also be understood that the term “and / or” as used herein refers to and includes any or all possible combinations of one or more of the associated listed items.

[0014] It should be understood that although the terms first, second, third, etc., may be used in this application to describe various information, such information should not be limited to these terms. These terms are only used to distinguish information of the same type from one another. For example, without departing from the scope of this application, first information may also be referred to as second information, and similarly, second information may also be referred to as first information. Depending on the context, the word "if" as used herein may be interpreted as "when," "when," or "in response to determination."

[0015] Research has found that current graph indexing methods often employ a refinement-based strategy to construct high-quality k-nearest neighbor graphs. The refinement-based strategy typically consists of two phases: the first is the k-NN graph initialization phase, used to construct the initial k-Nearest Neighbor Graph (k-NN Graph); the second is the graph pruning phase, used to prune the initial k-NN Graph.

[0016] Existing techniques, such as Nearest Neighbor Descent (NN-Descent), are commonly used to initialize k-nearest neighbor graphs. This method discovers closer neighbors by iteratively allowing nodes to "introduce" each other to their neighbors. However, these algorithms did not fully consider the parallel computing capabilities of GPUs in their initial design, leading to numerous challenges when implemented directly on GPUs. For example, the standard NN-Descent algorithm suffers from slow convergence during graph construction, and its core operations (such as distance calculation and neighbor list updates) experience severe serial bottlenecks and memory access conflicts on GPUs, failing to fully utilize the powerful parallel computing capabilities of GPUs and resulting in inefficient initial k-nearest neighbor graphs. While some methods have emerged that leverage GPUs to accelerate graph initialization and pruning, such as Hierarchical Navigable Small World (HNSW), Navigating Spreading-out Graph (NSG), Vamana, Diversified Proximity Graph (DPG), Navigating Spreading-out Synergy Graph (NSSG), and NVIDIA's Coarse-to-Fine GPU Accelerated Graph-based Retrieval Algorithm (CAGRA), these methods lack a unified acceleration framework. They are often customized optimization schemes for specific graph indexes (such as HNSW or NSG), resulting in poor code reusability and difficulty in efficiently building various mainstream index structures within a unified framework.

[0017] For example, CAGRA's core strategy is a ranking-based pruning approach. This method doesn't store the exact distance between a node and its neighbors; instead, it estimates the distance using the neighbor's position in the ranking list. It removes redundant edges in the graph in parallel by determining if a "detourable route" exists, achieving efficient GPU-parallel pruning. However, despite optimizing the pruning phase, CAGRA still relies on the traditional or improved NN-Descent algorithm for initializing the k-NN graph. This still suffers from inefficiencies on GPUs during initialization, slow convergence, frequent neighbor list updates leading to memory access conflicts, and high synchronization overhead, thus becoming a performance bottleneck in the entire index building process. Furthermore, CAGRA primarily optimizes its own index building process and fails to provide a general framework to support various mainstream graph indexes (such as NSG, Vamana, and DPG), lacking uniformity. Users need different, incompatible systems to build different types of indexes. Additionally, CAGRA cannot effectively parallelize pruning strategies like NSG and DPG that rely on serial computation of complex neighbor relationships, resulting in underutilization of GPU computing power.

[0018] Furthermore, existing graph construction methods generally suffer from limited processing power on large-scale datasets. When the dataset size exceeds the memory capacity of a single GPU or even a Central Processing Unit (CPU), traditional in-memory index construction methods fail. Although some disk-based solutions have been proposed, frequent disk I / O operations become the main performance bottleneck when dealing with ultra-large-scale data, resulting in excessively long construction times. For example, Disk-based Approximate Nearest Neighbor Search Graph-structured Index (DiskANN), a disk-based approximate nearest neighbor search method for billions of vector data, employs a divide-and-conquer strategy. First, it divides the ultra-large-scale dataset into multiple small clusters using k-means clustering. Then, it independently constructs a local graph index for each cluster in CPU memory and writes these indexes to disk. Finally, the system reads all local indexes from disk and merges them into a complete global graph index. The core idea of ​​this method is to leverage disk storage to overcome memory capacity limitations, thereby enabling indexing of massive amounts of data. However, DiskANN has the following drawbacks: 1. Waste of computational resources: DiskANN primarily performs index building tasks on the CPU. When its workflow is extended to heterogeneous systems including GPUs, simply delegating local index building to the GPU results in the CPU being idle most of the time, failing to achieve collaborative computing between the CPU and GPU, thus wasting valuable computational resources. 2. Huge I / O overhead: During the construction and merging of local indexes, DiskANN frequently writes intermediate results to and reads them from disk. This large amount of disk I / O operations is its main performance bottleneck, leading to excessively long overall build times. 3. Lack of optimization for asynchronous collaboration between GPU, CPU, and disk: DiskANN lacks an efficient asynchronous framework to coordinate data flow and computational tasks among the three, and also lacks an intelligent caching mechanism to prefetch and manage hot data, thus failing to effectively alleviate I / O pressure.

[0019] Based on the above analysis, current nearest-neighbor graph construction methods face the following core challenges: a) Traditional graph initialization algorithms (such as NN-Descent) have low parallel efficiency and slow convergence speed on GPUs, becoming a performance bottleneck; b) There is a lack of a unified framework to efficiently accelerate various mainstream graph pruning strategies, resulting in poor code reusability; c) When the data scale exceeds the GPU memory capacity, existing methods have low coordination efficiency between CPU and GPU, and huge disk I / O overhead. Therefore, there is an urgent need for a scalable graph index construction technology that can fully leverage the advantages of GPU parallel computing, support the construction of various mainstream graph indexes, and efficiently handle ultra-large-scale datasets.

[0020] Based on the above research, this disclosure provides a nearest neighbor graph construction method, apparatus, storage medium, and computer device. It employs a two-stage parallel graph construction approach. In the first construction stage, a shared resource pool is constructed, combined with the parallel processing capabilities of the GPU, to convert the distance calculation between data vectors corresponding to a large number of nodes into a highly parallel matrix operation and multiple iterations. This fully utilizes the parallel computing power of the GPU, improving the distance calculation speed in the early stages of nearest neighbor graph construction, and thus increasing the convergence speed of the nearest neighbor graph construction. In the second construction stage, the parallel computing power of the GPU is used to mine nearest neighbors for each node individually. This avoids the neighbor omissions caused by shared sampling using the shared resource pool in the first construction stage, accurately determining the nearest neighbors for each node, thereby achieving refined neighbor optimization. Furthermore, by setting preset node pruning strategies for different graph indexing frameworks, during graph pruning, a target pruning strategy is selected based on the graph indexing framework used, and the target pruning strategy is used to prune the nearest neighbor graph. This fully utilizes the computing resources of the GPU, improving pruning efficiency. In summary, this application proposes a GPU-based scalable nearest neighbor graph index construction method that is comprehensively optimized from the algorithm, architecture and storage levels, enabling high-speed, efficient and highly scalable graph index construction for ultra-large-scale datasets.

[0021] The shortcomings of the above solutions are the result of the inventor's practical experience and careful research. Therefore, the discovery process of the above problems and the solutions proposed in this disclosure below are all contributions made by the inventor to this disclosure.

[0022] It should be noted that similar labels and letters in the following figures indicate similar items. Therefore, once an item is defined in one figure, it does not need to be further defined and explained in subsequent figures.

[0023] It is understood that before using the technical solutions disclosed in the various embodiments of this disclosure, users should be informed of the types, scope of use, and usage scenarios of the personal information involved in this disclosure in an appropriate manner in accordance with relevant laws and regulations, and user authorization should be obtained.

[0024] It should be noted that the specific terms mentioned in the embodiments of this disclosure include: k-NN Graph: A directed or undirected graph structure where data vectors are nodes and edges connect each node to its k nearest neighbors. k-NN graphs are the core indexing form of modern ANNS systems, supporting efficient graph traversal and search, and are widely used in advanced algorithms such as NSG, HNSW, Vamana, and CAGRA. Graph-Based Nearest Neighbor Search (Graph-Based ANNS): A class of ANNS methods that use graph structures to organize high-dimensional vector data and perform navigational search. The core idea is to start from the entry node, greedily approach the query vector along the graph edges, and finally converge to the nearest neighbor. Compared with hashing or quantization methods, graph structures can usually achieve a higher balance between recall and search efficiency.

[0025] Atomic operations are low-level instructions (such as atomicAdd and atomicCAS) used in GPU programming to implement thread-safe writes to shared or global memory. In lock-free parallel algorithms, atomic operations are often used to avoid data races, but overuse can lead to performance bottlenecks. Tensor Core Acceleration (Tensor Core Acceleration for short): A hardware unit in the GPU specifically designed for matrix operations, which can greatly accelerate mixed-precision (such as FP16 / INT8) matrix multiplication and addition operations. In ANNS, it transforms batch vector distance calculations into matrix multiplication. This can fully utilize Tensor Cores to achieve extreme throughput and is a key optimization method for modern GPU-ANNS systems. Two-Stage Parallel Graph Construction: A k-nearest neighbor graph initialization method designed specifically for GPUs, comprising two consecutive stages: "coarse-grained sampling" and "fine-grained sampling". The first construction stage achieves fast convergence through a globally shared resource pool and batch matrix multiplication, while the second stage employs node-independent sampling and a non-revisit strategy for fine-grained optimization. Tagore: A GPU-accelerated library for high-dimensional vector nearest neighbor search; atomicAdd is an atomic addition operation used to ensure that the sequence of "read-modify-write" operations is indivisible and that there is no data race between threads when multiple threads concurrently access the same memory address. atomicCAS is an atomic operation that compares and swaps. Its core function is to atomically compare the value at a memory address with an expected value. If they are equal, the value at that memory address is replaced with the new value; if they are not equal, no modification is made. The entire process is indivisible and cannot be interrupted by other threads. thrust::sort is a general-purpose parallel sorting function provided by a parallel algorithm library.

[0026] To facilitate understanding of this embodiment, a detailed description of a nearest neighbor graph construction method disclosed in this disclosure will be provided first. The execution subject of the nearest neighbor graph construction method provided in this disclosure is generally a terminal device or other processing device with certain computing capabilities. The terminal device may be a user equipment (UE), a mobile device, a terminal, a personal digital assistant (PDA), a handheld device, a computer device, etc. In some possible implementations, the nearest neighbor graph construction method can be implemented by the processor calling computer-readable instructions stored in the memory.

[0027] The nearest neighbor graph construction method provided in this disclosure is illustrated below, taking a computer device as the execution subject as an example.

[0028] like Figure 1 The flowchart shown is a method for constructing a nearest neighbor graph according to an embodiment of this disclosure, which may include the following steps: S101: In the first construction phase, based on the first neighbor list of the node corresponding to each piece of data obtained in the previous iteration, a shared resource pool is created for the current iteration; wherein, when the current iteration is the first iteration, the first neighbor list is the node's initial neighbor list.

[0029] To address the issues of slow convergence and low neighbor update efficiency in the later stages of nearest neighbor graph construction using GPU-accelerated graph indexing algorithms such as NN-Descent, this application first proposes a two-stage parallelization algorithm specifically designed for GPUs. This algorithm aims to accelerate the convergence speed and improve the efficiency of nearest neighbor graph construction. The two stages can be further divided into a first construction stage and a second construction stage, each corresponding to a different sampling strategy and optimization objective. Specifically, the sampling strategy of the first construction stage is coarse-grained sampling in a shared resource pool, with the optimization objective being to accelerate the convergence speed of nearest neighbor graph construction. The sampling strategy of the second construction stage is fine-grained sampling for each node, with the optimization objective being to precisely optimize the neighbor nodes corresponding to each node. Both the first and second construction stages include iterative steps, with each iteration performing one optimization of the nearest neighbor graph. The two construction stages will be described in detail below.

[0030] In the first construction phase, the powerful parallel computing capabilities of the GPU are utilized to accelerate the convergence of the nearest neighbor graph through an iterative approach in the early stages when the graph quality is low, thereby quickly determining the first neighbor list corresponding to each node. The multiple iterations in the first construction phase can be divided into initial iterations and non-initial iterations. For the initial iteration, the first neighbor list of each node can be an initial neighbor list initialized for each node, including a first preset number of initial neighbor nodes corresponding to the node. For any non-initial iteration, after the iteration is completed, a new first neighbor list corresponding to each node can be obtained. A node's first neighbor list includes a first preset number of neighbor nodes corresponding to that node, and the neighbor relationships between nodes can be represented using connecting edges between nodes. The first preset number can be set empirically, and this application does not impose a specific limitation. Hereafter, the first preset number will be defined as k for explanation.

[0031] Each node corresponds to a data vector of a single data point in the dataset. Different nodes correspond to different data vectors, and the number of nodes is the same as the number of data vectors in the dataset. The dataset can be any set of vectors for which a nearest neighbor graph needs to be constructed. The nodes v corresponding to each data vector in the dataset form a node set V.

[0032] In each iteration of the first construction phase, a shared resource pool can be generated for that iteration. This pool contains the target number of shared nodes, which can be shared by all nodes v (v∈V). In other words, all nodes will select sampling nodes from this unified shared resource pool during this iteration. By creating this shared resource pool, the parallelism of the GPU can be maximized, allowing the data vectors corresponding to all candidate nodes in the entire shared resource pool to be loaded into GPU memory in batches, enabling large-scale distance calculations to be completed in one go.

[0033] In practical implementation, after starting to build the nearest neighbor graph, the first construction phase can be entered, where an initial neighbor list G(v) of size k is randomly initialized for each data vector corresponding to a node v in the dataset. Then, an iterative construction process can be performed. For each iteration, when the current iteration is the first iteration, the initial neighbor list G(v) can be set as the first neighbor list for each node. A certain number of candidate nodes are then extracted from each node's first neighbor list according to a preset strategy to form the shared resource pool for the current iteration. The preset strategy can be, for example, the method and number of candidate nodes extracted from each first neighbor list, such as randomly selecting a specific number of candidate nodes. When the current iteration is not the first iteration, the first neighbor list obtained for each node after the previous iteration can be retrieved. Then, a certain number of candidate nodes are extracted from each node's first neighbor list according to the preset strategy to form the shared resource pool for the current iteration. The number of candidate nodes included in the shared resource pool created in each iteration is the same, but the specific candidate nodes included can be different.

[0034] S102: From the shared resource pool, select a first sampling node for each node, and use the graphics processing unit (GPU) to perform matrix calculations on the first matrix composed of the data vectors corresponding to each node and the second matrix composed of the data vectors corresponding to each first sampling node, to obtain the first distance between each node and the corresponding first sampling node.

[0035] Here, the first sampling nodes are selected from the shared resource pool as a subset of candidate nodes for the current iteration. The first matrix is ​​a matrix composed of the data vectors corresponding to each node v, defined as matrix A. The second matrix is ​​a matrix composed of the data vectors corresponding to each first sampling node, defined as matrix B. The first distance is the vector distance between node v and the first sampling nodes. For example, for a node v1, if the first sampling nodes selected in the current iteration include nodes v2 to v4, then the first distance can include the vector distances between v1 and v2 to v4 respectively.

[0036] In practice, for the current iteration, a second preset number of first sampling nodes can be extracted from the shared resource pool for each node v. The second preset number can be set empirically, based on the computational power of the thread blocks and threads in the GPU, or determined by a preset ratio corresponding to the number of candidate nodes in the shared resource pool. The second preset number is usually greater than the first preset number. Then, the data vectors corresponding to each node v are used to form a matrix A, where matrix A has dimensions N. v ×D, N vThis represents the total number of nodes participating in the current iteration, and D represents the vector dimension of the data vector. Additionally, the data vectors corresponding to the first sampled node of each node can be combined to form a matrix B, where matrix B has a dimension of N. u ×D, N u This represents the total number of first-sample nodes corresponding to each node participating in the current iteration, and D represents the vector dimension of the data vector. All data vectors in the dataset have the same vector dimension. The size of matrix B is a multiple of that of matrix A.

[0037] Then, leveraging the matrix multiplication capabilities of the Tensor Cores in the GPU, we can load matrices A and B corresponding to the current iteration and perform matrix multiplication to obtain the result matrix C corresponding to the current iteration. Where C = Then, based on each matrix value in the result matrix C, the first distance between each node v and its corresponding first sampling nodes is determined.

[0038] Optionally, when selecting the first sampling node u for each node v from the shared resource pool, it can be determined whether node v has selected the first sampling node u in previous iterations based on the historical access records of the extracted first sampling node u. If so, the first sampling node u can be marked as a "new node" for node v in the current iteration and added to the list of new nodes for node v in the current iteration; if not, the first sampling node u can be marked as an "old node" for node v in the current iteration and added to the list of old nodes for node v in the current iteration. Understandably, new nodes can be candidate nodes selected from the shared resource pool for a given node v in the current iteration that have never been sampled by node v in any previous iteration. These nodes represent entirely new potential neighbor nodes that node v is exploring. Old nodes can be candidate nodes selected from the shared resource pool for a given node v in the current iteration that have been sampled by node v in previous iterations. These nodes are those for which node v needs to re-evaluate its proximity.

[0039] Optionally, to improve the rationality of neighbor node exploration in each iteration, the ratio of new nodes to old nodes included in the first neighbor list obtained in the previous iteration can be automatically determined in each iteration to determine the ratio of new nodes to old nodes to be selected for node v in the current iteration, and the first sampling node can be selected for node v from the shared resource pool of the current iteration according to the ratio.

[0040] In one embodiment, the step of performing batch matrix calculations in S102 described above can be implemented according to the following steps: S102-1: Load the first and second matrices into the GPU's global memory.

[0041] Here, during the distance calculation in the first construction phase, in order to maximize the use of the GPU's parallel computing capabilities, especially the matrix multiplication capabilities of the Tensor Cores, it is necessary to organize the data vectors corresponding to the nodes into matrix form. Specifically, the data vectors corresponding to each node v participating in the current iteration can be combined into matrix A, and the data vectors corresponding to the first sampling node of each node v can be combined into matrix B.

[0042] Optionally, when constructing matrices A and B, it is also necessary to consider the number of thread blocks and their processing capabilities in the GPU to partition matrices A and B. If the parallel processing capability of the thread blocks in the GPU supports full processing of matrix A, which is composed of the data vectors corresponding to each node v participating in the current iteration, and matrix B, which is composed of the data vectors corresponding to the first sampling node of each node v, then a single matrix A and matrix B can be constructed and processed using the GPU. If full processing is not supported, the nodes v participating in the current iteration can be grouped according to the parallel processing capability of the thread blocks in the GPU, resulting in multiple groups. Simultaneously, for each group, a matrix A can be generated based on the data vectors of each node v within that group. Simultaneously, matrix B can be formed by assembling the data vectors corresponding to the first sampling node of each node v within that group. In this way, multiple matrices A and B corresponding to each group can be obtained. Then, for each group's matrix A and matrix B, the GPU can perform batch matrix calculations on the matrix A and matrix B corresponding to that group, obtaining the group result matrix corresponding to that group. Finally, based on the group result matrices corresponding to each group, the first distance between each node and its corresponding first sampling node can be obtained.

[0043] When the GPU supports full-scale processing, matrix A, composed of data vectors from all nodes v, and matrix B, composed of data vectors from the first sampled node of full node v, can be synchronously loaded into the GPU's global memory. Then, batch computation can be performed using subsequent steps S102-2 to S102-5. When the GPU does not support full-scale processing, multiple batch processing operations can be performed. During each batch processing operation, matrices A and B corresponding to one group can be synchronously loaded into the GPU's global memory, and then batch computation can be performed using subsequent steps S102-2 to S102-5. The number of batch processing operations corresponds to the number of groups. The batch processing for each group is similar to the process of batch processing all nodes.

[0044] In practice, for each iteration, the corresponding matrices A and B can be synchronously loaded into the GPU's global memory for the GPU to perform batch distance calculations.

[0045] S102-2: Based on the number of thread blocks and the processing capacity of the thread blocks in the GPU, allocate the processing node to be processed and the first sampling node corresponding to the processing node to each thread block from each node.

[0046] Here, parallel computing on a GPU is executed by thread blocks and threads. Different GPUs contain different numbers of thread blocks, thus resulting in different processing capabilities. Thread block processing capacity indicates the maximum number of nodes v that a GPU can process at one time.

[0047] In its implementation, Tagore divides distance calculation tasks primarily as follows: Based on the actual GPU model used, the number of thread blocks and their processing capacity are determined. Then, based on the number and processing capacity of the thread blocks, all nodes v and all first sampling nodes are assigned to different thread blocks for processing. For example, if the GPU has 10 thread blocks, each supporting batch distance calculation for a maximum of 10 nodes v, and there are 91 nodes v, these 91 nodes v can be divided into 10 groups. The first nine groups each contain 10 nodes v, and the last group contains 1 node v. Each node v in each group can be defined as a node to be processed. The 10 groups of nodes and each first sampling node are then assigned to 10 thread blocks. Nine of these 10 thread blocks are assigned 10 nodes to be processed and their corresponding first sampling nodes, while only one thread block is assigned one node to be processed and its corresponding first sampling nodes. Thus, in this application, a thread block can be used to process one or more nodes v and their corresponding first sampling nodes.

[0048] S102-3: Using each thread block, load the first block matrix data related to the node to be processed from the first matrix in the first matrix from the global memory, and load the second block matrix data related to the first sampling node corresponding to the node to be processed from the global memory in the second matrix.

[0049] S102-4: Using each thread in each thread block, based on the loaded first and second block matrix data, determine the block calculation results corresponding to the thread block and write them into global memory.

[0050] Here, the first block matrix data is the submatrix composed of the data vectors corresponding to each node to be processed in the first matrix, to which the thread block is assigned. The second block matrix data is the submatrix composed of the data vectors of the first sampling nodes corresponding to each node to be processed in the second matrix, to which the thread block is assigned. The number of threads in a thread block is determined according to the GPU model, and a thread can specifically be a core in the GPU, such as a CUDA Core or a Tensor Core.

[0051] For example, during batch matrix multiplication, to improve GPU memory utilization efficiency, for each thread block, the first block matrix data related to the thread block can be loaded separately from matrix A (included in global memory) into the shared memory of the thread block, and the second block matrix data related to the thread block can be loaded separately from matrix B (included in global memory) into the shared memory of the thread block. Then, the threads within the thread block cooperate to complete the matrix multiplication calculation of the first and second block matrix data in the shared memory, obtaining the block calculation result corresponding to the thread block and writing it into the GPU's global memory. The block calculation result includes the first distance between the node to be processed assigned to the thread block and the corresponding first sampling nodes. In this way, each thread block in the GPU loads a small block of matrix A and a small block of matrix B into the shared memory, and then the threads within each thread block cooperate to complete the multiplication operation of the corresponding loaded small block matrix and write the result into global memory.

[0052] Understandably, in each iteration, any thread block in the GPU is assigned the same pending node. However, in different iterations, because the shared resource pool includes different candidate nodes, the first sampling node corresponding to the pending node assigned to a thread block is different in different iterations.

[0053] S102-5: Based on the block calculation results written by each thread block in the global memory, determine the first distance between each node and the corresponding first sampling node.

[0054] In practice, the result matrix C between the first and second matrices can be determined based on the block calculation results written to global memory by each thread block. Then, the first distance between each node v and its corresponding first sampling nodes can be determined based on each matrix value in the result matrix C.

[0055] Thus, the batch matrix multiplication proposed in this application, as a key optimization in the first construction phase, allows us to avoid having each thread block independently calculate the first distance between node v and its first sampled node. Instead, we package the data vectors of all nodes v and all first sampled nodes into two large matrices A and B and perform matrix operations on them, thereby calculating the first distance in one go. The result is an N. v xN u The distance matrix is ​​calculated. During this process, the GPU automatically divides the matrix into blocks and schedules a large number of threads (including CUDA Cores and Tensor Cores) to process the matrix multiplication operations of these matrix blocks in parallel. This batch processing method greatly reduces the communication overhead between the CPU and GPU and fully utilizes the throughput of the GPU hardware.

[0056] S103: Based on the first distance and the first neighbor list, determine the first neighbor list corresponding to each node in the current iteration, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each data. This is the step of creating a shared resource pool for the current iteration until the first cutoff condition is met, obtaining the first target neighbor list for each node and entering the second construction phase.

[0057] Here, after each iteration of the first construction phase, a new first neighbor list can be generated for each node v, and then the next iteration can continue until the first cutoff condition is met. The first cutoff condition may include the number of iterations reaching a preset number and / or the proportion of node change between the first neighbor lists obtained by each node in two consecutive iterations being less than a specific proportion. The first target neighbor list is the neighbor list optimized for node v after the first construction phase ends.

[0058] In specific implementation, in the current iteration, for each node v, after obtaining the first distance between node v and each first sampling node, the k closest nodes can be selected from the first sampling nodes and the first neighbor nodes obtained in the previous iteration based on the first distance and the first distance between each first neighbor node in the first neighbor list obtained in the previous iteration, to form the first neighbor list corresponding to node v in the current iteration, thereby optimizing the graph structure corresponding to node v.

[0059] Optionally, in the current iteration, for each node v, the first sampled node in the new node list and the first sampled node in the old node list of the current iteration can be independently evaluated based on the first distance of the first sampled node and the first distance of each first neighbor node, thus obtaining the first neighbor list corresponding to node v in the current iteration. For example, for each new node in the new node list, the first x1 first nodes with the smallest first distance can be selected from the new nodes based on the first distance of each new node, where x1 can be adaptively adjusted according to the number of new nodes. At the same time, for each old node in the old node list, the weighted distance of each old node is determined based on the number of times each old node appears in the first neighbor list obtained in previous iterations and the first distance of each old node, and x2 second nodes are selected from the old nodes based on the weighted distance. Based on the first distance of the x1 first nodes, the weighted distance of the x2 second nodes, and the first distance between each first neighbor node in the first neighbor list obtained in the previous iteration and node v, the k closest nodes are selected to form the first neighbor list corresponding to node v in the current iteration.

[0060] After determining the first neighbor list for each node v in the current iteration, the current iteration can be considered complete. It is then determined whether the first cutoff condition is met. If so, the first neighbor list for the current iteration is used as the first target neighbor list, ending the first construction phase and proceeding to the second construction phase. If not, the process returns to the step of creating the shared resource pool in S101 for the next iteration. This iterative process continues until the first cutoff condition is met. The latest iteration's optimized first neighbor list for each node is then used as the node's first target neighbor list, and the process proceeds to the second construction phase.

[0061] Optionally, if new and old labels are set for the first sampling node in each iteration, after obtaining the list of first neighbors corresponding to a node in the current iteration, the new nodes in the new node list corresponding to each node can be recorded in the node's historical access record. Thus, in the next iteration, these new nodes will be treated as old nodes. Simultaneously, the new node list and old node list corresponding to each node in the current iteration can be cleared, as well as the sampling record corresponding to each node in the current iteration (i.e., clearing all the first sampling nodes in the current iteration), to prepare for the next iteration.

[0062] In this way, during the first construction phase, the shared resource pool and batch matrix multiplication significantly improve the speed of initial iterations of the nearest neighbor graph, enabling the graph structure to evolve rapidly from a low-quality state to a high-quality state, effectively improving the convergence speed of the graph structure. Furthermore, it avoids the complexity of managing the sampling process individually for each node, fully utilizing the massively parallel computing capabilities of the GPU to maximize parallelism. By dynamically managing the "new / old" labels, it ensures that the construction process can both explore new potential neighbors corresponding to nodes (new nodes) and effectively re-evaluate existing neighbors (old nodes), guaranteeing both efficiency and graph construction quality.

[0063] In one embodiment, when updating the neighbor lists of different nodes, existing technologies typically employ mutex locks or atomic operations to ensure data consistency when multiple threads concurrently modify the same neighbor list. However, in highly parallel GPU architectures, such synchronization mechanisms can lead to severe thread blocking and resource contention, significantly limiting parallel efficiency. Therefore, there is an urgent need for a neighbor list update method that does not require explicit locks and can fully utilize the parallel capabilities of GPUs. To this end, this application proposes a lock-free parallel update mechanism based on "deterministic position calculation." This mechanism involves pre-calculating the unique and deterministic position index of each neighbor node to be inserted into the neighbor list in the final merged neighbor list, and then using atomic operations to directly write the neighbor node into the neighbor list according to this position index, thereby completely eliminating the overhead caused by synchronization locks. Therefore, the step of determining the neighbor list in S103 above can be implemented according to the following steps A1 to A5: A1: For each node, based on the first distances corresponding to the node, determine the first candidate neighbor node of the node from the first sampled nodes.

[0064] In specific implementation, during the current iteration, for each node v, based on the first distance between node v and each first sampling node, first candidate neighbor nodes whose first distance is less than a preset distance can be selected from the first sampling nodes. Alternatively, the first sampling nodes of node v can be sorted in ascending order of the first distance, and the first sampling nodes whose sorting order is less than the preset order can be used as the first candidate neighbor nodes of node v in the current iteration. Alternatively, all the first sampling nodes of node v in the current iteration can be directly used as the first candidate neighbor nodes of node v in the current iteration.

[0065] A2: In the shared memory of a thread block allocated to a node, sort the first candidate neighbor nodes of the node in ascending order according to the first distance to obtain the candidate list of each first candidate neighbor node.

[0066] In specific implementation, for any node v, when updating the first neighbor node list, it corresponds to two lists: one is a list of all first candidate neighbor nodes, and the other is the first neighbor list obtained by that node after the previous iteration (this list is defined as the Current Neighbor List). Furthermore, when calculating the first distance between node v and each first sampled node, the node has already been allocated to a thread block in the GPU. This is because within this thread block, the first sampled nodes can be sorted in ascending order according to their first distance, within the shared memory of that thread block, to obtain a candidate list of first candidate neighbor nodes. The sorting position of each first candidate neighbor node in the candidate list is defined as the first sorting index. Optionally, for any node v, when updating the neighbor list, a new thread block can be allocated for that node v, and the shared content of that thread block can be sorted to obtain the Candidate List.

[0067] Furthermore, node v's Current Neighbor List is usually already sorted by distance in shared memory, so there is no need for repeated sorting. The sorting position of each existing neighbor node in the Current Neighbor List is defined as the second sorting index.

[0068] In this way, by determining the Candidate List and the Current Neighbor List, an ordered set of basic data can be provided for subsequent binary search and location calculation, ensuring the accuracy and efficiency of the location calculation process.

[0069] A3: From the threads included in the thread block, assign a target thread to each first candidate neighbor node and each first neighbor node in the first neighbor list.

[0070] In practice, a thread block can include multiple threads. Therefore, for any node v, within the thread block allocated to node v, an independent target thread can be assigned to each first candidate neighbor node in the Candidate List and each existing neighbor node in the Current Neighbor List. Optionally, if the threads within the thread block have sufficient processing power, multiple nodes can be assigned to the thread from the first candidate neighbor nodes and / or existing neighbor nodes. For ease of description, the assigned node for each target thread is defined as e.

[0071] A4: Use each target thread to determine the relative ranking of the assigned node in the peer list; where the candidate list and the first neighbor list are peer lists to each other.

[0072] Here, the relative rank (Rank) represents the insertion position of object e in the list of objects, i.e., rank_opponent(e). The Candidate List and the Current Neighbor List are mutually exclusive lists. For any object e, if e belongs to the Candidate List, its relative rank in the Current Neighbor List needs to be calculated; conversely, if e belongs to the Current Neighbor List, its relative rank in the Candidate List needs to be calculated.

[0073] Taking the example that each target thread is responsible for one assigned node e, the rank_opponent(e) of the assigned node e under its responsibility can be calculated in parallel in the shared memory of the thread block using a binary search method.

[0074] In this way, by calculating rank_opponent(e), the "size" relationship of each assigned node relative to the opposing list can be precisely quantified, providing a key basis for determining the global position of the assigned node in the final merge list.

[0075] A5: Determine the list of first neighbors for each node in the current iteration based on the relative ranking of each assigned node.

[0076] In practice, for each assigned node e, the displacement index position of each node in the first neighbor list corresponding to the current iteration can be determined according to its relative ranking and its position index in its own list. Then, according to this unique index position, the assigned node e is written into the first neighbor list corresponding to the current iteration in global memory.

[0077] Understandably, different nodes can synchronously utilize different thread blocks to determine the first neighbor list corresponding to the current iteration in parallel according to steps A1 to A5.

[0078] In one embodiment, A5 can be implemented according to the following steps: A5-1: Determine the write location of each assigned node in the GPU's global memory based on the position index of each assigned node in its own list, its relative ranking in the object list, and the node priority of the assigned node.

[0079] Here, node priority is used to indicate the importance of a node, and node priority can be represented by a preset secondary key. The preset secondary key can be, for example, the size of the node identifier. The list to which the assigned node e belongs is the list in which the assigned node e resides. If the assigned node e belongs to the Candidate List, its position index in the list is the first position index; if the assigned node e belongs to the Current Neighbor List, its position index in the list is the second position index. For ease of description, the position index of the assigned node e in the list is defined as pos_self(e). The write position is used to indicate the final position index final_index(e) of the assigned node e in the GPU's global memory.

[0080] In practice, for each assigned node e, its pos_self(e) and rank_opponent(e) can be added together to obtain the final position index final_index(e). That is, final_index(e) = pos_self(e) + rank_opponent(e), where pos_self(e) represents how many elements "before" e in its own list, and rank_opponent(e) represents how many elements "before" e in its counterpart list. The sum of these two values ​​gives the absolute position e should occupy in the merged list.

[0081] Furthermore, to avoid conflicts between `final_index(e)` values, it can be further determined whether there is a consistent value among the various `final_index(e)` values. If so, the `final_index(e)` can be updated using the secondary keys such as the node ID of the consistent `final_index(e)` values, thereby ensuring that each assigned node `e` has a unique, globally consistent final position index. In this way, by generating a unique, deterministic global position index, the foundation for subsequent lock-free writes can be laid.

[0082] A5-2: Utilize the target thread and employ lock-free writing based on atomic operations to write each allocated node into global memory in parallel according to the write position.

[0083] In practice, each target thread can utilize CUDA's atomic operations to simultaneously write each allocated node e to its corresponding location in the pre-allocated global memory, according to the final_index(e) of the allocated node e. Atomic operations can be, for example, atomicAdd or atomicCAS.

[0084] Thus, since final_index(e) is pre-calculated and ideally unique (or its uniqueness can be guaranteed by secondary keys such as node ID), multiple target threads can simultaneously write to different addresses of the allocated node e without conflict. Therefore, based on the final_index(e) calculated in this application, parallel writing of all nodes to be allocated can be completed safely and efficiently without using any locks, maximizing the parallel throughput of the GPU.

[0085] A5-3: Based on the first distance between each assigned node and the node in global memory, select each first neighbor node in the first neighbor list corresponding to the assigned node in the current iteration.

[0086] In practice, during the current iteration, for any node v, after writing all assigned nodes to that node into global memory, a merged list of length len(Candidate List) + len(Current Neighbor List) is obtained. len(Candidate List) is the length of the Candidate List, and len(Current Neighbor List) is the length of the Current Neighbor List. Since the number of nodes in this merged list is greater than a first preset number, to meet the sparsity requirement of the graph index, a Top-k Selection Stage is needed to select the k closest nodes from this long list as a new Current Neighbor List. This simplifies the merged list into a first neighbor list containing the first preset number of neighbor nodes. During the Top-k Selection Stage, the assigned nodes are sorted according to their first distance from node v, in ascending order of the first distance. The assigned nodes whose sorting order is less than or equal to k are selected as the first neighbor nodes of node v in the current iteration's corresponding first neighbor list.

[0087] For example, the `thrust::sort` function can be used to sort the merged list in ascending order based on the first distance between each assigned node and the node in the first neighbor list. Then, the top k nodes are selected as the first neighbor nodes of node v in the current iteration. In this way, the Top-K selection phase can be completed quickly in shared memory, and the size of the final output first neighbor list remains constant at k, maintaining the quality of the graph structure and query efficiency.

[0088] To facilitate understanding, the following is a specific example illustrating the process of the lock-free parallel update mechanism provided in this application: Assume the node requiring lock-free parallel update is v1, and v1's Current Neighbor List is [A, B, C], where the three existing neighbor nodes A, B, and C are sorted by distance, with indices 0, 1, and 2 respectively. v1's Candidate List is [D, E], where the two first-candidate neighbor nodes D and E are also sorted by distance, with indices 0 and 1 respectively. The graph degree k=3, meaning the first-candidate neighbor list needs to retain 3 neighbor nodes. For simplicity, assume the first distance value of all nodes is known, and there are no cases where distances are equal. The lock-free parallel update mechanism for v1 can include: 1. Sorting: The Candidate List is sorted to [D, E]. The Current Neighbor List is sorted to [A, B, C]. Load nodes A, B, C, D, and E into shared memory.

[0089] 2. Position Calculation: Assign a target thread to each of the 5 nodes (A, B, C, D, E).

[0090] Target thread 1 (node ​​A): Perform a binary search in the candidate list [D, E]. Assuming that A should be inserted after E, then rank_opponent(A) = 2.

[0091] Target thread 2 (node ​​B): Perform a binary search in the candidate list [D, E]. Assuming that B should be inserted between D and E, then rank_opponent(B) = 1.

[0092] Target thread 3 (node ​​C): Perform a binary search in the candidate list [D, E]. Assuming that C should be inserted before D, then rank_opponent(C) = 0.

[0093] Target thread 4 (node ​​D): Perform a binary search in the current neighbor list [A, B, C]. Assuming that D should be inserted between B and C, then rank_opponent(D) = 2.

[0094] Target thread 5 (node ​​E): Perform a binary search in the current neighbor list [A, B, C]. Assuming that E should be inserted after C, then rank_opponent(E) = 3.

[0095] 3. Index determination: Node A: final_index(A) = pos_self(A) + rank_opponent(A) = 0 + 2 = 2; Node B: final_index(B) = 1 + 1 = 2 (a conflict occurs here, indicating that A and B are equivalent in the merged list and need to be optimized and sorted by the secondary key); Node C: final_index(C) = 2 + 0 = 2 (conflict again); Node D: final_index(D) = 0 + 2 = 2 (conflict again); Node E: final_index(E) = 1 + 3 = 4.

[0096] 4. Atomic write: Target threads 1 to 4 all attempt to write to index 2 of the global memory. Due to conflicts, in the actual implementation, the tie needs to be broken by secondary keys such as node IDs to ensure that each final_index is unique. For example, it is stipulated that the node with a smaller ID has priority. Assuming A < B < C < E < D, then A is written at index 2 finally, B is written at index 3, C is written at index 4, D is written at index 6, and target thread 5 writes E at index 5.

[0097] Finally, the merged list in the global memory is: [?, ?, A, B, C, E, D] (where "?" represents the unfilled空位).

[0098] 5. Top - K selection: Sort the merged list in the global memory by distance to obtain the final order, such as [A, D, B, E, C].截取 the first K = 3 nodes to get a new first neighbor list: [A, D, B], and this first neighbor list will be used as the Current Neighbor List for the next iteration.

[0099] Generally speaking, in the first construction stage of this application, by utilizing the powerful parallel computing ability of the GPU, based on the "shared sampling" strategy combined with efficient batch distance calculation and lock - free update mechanism, it can achieve fast convergence in the initial stage with low graph quality.

[0100] S104: In the second construction stage, for each node, use the GPU to determine the second target neighbor list of the node according to the data vector of the node and the first target neighbor list.

[0101] Here, the core goal of the second construction stage is to ensure that more accurate neighbor nodes are discovered for each node through a more refined individual sampling strategy at a high recall rate (such as > 95%), to avoid neighbor omission caused by shared sampling, and to solve the problem of slow convergence in the later stage of the "shared sampling" in the first construction stage, so as to maintain a high - efficient convergence speed in the later stage with high graph quality.

[0102] The second target neighbor list is the neighbor list optimized for node v after the second construction phase. In the second construction phase, instead of using a shared resource pool for node sampling, each node's first target neighbor list is used to sample independently, thereby accurately optimizing the neighbor nodes for each node.

[0103] In practice, after switching to the second construction phase, for each node, a thread block in the GPU can determine the second target neighbor list of the node through iterative optimization based on the data vector corresponding to the node and the first target neighbor lists of each node in the first target neighbor list of the node.

[0104] In one embodiment, the above-described S104 can be implemented according to the following steps: S104-1: In the second construction phase, for each node, the second candidate neighbor node corresponding to the node in the current iteration is determined from the second neighbor list obtained in the previous iteration; wherein, if the current iteration is the first iteration of the second construction phase, the second neighbor list is the first target neighbor list.

[0105] Here, the second construction phase can be performed after the first construction phase, iteratively optimizing the first target neighbor list for each node based on the first construction phase's optimized first target neighbor list. This results in a more accurate second target neighbor list for each node. The multiple iterations of the second construction phase can be divided into initial iterations and non-initial iterations. For the initial iteration, the second neighbor list for each node can be the first target neighbor list constructed for each node, which includes a first preset number of neighbor nodes corresponding to that node. For any non-initial iteration, after the iteration is completed, a new second neighbor list for each node can be obtained, where each node's second neighbor list includes the first preset number of neighbor nodes corresponding to that node.

[0106] In specific implementation, the second construction phase no longer uses a shared resource pool, but instead adopts a strategy of independent sampling for each node. Specifically, for each iteration of the second construction phase, if the current iteration is the first iteration, the first target neighbor list obtained in the first construction phase can be used as the second neighbor list of the node. Then, for each node, from the neighbor nodes included in the node's second neighbor list, the m closest second candidate neighbor nodes corresponding to the first iteration are selected. The value of m can be set empirically, and this embodiment does not impose a specific limitation. For example, m can be equal to 2. If the current iteration is not the first iteration, the second neighbor list obtained for each node after the previous iteration can be obtained, and from the second neighbor list obtained for each node, the m closest second candidate neighbor nodes corresponding to the non-first iteration are selected for each node. In this way, by independently selecting the m nearest neighbors (top-m NN) of each node v from its second neighbor list as candidate sources, it can be ensured that the second sampling nodes in subsequent sampling are closer to node v.

[0107] S104-2: Based on the second neighbor list obtained by each second candidate neighbor node in the previous iteration and the historical access list corresponding to the node, determine the second sampling node corresponding to the node in the current iteration; the historical access list includes the second sampling nodes selected in each historical iteration in the second construction phase.

[0108] Here, the historical access list indicates the sampled nodes that have been selected for a node in each historical iteration during the second construction phase. Implementing a non-revisit sampling strategy based on the historical access list allows for the exclusion of already processed nodes in subsequent iterations, eliminating redundant computations. In specific implementation, in the current iteration, for each node v, based on each node in the historical access list of node v, the second neighbor list of each second candidate neighbor node of node v obtained in the previous iteration is traversed, and nodes that were not visited in the previous iteration are extracted for node v as the second sampling nodes corresponding to node v in the current iteration. The number of second sampling nodes selected can be a third preset number, which can be selected based on experience or the parallel processing capability of the thread block.

[0109] Optionally, when extracting a second sampling node for node v, the system can simultaneously determine whether to include the extracted node as the second sampling node for the current iteration based on the historical access list of the extracted node u. For example, if the extracted node u is not in its historical access list, it means that node v has never been visited by node v in previous iterations, and it can be included as the second sampling node and added to the new node list for the current iteration, while also being recorded in its own historical access list. If the extracted node u is in its historical access list, it means that node v has already been visited by node v in previous iterations, and it can be excluded from inclusion as the second sampling node for the current iteration, while being recorded in the old node list for the current iteration.

[0110] S104-3: Using a thread block in the GPU, calculate the second distance between the node and each second sampling node based on the node's data vector and the data vector of the second sampling node corresponding to the node in the current iteration.

[0111] Here, since each sampling in the second construction phase is performed individually for node v, it is not possible to construct a unified large matrix for batch multiplication as in the first construction phase. Therefore, the distance calculation in each iteration of the second construction phase can adopt a "node-centered" parallel mode. That is, different thread blocks are used to calculate the second distance between each node and the second sampling node in parallel.

[0112] In practice, for the current iteration, thread blocks can be allocated to each node v. Specifically, each node v and its corresponding second sampling node in the current iteration can be assigned to an independent thread block. That is, if N nodes participate in the iteration of the second construction phase, N thread blocks in the GPU will be launched. Then, for each node v, the allocated thread block can be used to synchronously load the number vector of node v and the data vectors of each second sampling node corresponding to node v in the current iteration into the shared memory of the thread block. Then, using each thread in the thread block, based on the data vector in the shared memory, vector-matrix multiplication is performed between the matrix formed by the data vector of node v and the data vectors of each second sampling node to obtain the second distance between node v and each second sampling node. Each thread in the thread block can be used to calculate the second distance between the data vector of node v and one or more second sampling nodes. In this way, by calculating the second distance between the node and each second sampling node in parallel through vector-matrix multiplication, the sampling accuracy can be guaranteed while maximizing the efficiency of distance calculation.

[0113] S104-4: Based on the second distance and the second neighbor list, determine the second neighbor list corresponding to the node in the current iteration, and update the second sampling node corresponding to the current iteration to the historical access list corresponding to the node.

[0114] In specific implementation, the process of updating the second neighbor list of a node in the current iteration based on the second distance and the second neighbor list obtained in the previous iteration during each iteration of the second construction phase can also be implemented based on the lock-free parallel update mechanism described above. Therefore, the specific implementation process of updating the second neighbor list of a node in each iteration can refer to the process of updating the first neighbor list of a node in each iteration based on the first distance and the first neighbor list described above (that is, refer to the process A1 to A5 described above), and will not be repeated here.

[0115] Furthermore, after obtaining the list of second neighbors for each node in the current iteration, the second sampled node sampled for each node in the current iteration can be updated to the historical access list of the corresponding node, so that it can be regarded as a visited "old node" in the next iteration. At the same time, the temporary sampling record corresponding to the current iteration can be cleared to make accurate preparations for the next iteration.

[0116] S104-5: Return the steps of determining the second candidate neighbor node of the node in the current iteration from the second neighbor list obtained from the previous iteration, until the second preset cutoff condition is met, and obtain the second target neighbor list of the node.

[0117] In practice, after completing the current iteration, a list of second neighbors for each node in the current iteration is obtained. Then, it is determined whether the second cutoff condition is met. The second cutoff condition may include the number of iterations reaching a preset number and / or the percentage change in the number of nodes between the second neighbor lists obtained by each node in two consecutive iterations being less than a specific percentage. If so, the second neighbor list corresponding to the current iteration is used as the second target neighbor list, ending the second construction phase. If not, the process returns to the step "determine the second candidate neighbor node" in S104-1 for the next iteration. This iterative process continues until the second cutoff condition is met, and the second neighbor list optimized for each node in the latest iteration is used as the node's second target neighbor list.

[0118] In this way, by sampling independently for each node and using a node-centric parallel model, more accurate neighbor nodes can be found even with high recall, avoiding the potential omission of neighbor nodes that might occur with shared sampling in the first construction phase. This achieves precise optimization and improves the quality of the graph structure. It also effectively solves the problem of slow graph convergence in the later stages of the first construction phase, enabling the entire graph construction process to run continuously and efficiently under high accuracy requirements. Furthermore, by utilizing a non-revisit strategy based on a historical visit list, already visited nodes can be excluded in each iteration, eliminating redundant computation and improving computational efficiency.

[0119] This application, based on a two-stage parallelization algorithm, achieves a seamless transition from "coarse-grained rapid convergence" to "refined and precise optimization," ensuring both the speed and quality of graph structure construction. Furthermore, by combining a lock-free neighbor update mechanism, it fully utilizes the parallel capabilities of the GPU, significantly improving the efficiency of graph structure construction and neighbor update.

[0120] S105: Based on the second target neighbor list, construct the target nearest neighbor graph corresponding to each data item.

[0121] In practice, a K-NN graph including each node v can be constructed based on the neighbor nodes included in the second target neighbor list of each node v. Alternatively, existing pruning techniques can be used to prune each node v according to its second target neighbor list, and the target nearest neighbor graph corresponding to each data point can be obtained based on the pruning results.

[0122] In one embodiment, in a graph-based Approximate Nearest Neighbor Search (ANNS) system, pruning is a key step in building a high-quality index, which can improve the quality of the constructed nearest neighbor graph. For example, typical pruning strategies in the prior art (such as NSG, Vamana, NSSG, DPG, CAGRA, etc.) optimize the navigation and connectivity of the graph by filtering redundant edges in the initial k-NN graph. However, existing pruning methods face two major technical bottlenecks on GPUs: 1. Serial dependency bottleneck: Pruning strategies such as NSG and Vamana need to verify the relationship between candidate neighbor nodes and existing neighbor nodes in the initial k-NN graph one by one (such as pruning based on the Relative Neighborhood Graph (RNG) condition), which has strong data dependencies and is difficult to parallelize; 2. Load imbalance bottleneck: Although strategies such as CAGRA can prune in parallel, the "hub node" phenomenon in high-dimensional data vectors leads to significant differences in the computational cost of different candidate neighbor nodes, resulting in a serious load imbalance between GPU thread blocks and low hardware utilization. Therefore, existing pruning implementations on GPUs (such as CAGRA) either only partially accelerate the process or fail to address the fundamental issues mentioned above, thus failing to achieve efficient pruning while maintaining index quality. Therefore, this application can also construct an initial k-NN graph based on the second target neighbor list after obtaining it. Furthermore, to ensure compatibility with multiple pruning strategies and improve the parallelism of pruning on GPUs, this application also provides a unified GPU-based pruning method. This method proposes a unified pruning process consisting of three stages: collection, filtering, and storage, decoupling the pruning operation into standardized modules, thereby achieving efficient pruning of the initial k-NN graph.

[0123] Specifically, for the above S105, the following steps can be taken: S105-1: Select the target pruning strategy from a variety of preset node pruning strategies; the preset node pruning strategies include batch parallel pruning strategy and load balancing pruning strategy.

[0124] Here, the preset node pruning strategy is an optimized pruning method designed for various pruning strategies in the prior art. Specifically, by providing a general adaptation interface for strategies such as NSG / Vamana / NSSG / CAGRA, targeted optimizations for various pruning strategies are achieved. For example, for pruning algorithms such as NSG, Vamana, DPG, and NSSG in the prior art, since these algorithms often do not have the capability to implement parallel pruning on the GPU, this application sets up a batch-parallel pruning strategy for such algorithms to achieve parallel pruning on the GPU. For pruning algorithms such as CAGRA in the prior art, although these algorithms often have the capability to implement parallel pruning on the GPU, there is a serious problem of load imbalance between thread blocks in the GPU during parallel pruning. Therefore, this application proposes a balanced parallel pruning strategy for such algorithms to achieve load balancing between GPU thread blocks.

[0125] The target pruning strategy can be determined based on the type of pruning method selected, which may include NSG, Vamana, DPG, NSSG, CAGRA, etc.

[0126] In practical implementation, if pruning strategies rely on pruning algorithms such as NSG, Vamana, DPG, and NSSG, then batch parallel pruning can be used as the target pruning strategy. If pruning relies on the CAGRA pruning algorithm, then load balancing pruning can be used as the target pruning strategy.

[0127] S105-2: For each node, based on the node filtering method corresponding to the target pruning strategy, filter out the third candidate neighbor node corresponding to the node from the second target neighbor list corresponding to the node.

[0128] Here, different target pruning strategies can correspond to different node selection methods. For example, when the target pruning strategy is a batch parallel pruning strategy, there are three node selection methods. The first is a 1-hop neighbor selection method, that is, for each node in the initial k-NN graph, the node's direct neighbors in the initial k-NN graph are used as the third candidate neighbor nodes. The second is a 2-hop neighbor selection method, that is, for each node in the initial k-NN graph, the node's one-hop and two-hop neighbors in the initial k-NN graph are used together as the third candidate neighbor nodes. The third method is a path-based selection method, that is, for each node in the initial k-NN graph, a batch greedy search is performed starting from that node in the initial k-NN graph, collecting all nodes on the search path as the third candidate neighbor nodes. The termination condition of the batch greedy search can be that a node at the target depth is found in the initial k-NN graph, and / or the distance between the found node and the starting point is greater than a preset distance value. When the target pruning strategy is a load balancing pruning strategy, there is a corresponding node filtering method, which can be a path-based filtering method.

[0129] In practice, during the collection phase, for each node v in the initial k-NN graph, each third candidate neighbor node can be selected from the neighbor nodes included in the second target neighbor list corresponding to node v according to any node filtering method corresponding to the target pruning strategy.

[0130] Thus, by supporting three node selection methods to collect third candidate neighbor nodes for each node, this application can achieve compatibility with various existing pruning strategies.

[0131] S105-3: Invoke the thread block in the GPU according to the GPU invocation method that matches the target pruning strategy, and determine the target neighbor node corresponding to the node from the third candidate neighbor nodes according to the target pruning strategy.

[0132] Here, different target pruning strategies can correspond to different GPU calling methods. For example, the batch parallel pruning strategy corresponds to calling GPU thread blocks in batches; the load balancing pruning strategy corresponds to calling GPU thread blocks to balance the amount of computation.

[0133] In practice, for the initial k-NN graph, the GPU can invoke various thread blocks in the GPU according to the GPU invocation method that matches the target pruning strategy. Then, the thread blocks use the target pruning strategy and the third candidate neighbor nodes of each node to remove redundant edges from the connection edges of each node in the initial k-NN graph, thereby obtaining the target neighbor nodes corresponding to each node. The target neighbor nodes corresponding to any given node are the final optimized neighbor nodes for that node.

[0134] Because this application sets different preset node pruning strategies for different pruning methods, it also sets different GPU kernel designs for each preset node pruning strategy, thereby achieving pruning optimization under different preset node pruning strategies. The pruning optimization process corresponding to different preset node pruning strategies will be explained in detail below: In one embodiment, when the target pruning strategy is a batch parallel pruning strategy, the above S105-3 can be implemented according to the following steps B1~B5: B1: Based on the preset node batch size, divide each third candidate neighbor node into multiple node batches and process each node batch in sequence.

[0135] Here, the preset node batch size indicates the number of nodes that can be processed in each batch, and each node batch includes no more than that number of third candidate neighbor nodes. The third candidate neighbor nodes included in different batches are different.

[0136] When the target pruning strategy is Batch-Parallel Pruning, the core objective is to transform the traditional sequential pruning process into a single-round, multi-batch, fully parallel GPU execution mode, provided that the initial k-NN graph has already been constructed. Traditional pruning methods (such as NSG, NSSG, Vamana, etc.) require candidate neighbor nodes to be inserted into the node's nearest neighbor list one by one, and to compare constraints with all existing neighbor nodes in the current nearest neighbor list before each insertion, forming a strong data dependency chain that cannot be directly parallelized. This application utilizes the monotonicity of pruning constraints (i.e., once a candidate node is determined to be invalid, subsequent insertion operations will not make it valid again) to perform a one-time batch partitioning of each node's third candidate neighbor nodes, and complete the parallel pruning of all batches in a single round of execution, thereby efficiently mapping to the GPU architecture.

[0137] In the Batch-Parallel Pruning strategy, the batch, as the core abstraction, is created by dividing the third candidate neighbor nodes of each node into several batches according to certain rules (such as randomness or a specific order). Each batch constitutes a "processing unit." For example, the first batch of third candidate neighbor nodes forms the "first batch," the second batch forms the "second batch," and so on. Simultaneously, this strategy prunes nodes through intra-batch parallelism and inter-batch dependency. Intra-batch parallelism means that within a batch, the various third candidate neighbor nodes included in that batch can be allocated to different thread blocks in the GPU for parallel processing. Inter-batch dependency refers to the fact that when evaluating whether a third candidate neighbor node included in a batch can be used as a target neighbor node, it only needs to be compared with the target neighbor node that has been successfully determined in the previous batch, without waiting for the processing results of other third candidate neighbor nodes in the current batch. This breaks the original serial dependency chain and realizes inter-batch parallelism.

[0138] In practice, after determining the third candidate neighbor nodes corresponding to each node (such as 1-hop or 2-hop neighbor nodes from the collection phase), node batching operations can be performed. For example, for each node, the third candidate neighbor nodes of that node can be divided into multiple node batches (such as batch1, batch2, ...) according to the pre-defined node batch size, and then the third candidate neighbor nodes in each node batch can be processed sequentially.

[0139] B2: For the current batch of nodes being processed, invoke a thread block from the GPU for each third candidate neighbor node in the batch.

[0140] In practice, for the current batch of nodes being processed, a separate thread block can be invoked from the various thread blocks included in the GPU for each third candidate neighbor node in that batch. That is, the GPU can launch a number of thread blocks equal to the number of third candidate neighbor nodes in the current batch, and each thread block is responsible for one third candidate neighbor node in the current batch.

[0141] B3: Utilize the threads in each called thread block to determine in parallel the constraint values ​​between the third candidate neighbor node and each retained neighbor node obtained after the previous node batch processing under the batch parallel pruning strategy; wherein, if the current node batch being processed is the first node batch, then each retained neighbor node obtained after the previous node batch processing is empty.

[0142] Here, the retained neighbor nodes are those nodes that are selected from the third candidate neighbor nodes after processing the processed node batches, and are likely to be used as target neighbor nodes. If the current node batch being processed is the first node batch, the retained neighbor nodes obtained after processing the previous node batch can be empty, or they can be preset base neighbor nodes, which can be preset according to the pruning algorithm they depend on.

[0143] In practice, for any given node, after dividing it into batches, an empty final neighbor list can be initialized synchronously. Then, when the currently processed batch is the first batch, threads within each called thread block can be used to calculate the constraint values ​​of each third candidate neighbor node in parallel with the retained neighbor nodes in the initialized final neighbor list under the batch parallel pruning strategy. Here, since the initialized final neighbor list is empty, the constraint values ​​corresponding to each third candidate neighbor node in the first batch can be based on preset values ​​that satisfy the constraint conditions. At this point, each third candidate neighbor node in the first batch can be used as the retained neighbor nodes obtained after processing the current batch. Simultaneously, the constraint values ​​between each third candidate neighbor node and the current node under the batch parallel pruning strategy can be determined.

[0144] B4: Based on the constraint values, determine the remaining neighbor nodes obtained after batch processing of the current node from the third candidate neighbor nodes.

[0145] Here, the batch parallel pruning strategy can correspond to different preset pruning conditions under different pruning methods. For example, when relying on the NSG / Vamana algorithm, a greedy search method can be used to collect each third candidate neighbor node for each node. Then, after dividing the nodes into batches, the preset pruning condition can be that the third candidate neighbor node in any batch of nodes is a candidate neighbor node. If the constraint value satisfies the following Formula 1, it is considered a reserved neighbor node: (Formula 1) When using the NSG algorithm, =1,;When using the Vamana algorithm It can be a preset value greater than 1; PThis represents a node that is currently being pruned. R This represents the final set of neighbors consisting of the identified target neighbor nodes. express R One of the target neighbor nodes. express P and The Euclidean distance between them, that is P and The constraint values ​​between them. express and The constraint values ​​between them.

[0146] When relying on the DPG algorithm, each node can collect its third candidate neighbor nodes using a 1-hop or 2-hop approach. After dividing the nodes into batches, the preset pruning condition can be that a node has a third candidate neighbor node if and only if the node has a third candidate neighbor node in any given batch. If the constraint value satisfies the following Formula 2, it is considered a reserved neighbor node: (Formula 2) in, Indicates from P point to ; Indicates from P point to ; express and The angle between them, that angle is also The constraint value; This indicates the preset minimum angle, such as 60°.

[0147] When relying on the NSSG algorithm, each node can collect its third candidate neighbor nodes using a 1-hop or 2-hop approach. After dividing the nodes into batches, the preset pruning condition is to maximize the sum of the angles between each target neighbor node and a currently pruned node when the third candidate neighbor node is used as the target neighbor node. Specifically, the constraint values ​​between the third candidate neighbor node and existing neighbor nodes can be used to filter out nodes to be inserted from the third candidate neighbor nodes. Then, based on the angle between the node to be inserted and a currently pruned node, and the angle between existing target neighbor nodes and a currently pruned node, the following formula (Formula 3) is maximized as the objective to select retained neighbor nodes from the nodes to be inserted: (Formula 3) Where R represents the identified target neighbor node and the node to be inserted; P This represents a node that is currently being pruned.

[0148] Using Formula 3 as the preset pruning condition, a greedy insertion method can be used to make the distribution of neighboring nodes cover the spherical direction as evenly as possible, thereby improving the search efficiency of the graph.

[0149] In practice, the system can determine whether a third candidate neighbor node meets the preset pruning conditions based on one or more of the constraint values ​​between the third candidate neighbor node and the retained neighbor node, the constraint values ​​between the third candidate neighbor node and the current node, and the constraint values ​​between the retained neighbor node and the current node, as well as the preset pruning conditions corresponding to the target pruning strategy. If it does, the third candidate neighbor node is treated as a retained neighbor node after batch processing of the current node; otherwise, it is removed. It can be assumed that the constraint values ​​of all third candidate neighbor nodes in the first node batch meet the preset pruning conditions, so all third candidate neighbor nodes in the first node batch can be treated as retained neighbor nodes and marked as insertable, stored in shared content or global memory.

[0150] For non-first node batches, the constraint values ​​of each third candidate neighbor node in the node batch, as well as the constraint values ​​of the retained neighbor nodes determined in the previous node batch and the current node and the third candidate neighbor nodes respectively, can be used to select each retained neighbor node obtained after processing the node batch from each third candidate neighbor node in the node batch and the retained neighbor nodes determined in the previous node batch.

[0151] For example, for the i-th (i>1)th node batch, the same number of thread blocks can be started based on the number of third candidate neighbor nodes in that node batch, with one thread block responsible for one third candidate neighbor node. Then, each thread block can load all reserved neighbor nodes from the (i-1)-th (i-1)-th node batch into its local register or shared memory from global memory or shared memory. Then, each thread block performs parallel constraint evaluation; that is, within each thread block, the threads work together to calculate the constraint values ​​(such as angles) between the responsible third candidate neighbor node and all reserved neighbor nodes in the (i-1)-th node batch. Or distance dis). Then each thread block can make parallel decisions, that is, according to the preset pruning conditions corresponding to the pruning algorithm it relies on (such as the conditions described in any of formulas one to three above), each thread block independently judges whether the third candidate neighbor node it is responsible for meets the preset pruning conditions. If it does, the third candidate neighbor node it is responsible for is treated as a new retained neighbor node and marked as insertable, and the next round of iteration is obtained. If not, the third candidate neighbor node it is responsible for is removed. In this way After processing all third candidate neighbor nodes in the i-th node batch, all reserved neighbor nodes marked as insertable in the i-th node batch, as well as all reserved neighbor nodes in the (i-1)-th node batch, can be combined into the final neighbor list as the reserved neighbor nodes corresponding to the i-th node batch. Then, the processing of the next node batch continues, repeating B2~B4 above, until all node batches are processed, and the reserved neighbor nodes corresponding to the last node batch are obtained.

[0152] B5: Select the remaining neighbor nodes obtained after batch processing of the last node as the target neighbor nodes of the node.

[0153] In practice, the remaining neighbor nodes obtained after batch processing of the last node can be used as the target neighbor nodes of the node and merged into the final neighbor list of the current node in batches. Then, the final neighbor list can be written from shared memory or local registers back to the graph index structure in global memory.

[0154] In this way, by transforming the serial dependencies in the pruning process of traditional algorithms such as NSG, Vamana, DPG, and NSSG into finite dependencies between batches, the parallel potential of the GPU is greatly unleashed. This allows pruning operations that were originally impossible to parallelize to be executed efficiently, breaking through the bottleneck of serial computing and improving pruning efficiency. Furthermore, the batch parallel pruning strategy of this application only requires modification to the constraint evaluation code to adapt to various pruning strategies based on sequence dependencies (such as NSG, NSSG, and DPG), demonstrating strong versatility. In addition, through reasonable batch partitioning and data loading, the parallel computing units and cache of the GPU are maximized, avoiding unnecessary synchronization overhead and achieving efficient utilization of GPU resources.

[0155] To facilitate understanding of the batch parallel pruning strategy provided in the embodiments of this application, specific examples will be used below for illustration: Suppose that the set of third candidate neighbor nodes determined for node A is {C, D, E, F}, and these nodes need to be inserted into node A's neighbor list according to the NSG strategy. The existing serial approach is: check if C can be inserted (compare with the existing neighbor list). If C can be inserted, update the neighbor list. Check if D can be inserted (compare with the new neighbor list containing C). And so on, ..., until the latest neighbor list is obtained. The batch parallel pruning strategy implemented in this application is executed as follows: The set {C, D, E, F} is divided into two node batches: Batch1 = {C, D}; Batch2 = {E, F}.

[0156] Batch 1 processing: Thread block 1 processes C: compared with the empty final neighbor list, it is found that C can be inserted.

[0157] Thread block 2 processes D: compared with the empty final neighbor list, it finds that D can be inserted.

[0158] Threads 1 and 2 process in parallel to avoid interference, resulting in {C, D} being marked as insertable and batched into an empty list of latest neighbors, thus obtaining the latest final neighbor list containing C and D.

[0159] Batch2 processing: Thread block 3 processing E: Load the first batch of results {C, D}, compare them with C and D respectively, and find that E does not meet the constraints and cannot be inserted.

[0160] Thread block 4 processes F: Load the first batch of results {C, D}, compare them with C and D respectively, and find that F satisfies the constraints and can be inserted.

[0161] The two thread blocks execute in parallel, resulting in: {F} being marked as insertable and batched into the first batch of the corresponding latest neighbor list, resulting in the latest final neighbor list containing C, D, and F.

[0162] In one embodiment, when the target pruning strategy is a load balancing pruning strategy, the above S105-3 can be implemented according to the following steps C1~C5: C1: Based on the relative ranking of each third candidate neighbor node in the third target neighbor list, select the first and second nodes from the third candidate neighbor nodes.

[0163] Here, in the initial k-NN graph, a node v corresponds to a third-target neighbor list, which includes all the third-candidate neighbor nodes corresponding to node v. The relative rank (Rank) is used to indicate the position of the third-candidate neighbor node in the third-target neighbor list.

[0164] The first node is the third candidate neighbor node whose relative rank is less than or equal to a preset rank b. The second node is each of the third candidate neighbor nodes in the third target neighbor list, excluding the first node. The preset rank b can be determined in advance through small-sample experiments. For example, CAGRA can be run on a representative subset to count the number of detour paths at each rank position, and the minimum b can be selected so that the coverage rate of the top b neighbor nodes in the final top-k retained edges is ≥99%. The representative subset can be a subset of nodes selected from the dataset, or a subset of nodes obtained through existing methods.

[0165] To facilitate understanding of the load balancing pruning strategy provided in this application, we will first explain unbalanced parallel pruning. Unbalanced parallel pruning refers to a pruning strategy where the computational cost of pruning is unevenly distributed across different candidate edges. Candidate edges are those edges in the initial k-NN graph that require pruning judgment. A candidate edge includes a node and its connected neighboring nodes. The CAGRA algorithm, as a typical example of unbalanced parallel pruning, prunes a candidate edge (v, u) by traversing all its neighbors w to check for a detour path v→w→u. Its computational cost depends on |N(u)|∩N(v)|, where N(u) represents the list of the third target neighbors of node u, and N(v) represents the list of the third target neighbors of node v.

[0166] For detour detection, we define dis(v, u) = posu = Ranku, where dis(v, u) represents the distance between the candidate edges of v and u, and posu represents the position of u in the third target neighbor list of v, which is the relative ranking of u in the third target neighbor list of v. If there is an intermediate node w in the candidate edge (v, u) that satisfies the detour pruning condition corresponding to Formula 4 below, we determine that there is a detourable path for the candidate edge (v, u): Max (dis (v, w), dis (w, u)) < dis (v, u); (Formula 4) Where dis(v, w) represents the distance between candidate edges between v and w, and dis(w, u) represents the distance between candidate edges between w and u. If there exists a node w between v and u that satisfies Formula 4 above, then the path v→w→u can be called a detourable route (v, u). Specifically, for any candidate edge (v, u), the source of its detour point w is: traversing the third target neighbor list N(u) of u; for each w∈N(u), determining whether w also belongs to the third target neighbor list N(v) of v; if it does, then w is determined as a possible detour point, and whether it belongs to a detourable route is determined by Formula 4 above.

[0167] Therefore, to avoid the load imbalance problem that occurs on GPUs with pruning algorithms such as CAGRA, this application proposes an optimized load balancing pruning strategy for pruning algorithms such as CAGRA.

[0168] In CAGRA, for a node v, the higher the relative ranking of its neighbor u, the more difficult it is to bypass the candidate edge (v, u). This makes it almost impossible for dis(v, u) = posu to be minimized and for the bypass pruning condition Max(dis(v, w), dis(w, u)) < dis(v, u) to hold. Therefore, the first b neighbors (pos∈[1, b]) can be safely skipped from the pruning calculation and directly retained.

[0169] In practical implementation, in the load balancing pruning strategy, for each node v in the initial k-NN graph, the relative ranking of each third candidate neighbor node of node v in the third target neighbor list can be determined first. Then, a small sample (e.g., 0.1% of the sample) is extracted from the dataset and CAGRA pruning is performed to analyze the distribution of traversable paths at each rank position, thereby determining the minimum offset b, so that the third candidate neighbor node pos∈[1, b] can safely skip the pruning. After determining b, for node v, the third candidate neighbor node with a relative ranking less than or equal to the preset ranking b can be taken as the first node, and the third candidate neighbor node with a relative ranking greater than the preset ranking b can be taken as the second node.

[0170] C2: Determine each node pair corresponding to the second node based on the relative ranking of each second node in the third target neighbor list corresponding to the node, the first number of the first node, and the second number of the third candidate neighbor nodes.

[0171] To achieve load balancing across thread blocks during node pruning, this application proposes a method of pairing second nodes to form node pairs, and assigning the nodes in the node pairs to the same thread block for pruning. Assuming the second number of third candidate neighbor nodes selected for each node v is k1, the effective pruning range is [b+1, k1]. In this case, there are h = k1 - b candidate edges that need pruning, where each candidate edge includes node v and a third candidate neighbor node. If two candidate edges (v, u1) and (v, u2) satisfy posu1 + posu1 = k + b + 1, then the computational complexity of the two candidate edges is complementary and balanced (lightweight computation + heavyweight computation), making pairing suitable. Here, u1 and u2 represent the two third candidate neighbor nodes of node v.

[0172] Therefore, in practical implementation, for each node v, based on the relative ranking posu of each second node u in the third target neighbor list corresponding to node v, the first number b of the first node, and the second number k1 of the third candidate neighbor nodes, two second nodes u1 and u2 that satisfy posu1 + posu1 = k1 + b + 1 can be considered as a node pair. Understandably, if the number of second nodes is odd, then a node pair refers to the existence of a second node u.

[0173] C3: Call the thread bundle in the thread block for each node pair based on the number of third candidate neighbor nodes of the second node in each node pair.

[0174] In practice, for each node pair, the number of third candidate neighbor nodes of the second node in the node pair can be used to determine the number of thread bundles in the required thread block. The second node and the third candidate neighbor nodes in the node pair are then assigned to the corresponding number of thread bundle warps. A thread block can include multiple thread bundles, and a thread bundle can include multiple threads.

[0175] In one embodiment, even after pairing the second node, the number of neighbors for the candidate edge between the second node and the current node may still far exceed the GPU's warp processing capacity. For example, when the third target neighbor list |N(u)| of the second node > 1000, a single warp cannot perform bypass detection on candidate edges formed by the second node u and more than 1000 third candidate neighbor nodes and the current node. Therefore, N(u) needs to be divided into multiple neighbor node subsets, with each neighbor node subset serving as an independent computing unit, thereby supporting finer-grained dynamic scheduling and load balancing. Therefore, C3 above can be implemented according to the following steps: Based on the number of third candidate neighbor nodes of the second node in each node pair and the parallel processing capability of the thread block, determine the corresponding neighbor node subset for each node pair, and call the thread bundle in the thread block for each neighbor node subset.

[0176] In practice, for each second node u in any node pair, based on the number of third candidate neighbor nodes in the third target neighbor list n(u) of the second node u, and the parallel processing capability of the thread block (such as the number of thread bundles in the thread block and the thread bundle processing capability), n(u) can be divided into multiple neighbor node subsets of a fixed size according to the thread bundle processing capability, and one thread bundle in the thread block can be called for each neighbor node subset. The neighbor node subset includes some of the third candidate neighbor nodes in n(u).

[0177] For example, for any node v, for each candidate edge (v, u) of node v that needs pruning (i.e., posu ∈ [b+1, k]), its third target neighbor list N(u) is divided into a subset of neighbor nodes of a fixed size. Then, for each second node corresponding to node v with posu1 ∈ [b+1, k1], its complementary position is (k1+b+1) - posu1. The second nodes that satisfy posu1 + posu2 = k1 + b+1 are paired, and the neighbor nodes of each paired second node are assigned to the same thread bundle for pruning.

[0178] In this way, by assigning a subset of neighboring nodes in the same node pair to the same thread bundle for processing, the processing responsibilities of each thread bundle and thread block can be made more consistent, thereby avoiding load imbalance and fully utilizing the performance of the GPU.

[0179] C4: Using the threads in each calling thread bundle, determine the number of traversable paths for each second node under the load balancing pruning strategy based on the third candidate neighbor nodes of each second node in the node pair.

[0180] In practice, after assigning different thread bundles to each node and its corresponding second node and third candidate neighbor node, each thread bundle can perform detour detection on the assigned second node in parallel according to the detour pruning conditions and the assigned third candidate neighbor node, so as to obtain the number of detour paths for each second node under the load balancing pruning strategy.

[0181] In one embodiment, C4 described above can be implemented according to the following steps: C4-1: For any third candidate neighbor node of any second node in a node pair, use one thread in any call's thread bundle to determine whether the third candidate neighbor node belongs to the third target neighbor list corresponding to the node.

[0182] In practice, for any node v, each second node (u1 or u2) in a node pair of v, and its third candidate neighbor node w, are assigned to different thread bundles for processing. For each thread bundle, each thread processes one assigned third candidate neighbor node w, where w ∈ N(u1) or N(u2). Here, N(u1) and N(u2) represent the third target neighbor lists corresponding to the two second nodes u1 and u2 in a node pair, respectively. Parallel computation is used across threads, specifically by each thread determining whether the assigned third candidate neighbor node w is located in node v's third target neighbor list n(v). If not, it is determined that the third candidate neighbor node w does not belong to the traversable path of u1 or u2. If so, C4-2 is executed below.

[0183] C4-2: If so, then use threads to determine the first relative ranking of the third candidate neighbor node in the third target neighbor list corresponding to the node, and determine the second relative ranking of the second node in the third target neighbor list corresponding to the third candidate neighbor node.

[0184] Taking a thread responsible for the third candidate neighbor node w of the second node u1 as an example, when the third candidate neighbor node w is located in the third target neighbor list n(v), the first relative ranking dis(v, w) of the third candidate neighbor node w in n(v) can be determined, and the second relative ranking dis(w, u1) of the second node u1 in the third target neighbor list n(w) corresponding to the third candidate neighbor node w can be determined.

[0185] C4-3: Based on the maximum value of the first relative ranking and the second relative ranking, and the third relative ranking of the second node in the third target neighbor list corresponding to the node, determine whether the path between the third candidate neighbor node and the node is a detourable path between the second node and the node.

[0186] In specific implementation, taking the example of a thread being responsible for the third candidate neighbor node w of the second node u1, we can also determine the third relative ranking dis(v, u1) of the second node u1 in the third target neighbor list n(v) of node v. Then, we check whether Max(dis(v, w), dis(w, u1)) < dis(v, u1) is true. If it is not true, we can determine that the third candidate neighbor node w does not belong to the traversable path between edge (v, u1). If it is true, we can determine that the edge (v, w) between the third candidate neighbor node w and node v belongs to the traversable path between edge (v, u1). We use atomicAdd to increment the traversable path counter of edge (v, u1) by 1 to obtain the latest number of traversable paths for the second node u1.

[0187] C4-4: Based on the judgment results of each thread in each calling thread bundle, determine the number of bypass paths for each second node under the load balancing pruning strategy.

[0188] Here, the result of the thread's judgment is used to indicate whether the third candidate neighbor node that the thread is responsible for is a traversable path of the second node.

[0189] In practice, after each thread in each calling thread bundle has completed its judgment, the number of traversable paths for each second node under the load balancing pruning strategy can be determined based on the judgment results of each thread. For example, the number of traversable paths for each second node u can be determined based on the value of the traversable path counter for each edge (v, u). Here, u includes all the second nodes of node v.

[0190] C5: Determine the target neighbor node corresponding to the node based on the first node and the number of detourable paths for each second node in each node pair.

[0191] Here, the number of detour paths for the second node is the number of detour paths corresponding to the edge between the second node and node v.

[0192] In practice, for each node v, the first node corresponding to that node can be designated as its target neighbor node. Simultaneously, from the various second nodes corresponding to that node, k-b second nodes can be selected as target neighbors based on the number of possible detour paths. Here, k1 is greater than k, and k is a first preset number. For example, the k-b second nodes with the smallest number of detour paths can be selected together with the first node as target neighbors.

[0193] To facilitate understanding of the load balancing pruning strategy provided in the embodiments of this application, specific examples will be used below for illustration: Suppose that the initial K-NN neighbor list of a node v includes third candidate neighbor nodes A~J (i.e., k1=10), and the third candidate neighbor nodes A~J are ranked Rank=1~10 according to their relative ranking in the initial K-NN neighbor list. Let the graph degree k=8, that is, the first preset number is 8. By running a CAGRA pruning experiment on a small sample data, it was found that the number of bypass paths for the neighbor nodes pos=1 and pos=2 (i.e., nodes A and B) is almost 0; their recall rate in the final retained top-8 neighbors is >99.9%, so they can be safely skipped, so it can be determined that b=2.

[0194] Therefore, the effective pruning range is: pos∈[3,10], that is, candidate edges (v,C)~(v,J) are candidate edges that need to be detected by detour.

[0195] Pairing is performed according to the node pairing scheduling method (posu1+posu2=k1+b+1=10+2+1=13, where u1, u2∈[C,J]): pos=3 (C)↔pos=10 (J)→3+10=13, that is, C and J form a node pair; pos=4 (D)↔pos=9 (I)→4+9=13, that is, D and I form a node pair; pos=5 (E)↔pos=8 (H)→5+8=13, that is, E and H form a node pair; pos=6(F)↔pos=7(G)→6+7=13, that is, F and G form a node pair.

[0196] Therefore, it can be seen that four node pairs can be formed, with each node allocated one thread warp.

[0197] Warp 1: Handling neighbor traversal and detour detection for C and J; Warp2: Handling neighbor traversal and detour detection for D and I; Warp3: Handling neighbor traversal and detour detection for E and H; Warp4: Handles neighbor traversal and detour detection for F and G.

[0198] Since C (pos=3) has a small rank and requires less computation, while J (pos=10) has a large rank and requires more computation, the two complement each other, and the total workload of each warp tends to be balanced.

[0199] Finally, count the number of detourable routes for each edge (v, x), and combine this with the already retained A and B, select the top - 8 nodes with the fewest detourable paths from all 10 third candidate neighbor nodes A~J and retain them (usually A and B must be among them). Where x∈[C, J].

[0200] In this way, this application transforms the originally unbalanced pruning tasks (especially the counterintuitive phenomenon of "the higher the rank, the greater the computational cost" in CAGRA) into evenly distributed subtasks through task decomposition and paired scheduling. This greatly improves GPU utilization, solves the fundamental reason for the low efficiency of strategies such as CAGRA on GPUs, and breaks through the bottleneck of unbalanced load. The load balancing pruning strategy of this application is not only applicable to CAGRA, but also to any pruning strategy with "non-uniform computational cost," requiring only adaptation and modification of the task decomposition and paired rules. Through dynamic paired and atomic operations, the parallel computing units and cache of the GPU are maximized, avoiding idle computing units caused by uneven load. The pruning optimization process fully retains the idea of ​​using rank instead of distance + finding detour points from the neighbors of neighbors, achieving extreme parallel efficiency while ensuring the quality of the graph structure.

[0201] Furthermore, based on the configured batch parallel pruning strategy and load balancing pruning strategy, it is possible to implement three types of metrics (i.e., metrics based on Euclidean distance dis, metrics based on vector angle angel, and metrics based on the relative queuing rank of neighbor nodes in the list), and allow the final neighbor list to be written from high-speed shared memory to global memory, thus achieving efficient storage of the neighbor list.

[0202] S105-4: Construct the target nearest neighbor graph for each data point based on the target neighbor nodes corresponding to each node.

[0203] In practice, a target nearest neighbor graph can be constructed for each data point based on the target neighbor nodes optimized by pruning each node v. This target nearest neighbor graph can be a k-NN graph. In the target nearest neighbor graph, each node has connecting edges with its corresponding target neighbor nodes.

[0204] Thus, this application significantly improves the overall efficiency and quality of k-nearest neighbor (k-NN) graph construction and pruning under large-scale high-dimensional data by using a two-stage parallel graph construction algorithm deeply optimized for GPU architecture and a unified pruning acceleration method.

[0205] Specifically, firstly, in the graph initialization phase, the proposed two-stage parallel strategy of "coarse-grained sampling + fine-grained sampling" effectively solves the core bottlenecks of slow convergence and low neighbor update efficiency in the later stages of traditional NN-Descent algorithms on GPUs. The first construction stage transforms massive distance calculations into highly parallel Tensor Core-friendly matrix operations through a global shared resource pool and batch matrix multiplication, greatly improving the initial convergence speed. The second construction stage switches to an independent node sampling mode, combined with a non-revisit mechanism, to accurately mine potential neighbors with high recall, avoiding neighbor omissions caused by shared sampling, thus achieving a smooth transition from "fast coarse convergence" to "fine-grained high-quality optimization." Through the collaborative work of the two construction stages, the overall construction time is significantly shortened while ensuring the quality of the graph structure.

[0206] Secondly, the lock-free parallel neighbor update mechanism proposed in this application abandons the traditional synchronization methods based on mutex locks or coarse-grained atomic operations, and instead adopts a "deterministic position calculation + atomic write" strategy. By sorting the candidate list and the current neighbor list (i.e., the first neighbor list or the second neighbor list) in shared memory, performing binary search, and pre-compiling the global index, each node to be inserted obtains a unique write position, thereby allowing multiple threads to concurrently write to global memory in a lock-free state. This lock-free parallel neighbor update mechanism not only completely eliminates the synchronization overhead between GPU threads and the thread blocking and resource contention caused by traditional lock mechanisms on the GPU, but also fully utilizes the high throughput characteristics of the GPU, significantly improving the parallel efficiency and scalability of neighbor list updates.

[0207] Finally, in the graph pruning stage, the unified "collection-filtering-storage" framework proposed in this application is compatible with various mainstream pruning strategies (such as NSG, Vamana, CAGRA, etc.). Dedicated GPU kernels are designed to address two typical pruning bottlenecks: Firstly, the "batch parallel pruning" strategy transforms the serial insertion process of strongly dependent strategies such as NSG and Vamana into an execution mode with limited inter-batch dependencies and complete intra-batch parallelism, breaking through the long-standing limitation of serial dependencies. Secondly, for load-unbalanced pruning strategies such as CAGRA, a mechanism of "head skipping (i.e., skipping the first b first nodes) + paired scheduling + fine-grained task decomposition" is introduced to dynamically balance light and heavy computational tasks, significantly improving the utilization of GPU warps and effectively alleviating the load skew problem caused by "hub nodes" or high-ranking neighbors.

[0208] Based on this, the nearest neighbor graph construction method provided in this application can achieve efficient GPU parallelization of the entire process of k-NN graph construction and pruning without sacrificing index quality, significantly improving throughput and convergence speed in large-scale high-dimensional scenarios, and providing a high-performance, scalable and universal underlying graph index construction foundation for approximate nearest neighbor search systems.

[0209] Those skilled in the art will understand that, in the above-described method of the specific implementation, the order in which each step is written does not imply a strict execution order and does not constitute any limitation on the implementation process. The specific execution order of each step should be determined by its function and possible internal logic.

[0210] Based on the same inventive concept, this disclosure also provides a nearest neighbor graph construction device corresponding to the nearest neighbor graph construction method. Since the principle of the device in this disclosure for solving the problem is similar to the near neighbor graph construction method described above, the implementation of the device can refer to the implementation of the method, and the repeated parts will not be described again.

[0211] like Figure 2 The diagram shown is a schematic representation of a nearest neighbor graph construction apparatus provided in an embodiment of this disclosure, comprising: The first construction module 201 is used in the first construction phase to create a shared resource pool for the current iteration based on the first neighbor list obtained in the previous iteration for each data node; wherein, when the current iteration is the first iteration, the first neighbor list is the initial neighbor list of the node; The calculation module 202 is used to select a first sampling node for each node from the shared resource pool, and use the graphics processing unit (GPU) to perform matrix calculation on a first matrix composed of data vectors corresponding to each node and a second matrix composed of data vectors corresponding to each first sampling node, so as to obtain a first distance between each node and the corresponding first sampling node. The loop module 203 is used to determine the first neighbor list corresponding to each node in the current iteration based on the first distance and the first neighbor list, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each piece of data, and create a shared resource pool for the current iteration, until the first cutoff condition is met, obtain the first target neighbor list of each node and enter the second construction stage; The second construction module 204 is used in the second construction phase to determine the second target neighbor list of each node using the GPU based on the node's data vector and the first target neighbor list. The third construction module 205 is used to construct the target nearest neighbor graph corresponding to each data item based on the second target neighbor list.

[0212] In one possible implementation, the loop module 203, when determining the first neighbor list corresponding to each node in the current iteration based on the first distance and the first neighbor list, is configured to: For each node, based on the first distances corresponding to the node, a first candidate neighbor node is determined from the first sampled nodes; In the shared memory of a thread block allocated to the node, the first candidate neighbor nodes of the node are sorted in ascending order according to the first distance to obtain a candidate list of each first candidate neighbor node; From each thread included in the thread block, a target thread is assigned to each first candidate neighbor node and each first neighbor node in the first neighbor list; Using each target thread, the relative ranking of the assigned node in the opposing list is determined; wherein the candidate list and the first neighbor list are opposing lists to each other; Based on the relative ranking of each assigned node, determine the first neighbor list corresponding to each node in the current iteration.

[0213] In one possible implementation, the loop module 203, when determining the first neighbor list corresponding to each node in the current iteration based on the relative ranking of each assigned node, is configured to: The write location of each assigned node in the global memory of the GPU is determined based on the position index of each assigned node in its own list, its relative ranking in the object list, and the node priority of the assigned node. Using the target thread, lock-free writing based on atomic operations is employed to write each of the allocated nodes in parallel into the global memory according to the writing positions. Based on the first distance between each allocated node and the node in the global memory, select each first neighbor node from the first neighbor list corresponding to the node in the current iteration.

[0214] In one possible implementation, the computing module 202, when using the graphics processing unit (GPU) to perform matrix calculations on the first matrix composed of data vectors corresponding to each node and the second matrix composed of data vectors corresponding to each of the first sampling nodes to obtain the first distance between each node and its corresponding first sampling node, is configured to: Load the first matrix and the second matrix into the global memory of the GPU; Based on the number of thread blocks and the processing capacity of the thread blocks in the GPU, each thread block is assigned a processing node and a first sampling node corresponding to the processing node from each of the nodes. Each of the thread blocks loads the first block matrix data related to the node to be processed from the first matrix from the global memory, and loads the second block matrix data related to the first sampling node corresponding to the node to be processed from the global memory. Using each thread in each of the aforementioned thread blocks, based on the loaded first block matrix data and second block matrix data, the block calculation result corresponding to the thread block is determined and written into the global memory; Based on the block calculation results written in the global memory by each of the thread blocks, a first distance is determined between each node and the corresponding first sampling node.

[0215] In one possible implementation, the second construction module 204, during the second construction phase, when determining the second target neighbor list of each node using the GPU based on the node's data vector and the first target neighbor list, is configured to: In the second construction phase, for each node, the second candidate neighbor node corresponding to the node in the current iteration is determined from the second neighbor list obtained in the previous iteration; wherein, if the current iteration is the first iteration of the second construction phase, the second neighbor list is the first target neighbor list; Based on the second neighbor list obtained by each second candidate neighbor node in the previous iteration and the historical access list corresponding to the node, the second sampling node corresponding to the node in the current iteration is determined; the historical access list includes the second sampling nodes selected in each historical iteration in the second construction phase; Using a thread block in the GPU, a second distance between the node and each of the second sampling nodes is calculated based on the node's data vector and the data vector of the second sampling node corresponding to the node in the current iteration; Based on the second distance and the second neighbor list, determine the second neighbor list corresponding to the node in the current iteration, and update the second sampling node corresponding to the current iteration to the historical access list corresponding to the node; The process of returning to the second neighbor list obtained from the previous iteration and determining the second candidate neighbor node corresponding to the node in the current iteration continues until the second preset cutoff condition is met, thus obtaining the second target neighbor list of the node.

[0216] In one possible implementation, the third construction module 205, when constructing the target nearest neighbor graph corresponding to each piece of data based on the second target neighbor list, is used to: Select a target pruning strategy from a variety of preset node pruning strategies; the preset node pruning strategies include batch parallel pruning strategy and load balancing pruning strategy; For each node, according to the node filtering method corresponding to the target pruning strategy, the third candidate neighbor node corresponding to the node is filtered from the second target neighbor list corresponding to the node; According to the GPU calling method that matches the target pruning strategy, the thread block in the GPU is invoked, and the target neighbor node corresponding to the node is determined from the third candidate neighbor nodes according to the target pruning strategy; Based on the target neighbor nodes corresponding to each node, construct the target nearest neighbor graph corresponding to each data item.

[0217] In one possible implementation, when the target pruning strategy is the batch parallel pruning strategy, the third construction module 205, when invoking a thread block in the GPU according to a GPU invocation method matching the target pruning strategy, and determining the target neighbor node corresponding to the node from the third candidate neighbor nodes according to the target pruning strategy, is configured to: Based on the preset node batch size, each third candidate neighbor node is divided into multiple node batches, and each node batch is processed in sequence. For the current batch of nodes being processed, a thread block is invoked from the GPU for each third candidate neighbor node in the batch. Using threads in each called thread block, the constraint values ​​between the third candidate neighbor node and each retained neighbor node obtained after the previous node batch processing are determined in parallel under the batch parallel pruning strategy; wherein, if the current node batch is the first node batch, then each retained neighbor node obtained after the previous node batch processing is empty. Based on the constraint value, determine the remaining neighbor nodes obtained after batch processing of the current node from the third candidate neighbor nodes; Each of the retained neighbor nodes obtained after batch processing the last node is used as the target neighbor node corresponding to the node.

[0218] In one possible implementation, when the target pruning strategy is the load balancing pruning strategy, the third construction module 205, when invoking a thread block in the GPU according to a GPU invocation method matching the target pruning strategy, and determining the target neighbor node corresponding to the node from the third candidate neighbor nodes according to the target pruning strategy, is configured to: Based on the relative ranking of each of the third candidate neighbor nodes in the third target neighbor list, the first node and the second node are selected from the third candidate neighbor nodes; Based on the relative ranking of each second node in the third target neighbor list corresponding to the node, the first number of the first node and the second number of the third candidate neighbor nodes, each node pair corresponding to the second node is determined; Based on the number of the third candidate neighbor nodes of the second node in each node pair, call the thread bundle in the thread block for each node pair; Using the threads in each calling thread bundle, the number of traversable paths for each second node under the load balancing pruning strategy is determined based on the third candidate neighbor nodes of each second node in the node pair. The target neighbor node corresponding to the node is determined based on the first node and the number of detourable paths of each second node in each node pair.

[0219] In one possible implementation, the third construction module 205, when using threads in each called thread bundle to determine the number of traversable paths for each second node under the load balancing pruning strategy based on the third candidate neighbor nodes of each second node in the node pair, is configured to: For any third candidate neighbor node of any second node in the node pair, use one thread in any called thread bundle to determine whether the third candidate neighbor node belongs to the third target neighbor list corresponding to the node. If so, the thread is used to determine the first relative ranking of the third candidate neighbor node in the third target neighbor list corresponding to the node, and to determine the second relative ranking of the second node in the third target neighbor list corresponding to the third candidate neighbor node. Based on the maximum value of the first relative ranking and the second relative ranking, and the third relative ranking of the second node in the third target neighbor list corresponding to the node, it is determined whether the path between the third candidate neighbor node and the node is a detourable path between the second node and the node. Based on the judgment results of each thread in each calling thread bundle, the number of bypass paths for each second node under the load balancing pruning strategy is determined.

[0220] In one possible implementation, the third construction module 205, when invoking a thread bundle in a thread block for each node pair based on the number of the third candidate neighbor nodes of the second node in each node pair, is configured to: Based on the number of the third candidate neighbor nodes of the second node in each node pair and the parallel processing capability of the thread block, determine the corresponding neighbor node subset for each node pair, and call the thread bundle in the thread block for each neighbor node subset.

[0221] For the device embodiments, since they basically correspond to the method embodiments, the relevant parts can be referred to in the description of the method embodiments. The device embodiments described above are merely illustrative. The units described as separate components may or may not be physically separate, and the components shown as units may or may not be physical units, that is, they may be located in one place or distributed across multiple network units. Some or all of the modules can be selected to achieve the purpose of this application according to actual needs. Those skilled in the art can understand and implement this without creative effort.

[0222] Based on the same technical concept, embodiments of this application also provide a computer device. (Refer to...) Figure 3 The diagram shown is a structural schematic of a computer device provided in an embodiment of this application, comprising: The processor 301, memory 302, and bus 303 are included. The memory 302 stores machine-readable instructions that can be executed by the processor 301. The processor 301 executes the machine-readable instructions stored in the memory 302. When the machine-readable instructions are executed by the processor 301, the processor 301 performs the following steps: S101~S105.

[0223] The aforementioned memory 302 includes a main memory 3021 and an external memory 3022. The main memory 3021, also known as internal memory, is used to temporarily store the computational data in the processor 301, as well as the data exchanged with external memory such as a hard disk. The processor 301 exchanges data with the external memory 3022 through the main memory 3021. When the computer device is running, the processor 301 and the memory 302 communicate through the bus 303, so that the processor 301 executes the execution instructions mentioned in the above method embodiments.

[0224] This disclosure also provides a computer-readable storage medium storing a computer program, which, when executed by a processor, performs the steps of the nearest neighbor graph construction method described in the above method embodiments. The storage medium can be a volatile or non-volatile computer-readable storage medium.

[0225] This disclosure also provides a computer program product carrying program code. The program code includes instructions that can be used to execute the steps of the nearest neighbor graph construction method described in the above method embodiments. For details, please refer to the above method embodiments, which will not be repeated here.

[0226] The computer program product can be implemented specifically through hardware, software, or a combination thereof. In one alternative embodiment, the computer program product is specifically embodied in a computer storage medium; in another alternative embodiment, the computer program product is specifically embodied in a software product, such as a software development kit (SDK), etc.

[0227] Those skilled in the art will clearly understand that, for the sake of convenience and brevity, the specific working processes of the systems and devices described above can be referred to the corresponding processes in the foregoing method embodiments, and will not be repeated here. In the several embodiments provided in this disclosure, it can be understood that the disclosed systems, devices, and methods can be implemented in other ways. The device embodiments described above are merely illustrative. For example, the division of units is only a logical functional division, and in actual implementation, there may be other division methods. Furthermore, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Another point is that the displayed or discussed mutual coupling or direct coupling or communication connection may be through some communication interfaces; the indirect coupling or communication connection of devices or units may be electrical, mechanical, or other forms.

[0228] The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the units can be selected to achieve the purpose of this embodiment according to actual needs.

[0229] In addition, the functional units in the various embodiments of this disclosure can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit.

[0230] If the aforementioned functions are implemented as software functional units and sold or used as independent products, they can be stored in a processor-executable, non-volatile, computer-readable storage medium. Based on this understanding, the technical solution of this disclosure, in essence, or the part that contributes to the prior art, or a portion of the technical solution, can be embodied in the form of a software product. This computer software product is stored in a storage medium and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute all or part of the steps of the methods described in the various embodiments of this disclosure. The aforementioned storage medium includes various media capable of storing program code, such as USB flash drives, portable hard drives, read-only memory (ROM), random access memory (RAM), magnetic disks, or optical disks.

[0231] Finally, it should be noted that the above description is only a preferred embodiment of this application and is not intended to limit this application. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this application should be included within the scope of protection of this application.

Claims

1. A method for constructing a nearest neighbor graph, characterized in that, The method includes: In the first construction phase, a shared resource pool is created for the current iteration based on the first neighbor list of the node corresponding to each piece of data obtained in the previous iteration; wherein, when the current iteration is the first iteration, the first neighbor list is the initial neighbor list of the node; From the shared resource pool, a first sampling node is selected for each node, and using the graphics processing unit (GPU), matrix calculations are performed on the first matrix composed of the data vectors corresponding to each node and the second matrix composed of the data vectors corresponding to each first sampling node to obtain the first distance between each node and the corresponding first sampling node. Based on the first distance and the first neighbor list, determine the first neighbor list corresponding to each node in the current iteration, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each data, and create a shared resource pool for the current iteration, until the first cutoff condition is met, obtain the first target neighbor list of each node and enter the second construction stage; In the second construction phase, for each node, the GPU is used to determine the second target neighbor list of the node based on the node's data vector and the first target neighbor list; Based on the second target neighbor list, construct the target nearest neighbor graph corresponding to each data entry.

2. The method according to claim 1, characterized in that, The step of determining the first neighbor list corresponding to each node in the current iteration based on the first distance and the first neighbor list includes: For each node, based on the first distances corresponding to the node, a first candidate neighbor node is determined from the first sampled nodes; In the shared memory of a thread block allocated to the node, the first candidate neighbor nodes of the node are sorted in ascending order according to the first distance to obtain a candidate list of each first candidate neighbor node; From each thread included in the thread block, a target thread is assigned to each first candidate neighbor node and each first neighbor node in the first neighbor list; Using each target thread, the relative ranking of the assigned node in the opposing list is determined; wherein the candidate list and the first neighbor list are opposing lists to each other; Based on the relative ranking of each assigned node, determine the first neighbor list corresponding to each node in the current iteration.

3. The method according to claim 2, characterized in that, The step of determining the first neighbor list corresponding to each node in the current iteration based on the relative ranking of each assigned node includes: The write location of each assigned node in the global memory of the GPU is determined based on the position index of each assigned node in its own list, its relative ranking in the object list, and the node priority of the assigned node. Using the target thread, lock-free writing based on atomic operations is employed to write each of the allocated nodes in parallel into the global memory according to the writing positions. Based on the first distance between each allocated node and the node in the global memory, select each first neighbor node from the first neighbor list corresponding to the node in the current iteration.

4. The method according to claim 1, characterized in that, The step of using a graphics processing unit (GPU) to perform matrix calculations on a first matrix composed of data vectors corresponding to each node and a second matrix composed of data vectors corresponding to each of the first sampling nodes, to obtain a first distance between each node and its corresponding first sampling node, includes: Load the first matrix and the second matrix into the global memory of the GPU; Based on the number of thread blocks and the processing capacity of the thread blocks in the GPU, each thread block is assigned a processing node and a first sampling node corresponding to the processing node from each of the nodes. Each of the thread blocks loads the first block matrix data related to the node to be processed from the first matrix from the global memory, and loads the second block matrix data related to the first sampling node corresponding to the node to be processed from the global memory. Using each thread in each of the aforementioned thread blocks, based on the loaded first block matrix data and second block matrix data, the block calculation result corresponding to the thread block is determined and written into the global memory; Based on the block calculation results written in the global memory by each of the thread blocks, a first distance is determined between each node and the corresponding first sampling node.

5. The method according to claim 1, characterized in that, In the second construction phase, for each node, the GPU determines a second target neighbor list based on the node's data vector and the first target neighbor list, including: In the second construction phase, for each node, the second candidate neighbor node corresponding to the node in the current iteration is determined from the second neighbor list obtained in the previous iteration; wherein, if the current iteration is the first iteration of the second construction phase, the second neighbor list is the first target neighbor list; Based on the second neighbor list obtained by each second candidate neighbor node in the previous iteration and the historical access list corresponding to the node, the second sampling node corresponding to the node in the current iteration is determined; the historical access list includes the second sampling nodes selected in each historical iteration in the second construction phase; Using a thread block in the GPU, a second distance between the node and each of the second sampling nodes is calculated based on the node's data vector and the data vector of the second sampling node corresponding to the node in the current iteration; Based on the second distance and the second neighbor list, determine the second neighbor list corresponding to the node in the current iteration, and update the second sampling node corresponding to the current iteration to the historical access list corresponding to the node; The process of returning to the second neighbor list obtained from the previous iteration and determining the second candidate neighbor node corresponding to the node in the current iteration continues until the second preset cutoff condition is met, thus obtaining the second target neighbor list of the node.

6. The method according to claim 1, characterized in that, The step of constructing the target nearest neighbor graph corresponding to each data entry based on the second target neighbor list includes: Select a target pruning strategy from a variety of preset node pruning strategies; the preset node pruning strategies include batch parallel pruning strategy and load balancing pruning strategy; For each node, according to the node filtering method corresponding to the target pruning strategy, the third candidate neighbor node corresponding to the node is filtered from the second target neighbor list corresponding to the node; According to the GPU calling method that matches the target pruning strategy, the thread block in the GPU is invoked, and the target neighbor node corresponding to the node is determined from the third candidate neighbor nodes according to the target pruning strategy; Based on the target neighbor nodes corresponding to each node, construct the target nearest neighbor graph corresponding to each data item.

7. The method according to claim 6, characterized in that, When the target pruning strategy is the batch parallel pruning strategy, the step of invoking a thread block in the GPU according to a GPU invocation method matching the target pruning strategy, and determining the target neighbor node corresponding to the node from the third candidate neighbor nodes according to the target pruning strategy, includes: Based on the preset node batch size, each third candidate neighbor node is divided into multiple node batches, and each node batch is processed in sequence. For the current batch of nodes being processed, a thread block is invoked from the GPU for each third candidate neighbor node in the batch. Using threads in each called thread block, the constraint values ​​between the third candidate neighbor node and each retained neighbor node obtained after the previous node batch processing are determined in parallel under the batch parallel pruning strategy; wherein, if the current node batch is the first node batch, then each retained neighbor node obtained after the previous node batch processing is empty. Based on the constraint value, determine the remaining neighbor nodes obtained after batch processing of the current node from the third candidate neighbor nodes; Each of the retained neighbor nodes obtained after batch processing the last node is used as the target neighbor node corresponding to the node.

8. The method according to claim 6, characterized in that, When the target pruning strategy is the load balancing pruning strategy, the step of invoking a thread block in the GPU according to a GPU invocation method matching the target pruning strategy, and determining the target neighbor node corresponding to the node from the third candidate neighbor nodes according to the target pruning strategy, includes: Based on the relative ranking of each of the third candidate neighbor nodes in the third target neighbor list, the first node and the second node are selected from the third candidate neighbor nodes; Based on the relative ranking of each second node in the third target neighbor list corresponding to the node, the first number of the first node and the second number of the third candidate neighbor nodes, each node pair corresponding to the second node is determined; Based on the number of the third candidate neighbor nodes of the second node in each node pair, call the thread bundle in the thread block for each node pair; Using the threads in each calling thread bundle, the number of traversable paths for each second node under the load balancing pruning strategy is determined based on the third candidate neighbor nodes of each second node in the node pair. The target neighbor node corresponding to the node is determined based on the first node and the number of detourable paths of each second node in each node pair.

9. The method according to claim 8, characterized in that, The step of utilizing threads in each calling thread bundle to determine the number of traversable paths for each second node under the load balancing pruning strategy based on the third candidate neighbor nodes of each second node in the node pair includes: For any third candidate neighbor node of any second node in the node pair, use one thread in any called thread bundle to determine whether the third candidate neighbor node belongs to the third target neighbor list corresponding to the node. If so, the thread is used to determine the first relative ranking of the third candidate neighbor node in the third target neighbor list corresponding to the node, and to determine the second relative ranking of the second node in the third target neighbor list corresponding to the third candidate neighbor node. Based on the maximum value of the first relative ranking and the second relative ranking, and the third relative ranking of the second node in the third target neighbor list corresponding to the node, it is determined whether the path between the third candidate neighbor node and the node is a detourable path between the second node and the node. Based on the judgment results of each thread in each calling thread bundle, the number of bypass paths for each second node under the load balancing pruning strategy is determined.

10. The method according to claim 8, characterized in that, The step of calling a thread bundle in a thread block for each node pair based on the number of the third candidate neighbor nodes of the second node in each node pair includes: Based on the number of the third candidate neighbor nodes of the second node in each node pair and the parallel processing capability of the thread block, determine the corresponding neighbor node subset for each node pair, and call the thread bundle in the thread block for each neighbor node subset.

11. A nearest neighbor graph construction device, characterized in that, The device includes: The first construction module is used in the first construction phase to create a shared resource pool for the current iteration based on the first neighbor list obtained in the previous iteration for each data node; wherein, when the current iteration is the first iteration, the first neighbor list is the initial neighbor list of the node; The calculation module is used to select a first sampling node for each node from the shared resource pool, and use the graphics processing unit (GPU) to perform matrix calculation on a first matrix composed of data vectors corresponding to each node and a second matrix composed of data vectors corresponding to each first sampling node, so as to obtain a first distance between each node and the corresponding first sampling node. The loop module is used to determine the first neighbor list corresponding to each node in the current iteration based on the first distance and the first neighbor list, and return the first neighbor list obtained after the previous iteration based on the node corresponding to each piece of data, and create a shared resource pool for the current iteration, until the first cutoff condition is met, obtain the first target neighbor list of each node and enter the second construction stage; The second construction module is used in the second construction phase to determine, for each node, a second target neighbor list of the node using the GPU based on the node's data vector and the first target neighbor list; The third construction module is used to construct the target nearest neighbor graph corresponding to each data item based on the second target neighbor list.

12. A computer-readable storage medium having a computer program stored thereon, characterized in that, When the program is executed by a processor, it implements the steps of the method as described in any one of claims 1 to 10.

13. A computer device comprising a memory, a processor, and a computer program stored in the memory and executable on the processor, characterized in that, When the processor executes the program, it implements the steps of the method as described in any one of claims 1 to 10.