
    AVhkW                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 dd	l
mZ dd
l
mZ ddl
mZ ddlmZ  ej                   ej"                        	 	 	 	 ddej$                  dej$                  fd       Zd Zd Zd Zd Zd Zd Z ej                   ej&                        	 	 	 	 ddej$                  dej$                  fd       Z ej                   ej6                        	 	 	 ddej$                  dej$                  fd       Z ej                   ej8                        	 	 	 ddej$                  dej$                  fd       Z ej<                  d      d        Zy) z$Gather operations for RaggedTensors.    )dtypes)indexed_slices)ops)tensor_shape)	array_ops)gen_ragged_array_ops)math_ops)ragged_array_ops)ragged_math_ops)ragged_tensor)dispatchNparamsindicesc                 D   ~t        j                  |d| |g      5  t        j                  | d      } t        j                  |d      }t        j                  | |      \  } }||j
                  j                  k7  r-t        j                  ||j
                  j                  dd      }| j
                  j                  $|| j
                  j                  k\  rt        d	      ||}t        j                  || j
                  j                  d
      }||k  rt        d      |j
                  j                  Fd|cxk  r|j
                  j                  k  s'n t        d|d|j
                  j                        t        | |||      cddd       S # 1 sw Y   yxY w)a  Gathers ragged slices from `params` axis `0` according to `indices`.

  See `tf.gather` for full documentation.  (This version has the same API
  as `tf.gather`, but supports ragged `params` and `indices`.)

  Examples:

  >>> params = tf.constant(['a', 'b', 'c', 'd', 'e'])
  >>> indices = tf.constant([3, 1, 2, 1, 0])
  >>> ragged_params = tf.ragged.constant([['a', 'b', 'c'], ['d'], [], ['e']])
  >>> ragged_indices = tf.ragged.constant([[3, 1, 2], [1], [], [0]])

  >>> tf.gather(params, ragged_indices)
  <tf.RaggedTensor [[b'd', b'b', b'c'], [b'b'], [], [b'a']]>

  >>> tf.gather(ragged_params, indices)
  <tf.RaggedTensor [[b'e'], [b'd'], [], [b'd'], [b'a', b'b', b'c']]>

  >>> tf.gather(ragged_params, ragged_indices)
  <tf.RaggedTensor [[[b'e'], [b'd'], []], [[b'd']], [], [[b'a', b'b', b'c']]]>

  Args:
    params: The potentially ragged tensor from which to gather values. Must be
      at least rank 1.
    indices: The potentially ragged tensor indicating which values to gather.
      Must have dtype `int32` or `int64`.  Values must be in the range `[0,
      params.shape[0]]`.
    validate_indices: Ignored.
    axis: The axis in `params` to gather `indices` from.
    batch_dims: The number of batch dimensions.
    name: A name for the operation (optional).

  Returns:
    A `RaggedTensor`, where `output.dtype=params.dtype` and
    `output.shape=indices.shape + params.shape[1:]` and
    `output.ragged_rank=indices.shape.ndims + params.ragged_rank`.

  Raises:
    ValueError: If indices.shape.ndims is not known statically.
  RaggedGatherr   namer   
batch_dimszrank(indices))	axis_name
ndims_nameNz)batch_dims must be less than rank(params)zrank(params))r   z0axis must be greater than or equal to batch_dimsr   zbatch_dims=z% must be between 0 and rank(indices)=)r   
name_scoper   "convert_to_tensor_or_ragged_tensormatch_row_splits_dtypesshaperankr   get_positive_axis
ValueError_gather)r   r   validate_indicesaxisr   r   s         ^/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_gather_ops.pygatherr"   !   sp   ^ 
~~dNVW,=> 6==XF>>i!G#;;FGLOFGW]]'''..

--

 $	&j
 ||$v||7H7H)HBCC|d&&fllN<DjIJJ}}%*2 2 22++-. 	. 67D*576 6 6s   E1FFc                    t        j                  |       }t        j                  |      }|s|st        j                  | |||      S |dkD  rt	        | |||      S |dkD  rt        | ||      S |r'|j                  t        | |j                  dd            S |j                  j                  t        d      |j                  j                  t        | j                        z   dz
  }t        j                  || j                   | j                  |      }t         j"                  j%                  |j&                  |j(                  d      }|j                  j                  dkD  r|}t        j                  || j*                  j,                        }	t/        j0                  |	      }
t3        |j                  j                  dz
        D ]%  }|
