
    uki2                       U d dl mZ d dlZd dlmZ d dlZd dlZd dlZd dl	m
Z
 d dl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c 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!m"Z"  ejF                  e$        G d de%      Z& ejN                  ejP                        jR                  Z* ejV                         Z,g a-de.d<    G d dej^                        Z0 e0       Z1d'dZ2 G d d      Z3d(dZ4d'dZ5 ejl                  d       G d d             Z7 ejp                  e7dd        ejr                  e7e7jt                   d e7jv                   d! d" #       d)d$Z<d% Z=d& Z>y)*    )annotationsN)partial)TracebackType)core)source_info_util)traceback_util)	tree_util)	shard_map)_export)lax)NamedShardingPartitionSpec)Array	ArrayLikec                      e Zd ZdZy)JaxValueErrorzEException raised for runtime errors detected within JAX computations.N)__name__
__module____qualname____doc__     O/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/error_check.pyr   r   *   s    Mr   r   z%list[tuple[str, TracebackType | str]]_error_listc                      e Zd Zd Zy)_ErrorStoragec                    d | _         y N)refselfs    r   __init__z_ErrorStorage.__init__<   s	     $DHr   N)r   r   r   r"   r   r   r   r   r   :   s    %r   r   c                 ^   t        j                         } | j                  rt        j                  t
              }nUt        | t        | j                         }t        j                  | j                  t        j                  t
              |      }t        j                  |      t        _        y)a  Initialize the error code ref in the current thread.

  The shape and size of the error code array depend on the mesh in the context.
  In single-device environments, the array is a scalar. In multi-device
  environments, its shape and size match those of the mesh.
  shardingN)mesh_libget_concrete_meshemptynpuint32	_NO_ERRORr   P
axis_namesr   full
axis_sizesr   new_ref_error_storager   )mesh
error_coder%   s      r   _initialize_error_code_refr4   C   su     
	#	#	%$	ZZIIi0J T1doo#67H
		)J ||J/.r   c                  &    e Zd ZdZdZd Zd Zd Zy)error_checking_contextaq  Redefine the internal error state based on the mesh in the context.

  When using JAX in multi-device environments in explicit mode, error tracking
  needs to be properly aligned with the device mesh. This context manager
  ensures that the internal error state is correctly initialized based on the
  current mesh configuration.

  This context manager should be used when starting a multi-device computation,
  or when switching between different device meshes.

  On entering the context, it initializes a new error state based on the mesh in
  the context. On exiting the context, it restores the previous error state.
  old_refc                    d | _         y r   r7   r    s    r   r"   zerror_checking_context.__init__l   s	    DLr   c                    t         j                  | _        t        j                         5  t                d d d        | S # 1 sw Y   | S xY wr   )r1   r   r8   r   eval_contextr4   r    s    r   	__enter__z error_checking_context.__enter__o   s;    !%%DL				 # "#K#Ks	   ?A	c                .    | j                   t        _        y r   )r8   r1   r   )r!   exc_type	exc_value	tracebacks       r   __exit__zerror_checking_context.__exit__u   s    Nr   N)r   r   r   r   	__slots__r"   r<   rA   r   r   r   r6   r6   [   s     )&r   r6   c                  ddl m} t        j                  9t	        j
                         5  t                ddd       t        j                  J t        j                         j                  }|J |j                         }t        |t              sJ t        j                  |      }t        |t              sJ t        5  t!        j"                  t%        t&                    }t&        j)                  ||f       ddd       t	        j*                  t        j                        j,                  }t	        j*                  |       j,                  }t/        d |j0                  D              r| j3                         } nt4        j6                  j8                  |j:                  j<                  v }|r+t?        j@                  dtB               | j3                         } n|j:                  |j:                  k7  r&tE        d|j:                   d|j:                   d       tG        jF                  tI        |j2                  d	      |j:                  |j0                  |j0                  
      |       } t        j                  d   }|jK                  ||j#                  tL              k(  |       }	|jO                  |	|      }|t        j                  d<   y# 1 sw Y   xY w# 1 sw Y   xY w)a(  Set the internal error state if any element of `pred` is `True`.

  This function is used inside JAX computations to detect runtime errors without
  immediately halting execution. When this function is traced (e.g., inside
  :func:`jax.jit`), the corresponding error message and its traceback are
  recorded. At execution time, if `pred` contains any `True` values, the error
  state is set, but execution continues without interruption. The recorded error
  can later be raised using :func:`raise_if_error`.

  If the error state has already been set, subsequent errors are ignored and
  will not override the existing error.

  For multi-device environments, in explicit mode, users must call
  :func:`error_checking_context` to initialize a new error tracking state that
  matches the device mesh. In auto mode, implicit cross-device communication may
  occur inside this function, which could impact performance. A warning is
  issued in such cases.

  When exporting a function with `jax.export`, error checking must be explicitly
  wrapped using :func:`wrap_for_export` before export and
  :func:`unwrap_from_import` after import.

  Args:
    pred: A JAX boolean array. If any element of `pred` is `True`, the internal
      error state will be set.
    msg: The corresponding error message to be raised later.
  r   Nc              3  $   K   | ]  }|d u  
 y wr   r   ).0dims     r   	<genexpr>zset_error_if.<locals>.<genexpr>   s     22s   zWhen at least one mesh axis of `pred` is in auto mode, calling `set_error_if` will cause implicit communication between devices. To avoid this, consider converting the mesh axis in auto mode to explicit mode.zIThe error code state and the predicate must be on the same mesh, but got z and zm respectively. Please use `with error_checking_context()` to redefine the error code state based on the mesh.T)keepdims)r2   in_specs	out_specs.)(	jax.numpynumpyr1   r   r   r;   r4   r   currentr@   as_python_traceback
isinstancer   r   filter_traceback_error_list_lockr)   r*   lenr   appendtypeofr%   allspecanyr&   AxisTypeAutor2   
axis_typeswarningswarnRuntimeWarning
ValueErrorr
   r   logical_andr+   where)
