
    `i              	          U d dl Z d dlZd dlZd dlZd dlmZmZ d dlZd dlZd dl	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Zd dlZd dlmZ  e            r'd dlZdZej        ej        j        fZeedf         ed	<   n
d
Zej        fZd Zd Zd Zd Z d Z!e"e#e$e%e&e'e(ee
j)        j*        g	Z+d Z,d Z-	 dDdZ.d Z/d Z0d Z1d Z2d Z3	 	 dEdZ4d Z5d Z6d Z7	 	 	 dFddd Z8	 	 	 	 dGd"Z9	 	 	 dHd$Z:	 	 	 dId%Z;	 	 	 dJd&Z<	 dKd'Z=	 	 	 dLd(Z>dMd)Z?ddde#fd*Z@d8d,ZAe
jB        e
jC        fZDe
jE        e
jF        fZGeGe
jH        fz   ZI eJd- d.D                       ZK eJd/ d0D                       ZLeKeLz   ZMeMe
jN        fz   ZOeGeOz   ZPeIeOz   ZQd1 ZR	 	 dNd2ZSdOd3ZTd8d4ZUd8d5ZVdOd6ZWd8d7ZXdPd9ZY	 	 	 dQd;ZZdPd<Z[dPd=Z\dRd>Z]dSd@Z^dSdAZ_dTdCZ`dS )U    N)TupleType)	AxisError)_array)_parameterized)is_availableT._skip_classesFc                     | d S d                     t          j                            |                                                     S )N )join	tracebackTracebackExceptionfrom_exceptionformat)excs    g/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/cupy/testing/_loops.py_format_exceptionr       s;    
{t779/>>sCCJJLLMMM    c                     t           f}t          r|t          j        j        fz  }	  | |i |}d }n&# |$ r}|j        }|j        |d }|}Y d }~nd }~ww xY w||fS N)	Exception_is_pytest_available_pytestoutcomesSkipped__traceback__tb_next)implargskw
exceptionsresulterroretbs           r   
_call_funcr&   '   s    J 0g&.//
	t"r""   _:G 5=s   
1 AAAc                 N   t          |t                    sJ |t          |t                    sJ |t          |t                    sJ |                                }|rt          j        j        ||<   |rt          j        ||<   t          ||<   t          | ||          \  }}||fS r   )
isinstancestrcopycupyxscipysparsecupyr&   )r   r   r    namesp_name
scipy_namer"   r#   s           r   _call_func_cupyr2   ;   s    dC     ?j#66??6J!<!<<	B  )k(7 %:BtHtT2..MFE5=r   c                 6   t          |t                    sJ |t          |t                    sJ |t          |t                    sJ |                                }t          ||<   |rdd l}|j        ||<   |r	dd l}|||<   t          | ||          \  }}||fS )Nr   )r(   r)   r*   numpyscipy.sparser-   r,   r&   )	r   r   r    r/   r0   r1   r,   r"   r#   s	            r   _call_func_numpyr6   K   s    dC     ?j#66??6J!<!<<	B BtH #l7 :tT2..MFE5=r   c                 j    t          | |||||          \  }}t          | |||||          \  }}	||||	fS r   )r2   r6   )
r   r   r    r/   r0   r1   cupy_result
cupy_errornumpy_resultnumpy_errors
             r   _call_func_numpy_cupyr<   ]   s\    -dBgz3 3K !1dBgz!3 !3L+ 	Zk# #r   c                 H     t           fdt          D                       S )zJChecks if try/except blocks are equivalent up to public error classes
    c              3   \   K   | ]&}t          |          t          |          k    V  'd S r   )r(   ).0errr9   r;   s     r   	<genexpr>z5_check_numpy_cupy_error_compatible.<locals>.<genexpr>v   sP       ) ) *c**jc.J.JJ ) ) ) ) ) )r   )all_numpy_errorsr9   r;   s   ``r   "_check_numpy_cupy_error_compatiblerE   r   sC      ) ) ) ) )') ) ) ) ) )r   c                     |                     t          |          t          |                    }t          |                              |           )NrD   )r   r   AssertionErrorwith_traceback)r%   
msg_formatr9   r;   msgs        r   !_fail_test_with_unexpected_errorsrK   z   sR     

$Z00%k22  4 4C
 


,
,R
0
00r   c                    t          | t                    rSt          |t                    r>| j        |j        urt          d          | j        |j        k    rt          d          |t
          j                            dd          dk    rx| vt          j	        | j
                  d         }t
          j                            |j                  }|dk    rn,|                    d          rt          | j
        d| d            |d	u rt           }n|sd
}| |t          d          | t          |j
        dd |           d S |t          | j
        d| d            d S t#          | |          st          | j
        d| |           d S t          | |          rt          ||          st          | j
        d| |           d S d S )Nz?Both numpy and cupy were skipped but with different exceptions.z;Both numpy and cupy were skipped but with different causes.CUPY_CIr   ztest_helper.pytest_z.Error was raised from test code.

{cupy_error}T z9Both cupy and numpy are expected to raise errors, but notz&Only numpy raises error

{numpy_error}z$Only cupy raises error

{cupy_error}zKDifferent types of errors occurred

cupy
{cupy_error}

numpy
{numpy_error}
zMBoth cupy and numpy raise exceptions

cupy
{cupy_error}

numpy
{numpy_error}
)r(   r	   	__class__rG   r   osenvirongetr   
extract_tbr   pathbasenamefilename
startswithrK   r   rE   )r9   r;   accept_errorframerX   s        r   _check_cupy_numpy_errorr\      s\    	:}-- 	;66	{'<<<    ?k... MO O O 
z~~i$$**z/E$Z%=>>rB7##EN33'''  )) 	"-(BD" " " t  k1GI I 	I		)%6+	 	 	 	 	 
	)$4	 	 	 	 	
 0
