K iBdZddlZddlmZddlmZddlmZddlm Z ddl m Z edZ e rTed jZed jZej#ej%ej'd dgiZGd d eZGddeZgZeZdaGddZGddeZGddZdZe dddZy)z Use llvmlite to create executable functions from SymPy expressions This module requires llvmlite (https://github.com/numba/llvmlite). N) import_module)Printer)S) IndexedBase)doctest_depends_onllvmlitez llvmlite.irzllvmlite.binding llvm_callablecXeZdZdZfdZdZdZdZdZdZ dZ d Z d Z d Z xZS) LLVMJitPrinterzConvert expressions to LLVM IRc|jdi|_ts tdt ||i|t j|_||_ ||_ ||_ i|_ i|_ y)N func_arg_mapz'llvmlite is required for LLVMJITPrinter)popr r ImportErrorsuper__init__ll DoubleTypefp_typemodulebuilderfnext_fntmp_var)selfrrrargskwargs __class__s `/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/printing/llvmjitcode.pyrzLLVMJitPrinter.__init__sg"JJ~r:GH H $)&)}}     c"||j|<yN)r)rnamevalues r _add_tmp_varzLLVMJitPrinter._add_tmp_var)s" TrcTtj|jt|Sr!)rConstantrfloat)rns r _print_NumberzLLVMJitPrinter._print_Number,s{{4<<q22rchtj|jt|jSr!)rr&rr'prexprs r_print_IntegerzLLVMJitPrinter._print_Integer/s{{4<<tvv77rc|jj|}|s|jj|}|std|z|S)NSymbol not found: %s)rgetr LookupError)rsvals r _print_SymbolzLLVMJitPrinter._print_Symbol2sHllq!##''*C4q89 9 rc|j|j}|jtjk(r:|j j tj|jd|S|jtjk(r|jjd}|s[tj|j|jg}tj|j|d}||jd<|j j!||gdS|jdk(r|j j#||S|j|j}|jjd}|sftj|j|j|jg}tj|j|d}||jd<|j j!|||gdS)Ng?sqrtpow)_printbaseexpr NegativeOnerfdivrr&rHalfrr1 FunctionTypeFunctionrcallfmul)rr-base0rfn_typeexp0s r _print_PowzLLVMJitPrinter._print_Pow;ss DII& 88q}} $<<$$R[[s%CUK K 88qvv (B//$,,G[[gv>&( F#<<$$R%&9 9 88q=<<$$UE2 2{{488$ [[__U #oodllT\\4<<4PQGT[['59B!#DKK ||  eT]E::rc|jDcgc]}|j|}}|d}|ddD]}|jj||} |Scc}wNr)rr:rrCrr-anodesenodes r _print_MulzLLVMJitPrinter._print_MulQ_)-3AQ33 !H!"I +D !!!T*A + 4Ac|jDcgc]}|j|}}|d}|ddD]}|jj||} |Scc}wrI)rr:rfaddrKs r _print_AddzLLVMJitPrinter._print_AddXrQrRc|jj}|j|jd}|jj |}|s[t j|j|jg}t j|j||}||j|<|jj||g|SNr) func__name__r:rrr1rr@rrArrrB)rr-r"e0rrEs r_print_FunctionzLLVMJitPrinter._print_Functionasyy!! [[1 & [[__T "oodllT\\NCGT[['48B "DKK ||  bT400rc0tdt|z)Nz,Unsupported type for LLVM JIT conversion: %s) TypeErrortyper,s r emptyPrinterzLLVMJitPrinter.emptyPrinterksFt*%& &r)rY __module__ __qualname____doc__rr$r)r.r5rGrPrUr[r_ __classcell__rs@rr r s8( #38;,1&rr c*eZdZfdZdZdZxZS)LLVMJitCallbackPrinterc$t||i|yr!rr)rrrrs rrzLLVMJitCallbackPrinter.__init__ss $)&)rc|j|j\}}t|jdj }|j j |tjtjd|g}|j j|tj|j}|j j|}|S)Nr )r r;intindicesevalfrgeprr&IntTypebitcast PointerTyperload)rr-arrayidxoffset array_ptr fp_array_ptrr#s r_print_Indexedz%LLVMJitCallbackPrinter._print_Indexedvs&&tyy1 sT\\!_**,-LL$$UR[[B-P,QR ||++Ir~~dll7ST  !!,/ rc|jj|}|r|S|jj|ddg\}}|std|z|jj |t jt jd|g}|jj|t j|j}|jj|}|S)Nrr0rj) rr1r r2rrnrr&rorprqrrr)rr3r4rsrtrvrwr#s rr5z$LLVMJitCallbackPrinter._print_Symbol~sllq! J&&**1tQi8 s4q89 9LL$$UR[[B-M,NO ||++I,.NN4<<,HJ  !!,/ r)rYr`rarrxr5rcrds@rrfrfrs* rrfcBeZdZdZdZdZdZdZdZdZ dZ d Z y ) LLVMJitCodec||_tj|_tj d|_d|_g|_|j|_i|_ d|_ y)Nmod1) signaturerrrModulerrllvm_arg_types llvm_ret_type param_dict link_name)rrs rrzLLVMJitCode.__init__sO"}} ii'  !\\rc6|tjk(rtjdS|tjk(r |j S|tj tjk(rtj|j S|tjk(r(tjtjdS|tjk(r(tjtjdStdt|zy)NrjzUnhandled ctype = %s) ctypesc_intrroc_doublerPOINTERrqc_void_p py_objectprintstr)rctypes r _from_ctypezLLVMJitCode._from_ctypes FLL ::b> ! FOO #<<  FNN6??3 3>>$,,/ / FOO #>>"**R.1 1 F$$ $>>"**R.1 1 $s5z12rc|j|jj|_|jjDcgc]}|j|c}|_ycc}w)z#Create types for function argumentsN)rrret_typer arg_ctypesr)r func_argsrLs r _create_argszLLVMJitCode._create_argssM!--dnn.E.EF*...*C*C DQT  a D  DsA$c<d}tdz a|ttz|_tj |jt j |j|j}t j|j||j|_ y)z,Create function with name and type signaturejit_funcrJ)r"N) current_link_suffixrr link_namesaddrr@rrrArr)rdefault_link_namerEs r_create_function_basez!LLVMJitCode._create_function_basesq'q *S1D-EEt~~&//$"4"4d6I6IJ++dkk7+Hrct|D]R\}}t||jj|_|jj||j |<Ty)z0Mapping of symbolic values to function argumentsN) enumeraterrrr"rrrirLs r_create_param_dictzLLVMJitCode._create_param_dictsLi( 1DAq#&q6DGGLLO !%aDOOA  1rcd|jjd}tj|}t |j ||j|j }|j||}|jj|j||t|j }|S)'Create function body and return LLVM IRentryr ) rappend_basic_blockr IRBuilderr rr _convert_exprrret _wrap_returnr)rr-bb_entryrljrstrmods r_create_functionzLLVMJitCode._create_functions77--g6,,x( DKK$'')-:  T* t((S12T[[! rcP|jjtjk(r|dStj tj d}tj||jg}tj|j|d}|Dcgc]}|jj||g!}}t|dk(r|d}|Stj dg} | j|gt|ztj|| } tj|j| d} tjtj dt|g} | j||jj| | }|Scc}w)NrrjPyFloat_FromDoublerJ PyTuple_Pack)rrrrrrqror@rrArrrBlenextendr&) rrvalsvoid_ptr wrap_typewrap_fnv wrapped_vals final_valtuple_arg_types tuple_typetuple_fn tuple_argss rrzLLVMJitCode._wrap_returnsI >> " "foo 57N>>"**R.1OOHt||n= ++bii4HI?CD! !5D D t9>$QI  "zz"~.O  " "H:c$i#7 8?CJ{{299j.IH++bjjnc,6GHIJ   l + *=I%Es$F#c| t|dk(rw|d}|d}t|dk7r2|jjtjk(r t d|D](\}}|j |}|j||*Dcgc]}|j |}}|S#t$r|g}Y.wxYwcc}w)Nr8rrJz>Return of multiple expressions not supported for this callback) rrrrrNotImplementedErrorr:r$r]) rrr- tmp_exprs final_exprsr"rNr4rs rrzLLVMJitCode._convert_exprs !4yA~ G "1g {#q(T^^-D-D-W-.noo(/GD!))A,COOD#./ '22 ! 22  !&K !3sBB' B9' B65B6ctj|}tj}d|_tj }|j ||j |tjjj}tj||}|jtj| |j!|j"}|S)Nr8)llvmparse_assemblycreate_pass_manager_builder opt_levelcreate_module_pass_managerpopulaterunTargetfrom_default_triplecreate_target_machinecreate_mcjit_compilerfinalize_object exe_enginesappendr emit_assemblyget_function_addressr)rrllmodpmb pass_managertarget_machineexe_engfptrs r_compile_functionzLLVMJitCode._compile_function s##F+..0 668  \" KK + + - C C E ,,UNC!7# ++DNN; rN) rYr`rarrrrrrrrrrrr{r{s2 3E I1 !F$rr{c*eZdZfdZdZdZxZS)LLVMJitCodeCallbackc$t||yr!rh)rrrs rrzLLVMJitCodeCallback.__init__#s #rcbt|D]\}}t|trP|jj||f|j |<t ||jj|_f|jj|jj|f|j |<yr!) r isinstancerrrrrr"r input_argrs rrz&LLVMJitCodeCallback._create_param_dict&si( )DAq![)&*ggll1oq%9"'*1v Q$&*ggll4>>3K3K&L&'&)"  )rcx|jjd}tj|}t |j ||j|j }|j||}|jjr|j|jj|jjtj|j}t|D]S\}}tjtj!d|} |j#|| g} |j%|| U|j'tjtj!ddn+|j(j'|j+||t-|j } | S)rrrrjr)rrrrrfrrrrret_argrprrqrrr&rornstorerrrr) rr-rrrr output_fp_ptrrr4indexoutput_array_ptrrs rrz$LLVMJitCodeCallback._create_function/s?77--g6,,x( #DKK$''15B  T* >> ! !#OODGGLL9O9O,P,.NN4<<,HJM#C. 53 BJJrNA6#*;;}ug#F  c#34 5 KK BJJrNA6 7 JJNN4,,R5 6T[[! r)rYr`rarrrrcrds@rrr"s$)rrceZdZdZy) CodeSignaturec<||_g|_d|_d|_yrW)rrrr)rrs rrzCodeSignature.__init__Is"   rN)rYr`rarrrrrrHs rrc| t|}n t|}|j||j|j ||j |} |j|}|S)z5Create a native code function from a SymPy expression)r{rrrrrrr)rr-r callback_typejitrrs r_llvm_jit_coderUsn)$!),T4  ! !$ 'F    (D Kr)rscipy)modulescts tdttj}g}|*|D]#}tj }|j |%n|dvrptj |_tjtjtj g}tjtj g}d|_ n|dk(rtjtjtj tjtjtjtj g}tj|_d|_ d|_ ntd|z||_t||||}|r|dk(r}|jtjk(rtj } ntj"} | |jg||} | S)a 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 >>> 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) z$llvmlite is required for llvmjitcode)scipy.integratezscipy.integrate.testrJcubaturezUnknown callback type: %sr)rrrrrrrrrrrrr ValueErrorrr PYFUNCTYPE CFUNCTYPE) rr-rrr_ arg_ctypearg_ctypes_formalrFUNCTYPEcfuncs rr r gsj @AAf../IJ )AI   i ( ) E E#__ llFNN6??$CD #\\6??;  * $llnnV__5oollnnV__5  $\\   4}DEE%I $i ?D*;;& V---$$## 5HY'' 5* 5d ;E Lrr!) rbrsympy.externalrsympy.printing.printerrsympy.core.singletonrsympy.tensor.indexedrsympy.utilities.decoratorrrirrbindingr initializeinitialize_native_targetinitialize_native_asmprinter__doctest_requires__r rfrsetrrr{rrrr rrrrs (*",8  $ } % ( (B + , 4 4DOO!!#%%')J<8R&WR&n^: U IIX#+#L  $12B3Br