
    AVh9)                        d Z ddlmZ ddlmZ ddlmZ  ej                  d        ej                  d        ej                  d        ej                  d        ej                  d	        ej                  d
        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d       d Z ej                  d       ej                  d       ej                  d      dej                  fd                     Z
 ej                  d       ej                  d       ej                  d      dej                  fd                     Z ej                  d       ej                  d       ej                  d      dej                  fd                     Z ej                  d        ej                  d!       ej                  d"      dej                  fd#                     Z ej                  d$       ej                  d%       ej                  d&      dej                  fd'                     Z ej                  d(       ej                  d)       ej                  d*      dej                  fd+                     Zy,)-z7Gradients for operators defined in tensor_array_ops.py.    )ops)	array_ops)tensor_array_opsTensorArrayTensorArrayGradTensorArraySizeTensorArrayCloseTensorArrayV2TensorArrayGradV2TensorArraySizeV2TensorArrayCloseV2TensorArrayV3TensorArrayGradV3TensorArrayGradWithShapeTensorArraySizeV3TensorArrayCloseV3c                    | j                   j                  d      }t        |      D cg c]  \  }}|j                  d      s| }}}|st	        d| j                    d      dj                  |d|d   dz          S c c}}w )a  Identify which call to tf.gradients created this gradient op or tensor.

  TensorArray gradient calls use an accumulator TensorArray object.  If
  multiple gradients are calculated and run in the same session, the multiple
  gradient nodes may accidentally flow through the same accumulator TensorArray.
  This double counting breaks the TensorArray gradient flow.

  The solution is to identify which gradient call this particular
  TensorArray*Grad is being called in, by looking at the input gradient
  tensor's name, and create or lookup an accumulator gradient TensorArray
  associated with this specific call.  This solves any confusion and ensures
  different gradients from the same forward graph get their own accumulators.

  This function creates the unique label associated with the tf.gradients call
  that is used to create the gradient TensorArray.

  Args:
    op_or_tensor: `Tensor` or `Operation` which is an input to a
      TensorArray*Grad call.

  Returns:
    A python string, the unique label associated with this particular
    gradients calculation.

  Raises:
    ValueError: If not called within a gradients calculation.
  /	gradientszHExpected op/tensor name to start with gradients (excluding scope), got: z. This means that a tf.gradients op with this op in its dependency path has a custom name that does not start with 'gradients'. Please make sure all calls to tf.gradients that have non-empty `name` arguments use names that start with 'gradients'.N   )namesplit	enumerate
startswith
ValueErrorjoin)op_or_tensorname_tokensixgrad_poss        W/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/tensor_array_grad.py_GetGradSourcer$   '   s    8 !!'',+%k2PDAqall;6OaP(P	
	##$ %	  
+/x|a/0	11 Qs   B B TensorArrayReadTensorArrayReadV2TensorArrayReadV3opc                 *   | j                   d   }| j                   d   }| j                   d   }| j                  d      }t        |      }t        j                  |||d      j                  ||      }|j                  ||      }dd|j                  gS )	a  Gradient for TensorArrayRead.

  Args:
    op: Forward TensorArrayRead op.
    grad: Gradient `Tensor` to TensorArrayRead.

  Returns:
    A flow `Tensor`, which can be used in control dependencies to
    force the write of `grad` to the gradient `TensorArray`.
  r   r      dtypeFr+   handleflowcolocate_with_first_write_callsourcer.   N)inputsget_attrr$   r   r   gradwriter.   )	r(   r4   r-   indexr.   r+   grad_sourcegw_gs	            r#   _TensorArrayReadGradr:   P   s    & 99Q<&
))A,%	1$
++g
%t$+##%TCHJKd+  	
t#
chh	    TensorArrayWriteTensorArrayWriteV2TensorArrayWriteV3c                    | j                   d   }| j                   d   }| j                  d      }t        |      }t        j                  | j
                  d   d      }t        j                  |g      5  t        j                  |d      }ddd       t        j                  |||d      j                  ||	      }|j                  |      }dd||gS # 1 sw Y   JxY w)
zGradient for TensorArrayWrite.

  Args:
    op: Forward TensorArrayWrite op.
    flow: Gradient `Tensor` flow to TensorArrayWrite.

  Returns:
    A grad `Tensor`, the gradient created in an upstream ReadGrad or PackGrad.
  r   r   Tflow_outwrite_barrierNFr,   r0   )r2   r3   r$   r   identityoutputsr   control_dependenciesr   r   r4   read)	r(   r.   r-   r6   r+   r7   rA   r8   r4   s	            r#   _TensorArrayWriteGradrG   o   s     99Q<&
))A,%
++c
%t$+