KHH %)$ 
	% 
	% 
	% 
	% 
	% \22 %[,77%)$ 
	% 
	% 
	% 
	% 
	%% %r   c                     t          j        t          j        |           j                                                  j        S r   )r4   dtypecharlowertyper^   s    r   _signed_counterpartrc      s.    ;u{5)).446677<<r   c                    d |                                 D             }|D ]}t          ||                   ||<   t          | |||||          \  }}	|	J t          |t          t
          f          s|f}d |D             S )Nc                 *    g | ]\  }}|t           v |S rP   )_unsigned_dtypes)r?   kvs      r   
<listcomp>z(_make_positive_masks.<locals>.<listcomp>   s'    	<	<	<1a+;&;&;!&;&;&;r   c                 >    g | ]}t          j        |          d k    S )r   )r.   asnumpy)r?   rs     r   ri   z(_make_positive_masks.<locals>.<listcomp>   s%    111QDLOOq 111r   )itemsrc   r2   r(   tuplelist)
r   r   r    r/   r0   r1   ksrg   r"   r#   s
             r   _make_positive_masksrq      s     
=	<

	<	<	<B + +#BqE**1#dBgz3 3MFE===fudm,, 11&1111r   c                     d t          fd|                                 D                       t          fdt          D                       o't          fdt          t
          z   D                       S )Nc                     t          | t          j                  rdS t          | t                    rdS t          | t                    rt          | t          j                  rdS dS )NTF)r(   r4   r^   r)   ra   
issubclassnumber)rh   s    r   isdtypez._contains_signed_and_unsigned.<locals>.isdtype   sa    a%% 	43 	44   	Z5<%@%@ 	45r   c              3   2   K   | ]} |          |V  d S r   rP   )r?   rh   rv   s     r   rA   z0_contains_signed_and_unsigned.<locals>.<genexpr>   s0      221wwqzz2Q222222r   c              3       K   | ]}|v V  	d S r   rP   r?   dvss     r   rA   z0_contains_signed_and_unsigned.<locals>.<genexpr>   s'      111qBw111111r   c              3       K   | ]}|v V  	d S r   rP   ry   s     r   rA   z0_contains_signed_and_unsigned.<locals>.<genexpr>   s'      <<AG<<<<<<r   )setvaluesanyrf   _float_dtypes_signed_dtypes)r    rv   r{   s    @@r   _contains_signed_and_unsignedr      s       
2222		222	2	2B1111 011111 =<<<<]^;<<<<<=r   c                       fd}|S )Nc                      t          j                  |           } t          j        t          j        fi d D                       | _        | S )Nc                     i | ]}|d S r   rP   )r?   r/   s     r   
<dictcomp>z5_wraps_partial.<locals>.decorator.<locals>.<dictcomp>   s    )G)G)G$)G)G)Gr   )	functoolswrapsinspect	signaturepartial__signature__)r   nameswrappeds    r   	decoratorz!_wraps_partial.<locals>.decorator   s]    'yw''--$.gHH)G)G)G)G)GHHJ Jr   rP   )r   r   r   s   `` r   _wraps_partialr      s*         
 r   c                 >    |||g}d |D             }t          | g|R  S )Nc                     g | ]}||S r   rP   )r?   ns     r   ri   z%_wraps_partial_xp.<locals>.<listcomp>   s    ///1Qr   r   )r   r/   r0   r1   r   s        r   _wraps_partial_xpr      s7    7J'E/////E'*E****r   c                      t          t                    sJ t          t                    sJ t          t                    sJ  fd}|S )Nc           
      T     t                      	f	d            }|S )Nc                    	 t          | |          \  }}}}||J ||J |s|rt          ||           d S t          |t          t          f          s|f}t          |t          t          f          s|f}t          |          t          |          k    sJ fdt          ||          D             }t          j        	                    t          j
                  }rK|dk     rE|D ]B\  }}	|j        |	j        k    r-t          d                    |j        |	j                            Crt          ||          D ]\  }}	t          |	t          j                  r|	j        j        rC|j        j        s7t          d                    |j        j        |	j        j                            |	j        j        rC|j        j        s7t          d                    |j        j        |	j        j                            |D ]\  }}	|j        |	j        k    sJ d gt          |          z  }