predmsgjnpr@   new_error_codeout_shardingin_shardinghas_auto_axesr3   should_updates
             r   set_error_ifri   y   sg   : 				 # "#))) &&(22)			++-)	I}	--	---i8)	I}	--	- )YYs;/0NY'() ^//099,#{{4099+ 	2 1 12288:D%%**k.>.>.I.IIMmm  XXZd			k..	.#((){/?/?.@ A,,
 	
Y  
#''D
)  ## %%	
 	d !!#&*//*

90E"EtL-yy
C*&.Si# #) )s   K:KKK#c                    t         j                  yt         j                  d   j                         } t        | t        j
                        rt        d      | t        j                  t              k(  ryt        j                  t         j                  j                  t        j                  t              t         j                  j                        t         j                  d<   t        5  t        |    \  }}ddd       t        t               rt#         d|       }|t#              }|j%                  |      # 1 sw Y   GxY w)a"  Raise an exception if the internal error state is set.

  This function should be called after a computation completes to check for any
  errors that were marked during execution via `set_error_if()`. If an error
  exists, it raises a `JaxValueError` with the corresponding error message.

  This function should not be called inside a traced function (e.g., inside
  :func:`jax.jit`). Doing so will raise a `ValueError`.

  Raises:
    JaxValueError: If the internal error state is set.
    ValueError: If called within a traced JAX function.
  N.z`raise_if_error() should not be called within a traced context, such as within a jitted function.r$   z(
The original traceback is shown below:
)r1   r   minrO   r   Tracerr^   r)   r*   r+   r   r.   shaper%   rQ   r   strr   with_traceback)r3   rb   r@   excs       r   raise_if_errorrq      s    
!!#&**,*
DKK(
	%  299Y''
HHii	!!**.S  - ,NC-	3
%9)EC I

C


Y
''- -s   +D>>ET)frozenc                  &    e Zd ZU dZded<   ded<   y)_ErrorClassa  A class to store error information for AOT compilation.

  This class is used internally by the wrapper functions `wrap_for_export` and
  `unwrap_from_import` to encapsulate error-related data within an exported
  function.

  Attributes:
    error_code (jax.Array): A JAX array representing the final error state of
      the function to be exported. This value is local to the wrapper function.
    error_list (list[tuple[str, str]]): A list of `(error_message, traceback)`
      pairs containing error messages and corresponding stack traces. This error
      list is local to the wrapper function, and does not contain pairs of error
      information from other functions.
  r   r3   zlist[tuple[str, str]]
error_listN)r   r   r   r   __annotations__r   r   r   rt   rt      s     ##r   rt   )r3   )ru   )data_fieldsmeta_fields.c                N    t        j                  | d      j                  d      S )NF)ensure_asciiutf-8)jsondumpsencodexs    r   <lambda>r     s    

15 A H H! r   c                J    t        j                  | j                  d            S )Nr|   )r}   loadsdecoder   s    r   r   r     s    $**QXXg->"? r   )serialized_nameserialize_auxdatadeserialize_auxdatac                    dj                  t        j                  t        j                  |                   j	                  d      S )z+Convert a traceback to a string for export. 
)jointb_libformat_list
extract_tbrstrip)r@   s    r   _traceback_to_strr     s2    	##F$5$5i$@A	B	I	I$	OOr   c                      fd}|S )a  Wrap a function with error checking to make it compatible with AOT mode.

  Error checking relies on global state, which cannot be serialized across
  processes. This wrapper ensures that the error state remains within the
  function scope, making it possible to export the function and later import in
  other processes.

  When the function is later imported, it must be wrapped with
  :func:`unwrap_from_import` to integrate the error checking mechanism of the
  imported function into the global error checking mechanism of the current
  process.

  This function should only be applied once to a function; wrapping the same
  function multiple times is unnecessary.
  c                    t        j                         5  t        j                  }d d d        t	                t
        5  t        g c}a 	| i |}t        j                  d   j                         }|t        ca}d d d        t        j                         5  t        _        d d d        D cg c]  \  }}|t        |      f }}}t        |      fS # 1 sw Y   xY w# 1 sw Y   jxY w# 1 sw Y   NxY wc c}}w N.)
r   r;   r1   r   r4   rQ   r   rk   r   rt   )
argskwargsr8   old_error_listoutr3   new_error_listrb   r@   fs
            r   innerzwrap_for_export.<locals>.inner3  s    
			 #""g# 	 @$/!nk tvc!%%c*..0j %3K!k>@ 
			 #"n# CQ0>Y	*+N  J777%# #@ @# #s(   C<C$C00C<C!$C-0C9r   r   r   s   ` r   wrap_for_exportr   "  s    "80 
