o
    Ne0                     @   sl   d dl Z d dlmZ d dlmZmZ d dlmZ d dlm	Z	 d dl m
Z
mZ g Z	dddZ	dd	d
ZdS )    N)LayerHelper)_non_static_modeVariable)check_variable_and_dtype)core)_C_ops_legacy_C_opsc              	   C   s  |dur
|dur
dnd}t  r"t| ||||d|\}}}	|||	fS t| ddd t|ddd t|d	d
d |rGt|dd
d t|dd
d tdi t }
|
j| jd}|
j| jd}|
j| jd}	|
jd| |||rn|nd|rs|ndd|||	dd|id |||	fS )a  
    Reindex Graph API.

    This API is mainly used in Graph Learning domain, which should be used
    in conjunction with `paddle.geometric.sample_neighbors` API. And the main purpose
    is to reindex the ids information of the input nodes, and return the
    corresponding graph edges after reindex.

    Take input nodes x = [0, 1, 2] as an example. If we have neighbors = [8, 9, 0, 4, 7, 6, 7], and count = [2, 3, 2],
    then we know that the neighbors of 0 is [8, 9], the neighbors of 1 is [0, 4, 7], and the neighbors of 2 is [6, 7].
    Then after graph_reindex, we will have 3 different outputs: reindex_src: [3, 4, 0, 5, 6, 7, 6], reindex_dst: [0, 0, 1, 1, 1, 2, 2]
    and out_nodes: [0, 1, 2, 8, 9, 4, 7, 6]. We can see that the numbers in `reindex_src` and `reindex_dst` is the corresponding index
    of nodes in `out_nodes`.

    Note:
        The number in x should be unique, otherwise it would cause potential errors. We will reindex all the nodes from 0.

    Args:
        x (Tensor): The input nodes which we sample neighbors for. The available
                    data type is int32, int64.
        neighbors (Tensor): The neighbors of the input nodes `x`. The data type
                            should be the same with `x`.
        count (Tensor): The neighbor count of the input nodes `x`. And the
                        data type should be int32.
        value_buffer (Tensor|None): Value buffer for hashtable. The data type should be int32,
                                    and should be filled with -1. Only useful for gpu version.
        index_buffer (Tensor|None): Index buffer for hashtable. The data type should be int32,
                                    and should be filled with -1. Only useful for gpu version.
                                    `value_buffer` and `index_buffer` should be both not None
                                    if you want to speed up by using hashtable buffer.
        name (str, optional): Name for the operation (optional, default is None).
                              For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        - reindex_src (Tensor), the source node index of graph edges after reindex.

        - reindex_dst (Tensor), the destination node index of graph edges after reindex.

        - out_nodes (Tensor), the index of unique input nodes and neighbors before reindex, where we put the input nodes `x` in the front, and put neighbor nodes in the back.

    Examples:
        .. code-block:: python

            import paddle
            x = [0, 1, 2]
            neighbors = [8, 9, 0, 4, 7, 6, 7]
            count = [2, 3, 2]
            x = paddle.to_tensor(x, dtype="int64")
            neighbors = paddle.to_tensor(neighbors, dtype="int64")
            count = paddle.to_tensor(count, dtype="int32")
            reindex_src, reindex_dst, out_nodes = paddle.geometric.reindex_graph(x, neighbors, count)
            # reindex_src: [3, 4, 0, 5, 6, 7, 6]
            # reindex_dst: [0, 0, 1, 1, 1, 2, 2]
            # out_nodes: [0, 1, 2, 8, 9, 4, 7, 6]

    NTFflag_buffer_hashtableXint32Zint64graph_reindex	NeighborsCountr   HashTable_ValueHashTable_Indexreindex_graphdtyper
   r   r   r   r   ZReindex_SrcZReindex_DstZ	Out_NodestypeZinputsZoutputsattrs)r   )	r   r   r   r   r   locals"create_variable_for_type_inferencer   	append_opxZ	neighborscountZvalue_bufferZindex_buffernameZuse_buffer_hashtableZreindex_srcZreindex_dstZ	out_nodeshelper r"   HD:\Projects\ConvertPro\env\Lib\site-packages\paddle/geometric/reindex.pyr      sX   <

	