t'          |          rKd |D             }t)          |          r0t+          | |          }
t-          |          D ]\  }}|sd |
|<   t          ||
          D ]`\  \  }}	}d}|F|j        d	k    r|d
k                                    }n"||                                         }|	|         }	|s ||	           ad S )NrZ   c                 :    g | ]\  }}t          ||          S rP   )_convert_output_to_ndarray)r?   cupy_rnumpy_rcheck_sparse_formatr0   s      r   ri   zI_make_decorator.<locals>.decorator.<locals>.test_func.<locals>.<listcomp>(  sK     *G *G *G $FG +GW.AC C*G *G *Gr   z2.0.0z=ndarrays of different dtypes are returned.
cupy: {}
numpy: {}zIThe state of c_contiguous flag is false. (cupy_result:{} numpy_result:{})zIThe state of f_contiguous flag is false. (cupy_result:{} numpy_result:{})c                 *    g | ]}|j         t          v S rP   )r^   rf   )r?   r   s     r   ri   zI_make_decorator.<locals>.decorator.<locals>.test_func.<locals>.<listcomp>P  s0     / / / L$44/ / /r   FrP   r   )r<   r\   r(   rn   ro   lenzipr4   libNumpyVersion__version__r^   rG   r   ndarrayflagsc_contiguousf_contiguousshaper   r   rq   	enumeraterB   rT   )r   r    r8   r9   r:   r;   cupy_numpy_result_ndarraysnumpy_versionr   r   masks
needs_maskiflagmaskskiprZ   
check_funcr   contiguous_checkr   r/   r1   r0   
type_checks                   r   	test_funcz5_make_decorator.<locals>.decorator.<locals>.test_func  s    *dBgzC C+Zk *j.D.DD+{/F/FF  [ '
(35AC C C C  kE4=99 +)llUDM:: -+}{##s<'8'88888*G *G *G *G *G (+;'E'E*G *G *G& "I2253DEEM 2mg55'A 2 2OFG|w}44,VFL'-002 2 2 5   A'*;'E'E A AOFG!'5=99 A#M6 A(.(AA"0!CCI6$*L$=$+M$>D@ D@#A #A A
 $M6 A(.(AA"0!CCI6$*L$=$+M$>D@ D@#A #A A $> 5 5|w}44444FS---E,R00 	,/ /"-/ / /
 z?? ,0dBgzC CE#,Z#8#8 , ,4# ,'+E!H ,/.,7 ,7 0 0'!4 #|r)) $	00!'!1!1!3!3")$- 0Jvw///#0 0r   r   )
r   r   rZ   r   r   r   r/   r1   r0   r   s
   ` r   r   z"_make_decorator.<locals>.decorator  st    	4w
	;	;_	0 _	0 _	0 _	0 _	0 _	0 _	0 _	0 _	0 _	0 _	0 _	0 
<	;_	0@ r   )r(   r)   )	r   r/   r   r   rZ   r0   r1   r   r   s	   ```````` r   _make_decoratorr     s     dC     ?j#66??6J!<!<<b b b b b b b b b b b bF r   c                    |t           j        j                            |           r\ddl}|j                            |          sJ |r| j        |j        k    sJ |                                 |                                fS t          | t          j	                  r*t          |t          j	        t          j        f          r| |fS t          | t          j                  r:t          |t          j                  r | j        |j        k    sJ | j        |j        fS t          | t          j                  rt          |t          j                  r| |fS t          j        |           r<t          j        |          r(t          j        |           t          j        |          fS t#          d                    t%          |           t%          |                              )a  Checks type of cupy/numpy results and returns cupy/numpy ndarrays.

    Args:
        c_out (cupy.ndarray, cupyx.scipy.sparse matrix, cupy.poly1d or scalar):
            cupy result
        n_out (numpy.ndarray, scipy.sparse matrix, numpy.poly1d or scalar):
            numpy result
        sp_name(str or None): Argument name whose value is either
            ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
            argument is given for the modules.
        check_sparse_format (bool): If ``True``, consistency of format of
            sparse matrix is also checked. Default is ``True``.

    Returns:
        The tuple of cupy.ndarray and numpy.ndarray.
    Nr   zInumpy and cupy returns different type of return value:
cupy: {}
numpy: {})r+   r,   r-   issparser5   r   toarrayr(   r.   r   r4   genericpoly1dvariablecoeffsisscalararrayrG   ra   )c_outn_outr0   r   r,   s        r   r   r   q  s   " u{1::5AA|$$U+++++ 	0<5<////}}//5$,'' 55=%-"@AA e|%%% **UEL*I*I *~////|U\))%'' Juem,L,L e|~e 5!6!6 5z%  %+e"4"444
	$fKKe& &' ' 'r   c                 8    d } ||             ||           d S )Nc                     t          | t                    r[|                                 D ]H}t          |          t          u rt          |          t          u r|dk    r6d}t          |          d S d S )NdefaultzuKeys of the tolerance dictionary need to be type objects as `numpy.float32` and `cupy.float32` or `'default'` string.)r(   dictkeysra   r)   	TypeError)tolrg   rJ   s      r   _checkz%_check_tolerance_keys.<locals>._check  s    c4   		%XXZZ % %77d??77c>>a9nn/  nn$		% 		%% %r   rP   )rtolatolr   s      r   _check_tolerance_keysr     s1    
