
\K]c           @` s  d  Z  d d l m Z m Z m Z d d l Z d d l Z d d l Z d d l m	 Z	 m
 Z
 m Z m Z m Z m Z m Z d d l 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 m Z e j e  Z d Z d Z  d
 Z! d Z" d Z# e	 Z$ e
 Z% d j&   Z' x1 e( e'  D]# \ Z) Z* e+ e j, e e* e)  q*Wd   Z- e j.   Z/ d e0 f d     YZ1 d e0 f d     YZ2 i d d 6d d 6Z3 e3 e4 j5 d Z6 y e1   j7   Z8 Wn dG Z8 n Xe8 dH k  rdI dJ dK dL dM dN dO dP dQ dR f
 Z9 n! dS dT dU dV dW dX dY dZ d[ f	 Z9 d   Z: d   Z; d Z< d e0 f d     YZ= d  Z> d! Z? d" Z@ d# ZA d$   ZB d%   ZC d&   ZD e jE d'  ZF e jE d(  ZG e jE d)  ZH e jE d* jI d+ d,   ZJ e jE d-  ZK d. d/ d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 h ZL e jE d:  ZM e jE d;  ZN e jE d<  ZO e jE d=  ZP e jE d>  ZQ e jE d?  ZR e jE d@  ZS e jE dA  ZT dB   ZU dC   ZV dD   ZW dE   ZX dF   ZY d S(\   s(   
This is a direct translation of nvvm.h
i    (   t   print_functiont   absolute_importt   divisionN(   t   c_void_pt   c_intt   POINTERt   c_char_pt   c_size_tt   byreft   c_char(   t   ir(   t   configi   (   t	   NvvmErrort   NvvmSupportError(   t   get_libdevicet   open_libdevicet   open_cudalibi   i   i   s  
NVVM_SUCCESS
NVVM_ERROR_OUT_OF_MEMORY
NVVM_ERROR_PROGRAM_CREATION_FAILURE
NVVM_ERROR_IR_VERSION_MISMATCH
NVVM_ERROR_INVALID_INPUT
NVVM_ERROR_INVALID_PROGRAM
NVVM_ERROR_INVALID_IR
NVVM_ERROR_INVALID_OPTION
NVVM_ERROR_NO_MODULE_IN_PROGRAM
NVVM_ERROR_COMPILATION
c           C` s(   y t    Wn t k
 r t SXt Sd S(   s(   
    Return if libNVVM is available
    N(   t   NVVMR   t   Falset   True(    (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   is_available1   s
    R   c           B` s   e  Z d  Z i	 e e e  e e  f d 6e e e  f d 6e e e  f d 6e e e e e f d 6e e e e e  f d 6e e e e  f d 6e e e f d 6e e e e  f d 6e e e f d	 6Z	 d Z d
   Z d   Z e d  Z RS(   s   Process-wide singleton.
    t   nvvmVersiont   nvvmCreateProgramt   nvvmDestroyProgramt   nvvmAddModuleToProgramt   nvvmCompileProgramt   nvvmGetCompiledResultSizet   nvvmGetCompiledResultt   nvvmGetProgramLogSizet   nvvmGetProgramLogc      	   C` s   t   |  j d  k r t j |   |  _ } y t d d t | _ Wn2 t k
 ry } d  |  _ d } t	 | |   n Xx\ | j
 j   D]H \ } } t | j |  } | d | _ | d | _ t | | |  q Wn  Wd  QX|  j S(   Nt   nvvmt   cccs;   libNVVM cannot be found. Do `conda install cudatoolkit`:
%si    i   (   t
   _nvvm_lockt   _NVVM__INSTANCEt   Nonet   objectt   __new__R   R   t   drivert   OSErrorR   t   _PROTOTYPESt   itemst   getattrt   restypet   argtypest   setattr(   t   clst   instt   et   errmsgt   namet   protot   func(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR$   j   s    	c         C` sP   t    } t    } |  j t |  t |   } |  j | d  | j | j f S(   Ns   Failed to get version.(   R   R   R   t   check_errort   value(   t   selft   majort   minort   err(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   get_version   s
    		c         C` sF   | rB t  | t |  } | r9 t |  t j d  qB |  n  d  S(   Ni   (   R   t   RESULT_CODE_NAMESt   printt   syst   exit(   R6   t   errort   msgR>   t   exc(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR4      s    
N(   t   __name__t
   __module__t   __doc__t   nvvm_resultR   R   t   nvvm_programR   R   R'   R"   R!   R$   R:   R   R4   (    (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR   ?   s   		t   CompilationUnitc           B` s>   e  Z d    Z d   Z d   Z d   Z d   Z d   Z RS(   c         C` sJ   t    |  _ t   |  _ |  j j t |  j   } |  j j | d  d  S(   Ns   Failed to create CU(   R   R%   RF   t   _handleR   R   R4   (   R6   R9   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   __init__   s    c         C` s;   t    } | j t |  j   } | j | d d t d  S(   Ns   Failed to destroy CUR>   (   R   R   R   RH   R4   R   (   R6   R%   R9   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   __del__   s    	c         C` s;   |  j  j |  j | t |  d  } |  j  j | d  d S(   s   
         Add a module level NVVM IR to a compilation unit.
         - The buffer should contain an NVVM module IR either in the bitcode
           representation (LLVM3.0) or in the text representation.
        s   Failed to add moduleN(   R%   R   RH   t   lenR"   R4   (   R6   t   bufferR9   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt
   add_module   s    c         K` s  g  } d | k r4 | j  d  r4 | j d  q4 n  | j d  r` | j d | j  d   n  | j d  r | j d | j  d   n  d } x[ | D]S } | | k r t t | j  |    } | j d | j d d  | f  q q W| r,d j t t | j	     } t
 d j |    n  t t |  g  | D] } t | j d   ^ q@  } |  j j |  j t |  |  }	 |  j |	 d  t   }
 |  j j |  j t |
   }	 |  j |	 d  t |
 j   } |  j j |  j |  }	 |  j |	 d  |  j   |  _ | S(   sF  Perform Compliation

        The valid compiler options are

         *   - -g (enable generation of debugging information)
         *   - -opt=
         *     - 0 (disable optimizations)
         *     - 3 (default, enable optimizations)
         *   - -arch=
         *     - compute_20 (default)
         *     - compute_30
         *     - compute_35
         *   - -ftz=
         *     - 0 (default, preserve denormal values, when performing
         *          single-precision floating-point operations)
         *     - 1 (flush denormal values to zero, when performing
         *          single-precision floating-point operations)
         *   - -prec-sqrt=
         *     - 0 (use a faster approximation for single-precision
         *          floating-point square root)
         *     - 1 (default, use IEEE round-to-nearest mode for
         *          single-precision floating-point square root)
         *   - -prec-div=
         *     - 0 (use a faster approximation for single-precision
         *          floating-point division and reciprocals)
         *     - 1 (default, use IEEE round-to-nearest mode for
         *          single-precision floating-point division and reciprocals)
         *   - -fma=
         *     - 0 (disable FMA contraction)
         *     - 1 (default, enable FMA contraction)
         *
         t   debugs   -gt   opts   -opt=%dt   archs   -arch=%st   ftzt	   prec_sqrtt   prec_divt   fmas   -%s=%dt   _t   -s   , s   unsupported option {0}t   utf8s   Failed to compile
s&   Failed to get size of compiled result.s   Failed to get compiled result.(   RQ   RR   RS   RT   (   t   popt   appendt   gett   intt   boolt   replacet   joint   mapt   reprt   keysR   t   formatR   RK   t   encodeR%   R   RH   t
   _try_errorR   R   R   R	   R5   R   t   get_logt   log(   R6   t   optionst   optst   other_optionst   kt   vt   optstrt   xt   c_optsR9   t   reslent   ptxbuf(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   compile   s>    #   *(!	c         C` s'   |  j  j | d | |  j   f  d  S(   Ns   %s
%s(   R%   R4   Re   (   R6   R9   R@   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyRd      s    c         C` s   t    } |  j j |  j t |   } |  j j | d  | j d k r t | j   } |  j j |  j |  } |  j j | d  | j j	 d  Sd S(   Ns#   Failed to get compilation log size.i   s   Failed to get compilation log.RW   t    (
   R   R%   R   RH   R   R4   R5   R	   R   t   decode(   R6   Ro   R9   t   logbuf(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyRe      s    	(   RB   RC   RI   RJ   RM   Rq   Rd   Re   (    (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyRG      s   			
	T	s   e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64i    s   e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v32:32:32-v64:64:64-v128:128:128-n16:32:64i@   i   i   i   i   c         C` ss   xh t  t  D]Z \ } } | |  k r) | S| |  k r | d k rX t d |  |   qg t | d Sq q Wt d S(   Ni    s@   GPU compute capability %d.%d is not supported (requires >=%d.%d)i   i(   t	   enumeratet   SUPPORTED_CCR   (   t   mycct   it   cc(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt
   _find_arch$  s    c         C` s/   t  j r t  j } n t |  | f  } d | S(   s1   Matches with the closest architecture option
    s   compute_%d%d(   R   t   FORCE_CUDA_CCRz   (   R7   R8   RP   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   get_arch_option7  s    	s   Missing libdevice file for {arch}.
Please ensure you have package cudatoolkit >= 8.
Install package by:

    conda install cudatoolkit
t	   LibDevicec           B` s;   e  Z i  Z d  d d d g Z d   Z d   Z d   Z RS(   t
   compute_20t
   compute_30t
   compute_35t
   compute_50c         C` s~   | |  j  k ra |  j |  } t |  d k rK t t j d |    n  t |  |  j  | <n  | |  _ |  j  | |  _	 d S(   s@   
        arch --- must be result from get_arch_option()
        RP   N(
   t   _cache_t   _get_closest_archR   R"   t   RuntimeErrort   MISSING_LIBDEVICE_FILE_MSGRb   R   RP   t   bc(   R6   RP   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyRI   R  s    	c         C` s:   |  j  d } x& |  j  D] } | | k r | } q q W| S(   Ni    (   t   _known_arch(   R6   RP   t   rest	   potential(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR   _  s
    c         C` s   |  j  S(   N(   R   (   R6   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyRZ   f  s    (   RB   RC   R   R   RI   R   RZ   (    (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR}   I  s   			s   
define internal i32 @___numba_cas_hack(i32* %ptr, i32 %cmp, i32 %val) alwaysinline {
    %out = cmpxchg volatile i32* %ptr, i32 %cmp, i32 %val monotonic
    ret i32 %out
}
se  
define internal double @___numba_atomic_double_add(double* %ptr, double %val) alwaysinline {
entry:
    %iptr = bitcast double* %ptr to i64*
    %old2 = load volatile i64, i64* %iptr
    br label %attempt

attempt:
    %old = phi i64 [ %old2, %entry ], [ %cas, %attempt ]
    %dold = bitcast i64 %old to double
    %dnew = fadd double %dold, %val
    %new = bitcast double %dnew to i64
    %cas = cmpxchg volatile i64* %iptr, i64 %old, i64 %new monotonic
    %repeat = icmp ne i64 %cas, %old
    br i1 %repeat, label %attempt, label %done

done:
    %result = bitcast i64 %old to double
    ret double %result
}
s  
define internal {T} @___numba_atomic_{T}_max({T}* %ptr, {T} %val) alwaysinline {{
entry:
    %ptrval = load volatile {T}, {T}* %ptr
    ; Check if val is a NaN and return *ptr early if so
    %valnan = fcmp uno {T} %val, %val
    br i1 %valnan, label %done, label %lt_check

lt_check:
    %dold = phi {T} [ %ptrval, %entry ], [ %dcas, %attempt ]
    ; Continue attempts if dold < val or dold is NaN (using ult semantics)
    %lt = fcmp ult {T} %dold, %val
    br i1 %lt, label %attempt, label %done

attempt:
    ; Attempt to swap in the larger value
    %iold = bitcast {T} %dold to {Ti}
    %iptr = bitcast {T}* %ptr to {Ti}*
    %ival = bitcast {T} %val to {Ti}
    %cas = cmpxchg volatile {Ti}* %iptr, {Ti} %iold, {Ti} %ival monotonic
    %dcas = bitcast {Ti} %cas to {T}
    br label %lt_check

done:
    ; Return max
    %ret = phi {T} [ %ptrval, %entry ], [ %dold, %lt_check ]
    ret {T} %ret
}}
s  
define internal {T} @___numba_atomic_{T}_min({T}* %ptr, {T} %val) alwaysinline{{
entry:
    %ptrval = load volatile {T}, {T}* %ptr
    ; Check if val is a NaN and return *ptr early if so
    %valnan = fcmp uno {T} %val, %val
    br i1 %valnan, label %done, label %gt_check

gt_check:
    %dold = phi {T} [ %ptrval, %entry ], [ %dcas, %attempt ]
    ; Continue attempts if dold > val or dold is NaN (using ugt semantics)
    %lt = fcmp ugt {T} %dold, %val
    br i1 %lt, label %attempt, label %done

attempt:
    ; Attempt to swap in the smaller value
    %iold = bitcast {T} %dold to {Ti}
    %iptr = bitcast {T}* %ptr to {Ti}*
    %ival = bitcast {T} %val to {Ti}
    %cas = cmpxchg volatile {Ti}* %iptr, {Ti} %iold, {Ti} %ival monotonic
    %dcas = bitcast {Ti} %cas to {T}
    br label %gt_check

done:
    ; Return min
    %ret = phi {T} [ %ptrval, %entry ], [ %dold, %gt_check ]
    ret {T} %ret
}}
c         C` sb   |  j    } xF t |  D]8 \ } } | j d  r d } | j t  | | <Pq q Wd j |  S(   s@   
    Find the line containing the datalayout and replace it
    s   target datalayouts   target datalayout = "{0}"s   
(   t
   splitlinesRu   t
   startswithRb   t   default_data_layoutR^   (   t   llvmirt   linesRx   t   lnt   tmp(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   _replace_datalayout  s    c         K` s+  t    } t d | j d d   } t |   }  d t f d t f d t j d d d d	  f d
 t j d d d d  f d t j d d d d	  f d t j d d d d  f g } x& | D] \ } } |  j	 | |  }  q Wt
 |   }  | j |  j d   | j | j    | j |   } t |  S(   NRP   R~   s.   declare i32 @___numba_cas_hack(i32*, i32, i32)s;   declare double @___numba_atomic_double_add(double*, double)s7   declare float @___numba_atomic_float_max(float*, float)t   Tt   floatt   Tit   i32s;   declare double @___numba_atomic_double_max(double*, double)t   doublet   i64s7   declare float @___numba_atomic_float_min(float*, float)s;   declare double @___numba_atomic_double_min(double*, double)RW   (   RG   R}   RZ   R   t   ir_numba_cas_hackt   ir_numba_atomic_double_addt   ir_numba_atomic_maxRb   t   ir_numba_atomic_minR]   t   llvm39_to_34_irRM   Rc   Rq   t   patch_ptx_debug_pubnames(   R   Rh   t   cut	   libdevicet   replacementst   declt   fnt   ptx(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   llvm_to_ptx  s,    	c         C` ss   xl t  rn |  j d  } | d k  r( Pn  |  j d |  } | d k  rU t d   n  |  |  |  | d }  q W|  S(   s   
    Patch PTX to workaround .debug_pubnames NVVM error::

        ptxas fatal   : Internal error: overlapping non-identical data

    s   .section .debug_pubnamesi    t   }s   missing "}"i   (   R   t   findt
   ValueError(   R   t   startt   stop(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR     s    	s	   \!\d+\s*=s   metadata\s*\![{'\"0-9]s   \!\d+s,   \!{i32 \d, \!\"Debug Info Version\", i32 \d}t    s   \s+s"   ^attributes #\d+ = \{ ([\w\s]+)\ }t   alwaysinlinet   coldt
   inlinehintt   minsizet   noduplicatet   noinlinet   noreturnt   nounwindt   optnonet   optiszet   readnonet   readonlys"   \bgetelementptr\s(?:inbounds )?\(?s   =\s*\bload\s(?:\bvolatile\s)?s   (call\s[^@]+\))(\s@)s   \s*!range\s+!\d+s
   [,{}()[\]]s   \bnonnull\bs"   \b(local_unnamed_addr|writeonly)\bs   \((.*)\)c         C` s8  d   } g  } x|  j    D]} | j d  rF | j d d  } n  | j   j d  r| d | k r| | j d d  } n  t j |  r d t j |  k r | j d d  } | j d	 d
  } | j	 d  } | | d  | | d } } d   } d j
 | t j | |  f  } q n  | j d  r5q n  t j |  d k	 rbt j d   |  } n  | j d  rt j |  } | j d  j   }	 d j
 d   |	 D  }	 | j | j d  |	  } n  d | k r0t j |  } | d k r	t d | f   n  | j   }
 | |
  | | |
  } n  d | k r{t j |  } | r{| j   }
 | |
  | | |
  } q{n  d | k rt j d |  } t j d |  j d  } d | k rt j t |  } qn  d | k rd | k rt j t |  } qn  t j d |  } | j |  q Wd j
 |  S(   s+   
    Convert LLVM 3.9 IR for LLVM 3.4.
    c         S` s   d } d } x t  r t j |  |  } | d  k rJ t d |  f   Pn  | j   } | j d  } | d k r | d k r Pq q | d k r | d 7} q | d k r | d 8} q q W|  | j   S(   Ni    s   failed parsing leading type: %st   ,s   {[(i   s   )]}(   R   t   re_type_tokt   searchR"   R   t   endt   groupt   lstrip(   t   st	   par_levelt   post   mt   tok(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   parse_out_leading_type&  s"    	s   !numba.llvm.dbg.cus   !llvm.dbg.cus%   tail call void asm sideeffect "// dbgs
   !numba.dbgs   !dbgs   !{s   metadata !{s   !"s   metadata !"t   =i   c         S` s   d |  j  d  S(   Ns	   metadata i    (   R   (   R   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   fix_metadata_refS  s    R   s   source_filename =c         S` s   d S(   NRr   (    (   R   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   <lambda>Y  Rr   s   attributes #c         s` s!   |  ] } | t  k r | Vq d  S(   N(   t   supported_attributes(   t   .0t   a(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pys	   <genexpr>_  s    s   getelementptr s    failed parsing getelementptr: %ss   load s   call s   \1*\2Rr   R   s   @llvm.memsett   declares   
N(   R   R   R]   R   t   re_metadata_deft   matchR"   t   re_metadata_correct_usageR   R   R^   t   re_metadata_reft   subt   re_unsupported_keywordst   re_attributes_defR   t   splitt   re_getelementptrR   R   t   re_loadt   re_callt   re_ranget   rstript   re_parenthesized_listt   _replace_llvm_memset_usaget    _replace_llvm_memset_declarationt   re_annotationsRY   (   R
   R   t   buft   linet   assigpost   lhst   rhsR   R   t   attrsR   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR   "  sf    		'c         C` sr   t  |  j d  j d   } t j d | d  j d  } | j d d j |   d j |  } d j |  S(	   sN   Replace `llvm.memset` usage for llvm7+.

    Used as functor for `re.sub.
    i   R   s   align (\d+)i    is   i32 {}s   , s   ({})(   t   listR   R   t   reR   t   insertRb   R^   (   R   t   paramst   alignt   out(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR     s
    c         C` sJ   t  |  j d  j d   } | j d d  d j |  } d j |  S(   sT   Replace `llvm.memset` declaration for llvm7+.

    Used as functor for `re.sub.
    i   R   iR   s   , s   ({})(   R   R   R   R   R^   Rb   (   R   R   R   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyR     s    c         C` s   d d l  m } m } m } m } |  j } |  | j | d  | j | j   d  f } | j | |  } | j d  } | j	 |  t
 j d  }	 | j |	 d  |	 d  |	 d  |	 d  g  }
 | j d |
  d  S(	   Ni    (   t   MetaDatat   MetaDataStringt   Constantt   Typet   kerneli   s   nvvm.annotationsi    i   s   nvvmir.version(   t   llvmlite.llvmpy.coreR   R   R   R   t   moduleRZ   R[   t   get_or_insert_named_metadatat   addR
   t   IntTypet   add_metadatat   add_named_metadata(   t   lfuncR   R   R   R   R   t   opst   mdt   nmdR   t   md_ver(    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   set_cuda_kernel  s    "	-3c         C` s   t  |  _ d  S(   N(   R   t   data_layout(   R   (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   fix_data_layout  s    (   i    i    (   i   i   (   i   i    (   i   i   (   i   i    (   i   i   (   i   i    (   i   i   (   i   i   (   i   i    (   i   i   (   i   i   (   i   i    (   i   i   (   i   i    (   i   i   (   i   i   (   i   i    (   i   i   (   i   i   (   i   i    (Z   RD   t
   __future__R    R   R   R=   t   loggingR   t   ctypesR   R   R   R   R   R   R	   t	   threadingt   llvmliteR
   t   numbaR   R?   R   R   t   libsR   R   R   t	   getLoggerRB   t   loggert   ADDRSPACE_GENERICt   ADDRSPACE_GLOBALt   ADDRSPACE_SHAREDt   ADDRSPACE_CONSTANTt   ADDRSPACE_LOCALRF   RE   R   R;   Ru   Rx   Rj   R,   t   modulesR   t   LockR    R#   R   RG   R   t   tuplet   __itemsize__R   R:   t   NVVM_VERSIONRv   Rz   R|   R   R}   R   R   R   R   R   R   R   Rq   R   R   R   R]   t   re_metadata_debuginfoR   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s6   lib/python2.7/site-packages/numba/cuda/cudadrv/nvvm.pyt   <module>   s   $4	Q|

'!		&		"		j			