|   |_        |	|dz      |_        |j                  }' |S )	a4  Helper that implements the body for ragged gather().

  Assumes that `params` and `indices` have been converted to tensors or
  ragged tensors, and that `axis` and `batch_dims` have been normalized to
  be positive.  (So these conversions & normalizations can be skipped in
  recursive calls to _gather).

  Args:
    params: The tensor from which to gather values.
    indices: The indices of values to gather.
    axis: The axis in `params` to gather `indices` from.
    batch_dims: The number of batch dimensions.

  Returns:
    A potentially ragged tensor.
  )r    r   r   &rank(indices) must be known statically   )r   params_dense_valuesparams_nested_splitsOUTPUT_RAGGED_RANKF)validateout_type)r   	is_raggedr   r"   _batch_gather_axis_gatherwith_valuesr   valuesr   ndimsr   lennested_row_splitsr   ragged_gatherflat_valuesRaggedTensorfrom_nested_row_splitsoutput_dense_valuesoutput_nested_splits
row_splitsdtyper	   cumprodrange_cached_nrows_uniform_row_length)r   r   r    r   params_is_raggedindices_is_raggedout_ragged_rankresulttargetindices_shapeshape_cumproddims               r!   r   r   p   s   " #,,V4#--g6
/FG$:NN!^$
;;	AX..wvw~~q!DEE]] 
=
>>MM''#f.F.F*GG!K/-- ,,!33(	*& %%<<  &"="= = O& ]]1FOOGf6G6G6M6MNM$$]3MW]]((1,- *3/f#0q#9f }}f	 
-    c                    | j                   d| j                  |j                   d|       s(t        d|j                   d| d| j                         |dkD  rt        | t        j
                        sM|j                  t        d      t        j
                  j                  | d|j                  j                        } t        |t        j
                        sM| j                  t        d      t        j
                  j                  |d| j                  j                        }| j                  t        | j                  |j                  |dz
  |dz
              S |dkD  rt        |t        j
                        s5| j                  t        j                  || j                         d            }nt        | t        j
                        s6t        j
                  j                  | d|j                  j                        } t        || j                  t        j                  t!        j"                  | j%                               | j                                     dd      }t'        | |||dz         S |j                   j(                  t        d	      |dk(  sJ t+        |       }t-        | |j                        }t/        ||j                   j0                        }||z   }t        |||dz
  d      S )
aJ  Helper that implements the body for ragged gather() when batch_dims>0.

  Args:
    params: The tensor from which to gather values.
    indices: The indices of values to gather.
    axis: The axis in `params` to gather `indices` from.
    batch_dims: The number of batch dimensions.

  Returns:
    A potentially ragged tensor.
  Nzbatch shape from indices z does not match params shape r%   zvbatch shape from indices does not match params shape: ragged indices dimension corresponds to uniform params dimensionragged_rankrow_splits_dtypezvbatch shape from indices does not match params shape: ragged params dimension corresponds to uniform indices dimensionr   r$   )r   is_compatible_withr   
isinstancer   r6   uniform_row_lengthfrom_tensorr:   r;   r/   r   r0   r   repeatrow_lengthsr	   r=   nrowsr-   r   _flatten_dims_0_and_1_row_starts_increase_rank_tor1   )r   r   r    r   adjusted_indicesflat_paramsadjustmentss          r!   r-   r-      s   " 
kz	"	5	5mmKZ 
"
#*==*#=v||M N N !^fm889		#	#	+HI 	I ))55
a'2D2D2J2J 6 Lfg}99:		"	"	*HI 	I **66
q63D3D3J3J 7 Lg w~~taxaHJ J 
AX g}99:++


7F$6$6$8!
<>  : :;++77G4F4F4L4L 8 N 



..0&2D2D2FHIJKQ	P
 !14aHH]]
=
>>	q &f-+FGMM2+!+w}}/B/BC+{*	.q!	<<rH   c                    |dkD  rzt        | t        j                        s6t        j                  j                  | d|j                  j
                        } | j                  t        | j                  ||dz
  d            S |j                  j                  t        d      |dk(  sJ t        |       }t        | |j
                        }t        ||j                  j                  dz         }||z   }t        |||dz
  d      S )a  Helper that implements ragged gather when axis>0 and batch_dims==0.

  Args:
    params: The tensor from which to gather values.
    indices: The indices of values to gather.
    axis: The axis in `params` to gather `indices` from.

  Returns:
    A potentially ragged tensor.
  r%   rJ   r   r$   )rN   r   r6   rP   r:   r;   r/   r   r0   r   r   r   rT   rU   rV   r1   )r   r   r    rX   rY   rW   s         r!   r.   r.      s     