% 
% 
% F4LLL
F4LLLLLr   c                 N    d }|j         } |||          } |||          }||fS )Nc                     t          |t                    r\|                    | j                  }|>|                    d          }|'t	          d                    | j                            |S |S )Nr   zCan not find tolerance for {})r(   r   rT   ra   r   r   )r^   r   tol1s      r   _resolvez$_resolve_tolerance.<locals>._resolve  st    c4   		775:&&D|wwy))<#7>>uzJJL L LKJr   rb   )r   r"   r   r   r   r^   rtol1atol1s           r   _resolve_tolerancer     sF    
 
 
 LEHUD!!EHUD!!E%<r   Hz>r   xp)_check_sparse_formatc
          
           t                      s9t           t                    st          t                    rt          d           fd}t	          |||	||||
          S )a	  Decorator that checks NumPy results and CuPy ones are close.

    Args:
         rtol(float or dict): Relative tolerance. Besides a float value, a
             dictionary that maps a dtypes to a float value can be supplied to
             adjust tolerance per dtype. If the dictionary has ``'default'``
             string as its key, its value is used as the default tolerance in
             case any dtype keys do not match.
         atol(float or dict): Absolute tolerance. Besides a float value, a
             dictionary can be supplied as ``rtol``.
         err_msg(str): The error message to be printed in case of failure.
         verbose(bool): If ``True``, the conflicting values are
             appended to the error message.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.
         contiguous_check(bool): If ``True``, consistency of contiguity is
             also checked.

    Decorated test fixture is required to return the arrays whose values are
    close between ``numpy`` case and ``cupy`` case.
    For example, this test case checks ``numpy.zeros`` and ``cupy.zeros``
    should return same value.

    >>> import unittest
    >>> from cupy import testing
    >>> class TestFoo(unittest.TestCase):
    ...
    ...     @testing.numpy_cupy_allclose()
    ...     def test_foo(self, xp):
    ...         # ...
    ...         # Prepare data with xp
    ...         # ...
    ...
    ...         xp_result = xp.zeros(10)
    ...         return xp_result

    .. seealso:: :func:`cupy.testing.assert_allclose`
    zJWhen `type_check` is `False`, `rtol` and `atol` must be supplied as float.c                 d    t          |           \  }}t          j        | |||           d S r   )r   r   assert_allclose)	cr   r   r   r   err_msgr   r   verboses	       r   r   z'numpy_cupy_allclose.<locals>.check_func  s;    )*atDDuq!UE7GDDDDDr   )r   r(   r   r   r   )r   r   r   r   r/   r   rZ   r0   r1   r   r   r   s   ```` `      r   numpy_cupy_allcloser     s    n $%%%
  :dD!! 	:Zd%;%; 	: 9 : : :E E E E E E E E E :tZ9I'*/1 1 1r      c           	      @      fd}t          |||d|||          S )a  Decorator that checks NumPy results and CuPy ones are almost equal.

    Args:
         decimal(int): Desired precision.
         err_msg(str): The error message to be printed in case of failure.
         verbose(bool): If ``True``, the conflicting values
             are appended to the error message.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the same arrays
    in the sense of :func:`cupy.testing.assert_array_almost_equal`
    (except the type of array module) even if ``xp`` is ``numpy`` or ``cupy``.

    .. seealso:: :func:`cupy.testing.assert_array_almost_equal`
    c                 8    t          j        | |           d S r   )r   assert_array_almost_equal)xydecimalr   r   s     r   r   z1numpy_cupy_array_almost_equal.<locals>.check_func*  s"    (AwIIIIIr   Fr   )	r   r   r   r/   r   rZ   r0   r1   r   s	   ```      r   numpy_cupy_array_almost_equalr   	  sQ    BJ J J J J J J:tZ'*> > >r      c           	      :      fd}t          |||d||d          S )a  Decorator that checks results of NumPy and CuPy are equal w.r.t. spacing.

    Args:
         nulp(int): The maximum number of unit in the last place for tolerance.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True``, all error types are acceptable.
             If it is ``False``, no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the same arrays
    in the sense of :func:`cupy.testing.assert_array_almost_equal_nulp`
    (except the type of array module) even if ``xp`` is ``numpy`` or ``cupy``.

    .. seealso:: :func:`cupy.testing.assert_array_almost_equal_nulp`
    c                 4    t          j        | |           d S r   )r   assert_array_almost_equal_nulp)r   r   nulps     r   r   z6numpy_cupy_array_almost_equal_nulp.<locals>.check_funcM  s    -aD99999r   FN)r1   r   )r   r/   r   rZ   r0   r1   r   s   `      r   "numpy_cupy_array_almost_equal_nulpr   0  sF    :: : : : ::tZ'TC C C Cr   c           	      <      fd}t          |||d|||          S )a	  Decorator that checks results of NumPy and CuPy ones are equal w.r.t. ulp.

    Args:
         maxulp(int): The maximum number of units in the last place
             that elements of resulting two arrays can differ.
         dtype(numpy.dtype): Data-type to convert the resulting
             two array to if given.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the same arrays
    in the sense of :func:`assert_array_max_ulp`
    (except the type of array module) even if ``xp`` is ``numpy`` or ``cupy``.

    .. seealso:: :func:`cupy.testing.assert_array_max_ulp`

    c                 6    t          j        | |           d S r   )r   assert_array_max_ulp)r   r   r^   maxulps     r   r   z,numpy_cupy_array_max_ulp.<locals>.check_funct  s     #Aq&%88888r   Fr   )r   r^   r/   r   rZ   r0   r1   r   s   ``      r   numpy_cupy_array_max_ulpr   S  sD    B9 9 9 9 9 9:tZ'*> > >r   c           	      @      fd}t          |||d|||          S )a*  Decorator that checks NumPy results and CuPy ones are equal.

    Args:
         err_msg(str): The error message to be printed in case of failure.
         verbose(bool): If ``True``, the conflicting values are
             appended to the error message.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.
         strides_check(bool): If ``True``, consistency of strides is also
             checked.

    Decorated test fixture is required to return the same arrays
    in the sense of :func:`numpy_cupy_array_equal`
    (except the type of array module) even if ``xp`` is ``numpy`` or ``cupy``.

    .. seealso:: :func:`cupy.testing.assert_array_equal`
    c                 8    t          j        | |           d S r   r   assert_array_equal)r   r   r   strides_checkr   s     r   r   z*numpy_cupy_array_equal.<locals>.check_func  s"    !!Q-HHHHHr   Fr   )	r   r   r/   r   rZ   r0   r1   r   r   s	   ``     ` r   numpy_cupy_array_equalr   z  sQ    BI I I I I I I:tZ'*> > >r   c           	      p     t          j        dt                      fd}t          ||ddd||          S )a  Decorator that checks the resulting lists of NumPy and CuPy's one are equal.

    Args:
         err_msg(str): The error message to be printed in case of failure.
         verbose(bool): If ``True``, the conflicting values are appended
             to the error message.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the same list of arrays
    (except the type of array module) even if ``xp`` is ``numpy`` or ``cupy``.

    .. seealso:: :func:`cupy.testing.assert_array_list_equal`
    zNnumpy_cupy_array_list_equal is deprecated. Use numpy_cupy_array_equal instead.c                 6    t          j        | |           d S r   r   r   r   r   r   s     r   r   z/numpy_cupy_array_list_equal.<locals>.check_func  s     !!Q99999r   F)warningswarnDeprecationWarningr   )r   r   r/   r0   r1   r   s   ``    r   numpy_cupy_array_list_equalr     sa    , M	/  
