B
    `=                 @   sR  d Z ddlZddlZddlZddlZddlZedededgedddd	d
dfedededgedddd	d
dfdZ	dddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgdddgddd gdddgdddgdddgdddggZ
d^d"d#Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Zd2d3 Zejd4e
d5d6 Zd7d8 Zd9d: Zd;d< Zd=d> Zd?d@ ZdAdB ZdCdD ZejdEdddddgdFdG ZejdHdd	dIdJdKdLgdMdN ZdOdP Z dQdR Z!ejj"ej#dSk dTdUdVdW Z$dXdY Z%dZd[ Z&d\d] Z'dS )_zm
Tests the accuracy of the opt_einsum paths in addition to unit tests for
the various path helper functions.
    NZabdacZbdc             )abcdZabcdabcZbc   )GEMM1ZInner1greedyzeb,cb,fb->cef))r   r   )r   r   z
branch-allzbranch-2optimaldp))r   r   )r   r   zdd,fb,be,cdb->cef))r   r   )r   r   )r   r   ))r   r   )r   r   )r   r   zbca,cdb,dbf,afc->))r   r   )r   r   )r   r   ))r   r   )r   r   )r   r   zdcc,fce,ea,dbf->ab))r   r   )r   r   )r   r   Fc             C   sf   t | tsdS t| t|kr"dS d}x:tt| D ]*}|t | | tM }|| | || kM }q4W |S )NFT)
isinstancelistlenrangetuple)test_output	benchmarkbypassretpos r   J/home/dcms/DCMS/lib/python3.7/site-packages/opt_einsum/tests/test_paths.py
check_path7   s    
r   c             C   s,   | |d |d |d |}t ||s(td S )Nr   r   r   )r   AssertionError)func	test_datamax_sizer   r   r   r   r   assert_contract_orderE   s    r#   c              C   s   i } x*t dddddddgD ]\}}|| |< qW tjj}d|d	| ksJtd|d
| ks\td|d| ksntd|d| kstd|d| kstd|d| kstd|d| kstd|d| kstd S )NZabcdezr   r   	         r   r   r   r   r	   zazZzbch   ZaaaeiF2  Zabcde)zipoehelpersZcompute_size_by_dictr   )Z
sizes_dictindvalZ	path_funcr   r   r   test_size_by_dictK   s     r/   c              C   s   dd dD } dt jddd| ks(tdt jddd| ksBtd	t jd
dd| ks\tdt jddd| ksvtdt jd
dd| kstdt jddd| kstdt jddd| kstd S )Nc             S   s   i | ]
}d |qS )
   r   ).0vr   r   r   
<dictcomp>a   s    z"test_flop_cost.<locals>.<dictcomp>Zabcdefr0   r   Fr   r   d   ab   T      r   i  r   )r+   r,   Z
flop_countr   )	size_dictr   r   r   test_flop_cost_   s    r:   c            	   C   s4   t t  tjddgdgdgdd W d Q R X d S )Nza,b,cr   r   r   Zoptimall)optimize)pytestraisesKeyErrorr+   contractr   r   r   r   test_bad_path_optionu   s    r@   c              C   s2   t jddgdgdgddgd} |  dks.td S )	Nza,b,cr   r   r   )r   r   )r   r   )r;      )r+   r?   itemr   )xr   r   r   test_explicit_pathz   s    rD   c              C   s6   t jj} td }t| |dddg t| |ddg d S )Nr   i  )r   r   )r   r   r   )r   r   r   )r+   pathsr   explicit_path_testsr#   )	test_funcr!   r   r   r   test_path_optimal   s    rH   c              C   s6   t jj} td }t| |dddg t| |ddg d S )Nr   i  )r   r   )r   r   r   )r   r   r   )r+   rE   r   rF   r#   )rG   r!   r   r   r   test_path_greedy   s    rI   c              C   s   d} t j| }t j| f|ddd}t|d dgs<tt j| f|ddd}t|d dgshtt j| f|ddd}t|d d	d
dddgstt j| f|ddd}t|d d	d
dddgstd S )Nzabc,bdef,fghj,cem,mhk,ljk->adglr   r   )r;   memory_limitr   )r   r   r   r   r   r   r   )r   r   )r   r   )r   r   )r   r   )r+   r,   build_viewscontract_pathr   r   )
expressionviewspath_retr   r   r   test_memory_paths   s    rQ   zalg,expression,orderc             C   s8   t j|}t j|f|d| i}t|d |s4td S )Nr;   r   )r+   r,   rL   rM   r   r   )algrN   orderrO   rP   r   r   r   test_path_edge_cases   s    rT   c              C   s~   d} t jj| dddddd}t j| f|ddd\}}t|dd	gsLtt j| f|d
dd\}}t|dd	gsztd S )Nza,ac,ab,ad,cd,bd,bc->r6   )r   r	   r
   r   )dimension_dictr   	max_input)r;   rJ   )r   r   )r   r   r   r   r   r   r   )r+   r,   rL   rM   r   r   )rN   Z
edge_test4pathpath_strr   r   r   test_optimal_edge_cases   s    rY   c              C   s   d} dd |  ddD }tjj| |d}tj| f|ddd	\}}t|d
gsVttj| f|ddd	\}}t|dddgstd S )Nzabc,cfd,dbe,efac             S   s   i | ]
}d |qS )r6   r   )r1   kr   r   r   r3      s    z*test_greedy_edge_cases.<locals>.<dictcomp>,r   )rU   r   rV   )r;   rJ   )r   r   r   r   rK   )r   r   )r   r   )replacer+   r,   rL   rM   r   r   )rN   Zdim_dicttensorsrW   rX   r   r   r   test_greedy_edge_cases   s    r^   c              C   s@   d} dddg}t j| f|dddd }t|jdks<td S )	Nznlp,nlq,pl->n)r   r   r   )r   r   Tr   )shapesr;   r   r   )r+   rM   max
scale_listr   )eqr_   infor   r   r   test_dp_edge_cases_dimension_1   s    
rd   c              C   s@   d} dddg}t j| f|dddd }t|jdks<td S )	Nza,bcd,efg->)r   )r   r   r   Tr   )r_   r;   r   r   )r+   rM   r`   ra   r   )rb   r_   rc   r   r   r   &test_dp_edge_cases_all_singlet_indices   s    
re   c        	      C   s   d} d\}}}|f|f|||fg}t jdd}t jdd}t j| f|d|dd }t j| f|d|dd }|j|jk std S )Nz
a,b,abc->c)r   r   r   F)Zsearch_outerT)r_   r;   r   )r+   DynamicProgrammingrM   opt_costr   )	rb   dadbdcr_   opt1opt2info1info2r   r   r   .test_custom_dp_can_optimize_for_outer_products   s    
ro   c              C   s   t jjdddd\} }t jdd}t jdd}t j| f|d|d	d
 }t j| f|d|d	d
 }|j|jk svt|j|jkstd S )Nr0   r   +   )seedflops)minimizesizeT)r_   r;   r   )r+   r,   rand_equationrf   rM   rg   r   largest_intermediate)rb   r_   rk   rl   rm   rn   r   r   r   $test_custom_dp_can_optimize_for_size   s    rw   c              C   s   t jjdddd\} }t jdd}t jdd}t jdd}t j| f|d|d	d
 }t j| f|d|d	d
 }t j| f|d|d	d
 }|j|j  kr|jksn td S )Nr   r   *   )rq   T)Zcost_capFr4   )r_   r;   r   )r+   r,   ru   rf   rM   rg   r   )rb   r_   rk   rl   Zopt3rm   rn   Zinfo3r   r   r   test_custom_dp_can_set_cost_cap   s    ry   r;   c             C   sR   dd t dD \}}}tjdd}tjd||||| dd d	d