,r   c                     t         j                  9t        j                         5  t	                ddd       t         j                  J  fd}|S # 1 sw Y   "xY w)a  Unwrap a function after AOT import to restore error checking.

  When an AOT-exported function is imported in a new process, its error state is
  separate from the global error state of the current process. This wrapper
  ensures that errors detected during execution are correctly integrated into
  the global error checking mechanism of the current process.

  This function should only be applied to functions that were previously wrapped
  with :func:`wrap_for_export` before export.
  Nc                     	| i |\  }}|j                   |j                  }}t        5  t        t              }t        j                  |       d d d        t        j                  d   }t        j                  |t        j                  t              k(  |t        j                  t              k7        }t        j                  ||z   |      }|t        j                  d<   |S # 1 sw Y   xY wr   )r3   ru   rQ   rR   r   extendr1   r   r   bitwise_andr)   r*   r+   select)
r   r   r   error_classrd   ru   offsetr3   rh   r   s
            r   r   z!unwrap_from_import.<locals>.inner^  s    $)&)C!,!7!79O9OJN 
 %;f$%
  ##C(JOObii	**"))I..M M>F+BJOJ(NsJ% %s   %C$$C-)r1   r   r   r;   r4   r   s   ` r   unwrap_from_importr   N  sV     				 # "#)))* 
,3# #s   AA)returnNone)rb   rn   ra   r   r   r   )r@   r   r   rn   )?
__future__r   dataclasses	functoolsr   r}   	threadingr@   r   typesr   r[   rL   r)   jax._srcr   r   r   r	   jax._src.mesh_srcr2   r&   r
   jax._src.exportr   jax._src.laxr   jax._src.sharding_implsr   r   r,   jax._src.typingr   r   register_exclusion__file__r^   r   iinfor*   maxr+   RLockrQ   r   rv   localr   r1   r4   r6   ri   rq   	dataclassrt   register_dataclass"register_pytree_node_serializationr   r   r   r   r   r   r   r   <module>r      s\   #          % #       #  E , " ! !( +NJ N BHHRYY##	 #9??$ 572 7%IOO % 00& &<T'n((V d#$ $ $$( 	  _/ + * *"--.a0D0D/EF @P
)X%r   