: : : : : ::tUE ':7 7 7r   c           	      <      fd}t          |||d|||          S )a  Decorator that checks the CuPy result is less than NumPy result.

    Args:
         err_msg(str): The error message to be printed in case of failure.
         verbose(bool): If ``True``, the conflicting values are
             appended to the error message.
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         type_check(bool): If ``True``, consistency of dtype is also checked.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the smaller array
    when ``xp`` is ``cupy`` than the one when ``xp`` is ``numpy``.

    .. seealso:: :func:`cupy.testing.assert_array_less`
    c                 6    t          j        | |           d S r   )r   assert_array_lessr   s     r   r   z)numpy_cupy_array_less.<locals>.check_func  s      Aw88888r   Fr   )r   r   r/   r   rZ   r0   r1   r   s   ``      r   numpy_cupy_array_lessr    sC    <9 9 9 9 9 9:tZ'*> > >r   c                       fd}|S )a  Decorator that checks NumPy results are equal to CuPy ones.

    Args:
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.

    Decorated test fixture is required to return the same results
    even if ``xp`` is ``numpy`` or ``cupy``.
    c                 J     t                      fd            }|S )Nc                      t          | |
	          \  }}}}|s|rt          ||d           d S ||k    r1dt          |          dt          |          }t          |          d S )NFr   zResults are not equal:
cupy: z
numpy: )r<   r\   r)   rG   )r   r    r8   r9   r:   r;   messager   r/   r1   r0   s          r   r   z6numpy_cupy_equal.<locals>.decorator.<locals>.test_func  s     *dBgzC C+Zk  [ '!&( ( ( ( l*** K    #l"3"3"35 %W---	 +*r   r   )r   r   r/   r1   r0   s   ` r   r   z#numpy_cupy_equal.<locals>.decorator  sM    	4w
	;	;	. 	. 	. 	. 	. 	. 	. 
<	;	.& r   rP   )r/   r0   r1   r   s   ``` r   numpy_cupy_equalr	    s0           , r   c                 R     t          j        dt                      fd}|S )a-  Decorator that checks the NumPy and CuPy throw same errors.

    Args:
         name(str): Argument name whose value is either
             ``numpy`` or ``cupy`` module.
         sp_name(str or None): Argument name whose value is either
             ``scipy.sparse`` or ``cupyx.scipy.sparse`` module. If ``None``, no
             argument is given for the modules.
         scipy_name(str or None): Argument name whose value is either ``scipy``
             or ``cupyx.scipy`` module. If ``None``, no argument is given for
             the modules.
         accept_error(bool, Exception or tuple of Exception): Specify
             acceptable errors. When both NumPy test and CuPy test raises the
             same type of errors, and the type of the errors is specified with
             this argument, the errors are ignored and not raised.
             If it is ``True`` all error types are acceptable.
             If it is ``False`` no error is acceptable.

    Decorated test fixture is required throw same errors
    even if ``xp`` is ``numpy`` or ``cupy``.
    z-cupy.testing.numpy_cupy_raises is deprecated.c                 L     t                      fd            }|S )Nc                  ^    t          | |
	          \  }}}}t          ||           d S )Nr   )r<   r\   )r   r    r8   r9   r:   r;   rZ   r   r/   r1   r0   s         r   r   z7numpy_cupy_raises.<locals>.decorator.<locals>.test_func+  s[     *dBgzC C+Zk $J$/1=? ? ? ? ? ?r   r   )r   r   rZ   r/   r1   r0   s   ` r   r   z$numpy_cupy_raises.<locals>.decorator*  sR    	4w
	;	;
	? 
	? 
	? 
	? 
	? 
	? 
	? 
	? 