dgksNtd S )Nc             S   s   g | ]}t jd d qS )r0   )nprandomrandn)r1   _r   r   r   
<listcomp>   s    z4test_can_optimize_outer_products.<locals>.<listcomp>r   r0   r   zab,cd,ef,fg)r;   r   )r   r   )r   r   )r   r   )r   rz   r{   r|   r+   rM   r   )r;   r   r	   r
   r   r   r   r    test_can_optimize_outer_products   s    r   num_symbols   4   t   i,  c                s|   d dd t| D  tt tdddg}d  fddt| d	 D }tjj||d
}tj	|f|ddi d S )Nr   c             s   s   | ]}t |V  qd S )N)r+   Z
get_symbol)r1   ir   r   r   	<genexpr>  s    z"test_large_path.<locals>.<genexpr>r   r   r   r[   c             3   s   | ]} ||d   V  qdS )r   Nr   )r1   t)symbolsr   r   r     s    r   )rU   r;   r   )
joinr   dictr*   	itertoolscycler+   r,   rL   rM   )r   rU   rN   r]   r   )r   r   test_large_path  s
     r   c           	   C   s  t jjdddd\} }tttj|}tt	 t j
dd W d Q R X t j
ddd}t j| f|d	|i\}}t|jdkstt|jdkst||jkst|jd t|jkst|j|jd
 kst|j|jd kstd|_d|_t j| f|d	|i\}}t|jdkstt|jdks0t||jks@t|jd
 t|jksZt|j|jd
 kspt|j|jd kstt jjdddd\} }tttj|}tt	  t j| f|d	|i\}}W d Q R X d S )Nr0   r   rx   )rq   Z	something)rs   rr   )max_repeatsrs   r;   rt   g        rA      )   )r+   r,   ru   r   maprz   onesr<   r=   
ValueErrorRandomGreedyrM   r   costsr   sizesrW   bestminrv   rg   Ztemperaturer   )rb   r_   rO   	optimizerrW   	path_infor   r   r   test_custom_random_greedy  s2    r   c           	   C   s<  t jjdddd\} }tttj|}t jdddd}t j| f|d	|i\}}||j	ks^t
|j|jd ksrt
|j|jd
 kst
d|_d|_t j| f|d	|i\}}||j	kst
|j|jd kst
|j|jd
 kst