AXfm889))55
a'2D2D2J2J 6 Lf gfmmWdQhJKK]]
=
>>
 
 &f-+FGMM2+!+w}}/B/BQ/FG+{*	.q!	<<rH   c           	          t        | t        j                        r| j                  S t	        j
                  |       }t	        j                  | t	        j                  dg|dd gd            S )z;Returns a copy of `t` with the outer two dimensions merged.   Nr   r    )rN   r   r6   r0   r   r   reshapeconcat)tt_shapes     r!   rT   rT   (  sV    =--.88Oooa GQ	 0 02$1D1 MNNrH   c                     t        | t        j                        r$t        j                  | j                         |      S t        j                  | |      }t        j                  |d         |d   z  S )z.Returns the start indices for the rows in `t`.r*   r   r%   )	rN   r   r6   r	   cast
row_startsr   r   r=   )ra   r;   rb   s      r!   rU   rU   1  sU    =--.==//ooa%0G>>'!*%
22rH   c                 h   t        | t        j                        r| j                  t	        | |dz
              S t        j                  |       }t        j                  |t        j                  |       z
  g|j                        }t        j                  ||gd      }t        j                  | |      S )zEAdds *trailing* size-1 dimensions to `t` until it has the given rank.r%   r   r^   )rN   r   r6   r/   rV   r   r   onesr   r;   r`   r_   )ra   r   old_dimsnew_dims	new_shapes        r!   rV   rV   :  s    =--.==*1dQh788q!H~~tinnQ&778(..IH  (H!5A>IQ	**rH   c                 "    t        | |||||      S )N)r"   )r   r   r   r   r    r   s         r!   _ragged_gather_v1rl   E  s     
!14T	JJrH   c           	      &	   t        |t              r|dk7  rt        d      t        j                  |       s.t        j                  |      st        j                  | |||      S |dvrt        d      t        j                  |d| |g      5  t        j                  | d      } t        j                  |d	      }t        j                  | |      \  } }|j                  }|j                  }|t        d      |dk(  rt        d      t        j                  |      r||j                  dz   k(  rt        d      t        j                  |d         }|t        d      |dkD  rt        j                  |       }|r9t        j                   j#                  ||dz
  | j$                  j&                        }|j)                  t        | |j*                              }	|rFt        j                  |	      r1|	j                  |dz
  k(  rt        j                   j-                  |	      }	|	cd
d
d
       S t        j                  |      rJ t        j                  |       sJ |dk(  r| j                  t        j.                  | j*                        z   }
t1        |dz
        D ]  }t3        j4                  | d      }  t        j6                  t        j                  |      d
d t        j8                  |
gt:        j<                        gd      }t3        j>                  | |      cd
d
d
       S |dk(  r,t        j@                  |dg      }tC        | |      cd
d
d
       S tE        jF                  || j$                  j&                        }t        jB                  | j$                  |d         }||d   z  }| jH                  }t1        d|      D ]  }t        j                  |      sXt        j4                  |d      }t        j6                  ||d|d
f   gd      }t        j                  ||      c cd
d
d
       S t        jB                  |jK                         |      }||d|f   z  }|jH                  } tC        ||      cd
d
d
       S # 1 sw Y   y
xY w)a  Gather slices from `params` using `n`-dimensional indices.

  This operation is similar to `gather`, but it uses the innermost dimension
  of `indices` to define a slice into `params`.  In particular, if:

  * `indices` has shape `[A1...AN, I]`
  * `params` has shape `[B1...BM]`

  Then:

  * `result` has shape `[A1...AN, B_{I+1}...BM]`.
  * `result[a1...aN] = params[indices[a1...aN, :]]`

  Args:
    params: A potentially ragged tensor with shape `[A1...AN, I]`.
    indices: A potentially ragged tensor with shape `[B1...BM]`.
    batch_dims: Must be zero.
    name: A name for the operation (optional).
    bad_indices_policy: A string. If `""` or `"DEFAULT"`, the default behavior
      is used (error on CPU and ignore on GPU). If `"IGNORE"`, the bad indices
      are ignored and 0 is stored in the

  Returns:
    A potentially ragged tensor with shape `[A1...AN, B_{I+1}...BM]`.

  #### Examples:

  >>> params = tf.ragged.constant(
  ...     [ [ ['000', '001'], ['010'              ]          ],
  ...       [ ['100'       ], ['110', '111', '112'], ['120'] ],
  ...       [ [            ], ['210'              ]          ] ])

  >>> # Gather 2D slices from a 3D tensor
  >>> tf.gather_nd(params, [[2], [0]])
  <tf.RaggedTensor [[[], [b'210']], [[b'000', b'001'], [b'010']]]>

  >>> # Gather 1D slices from a 3D tensor
  >>> tf.gather_nd(params, [[2, 1], [0, 0]])
  <tf.RaggedTensor [[b'210'], [b'000', b'001']]>

  >>> # Gather scalars from a 3D tensor
  >>> tf.gather_nd(params, [[0, 0, 1], [1, 1, 2]]).numpy()
  array([b'001', b'112'], dtype=object)
  r   z7batch_dims != 0 is not supported for ragged gather yet.)r   bad_indices_policy) DEFAULTz>non-default bad_indices_policy not supported for ragged gatherRaggedGatherNdr   r   r   Nz!indices.rank be statically known.z indices.rank must be at least 1.r%   z4The innermost dimension of indices may not be raggedr\   z+indices.shape[-1] must be statically known.r]   rJ   r^   ).r   ).r%   .)&rN   intr   r   r,   r   	gather_ndr   r   r   r   r   r1   rK   r   dimension_valuer6   rP   r:   r;   with_flat_valuesr5   	to_tensorr   r=   r
   expand_dimsr`   rg   r   int32tiler_   r"   r	   rd   r0   re   )r   r   r   r   rn   rE   indices_ndims