<	;
	? r   )r   r   r   )r/   r0   r1   rZ   r   s   ```` r   numpy_cupy_raisesr    sR    . M7          r   r^   c                       fd}|S )a  Decorator for parameterized dtype test.

    Args:
         dtypes(list of dtypes): dtypes to be tested.
         name(str): Argument name to which specified dtypes are passed.

    This decorator adds a keyword argument specified by ``name``
    to the test fixture. Then, it runs the fixtures in parallel
    by passing the each element of ``dtypes`` to the named
    argument.
    c                 D     t                      fd            }|S )Nc            	         D ]}}	 t          j        |          j        |<    | i | (# t          $ r.}t	          d                    ||                     Y d }~[d }~wt          $ r t	          d|            w xY wd S )Nzskipped: {} = {} ({})is)r4   r^   ra   r	   printr   r   )r   r    r^   r$   dtypesr   r/   s       r   r   z0for_dtypes.<locals>.decorator.<locals>.test_funcH  s      ${5116BtHD$%"%%%%$ J J J188uaHHIIIIIIII    $e,,, s   $,
A?$A A?r   )r   r   r  r/   s   ` r   r   zfor_dtypes.<locals>.decoratorG  sD    	d	#	#		 		 		 		 		 		 
$	#		 r   rP   )r  r/   r   s   `` r   
for_dtypesr  ;  s*          r   c              #   H   K   | ]}t          j        |          j        V  d S r   r4   r^   ra   r?   r   s     r   rA   rA   [  s-      <<qu{1~~*<<<<<<r   bhilqc              #   H   K   | ]}t          j        |          j        V  d S r   r  r  s     r   rA   rA   \  s-      >>Q,>>>>>>r   BHILQc                 n    | rt           }nt          }|r|t          z  }n
|t          z  }|s
|t          z  }|S r   )_regular_float_dtypesr   _int_dtypes_int_bool_dtypes_complex_dtypes)
no_float16no_bool
no_complexr  s       r   _make_all_dtypesr#  c  sL     & #+"" "/!Mr   c                 B    t          t          |||          |           S )a  Decorator that checks the fixture with all dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.
         no_float16(bool): If ``True``, ``numpy.float16`` is
             omitted from candidate dtypes.
         no_bool(bool): If ``True``, ``numpy.bool_`` is
             omitted from candidate dtypes.
         no_complex(bool): If ``True``, ``numpy.complex64`` and
             ``numpy.complex128`` are omitted from candidate dtypes.

    dtypes to be tested: ``numpy.complex64`` (optional),
    ``numpy.complex128`` (optional),
    ``numpy.float16`` (optional), ``numpy.float32``,
    ``numpy.float64``, ``numpy.dtype('b')``, ``numpy.dtype('h')``,
    ``numpy.dtype('i')``, ``numpy.dtype('l')``, ``numpy.dtype('q')``,
    ``numpy.dtype('B')``, ``numpy.dtype('H')``, ``numpy.dtype('I')``,
    ``numpy.dtype('L')``, ``numpy.dtype('Q')``, and ``numpy.bool_`` (optional).

    The usage is as follows.
    This test fixture checks if ``cPickle`` successfully reconstructs
    :class:`cupy.ndarray` for various dtypes.
    ``dtype`` is an argument inserted by the decorator.

    >>> import unittest
    >>> from cupy import testing
    >>> class TestNpz(unittest.TestCase):
    ...
    ...     @testing.for_all_dtypes()
    ...     def test_pickle(self, dtype):
    ...         a = testing.shaped_arange((2, 3, 4), dtype=dtype)
    ...         s = pickle.dumps(a)
    ...         b = pickle.loads(s)
    ...         testing.assert_array_equal(a, b)

    Typically, we use this decorator in combination with
    decorators that check consistency between NumPy and CuPy like
    :func:`cupy.testing.numpy_cupy_allclose`.
    The following is such an example.

    >>> import unittest
    >>> from cupy import testing
    >>> class TestMean(unittest.TestCase):
    ...
    ...     @testing.for_all_dtypes()
    ...     @testing.numpy_cupy_allclose()
    ...     def test_mean_all(self, xp, dtype):
    ...         a = testing.shaped_arange((2, 3), xp, dtype)
    ...         return a.mean()

    .. seealso:: :func:`cupy.testing.for_dtypes`
    r/   )r  r#  )r/   r   r!  r"  s       r   for_all_dtypesr&  t  s.    l &z7JGG! ! ! !r   c                 ^    |rt          t          |           S t          t          |           S )a  Decorator that checks the fixture with float dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.
         no_float16(bool): If ``True``, ``numpy.float16`` is
             omitted from candidate dtypes.

    dtypes to be tested are ``numpy.float16`` (optional), ``numpy.float32``,
    and ``numpy.float64``.

    .. seealso:: :func:`cupy.testing.for_dtypes`,
        :func:`cupy.testing.for_all_dtypes`
    r%  )r  r  r   )r/   r   s     r   for_float_dtypesr(    s3      4/d;;;;-d3333r   c                 .    t          t          |           S )a  Decorator that checks the fixture with signed dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.

    dtypes to be tested are ``numpy.dtype('b')``, ``numpy.dtype('h')``,
    ``numpy.dtype('i')``, ``numpy.dtype('l')``, and ``numpy.dtype('q')``.

    .. seealso:: :func:`cupy.testing.for_dtypes`,
        :func:`cupy.testing.for_all_dtypes`
    r%  )r  r   r%  s    r   for_signed_dtypesr*    s     n40000r   c                 .    t          t          |           S )a  Decorator that checks the fixture with unsigned dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.

    dtypes to be tested are ``numpy.dtype('B')``, ``numpy.dtype('H')``,

     ``numpy.dtype('I')``, ``numpy.dtype('L')``, and ``numpy.dtype('Q')``.

    .. seealso:: :func:`cupy.testing.for_dtypes`,
        :func:`cupy.testing.for_all_dtypes`
    r%  )r  rf   r%  s    r   for_unsigned_dtypesr,    s     &T2222r   c                 ^    |rt          t          |           S t          t          |           S )a  Decorator that checks the fixture with integer and optionally bool dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.
         no_bool(bool): If ``True``, ``numpy.bool_`` is
             omitted from candidate dtypes.

    dtypes to be tested are ``numpy.dtype('b')``, ``numpy.dtype('h')``,
    ``numpy.dtype('i')``, ``numpy.dtype('l')``, ``numpy.dtype('q')``,
    ``numpy.dtype('B')``, ``numpy.dtype('H')``, ``numpy.dtype('I')``,
    ``numpy.dtype('L')``, ``numpy.dtype('Q')``, and ``numpy.bool_`` (optional).

    .. seealso:: :func:`cupy.testing.for_dtypes`,
        :func:`cupy.testing.for_all_dtypes`
    r%  )r  r  r  )r/   r!  s     r   for_int_dtypesr.    s3       7+D1111*6666r   c                 .    t          t          |           S )a8  Decorator that checks the fixture with complex dtypes.

    Args:
         name(str): Argument name to which specified dtypes are passed.

    dtypes to be tested are ``numpy.complex64`` and ``numpy.complex128``.

    .. seealso:: :func:`cupy.testing.for_dtypes`,
        :func:`cupy.testing.for_all_dtypes`
    r%  )r  r  r%  s    r   for_complex_dtypesr0    s     oD1111r   rb   c                 :    t                      t                     dk    r\  }t           |          S |1t          t          j                            dd                    dk    }|r!t          j         fdD                       ng }t          t                              D ]8} dd         }t          j        |           |                     |z              9fdt          | D             d t                    D             fd	}|S )
a  Decorator that checks the fixture with a product set of dtypes.

    Args:
         types(list of dtypes): dtypes to be tested.
         names(list of str): Argument names to which dtypes are passed.
         full(bool): If ``True``, then all combinations
             of dtypes will be tested.
             Otherwise, the subset of combinations will be tested
             (see the description below).

    Decorator adds the keyword arguments specified by ``names``
    to the test fixture. Then, it runs the fixtures in parallel
    with passing (possibly a subset of) the product set of dtypes.
    The range of dtypes is specified by ``types``.

    The combination of dtypes to be tested changes depending
    on the option ``full``. If ``full`` is ``True``,
    all combinations of ``types`` are tested.
    Sometimes, such an exhaustive test can be costly.
    So, if ``full`` is ``False``, only a subset of possible combinations
    is randomly sampled. If ``full`` is ``None``, the behavior is
    determined by an environment variable ``CUPY_TEST_FULL_COMBINATION``.
    If the value is set to ``'1'``, it behaves as if ``full=True``, and
    otherwise ``full=False``.
    r   NCUPY_TEST_FULL_COMBINATION0r   c                     i | ]}|S rP   rP   )r?   r/   typess     r   r   z*for_dtypes_combination.<locals>.<dictcomp>)  s    -L-L-LddE-L-L-Lr   c                 J    g | ]}t          t          |                     S rP   )rn   r   )r?   typsr   s     r   ri   z*for_dtypes_combination.<locals>.<listcomp>2  s+    DDD4uS--..DDDr   c                 ,    g | ]}t          |          S rP   )r   )r?   
assoc_lists     r   ri   z*for_dtypes_combination.<locals>.<listcomp>4  s     KKKJtJ''KKKr   c                 <     t           gR   fd            }|S )Nc                  ~   D ]}|                                 }|                    |           	  | i | 5# t          $ r^}d                    d |                                D                       }t          d                    ||                     Y d }~d }~wt          $ r t          |            w xY wd S )Nz, c              3   H   K   | ]\  }}d                      ||          V  dS )z{} = {}N)r   )r?   r/   r^   s      r   rA   zOfor_dtypes_combination.<locals>.decorator.<locals>.test_func.<locals>.<genexpr>@  sJ       $; $;'D% "((u55$; $; $; $; $; $;r   zskipped: {} ({}))r*   updater	   r   rm   r  r   r   )r   r    r  kw_copyr$   rJ   combinationr   s         r   r   z<for_dtypes_combination.<locals>.decorator.<locals>.test_func7  s    %  ''))v&&&	D$*'****$ = = =)) $; $;+1<<>>$; $; $; ; ;C ,33C;;<<<<<<<<    &MMM s   9
B:ABB:r   )r   r   r?  r   s   ` r   r   z)for_dtypes_combination.<locals>.decorator6  sE    		%u	%	%	%	 	 	 	 	 
&	%	  r   )ro   r   r  intrR   rS   rT   r   productrangerandomshuffleappendr   r}   )	r5  r   fullr/   ts_shuffled_typesr   r?  s	   ``      @r   for_dtypes_combinationrJ    sG   4 KKE
5zzQ%&&&|2:>>">DDEEJ L$,-L-L-L-Le-L-L-LMMs5zz"" 	. 	.A"111XNN>***IIen,----DDDD38DDDKK#k:J:JKKK     & r   dtyesc                 F    t          |||          }t          || |          S )a  Decorator that checks the fixture with a product set of all dtypes.

    Args:
         names(list of str): Argument names to which dtypes are passed.
         no_float16(bool): If ``True``, ``numpy.float16`` is
             omitted from candidate dtypes.
         no_bool(bool): If ``True``, ``numpy.bool_`` is
             omitted from candidate dtypes.
         full(bool): If ``True``, then all combinations of dtypes
             will be tested.
             Otherwise, the subset of combinations will be tested
             (see description in :func:`cupy.testing.for_dtypes_combination`).
         no_complex(bool): If, True, ``numpy.complex64`` and
             ``numpy.complex128`` are omitted from candidate dtypes.

    .. seealso:: :func:`cupy.testing.for_dtypes_combination`
    )r#  rJ  )r   r   r!  rF  r"  r5  s         r   for_all_dtypes_combinationrN  L  s'    ( Z*==E!%555r   c                 0    t          t          | |          S )a  Decorator for parameterized test w.r.t. the product set of signed dtypes.

    Args:
         names(list of str): Argument names to which dtypes are passed.
         full(bool): If ``True``, then all combinations of dtypes
             will be tested.
             Otherwise, the subset of combinations will be tested
             (see description in :func:`cupy.testing.for_dtypes_combination`).

    .. seealso:: :func:`cupy.testing.for_dtypes_combination`
    r   rF  )rJ  r   rP  s     r   for_signed_dtypes_combinationrQ  d  s     ".DIIIIr   c                 0    t          t          | |          S )a  Decorator for parameterized test w.r.t. the product set of unsigned dtypes.

    Args:
         names(list of str): Argument names to which dtypes are passed.
         full(bool): If ``True``, then all combinations of dtypes
             will be tested.
             Otherwise, the subset of combinations will be tested
             (see description in :func:`cupy.testing.for_dtypes_combination`).

    .. seealso:: :func:`cupy.testing.for_dtypes_combination`
    rP  )rJ  rf   rP  s     r   for_unsigned_dtypes_combinationrS  s  s     ""2%dKKKKr   c                 F    |rt           }nt          }t          || |          S )a5  Decorator for parameterized test w.r.t. the product set of int and boolean.

    Args:
         names(list of str): Argument names to which dtypes are passed.
         no_bool(bool): If ``True``, ``numpy.bool_`` is
             omitted from candidate dtypes.
         full(bool): If ``True``, then all combinations of dtypes
             will be tested.
             Otherwise, the subset of combinations will be tested
             (see description in :func:`cupy.testing.for_dtypes_combination`).

    .. seealso:: :func:`cupy.testing.for_dtypes_combination`
    )r  r  rJ  )r   r!  rF  r5  s       r   for_int_dtypes_combinationrU    s*      ! !%555r   orderc                       fd}|S )ao  Decorator to parameterize tests with order.

    Args:
         orders(list of order): orders to be tested.
         name(str): Argument name to which the specified order is passed.

    This decorator adds a keyword argument specified by ``name``
    to the test fixtures. Then, the fixtures run by passing each element of
    ``orders`` to the named argument.

    c                 D     t                      fd            }|S )Nc                  n    D ]0}	 ||<    | i | # t           $ r t          d|            w xY wd S )Nr  )r   r  )r   r    rV  r   r/   orderss      r   r   z0for_orders.<locals>.decorator.<locals>.test_func  sr      $BtHD$%"%%%%    $e,,,	 s   2r   )r   r   r/   rZ  s   ` r   r   zfor_orders.<locals>.decorator  sD    	d	#	#	 	 	 	 	 	 
