o
    "j                     @   s   d dl Zd dlmZ d dlmZmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZ d dlmZ ed	d
ddd	dddZdS )    N)_C_ops)check_dtype
check_typecheck_variable_and_dtype)Variable)LayerHelper)in_dynamic_or_pir_mode)convert_out_size_to_listget_out_size_tensor_inputs)
deprecatedz2.4.0zpaddle.geometric.send_u_recv   z<graph_send_recv in paddle.incubate will be removed in future)ZsinceZ	update_tolevelreasonsumc                 C   s  |dvr
t d| t rt|d}t| ||| |S t| ddd t|ddd t|ddd |rAt|d	tt	j
t	jtfd t|trPt|jd	d
dgd tdi t }|j| jd}|jd
dd}| ||d}	d| i}
t|	|
|dd |jd|	||d|
d |S )a  

    Graph Learning Send_Recv combine operator.

    This operator is mainly used in Graph Learning domain, and the main purpose is to reduce intermediate memory
    consumption in the process of message passing. Take `x` as the input tensor, we first use `src_index`
    to gather the corresponding data, and then use `dst_index` to update the corresponding position of output tensor
    in different pooling types, like sum, mean, max, or min. Besides, we can set `out_size` to get necessary output shape.

    .. code-block:: text

           Given:

           X = [[0, 2, 3],
                [1, 4, 5],
                [2, 6, 7]]

           src_index = [0, 1, 2, 0]

           dst_index = [1, 2, 1, 0]

           pool_type = "sum"

           out_size = None

           Then:

           Out = [[0, 2, 3],
                  [2, 8, 10],
                  [1, 4, 5]]

    Args:
        x (Tensor): The input tensor, and the available data type is float32, float64, int32, int64.
        src_index (Tensor): An 1-D tensor, and the available data type is int32, int64.
        dst_index (Tensor): An 1-D tensor, and should have the same shape as `src_index`.
                            The available data type is int32, int64.
        pool_type (str): The pooling types of graph_send_recv, including `sum`, `mean`, `max`, `min`.
                         Default value is `sum`.
        out_size (int|Tensor|None): We can set `out_size` to get necessary output shape. If not set or
                                    out_size is smaller or equal to 0, then this input will not be used.
                                    Otherwise, `out_size` should be equal with or larger than
                                    max(dst_index) + 1.
        name (str, optional): Name for the operation (optional, default is None).
                              For more information, please refer to :ref:`api_guide_Name`.

    Returns:
        out (Tensor): The output tensor, should have the same shape and same dtype as input tensor `x`.
                      If `out_size` is set correctly, then it should have the same shape as `x` except
                      the 0th dimension.

    Examples:

        .. code-block:: python

            >>> import paddle

            >>> x = paddle.to_tensor([[0, 2, 3], [1, 4, 5], [2, 6, 7]], dtype="float32")
            >>> indexes = paddle.to_tensor([[0, 1], [1, 2], [2, 1], [0, 0]], dtype="int32")
            >>> src_index = indexes[:, 0]
            >>> dst_index = indexes[:, 1]
            >>> out = paddle.incubate.graph_send_recv(x, src_index, dst_index, pool_type="sum")
            >>> print(out)
            Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[0. , 2. , 3. ],
             [2. , 8. , 10.],
             [1. , 4. , 5. ]])

            >>> x = paddle.to_tensor([[0, 2, 3], [1, 4, 5], [2, 6, 7]], dtype="float32")
            >>> indexes = paddle.to_tensor([[0, 1], [2, 1], [0, 0]], dtype="int32")
            >>> src_index = indexes[:, 0]
            >>> dst_index = indexes[:, 1]
            >>> out_size = paddle.max(dst_index) + 1
            >>> out = paddle.incubate.graph_send_recv(x, src_index, dst_index, pool_type="sum", out_size=out_size)
            >>> print(out)
            Tensor(shape=[2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[0. , 2. , 3. ],
             [2. , 8. , 10.]])

            >>> x = paddle.to_tensor([[0, 2, 3], [1, 4, 5], [2, 6, 7]], dtype="float32")
            >>> indexes = paddle.to_tensor([[0, 1], [2, 1], [0, 0]], dtype="int32")
            >>> src_index = indexes[:, 0]
            >>> dst_index = indexes[:, 1]
            >>> out = paddle.incubate.graph_send_recv(x, src_index, dst_index, pool_type="sum")
            >>> print(out)
            Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
            [[0. , 2. , 3. ],
             [2. , 8. , 10.],
             [0. , 0. , 0. ]])
    )r   meanmaxminzBpool_type should be `sum`, `mean`, `max` or `min`, but received %sgraph_send_recvX)Zfloat32Zfloat64int32int64	Src_index)r   r   	Dst_indexout_sizer   r   )dtypeT)r   Zstop_gradient)r   r   r   Z	reduce_op)inputsattrsr   Zop_type)ZOutZ	Dst_count)typer   Zoutputsr   N)r   )
ValueErrorr   r	   r   Zsend_u_recvupperr   r   intnpr   r   r   
isinstancer   r   r   localsZ"create_variable_for_type_inferencer
   Z	append_op)xZ	src_indexZ	dst_indexZ	pool_typer   namehelperoutZ	dst_countr   r    r(   j/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/paddle/incubate/operators/graph_send_recv.pyr   !   sl   c

r   )r   NN)numpyr!   Zpaddler   Zpaddle.base.data_feederr   r   r   Zpaddle.base.frameworkr   Zpaddle.base.layer_helperr   Zpaddle.frameworkr   Z&paddle.geometric.message_passing.utilsr	   r
   Zpaddle.utilsr   r   r(   r(   r(   r)   <module>   s    