
    AVhT3                        d Z ddl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(                  ej*                     fd       Z ed      ej,                   ej$                  ej.                        	 	 ddej(                  ej*                     fd                     Zd Zd Zd Zd Zd Zd Zy)z.Concat and stack operations for RaggedTensors.    N)ops)tensor_shape)	array_ops)array_ops_stack)	check_ops)math_ops)ragged_gather_ops)ragged_tensor)ragged_util)dispatch)	tf_exportvaluesc                     t        | t        t        f      s| g} t        j                  |d|       5  t        | |d      cddd       S # 1 sw Y   yxY w)aG  Concatenates potentially ragged tensors along one dimension.

  Given a list of tensors with the same rank `K` (`K >= axis`), returns a
  rank-`K` `RaggedTensor` `result` such that `result[i0...iaxis]` is the
  concatenation of `[rt[i0...iaxis] for rt in values]`.

  Args:
    values: A list of potentially ragged tensors.  May not be empty. All
      `values` must have the same rank and the same dtype; but unlike
      `tf.concat`, they can have arbitrary shapes.
    axis: A python integer, indicating the dimension along which to concatenate.
      (Note: Unlike `tf.concat`, the `axis` parameter must be statically known.)
        Negative values are supported only if the rank of at least one
        `values` value is statically known.
    name: A name prefix for the returned tensor (optional).

  Returns:
    A `RaggedTensor` with rank `K`.
    `result.ragged_rank=max(axis, max(rt.ragged_rank for rt in values]))`.

  Raises:
    ValueError: If `values` is empty, if `axis` is out of bounds or if
      the input tensors have different ranks.

  #### Example:

  >>> t1 = tf.ragged.constant([[1, 2], [3, 4, 5]])
  >>> t2 = tf.ragged.constant([[6], [7, 8, 9]])
  >>> tf.concat([t1, t2], axis=0)
  <tf.RaggedTensor [[1, 2], [3, 4, 5], [6], [7, 8, 9]]>
  >>> tf.concat([t1, t2], axis=1)
  <tf.RaggedTensor [[1, 2, 6], [3, 4, 5, 7, 8, 9]]>
  RaggedConcatFstack_valuesN