$	#	 r   rP   )rZ  r/   r   s   `` r   
for_ordersr[    s*          r   c                 &    t          g d|           S )zDecorator that checks the fixture with orders 'C' and 'F'.

    Args:
         name(str): Argument name to which the specified order is passed.

    .. seealso:: :func:`cupy.testing.for_all_dtypes`

    )NCFr   f)r[  r%  s    r   for_CF_ordersr`    s     000$777r   axisc                       fd}|S )a  Decorator for parametrizing tests with possible contiguous axes.

    Args:
        name(str): Argument name to which specified axis are passed.

    .. note::
        1. Adapted from tests/cupy_tests/fft_tests/test_fft.py.
        2. Example: for ``shape = (1, 2, 3)``, the tested axes are
            ``[(2,), (1, 2), (0, 1, 2)]`` for the C order, and
            ``[(0,), (0, 1), (0, 1, 2)]`` for the F order.
    c                 B     t                      fd            }|S )Nc                    t          | j                  }| j        }t          |          D ]}d}|dv r!t          |dz
  |dz
  d          D ]}|f|z   }	n0|dv rt          d|dz             D ]}||fz   }	nt	          d          	 ||	<    | g|R i | l# t
          $ r t          	d|d	|d
| j        d|	  	          w xY wd S )NrP   )r   r]  r   rN   )r_  r^  r   zPlease specify the array order.r  z	, ndim isz
, shape isz
, order is)r   r   rV  rB  
ValueErrorr   r  )
selfr   r    ndimrV  r   ajr   r/   s
           r   r   z9for_contiguous_axes.<locals>.decorator.<locals>.test_func  s:   tz??DJE4[[  J&&"461Q333 % %D1H%j(("1ac]] % %H% %%FGGG BtHD++++++++    $adL*lE; ; ; s   B(C r   )r   r   r/   s   ` r   r   z&for_contiguous_axes.<locals>.decorator  s?    	d	#	#	 	 	 	 	 
$	#	( r   rP   )r/   r   s   ` r   for_contiguous_axesrj    s$        . r   )F)NNT)
r   r   r   Tr   TFNNT)r   r   Tr   TFNN)r   r   TFNN)r   Nr   TFNN)r   Tr   TFNNF)r   Tr   NN)r   Tr   TFNN)r   NN)r^   FFF)r^   F)rb   N)rK  FFNF)rb   FN)rV  )ra  )ar   r   rR   rC  typingr   r   r   unittestr   r4   r.   cupy.exceptionsr   cupy.testingr   r   r+   cupyx.scipy.sparsecupy.testing._pytest_implr   _pytest.outcomesr   r   SkipTestr   r   r	   __annotations__r   r&   r2   r6   r<   AttributeErrorr   
IndexErrorr   re  NotImplementedErrorr   linalgLinAlgErrorrC   rE   rK   r\   rc   rq   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r	  r  r  	complex64
complex128r  float64float32r  float16r   rn   r   rf   r  bool_r  _regular_dtypes_dtypesr#  r&  r(  r*  r,  r.  r0  rJ  rN  rQ  rS  rU  r[  r`  rj  rP   r   r   <module>r     s         				                  % % % % % %       ' ' ' ' ' '      2 2 2 2 2 2 <>> '7+3'5M5s# 5 5 5 5 !%&MN N N  (     $# # # Iz9j+u|') ) )1 1 1 */H% H% H% H%V= = =2 2 2= = =  + + + <@(,j j j jZ)' )' )'X     & @DAFHLF1 15F1 F1 F1 F1 F1R BF8<>B-1$> $> $> $>N FJCG26 C  C  C  CF JN9=(,$> $> $> $>N ;?HL:?$> $> $> $>P GK7 7 7 7B :>GK%)!> !> !> !>H& & & &R  $#,) ) ) )X   : ?E$456 %(88<<G<<<<<5>>g>>>>> //%+/ '*::
*
*  " <A#7! 7! 7! 7!t4 4 4 4(1 1 1 13 3 3 3 7 7 7 7,2 2 2 2D D D DN &0EI*/6 6 6 60J J J JL L L L6 6 6 6*   6	8 	8 	8 	8# # # # # #r   