1z:( 
+ 5dO4D5##%TCHJKd+  
$
dD	!!5 5   4CCTensorArrayGatherTensorArrayGatherV2TensorArrayGatherV3c                 *   | j                   d   }| j                   d   }| j                   d   }| j                  d      }t        |      }t        j                  |||d      j                  ||      }|j                  ||      }dd|j                  gS )	a  Gradient for TensorArrayGather.

  Args:
    op: Forward TensorArrayGather op.
    grad: Gradient `Tensor` to TensorArrayGather.

  Returns:
    A flow `Tensor`, which can be used in control dependencies to
    force the write of `grad` to the gradient `TensorArray`.
  r   r   r*   r+   Fr,   r0   N)r2   r3   r$   r   r   r4   scatterr.   )	r(   r4   r-   indicesr.   r+   r7   r8   u_gs	            r#   _TensorArrayGatherGradrP      s    & 99Q<&IIaL'	1$
++g
%t$+##%TCHJKd+  	
		'4 #
chh	r;   TensorArrayScatterTensorArrayScatterV2TensorArrayScatterV3c                    | j                   d   }| j                   d   }| j                  d      }t        |      }t        j                  | j
                  d   d      }t        j                  |g      5  t        j                  |d      }ddd       t        j                  |||d      j                  ||	      }|j                  |      }dd||gS # 1 sw Y   JxY w)
zGradient for TensorArrayScatter.

  Args:
    op: Forward TensorArrayScatter op.
    flow: Gradient `Tensor` flow to TensorArrayScatter.

  Returns:
    A grad `Tensor`, the gradient created in upstream ReadGrads or PackGrad.
  r   r   r@   rA   rB   NFr,   r0   )r2   r3   r$   r   rC   rD   r   rE   r   r   r4   gather)	r(   r.   r-   rN   r+   r7   rA   r8   r4   s	            r#   _TensorArrayScatterGradrV      s     99Q<&IIaL'
++c
%t$+

1z:( 
+ 5dO4D5##%TCHJKd+  
'	$
dD	!!5 5rH   TensorArrayConcatTensorArrayConcatV2TensorArrayConcatV3c                 *   | j                   d   }| j                   d   }| j                  d   }| j                  d      }t        |      }t	        j
                  |||d      j                  ||      }|j                  ||      }	d|	j                  gS )	a  Gradient for TensorArrayConcat.

  Args:
    op: Forward TensorArrayConcat op.
    grad: Gradient `Tensor` to TensorArrayConcat.

  Returns:
    A flow `Tensor`, which can be used in control dependencies to
    force the write of `grad` to the gradient `TensorArray`.
  r   r   r+   Fr,   r0   )lengthsN)	r2   rD   r3   r$   r   r   r4   r   r.   )
r(   r4   unused_lengths_gradr-   r.   r[   r+   r7   r8   rO   s
             r#   _TensorArrayConcatGradr]      s    & 99Q<&	1$JJqM'
++g
%t$+##%TCHJKd+  	
g&#
	r;   TensorArraySplitTensorArraySplitV2TensorArraySplitV3c                    | j                   d   }| j                  d      }t        |      }t        j                  | j
                  d   d      }t        j                  |g      5  t        j                  |d      }ddd       t        j                  |||d      j                  ||      }|j                         }d|d|gS # 1 sw Y   IxY w)	zGradient for TensorArraySplit.

  Args:
    op: Forward TensorArraySplit op.
    flow: Gradient `Tensor` flow to TensorArraySplit.

  Returns:
    A grad `Tensor`, the gradient created in upstream ReadGrads or PackGrad.
  r   r@   rA   rB   NFr,   r0   )r2   r3   r$   r   rC   rD   r   rE   r   r   r4   concat)r(   r.   r-   r+   r7   rA   r8   r4   s           r#   _TensorArraySplitGradrc      s     99Q<&
++c
%t$+

1z:( 
+ 5dO4D5##%TCHJKd+  
$
dD	!!5 5s   %CCN)__doc__tensorflow.python.frameworkr   tensorflow.python.opsr   r   NotDifferentiabler$   RegisterGradient	Operationr:   rG   rP   rV   r]   rc    r;   r#   <module>rk      s   > + + 2   m $   ' (   ' (   ( )   o &   ) *   ) *   * +   o &   ) *   0 1   ) *   * +&2R '()*)* S]]   + + ) 8 ()*+*+"cmm " , , *": )*+,+, s}}   - - + 8 *+,-,-" " . . ,"6 )*+,+,s}}  - - +: ()*+*+"cmm " , , *"r;   