t jjdddd\} }tttj|}tt  t j| f|d	|i\}}W d Q R X d S )N   r   rx   )rq   r   r0   rt   )nbranchcutoff_flops_factorrs   r;   rr   r   r   )r+   r,   ru   r   r   rz   r   ZBranchBoundrM   rW   r   rv   r   rg   r   r   r<   r=   r   )rb   r_   rO   r   rW   r   r   r   r   test_custom_branchbound5  s"    r   )r   r   zrequires python3.2 or higher)reasonc        	      C   s  ddl m}  | d}tjjdddd\}}tttj|}tj	d|d}tj
|f|d	|i\}}t|jdksttt|jdkst||jkst|j|kst|j|kst|jd
 t|jkst|j|jd kst|j|jd
 ksttd|_d|_d|_tj
|f|d	|i\}}t|jdks4tt|jdksHt||jksXt|jd
 t|jksrt|j|jd kst|j|jd
 kstd|_|jd k	st|j|k	stdd |jD }t|std S )Nr   )ProcessPoolExecutorr   r0   r   rx   )rq   )r   parallelr;   rr   rt   g    .Ag?Tc             S   s   g | ]}|  p| qS r   )Zrunningdone)r1   fr   r   r   r~   x  s    z/test_parallel_random_greedy.<locals>.<listcomp>)concurrent.futuresr   r+   r,   ru   r   r   rz   r   r   rM   r   r   r   r   rW   r   Z	_executorr   r   rv   rg   intr   Zmax_timeZ_futuresall)	r   poolrb   r_   rO   r   rW   r   Zare_doner   r   r   test_parallel_random_greedyP  s:    
r   c              C   s   G dd dt jj} t jjddddd\}}tttj|}t j	|f|ddi}|  }t j	|f|d|i}||kszt
|jst
d S )	Nc               @   s   e Zd ZdddZdS )z2test_custom_path_optimizer.<locals>.NaiveOptimizerNc             S   s   d| _ dgt|d  S )NT)r   r   r   )was_usedr   )selfinputsoutputr9   rJ   r   r   r   __call__~  s    z;test_custom_path_optimizer.<locals>.NaiveOptimizer.__call__)N)__name__
__module____qualname__r   r   r   r   r   NaiveOptimizer}  s   r   r   r   rx   )rq   d_maxr;   F)r+   rE   ZPathOptimizerr,   ru   r   r   rz   r   r?   r   r   )r   rb   r_   rO   expr   outr   r   r   test_custom_path_optimizer|  s    r   c              C   s   G dd dt jj} t jjddddd\}}tttj|}t j	|f|ddi}| d	d
}t j	|f|d|i}||ks~t
|jst
t|jd	kst
d S )Nc               @   s    e Zd Zedd Zdd ZdS )z:test_custom_random_optimizer.<locals>.NaiveRandomOptimizerc             S   s   t j|  g }tt|}x^t|dkrzt jjt|ddd\}}||t|  |	| |	| |
||f qW tj||||\}	}
||	|
fS )z9Picks a completely random contraction order.
            r   r   F)rt   r\   )rz   r{   rq   setr   r   choicer   addremoveappendr+   path_randomZssa_path_compute_cost)rnr   r   r9   Zssa_path	remainingr   jZcostrt   r   r   r   random_path  s    

zFtest_custom_random_optimizer.<locals>.NaiveRandomOptimizer.random_pathc             S   s(   d| _ t|}| j}||||f}||fS )NT)r   r   r   )r   r   r   r9   r   Ztrial_fnZ
trial_argsr   r   r   setup  s
    z@test_custom_random_optimizer.<locals>.NaiveRandomOptimizer.setupN)r   r   r   staticmethodr   r   r   r   r   r   NaiveRandomOptimizer  s   r   r   r   rx   )rq   r   r;   Fr   )r   )r+   r   ZRandomOptimizerr,   ru   r   r   rz   r   r?   r   r   r   r   )r   rb   r_   rO   r   r   r   r   r   r   test_custom_random_optimizer  s    

r   c           	   C   s   dd } t t tjd|  W d Q R X tjd|  dtjjksJtd}dddg}tj|f|d	dd
\}}|ddgksttjjd= d S )Nc             S   s   dgt | d  S )N)r   r   r   )r   )r   r   r9   rJ   r   r   r   custom_optimizer  s    z5test_optimizer_registration.<locals>.custom_optimizerr   Zcustomzab,bc,cd)r   r   )r   r   )r   r   T)r_   r;   )r   r   )	r<   r=   r>   r+   rE   Zregister_path_fnZ_PATH_OPTIONSr   rM   )r   rb   r_   rW   r   r   r   r   test_optimizer_registration  s    
r   )F)(__doc__r   sysnumpyrz   r<   Z
opt_einsumr+   r   rF   Zpath_edge_testsr   r#   r/   r:   r@   rD   rH   rI   rQ   markZparametrizerT   rY   r^   rd   re   ro   rw   ry   r   r   r   r   Zskipifversion_infor   r   r   r   r   r   r   r   <module>   sz   
			 "&,&