r   c              	   C   s  |dur
|dur
dnd}t  r0tj|dd}tj|dd}t| ||||d|\}}}	|||	fS t|tr8|g}t|tr@|g}tj|dd}tj|dd}t| ddd	 t|d
dd t|ddd |rst|ddd t|ddd tdi t	 }
|
j
| jd}|
j
| jd}|
j
| jd}	tj|dd}tj|dd}|
jd| |||r|nd|r|ndd|||	dd|id |||	fS )a  
    Reindex HeterGraph API.

    This API is mainly used in Graph Learning domain, which should be used
    in conjunction with `paddle.geometric.sample_neighbors` API. And the main purpose
    is to reindex the ids information of the input nodes, and return the
    corresponding graph edges after reindex.

    Take input nodes x = [0, 1, 2] as an example. For graph A, suppose we have neighbors = [8, 9, 0, 4, 7, 6, 7], and count = [2, 3, 2],
    then we know that the neighbors of 0 is [8, 9], the neighbors of 1 is [0, 4, 7], and the neighbors of 2 is [6, 7]. For graph B,
    suppose we have neighbors = [0, 2, 3, 5, 1], and count = [1, 3, 1], then we know that the neighbors of 0 is [0], the neighbors of 1 is [2, 3, 5],
    and the neighbors of 3 is [1]. We will get following outputs: reindex_src: [3, 4, 0, 5, 6, 7, 6, 0, 2, 8, 9, 1], reindex_dst: [0, 0, 1, 1, 1, 2, 2, 0, 1, 1, 1, 2]
    and out_nodes: [0, 1, 2, 8, 9, 4, 7, 6, 3, 5].

    Note:
        The number in x should be unique, otherwise it would cause potential errors. We support multi-edge-types neighbors reindexing in reindex_heter_graph api. We will reindex all the nodes from 0.

    Args:
        x (Tensor): The input nodes which we sample neighbors for. The available
                    data type is int32, int64.
        neighbors (list|tuple): The neighbors of the input nodes `x` from different graphs.
                                The data type should be the same with `x`.
        count (list|tuple): The neighbor counts of the input nodes `x` from different graphs.
                            And the data type should be int32.
        value_buffer (Tensor|None): Value buffer for hashtable. The data type should be int32,
                                    and should be filled with -1. Only useful for gpu version.
        index_buffer (Tensor|None): Index buffer for hashtable. The data type should be int32,
                                    and should be filled with -1. Only useful for gpu version.
                                    `value_buffer` and `index_buffer` should be both not None
                                    if you want to speed up by using hashtable buffer.
        name (str, optional): Name for the operation (optional, default is None).
                              For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        - reindex_src (Tensor), the source node index of graph edges after reindex.

        - reindex_dst (Tensor), the destination node index of graph edges after reindex.

        - out_nodes (Tensor), the index of unique input nodes and neighbors before reindex,
                              where we put the input nodes `x` in the front, and put neighbor
                              nodes in the back.

    Examples:
        .. code-block:: python

            import paddle
            x = [0, 1, 2]
            neighbors_a = [8, 9, 0, 4, 7, 6, 7]
            count_a = [2, 3, 2]
            x = paddle.to_tensor(x, dtype="int64")
            neighbors_a = paddle.to_tensor(neighbors_a, dtype="int64")
            count_a = paddle.to_tensor(count_a, dtype="int32")
            neighbors_b = [0, 2, 3, 5, 1]
            count_b = [1, 3, 1]
            neighbors_b = paddle.to_tensor(neighbors_b, dtype="int64")
            count_b = paddle.to_tensor(count_b, dtype="int32")
            neighbors = [neighbors_a, neighbors_b]
            count = [count_a, count_b]
            reindex_src, reindex_dst, out_nodes = paddle.geometric.reindex_heter_graph(x, neighbors, count)
            # reindex_src: [3, 4, 0, 5, 6, 7, 6, 0, 2, 8, 9, 1]
            # reindex_dst: [0, 0, 1, 1, 1, 2, 2, 0, 1, 1, 1, 2]
            # out_nodes: [0, 1, 2, 8, 9, 4, 7, 6, 3, 5]

    NTFr   )Zaxisr	   r
   r   Zheter_graph_reindexr   r   r   r   r   r   reindex_heter_graphr   r   r   r   )r$   )r   paddleconcatr   r   
isinstancer   r   r   r   r   r   r   r   r"   r"   r#   r$      sl   D

	




r$   )NNN)r%   Zpaddle.fluid.layer_helperr   Zpaddle.fluid.frameworkr   r   Zpaddle.fluid.data_feederr   Zpaddle.fluidr   r   r   __all__r   r$   r"   r"   r"   r#   <module>   s   
q