index_sizeindices_is_denserC   params_ndimsrG   	multiplesflattened_index_tuplesflattened_paramss                  r!   rs   rs   R  sz   h 
J	$
a
N
OO

!
!&
)]-D-DW-Md7I  .
H  ~~d,vw.?@ Y>==XF>>i!G#;;FGLOFGMMM!''M:;;9::(,,q00MNN --mB.?@JDEE
 q*44W==	,,88!2#..44 9 6 ''	&':M:M(NOf
}66v>


 1
1++55f=IY> Y>P &&w///""6*** Q'')..9K9K*LLl}q() >#!--f1=>""
//'
"3B
'
..,
6$ )*	+i
 ""695mY> Y>r 
q(002$?F23wY> Y>D gv'8'8'>'>?g  )//0A0A07 A/ q*% 3#&&'78#,#8#8$1$.
 #,#3#3%wsCDy'9:$D
 $$%57MN
NcY> Y>f "+!1!1'')+A"C'#s("33+223 $&<=sY> Y> Y>s(   FR.C0R('RCR6ARRc                 "    t        | ||||      S )N)rn   )rs   )r   r   r   r   rn   s        r!   _ragged_gather_nd_v1r     s     
gz4<N
 rH   r   c                    | j                   dd }| j                   d   }| j                   d   }|d   }|d   }|dd D ]  }t        j                  ||      } t        j                  |dg      }t	        j
                  t        j                  ||      t        j                  |dd |            j                  }	t        j                  ||	t        j                  |            }
|D cg c]  }d c}|
dgz   S c c}w )zGradient for RaggedGather op.Nr\   r   r%   )r0   r   dense_shape)
inputsr   r"   r_   r   r=   r0   r   IndexedSlicesr   )opgradsparam_nested_splitsparam_inner_valuesr   grad_inner_valuescombined_splitsr:   flat_indicesgrad_indicesparam_inner_values_grad_s               r!   _ragged_gather_gradr     s    		#2yy}IIbM'Bi
 (*/'+ Dj&&z?COD ""7RD1, !&&5qr*L9;;A6  +88//"457 ,	,1$	,0G/N	NN	,s   )	C:)NNr   N)NNr   r   )r   Nro   )Nr   ro   ) __doc__tensorflow.python.frameworkr   r   r   r   tensorflow.python.opsr   r   r	   tensorflow.python.ops.raggedr
   r   r   tensorflow.python.utilr   dispatch_for_api	gather_v2RaggedOrDenser"   r   r-   r.   rT   rU   rV   rl   gather_nd_v2rs   r   RegisterGradientr    rH   r!   <module>r      s   + . 6 + 4 + 6 * 9 8 6 + 9../ !K6=.. K6!//K6 0K6\;|O=d%=PO3+ 9++, (,!"Km99 K,::K -K 9112 	X>''X>((X> 3X>v 9../ 
	''	((	 0	 n%O &OrH   