ó
~9­\c           @  st  d  d l  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 e d ƒ Z e r¹ e d ƒ j Z e d	 ƒ j Z e j ƒ  e j ƒ  e j ƒ  n  i d g d
 6Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ g  a e ƒ  a d a d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z  e d d ƒ d d „ ƒ Z" d S(   iÿÿÿÿ(   t   print_functiont   divisionN(   t   import_module(   t   Printer(   t   St   IndexedBase(   t   doctest_depends_ont   llvmlites   llvmlite.irs   llvmlite.bindingt   llvm_callablet   LLVMJitPrinterc           B  sh   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z RS(   s   Convert expressions to LLVM IRc         O  sƒ   | j  d i  ƒ |  _ t s* t d ƒ ‚ n  t t |  ƒ j | | Ž  t j ƒ  |  _	 | |  _
 | |  _ | |  _ i  |  _ i  |  _ d  S(   Nt   func_arg_maps'   llvmlite is required for LLVMJITPrinter(   t   popR
   R   t   ImportErrort   superR	   t   __init__t   llt
   DoubleTypet   fp_typet   modulet   buildert   fnt   ext_fnt   tmp_var(   t   selfR   R   R   t   argst   kwargs(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR      s    				c         C  s   | |  j  | <d  S(   N(   R   (   R   t   namet   value(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _add_tmp_var*   s    c         C  s   t  j |  j t | ƒ ƒ S(   N(   R   t   ConstantR   t   float(   R   t   n(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _print_Number-   s    c         C  s   t  j |  j t | j ƒ ƒ S(   N(   R   R   R   R   t   p(   R   t   expr(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _print_Integer0   s    c         C  sJ   |  j  j | ƒ } | s- |  j j | ƒ } n  | sF t d | ƒ ‚ n  | S(   Ns   Symbol not found: %s(   R   t   getR
   t   LookupError(   R   t   st   val(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _print_Symbol3   s    c         C  s}  |  j  | j ƒ } | j t j k rF |  j j t j |  j	 d ƒ | ƒ S| j t j
 k rÌ |  j j d ƒ } | s³ t j |  j	 |  j	 g ƒ } t j |  j | d ƒ } | |  j d <n  |  j j | | g d ƒ S| j d k rî |  j j | | ƒ S|  j  | j ƒ } |  j j d ƒ } | sat j |  j	 |  j	 |  j	 g ƒ } t j |  j | d ƒ } | |  j d <n  |  j j | | | g d ƒ S(   Ng      ð?t   sqrti   t   pow(   t   _printt   baset   expR   t   NegativeOneR   t   fdivR   R   R   t   HalfR   R$   t   FunctionTypet   FunctionR   t   callt   fmul(   R   R"   t   base0R   t   fn_typet   exp0(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt
   _print_Pow<   s&    "!c         C  s]   g  | j  D] } |  j | ƒ ^ q
 } | d } x' | d D] } |  j j | | ƒ } q: W| S(   Ni    i   (   R   R+   R   R4   (   R   R"   t   at   nodest   et   node(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt
   _print_MulR   s
    %
c         C  s]   g  | j  D] } |  j | ƒ ^ q
 } | d } x' | d D] } |  j j | | ƒ } q: W| S(   Ni    i   (   R   R+   R   t   fadd(   R   R"   R9   R:   R;   R<   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt
   _print_AddY   s
    %
c         C  s–   | j  j } |  j | j d ƒ } |  j j | ƒ } | s} t j |  j |  j g ƒ } t j	 |  j
 | | ƒ } | |  j | <n  |  j j | | g | ƒ S(   Ni    (   t   funct   __name__R+   R   R   R$   R   R1   R   R2   R   R   R3   (   R   R"   R   t   e0R   R6   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _print_Functionb   s    c         C  s   t  d t | ƒ ƒ ‚ d  S(   Ns,   Unsupported type for LLVM JIT conversion: %s(   t	   TypeErrort   type(   R   R"   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   emptyPrinterl   s    (   RA   t
   __module__t   __doc__R   R   R    R#   R(   R8   R=   R?   RC   RF   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR	      s   											
t   LLVMJitCallbackPrinterc           B  s#   e  Z d  „  Z d „  Z d „  Z RS(   c         O  s   t  t |  ƒ j | | Ž  d  S(   N(   R   RI   R   (   R   R   R   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR   t   s    c         C  s“   |  j  | j \ } } t | j d j ƒ  ƒ } |  j j | t j t j	 d ƒ | ƒ g ƒ } |  j j
 | t j |  j ƒ ƒ } |  j j | ƒ } | S(   Ni    i    (   R
   R,   t   intt   indicest   evalfR   t   gepR   R   t   IntTypet   bitcastt   PointerTypeR   t   load(   R   R"   t   arrayt   idxt   offsett	   array_ptrt   fp_array_ptrR   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _print_Indexedw   s    -!c         C  sº   |  j  j | ƒ } | r | S|  j j | d  d g ƒ \ } } | sV t d | ƒ ‚ n  |  j j | t j t j	 d ƒ | ƒ g ƒ } |  j j
 | t j |  j ƒ ƒ } |  j j | ƒ } | S(   Ni    s   Symbol not found: %si    (   R   R$   R
   t   NoneR%   R   RM   R   R   RN   RO   RP   R   RQ   (   R   R&   R'   RR   RS   RU   RV   R   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR(      s    !-(   RA   RG   R   RW   R(   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyRI   s   s   		i    t   LLVMJitCodec           B  sY   e  Z d  „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 RS(	   c         C  s^   | |  _  t j ƒ  |  _ t j d ƒ |  _ d  |  _ g  |  _ |  j |  _	 i  |  _
 d |  _ d  S(   Nt   mod1t    (   t	   signatureR   R   R   t   ModuleR   RX   R   t   llvm_arg_typest   llvm_ret_typet
   param_dictt	   link_name(   R   R\   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR   ˜   s    				c         C  s¼   | t  j k r t j d ƒ S| t  j k r2 |  j S| t  j t  j ƒ k rZ t j |  j ƒ S| t  j k r t j t j d ƒ ƒ S| t  j	 k r¤ t j t j d ƒ ƒ St
 d t | ƒ ƒ d  S(   Ni    s   Unhandled ctype = %s(   t   ctypest   c_intR   RN   t   c_doubleR   t   POINTERRP   t   c_void_pt	   py_objectt   printt   str(   R   t   ctype(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _from_ctype¢   s    c         C  sG   |  j  |  j j ƒ |  _ g  |  j j D] } |  j  | ƒ ^ q% |  _ d S(   s#   Create types for function argumentsN(   Rk   R\   t   ret_typeR_   t
   arg_ctypesR^   (   R   t	   func_argsR9   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _create_args°   s    c         C  sp   d } t  d 7a  | t t  ƒ |  _ t j |  j ƒ t j |  j |  j ƒ } t j	 |  j
 | d |  j ƒ|  _ d S(   s,   Create function with name and type signaturet   jit_funci   R   N(   t   current_link_suffixRi   Ra   t
   link_namest   addR   R1   R_   R^   R2   R   R   (   R   t   default_link_nameR6   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _create_function_base¶   s    
c         C  sQ   xJ t  | ƒ D]< \ } } t | ƒ |  j j | _ |  j j | |  j | <q Wd S(   s0   Mapping of symbolic values to function argumentsN(   t	   enumerateRi   R   R   R   R`   (   R   Rn   t   iR9   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _create_param_dictÁ   s    c         C  sƒ   |  j  j d ƒ } t j | ƒ } t |  j | |  j  d |  j ƒ} |  j | | ƒ } | j j	 |  j
 | | ƒ ƒ t |  j ƒ } | S(   s'   Create function body and return LLVM IRt   entryR
   (   R   t   append_basic_blockR   t	   IRBuilderR	   R   R`   t   _convert_exprR   t   rett   _wrap_returnRi   (   R   R"   t   bb_entryR   t   ljR}   t   strmod(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _create_functionÇ   s    c         C  sO  |  j  j t j k r | d St j t j d ƒ ƒ } t j | |  j g ƒ } t j	 | j
 | d ƒ } g  | D] } | j j | | g ƒ ^ ql } t | ƒ d k r¯ | d } nœ t j d ƒ g }	 |	 j | g t | ƒ ƒ t j | |	 ƒ }
 t j	 | j
 |
 d ƒ } t j t j d ƒ t | ƒ ƒ g } | j | ƒ | j j | | ƒ } | S(   Ni    i    t   PyFloat_FromDoublei   t   PyTuple_Pack(   R\   Rl   Rb   Rd   R   RP   RN   R1   R   R2   R   R   R3   t   lent   extendR   (   R   R€   t   valst   void_ptrt	   wrap_typet   wrap_fnt   vt   wrapped_valst	   final_valt   tuple_arg_typest
   tuple_typet   tuple_fnt
   tuple_args(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR~   Õ   s     +$c   	      C  sÜ   y™ t  | ƒ d k r˜ | d } | d } t  | ƒ d k r_ |  j j t j k r_ t d ƒ ‚ n  x6 | D]+ \ } } | j | ƒ } | j | | ƒ qf Wn  Wn t k
 rµ | g } n Xg  | D] } | j | ƒ ^ q½ } | S(   Ni   i    i   s>   Return of multiple expressions not supported for this callback(	   R…   R\   Rl   Rb   Rd   t   NotImplementedErrorR+   R   RD   (	   R   R€   R"   t	   tmp_exprst   final_exprsR   R;   R'   R‡   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR|   ø   s    

'"c         C  sÄ   t  j | ƒ } t  j ƒ  } d | _ t  j ƒ  } | j | ƒ | j | ƒ t  j j ƒ  j	 ƒ  } t  j
 | | ƒ } | j ƒ  t j | ƒ t r® t d ƒ t | j | ƒ ƒ n  | j |  j ƒ } | S(   Ni   t   Assembly(   t   llvmt   parse_assemblyt   create_pass_manager_buildert	   opt_levelt   create_module_pass_managert   populatet   runt   Targett   from_default_triplet   create_target_machinet   create_mcjit_compilert   finalize_objectt   exe_enginest   appendt   FalseRh   t   emit_assemblyt   get_function_addressRa   (   R   R   t   llmodt   pmbt   pass_managert   target_machinet   exe_engt   fptr(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _compile_function
  s    	

(   RA   RG   R   Rk   Ro   Ru   Rx   R‚   R~   R|   R­   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyRY   —   s   	
						#	t   LLVMJitCodeCallbackc           B  s#   e  Z d  „  Z d „  Z d „  Z RS(   c         C  s   t  t |  ƒ j | ƒ d  S(   N(   R   R®   R   (   R   R\   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR   %  s    c         C  sŒ   x… t  | ƒ D]w \ } } t | t ƒ ra |  j j | | f |  j | <t | ƒ |  j j | _ q |  j j |  j j	 | f |  j | <q Wd  S(   N(
   Rv   t
   isinstanceR   R   R   R`   Ri   R   R\   t	   input_arg(   R   Rn   Rw   R9   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyRx   (  s    c         C  s?  |  j  j d ƒ } t j | ƒ } t |  j | |  j  d |  j ƒ} |  j | | ƒ } |  j j	 r| j
 |  j  j |  j j	 t j |  j ƒ ƒ } xZ t | ƒ D]L \ } } t j t j d ƒ | ƒ }	 | j | |	 g ƒ }
 | j | |
 ƒ q› W| j t j t j d ƒ d ƒ ƒ n | j j |  j | | ƒ ƒ t |  j ƒ } | S(   s'   Create function body and return LLVM IRRy   R
   i    i    (   R   Rz   R   R{   RI   R   R`   R|   R\   t   ret_argRO   R   RP   R   Rv   R   RN   RM   t   storeR}   R   R~   Ri   (   R   R"   R   R   R€   R}   t   output_fp_ptrRw   R'   t   indext   output_array_ptrR   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR‚   1  s     %(   RA   RG   R   Rx   R‚   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR®   $  s   			t   CodeSignaturec           B  s   e  Z d  „  Z RS(   c         C  s(   | |  _  g  |  _ d |  _ d  |  _ d  S(   Ni    (   Rl   Rm   R°   RX   R±   (   R   Rl   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR   K  s    			(   RA   RG   R   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR¶   J  s   c         C  sŠ   | d k r t | ƒ } n t | ƒ } | j |  ƒ | j ƒ  | j |  ƒ | j | ƒ } t rw t d ƒ t | ƒ n  | j	 | ƒ } | S(   s5   Create a native code function from a Sympy expressions   LLVM IRN(
   RX   RY   R®   Ro   Ru   Rx   R‚   R¤   Rh   R­   (   R   R"   R\   t   callback_typet   jitR   R¬   (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   _llvm_jit_codeW  s    

t   modulest   scipyc   
      C  sˆ  t  s t d ƒ ‚ n  t t j ƒ } g  } | d k r` x÷ |  D] } t j } | j | ƒ q= WnÐ | d k sx | d k r½ t j | _ t j	 t j
 t j ƒ g } t j	 t j g } d | _ ns | d k r t j	 t j
 t j ƒ t j t j	 t j
 t j ƒ g } t j	 | _ d | _ d | _ n t d | ƒ ‚ | | _ t |  | | | ƒ } | ri| d k ri| } n  t j | j | Œ | ƒ }	 |	 S(	   s  Compile function from a Sympy expression

    Expressions are evaluated using double precision arithmetic.
    Some single argument math functions (exp, sin, cos, etc.) are supported
    in expressions.

    Parameters
    ==========

    args : List of Symbol
        Arguments to the generated function.  Usually the free symbols in
        the expression.  Currently each one is assumed to convert to
        a double precision scalar.
    expr : Expr, or (Replacements, Expr) as returned from 'cse'
        Expression to compile.
    callback_type : string
        Create function with signature appropriate to use as a callback.
        Currently supported:
           'scipy.integrate'
           'scipy.integrate.test'
           'cubature'

    Returns
    =======

    Compiled function that can evaluate the expression.

    Examples
    ========

    >>> import sympy.printing.llvmjitcode as jit
    >>> from sympy.abc import a
    >>> e = a*a + a + 1
    >>> e1 = jit.llvm_callable([a], e)
    >>> e.subs(a, 1.1)   # Evaluate via substitution
    3.31000000000000
    >>> e1(1.1)  # Evaluate using JIT-compiled code
    3.3100000000000005


    Callbacks for integration functions can be JIT compiled.
    >>> import sympy.printing.llvmjitcode as jit
    >>> from sympy.abc import a
    >>> from sympy import integrate
    >>> from scipy.integrate import quad
    >>> e = a*a
    >>> e1 = jit.llvm_callable([a], e, callback_type='scipy.integrate')
    >>> integrate(e, (a, 0.0, 2.0))
    2.66666666666667
    >>> quad(e1, 0.0, 2.0)[0]
    2.66666666666667

    The 'cubature' callback is for the Python wrapper around the
    cubature package ( https://github.com/saullocastro/cubature )
    and ( http://ab-initio.mit.edu/wiki/index.php/Cubature )

    There are two signatures for the SciPy integration callbacks.
    The first ('scipy.integrate') is the function to be passed to the
    integration routine, and will pass the signature checks.
    The second ('scipy.integrate.test') is only useful for directly calling
    the function using ctypes variables. It will not pass the signature checks
    for scipy.integrate.

    The return value from the cse module can also be compiled.  This
    can improve the performance of the compiled function.  If multiple
    expressions are given to cse, the compiled function returns a tuple.
    The 'cubature' callback handles multiple expressions (set `fdim`
    to match in the integration call.)
    >>> import sympy.printing.llvmjitcode as jit
    >>> from sympy import cse, exp
    >>> from sympy.abc import x,y
    >>> e1 = x*x + y*y
    >>> e2 = 4*(x*x + y*y) + 8.0
    >>> after_cse = cse([e1,e2])
    >>> after_cse
    ([(x0, x**2), (x1, y**2)], [x0 + x1, 4*x0 + 4*x1 + 8.0])
    >>> j1 = jit.llvm_callable([x,y], after_cse)
    >>> j1(1.0, 2.0)
    (5.0, 28.0)
    s$   llvmlite is required for llvmjitcodes   scipy.integrates   scipy.integrate.testi   t   cubaturei   s   Unknown callback type: %sN(   R   R   R¶   Rb   Rg   RX   Rd   R£   Rl   Rc   Re   R°   Rf   R±   t
   ValueErrorRm   R¹   t	   CFUNCTYPE(
   R   R"   R·   R\   Rm   t   argt	   arg_ctypet   arg_ctypes_formalR¬   t   cfunc(    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyR   i  s:    S				(   R   R»   (#   t
   __future__R    R   Rb   t   sympy.externalR   t   sympy.printing.printerR   t   sympyR   R   t   sympy.utilities.decoratorR   R   t   irR   t   bindingR–   t
   initializet   initialize_native_targett   initialize_native_asmprintert   __doctest_requires__R	   RI   R¢   t   setRr   Rq   t   objectRY   R®   R¶   R¹   RX   R   (    (    (    s9   lib/python2.7/site-packages/sympy/printing/llvmjitcode.pyt   <module>   s0   

W	&	