isinstancelisttupler   
name_scope_ragged_stack_concat_helperr   axisnames      ^/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_concat_ops.pyconcatr       sO    F 
FT5M	*XF
~~dNF3 I&vt%HI I I   A		Azragged.stackc                     t        | t        t        f      s| g} t        j                  |d|       5  t        | |d      cddd       S # 1 sw Y   yxY w)a  Stacks a list of rank-`R` tensors into one rank-`(R+1)` `RaggedTensor`.

  Given a list of tensors or ragged tensors with the same rank `R`
  (`R >= axis`), returns a rank-`R+1` `RaggedTensor` `result` such that
  `result[i0...iaxis]` is `[value[i0...iaxis] for value in values]`.

  #### Examples:

  >>> # Stacking two ragged tensors.
  >>> t1 = tf.ragged.constant([[1, 2], [3, 4, 5]])
  >>> t2 = tf.ragged.constant([[6], [7, 8, 9]])
  >>> tf.ragged.stack([t1, t2], axis=0)
  <tf.RaggedTensor [[[1, 2], [3, 4, 5]], [[6], [7, 8, 9]]]>
  >>> tf.ragged.stack([t1, t2], axis=1)
  <tf.RaggedTensor [[[1, 2], [6]], [[3, 4, 5], [7, 8, 9]]]>

  >>> # Stacking two dense tensors with different sizes.
  >>> t3 = tf.constant([[1, 2, 3], [4, 5, 6]])
  >>> t4 = tf.constant([[5], [6], [7]])
  >>> tf.ragged.stack([t3, t4], axis=0)
  <tf.RaggedTensor [[[1, 2, 3], [4, 5, 6]], [[5], [6], [7]]]>

  Args:
    values: A list of `tf.Tensor` or `tf.RaggedTensor`.  May not be empty. All
      `values` must have the same rank and the same dtype; but unlike
      `tf.stack`, they can have arbitrary dimension sizes.
    axis: A python integer, indicating the dimension along which to stack.
      (Note: Unlike `tf.stack`, the `axis` parameter must be statically known.)
      Negative values are supported only if the rank of at least one
      `values` value is statically known.
    name: A name prefix for the returned tensor (optional).

  Returns:
    A `RaggedTensor` with rank `R+1` (if `R>0`).
    If `R==0`, then the result will be returned as a 1D `Tensor`, since
    `RaggedTensor` can only be used when `rank>1`.
    `result.ragged_rank=1+max(axis, max(rt.ragged_rank for rt in values]))`.

  Raises:
    ValueError: If `values` is empty, if `axis` is out of bounds or if
      the input tensors have different ranks.
  r   Tr   Nr   r   s      r   stackr    I   sO    ` 
FT5M	*XF
~~dNF3 H&vt$GH H Hr   c                    | st        d      | D cg c]  }t        j                  |d       } }t        j                  | ddi\  }} t	        |       } t        |       dk(  r|s| d   S d}| D ]6  }||j                  j                  }|j                  j                  |       8 ||s|n|dz   }t        j                  ||      }|rv|dk(  rq|dk(  rlt        j                  j                  t        j                  | d	      t        j                  | D cg c]  }t        j                  |       c}d	      
      S t        d | D              r@|>||dz
  k(  s||dz
  k(  r.|rt        j                   | |      S t        j                  | |      S t#        t        |             D ]C  }	t        j$                  | |	         rt        j                  j'                  | |	   d|      | |	<   E t)        t)        d | D              d      }
| D cg c]  }t+        ||
|       } }|dk(  rt-        | |      S |dk(  rt/        | |      S | D cg c]  }|j0                   }}| D cg c]  }|j2                  g }}t5        j6                  t9        j:                  |            5  t        j                  j=                  t?        ||dz
  |      |d   d   d      cddd       S c c}w c c}w c c}w c c}w c c}w # 1 sw Y   yxY w)a  Helper function to concatenate or stack ragged tensors.

  Args:
    rt_inputs: A list of RaggedTensors or Tensors to combine.
    axis: The axis along which to concatenate or stack.
    stack_values: A boolean -- if true, then stack values; otherwise,
      concatenate them.

  Returns:
    A RaggedTensor.
  Raises:
    ValueError: If rt_inputs is empty, or if axis is out of range.
  zrt_inputs may not be empty.rt_input)r   return_dtypeT   r   Nr   )r   row_lengthsc              3   H   K   | ]  }t        j                  |         y wN)r
   	is_ragged.0rts     r   	<genexpr>z._ragged_stack_concat_helper.<locals>.<genexpr>   s     =R]$$R(	(=s    ")ragged_rankrow_splits_dtypec              3   4   K   | ]  }|j                     y wr(   )r.   r*   s     r   r-   z._ragged_stack_concat_helper.<locals>.<genexpr>   s     ;2;s   Fvalidate) 
ValueErrorr
   "convert_to_tensor_or_ragged_tensormatch_row_splits_dtypesr   lenshapendimsassert_has_rankr   get_positive_axisRaggedTensorfrom_row_lengthsr   allr   r    ranger)   from_tensormax_increase_ragged_rank_to_ragged_stack_concat_axis_0_ragged_stack_concat_axis_1r   
row_splitsr   control_dependenciesr   assert_splits_matchfrom_row_splitsr   )	rt_inputsr   r   r"   r/   r8   r,   	out_ndimsrir.   r   splitss                r   r   r      s    

2
33
 6?)1 66
%)  !. E E!%#!%I9o) 	^qQ< % &b}hhnnehhu%	& \e	)		$	$T9	5$eqjTQY%%66	2$$)%LQiooa&8%L*+- 7 . . 	=9==di!m3tuqy7H	$$Y55	400 Y  Ja""9Q<0"//;;
A,A8H < JilJ C;;;Q?+"$ (K9IJ $) $ 
QY&y,??qy&y,??"+,Bbii,F,4=>x""#>F>		!	!+"A"A&"I	J (''77
%fdQh
E
)A, 8 (( (u4 &M,$ ->( (s)   KK$K)K.!K36K88Lc                 F   | D cg c]  }|j                    }}t        j                  |d      }| D cg c]  }|j                   }}| d   j                  }t        |      D cg c]  }t        |D cg c]  }||   	 c}        }	}}|rXt        j                  | D cg c]  }|j                          c}      }
t        j                  |
      }|	j                  d|       t        j                  j                  ||	d      S c c}w c c}w c c}w c c}}w c c}w )a  Helper function to concatenate or stack ragged tensors along axis 0.

  Args:
    rt_inputs: A list of RaggedTensors, all with the same rank and ragged_rank.
    stack_values: Boolean.  If true, then stack values; otherwise, concatenate
      them.

  Returns:
    A RaggedTensor.
  r   r%   Fr1   )flat_valuesr   r   nested_row_splitsr.   r>   _concat_ragged_splitsr   r    nrowsr   lengths_to_splitsinsertr
   r;   from_nested_row_splits)rH   r   r,   rN   concatenated_flat_valuesnested_splitsr.   dimnsconcatenated_nested_splitsstack_lengthsstack_splitss               r   rB   rB      s&    +44B4+4&--kB 3<<B2''<-<!((+ {#   '46!#  W 6 7    #))	*J"288:*JKM00?L%%a6		#	#	:	: :U 
; 
L L' 5
 =6  +Ks(   D	D'D5D	D"DDc           
      z   t        |       }g }| d   j                         }t        | dd       D ]A  \  }}|j                  t	        j
                  ||j                         d|dz    d             C t        j                  |      5  t        | d      }t        j                  ||z        }t        j                  ||d	g      }	t        j                  |	      }
t        j                  |
d	g      }t        j                  ||      }|rTt        j                  d||z  dz   |      }t!        | |       t"        j$                  j'                  ||d
      cddd       S |j(                  dd|   }t!        | |       t"        j$                  j'                  |j*                  |d
      cddd       S # 1 sw Y   yxY w)a  Helper function to concatenate or stack ragged tensors along axis 1.

  Args:
    rt_inputs: A list of RaggedTensors, all with the same rank and ragged_rank.
    stack_values: Boolean.  If true, then stack values; otherwise, concatenate
      them.

  Returns:
    A RaggedTensor.
  r   r$   Nz"Input tensors at index 0 (=x) and z (=y) have incompatible shapes.)messageFr   r1   )r6   rQ   	enumerateappendr   assert_equalr   rE   rB   r   r>   r   reshape	transposer	   gather_copy_row_shaper
   r;   rG   rD   r   )rH   r   
num_inputsnrows_checksrt_nrowsindexr,   concatenated_rtrow_indicesrow_index_matrixtransposed_row_index_matrixrow_permutationpermuted_rtr[   concat_splitss                  r   rC   rC      s    9~*,q\!(Yqr]+ 
ieRHHJ4U1WI >( (		
	
 - =1)%PO ..J!67K ((z26FG"+"5"56F"G''(CbTJO#**?OLK^^Ax*'<q'@*Mli.''77
|e 8 5)= =2 ",,\z\:mi/''77


me 8 =7= = =s   CF1A	F11F:c                     | D ]F  }|j                   d   |j                  t        j                  |j                   d   dz                H y)z>Sets splits.shape to [rt[shape[0]+1] for each rt in rt_inputs.r   Nr$   )r7   	set_shaper   TensorShape)rH   rL   r,   s      r   re   re   /  sF     Bb	xx{|//a@AB    c                     |dkD  rnt        j                  |       s!t         j                  j                  | |      } | j                  |k  r)| j                  t        | j                  |dz
  |            } | S )zGAdds ragged dimensions to `rt_input` so it has the desired ragged rank.r   )r/   r$   )r
   r)   r;   r?   r.   with_valuesrA   r   )r"   r.   r/   s      r   rA   rA   6  st    1_""8,++77
%5 8 7hk)%%
"8??K!O#356h 
/rt   c                     | d   g}| d   d   }| dd D ]!  }|j                  |dd |z          ||d   z  }# t        j                  |d      S )zCConcatenates a list of RaggedTensor splits to form a single splits.r   r^   r$   Nr%   )r`   r   r   )splits_listpiecessplits_offsetrL   s       r   rP   rP   C  sk    N&a.$-AB  f
MM&*},-VBZM  
		&q	))rt   r(   )r   N)__doc__typingtensorflow.python.frameworkr   r   tensorflow.python.opsr   r   r   r   tensorflow.python.ops.raggedr	   r
   r   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   dispatch_for_apir   ListRaggedOrDenseadd_dispatch_supportr    r   rB   rC   re   rA   rP    rt   r   <module>r      s    5  + 4 + 1 + * : 6 4 + 6 9++,%I6;;}::; %I -%IP >	?0010H&++m99: 0H 2  0HfP(f LF7=tB
*rt   